예제 #1
0
void VCAMRPoissonOp2::residualI(LevelData<FArrayBox>&       a_lhs,
                               const LevelData<FArrayBox>& a_phi,
                               const LevelData<FArrayBox>& a_rhs,
                               bool                        a_homogeneous)
{
  CH_TIME("VCAMRPoissonOp2::residualI");

  LevelData<FArrayBox>& phi = (LevelData<FArrayBox>&)a_phi;
  Real dx = m_dx;
  const DisjointBoxLayout& dbl = a_lhs.disjointBoxLayout();
  DataIterator dit = phi.dataIterator();
  {
    CH_TIME("VCAMRPoissonOp2::residualIBC");

    for (dit.begin(); dit.ok(); ++dit)
    {
      m_bc(phi[dit], dbl[dit()],m_domain, dx, a_homogeneous);
    }
  }

  phi.exchange(phi.interval(), m_exchangeCopier);

  for (dit.begin(); dit.ok(); ++dit)
    {
      const Box& region = dbl[dit()];
      const FluxBox& thisBCoef = (*m_bCoef)[dit];

#if CH_SPACEDIM == 1
      FORT_VCCOMPUTERES1D
#elif CH_SPACEDIM == 2
      FORT_VCCOMPUTERES2D
#elif CH_SPACEDIM == 3
      FORT_VCCOMPUTERES3D
#else
      This_will_not_compile!
#endif
                         (CHF_FRA(a_lhs[dit]),
                          CHF_CONST_FRA(phi[dit]),
                          CHF_CONST_FRA(a_rhs[dit]),
                          CHF_CONST_REAL(m_alpha),
                          CHF_CONST_FRA((*m_aCoef)[dit]),
                          CHF_CONST_REAL(m_beta),
#if CH_SPACEDIM >= 1
                          CHF_CONST_FRA(thisBCoef[0]),
#endif
#if CH_SPACEDIM >= 2
                          CHF_CONST_FRA(thisBCoef[1]),
#endif
#if CH_SPACEDIM >= 3
                          CHF_CONST_FRA(thisBCoef[2]),
#endif
#if CH_SPACEDIM >= 4
                          This_will_not_compile!
#endif
                          CHF_BOX(region),
                          CHF_CONST_REAL(m_dx));
    } // end loop over boxes
}
예제 #2
0
int scopingTest()
{
  Vector<Box> boxes;
  int retflag = 0;
  setGrids(boxes);

  LevelData<FArrayBox> levelFab;
  makeLevelData(boxes, levelFab);
  const DisjointBoxLayout& dbl = levelFab.getBoxes();
  DataIterator dit = dbl.dataIterator();
  int ivec = 0;
  for (dit.begin(); dit.ok(); ++dit)
    {
      if (!dbl.check(dit()))
        {
          if (verbose)
            pout() << indent2 << pgmname
                 << ": failed at box " << ivec << endl;
          retflag = 1;
        }
      else
        {
          levelFab[dit].setVal(0.);
        }
      if (retflag > 0) break;
      ivec++;
    }
  return retflag;
}
예제 #3
0
void
initData(LevelData<FArrayBox>& a_data, const Real a_dx)
{

  DataIterator dit = a_data.dataIterator();
  const DisjointBoxLayout& interiorBoxes = a_data.getBoxes();

  for (dit.begin(); dit.ok(); ++dit)
    {
      // first set to a bogus value which will persist in ghost cells
      // after initialization
      a_data[dit()].setVal(1.0e9);

      // this will be slow, but who cares?
      FArrayBox& localData = a_data[dit()];
      BoxIterator boxIt(interiorBoxes[dit()]);
      Real localVal;
      for (boxIt.begin(); boxIt.ok(); ++boxIt)
        {
          const IntVect& loc = boxIt();
          for (int comp=0; comp<localData.nComp(); comp++)
            {
              localVal = dataVal(loc, comp);
              localData(loc, comp) = localVal;
            }
        }

    }
}
예제 #4
0
// -----------------------------------------------------------------------------
// Interpolate ghosts at CF interface using zeros on coarser grids.
// -----------------------------------------------------------------------------
void homogeneousCFInterp (LevelData<FArrayBox>& a_phif,
                          const RealVect&       a_fineDx,
                          const RealVect&       a_crseDx,
                          const CFRegion&       a_cfRegion,
                          const IntVect&        a_applyDirs)
{
    CH_TIME("homogeneousCFInterp (full level)");

    // Loop over grids, directions, and sides and call the worker function.
    DataIterator dit = a_phif.dataIterator();
    for (dit.begin(); dit.ok(); ++dit) {
        if (a_phif[dit].box().isEmpty()) continue;

        for (int dir = 0; dir < SpaceDim; ++dir) {
            if (a_applyDirs[dir] == 0) continue;

            SideIterator sit;
            for (sit.begin(); sit.ok(); sit.next()) {
                homogeneousCFInterp(a_phif,
                                    dit(),
                                    dir,
                                    sit(),
                                    a_fineDx[dir],
                                    a_crseDx[dir],
                                    a_cfRegion);
            }
        }
    }
}
예제 #5
0
// this preconditioner first initializes phihat to (IA)phihat = rhshat
// (diagonization of L -- A is the matrix version of L)
// then smooths with a couple of passes of levelGSRB
void VCAMRPoissonOp2::preCond(LevelData<FArrayBox>&       a_phi,
                              const LevelData<FArrayBox>& a_rhs)
{
  CH_TIME("VCAMRPoissonOp2::preCond");

  // diagonal term of this operator in:
  //
  //       alpha * a(i)
  //     + beta  * sum_over_dir (b(i-1/2*e_dir) + b(i+1/2*e_dir)) / (dx*dx)
  //
  // The inverse of this is our initial multiplier.

  int ncomp = a_phi.nComp();

  CH_assert(m_lambda.isDefined());
  CH_assert(a_rhs.nComp()    == ncomp);
  CH_assert(m_bCoef->nComp() == ncomp);

  // Recompute the relaxation coefficient if needed.
  resetLambda();

  // don't need to use a Copier -- plain copy will do
  DataIterator dit = a_phi.dataIterator();
  for (dit.begin(); dit.ok(); ++dit)
    {
      // also need to average and sum face-centered bCoefs to cell-centers
      Box gridBox = a_rhs[dit].box();

      // approximate inverse
      a_phi[dit].copy(a_rhs[dit]);
      a_phi[dit].mult(m_lambda[dit], gridBox, 0, 0, ncomp);
    }

  relax(a_phi, a_rhs, 2);
}
예제 #6
0
void TimeInterpolatorRK4::saveRHS(const LevelData<FArrayBox>&   a_rhs)
{
  CH_assert(m_defined);
  CH_assert(m_gotDt);
  CH_assert(m_gotInitialSoln);
  CH_assert(!m_gotFullTaylorPoly);
  CH_assert(m_countRHS >= 0);
  CH_assert(m_countRHS < 4);
  CH_assert(a_rhs.nComp() == m_numStates);

  // a_rhs is on the coarse layout;
  // m_rhsCopy is on the coarsened fine layout.
  a_rhs.copyTo(m_rhsCopy, m_copier);

  DataIterator dit = m_rhsCopy.dataIterator();
  for (dit.begin(); dit.ok(); ++dit)
    {
      const FArrayBox& rhsCopyFab = m_rhsCopy[dit];
      FArrayBox& taylorFab = m_taylorCoeffs[dit];

      for (int ind = 0; ind < m_numCoeffs; ind++)
        {
          Real multFactor = m_coeffs[ind][m_countRHS];
          if (multFactor != 0.)
            {
              taylorFab.plus(rhsCopyFab,
                             multFactor, // multiply rhsCopyFab by this
                             0, // start rhsCopyFab component
                             ind * m_numStates, // start taylorFab component
                             m_numStates); // number of components
            }
        }
      // These are for getting to RK4 intermediates:
      // diff12 = m_dt * (rhs[2] - rhs[1])
      if (m_countRHS == 1)
        {
          FArrayBox& diff12Fab = m_diff12[dit];
          diff12Fab.copy(rhsCopyFab);
        }
      if (m_countRHS == 2)
        {
          FArrayBox& diff12Fab = m_diff12[dit];
          diff12Fab -= rhsCopyFab;
          diff12Fab *= -m_dt;
        }
    }
  m_countRHS++;
  if (m_countRHS == 4)
    {
      m_taylorCoeffs.exchange();
      m_gotFullTaylorPoly = true;
    }
}
예제 #7
0
파일: restart.cpp 프로젝트: rsnemmen/Chombo
//
// Generate field data.  We're not solving any real problem here;
// the only purpose of this is to come up with some numbers that couldn't
// happen by accident, so we can check if the hdf5 I/O is working.
//
// New data is a function of prev_checksum (a vector -- one element per
// level).
// Updates curr_checksum.
//
void
EBRestart::fillData( Vector<LevelData<EBCellFAB>* >& a_ebvector,
                     int                             a_nlevs,
                     int                             a_ncomps,
                     const EBRestart::CheckSumVect&  a_prev_checksums
             )
{
  static int g_i;
  g_i = 0;
  for (int lev=0; lev<a_nlevs; ++lev)
  {
    LevelData<EBCellFAB>& ld( *a_ebvector[lev] );
    DataIterator dit = ld.dataIterator();
    for ( dit.begin(); dit.ok(); ++dit )
    {
      EBCellFAB& ebcf( ld[dit] );

      //
      // Single-valued cells
      //
      BaseFab<Real>& singFab(ebcf.getSingleValuedFAB());
      for ( int i=0; i<singFab.box().numPts()*a_ncomps; ++i )
      {
        long x = (i+a_prev_checksums[lev].sum)
               % (a_prev_checksums[lev].len_irreg+100);
        singFab.dataPtr()[i] = x;
//      singFab.dataPtr()[i] = g_i++;
      }

      //
      // Multivalued cells
      //
      Box box( ld.disjointBoxLayout().get(dit) );
      box.grow( ld.ghostVect() );
      const IntVectSet& irregIVS( ebcf.getEBISBox().boundaryIVS(box) );
      const EBGraph& graph( ebcf.getEBISBox().getEBGraph() );
      Vector<Real> multidat( a_ncomps );
      const IntVectSet& multiIVS( ebcf.getMultiValuedFAB().getIVS() );
      for ( VoFIterator it(irregIVS,graph); it.ok(); ++it )
      {
        if ( multiIVS.contains( it().gridIndex() ) )
        {
          for ( int c=0;c<a_ncomps;++c )
          {
//          multidat[c] = 111000 + g_i++;
            multidat[c] = 111000 + g_i++ + 10*c + a_prev_checksums[lev].sum%71;
          }
          ebcf.assign( &multidat[0], it(), Interval(0,a_ncomps-1) );
        }
      }
    }
  }
}
예제 #8
0
void
initData(LevelData<FArrayBox>& a_data,
         Real a_dx)
{
  // for now, set phi to 1 everywhere
  Real phiVal = 1.0;

  DataIterator dit = a_data.dataIterator();
  for (dit.begin(); dit.ok(); ++dit)
    {
      a_data[dit].setVal(phiVal);
    }
}
예제 #9
0
// ---------------------------------------------------------
void
AMRNavierStokes::computeKineticEnergy(LevelData<FArrayBox>& a_energy) const
{
  // this is simple since no BC's need to be set.
  const LevelData<FArrayBox>& levelVel = *m_vel_new_ptr;
  const DisjointBoxLayout& levelGrids = levelVel.getBoxes();

  DataIterator dit = a_energy.dataIterator();
  for (dit.begin(); dit.ok(); ++dit)
    {
      FORT_KINETICENERGY(CHF_FRA1(a_energy[dit],0),
                         CHF_CONST_FRA(levelVel[dit]),
                         CHF_BOX(levelGrids[dit]));
    }
}
예제 #10
0
void VCAMRPoissonOp2::applyOpNoBoundary(LevelData<FArrayBox>&      a_lhs,
                                        const LevelData<FArrayBox>& a_phi)
{
  CH_TIME("VCAMRPoissonOp2::applyOpNoBoundary");

  LevelData<FArrayBox>& phi = (LevelData<FArrayBox>&)a_phi;

  const DisjointBoxLayout& dbl = a_lhs.disjointBoxLayout();
  DataIterator dit = phi.dataIterator();

  phi.exchange(phi.interval(), m_exchangeCopier);

  for (dit.begin(); dit.ok(); ++dit)
    {
      const Box& region = dbl[dit()];
      const FluxBox& thisBCoef = (*m_bCoef)[dit];

#if CH_SPACEDIM == 1
      FORT_VCCOMPUTEOP1D
#elif CH_SPACEDIM == 2
      FORT_VCCOMPUTEOP2D
#elif CH_SPACEDIM == 3
      FORT_VCCOMPUTEOP3D
#else
      This_will_not_compile!
#endif
                        (CHF_FRA(a_lhs[dit]),
                         CHF_CONST_FRA(phi[dit]),
                         CHF_CONST_REAL(m_alpha),
                         CHF_CONST_FRA((*m_aCoef)[dit]),
                         CHF_CONST_REAL(m_beta),
#if CH_SPACEDIM >= 1
                         CHF_CONST_FRA(thisBCoef[0]),
#endif
#if CH_SPACEDIM >= 2
                         CHF_CONST_FRA(thisBCoef[1]),
#endif
#if CH_SPACEDIM >= 3
                         CHF_CONST_FRA(thisBCoef[2]),
#endif
#if CH_SPACEDIM >= 4
                         This_will_not_compile!
#endif
                         CHF_BOX(region),
                         CHF_CONST_REAL(m_dx));
    } // end loop over boxes
}
예제 #11
0
void VCAMRPoissonOp2::applyOpI(LevelData<FArrayBox>&      a_lhs,
                             const LevelData<FArrayBox>& a_phi,
                             bool                        a_homogeneous )
{
  CH_TIME("VCAMRPoissonOp2::applyOpI");
  LevelData<FArrayBox>& phi = (LevelData<FArrayBox>&)a_phi;
  Real dx = m_dx;
  const DisjointBoxLayout& dbl = a_lhs.disjointBoxLayout();
  DataIterator dit = phi.dataIterator();

  for (dit.begin(); dit.ok(); ++dit)
    {
      m_bc(phi[dit], dbl[dit()],m_domain, dx, a_homogeneous);
    }

  applyOpNoBoundary(a_lhs, a_phi);
}
예제 #12
0
// Find the maximum wave speed on the current level
Real OldLevelGodunov::getMaxWaveSpeed(const LevelData<FArrayBox>& a_U)
{
  const DisjointBoxLayout& disjointBoxLayout = a_U.disjointBoxLayout();
  DataIterator dit = disjointBoxLayout.dataIterator();

  // Initial maximum wave speed
  Real speed = 0.0;

  // This computation doesn't need involve a time but the time being set
  // is checked by OldPatchGodunov::getMaxWaveSpeed so we have to set it
  // to something...
  m_patchGodunov->setCurrentTime(0.0);

  // Loop over all grids to get the maximum wave speed
  for (dit.begin(); dit.ok(); ++dit)
    {
      const Box& currentBox = disjointBoxLayout.get(dit());

      // Set the current box and get the maximum wave speed on the current grid
      m_patchGodunov->setCurrentBox(currentBox);
      Real speedOverBox = m_patchGodunov->getMaxWaveSpeed(a_U[dit()],
                                                          currentBox);

      // Compute a running maximum
      speed = Max(speed,speedOverBox);
    }

  // Gather maximum wave speeds and broadcast the maximum over these
  Vector<Real> allSpeeds;

  gather(allSpeeds,speed,uniqueProc(SerialTask::compute));

  if (procID() == uniqueProc(SerialTask::compute))
    {
      speed = allSpeeds[0];
      for (int i = 1; i < allSpeeds.size (); ++i)
        {
          speed = Max(speed,allSpeeds[i]);
        }
    }

  broadcast(speed,uniqueProc(SerialTask::compute));

  // Return the maximum wave speed
  return speed;
}
예제 #13
0
void setValue(LevelData<EBCellFAB>& phase, const BaseBCValue& value,
              const Box& domain,
              const RealVect& dx, const RealVect& origin,
              bool useKappa)
{
    RealVect loc;
    IntVect  originIV = domain.smallEnd();
    DataIterator dit = phase.dataIterator();
    for (dit.begin(); dit.ok(); ++dit)
    {
        EBCellFAB& efab = phase[dit];

        FArrayBox& fab  = efab.getFArrayBox();
        ForAllX(Real, fab)
        {
            D_EXPR(loc[0]=iR+nR-nR+originIV[0], loc[1]=jR+originIV[1], loc[2]=kR+originIV[2]);
            loc+=0.5;
            loc*=dx;
            loc+=origin;
            fabR = value.value(loc, RealVect::Zero, 1.e99,0);
        }
        EndFor ;
        if (useKappa)
        {
            const EBISBox& ebox = efab.getEBISBox();
            IntVectSet ivs = ebox.getIrregIVS(efab.getRegion());
            IVSIterator it(ivs);
            for (; it.ok(); ++it)
            {
                const IntVect iv = it();
                VolIndex vi(iv,0);
                if (ebox.bndryArea(vi) != 0)
                {
                    loc = iv;
                    loc+=0.5;
                    loc+= ebox.centroid(vi);
                    loc*=dx;
                    loc+=origin;
                    efab(vi, 0) = value.value(loc, RealVect::Zero, 1.e99,0)*ebox.volFrac(vi);
                }
            }
        }
    }
예제 #14
0
void TimeInterpolatorRK4::interpolate(/// interpolated solution on this level coarsened
                                      LevelData<FArrayBox>&   a_U,
                                      /// time interpolation coefficient in range [0:1]
                                      const Real&             a_timeInterpCoeff,
                                      /// interval of a_U to fill in
                                      const Interval&         a_intvl)
{
  CH_assert(m_defined);
  CH_assert(m_gotFullTaylorPoly);
  CH_assert(a_U.nComp() == m_numStates);

  LevelData<FArrayBox> UComp;
  aliasLevelData(UComp, &a_U, a_intvl);

  // For i in 0:m_numCoeffs-1,
  // coeffFirst[i] is index of first component of m_taylorCoeffs
  // that corresponds to a coefficient of t^i.
  Vector<int> coeffFirst(m_numCoeffs);
  int intervalLength = a_intvl.size();
  for (int i = 0; i < m_numCoeffs; i++)
    {
      coeffFirst[i] = a_intvl.begin() + i * m_numStates;
    }

  DataIterator dit = UComp.dataIterator();
  for (dit.begin(); dit.ok(); ++dit)
    {
      FArrayBox& UFab = UComp[dit];
      const FArrayBox& taylorFab = m_taylorCoeffs[dit];

      // Evaluate a0 + a1*t + a2*t^2 + a3*t^3
      // as a0 + t * (a1 + t * (a2 + t * a3)).
      UFab.copy(taylorFab, coeffFirst[m_numCoeffs-1], 0, intervalLength);
      for (int ind = m_numCoeffs - 2; ind >=0; ind--)
        {
          UFab *= a_timeInterpCoeff;
          UFab.plus(taylorFab, coeffFirst[ind], 0, intervalLength);
        }
    }
  // dummy statement in order to get around gdb bug
  int dummy_unused = 0; dummy_unused = 0;
}
예제 #15
0
// Set up initial conditions
void ExplosionIBC::initialize(LevelData<FArrayBox>& a_U)
{
  CH_assert(m_isFortranCommonSet == true);
  CH_assert(m_isDefined == true);

  DataIterator dit = a_U.boxLayout().dataIterator();

  // Iterator of all grids in this level
  for (dit.begin(); dit.ok(); ++dit)
  {
    // Storage for current grid
    FArrayBox& U = a_U[dit()];

    // Box of current grid
    Box uBox = U.box();
    uBox &= m_domain;

    // Set up initial condition in this grid
    FORT_EXPLOSIONINITF(CHF_FRA(U),
                        CHF_CONST_REAL(m_dx),
                        CHF_BOX(uBox));
  }
}
예제 #16
0
void TimeInterpolatorRK4::saveInitialSoln(const LevelData<FArrayBox>&   a_soln)
{
  CH_assert(m_defined);
  CH_assert(m_gotDt);
  CH_assert(!m_gotInitialSoln);
  CH_assert(a_soln.nComp() == m_numStates);

  // First zero out taylorFab.
  DataIterator dit = m_taylorCoeffs.dataIterator();
  for (dit.begin(); dit.ok(); ++dit)
    {
      FArrayBox& taylorFab = m_taylorCoeffs[dit];
      taylorFab.setVal(0.);
    }

  // a_soln is on the coarse layout;
  // m_taylorCoeffs is on the coarsened fine layout.
  // Copy from a_soln to first m_numStates components of m_taylorCoeffs.
  const Interval& srcInt = a_soln.interval();
  a_soln.copyTo(srcInt, m_taylorCoeffs, srcInt, m_copier);

  m_gotInitialSoln = true;
}
예제 #17
0
void
initData(LevelData<FArrayBox>& a_data, const Real a_dx)
{

  DataIterator dit = a_data.dataIterator();
  const DisjointBoxLayout& interiorBoxes = a_data.getBoxes();

  for (dit.begin(); dit.ok(); ++dit)
    {
      // first set to a bogus value which will persist in ghost cells
      // after initialization
      a_data[dit()].setVal(1.0e9);

      // this will be slow, but who cares?
      FArrayBox& localData = a_data[dit()];
      BoxIterator boxIt(interiorBoxes[dit()]);
      Real localVal;
      for (boxIt.begin(); boxIt.ok(); ++boxIt)
        {
          const IntVect& loc = boxIt();
          // linear profile
          //localVal = a_dx*(D_TERM(loc[0]+0.5,
          //                      + loc[1]+0.5,
          //                      + loc[2]+0.5));

          // quadratic profile
          localVal = a_dx*a_dx*(D_TERM6((loc[0]+0.5)*(loc[0]+0.5),
                                        + (loc[1]+0.5)*(loc[1]+0.5),
                                        + (loc[2]+0.5)*(loc[2]+0.5),
                                        + (loc[3]+0.5)*(loc[3]+0.5),
                                        + (loc[4]+0.5)*(loc[4]+0.5),
                                        + (loc[5]+0.5)*(loc[5]+0.5)));
          localData(loc) = localVal;
        }

    }
}
예제 #18
0
void VCAMRPoissonOp2::levelJacobi(LevelData<FArrayBox>&       a_phi,
                                 const LevelData<FArrayBox>& a_rhs)
{
  CH_TIME("VCAMRPoissonOp2::levelJacobi");

  // Recompute the relaxation coefficient if needed.
  resetLambda();

  LevelData<FArrayBox> resid;
  create(resid, a_rhs);

  // Get the residual
  residual(resid,a_phi,a_rhs,true);

  // Multiply by the weights
  DataIterator dit = m_lambda.dataIterator();
  for (dit.begin(); dit.ok(); ++dit)
  {
    resid[dit].mult(m_lambda[dit]);
  }

  // Do the Jacobi relaxation
  incr(a_phi, resid, 0.5);
}
예제 #19
0
파일: compare.cpp 프로젝트: rsnemmen/Chombo
// 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;
     }
}
예제 #20
0
// ---------------------------------------------------------------
void
AMRNavierStokes::computeAdvectionVelocities(LevelData<FluxBox>& a_advVel)
{
  if (s_verbosity >= 3)
    {
      pout() << "AMRNavierStokes::computeAdvectionVelocities: "
             << m_level << endl;
    }

  bool isViscous = (s_nu > 0.0);

  const DisjointBoxLayout& levelGrids = newVel().getBoxes();

  /// need to build grown grids to get be able to do all of
  /// tracing properly
  IntVect advect_grow(D_DECL(ADVECT_GROW, ADVECT_GROW, ADVECT_GROW));

  LevelData<FArrayBox> old_vel(levelGrids, SpaceDim, advect_grow);
  LevelData<FArrayBox> viscousSource(levelGrids, SpaceDim, advect_grow);
  LevelData<FArrayBox>* crseVelPtr = NULL;

  if (s_set_bogus_values)
    {
      setValLevel(old_vel, s_bogus_value);
      setValLevel(viscousSource, s_bogus_value);
    }

  // m_time contains the time at which the new state is centered
  Real old_time = m_time - m_dt;
  fillVelocity(old_vel, old_time);

  // set physical boundary conditions here
  // set physical boundary conditions on velocity

  if (isViscous)
    {
      LevelData<FArrayBox> viscousVel(levelGrids, SpaceDim, advect_grow);
      DataIterator dit = viscousVel.dataIterator();
      // rather than resetting BC's on old_vel, and then setting them
      // back, just copy old_vel to a temporary holder, and set
      // BCs on that one.
      for (dit.begin(); dit.ok(); ++dit)
        {
          viscousVel[dit].copy(old_vel[dit]);
        }
      VelBCHolder velBC(m_physBCPtr->viscousVelFuncBC());
      velBC.applyBCs(viscousVel, levelGrids,
                     m_problem_domain, m_dx,
                     false); // inhomogeneous

      // if crse level exists, fill coarse velocity BC
      if (m_level > 0)
        {
          const DisjointBoxLayout& crseGrids = crseNSPtr()->newVel().getBoxes();
          crseVelPtr = new LevelData<FArrayBox>(crseGrids, SpaceDim);
          crseNSPtr()->fillVelocity(*crseVelPtr, old_time);
        }

      computeLapVel(viscousSource, viscousVel, crseVelPtr);

      for (dit.reset(); dit.ok(); ++dit)
        {
          viscousSource[dit].mult(s_nu);
        }
    }
  else
    {
      setValLevel(viscousSource, 0.0);
    }

  // tracing will use inviscid BC's
  {
    VelBCHolder velBC(m_physBCPtr->tracingVelFuncBC());
    velBC.applyBCs(old_vel, levelGrids,
                   m_problem_domain, m_dx,
                   false); // inhomogeneous
  }

  // call utility function to do tracing
  traceAdvectionVel(a_advVel, old_vel, viscousSource,
                    m_patchGodVelocity, old_time, m_dt);

  EdgeVelBCHolder edgeVelBC(m_physBCPtr->advectionVelFuncBC(isViscous));
  edgeVelBC.applyBCs(a_advVel, levelGrids,
                     m_problem_domain, m_dx,
                     false); // inhomogeneous

  // noel  levelMacProject is big guy
  // now MAC project
  m_projection.levelMacProject(a_advVel, old_time, m_dt);

  // finally, add volume discrepancy correction
  if (m_projection.etaLambda() > 0 && s_applyFreestreamCorrection)
    {
      LevelData<FluxBox>& grad_e_Lambda = m_projection.grad_eLambda();

      DataIterator dit = levelGrids.dataIterator();
      for (dit.reset(); dit.ok(); ++dit)
        {
          FluxBox& thisGrad_eLambda = grad_e_Lambda[dit];
          FluxBox& thisAdvVel = a_advVel[dit];
          for (int dir=0; dir<SpaceDim; dir++)
            {
              thisAdvVel[dir] += thisGrad_eLambda[dir];
            }
        }
    }

  edgeVelBC.applyBCs(a_advVel, levelGrids,
                     m_problem_domain, m_dx,
                     false); // inhomogeneous

  // clean up storage
  if (crseVelPtr != NULL)
    {
      delete crseVelPtr;
      crseVelPtr = NULL;
    }
}
예제 #21
0
int
main(int argc ,char *argv[] )
{
#ifdef CH_MPI
  MPI_Init(&argc, &argv);
#endif

  int status = 0;
  // Make this test pass automatically if DIM > 3, to avoid FAIL message.
  if (SpaceDim <= 3)
  {
    parseTestOptions(argc, argv);

    // establish periodic domain -- first multiply periodic in all directions
    int baseDomainSize = 8;
    int numGhost = 2;
    IntVect ghostVect(numGhost*IntVect::Unit);

    Box baseDomBox(IntVect::Zero, (baseDomainSize-1)*IntVect::Unit);
    ProblemDomain baseDomain(baseDomBox);

    // set periodic in all directions
    for (int dir=0; dir<SpaceDim; dir++)
    {
      baseDomain.setPeriodic(dir, true);
    }

    {
      // QuadCFInterp test
      int nRef = 2;
      ProblemDomain fineDomain(baseDomain);
      fineDomain.refine(nRef);

      const Box domainBox = baseDomain.domainBox();
      Vector<Box> crseBoxes(1, domainBox);
      Vector<int> crseProcAssign(1,0);
      DisjointBoxLayout crseGrids(crseBoxes, crseProcAssign, baseDomain);

      // note the lack of ghost cells on the base level
      LevelData<FArrayBox> crseData(crseGrids, 1, IntVect::Zero);

      Real dxCrse = 1.0/(baseDomainSize);
      Real dxFine = dxCrse/nRef;
      initData(crseData, dxCrse);

#if (CH_SPACEDIM == 1)
      Vector<Box> fineBoxes(2);
      Vector<int> fineProcAssign(2);

      fineBoxes[0] = Box(IntVect::Zero, 5*IntVect::Unit);
      fineBoxes[1] = Box(IntVect(D_DECL6(6,10,10,6,10,0)), IntVect(D_DECL6(11,15,15,11,15,15)));
#else
      // try multiple boxes for fine level
      Vector<Box> fineBoxes(4);
      Vector<int> fineProcAssign(4);

      fineBoxes[0] = Box(IntVect::Zero, 9*IntVect::Unit);
      fineBoxes[1] = Box(IntVect(D_DECL6(6,10,10,6,10,0)), IntVect(D_DECL6(11,15,15,11,15,15)));
      // this box should fail the disjointness test
      //fineBoxes[1] = Box(IntVect(D_DECL(7,10,10)), 17*IntVect::Unit);
      fineBoxes[2] = Box(IntVect(D_DECL6(12,2,0,12,2,0)), IntVect(D_DECL6(15,7,7,15,7,7)));
      fineBoxes[3] = Box(IntVect(D_DECL6(12,12,0,12,12,0)), 15*IntVect::Unit);
#endif

      int loadbalancestatus = LoadBalance(fineProcAssign, fineBoxes);
      CH_assert (loadbalancestatus == 0);

      DisjointBoxLayout fineGrids;
      fineGrids.define(fineBoxes, fineProcAssign, fineDomain);
      LevelData<FArrayBox> fineData(fineGrids, 1, ghostVect);

      // set these to a bogus value to start with
      DataIterator fineDit = fineData.dataIterator();
      for (fineDit.begin(); fineDit.ok(); ++fineDit)
        {
          fineData[fineDit()].setVal(1.0e9);
        }

      FineInterp interpolator(fineGrids, 1, nRef, fineDomain);

      // turn on fine-data averaging even though it's unnecessary
      // since this is a test (so we'd like to know if it's broken)
      bool averageFineData = true;
      interpolator.interpToFine(fineData, crseData, averageFineData);

      // now fill in ghost cells
      QuadCFInterp filler(fineGrids, &crseGrids, dxFine, nRef, 1,
              fineDomain);

      filler.coarseFineInterp(fineData, crseData);
    }

    {
      // fineInterp near boundary test
      int numLev = 3;
      Vector<int> nRefVect(numLev);
      nRefVect[0] = 4;
      nRefVect[1] = 2;
      nRefVect[2] = -1;
      Vector<Real> dxVect(numLev);
      Vector<ProblemDomain> levelDomains(numLev);
      levelDomains[0] = Box(IntVect::Zero, 15*IntVect::Unit);
      dxVect[0] = 1.0/(levelDomains[0].domainBox().size(0));
      for (int lev=1; lev<numLev; lev++)
        {
          levelDomains[lev] = levelDomains[lev-1];
          levelDomains[lev].refine(nRefVect[lev-1]);
          dxVect[lev] = dxVect[lev-1]/nRefVect[lev-1];
        }

      Vector<DisjointBoxLayout> levelGrids(numLev);
      Vector<LevelData<FArrayBox>* > levelData(numLev, NULL);

      const Box domainBox = levelDomains[0].domainBox();
      Vector<Box> crseBoxes(1, domainBox);
      Vector<int> crseProcAssign(1,0);
      DisjointBoxLayout level0Grids(crseBoxes, crseProcAssign,
                                    levelDomains[0]);
      levelGrids[0] = level0Grids;

      // note the lack of ghost cells on the base level
      levelData[0] = new LevelData<FArrayBox>(level0Grids,
                                              1, IntVect::Zero);

      initData(*levelData[0], dxVect[0]);

      Vector<Box> level1Boxes(1, levelDomains[1].domainBox());
      int loadbalancestatus = LoadBalance(crseProcAssign, level1Boxes);
      CH_assert (loadbalancestatus == 0);

      IntVect newGhostVect(4*IntVect::Unit);
      DisjointBoxLayout fineGrids;
      fineGrids.define(level1Boxes, crseProcAssign, levelDomains[1]);
      levelGrids[1] = fineGrids;
      levelData[1] = new LevelData<FArrayBox>(fineGrids, 1,
                                              newGhostVect);

      Vector<Box> level2Boxes(1);
      //level2Boxes[0] = Box(20*IntVect::Unit, 119*IntVect::Unit);
      level2Boxes[0] = Box(100*IntVect::Unit, 127*IntVect::Unit);
      DisjointBoxLayout finestGrids(level2Boxes, crseProcAssign,
                                    levelDomains[2]);
      levelGrids[2] = finestGrids;
      levelData[2] = new LevelData<FArrayBox>(finestGrids, 1,
                                              newGhostVect);

      for (int lev=1; lev<numLev; lev++)
        {
          LevelData<FArrayBox>& fineData = *levelData[lev];
          LevelData<FArrayBox>& crseData = *levelData[lev-1];

          // set these to a bogus value to start with
          DataIterator fineDit = fineData.dataIterator();
          for (fineDit.begin(); fineDit.ok(); ++fineDit)
            {
              fineData[fineDit()].setVal(1.0e9);
            }

          FineInterp interpolator(levelGrids[lev], 1, nRefVect[lev-1],
                                  levelDomains[lev]);

          // turn on fine-data averaging even though it's unnecessary
          // since this is a test (so we'd like to know if it's broken)
          bool averageFineData = true;
          interpolator.interpToFine(fineData, crseData, averageFineData);

          pout() << "grids at level = " << lev << endl;
          dumpDBL(&levelGrids[lev]);
          pout() << "grids at level = " << lev-1 << endl;
          dumpDBL(&levelGrids[lev-1]);

          // now fill in ghost cells
          QuadCFInterp filler(levelGrids[lev], &levelGrids[lev-1],
                              dxVect[lev],
                              nRefVect[lev-1], 1,
                              levelDomains[lev]);

          filler.coarseFineInterp(fineData, crseData);
        }

#ifdef CH_USE_HDF5
      // dump data
      if (writePlots)
        {
          string fname = "interp.hdf5";
          Vector<string> varNames(1,"phi");
          Real dt = 0.0;
          Real time= 0.0;
          WriteAMRHierarchyHDF5(fname, levelGrids,
                                levelData, varNames,
                                levelDomains[0].domainBox(),
                                dxVect[0], dt, time,
                                nRefVect, numLev);
        }
#endif

      // clean up memory
      for (int lev=0; lev<levelData.size(); lev++)
        {
          if (levelData[lev] != NULL)
            {
              delete levelData[lev];
              levelData[lev] = NULL;
            }
        }
    }

    // now test partially periodic case (also coarsen back to original domain
    // no such thing as "partially periodic" for 1D; for 1D, test moving
    // fine-grid boxes from low-end of domain to high-end of domain

    {

      baseDomain.setPeriodic(0,false);
      // try similar tests to the previous case
      int nRef = 2;
      ProblemDomain fineDomain(baseDomain);
      fineDomain.refine(nRef);

      const Box domainBox = baseDomain.domainBox();
      Vector<Box> crseBoxes(1, domainBox);
      Vector<int> crseProcAssign(1,0);
      DisjointBoxLayout crseGrids(crseBoxes, crseProcAssign, baseDomain);

      // note the lack of ghost cells on the base level
      LevelData<FArrayBox> crseData(crseGrids, 1, IntVect::Zero);

      Real dxCrse = 1.0/(baseDomainSize);
      Real dxFine = dxCrse/nRef;
      initData(crseData, dxCrse);

#if (CH_SPACEDIM == 1)
      Vector<Box> fineBoxes(2);
      Vector<int> fineProcAssign(2);

      fineBoxes[0] = Box(12*IntVect::Unit, 15*IntVect::Unit);
      fineBoxes[1] = Box(IntVect(D_DECL6(6,10,10,6,10,10)), IntVect(D_DECL6(11,15,15,11,15,15)));
#else
      // try multiple boxes for fine level
      // note grids are different in this case to allow for all periodic checking
      Vector<Box> fineBoxes(3);
      Vector<int> fineProcAssign(3);

      fineBoxes[0] = Box(IntVect::Zero, 9*IntVect::Unit);
      fineBoxes[1] = Box(IntVect(D_DECL6(6,10,10,6,10,10)), IntVect(D_DECL6(11,15,15,11,15,15)));
      // this box should fail the disjointness test
      //fineBoxes[1] = Box(IntVect(D_DECL(7,10,10)), 17*IntVect::Unit);
      fineBoxes[2] = Box(IntVect(D_DECL6(12,2,0,12,2,0)), IntVect(D_DECL6(15,7,7,15,7,7)));
      //fineBoxes[3] = Box(IntVect(D_DECL(12,12,0)), 15*IntVect::Unit);
#endif

      int loadbalancestatus = LoadBalance(fineProcAssign, fineBoxes);
      CH_assert (loadbalancestatus == 0);

      DisjointBoxLayout fineGrids;
      fineGrids.define(fineBoxes, fineProcAssign, fineDomain);
      LevelData<FArrayBox> fineData(fineGrids, 1, ghostVect);

      // set these to a bogus value to start with
      DataIterator fineDit = fineData.dataIterator();
      for (fineDit.begin(); fineDit.ok(); ++fineDit)
        {
          fineData[fineDit()].setVal(1.0e9);
        }

      FineInterp interpolator(fineGrids, 1, nRef, fineDomain);

      // turn on fine-data averaging even though it's unnecessary
      // since this is a test (so we'd like to know if it's broken)
      bool averageFineData = true;
      interpolator.interpToFine(fineData, crseData, averageFineData);

      // now fill in first layer of ghost cells
      QuadCFInterp filler(fineGrids, &crseGrids, dxFine, nRef, 1,
                          fineDomain);

      filler.coarseFineInterp(fineData, crseData);

      // now fill in remaining ghost cell with extrapolation
      Interval extrapInterval(1,1);
      ExtrapFillPatch extrapFiller(fineGrids, fineDomain,
                                   extrapInterval);

      for (int dir=0; dir<SpaceDim; dir++)
        {
          extrapFiller.fillExtrap(fineData,dir,0,1);
        }

      fineData.exchange(fineData.interval());

    }

  } // if (SpaceDim <= 3)
  pout() << indent << pgmname << ": "
         << ( (status == 0) ? "passed all tests" : "failed at least one test,")
         << endl;

#ifdef CH_MPI
  MPI_Finalize();
#endif
  return status ;
}
예제 #22
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]);
                        }
                    }

                }
        }
    }

}
예제 #23
0
void
LevelFluxRegisterEdge::refluxCurl(LevelData<FluxBox>& a_uCoarse,
                                  Real a_scale)
{
  CH_assert(isDefined());
  CH_assert(a_uCoarse.nComp() == m_nComp);

  SideIterator side;
  // idir is the normal direction to the coarse-fine interface
  for (int idir=0 ; idir<SpaceDim; ++idir)
  {
    for (side.begin(); side.ok(); ++side)
    {
      LevelData<FluxBox>& fineReg = m_fabFine[index(idir, side())];

      // first, create temp LevelData<FluxBox> to hold "coarse flux"
      const DisjointBoxLayout coarseBoxes = m_regCoarse.getBoxes();

      // this fills the place of what used to be m_fabCoarse in the old
      // implementation
      LevelData<FluxBox> coarReg(coarseBoxes, m_nComp, IntVect::Unit);


      // now fill the coarReg with the curl of the stored coarse-level
      // edge-centered flux
      DataIterator crseDit = coarseBoxes.dataIterator();
      for (crseDit.begin(); crseDit.ok(); ++crseDit)
        {
          FluxBox& thisCoarReg = coarReg[crseDit];
          thisCoarReg.setVal(0.0);

          EdgeDataBox& thisEdgeData = m_regCoarse[crseDit];

          for (int edgeDir=0; edgeDir<SpaceDim; edgeDir++)
            {
              if (idir != edgeDir)
                {
                  FArrayBox& crseEdgeDataDir = thisEdgeData[edgeDir];
                  for (int faceDir = 0; faceDir<SpaceDim; faceDir++)
                    {
                      if (faceDir != edgeDir)
                        {
                          FArrayBox& faceData = thisCoarReg[faceDir];
                          int shiftDir = -1;
                          for (int i=0; i<SpaceDim; i++)
                            {
                              if ((i != faceDir) && (i != edgeDir) )
                                {
                                  shiftDir = i;
                                }
                            }
                          CH_assert(shiftDir >= 0);
                          crseEdgeDataDir.shiftHalf(shiftDir, sign(side()));
                          // scaling already taken care of in incrementCrse
                          Real scale = 1.0;
                          faceData.plus(crseEdgeDataDir, scale, 0, 0, faceData.nComp());
                          crseEdgeDataDir.shiftHalf(shiftDir, -sign(side()));
                        } // end if not normal direction
                    } // end loop over face directions
                } // end if edgeDir != idir
            } // end loop over edge directions
        } // end loop over crse boxes


      // first, we need to create a temp LevelData<FluxBox>
      // to make a local copy in the coarse layout space of
      // the fine register increments

      LevelData<FluxBox> fineRegLocal(coarReg.getBoxes(), m_nComp, IntVect::Unit);

      fineReg.copyTo(fineReg.interval(), fineRegLocal,
                     fineRegLocal.interval(),
                     m_crseCopiers[index(idir,side())]);

      for (DataIterator it = a_uCoarse.dataIterator(); it.ok(); ++it)
        {
          // loop over flux components here
          for (int fluxComp=0; fluxComp < SpaceDim; fluxComp++)
            {
              // we don't do anything in the normal direction
              if (fluxComp != idir)
                {
                  // fluxDir is the direction of the face-centered flux
                  FArrayBox& U = a_uCoarse[it()][fluxComp];
                  // set up IntVectSet to avoid double counting of updates
                  Box coarseGridBox = U.box();
                  // transfer to Cell-centered, then create IVS
                  coarseGridBox.shiftHalf(fluxComp,1);
                  IntVectSet nonUpdatedEdges(coarseGridBox);

                  // remember, we want to take the curl here
                  // also recall that fluxComp is the component
                  // of the face-centered curl (not the edge-centered
                  // vector field that we're refluxing, which is why
                  // the sign may seem like it's the opposite of what
                  // you might expect!
                  Real local_scale = -sign(side())*a_scale;
                  //int testDir = (fluxComp+1)%(SpaceDim);
                  if (((fluxComp+1)%(SpaceDim)) == idir)  local_scale *= -1;
                  Vector<IntVectSet>& ivsV =
                    m_refluxLocations[index(idir, side())][it()][fluxComp];
                  Vector<DataIndex>&  indexV =
                    m_coarToCoarMap[index(idir, side())][it()];
                  IVSIterator iv;

                  for (int i=0; i<ivsV.size(); ++i)
                    {
                      iv.define(ivsV[i]);
                      const FArrayBox& coar = coarReg[indexV[i]][fluxComp];
                      const FArrayBox& fine = fineRegLocal[indexV[i]][fluxComp];
                      for (iv.begin(); iv.ok(); ++iv)
                        {
                          IntVect thisIV = iv();
                          if (nonUpdatedEdges.contains(thisIV))
                          {
                            for (int comp=0; comp <m_nComp; ++comp)
                              {
                                //Real coarVal = coar(thisIV, comp);
                                //Real fineVal = fine(thisIV, comp);
                                U(thisIV, comp) -=
                                local_scale*(coar(thisIV, comp)
                                             +fine(thisIV, comp));
                              }
                            nonUpdatedEdges -= thisIV;
                          }
                        }

                    }
                } // end if not normal face
            } // end loop over fluxbox directions
        } // end loop over coarse boxes
    } // end loop over sides
  } // end loop over directions
}
예제 #24
0
// new define
void
LevelFluxRegisterEdge::define(
                              const DisjointBoxLayout& a_dbl,
                              const DisjointBoxLayout& a_dblCoarse,
                              const ProblemDomain& a_dProblem,
                              int a_nRefine,
                              int a_nComp)
{
  m_isDefined = true;
  CH_assert(a_nRefine > 0);
  CH_assert(a_nComp > 0);
  CH_assert(!a_dProblem.isEmpty());
  m_nComp = a_nComp;
  m_nRefine = a_nRefine;
  m_domainCoarse = coarsen(a_dProblem, a_nRefine);
  CH_assert (a_dblCoarse.checkPeriodic(m_domainCoarse));

  // allocate copiers
  m_crseCopiers.resize(SpaceDim*2);

  SideIterator side;

  // create a Vector<Box> of the fine boxes which also includes periodic images,
  // since we don't really care about the processor layouts, etc
  Vector<Box> periodicFineBoxes;
  CFStencil::buildPeriodicVector(periodicFineBoxes, a_dProblem, a_dbl);
  // now coarsen these boxes...
  for (int i=0; i<periodicFineBoxes.size(); i++)
    {
      periodicFineBoxes[i].coarsen(m_nRefine);
    }

  for (int idir=0 ; idir<SpaceDim; ++idir)
  {
    for (side.begin(); side.ok(); ++side)
    {
      // step one, build fineBoxes, flux register boxes
      // indexed by the fine level but in the coarse index
      // space
      DisjointBoxLayout fineBoxes,tmp;
      // first create coarsened dbl, then compute flux register boxes
      // adjacent to coarsened fine boxes
      coarsen(tmp, a_dbl, m_nRefine);
      if (side() == Side::Lo)
        {
          adjCellLo(fineBoxes, tmp, idir,1);
        }
      else
        {
          adjCellHi(fineBoxes, tmp, idir,1);
        }

      // now define the FluxBoxes of fabFine on this DisjointBoxLayout
      m_fabFine[index(idir, side())].define(fineBoxes, a_nComp);



      LayoutData<Vector<Vector<IntVectSet> > >& ivsetsVect
        = m_refluxLocations[index(idir, side())];
      ivsetsVect.define(a_dblCoarse);

      LayoutData<Vector<DataIndex> >& mapsV =
        m_coarToCoarMap[index(idir, side())];
      mapsV.define(a_dblCoarse);

      DisjointBoxLayout coarseBoxes = a_dblCoarse;
      DataIterator dit = a_dblCoarse.dataIterator();
      for (dit.begin(); dit.ok(); ++dit)
        {
          unsigned int thisproc = a_dblCoarse.procID(dit());
          if (thisproc == procID())
          {
            ivsetsVect[DataIndex(dit())].resize(SpaceDim);
          }
          const Box& coarseBox = a_dblCoarse[dit()];
          int count = 0;
          for (int i=0; i<periodicFineBoxes.size(); i++)
            {
              Box regBox;
              if (side() == Side::Lo)
                {
                  regBox = adjCellLo(periodicFineBoxes[i], idir, 1);
                }
              else
                {
                  regBox = adjCellHi(periodicFineBoxes[i], idir, 1);
                }

              // do this little dance in order to ensure that
              // we catch corner cells which might be in different
              // boxes.
              Box testBox(regBox);
              testBox.grow(1);
              testBox.grow(idir,-1);
              if (testBox.intersectsNotEmpty(coarseBox))
                {
                  testBox &= coarseBox;
                  ++count;
                  unsigned int proc = a_dblCoarse.procID(dit());
                  const DataIndex index = DataIndex(dit());
                  if (proc == procID())
                  {
                    mapsV[DataIndex(dit())].push_back(index);
                    // loop over face directions here
                    for (int faceDir=0; faceDir<SpaceDim; faceDir++)
                    {
                      // do nothing in normal direction
                      if (faceDir != idir)
                      {
                        // this should give us the face indices for the
                        // faceDir-centered faces adjacent to the coarse-fine
                        // interface which are contained in the current
                        // coarse box
                        Box intersectBox(regBox);
                        Box coarseEdgeBox(coarseBox);
                        coarseEdgeBox.surroundingNodes(faceDir);
                        intersectBox.surroundingNodes(faceDir);
                        intersectBox &= coarseEdgeBox;
                        intersectBox.shiftHalf(faceDir,1);
                        IntVectSet localIV(intersectBox);
                        ivsetsVect[DataIndex(dit())][faceDir].push_back(localIV);
                      }
                    }
                  }
                }
            } // end loop over boxes on coarse level
        }
      m_regCoarse.define(coarseBoxes, a_nComp, IntVect::Unit);

      // last thing to do is to define copiers
      m_crseCopiers[index(idir, side())].define(fineBoxes, coarseBoxes,
                                                IntVect::Unit);
    }
  }
}
예제 #25
0
파일: compare.cpp 프로젝트: rsnemmen/Chombo
// 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
}
예제 #26
0
void TimeInterpolatorRK4::intermediate(/// intermediate RK4 solution on this level coarsened
                                       LevelData<FArrayBox>&   a_U,
                                       /// time interpolation coefficient in range [0:1]
                                       const Real&             a_timeInterpCoeff,
                                       /// which RK4 stage:  0, 1, 2, 3
                                       const int&              a_stage,
                                       /// interval of a_U to fill in
                                       const Interval&         a_intvl) const
{
  CH_assert(m_defined);
  CH_assert(m_gotFullTaylorPoly);
  CH_assert(a_U.nComp() == m_numStates);
  CH_assert(a_stage >= 0);
  CH_assert(a_stage < 4);

  Real rinv = 1. / Real(m_refineCoarse);
  Vector<Real> intermCoeffs(4);
  // 0 is coefficient of m_taylorCoeffs[0] = Ucoarse(0)
  // 1 is coefficient of m_taylorCoeffs[1] =           K1
  // 2 is coefficient of m_taylorCoeffs[2] = 1/2 * (-3*K1 + 2*K2 + 2*K3 - K4)
  // 3 is coefficient of m_taylorCoeffs[3] = 2/3 * (   K1 -   K2 -   K3 + K4)
  Real diff12Coeffs;
  // coefficient of m_diff12               =              -   K2 +   K3
  switch (a_stage)
    {
    case 0:
      intermCoeffs[0] = 1.;
      intermCoeffs[1] = a_timeInterpCoeff;
      intermCoeffs[2] = a_timeInterpCoeff * a_timeInterpCoeff;
      intermCoeffs[3] = a_timeInterpCoeff * a_timeInterpCoeff  * a_timeInterpCoeff;
      diff12Coeffs = 0.;
      break;
    case 1:
      intermCoeffs[0] = 1.;
      intermCoeffs[1] = 0.5*rinv + a_timeInterpCoeff;
      intermCoeffs[2] = a_timeInterpCoeff * (rinv + a_timeInterpCoeff);
      intermCoeffs[3] = a_timeInterpCoeff * a_timeInterpCoeff * (1.5*rinv + a_timeInterpCoeff);
      diff12Coeffs = 0.;
      break;
    case 2:
      intermCoeffs[0] = 1.;
      intermCoeffs[1] = 0.5*rinv + a_timeInterpCoeff;
      intermCoeffs[2] = 0.5*rinv*rinv + a_timeInterpCoeff * (rinv + a_timeInterpCoeff);
      intermCoeffs[3] = 0.375*rinv*rinv*rinv + a_timeInterpCoeff * (1.5*rinv*rinv + a_timeInterpCoeff * (1.5*rinv + a_timeInterpCoeff));
      diff12Coeffs = -0.25 * rinv * rinv;
      break;
    case 3:
      intermCoeffs[0] = 1.;
      intermCoeffs[1] = rinv + a_timeInterpCoeff;
      intermCoeffs[2] = rinv*rinv + a_timeInterpCoeff * (2.*rinv + a_timeInterpCoeff);
      intermCoeffs[3] = 0.75*rinv*rinv*rinv + a_timeInterpCoeff * (3.*rinv*rinv + a_timeInterpCoeff * (3.*rinv + a_timeInterpCoeff));
      diff12Coeffs = 0.5 * rinv * rinv;
      break;
    default:
      MayDay::Error("TimeInterpolatorRK4::intermediate must have a_stage in range 0:3");
    }
  LevelData<FArrayBox> UComp;
  aliasLevelData(UComp, &a_U, a_intvl);

  // For i in 0:m_numCoeffs-1,
  // coeffFirst[i] is index of first component of m_taylorCoeffs
  // that corresponds to a coefficient of t^i.
  Vector<int> coeffFirst(m_numCoeffs);
  int intervalLength = a_intvl.size();
  for (int i = 0; i < m_numCoeffs; i++)
    {
      coeffFirst[i] = a_intvl.begin() + i * m_numStates;
    }

  DataIterator dit = UComp.dataIterator();
  for (dit.begin(); dit.ok(); ++dit)
    {
      FArrayBox& UFab = UComp[dit];
      const FArrayBox& taylorFab = m_taylorCoeffs[dit];

      // WAS:  Evaluate a0 + a1*t + a2*t^2 + a3*t^3
      // as a0 + t * (a1 + t * (a2 + t * a3)):
      // that is, set UFab to
      // a3, t*a3 + a2, t*(t*a3 + a2) + a1, t*(t*(t*a3 + a2) + a1) * a0.

      // NEW:  Evaluate a0*c0 + a1*c1 + a2*c2 + a3*c3,
      // where c0, c1, c2, c3 are scalars,
      // and c0 = intermCoeffs[0] = 1.
      UFab.copy(taylorFab, coeffFirst[0], 0, intervalLength);
      for (int ind = 1; ind < 4; ind++)
        {
          UFab.plus(taylorFab, intermCoeffs[ind],
                    coeffFirst[ind], 0, intervalLength);
        }
      const FArrayBox& diff12Fab = m_diff12[dit];
      UFab.plus(diff12Fab, diff12Coeffs, 0, 0, intervalLength);
    }
  // dummy statement in order to get around gdb bug
  int dummy_unused = 0; dummy_unused = 0;
}
예제 #27
0
// Create tags for regridding
void AMRLevelPluto::tagCells(IntVectSet& a_tags) 
{
  CH_assert(allDefined());

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

  // Create tags based on undivided gradient of density
  const DisjointBoxLayout& levelDomain = m_UNew.disjointBoxLayout();
  IntVectSet localTags;
  // If there is a coarser level interpolate undefined ghost cells
  if (m_hasCoarser)
  {
    const AMRLevelPluto* amrGodCoarserPtr = getCoarserLevel();

    PiecewiseLinearFillPluto pwl;

    pwl.define(levelDomain,
               amrGodCoarserPtr->m_UNew.disjointBoxLayout(),
               m_numStates,
               amrGodCoarserPtr->m_problem_domain,
               amrGodCoarserPtr->m_ref_ratio,
               m_dx,
               1);

    pwl.fillInterp(m_UNew,
                   amrGodCoarserPtr->m_UNew,
                   amrGodCoarserPtr->m_UNew,
                   1.0,
                   0,
                   0,
                   m_numStates);
  }
  m_UNew.exchange(Interval(0,m_numStates-1));

  #if GEOMETRY != CARTESIAN
   const LevelData<FArrayBox>& dV = m_levelPluto.getdV();
  #endif

  // Compute relative gradient
  DataIterator dit = levelDomain.dataIterator();
  for (dit.begin(); dit.ok(); ++dit){
    const Box& b = levelDomain[dit()];
    FArrayBox gradFab(b,1);
    FArrayBox& UFab = m_UNew[dit()];

    #if GEOMETRY != CARTESIAN
     const FArrayBox& curdV = dV[dit()];
    #else
     const FArrayBox curdV;
    #endif

    m_patchPluto->computeRefGradient(gradFab, UFab, curdV, b); 

    // Tag where gradient exceeds threshold
    BoxIterator bit(b);
    for (bit.begin(); bit.ok(); ++bit){
      const IntVect& iv = bit();
      if (gradFab(iv) >= m_refineThresh) {
        localTags |= iv;
      }
    }
  }

  localTags.grow(m_tagBufferSize);

  // Need to do this in two steps unless a IntVectSet::operator &=
  // (ProblemDomain) operator is defined
  Box localTagsBox = localTags.minBox();
  localTagsBox &= m_problem_domain;
  localTags &= localTagsBox;

  a_tags = localTags;
}
예제 #28
0
int
main(int argc, char** argv)
{
  //This test is an attempt to test linearization
  //of eb data holders directly

  int eekflag=0;
#ifdef CH_MPI
  MPI_Init(&argc, &argv);
#endif
  //begin forever present scoping trick
  {
    //registerDebugger();

    // Set up some geometry.
    Box domain;
    Real dx;

    do_geo( domain, dx );

    Vector<Box> boxes(1, domain);
    Vector<int> procs(1, 0);
    // Make a layout for the space.
    DisjointBoxLayout dbl(boxes, procs);

    // Fill in the layout with the geometrical info.
    EBISLayout ebisl;
    EBIndexSpace *ebisPtr = Chombo_EBIS::instance();
    ebisPtr->fillEBISLayout(ebisl, dbl, domain, 1 );

    // Define the leveldata for my one and only level.
    DataIterator dit = dbl.dataIterator();
    for ( dit.begin(); dit.ok(); ++dit )
      {
        eekflag = testIVFAB(ebisl[dit()], dbl.get(dit()));
        if (eekflag != 0)
          {
            pout() << "IVFAB linearization test failed " << endl;
            return eekflag;
          }
        eekflag = testIFFAB(ebisl[dit()], dbl.get(dit()));
        if (eekflag != 0)
          {
            pout() << "IFFAB  linearization test failed " << endl;
            return eekflag;
          }
        eekflag = testEBCellFAB(ebisl[dit()], dbl.get(dit()));
        if (eekflag != 0)
          {
            pout() << "EBCellFAB  linearization test failed " << endl;
            return eekflag;
          }
        eekflag = testEBFaceFAB(ebisl[dit()], dbl.get(dit()));
        if (eekflag != 0)
          {
            pout() << "EBFaceFAB  linearization test failed " << endl;
            return eekflag;
          }

        eekflag = testEBFluxFAB(ebisl[dit()], dbl.get(dit()));
        if (eekflag != 0)
          {
            pout() << "EBFluxFAB  linearization test failed " << endl;
            return eekflag;
          }
      }

    ebisPtr->clear();

  }//end scoping trick
  pout() << "linearization tests passed "<< endl;
#ifdef CH_MPI
  MPI_Finalize();
#endif
  return eekflag;
}
예제 #29
0
int
main(int argc ,char *argv[] )
{

#ifdef CH_MPI
  MPI_Init(&argc, &argv);
#endif
  parseTestOptions(argc, argv);

  // establish periodic domain -- first multiply periodic in all directions
  int status = 0;
  int baseDomainSize = 8;
  int numGhost = 2;
  IntVect ghostVect(numGhost*IntVect::Unit);

  Box baseDomBox(IntVect::Zero, (baseDomainSize-1)*IntVect::Unit);
  ProblemDomain baseDomain(baseDomBox);

  // set periodic in all directions
  for (int dir=0; dir<SpaceDim; dir++)
    {
      baseDomain.setPeriodic(dir, true);
    }

  // quick check
  //  should be (3^SpaceDim) -1 vectors
  int numVect =0;
  if (verbose) pout() << "ShiftIterator shift vectors:" << endl;
  ShiftIterator sit1 = baseDomain.shiftIterator();
  for (sit1.begin(); sit1.ok(); ++sit1)
    {
      numVect++;
      if (verbose) pout() << "   " << sit1() << endl;
    }
  Real exact =  pow(3.0,SpaceDim) -1;
  Real eps = 0.0001;
  if ((exact - numVect) > eps)
    {
      //fail
      if (verbose)
        {
          pout() << "failed ShiftIterator count test " << endl;
        }
      status += 1;
    }

  ShiftIterator sit2 = baseDomain.shiftIterator();

  {
    // first try a single box on this level
    if (verbose) pout() <<  "Single box test -- " << endl;

    Vector<Box> levelBoxes(1, baseDomBox);
    Vector<int> procAssign(1, 0);
    DisjointBoxLayout levelGrids(levelBoxes,procAssign, baseDomain);

    LevelData<FArrayBox> tester(levelGrids, 1, ghostVect);

    Real dx = 1.0/baseDomainSize;

    initData(tester, dx);

    // test exchange in this case -- should fill ghost cells with
    // periodically copied data
    if (verbose) pout() << "    begin exchange..." << endl;

    Interval comps = tester.interval();
    tester.exchange(comps);
    if (verbose) pout() << "    done exchange..." << endl;
    DataIterator dit = tester.dataIterator();

    for (dit.begin(); dit.ok(); ++dit)
      {
        FArrayBox& testFab = tester[dit()];
        // now check to be sure that this passed
        for (int dir=0; dir<SpaceDim; dir++)
          {
            if (verbose) pout() << "check lo cells in dir " << dir << endl;
            Box loGhostBox = adjCellLo(baseDomBox, dir, numGhost);
            BoxIterator loBit(loGhostBox);
            for (loBit.begin(); loBit.ok(); ++loBit)
              {
                const IntVect iv = loBit();
                IntVect validLoc = iv;
                validLoc.shift(dir, baseDomBox.size(dir));
                for (int comp=0; comp<tester.nComp(); comp++)
                  {
                    Real validVal = dataVal(validLoc, comp);
                    if (testFab(iv, comp) != validVal)
                      {
                        if (verbose)
                          {
                            pout() << "failed single-box exchange test at "
                                   << iv << endl;
                          }
                        status += 10;
                      }
                  }
              } // end loop over lo ghost cells

            if (verbose) pout() << "check hi cells in dir " << dir << endl;
            Box hiGhostBox = adjCellHi(baseDomBox, dir, numGhost);
            BoxIterator hiBit(hiGhostBox);
            for (hiBit.begin(); hiBit.ok(); ++hiBit)
              {
                const IntVect iv = hiBit();
                IntVect validLoc = iv;
                validLoc.shift(dir, -baseDomBox.size(dir));
                for (int comp=0; comp<tester.nComp(); comp++)
                  {
                    Real validVal = dataVal(validLoc, comp);
                    if (testFab(iv, comp) != validVal)
                      {
                        if (verbose)
                          {
                            pout() << "failed single-box exchange test at "
                                   << iv << endl;
                          }
                        status += 100;
                      }
                  }
              } // end loop over hi ghost cells
          } // end loop over directions
      } // end loop over boxes
    if (verbose) pout() << "done single-box test" << endl;
  } // end single-box test

  // now try refining things, this time look at 2 boxes
  baseDomain.refine(2);
  {
    if (verbose) pout() << "2-box test..." << endl;

    const Box domainBox = baseDomain.domainBox();
    Vector<Box> levelBoxes1(1, domainBox);
    Vector<int> procAssign1(1,0);
    DisjointBoxLayout levelGrids1(levelBoxes1, procAssign1, baseDomain);

    LevelData<FArrayBox> tester0(levelGrids1, 1, IntVect::Zero);
    LevelData<FArrayBox> tester1(levelGrids1, 1, ghostVect);

    Real dx = 1.0/(2.0*baseDomainSize);
    initData(tester1, dx);
    initData(tester0, dx);

    // first test exchange for single box
    Interval comps = tester1.interval();
    Copier ex;
    ex.exchangeDefine(levelGrids1, ghostVect);
    pout() << "copier = " << ex << endl;
    tester1.exchange(comps, ex);

    // now try multiple boxes
    Vector<Box> levelBoxes2(3);
    Vector<int> procAssign2(3);

    if (SpaceDim == 1)
      {
        // do this a little differently in 1d
        levelBoxes2[0] = Box(IntVect::Zero, 9*IntVect::Unit);
        levelBoxes2[1] = Box(10*IntVect::Unit, 11*IntVect::Unit);
        levelBoxes2[2] = Box(14*IntVect::Unit, 15*IntVect::Unit);
      }
    else
      {
        levelBoxes2[0] = Box(IntVect::Zero, 9*IntVect::Unit);
        levelBoxes2[1] = Box(IntVect(D_DECL6(7,10,10,10,10,10)),
                             15*IntVect::Unit);
        // this box should fail the disjointness test
        //levelBoxes2[1] = Box(IntVect(D_DECL6(7,10,10,10,10,10)),17*IntVect::Unit);
        levelBoxes2[2] = Box(IntVect(D_DECL6(11,0,0,0,0,0)),
                             IntVect(D_DECL6(15,7,7,7,7,7)));
      }

    int loadbalancestatus = LoadBalance(procAssign2, levelBoxes2);
    CH_assert (loadbalancestatus == 0);

    DisjointBoxLayout levelGrids2;
    levelGrids2.define(levelBoxes2, procAssign2, baseDomain);
    LevelData<FArrayBox> tester2(levelGrids2, 1, ghostVect);

    if (verbose) pout() << "    begin copyTo test" << endl;
    tester0.copyTo(comps, tester2, comps);
    if (verbose) pout() << "    done copyTo, now test values" << endl;
    // check that periodic copies worked OK:

    DataIterator dit2 = tester2.dataIterator();
    for (dit2.begin(); dit2.ok(); ++dit2)
      {
        const Box& thisBox = tester2[dit2()].box();
        if (!domainBox.contains(thisBox))
          {
            FArrayBox& destFab = tester2[dit2];
            for (int dir=0; dir<SpaceDim; dir++)
              {
                if (verbose)
                  {
                    pout() << "      check lo cells in dir "
                           << dir << endl;
                  }

                Box loGhost = adjCellLo(domainBox, dir, numGhost);
                loGhost &= thisBox;
                if (!loGhost.isEmpty())
                {
                  BoxIterator loBit(loGhost);
                  for (loBit.begin(); loBit.ok(); ++loBit)
                    {
                      IntVect iv = loBit();
                      IntVect srcIV = iv;
                      srcIV.shift(dir, domainBox.size(dir));
                      for (int comp=0; comp<destFab.nComp(); comp++)
                        {
                          Real validVal = dataVal(srcIV, comp);
                          if (validVal != destFab(iv, comp))
                            {
                              if (verbose)
                                {
                                  pout() << "failed multi-box copy test at "
                                         << iv << endl;
                                }
                              status += 1000;
                            } // end if we fail test
                        } // end loop over components
                    } // end loop over ghost cells outside domain
                } // end if there are lo-end ghost cells

                if (verbose)
                  {
                    pout() << "      check hi cells in dir "
                           << dir << endl;
                  }

                Box hiGhost = adjCellHi(domainBox, dir, numGhost);
                hiGhost &= thisBox;
                if (!hiGhost.isEmpty())
                  {
                    BoxIterator hiBit(hiGhost);
                    for (hiBit.begin(); hiBit.ok(); ++hiBit)
                      {
                        IntVect iv = hiBit();
                        IntVect srcIV = iv;
                        srcIV.shift(dir, -domainBox.size(dir));
                        for (int comp=0; comp<destFab.nComp(); comp++)
                          {
                            Real validVal = dataVal(srcIV, comp);
                            if (validVal != destFab(iv, comp))
                              {
                                if (verbose)
                                  {
                                    pout() << "failed multi-box copy test at "
                                           << iv << endl;
                                  }
                                status += 10000;
                              } // end if we fail test
                          } // end loop over components
                      } // end loop over high-end ghost cells
                  } // end if there are hi-end ghost cells

              } // end loop over directions
          } // end if there are ghost cells
      } // end loop over grids in destination
    if (verbose) pout() << "done 2-box test" << endl;
  }

  // this last test makes no sense in 1D
  if (SpaceDim > 1)
    {
      if (verbose) pout() << "partially-periodic case" << endl;
      // now test partially periodic case (also coarsen back to original domain)
      baseDomain.coarsen(2);
      baseDomain.setPeriodic(0,false);

      // try similar tests to the second case, only coarsened
      const Box domainBox = baseDomain.domainBox();
      Vector<Box> levelBoxes1(1, domainBox);
      Vector<int> procAssign1(1,0);
      DisjointBoxLayout levelGrids1(levelBoxes1, procAssign1, baseDomain);

      LevelData<FArrayBox> tester0(levelGrids1, 1, IntVect::Zero);
      LevelData<FArrayBox> tester1(levelGrids1, 1, ghostVect);

      Real dx = 1.0/(baseDomainSize);
      initData(tester1, dx);
      initData(tester0, dx);

      if (verbose) pout() << "    partially-periodic exchange..." << endl;
      // first test exchange for single box
      Interval comps = tester1.interval();
      tester1.exchange(comps);

      if (verbose) pout() << "    ....  done" << endl;

      if (verbose) pout() << "   multi-box partially periodic case" << endl;
      // now try multiple boxes
      Vector<Box> levelBoxes2(3);
      Vector<int> procAssign2(3);

      levelBoxes2[0] = Box(IntVect::Zero, 4*IntVect::Unit);
      levelBoxes2[1] = Box(IntVect(D_DECL6(3,5,5,5,5,5)), 7*IntVect::Unit);
      // this box should fail the disjointness test
      //levelBoxes2[1] = Box(IntVect(D_DECL6(3,5,5)), 10*IntVect::Unit);
      levelBoxes2[2] = Box(IntVect(D_DECL6(6,0,0,0,0,0)),
                           IntVect(D_DECL6(7,1,1,1,1,1)));

      int loadbalancestatus = LoadBalance(procAssign2, levelBoxes2);
      CH_assert (loadbalancestatus == 0);

      DisjointBoxLayout levelGrids2(levelBoxes2, procAssign2, baseDomain);
      LevelData<FArrayBox> tester2(levelGrids2, 1, ghostVect);

      tester0.copyTo(comps, tester2, comps);

      if (verbose) pout() << "done partially-periodic case" << endl;

      // We don't care about the results of these -- just want to see if they compile:
      if ( argc == 12345 )
      {
        tester0.apply( leveldataApplyFunc );
        tester0.apply( LevelDataApplyFunctor(3.14159) );
      }
    }

  // I'm thinking all pout()'s should be before MPI_Finalize... (ndk)
  pout() << indent << pgmname << ": "
         << ( (status == 0) ? "passed all tests" : "failed at least one test,")
         << endl;


#ifdef CH_MPI
  MPI_Finalize();
#endif

  return status ;
}
예제 #30
0
void VCAMRPoissonOp2::looseGSRB(LevelData<FArrayBox>&       a_phi,
                               const LevelData<FArrayBox>& a_rhs)
{
  CH_TIME("VCAMRPoissonOp2::looseGSRB");
#if 1
  MayDay::Abort("VCAMRPoissonOp2::looseGSRB - Not implemented");
#else
  // This implementation converges at half the rate of "levelGSRB" in
  // multigrid solves
  CH_assert(a_phi.isDefined());
  CH_assert(a_rhs.isDefined());
  CH_assert(a_phi.ghostVect() >= IntVect::Unit);
  CH_assert(a_phi.nComp() == a_rhs.nComp());

  // Recompute the relaxation coefficient if needed.
  resetLambda();

  const DisjointBoxLayout& dbl = a_phi.disjointBoxLayout();

  DataIterator dit = a_phi.dataIterator();

  // fill in intersection of ghostcells and a_phi's boxes
  {
    CH_TIME("VCAMRPoissonOp2::looseGSRB::homogeneousCFInterp");
    homogeneousCFInterp(a_phi);
  }

  {
    CH_TIME("VCAMRPoissonOp2::looseGSRB::exchange");
    a_phi.exchange(a_phi.interval(), m_exchangeCopier);
  }

  // now step through grids...
  for (dit.begin(); dit.ok(); ++dit)
  {
    // invoke physical BC's where necessary
    {
      CH_TIME("VCAMRPoissonOp2::looseGSRB::BCs");
      m_bc(a_phi[dit], dbl[dit()], m_domain, m_dx, true);
    }

    const Box& region = dbl.get(dit());
    const FluxBox& thisBCoef  = (*m_bCoef)[dit];

    int whichPass = 0;

#if CH_SPACEDIM == 1
    FORT_GSRBHELMHOLTZVC1D
#elif CH_SPACEDIM == 2
    FORT_GSRBHELMHOLTZVC2D
#elif CH_SPACEDIM == 3
    FORT_GSRBHELMHOLTZVC3D
#else
    This_will_not_compile!
#endif
                          (CHF_FRA(a_phi[dit]),
                           CHF_CONST_FRA(a_rhs[dit]),
                           CHF_BOX(region),
                           CHF_CONST_REAL(m_dx),
                           CHF_CONST_REAL(m_alpha),
                           CHF_CONST_FRA((*m_aCoef)[dit]),
                           CHF_CONST_REAL(m_beta),
#if CH_SPACEDIM >= 1
                           CHF_CONST_FRA(thisBCoef[0]),
#endif
#if CH_SPACEDIM >= 2
                           CHF_CONST_FRA(thisBCoef[1]),
#endif
#if CH_SPACEDIM >= 3
                           CHF_CONST_FRA(thisBCoef[2]),
#endif
#if CH_SPACEDIM >= 4
                           This_will_not_compile!
#endif
                           CHF_CONST_FRA(m_lambda[dit]),
                           CHF_CONST_INT(whichPass));

    whichPass = 1;

#if CH_SPACEDIM == 1
    FORT_GSRBHELMHOLTZVC1D
#elif CH_SPACEDIM == 2
    FORT_GSRBHELMHOLTZVC2D
#elif CH_SPACEDIM == 3
    FORT_GSRBHELMHOLTZVC3D
#else
    This_will_not_compile!
#endif
                          (CHF_FRA(a_phi[dit]),
                           CHF_CONST_FRA(a_rhs[dit]),
                           CHF_BOX(region),
                           CHF_CONST_REAL(m_dx),
                           CHF_CONST_REAL(m_alpha),
                           CHF_CONST_FRA((*m_aCoef)[dit]),
                           CHF_CONST_REAL(m_beta),
#if CH_SPACEDIM >= 1
                           CHF_CONST_FRA(thisBCoef[0]),
#endif
#if CH_SPACEDIM >= 2
                           CHF_CONST_FRA(thisBCoef[1]),
#endif
#if CH_SPACEDIM >= 3
                           CHF_CONST_FRA(thisBCoef[2]),
#endif
#if CH_SPACEDIM >= 4
                           This_will_not_compile!
#endif
                           CHF_CONST_FRA(m_lambda[dit]),
                           CHF_CONST_INT(whichPass));
  } // end loop through grids
#endif
}