// Initialize grids
void AMRLevelPluto::initialGrid(const Vector<Box>& a_newGrids)
{
  CH_assert(allDefined());

  if (s_verbosity >= 3)
  {
    pout() << "AMRLevelPluto::initialGrid " << m_level << endl;
  }

  // Save original grids and load balance
  m_level_grids = a_newGrids;
  m_grids = loadBalance(a_newGrids);

  if (s_verbosity >= 4)
  {
    // Indicate/guarantee that the indexing below is only for reading
    // otherwise an error/assertion failure occurs
    const DisjointBoxLayout& constGrids = m_grids;

    pout() << "new grids: " << endl;
    for (LayoutIterator lit = constGrids.layoutIterator(); lit.ok(); ++lit)
    {
      pout() << constGrids[lit()] << endl;
    }
  }

  // Define old and new state data structures
  IntVect ivGhost = m_numGhost*IntVect::Unit;
  m_UNew.define(m_grids,m_numStates,ivGhost);
  m_UOld.define(m_grids,m_numStates,ivGhost);

  // Set up data structures
  levelSetup();
}
// Set up data on this level after regridding
void AMRLevelPluto::regrid(const Vector<Box>& a_newGrids)
{
  CH_assert(allDefined());

  if (s_verbosity >= 3)
  {
    pout() << "AMRLevelPluto::regrid " << m_level << endl;
  }

  // Save original grids and load balance
  m_level_grids = a_newGrids;
  m_grids = loadBalance(a_newGrids);

  if (s_verbosity >= 4)
  {
    // Indicate/guarantee that the indexing below is only for reading
    // otherwise an error/assertion failure occurs
    const DisjointBoxLayout& constGrids = m_grids;

    pout() << "new grids: " << endl;

    for (LayoutIterator lit = constGrids.layoutIterator(); lit.ok(); ++lit)
    {
      pout() << constGrids[lit()] << endl;
    }
  }

  // Save data for later
  DataIterator dit = m_UNew.dataIterator();
  for(;dit.ok(); ++dit){
	m_UOld[dit()].copy(m_UNew[dit()]);
  }

  // Reshape state with new grids
  IntVect ivGhost = m_numGhost*IntVect::Unit;
  m_UNew.define(m_grids,m_numStates,ivGhost);


  // Set up data structures
  levelSetup();

  // Interpolate from coarser level
  if (m_hasCoarser)
  {
    AMRLevelPluto* amrGodCoarserPtr = getCoarserLevel();
    m_fineInterp.interpToFine(m_UNew,amrGodCoarserPtr->m_UNew);
  }

  // Copy from old state
  m_UOld.copyTo(m_UOld.interval(),
                m_UNew,
                m_UNew.interval());

  m_UOld.define(m_grids,m_numStates,ivGhost);
} 
Example #3
0
void CFStencil::buildPeriodicVector(Vector<Box>& a_periodicVector,
                                    const ProblemDomain& a_fineDomain,
                                    const DisjointBoxLayout& a_fineBoxes)
{
  Box periodicTestBox(a_fineDomain.domainBox());
  if (a_fineDomain.isPeriodic())
    {
      for (int idir=0; idir<SpaceDim; idir++)
        {
          if (a_fineDomain.isPeriodic(idir))
            {
              periodicTestBox.grow(idir,-1);
            }
        }
    }
  a_periodicVector.clear();
  a_periodicVector.reserve(a_fineBoxes.size());

  LayoutIterator lit = a_fineBoxes.layoutIterator();
  for (lit.reset(); lit.ok(); ++lit)
    {
      const Box& box = a_fineBoxes[lit()];
      a_periodicVector.push_back(box);
      // if periodic, also need to add periodic images
      // only do this IF we're periodic and box
      // adjacent to  the domain box boundary somewhere
      if (a_fineDomain.isPeriodic()
          && !periodicTestBox.contains(box))
        {
          ShiftIterator shiftIt = a_fineDomain.shiftIterator();
          IntVect shiftMult(a_fineDomain.domainBox().size());
          Box shiftedBox(box);
          for (shiftIt.begin(); shiftIt.ok(); ++shiftIt)
            {
              IntVect shiftVect = shiftMult*shiftIt();
              shiftedBox.shift(shiftVect);
              a_periodicVector.push_back(shiftedBox);
              shiftedBox.shift(-shiftVect);
            } // end loop over periodic shift directions
        } // end if periodic
    }
  a_periodicVector.sort();
}
Example #4
0
void
EBLevelGrid::
defineCoveringIVS()
{
    CH_assert(m_isDefined);
    if (!m_isCoveringIVSDefined)
    {
        m_isCoveringIVSDefined = true;
        //define the covering ivs by first assembling its complement
        const Box& domBox = m_domain.domainBox();
        IntVectSet complementIVS(domBox);
        for (LayoutIterator lit = m_grids.layoutIterator(); lit.ok(); ++lit)
        {
            complementIVS -= m_grids.get(lit());
        }
        m_coveringIVS = IntVectSet(domBox);
        m_coveringIVS -= complementIVS;
    }
}
Example #5
0
// -------------------------------------------------------------
void
Mask::buildMask(BaseFab<int>& a_mask, const ProblemDomain& a_dProblem,
                const BoxLayout& a_grids, const BoxLayout* a_fineGridsPtr,
                int a_nRefFine)
{
  // first set entire box to Physical BC
  a_mask.setVal(maskPhysical);

  // now set all of domain interior to coarse
  Box domainInterior(a_mask.box());
  domainInterior &= a_dProblem;
  a_mask.setVal(maskCoarse,domainInterior,0);

  // now loop over this level's boxes and set them to "copy"
  LayoutIterator lit = a_grids.layoutIterator();

  for (lit.reset(); lit.ok(); ++lit)
    {
      Box intersectBox = a_grids.get(lit());
      intersectBox &= a_mask.box();
      if (!intersectBox.isEmpty())
        {
          a_mask.setVal(maskCopy,intersectBox,0);
        }
    }

  // if finer grids exist, set them to "covered"
  if (a_fineGridsPtr != NULL)
    {
      CH_assert (a_nRefFine > 1);

      LayoutIterator litFine = a_fineGridsPtr->layoutIterator();
      for (litFine.reset(); litFine.ok(); ++litFine)
        {
          Box coarsenedBox(a_fineGridsPtr->get(litFine()));
          coarsenedBox.coarsen(a_nRefFine);
          coarsenedBox &= a_mask.box();
          if (!coarsenedBox.isEmpty())
            {
              a_mask.setVal(maskCovered,coarsenedBox,0);
            }
        }
    }
}
Example #6
0
void
CFStencil::define(
                  const ProblemDomain& a_fineDomain,
                  const Box& a_grid,
                  const DisjointBoxLayout& a_fineBoxes,
                  const DisjointBoxLayout& a_coarBoxes,
                  int a_refRatio,
                  int a_direction,
                  Side::LoHiSide a_hiorlo)
{
  m_isDefined = true;
  CH_assert(a_refRatio >= 1);
  CH_assert(a_direction >= 0);
  CH_assert(a_direction < SpaceDim);
  CH_assert((a_hiorlo == Side::Lo) ||
         (a_hiorlo == Side::Hi));
  CH_assert(!a_fineDomain.isEmpty());

  //set internal vars.  most of these are kept around
  //just to keep the class from having an identity crisis.
  m_direction = a_direction;
  m_hiorlo =  a_hiorlo;

  Box finebox = a_grid;


  //compute intvectset of all points on fine grid that
  //need to be interpolated

  //shift direction
  int hilo = sign(a_hiorlo);

  //create fine stencil
  Box edgebox;
  CH_assert((hilo ==1) || (hilo == -1));
  if (hilo == -1)
    {
      edgebox = adjCellLo(finebox,m_direction,1);
    }
  else
    {
      edgebox = adjCellHi(finebox,m_direction,1);
    }
  edgebox = a_fineDomain & edgebox;
  if (!edgebox.isEmpty())
    {
      Box periodicTestBox(a_fineDomain.domainBox());
      if (a_fineDomain.isPeriodic())
        {
          for (int idir=0; idir<SpaceDim; idir++)
            {
              if (a_fineDomain.isPeriodic(idir))
                {
                  periodicTestBox.grow(idir,-1);
                }
            }
        }

      m_fineIVS.define(edgebox);
      LayoutIterator lit = a_fineBoxes.layoutIterator();
      for (lit.reset(); lit.ok(); ++lit)
        {
          m_fineIVS -= a_fineBoxes[lit()];
          // if periodic, also need to subtract periodic images
          // only do this IF we're periodic _and_ both boxes
          // adjoin the domain box boundary somewhere
          if (a_fineDomain.isPeriodic() && !periodicTestBox.contains(edgebox)
              && !periodicTestBox.contains(a_fineBoxes[lit()]))
            {
              ShiftIterator shiftIt = a_fineDomain.shiftIterator();
              IntVect shiftMult(a_fineDomain.domainBox().size());
              Box shiftedBox(a_fineBoxes[lit()]);
              for (shiftIt.begin(); shiftIt.ok(); ++shiftIt)
                {
                  IntVect shiftVect = shiftMult*shiftIt();
                  shiftedBox.shift(shiftVect);
                  m_fineIVS -= shiftedBox;
                  shiftedBox.shift(-shiftVect);
                } // end loop over periodic shift directions
            } // end if periodic
        }
    }

  //ivs where all coarse slopes are defined
  //== coarsened fine ivs
  m_coarIVS.define(m_fineIVS);
  m_coarIVS.coarsen(a_refRatio);
  // this is a trick to get around the lack of a IntVectSet intersection
  // operator which works with a ProblemDomain
  ProblemDomain coardom= coarsen(a_fineDomain, a_refRatio);
  Box domainIntersectBox = m_coarIVS.minBox();
  domainIntersectBox = coardom & domainIntersectBox;
  m_coarIVS &= domainIntersectBox;

  m_packedBox = m_fineIVS.minBox();
  if (m_fineIVS.numPts() == m_packedBox.numPts())
    {
      m_isPacked = true;
    }
  else
    {
      m_isPacked = false;
      m_packedBox = Box();
    }
}
Example #7
0
int
testIFFAB(const DisjointBoxLayout&              a_dbl,
          const EBISLayout       &              a_ebisl,
          const Box              &              a_domain,
          const Real             &              a_dx )
{
  int faceDir = 0;
  int nFlux = 1;
  LayoutData<IntVectSet>        irregSetsGrown;
  LevelData< BaseIFFAB<Real> > fluxInterpolant;

  EBArith::defineFluxInterpolant(fluxInterpolant,
                                 irregSetsGrown,
                                 a_dbl, a_ebisl, a_domain, nFlux, faceDir);

  //set source fab to right ans over set only on grids interior cells
  int ibox = 0;
  for (DataIterator dit = a_dbl.dataIterator(); dit.ok(); ++dit)
    {
      BaseIFFAB<Real>& srcFab = fluxInterpolant[dit()];
      srcFab.setVal(-1.0);
      IntVectSet ivsSmall = irregSetsGrown[dit()];
      const Box& grid = a_dbl.get(dit());
      ivsSmall &=  grid;
      for (FaceIterator faceit(ivsSmall, a_ebisl[dit()].getEBGraph(), faceDir, FaceStop::SurroundingWithBoundary);
          faceit.ok(); ++faceit)
        {
          srcFab(faceit(), 0) = rightAns(faceit());
        }
      ibox++;
    }

  //diagnostics
  if (g_diagnosticMode)
    {
      pout() << " diagnostics for processor " << procID() << endl;
      for (DataIterator dit = a_dbl.dataIterator(); dit.ok(); ++dit)
        {
          const IntVectSet& ivsGrown = irregSetsGrown[dit()];
          const Box& grid = a_dbl.get(dit());
          pout() << "============" << endl;
          pout() << " box = " << grid;
          pout() << ", full ivs = "  ;
          dumpIVS(&ivsGrown);
          pout() << "============" << endl;
          for (LayoutIterator lit = a_dbl.layoutIterator(); lit.ok(); ++lit)
            {
              const Box& grid2 = a_dbl.get(lit());
              IntVectSet ivsIntersect = ivsGrown;
              ivsIntersect &= grid2;
              pout() << "intersection with box " << grid2 << " = ";
              dumpIVS(&ivsIntersect);
              pout() << "============" << endl;
            }
        }

    }

  BaseIFFAB<Real>::setVerbose(true);
  //do the evil exchange
  Interval interv(0, nFlux-1);
  fluxInterpolant.exchange(interv);
  ibox = 0;
  //check the answer over grown set
  Real tolerance = 0.001;
  for (DataIterator dit = a_dbl.dataIterator(); dit.ok(); ++dit)
    {
      const BaseIFFAB<Real>& srcFab = fluxInterpolant[dit()];
      const IntVectSet& ivsGrown = irregSetsGrown[dit()];
      for (FaceIterator faceit(ivsGrown, a_ebisl[dit()].getEBGraph(), faceDir, FaceStop::SurroundingWithBoundary);
          faceit.ok(); ++faceit)
        {
          Real correct = rightAns(faceit());
          Real fabAns  =   srcFab(faceit(), 0);
          if (Abs(correct - fabAns)  > tolerance)
            {
              pout() << "iffab test failed at face "
                     << faceit().gridIndex(Side::Lo)
                     << faceit().gridIndex(Side::Hi) << endl;
              pout() << " right ans = " << correct  << endl;
              pout() << " data holds= " << fabAns << endl;

              int eekflag = -3;
              return eekflag;
            }

        }
      ibox++;
    }
  return 0;
}
void
MappedLevelFluxRegister::define(const DisjointBoxLayout& a_dbl,
                          const DisjointBoxLayout& a_dblCoarse,
                          const ProblemDomain&     a_dProblem,
                          const IntVect&           a_nRefine,
                          int                      a_nComp,
                          bool                     a_scaleFineFluxes)
{
    CH_TIME("MappedLevelFluxRegister::define");
    m_isDefined = FluxRegDefined;  // Basically, define was called
    m_nRefine   = a_nRefine;

    m_scaleFineFluxes = a_scaleFineFluxes;

    DisjointBoxLayout coarsenedFine;
    coarsen(coarsenedFine, a_dbl, a_nRefine);

#ifndef DISABLE_TEMPORARY_FLUX_REGISTER_OPTIMIZATION
    // This doesn't work for multi-block calculations, which are
    // not properly nested. -JNJ

    //begin temporary optimization.  bvs
    int numPts = 0;
    for (LayoutIterator lit = a_dblCoarse.layoutIterator(); lit.ok(); ++lit) {
        numPts += a_dblCoarse[lit].numPts();
    }
    for (LayoutIterator lit = coarsenedFine.layoutIterator(); lit.ok(); ++lit) {
        numPts -= coarsenedFine[lit].numPts();
    }

    if (numPts == 0) {
        m_coarFlux.clear();
        // OK, fine region completely covers coarse region.  no registers.
        return;
    }
#endif

    //end temporary optimization.   bvs
    m_coarFlux.define( a_dblCoarse, a_nComp);
    m_isDefined |= FluxRegCoarseDefined;
    m_domain = a_dProblem;
    ProblemDomain coarsenedDomain;
    coarsen(coarsenedDomain, a_dProblem, a_nRefine);

    m_fineFlux.define( coarsenedFine, a_nComp, IntVect::Unit);
    m_isDefined |= FluxRegFineDefined;

    m_reverseCopier.ghostDefine(coarsenedFine, a_dblCoarse,
                                coarsenedDomain, IntVect::Unit);

    for (int i = 0; i < CH_SPACEDIM; i++) {
        m_coarseLocations[i].define(a_dblCoarse);
        m_coarseLocations[i + CH_SPACEDIM].define(a_dblCoarse);
    }


    DataIterator dC   = a_dblCoarse.dataIterator();
    LayoutIterator dF = coarsenedFine.layoutIterator();

    for (dC.begin(); dC.ok(); ++dC) {
        const Box& cBox = a_dblCoarse.get(dC);

        for (dF.begin(); dF.ok(); ++dF) {
            const Box& fBox  = coarsenedFine.get(dF);

            if (fBox.bigEnd(0) + 1 < cBox.smallEnd(0)) {
                //can skip this box since they cannot intersect, due to sorting
            } else if (fBox.smallEnd(0) - 1 > cBox.bigEnd(0)) {
                //skip to end, since all the rest of boxes will not intersect either
                dF.end();
            } else {

                for (int i = 0; i < CH_SPACEDIM; i++) {
                    Vector<Box>& lo = m_coarseLocations[i][dC];
                    Vector<Box>& hi = m_coarseLocations[i + CH_SPACEDIM][dC];

                    Box loBox = adjCellLo(fBox, i, 1);
                    Box hiBox = adjCellHi(fBox, i, 1);
                    if (cBox.intersectsNotEmpty(loBox)) lo.push_back(loBox & cBox);
                    if (cBox.intersectsNotEmpty(hiBox)) hi.push_back(hiBox & cBox);
                }
            }
        }
    }

    Box domainBox = coarsenedDomain.domainBox();

    if (a_dProblem.isPeriodic()) {
        Vector<Box> periodicBoxes[2 * CH_SPACEDIM];
        for (dF.begin(); dF.ok(); ++dF) {
            const Box& fBox  = coarsenedFine.get(dF);
            for (int i = 0; i < CH_SPACEDIM; i++) {
                if (a_dProblem.isPeriodic(i)) {
                    if (fBox.smallEnd(i) == domainBox.smallEnd(i))
                        periodicBoxes[i].push_back(adjCellLo(fBox, i, 1));
                    if (fBox.bigEnd(i) == domainBox.bigEnd(i))
                        periodicBoxes[i + CH_SPACEDIM].push_back(adjCellHi(fBox, i, 1));
                }
            }
        }
        for (int i = 0; i < CH_SPACEDIM; i++) {
            Vector<Box>& loV = periodicBoxes[i];
            Vector<Box>& hiV = periodicBoxes[i + CH_SPACEDIM];
            int size = domainBox.size(i);
            for (int j = 0; j < loV.size(); j++) loV[j].shift(i, size);
            for (int j = 0; j < hiV.size(); j++) hiV[j].shift(i, -size);
        }
        for (dC.begin(); dC.ok(); ++dC) {
            const Box& cBox = a_dblCoarse.get(dC);
            for (int i = 0; i < CH_SPACEDIM; i++)
                if (a_dProblem.isPeriodic(i)) {
                    Vector<Box>& loV = periodicBoxes[i];
                    Vector<Box>& hiV = periodicBoxes[i + CH_SPACEDIM];

                    if (cBox.smallEnd(i) == domainBox.smallEnd(i) ) {
                        Vector<Box>& hi = m_coarseLocations[i + CH_SPACEDIM][dC];
                        for (int j = 0; j < hiV.size(); j++) {
                            if (cBox.intersectsNotEmpty(hiV[j])) hi.push_back(cBox & hiV[j]);
                        }
                    }
                    if (cBox.bigEnd(i) == domainBox.bigEnd(i) ) {
                        Vector<Box>& lo = m_coarseLocations[i][dC];
                        for (int j = 0; j < loV.size(); j++) {
                            if (cBox.intersectsNotEmpty(loV[j])) lo.push_back(cBox & loV[j]);
                        }
                    }

                }
        }
    }

}
Example #9
0
// this function works on two solutions on equivalent grids.
// It subtracts the computed solution from the exact solution
// if a_doGhostCells == true, then does box-by-box comparison,
// including ghost cells (boxes must be the same for each).
// Otherwise, only does this for valid cells, but boxes don't
// need to be the same.
void computeSameSizeError(Vector<LevelData<FArrayBox>* >&       a_error,
                          const Vector<string>&                 a_errorVars,
                          const Vector<LevelData<FArrayBox>* >& a_computedSoln,
                          const Vector<string>&                 a_computedVars,
                          const Vector<DisjointBoxLayout>&      a_computedGrids,
                          const Real                            a_dx,
                          const Vector<int>&                    a_refRatio,
                          const Vector<LevelData<FArrayBox>* >& a_exactSoln,
                          const Vector<string>&                 a_exactVars,
                          Real                                  a_bogus_value,
                          bool                                  a_computeRelativeError,
                          bool                                  a_doGhostCells)

