// From AMRPoisson. // The Level class. The intersection of a level and a process. // Level contains all information about each patch at a particular height // in a particular process // at a particular time. class Level { private static final int dimensions = 2; private static final RectDomain<1> Ddims = [1:dimensions], Ddirs = [-1:1:2]; /* non-constant fields */ // process-local patches public RectDomain<1> indices; public Patch2 [1d] patches; // domain of patches is indices // these depend on the height only public int height; public RectDomain<2> domain; // index space of the whole domain public double [1d] ds; // step sizes [dimension 1:2] /* constructors */ public Level() { } public Level(RectDomain<1> I, RectDomain<2> D, int h, double [1d] stepsizes) { indices = I; patches = new Patch2[I]; domain = D; height = h; ds = new double[stepsizes.domain()]; ds.copy(stepsizes); } /* methods */ public void copy(Level level) { // Copy level, except leave the patches unassigned. indices = level.indices; patches = new Patch2[indices]; domain = level.domain; height = level.height; ds = new double[level.ds.domain()]; ds.copy(level.ds); } public static final Level LevelGodunov2(Level levelOld, double time, double dt, int iStep, // 0 <= iStep <= nRefine - 1 int dimfirst) { // dimension of first pass // Advance patches in a level by one timestep. // Return a new Level object containing patches at the new time. Level levelNew = new Level(); // .copy sets number of patches, but leaves the patches unassigned levelNew.copy(levelOld); // weights on old and new coarse data, used to get an interpolated // value for coarse data at the (fine) starting time step double wtNew = (double) iStep / (double) Amr2.nRefine; double wtOld = 1.0 - wtNew; Logger.barrier(); foreach (ind in levelOld.indices) { // for every patch at this level // Logger.append("LevelGodunov setting up patch"); Patch2 patchOld = levelOld.patches[ind]; // Need to set up a new patch. // The old patch must remain because adjacent patches should point // to the old fields. Patch2 patchNew = new Patch2(levelNew); patchNew.LevelGodunov2(patchOld, wtOld, wtNew, time, dt, dimfirst); levelNew.patches[ind] = patchNew; } // ind in indices Logger.barrier(); return levelNew; } public final void FindCoarserOld() { // Set patches[i].coarserPatchesOld for all i in indices in this Level. // All the domains should already be set. // Set patches[i].coarserPatchesNew to null. if (height == 0) { foreach (ind in indices) patches[ind].coarserPatchesOld = Patch2.NoPatches; } else { foreach (ind in indices) { Patch2 patch = patches[ind]; BoxedList_Patch2 coarserList = new BoxedList_Patch2(); // Loop over ALL patches at next coarser level. foreach (proc in Amr2.processes.domain()) { Level lev = Amr2.processes[proc].levels[height-1]; foreach (indC in lev.indices) {// loop over coarser patches Patch2 patchC = lev.patches[indC]; Domain<2> intersect = patch.coarseDomain * patchC.domain; if (!intersect.isNull()) coarserList.push(patchC); } } patch.coarserPatchesOld = coarserList.toArray(); } } foreach (ind in indices) patches[ind].coarserPatchesNew = Patch2.NoPatches; } public final void FindCoarserNew() { // Set patches[i].coarserPatchesNew for all i in indices in this Level. // All the domains should already be set. if (height == 0) { foreach (ind in indices) patches[ind].coarserPatchesNew = Patch2.NoPatches; } else { foreach (ind in indices) { Patch2 patch = patches[ind]; BoxedList_Patch2 coarserList = new BoxedList_Patch2(); // Loop over ALL patches at next coarser level. foreach (proc in Amr2.processes.domain()) { Level lev = Amr2.processes[proc].levels[height-1]; foreach (indC in lev.indices) {// loop over coarser patches Patch2 patchC = lev.patches[indC]; Domain<2> intersect = patch.coarseDomain * patchC.domain; if (!intersect.isNull()) coarserList.push(patchC); } } patch.coarserPatchesNew = coarserList.toArray(); } } } public final void FindAdjacent() { // Set patches[i].adjacentPatches for all i in indices in this Level. // All the domains should already by set! // System.out.println("FindAdjacent"); foreach (ind in indices) patches[ind].FindAdjacent(); } public final void AverageDown() { // Average solution at this level to get a new coarse solution // on all coarse cells (at next coarser level) covered by this level. foreach (ind in indices) patches[ind].AverageDown(); } public final void Reflux() { // Correct the solution (U and q) at coarse-fine boundaries // due to flux discrepancy. foreach (ind in indices) patches[ind].Reflux(); } public final void FillRegrid() { foreach (indpatch in indices) patches[indpatch].FillRegrid(); } }