public void Command(string[] arg) { Domain domain = sparta.domain; Grid grid = sparta.grid; int narg = arg.Length; if (!domain.box_exist) { sparta.DumpError("Cannot create grid before simulation box is defined"); } if (grid.exist) { sparta.DumpError("Cannot create grid when grid is already defined"); } grid.exist = true; if (narg < 3) { sparta.DumpError("Illegal create_grid command"); } int nx = int.Parse(arg[0]); int ny = int.Parse(arg[1]); int nz = int.Parse(arg[2]); if (nx < 1 || ny < 1 || nz < 1) { sparta.DumpError("Illegal create_grid command"); } if (domain.dimension == 2 && nz != 1) { sparta.DumpError("Create_grid nz value must be 1 for a 2d simulation"); } dimension = domain.dimension; int nlevels = 1; Bstyle bstyle = Bstyle.NONE; int px = 0; int py = 0; int pz = 0; int order; Inside inside = Inside.ANY; int iarg = 3; while (iarg < narg) { sparta.DumpError("Complete CreateGrid.Command optional arguments"); iarg++; } if (bstyle == Bstyle.NONE) { bstyle = Bstyle.LEVEL; } if (bstyle == Bstyle.BLOCK) { sparta.DumpError("Complete CreateGrid.Command Bstyle.Block"); } double time1 = Timer.getTime(); int level = 1; int xlo, xhi, ylo, yhi, zlo, zhi; xlo = xhi = ylo = yhi = zlo = zhi = 1; iarg = 3; Region region = null; Int64 count = 0; int pnx, pny, pnz, ix, iy, iz, nbits, proc; bool pflag; int m, nth, idgrandparent, idparent, idchild; double[] lo = new double[3], hi = new double[3]; Grid.ParentCell p; while (true) { if (level == 1) { grid.AddParentCell(0, -1, nx, ny, nz, domain.boxlo, domain.boxhi); } else { int nparent = grid.nparent; int prevlevel = level - 2; for (int igrandparent = 0; igrandparent < nparent; igrandparent++) { if (grid.pcells[igrandparent].level != prevlevel) { continue; } p = grid.pcells[igrandparent]; idgrandparent = p.id; nbits = p.nbits; pnx = p.nx; pny = p.ny; pnz = p.nz; m = 0; for (iz = 0; iz < pnz; iz++) { for (iy = 0; iy < pny; iy++) { for (ix = 0; ix < pnx; ix++) { m++; idparent = idgrandparent | (m << nbits); grid.IdChildLohi(igrandparent, m, lo, hi); if (region != null) { pflag = CellInRegion(lo, hi, region, inside); } else { pflag = true; if (ix + 1 < xlo || ix + 1 > xhi) { pflag = false; } if (iy + 1 < ylo || iy + 1 > yhi) { pflag = false; } if (iz + 1 < zlo || iz + 1 > zhi) { pflag = false; } } if (pflag) { grid.AddParentCell(idparent, igrandparent, nx, ny, nz, lo, hi); } else { if (count % 1 == 0) { grid.AddChildCell(idparent, igrandparent, lo, hi); } count++; } } } } } } // final level, add current level cells as child cells // loop over all parent cells to find ones at previous level // use their info to generate my child cells at this level // if BSTYLE is set, there is only 1 level, create proc's cells directly if (level == nlevels) { List <Grid.ParentCell> pcells = grid.pcells; int nparent = grid.nparent; int prevlevel = level - 1; for (int iparent = 0; iparent < nparent; iparent++) { if (pcells[iparent].level != prevlevel) { continue; } p = pcells[iparent]; idparent = p.id; nbits = p.nbits; nx = p.nx; ny = p.ny; nz = p.nz; if (bstyle == Bstyle.LEVEL) { int ntotal = (int)nx * ny * nz; int firstproc = (int)count % 1; int ifirst = 0 - firstproc + 1; if (ifirst <= 0) { ifirst += 1; } for (m = ifirst; m <= ntotal; m += 1) { idchild = idparent | (m << nbits); grid.IdChildLohi(iparent, m, lo, hi); grid.AddChildCell(idchild, iparent, lo, hi); } count += ntotal; // loop over all child cells // convert M to Nth based on order // assign each cell to proc based on Nth and STRIDE or CLUMP } else { sparta.DumpError("CreateGrid->Command: more Bstyle"); } } break; } if (level == nlevels) { break; } level++; switch (arg[iarg]) { //case "level" default: sparta.DumpError("CreateGrid->Command: complete this"); break; } } List <Grid.ParentCell> pcells1 = grid.pcells; int nparent1 = grid.nparent; for (int i = 1; i < nparent1; i++) { pcells1[pcells1[i].iparent].grandparent = 1; } if (bstyle == Bstyle.CLUMP || bstyle == Bstyle.BLOCK) { grid.clumped = true; } else { grid.clumped = false; } double time2 = Timer.getTime(); grid.SetupOwned(); grid.AcquireGhosts(); grid.FindNeighbors(); grid.CheckUniform(); double time3 = Timer.getTime(); double time_total = time3 - time1; StringBuilder sb = new StringBuilder(); sb.AppendFormat("Create {0} child grid cells\n", grid.ncell); sb.AppendFormat(" parent cells = {0}\n", grid.nparent); sb.AppendFormat(" CPU time = {0} secs\n", time_total); sb.AppendFormat(" create/ghost percent = {0} {1}\n", 100.0 * (time2 - time1) / time_total, 100.0 * (time3 - time2) / time_total); sparta.DumpMessage(sb.ToString()); }
public void Command(string[] arg) { Grid grid = sparta.grid; int narg = arg.Length; if (!grid.exist) { sparta.DumpError("Cannot balance grid before grid is defined"); } if (narg < 1) { sparta.DumpError("Illegal balance_grid command"); } Bstyle bstyle = Bstyle.NONE; Order order; int px, py, pz; RCBtype rcbwt = RCBtype.CELL; int rcbflip; switch (arg[0]) { case "rcb": if (narg != 2 && narg != 3) { sparta.DumpError("Illegal balance_grid command"); } bstyle = Bstyle.BISECTION; switch (arg[1]) { case "cell": rcbwt = RCBtype.CELL; break; case "part": rcbwt = RCBtype.PARTICLE; break; default: sparta.DumpError("Illegal balance_grid command"); break; } // undocumented optional 3rd arg // rcbflip = 3rd arg = 1 forces rcb.compute() to flip sign // of all grid cell "dots" to force totally different // assignment of grid cells to procs and induce // complete rebalance data migration rcbflip = 0; if (narg == 3) { rcbflip = int.Parse(arg[2]); } break; default: sparta.DumpError("BalanceGrid.Command(): complete arguments"); break; } if (bstyle == Bstyle.STRIDE || bstyle == Bstyle.CLUMP || bstyle == Bstyle.BLOCK) { if (!grid.uniform) { sparta.DumpError("Invalid balance_grid style for non-uniform grid"); } } double time1 = Timer.getTime(); List <Grid.ChildCell> cells = grid.cells; List <Grid.ChildInfo> cinfo = grid.cinfo; int nglocal = grid.nlocal; switch (bstyle) { case Bstyle.NONE: break; case Bstyle.STRIDE: break; case Bstyle.CLUMP: break; case Bstyle.BLOCK: break; case Bstyle.RANDOM: break; case Bstyle.PROC: break; case Bstyle.BISECTION: RCB rcb = new RCB(sparta); double[,] x; x = new double[nglocal, 3]; double[] lo, hi; int nbalance = 0; for (int icell = 0; icell < nglocal; icell++) { if (cells[icell].nsplit <= 0) { continue; } lo = cells[icell].lo; hi = cells[icell].hi; x[nbalance, 0] = 0.5 * (lo[0] + hi[0]); x[nbalance, 1] = 0.5 * (lo[1] + hi[1]); x[nbalance, 2] = 0.5 * (lo[2] + hi[2]); nbalance++; } double[] wt; if (rcbwt == RCBtype.PARTICLE) { //sparta.particle.Sort(); //int zero = 0; //int n; //wt = new double[nglocal]; //nbalance = 0; //for (int icell = 0; icell < nglocal; icell++) //{ // if (cells[icell].nsplit <= 0) continue; // n = cinfo[icell].count; // if (n!=0) wt[nbalance++] = n; // else // { // wt[nbalance++] = ZEROPARTICLE; // zero++; // } //} sparta.DumpError("BalanceGrid->Command: complete sorted by particle"); } //rcb.Compute(nbalance, x, wt, rcbflip); //rcb.Invert(); //nbalance = 0; //int[] sendproc = rcb.Sendproc; //for (int icell = 0; icell < nglocal; icell++) //{ // if (cells[icell].nsplit <= 0) continue; // cells[icell].proc = sendproc[nbalance++]; //} //nmigrate = nbalance - rcb.nkeep; break; default: break; } }