{
  int numLevels = a_computedSoln.size();

  CH_assert(a_exactSoln.size() == numLevels);
  CH_assert(a_error.size() == numLevels);
  CH_assert(a_refRatio.size() >= numLevels - 1);

  Real dxLevel = a_dx;

  // outer loop is over levels
  for (int level = 0; level < numLevels; level++)
  {
    LevelData<FArrayBox>& thisLevelError = *a_error[level];
    LevelData<FArrayBox>& thisLevelComputed = *a_computedSoln[level];
    LevelData<FArrayBox>& thisLevelExact = *a_exactSoln[level];

    const DisjointBoxLayout levelGrids = thisLevelComputed.getBoxes();
    const DisjointBoxLayout exactGrids = thisLevelExact.getBoxes();

    DataIterator levelDit = levelGrids.dataIterator();
    for (levelDit.begin(); levelDit.ok(); ++levelDit)
    {
      // initialize error to a bogus value
      thisLevelError[levelDit()].setVal(a_bogus_value);
    }

    // loop over variables
    for (int nErr = 0; nErr < a_errorVars.size(); nErr++)
    {
      string thisErrVar = a_errorVars[nErr];
      bool done = false;

      // this is where things differ between the ghost-cell
      // and non-ghost-cell approach.
      if (a_doGhostCells)
      {
        // this is the older approach to things --
        // do everything grid-by-grid

        // first loop over exact variables
        for (int exactComp = 0; exactComp < a_exactVars.size(); exactComp++)
        {
          string thisExactVar = a_exactVars[exactComp];
          // check if this exact variable is "the one"
          if (thisExactVar == thisErrVar)
          {
            int computedComp = 0;

            // now loop over computed variables
            while (!done && (computedComp < a_computedVars.size()))
            {
              if (a_computedVars[computedComp] == thisErrVar)
              {
                // copy exact solution -> error
                // and then subtract computed solution
                DataIterator exactDit = thisLevelExact.dataIterator();
                for (levelDit.reset(); levelDit.ok(); ++levelDit)
                {
                  FArrayBox& thisComputed = thisLevelComputed[levelDit()];
                  FArrayBox& thisError = thisLevelError[levelDit()];
                  const Box& thisBox = levelGrids[levelDit()];

                  for (exactDit.begin(); exactDit.ok(); ++exactDit)
                  {
                    if (thisBox.contains(exactGrids[exactDit()]))
                    {
                      thisError.copy(thisLevelExact[exactDit()],
                                     exactComp, nErr, 1);
                    } // end if exact and computed boxes match
                  } // end loop over exact grids

                  if (a_computeRelativeError)
                  {
                    // do this a little strangely -- relative
                    // error is one - computed/exact.
                    thisError.divide(thisComputed, computedComp, nErr, 1);
                    thisError.invert(-1.0, nErr, 1);
                    thisError.plus(1.0, nErr, 1);
                  }
                  else
                  {
                    thisError.minus(thisComputed, computedComp, nErr, 1);
                  }
                } // end loop over grids

                done = true;
              } // if a_computedVar is a_errorVar

              computedComp += 1;
            } // end loop over a_computedVars

            if (!done)
            {
              pout() << "Variable " << thisErrVar  << " not found!!!" << endl;
              MayDay::Error();
            }
          } // end if this exactVar is correct
        }  // end loop over exact variables
      }
      else
        // non-ghost cell case; this is simpler:
      {
        // first loop over exact variables and copy into error
        for (int exactComp=0; exactComp<a_exactVars.size(); ++exactComp)
        {
          string thisExactVar = a_exactVars[exactComp];

          // check if this exact variable is "the one"
          if (thisExactVar == thisErrVar)
          {
            // copy exact solution -> error
            Interval exactInterval(exactComp, exactComp);
            Interval errInterval(nErr, nErr);
            thisLevelExact.copyTo(exactInterval,
                                  thisLevelError,
                                  errInterval);
            done = true;
          } // end if this exact var is the error var
        } // end loop over exact comps

        if (!done)
        {
          pout() << "Variable " << thisErrVar
                 << " not found in exact solution!!!" << endl;
          MayDay::Error();
        }

        done = false;
        int computedComp = 0;
        // now loop over computed variables and subtract computed solution
        while (!done && (computedComp < a_computedVars.size()))
        {
          if (a_computedVars[computedComp] == thisErrVar)
          {
            for (levelDit.reset(); levelDit.ok(); ++levelDit)
            {
              FArrayBox& thisComputed = thisLevelComputed[levelDit()];
              FArrayBox& thisError = thisLevelError[levelDit()];

              thisError.minus(thisComputed, computedComp, nErr, 1);
            } // end loop over computed/error grids

            done = true;
          } // if a_computedVar is a_errorVar

          computedComp += 1;
        } // end loop over a_computedVars

        if (!done)
        {
          pout() << "Variable " << thisErrVar  << " not found!!!" << endl;
          MayDay::Error();
        }
      } // end non-ghost-cell case
    } // end loop over errors

    // now need to set covered regions to 0
    if (level < numLevels - 1)
    {
      // will need to loop over all boxes in finer level, not just
      // those on this processor...
      const BoxLayout& finerGrids = a_computedSoln[level + 1]->boxLayout();
      LayoutIterator fineLit = finerGrids.layoutIterator();

      // outer loop over this level's grids, since there are fewer of them
      DataIterator levelDit = thisLevelError.dataIterator();
      for (levelDit.reset(); levelDit.ok(); ++levelDit)
      {
        const Box& coarseBox = levelGrids[levelDit()];
        FArrayBox& thisError = thisLevelError[levelDit()];
        int numError = thisError.nComp();

        for (fineLit.reset(); fineLit.ok(); ++fineLit)
        {
          Box fineBox(finerGrids[fineLit()]);
          // now coarsen box down to this level
          fineBox.coarsen(a_refRatio[level]);
          // if coarsened fine box intersects error's box, set
          // overlap to 0
          fineBox &= coarseBox;
          if (!fineBox.isEmpty())
          {
            thisError.setVal(0.0, fineBox, 0, numError);
          }
        } // end loop over finer-level grids
      } // end loop over this-level grids

      // this is a good place to update dx as well
      dxLevel = dxLevel / a_refRatio[level];
    } // end if there is a finer level

    // finally, if we're not doing ghost cells, do an exchange just
    // to "prettify" the output
    if (!a_doGhostCells)
    {
      thisLevelError.exchange(thisLevelError.interval());
    }
  } // end loop over levels
}
Example #10
0
// this function averages down the fine solution to the valid
// regions of the computed solution, then subtracts ir from
// the computed solution.  (error is exact-computed)
void computeAMRError(Vector<LevelData<FArrayBox>* >&       a_error,
                     const Vector<string>&                 a_errorVars,
                     const Vector<LevelData<FArrayBox>* >& a_computedSoln,
                     const Vector<string>&                 a_computedVars,
                     const Vector<DisjointBoxLayout>&      a_computedGrids,
                     const Real                            a_computedDx,
                     const Vector<int>&                    a_computedRefRatio,
                     const Vector<LevelData<FArrayBox>* >& a_exactSoln,
                     const Vector<string>&                 a_exactVars,
                     const Real                            a_exactDx,
                     Real                                  a_bogus_value,
                     bool                                  a_HOaverage,
                     bool                                  a_computeRelativeError)
{
  int numLevels = a_computedSoln.size();

  CH_assert(a_exactSoln.size() == 1);
  CH_assert(a_error.size() == numLevels);
  CH_assert(a_exactDx <= a_computedDx);
  CH_assert(a_computedRefRatio.size() >= numLevels - 1);

  if (a_exactDx == a_computedDx)
  {
    cerr << "Exact dx and computed dx are equal." << endl;
  }

  // check whether input file selects "sum all variables"
  bool sumAll = false;
  ParmParse pp;
  pp.query("sumAll",sumAll);
  
  // const DisjointBoxLayout& exactGrids = a_exactSoln[0]->getBoxes();

  Real dxLevel = a_computedDx;

  // do a bit of sleight-of-hand in the case where there are no
  // ghost cells in the exact solution -- allocate a temporary which
  // _has_ ghost cells, and do a copyTo
  LevelData<FArrayBox>* exactSolnPtr = NULL;
  bool allocatedMemory = false;
  if (a_exactSoln[0]->ghostVect() == IntVect::Zero)
    {
      exactSolnPtr = new LevelData<FArrayBox>(a_exactSoln[0]->getBoxes(),
                                              a_exactSoln[0]->nComp(),
                                              IntVect::Unit);
      a_exactSoln[0]->copyTo(*exactSolnPtr);

      allocatedMemory = true;
     }
   else
     {
       // if there are ghost cells, we can use the exactSoln as-is
       exactSolnPtr = a_exactSoln[0];
     }
   LevelData<FArrayBox>& exactSolnRef = *exactSolnPtr;

   // first need to set boundary conditions on exactsoln
   // this is for the Laplacian which is needed in AverageHO
   DataIterator ditFine = exactSolnRef.dataIterator();
   DomainGhostBC exactBC;
   Interval exactComps(0, a_exactVars.size() - 1);
   for (int dir = 0; dir < SpaceDim; dir++)
   {
     SideIterator sit;
     for (sit.reset(); sit.ok(); ++sit)
     {
       // use HO extrapolation at physical boundaries
       HOExtrapBC thisBC(dir, sit(), exactComps);
       exactBC.setBoxGhostBC(thisBC);
     }
   }

   for (ditFine.begin(); ditFine.ok(); ++ditFine)
   {
     FArrayBox& thisFineSoln = exactSolnRef[ditFine()];
     const Box& fineBox = exactSolnRef.getBoxes()[ditFine()];
     exactBC.applyInhomogeneousBCs(thisFineSoln, fineBox, a_exactDx);
   }
   exactSolnRef.exchange(exactComps);

   // outer loop is over levels
   for (int level = 0; level < numLevels; level++)
   {
     LevelData<FArrayBox>& thisLevelError = *a_error[level];
     LevelData<FArrayBox>& thisLevelComputed = *a_computedSoln[level];

     // compute refinement ratio between solution at this level
     // and exact solution
     Real nRefTemp = (dxLevel / a_exactDx);
     int nRefExact = (int) nRefTemp;

     // this is to do rounding properly if necessary
     if (nRefTemp - nRefExact > 0.5) nRefExact += 1;

     // make sure it's not zero
     if (nRefExact == 0) nRefExact =1;

     const DisjointBoxLayout levelGrids = a_error[level]->getBoxes();
     const DisjointBoxLayout fineGrids = a_exactSoln[0]->getBoxes();
     DisjointBoxLayout coarsenedFineGrids;

     // petermc, 14 Jan 2014: Replace this because fineGrids might
     // not be coarsenable by nRefExact.
     // coarsen(coarsenedFineGrids, fineGrids, nRefExact);
     int nCoarsenExact = nRefExact;
     while ( !fineGrids.coarsenable(nCoarsenExact) && (nCoarsenExact > 0) )
       {
         // Divide nCoarsenExact by 2 until fineGrids is coarsenable by it.
         nCoarsenExact /= 2;
       }
     if (nCoarsenExact == 0)
       {
         nCoarsenExact = 1;
       }
     coarsen(coarsenedFineGrids, fineGrids, nCoarsenExact);

     int numExact = a_exactVars.size();
     LevelData<FArrayBox> averagedExact(coarsenedFineGrids, numExact);

     Box fineRefBox(IntVect::Zero, (nCoarsenExact-1)*IntVect::Unit);

     // average fine solution down to coarsened-fine level
     // loop over grids and do HO averaging down
     //DataIterator crseExactDit = coarsenedFineGrids.dataIterator();
     for (ditFine.reset(); ditFine.ok(); ++ditFine)
       {
         const Box fineBox = exactSolnRef.getBoxes()[ditFine()];
         FArrayBox fineTemp(fineBox, 1);
         Box coarsenedFineBox(fineBox);
         coarsenedFineBox.coarsen(nCoarsenExact);
         if (a_exactDx < a_computedDx)
           {
             // loop over components
             for (int comp = 0; comp < numExact; comp++)
               {
                 Box coarseBox(coarsenedFineGrids.get(ditFine()));
                 coarseBox &= coarsenedFineBox;
                 
                 if (!coarseBox.isEmpty())
                   {
                     // for now, this is a quick and dirty way to avoid
                     // stepping out of bounds if there are no ghost cells.
                     // LapBox will be the box over which we are
                     // able to compute the Laplacian.
                     Box LapBox = exactSolnRef[ditFine()].box();
                     LapBox.grow(-1);
                     LapBox &= fineBox;
                     fineTemp.setVal(0.0);
                     int doHO = 0;
                     if (a_HOaverage)
                       { 
                         doHO = 1;
                       }
                     
                     // average by default
                     int doAverage = 1;
                     
                     if (sumAll || sumVar(a_exactVars[comp]))
                       {
                         doAverage = 0;
                       }
                     
                     // average or sum, based on booleans
                     FORT_AVERAGEHO(CHF_FRA1(averagedExact[ditFine], comp),
                                    CHF_CONST_FRA1(exactSolnRef[ditFine], comp),
                                    CHF_FRA1(fineTemp, 0),
                                    CHF_BOX(coarseBox),
                                    CHF_BOX(LapBox),
                                    CHF_CONST_INT(nCoarsenExact),
                                    CHF_BOX(fineRefBox),
                                    CHF_INT(doHO),
                                    CHF_INT(doAverage));
                   } // end if crseBox not empty
               } // end loop over comps
           }
         else
           {
             // if cell sizes are the same, then copy
             averagedExact[ditFine].copy(exactSolnRef[ditFine]);
           }
         
       } // end loop over exact solution boxes
     
     int nRefineComputed = nRefExact / nCoarsenExact;
     LevelData<FArrayBox>* thisLevelComputedRefinedPtr = &thisLevelComputed;
     LevelData<FArrayBox>* thisLevelErrorRefinedPtr = &thisLevelError;
     if (nRefineComputed > 1)
       {
         // Do piecewise constant interpolation (replication) by nRefineComputed
         // on thisLevelComputed.
         DisjointBoxLayout levelRefinedGrids;
         refine(levelRefinedGrids, levelGrids, nRefineComputed);
         int nCompComputed = thisLevelComputed.nComp();
         IntVect ghostVectComputed = nRefineComputed * thisLevelComputed.ghostVect();
         thisLevelComputedRefinedPtr =
           new LevelData<FArrayBox>(levelRefinedGrids, nCompComputed, ghostVectComputed);
         ProblemDomain levelDomain = levelRefinedGrids.physDomain();
         FineInterp interpolator(levelRefinedGrids, nCompComputed, nRefineComputed,
                                 levelDomain);
         interpolator.pwcinterpToFine(*thisLevelComputedRefinedPtr, thisLevelComputed);

         int nCompErr = thisLevelError.nComp();
         IntVect ghostVectErr = nRefineComputed * thisLevelError.ghostVect();
         thisLevelErrorRefinedPtr =
           new LevelData<FArrayBox>(levelRefinedGrids, nCompErr, ghostVectErr);
       }

     // initialize error to 0
     // also initialize error to a bogus value
     DataIterator levelDit = thisLevelError.dataIterator();
     for (levelDit.begin(); levelDit.ok(); ++levelDit)
       {
         (*thisLevelErrorRefinedPtr)[levelDit].setVal(a_bogus_value);
       }

     Box refComputedBox(IntVect::Zero, (nRefineComputed-1)*IntVect::Unit);
     // loop over variables
     for (int nErr = 0; nErr < a_errorVars.size(); nErr++)
       {
         string thisErrVar = a_errorVars[nErr];
         bool done = false;

         // first loop over exact variables
         for (int exactComp = 0; exactComp < a_exactVars.size(); exactComp++)
           {
             string thisExactVar = a_exactVars[exactComp];
             // check if this exact variable is "the one"
             if ((thisExactVar == thisErrVar) || nonAverageVar(thisErrVar))
               {
                 int computedComp = 0;
                 // now loop over computed variables
                 while (!done && (computedComp < a_computedVars.size()))
                   {
                     if (a_computedVars[computedComp] == thisErrVar)
                       {
                         if (!nonAverageVar(thisErrVar))
                           {
                             // copy averaged exact solution -> error
                             // and then subtract computed solution
                             Interval exactInterval(exactComp, exactComp);
                             Interval errorInterval(nErr, nErr);
                             averagedExact.copyTo(exactInterval, *thisLevelErrorRefinedPtr,
                                                  errorInterval);
                           }
                         
                         DataIterator levelDit = thisLevelError.dataIterator();
                         for (levelDit.reset(); levelDit.ok(); ++levelDit)
                           {
                             FArrayBox& thisComputedRefined = (*thisLevelComputedRefinedPtr)[levelDit];
                             FArrayBox& thisErrorRefined = (*thisLevelErrorRefinedPtr)[levelDit];
                             if (a_computeRelativeError)
                               {
                                 // do this a little strangely -- relative
                                 // error is one - computed/exact.
                                 thisErrorRefined.divide(thisComputedRefined, computedComp, nErr, 1);
                                 thisErrorRefined.invert(-1.0, nErr, 1);
                                 thisErrorRefined.plus(1.0, nErr, 1);
                               }
                             else
                               {
                                 thisErrorRefined.minus(thisComputedRefined, computedComp, nErr, 1);
                               }
                             if (nRefineComputed > 1)
                               {
                                 FArrayBox& thisError = thisLevelError[levelDit];
                                 Box coarseBox = thisError.box();
                                 // Average thisErrorRefined to thisError.
                                 int doHO = 0;
                                 if (a_HOaverage)
                                   { 
                                     doHO = 1;
                                   }
                                 CH_assert(doHO == 0);

                                 // for now, this is a quick and dirty way to avoid
                                 // stepping out of bounds if there are no ghost cells.
                                 // LapBox will be the box over which we are
                                 // able to compute the Laplacian.
                                 Box LapBox = thisErrorRefined.box();
                                 LapBox.grow(-1);
                                 // LapBox &= fineBox;
                                 FArrayBox fineTemp(thisErrorRefined.box(), 1);
                                 fineTemp.setVal(0.0);
                                 
                                 // average by default
                                 int doAverage = 1;
                                 // average or sum, based on booleans
                                 FORT_AVERAGEHO(CHF_FRA1(thisError, nErr),
                                                CHF_CONST_FRA1(thisErrorRefined, nErr),
                                                CHF_FRA1(fineTemp, 0),
                                                CHF_BOX(coarseBox),
                                                CHF_BOX(LapBox),
                                                CHF_CONST_INT(nRefineComputed),
                                                CHF_BOX(refComputedBox),
                                                CHF_INT(doHO),
                                                CHF_INT(doAverage));
                                 
                               }
                           } // end loop over coarse grids
                         
                         done = true;
                       } // if computedVar is a_errorVar
                     
                     computedComp += 1;
                   } // end loop over a_computedVars
                 
                 if (!done)
                   {
                     pout() << "Variable " << thisErrVar  << " not found!!!" << endl;
                     MayDay::Error();
                   }
               } // end if this exactVar is correct
           } // end loop over exact variables
       } // end loop over errors
     
     if (nRefineComputed > 1)
       {
         delete thisLevelComputedRefinedPtr;
         delete thisLevelErrorRefinedPtr;
       }
     
     // now need to set covered regions to 0
     if (level < numLevels - 1)
       {
         // will need to loop over all boxes in finer level, not just
         // those on this processor...
         const BoxLayout& finerGrids = a_computedSoln[level + 1]->boxLayout();
         LayoutIterator fineLit = finerGrids.layoutIterator();
         
         // outer loop over this level's grids, since there are fewer of them
         DataIterator levelDit = thisLevelError.dataIterator();
         for (levelDit.reset(); levelDit.ok(); ++levelDit)
           {
             const Box& coarseBox = levelGrids[levelDit()];
             FArrayBox& thisError = thisLevelError[levelDit()];
             int numError = thisError.nComp();
             
             for (fineLit.reset(); fineLit.ok(); ++fineLit)
               {
                 Box fineBox(finerGrids[fineLit()]);
                 // now coarsen box down to this level
                 fineBox.coarsen(a_computedRefRatio[level]);
                 // if coarsened fine box intersects error's box, set
                 // overlap to 0
                 fineBox &= coarseBox;
                 if (!fineBox.isEmpty())
                   {
                     thisError.setVal(0.0, fineBox, 0, numError);
                   }
               } // end loop over finer-level grids
           } // end loop over this-level grids
         
         // this is a good place to update dx as well
         dxLevel = dxLevel / a_computedRefRatio[level];
       } // end if there is a finer level
     
     thisLevelError.exchange();
   } // end loop over levels
   
   // clean up if we need to
   if (allocatedMemory)
     {
       delete exactSolnPtr;
       exactSolnPtr = NULL;
     }
}
Example #11
0
void
EBCoarToFineRedist::
define(const DisjointBoxLayout& a_dblFine,
       const DisjointBoxLayout& a_dblCoar,
       const EBISLayout& a_ebislFine,
       const EBISLayout& a_ebislCoar,
       const Box& a_domainCoar,
       const int& a_nref,
       const int& a_nvar,
       int a_redistRad,
       const EBIndexSpace* ebisPtr)
{
  CH_TIME("EBCoarToFineRedist::define");
  m_isDefined = true;
  m_nComp = a_nvar;
  m_refRat = a_nref;
  m_domainCoar = a_domainCoar;
  m_gridsFine = a_dblFine;
  m_gridsCoar = a_dblCoar;
  m_ebislFine = a_ebislFine;
  m_ebislCoar = a_ebislCoar;
  m_redistRad = a_redistRad;

  //created the coarsened fine layout
  m_gridsCedFine = DisjointBoxLayout();
  coarsen(m_gridsCedFine, m_gridsFine, m_refRat);

  CH_assert(ebisPtr->isDefined());
  int nghost = 3*m_redistRad;
  ebisPtr->fillEBISLayout(m_ebislCedFine, m_gridsCedFine,
                          m_domainCoar, nghost);
  m_ebislCedFine.setMaxRefinementRatio(m_refRat, ebisPtr);

  //define the intvectsets over which the objects live
  m_setsCoar.define(m_gridsCoar);
  m_setsCedFine.define(m_gridsCedFine);
  //the buffers for the fine level are really simple.
  //grow the coarsened fine grid by the redist radius
  //and subtract off the coarsened fine grids.
  //intersect with the irregular cells.
  //this way get irregular cells range of this grid on coarse
  //grid.
  {
    CH_TIME("coarsened_fine_sets");
    for (DataIterator dit = m_gridsCedFine.dataIterator();
        dit.ok(); ++dit)
      {
        Box grownBox = grow(m_gridsCedFine.get(dit()), m_redistRad);
        grownBox &= m_domainCoar;
        IntVectSet localIVS = m_ebislCedFine[dit()].getIrregIVS(grownBox);
        //subtract off all boxes on fine level so we get stuff at the
        //coarse-fine interface that will redistribute to this grid
        for (LayoutIterator lit = m_gridsCedFine.layoutIterator();
            lit.ok(); ++lit)
          {
            localIVS -= m_gridsCedFine.get(lit());
          }
        m_setsCedFine[dit()] = localIVS;
      }
  }
  //the coarse buffers are more complicated.
  //Need to intersect irregular cells on this grid
  // with entire coarse/fine interface of width redist radius
  {
    CH_TIME("coarse_sets");
    for (DataIterator dit = m_gridsCoar.dataIterator();
        dit.ok(); ++dit)
      {
        Box coarBox = m_gridsCoar.get(dit());
        //make the complement set the whole
        IntVectSet cfIntComp(coarBox);
        //subtract the CF Interface from each coarsened fine box
        //from the complement
        for (LayoutIterator lit1 = m_gridsCedFine.layoutIterator();
            lit1.ok(); ++lit1)
          {
            Box grownBox = grow(m_gridsCedFine.get(lit1()), m_redistRad);
            grownBox &= m_domainCoar;
            IntVectSet cedCFIVS(grownBox);
            //subtract off all boxes on fine level so we get stuff at the
            //coarse-fine interface that will redistribute to this grid
            for (LayoutIterator lit2 = m_gridsCedFine.layoutIterator();
                lit2.ok(); ++lit2)
              {
                cedCFIVS -= m_gridsCedFine.get(lit2());
              }

            cfIntComp -=cedCFIVS;
          }
        //coarse fine interface is whole box - complement
        IntVectSet cfInterface(coarBox);
        cfInterface -= cfIntComp;

        IntVectSet localIVS = m_ebislCoar[dit()].getIrregIVS(coarBox);
        //intersect with fat coarse-fine interface
        localIVS &= cfInterface;
        m_setsCoar[dit()] = localIVS;
      }
  }

  //define the registers and all that
  defineDataHolders();

  //initialize the buffers to zero
  setToZero();
}
void
EBLevelTransport::
define(const DisjointBoxLayout&           a_thisDBL,
       const DisjointBoxLayout&           a_coarDBL,
       const EBISLayout&                  a_thisEBISL,
       const EBISLayout&                  a_coarEBISL,
       const ProblemDomain&               a_domain,
       const int&                         a_nRefine,
       const RealVect&                    a_dx,
       const bool&                        a_hasCoarser,
       const bool&                        a_hasFiner,
       RefCountedPtr<EBPatchTransport>&     a_patchGodunov,
       const EBIndexSpace*          const a_eb)
{
  CH_TIME("EBLevelTransport::define");
  CH_assert(a_dx[0] > 0.0);
  CH_assert(a_nRefine > 0);

  m_ebPatchGodunov = a_patchGodunov;

  m_isDefined = true;
  m_thisGrids    = a_thisDBL;
  m_thisEBISL    = a_thisEBISL;
  m_refRatCrse   = a_nRefine;
  m_dx           = a_dx;
  m_domain       = a_domain;
  m_hasCoarser   = a_hasCoarser;
  m_hasFiner     = a_hasFiner;
  if (m_hasCoarser)
    {
      m_coarGrids = a_coarDBL;
      m_coarEBISL = a_coarEBISL;
    }

  m_nVar         =  m_ebPatchGodunov->numPrimitives();
  m_nPrim        =  m_ebPatchGodunov->numPrimitives();
  m_nCons        =  m_ebPatchGodunov->numConserved();
  m_nFlux        =  m_ebPatchGodunov->numFluxes();

  m_irregSetsSmall.define(m_thisGrids);
  for(DataIterator dit = m_thisGrids.dataIterator();
      dit.ok(); ++dit)
    {
      const EBISBox& ebisBox = m_thisEBISL[dit()];
      if(!ebisBox.isAllCovered())
        {
          const Box&     thisBox = m_thisGrids.get(dit());
          m_irregSetsSmall[dit()] = ebisBox.getIrregIVS(thisBox);

        }
    }

  m_cfIVS.define(m_thisGrids); 
  for(DataIterator ditOuter = m_thisGrids.dataIterator();
      ditOuter.ok(); ++ditOuter)
    {
      const EBISBox& ebisBox = m_thisEBISL[ditOuter()];
      if(!ebisBox.isAllCovered())
        {
          // make a grown box of the grid and then subtract off each grid in the
          //domain to make the coarse-fine IVS
          // CFIVS = grow(b, 1) - sum(bi)
          Box grownBox = grow(m_thisGrids.get(ditOuter()), 1);
          grownBox &= m_domain;
          IntVectSet complementIVS(grownBox);

          for(LayoutIterator litInner = m_thisGrids.layoutIterator();
              litInner.ok(); ++litInner)
            {
              Box innerBox = m_thisGrids.get(litInner());
              complementIVS -= innerBox;
            }

          m_cfIVS[ditOuter()] = complementIVS;
        }
    }

  m_nGhost = a_thisEBISL.getGhost();

  if (m_hasCoarser)
    {
      CH_TIME("EBLevelTransport::define::fillPatchDefine");
      ProblemDomain domainCrse = coarsen(m_domain, m_refRatCrse);

      //patcher is defined with the number of conserved vars.
      m_fillPatch.define(m_thisGrids, m_coarGrids,
                         m_thisEBISL, m_coarEBISL,
                         domainCrse, m_refRatCrse, m_nVar,
                         m_nGhost, a_eb);

      m_fillPatchVel.define(m_thisGrids, m_coarGrids,
                            m_thisEBISL, m_coarEBISL,
                            domainCrse, m_refRatCrse, SpaceDim,
                            m_nGhost, a_eb);

    }

  m_irregSetsSmall.define(m_thisGrids);
  for(DataIterator dit = m_thisGrids.dataIterator();
      dit.ok(); ++dit)
    {
      const EBISBox& ebisBox = m_thisEBISL[dit()];
      if(!ebisBox.isAllCovered())
        {
          const Box&     thisBox = m_thisGrids.get(dit());
          m_irregSetsSmall[dit()] = ebisBox.getIrregIVS(thisBox);

        }
    }
  for(int faceDir = 0; faceDir < SpaceDim; faceDir++)
    {
      EBArith::defineFluxInterpolant(m_fluxInterpolants[faceDir],
                                     m_irregSetsGrown  [faceDir],
                                     m_thisGrids, m_thisEBISL,
                                     m_domain, m_nFlux, faceDir);
    }

  BaseIVFactory<Real> cellFactorySmall(m_thisEBISL, m_irregSetsSmall);
  m_nonConsDivergence.define(m_thisGrids, m_nCons,
                             IntVect::Zero, cellFactorySmall);
  m_ebIrregFaceFlux.define(m_thisGrids, m_nFlux,
                           IntVect::Zero, cellFactorySmall);

 //create temp data with the correct number of ghost cells
  IntVect ivGhost = m_nGhost*IntVect::Unit;
  EBCellFactory factory(m_thisEBISL);
  IntVect flatGhostIV = 3*IntVect::Unit;
  m_flattening.define(m_thisGrids, 1, flatGhostIV, factory); 
}
Example #13
0
PetscErrorCode setupGrids( Vector<int> &a_refratios,  // out
                           Vector<ProblemDomain> &a_domains, // out
                           Vector<DisjointBoxLayout> &a_grids, // in/out
                           int a_nLevs,
                           Real &a_cdx, // out
                           Vector<RefCountedPtr<LevelData<FArrayBox> > > a_exact,
                           Vector<RefCountedPtr<LevelData<FArrayBox> > > a_phi,
                           Real a_max_norm_error,
                           Vector<IntVectSet> &a_tagVects,
                           bool &a_same // out
                           )
{
  CH_TIME("setupGrids");
  const int new_level=a_nLevs-1;
  bool isperiodic[3] = {false,false,false};
  PetscFunctionBeginUser;

  a_cdx = 1./s_nCells0; // out

  a_refratios.resize(a_nLevs-1);
  a_domains.resize(a_nLevs);
  a_grids.resize(a_nLevs);

  if (a_nLevs==1)
    {
      Vector<int> procAssign;
      Vector<Box> boxvector;
      Box levbox(IntVect::Zero,(s_nCells0-1)*IntVect::Unit), dombox=levbox;
      pout() << "setupGrids for level " << new_level+1 << "/" << a_nLevs << ". level domain " << levbox << endl;
      domainSplit(levbox, boxvector, s_maxboxsz, s_blockingfactor); // need blocking factor of 4 for C-F
      LoadBalance( procAssign, boxvector );
      a_grids[new_level].define(boxvector,procAssign);
      a_domains[new_level].define(dombox,isperiodic);
      a_same = false;
    }
  else
    {
      Vector<Vector<Box> > old_grids(a_nLevs-1);
      int new_finest_level;
      Real fillRatio = .8;
      BRMeshRefine refiner;
      Box curr_dom_box;
      static double thresh;

      // refratio
      a_refratios[new_level-1] = s_refRatio;
      // make new domain
      {
        Box dombox = a_domains[new_level-1].domainBox();
        dombox.refine(s_refRatio);
        a_domains[new_level].define(dombox,isperiodic);
      }

      refiner.define(a_domains[0],a_refratios,fillRatio,s_blockingfactor,s_nesting,s_maxboxsz);

      Real dx = a_cdx;
      if (a_nLevs==2)
        {
          // get max_grad on coarsest level - has the whole domain
          double max_ = 0.;
          const DisjointBoxLayout& dbl = a_grids[0];
          for (DataIterator dit = dbl.dataIterator(); dit.ok(); ++dit)
            {
              FArrayBox& exactFAB = (*a_exact[0])[dit];
              FArrayBox& phiFAB = (*a_phi[0])[dit];
              Box region = dbl[dit];
              for (BoxIterator bit(region); bit.ok(); ++bit)
                {
                  const IntVect& iv = bit();
                  Real grad = 0., tt;
                  if (s_amr_type_iserror)
                    {
                      tt = fabs(phiFAB(iv,0)-exactFAB(iv,0));
                      if (tt>max_) max_ = tt;
                    }
                  else
                    {
                      for (int dir=0; dir<SpaceDim; ++dir)
                        {
                          IntVect liv(iv), riv(iv); liv.shift(dir,-1); riv.shift(dir,1); 
                          tt = (exactFAB(riv,0)-exactFAB(liv,0))/(2.*dx);
                          grad += tt*tt;
                        }
                      grad = sqrt(grad);
                      if (grad>max_) max_ = grad;
                    }
                }
            }
#ifdef CH_MPI
          MPI_Allreduce( &max_, &thresh, 1, MPI_DOUBLE, MPI_MAX, PETSC_COMM_WORLD );
#else
	  thresh = max_;
#endif
          // set thresh
          thresh /= 2.; 
        }
      
      // make tags
      curr_dom_box = a_domains[0].domainBox(); // used for hard wired refinement
      for (int ilev=0;ilev<new_level;ilev++)
        {
          const DisjointBoxLayout& dbl = a_grids[ilev];
          for (DataIterator dit = dbl.dataIterator(); dit.ok(); ++dit)
            {
              FArrayBox& exactFAB = (*a_exact[ilev])[dit];
              FArrayBox& phiFAB = (*a_phi[ilev])[dit];
              Box region = dbl[dit];
              for (BoxIterator bit(region); bit.ok(); ++bit)
                {
                  const IntVect& iv = bit();
                  if (s_amr_type_iserror)
                    {
                      Real error = fabs(phiFAB(iv,0)-exactFAB(iv,0));
                      if (error > thresh) a_tagVects[ilev] |= iv; // real AMR
                    }
                  else // grad
                    {
                      Real grad = 0., tt;
                      for (int dir=0; dir<SpaceDim; ++dir)
                        {
                          IntVect liv(iv), riv(iv); liv.shift(dir,-1); riv.shift(dir,1); 
                          tt = (exactFAB(riv,0)-exactFAB(liv,0))/(2.*dx);
                          grad += tt*tt;
                        }
                      grad = sqrt(grad);
                      if (grad > thresh) a_tagVects[ilev] |= iv; // real AMR
                    }
                }
            } // grid

          // hardwire refinement in fake place
          IntVect se = a_domains[ilev].domainBox().smallEnd();
          //se.shift(1,curr_dom_box.size(1)-1);
          a_tagVects[ilev] |= se; 

          curr_dom_box.refine(s_refRatio);
          dx /= s_refRatio;
          thresh *= s_error_thresh; 
        }
  
      // make old_grids, need to make all because coarse grids can change after refinement
      for (int ilev=0;ilev<new_level;ilev++)
        {
          const DisjointBoxLayout& dbl = a_grids[ilev];
          old_grids[ilev].resize(dbl.size());
          LayoutIterator lit = dbl.layoutIterator();
          int boxIndex = 0;
          for (lit.begin(); lit.ok(); ++lit, ++boxIndex) 
            {
              old_grids[ilev][boxIndex] = dbl[lit()];
            }
        }
      
      pout() << "setupGrids for level " << new_level+1 << "/" << a_nLevs << ". level domain " << a_domains[new_level].domainBox() << endl;

      // want to keep these
      Vector<IntVectSet> tagVects_copy(a_nLevs-1);
      for (int ilev=0;ilev<new_level;ilev++)
        {
          tagVects_copy[ilev] = a_tagVects[ilev];
        }
      Vector<Vector<Box> > new_grids;
      new_finest_level = refiner.regrid( new_grids, tagVects_copy, 
                                         0, new_level-1, 
                                         old_grids );

      if (new_finest_level == new_level-1) 
        {
          a_same = true;
        }
      else
        {
          // test to see if grids have changed, create new DBLs
          a_same = true;
          for (int ilev=1; ilev<=new_finest_level; ++ilev)
            {
              int numGridsNew = new_grids[ilev].size();
              Vector<int> procIDs(numGridsNew);
              LoadBalance(procIDs, new_grids[ilev]);
              const DisjointBoxLayout newDBL( new_grids[ilev], procIDs,
                                              a_domains[ilev] );
              const DisjointBoxLayout oldDBL = a_grids[ilev];
              a_same &= oldDBL.sameBoxes(newDBL);
              a_grids[ilev] = newDBL;
            }
        }
      if (a_same)
        {
          pout() << "setupGrids -- grids unchanged" << endl;
        }
    }

  PetscFunctionReturn(0);
}
Example #14
0
void
EBCoarseAverage::define(const DisjointBoxLayout& a_dblFine,
                        const DisjointBoxLayout& a_dblCoar,
                        const EBISLayout& a_ebislFine,
                        const EBISLayout& a_ebislCoar,
                        const ProblemDomain& a_domainCoar,
                        const int& a_nref,
                        const int& a_nvar,
                        const EBIndexSpace* ebisPtr)
{
  CH_TIME("EBCoarseAverage::define");
  CH_assert(ebisPtr->isDefined());

  ProblemDomain domainFine = a_domainCoar;
  domainFine.refine(a_nref);
  EBLevelGrid eblgFine;
  EBLevelGrid eblgCoar = EBLevelGrid(a_dblCoar, a_ebislCoar, a_domainCoar);
  EBLevelGrid eblgCoFi;

  //check to see if the input layout is coarsenable.
  //if so, proceed with ordinary drill
  //otherwise, see if the layout covers the domain.
  //if it does, we can use domainsplit
  if (a_dblFine.coarsenable(a_nref))
    {
      eblgFine = EBLevelGrid(a_dblFine, a_ebislFine,   domainFine);
      m_useFineBuffer = false;
    }
  else
    {
      Box fineDomBox = refine(a_domainCoar.domainBox(), a_nref);
      int numPtsDom = fineDomBox.numPts();
      //no need for gathers here because the meta data is global
      int numPtsLayout = 0;
      for (LayoutIterator lit = a_dblFine.layoutIterator(); lit.ok(); ++lit)
        {
          numPtsLayout += a_dblFine.get(lit()).numPts();
        }
      bool coveringDomain = (numPtsDom == numPtsLayout);
      if (coveringDomain)
        {
          m_useFineBuffer = true;
          int maxBoxSize = 4*a_nref;
          Vector<Box> boxes;
          Vector<int> procs;
          domainSplit(fineDomBox, boxes, maxBoxSize);
          mortonOrdering(boxes);
          LoadBalance(procs, boxes);
          DisjointBoxLayout dblBufFine(boxes, procs);

          eblgFine = EBLevelGrid(dblBufFine, domainFine, 2, eblgCoar.getEBIS());
        }
      else
        {
          pout() << "EBCoarseAverage::input layout is not coarsenable and does not cover the domain--bailing out" << endl;
          MayDay::Error();
        }
    }

  coarsen(eblgCoFi, eblgFine, a_nref);
  define(eblgFine, eblgCoar, eblgCoFi, a_nref, a_nvar);
}
Example #15
0
void
EBFineToCoarRedist::
define(const DisjointBoxLayout& a_dblFine,
       const DisjointBoxLayout& a_dblCoar,
       const EBISLayout& a_ebislFine,
       const EBISLayout& a_ebislCoar,
       const Box& a_domainCoar,
       const int& a_nref,
       const int& a_nvar,
       int a_redistRad,
       const EBIndexSpace* const a_ebisPtr)
{
  CH_TIME("EBFineToCoarRedist::stardard_define");
  m_isDefined = true;
  m_nComp = a_nvar;
  m_refRat = a_nref;
  m_domainCoar = a_domainCoar;
  m_gridsFine = a_dblFine;
  m_gridsCoar = a_dblCoar;
  m_ebislFine = a_ebislFine;
  m_ebislCoar = a_ebislCoar;
  m_redistRad = a_redistRad;
  //created the coarsened fine layout
  m_gridsRefCoar = DisjointBoxLayout();
  refine(m_gridsRefCoar, m_gridsCoar, m_refRat);

  CH_assert(a_ebisPtr->isDefined());
  int nghost = 3*m_redistRad;
  Box domainFine = refine(m_domainCoar, m_refRat);
  a_ebisPtr->fillEBISLayout(m_ebislRefCoar, m_gridsRefCoar,
                            domainFine, nghost);
  m_ebislRefCoar.setMaxCoarseningRatio(m_refRat,a_ebisPtr);

  //define the intvectsets over which the objects live
  m_setsFine.define(m_gridsFine);
  m_setsRefCoar.define(m_gridsCoar);

  //make sets
  //global set consists of redistrad on the fine side of the coarse-fine
  //interface
  //the fine set is that within one fine box.
  //the refcoar set is that set within one refined coarse box.
  {
    CH_TIME("make_fine_sets");
    for (DataIterator dit =
          m_gridsFine.dataIterator(); dit.ok(); ++dit)
      {
        const Box& fineBox = m_gridsFine.get(dit());
        IntVectSet& fineSet = m_setsFine[dit()];
        //add entire fine box
        fineSet = IntVectSet(fineBox);
        IntVectSet irregIVS = m_ebislFine[dit()].getIrregIVS(fineBox);
        fineSet &= irregIVS;
        //subtract fine box shrunk by the redistribution radius
        fineSet -= grow(fineBox, -m_redistRad);
        //subtract all other the fine boxes shifted in all
        //directions
        for (LayoutIterator lit =
              m_gridsFine.layoutIterator(); lit.ok(); ++lit)
          {
            const Box& otherBox = m_gridsFine.get(lit());
            if (otherBox != fineBox)
              {
                for (int idir = 0; idir < SpaceDim; idir++)
                  {
                    for (SideIterator sit; sit.ok(); ++sit)
                      {
                        Box shiftBox = otherBox;
                        shiftBox.shift(idir, sign(sit())*m_redistRad);
                        fineSet -= shiftBox;
                      }
                  }
              }
          }
      }
  }
  {
    CH_TIME("make_coar_sets");
    for (DataIterator dit =
          m_gridsCoar.dataIterator(); dit.ok(); ++dit)
      {
        Box grownBox = grow(m_gridsRefCoar.get(dit()), m_redistRad);
        grownBox &= domainFine;
        //find the complement of what we really want
        IntVectSet ivsComplement(grownBox);
        for (LayoutIterator litFine =
              m_gridsFine.layoutIterator(); litFine.ok(); ++litFine)
          {
            const Box& fineBox = m_gridsFine.get(litFine());
            IntVectSet fineSet(fineBox);
            //add entire fine box
            fineSet = IntVectSet(fineBox);
            Box interiorBox = grow(fineBox, -m_redistRad);
            //subtract fine box shrunk by the redistribution radius
            fineSet -= interiorBox;
            //subtract all other the fine boxes shifted in all
            //directions
            for (LayoutIterator lit =
                  m_gridsFine.layoutIterator(); lit.ok(); ++lit)
              {
                const Box& otherBox = m_gridsFine.get(lit());
                if (otherBox != fineBox)
                  {
                    for (int idir = 0; idir < SpaceDim; idir++)
                      {
                        for (SideIterator sit; sit.ok(); ++sit)
                          {
                            Box shiftBox = otherBox;
                            shiftBox.shift(idir, sign(sit())*m_redistRad);
                            fineSet -= shiftBox;
                          }
                      }
                  }
              }
            //subtract the fine set from the complement
            ivsComplement -= fineSet;
          }
        //now the set we want is the grownbox - complement
        IntVectSet& refCoarSet = m_setsRefCoar[dit()];
        refCoarSet = IntVectSet(grownBox);
        refCoarSet -= ivsComplement;
        IntVectSet irregIVS = m_ebislRefCoar[dit()].getIrregIVS(grownBox);
        refCoarSet &= irregIVS;
      }
  }
  defineDataHolders();
  setToZero();
}