src/test/balance5.c

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    
    #include "utils.h"
    #include "output.h"
    #include "refine_unbalanced.h"
    #include "check_restriction.h"
    
    #define BGHOSTS 2
    
    void image()
    {
      // const scalar pid[] = pid(); // fixme: this should work
      scalar pid[];
      foreach()
        pid[] = pid();
      output_ppm (pid, n = 128, min = 0, max = npe() - 1);
    }
    
    void set_unused_pids()
    {
      scalar pid[];
      foreach_cell()
        pid[] = is_local(cell) ? pid() : -1;
      for (int l = 0; l <= depth(); l++)
        boundary_iterate (restriction, {pid}, l);
      foreach_cell()
        if (pid[] < 0)
          cell.pid = npe();
    }
    
    void partition (const char * prog)
    {
      // generates reference solution (in ref)
      init_grid (1);
    
      foreach_cell() {
        cell.pid = pid();
        cell.flags |= active;
      }
      tree->dirty = true;
    
      refine_unbalanced (level < 5, NULL);
    
      refine_unbalanced (level <= 9 && sq(x - 0.5) + sq(y - 0.5) < sq(0.05), NULL);
    
      mpi_partitioning();
      set_unused_pids();
    
      char name[80];
      sprintf (name, "ref-%d", pid());
      FILE * fp = fopen (name, "w");
      debug_mpi (fp);
      fclose (fp);
    
      MPI_Barrier (MPI_COMM_WORLD);
      if (pid() == 0) {
        sprintf (name, "cat ref-* > ref && cp -f ref %s.ref", prog);
        system (name);
      }
    }
    
    int main (int argc, char * argv[])
    {
      partition (argv[0]);
    
      init_grid (32);
    
      scalar s[];
      face vector u[];
      reset ({s,u}, undefined);
      foreach()
        s[] = 1;
      foreach_face()
        u.x[] = 1;
    
      boundary ({s,u});
      scalar * list = {s,u};
    
      /** the loop below is the prototype for grid/tree-common.h:refine()
          Fixes made here must also be applied to refine() */
    
      int refined, n = 0;
      do {
        refined = 0;
        tree->refined.n = 0;
        foreach_leaf()
          if (level <= 9 && sq(x - 0.5) + sq(y - 0.5) < sq(0.05)) {
    	refine_cell (point, list, 0, &tree->refined);
    	refined++;
    	continue;
          }
        mpi_all_reduce (refined, MPI_INT, MPI_SUM);
        if (refined) {
          mpi_boundary_refine (list);
          mpi_boundary_update_buffers();
          grid->tn = 0; // so that tree is not "full"
          boundary (list);
          image();
          while (balance()) {
    	foreach()
    	  foreach_neighbor()
                assert (s[] == 1);
    	foreach_face()
    	  for (int i = -2; i <= 2; i++)
    	    assert ((u.x[0,i] == 1));
    	image();
          }
        }
        n++;
      } while (refined);
    
      set_unused_pids();
      debug_mpi (qerr);
    
      check_restriction (s);
    }