DisplayScreen::DisplayScreen(ExportScreen* _export_screen, int _screen_width, int _screen_height):
    window_height(420), window_width(337), paused(false), export_screen(_export_screen),
    screen_height(_screen_height), screen_width(_screen_width)
{
    // Initialise SDL Video */
    if (SDL_Init(SDL_INIT_VIDEO) < 0) {
        fprintf(stderr, "Could not initialize SDL: %s\n", SDL_GetError());
        exit(1);
    }

    screen = SDL_SetVideoMode(window_width,window_height, 0, SDL_HWPALETTE|SDL_DOUBLEBUF|SDL_RESIZABLE);
	
    if (screen == NULL) {
        fprintf(stderr, "Couldn't Initialize Screen: %s\n", SDL_GetError());
        exit(-1);
    }

    // Set the screen title
    SDL_WM_SetCaption("A.L.E. Viz", NULL);

    // Initialize our screen matrix
    for (int i=0; i<screen_height; ++i) { 
        IntVect row;
        for (int j=0; j<screen_width; ++j)
            row.push_back(-1);
        screen_matrix.push_back(row);
    }

    // Register ourselves as an event handler
    registerEventHandler(this);

    fprintf(stderr, "Screen Display Active. Press 'h' for help.\n");
}
Ejemplo n.º 2
0
const IntVect
BoxLib::coarsen (const IntVect& p1,
		 const IntVect& p2)
{
    IntVect v = p1;
    return v.coarsen(p2);
}
Ejemplo n.º 3
0
 // the contents of v are blown out
 void ExplicitBitVect::getOnBits (IntVect& v) const {
   unsigned int nOn = getNumOnBits();
   if(!v.empty()) IntVect().swap(v);
   v.reserve(nOn);
   for(unsigned int i=0;i<d_size;i++){
     if((bool)(*dp_bits)[i]) v.push_back(i);
   }
 };
Ejemplo n.º 4
0
const IntVect
BoxLib::coarsen (const IntVect& p,
		 int            s)
{
    BL_ASSERT(s > 0);
    IntVect v = p;
    return v.coarsen(IntVect(D_DECL(s,s,s)));
}
Ejemplo n.º 5
0
BoxList&
BoxList::maxSize (const IntVect& chunk)
{
    for (iterator bli = begin(), End = end(); bli != End; ++bli)
    {
        IntVect boxlen = bli->size();
        const int* len = boxlen.getVect();

        for (int i = 0; i < BL_SPACEDIM; i++)
        {
            if (len[i] > chunk[i])
            {
                //
                // Reduce by powers of 2.
                //
                int ratio = 1;
                int bs    = chunk[i];
                int nlen  = len[i];
                while ((bs%2 == 0) && (nlen%2 == 0))
                {
                    ratio *= 2;
                    bs    /= 2;
                    nlen  /= 2;
                }
                //
                // Determine number and size of (coarsened) cuts.
                //
                const int numblk = nlen/bs + (nlen%bs ? 1 : 0);
                const int size   = nlen/numblk;
                const int extra  = nlen%numblk;
                //
                // Number of cuts = number of blocks - 1.
                //
                for (int k = 0; k < numblk-1; k++)
                {
                    //
                    // Compute size of this chunk, expand by power of 2.
                    //
                    const int ksize = (k < extra ? size+1 : size) * ratio;
                    //
                    // Chop from high end.
                    //
                    const int pos = bli->bigEnd(i) - ksize + 1;

                    push_back(bli->chop(i,pos));
                }
            }
        }
        //
        // b has been chopped down to size and pieces split off
        // have been added to the end of the list so that they
        // can be checked for splitting (in other directions) later.
        //
    }
    return *this;
}
Ejemplo n.º 6
0
// """ -------------------------------------------------------
//
// getOnBits(IntVect &which)
//  C++: Passes the set of on bits out in the IntVect passed in.
//   The contents of IntVect are destroyed.
//
//  Python: Returns the tuple of on bits
//
// """ -------------------------------------------------------
void SparseBitVect::getOnBits(IntVect &v) const {
  if (!dp_bits) {
    throw ValueErrorException("BitVect not properly initialized.");
  }
  unsigned int nOn = getNumOnBits();
  if (!v.empty()) IntVect().swap(v);
  v.reserve(nOn);
  v.resize(nOn);
  std::copy(dp_bits->begin(), dp_bits->end(), v.begin());
};
Ejemplo n.º 7
0
void
Box::next (IntVect&   p,
           const int* shv) const
{
    BL_ASSERT(contains(p));

#if   BL_SPACEDIM==1
    p.shift(0,shv[0]);
#elif BL_SPACEDIM==2
    p.shift(0,shv[0]);
    if (!(p <= bigend))
    {
        //
        // Reset 1 coord is on edge, and 2 coord is incremented.
        //
        p.setVal(0,smallend[0]);
        p.shift(1,shv[1]);
    }
#elif BL_SPACEDIM==3
    p.shift(0,shv[0]);
    if (!(p <= bigend))
    {
        //
        // Reset 1 coord is on edge, and 2 coord is incremented.
        //
        p.setVal(0,smallend[0]);
        p.shift(1,shv[1]);
        if(!(p <= bigend))
        {
            p.setVal(1,smallend[1]);
            p.shift(2,shv[2]);
        }
    }
#endif
}
Ejemplo n.º 8
0
/* ***************************************************************************
 *  This is a temporary method, used for preparing a demo video.
 *  It should be pretty much ignored!
 * ***************************************************************************/
Action SearchAgent::tmp_prepare_demo_vid(void) {
	if (i_frame_counter < 1250) {
		return PLAYER_A_NOOP;
	}
	if (i_frame_counter < 1300) {
		return PLAYER_A_DOWN;
	}
	str_curr_state = save_state();
	// initilize the screen_matrix
	if (pm_sim_scr_matrix == NULL) {
		pm_sim_scr_matrix = new IntMatrix;
		assert(i_screen_height > 0);
		assert(i_screen_width > 0);
		for (int i = 0; i < i_screen_height; i++) {
			IntVect row;
			for (int j = 0; j < i_screen_width; j++) {
				row.push_back(-1);
			}
			pm_sim_scr_matrix->push_back(row);
		}
	}
	char buffer [50];
	ostringstream filename;
	MediaSource& mediasrc = p_osystem->console().mediaSource();
	for (int a = 0; a < i_num_actions; a++) {
		load_state(str_curr_state);
		GameController::apply_action(p_sim_event_obj, PLAYER_A_NOOP, PLAYER_B_NOOP);
		p_osystem->myTimingInfo.start = p_osystem->getTicks();
		mediasrc.update(); 
		Action curr_act = (*p_game_settings->pv_possible_actions)[a];
		filename.str("");
		filename << "action_" << action_to_string(curr_act)  << "_00.png";
		p_osystem->p_export_screen->save_png(pm_sim_scr_matrix, filename.str());
		for (int i = 0; i < 15; i++) {
			GameController::apply_action(p_sim_event_obj, curr_act, PLAYER_B_NOOP);
			p_osystem->myTimingInfo.start = p_osystem->getTicks();
			mediasrc.update(); 
			copy_simulated_framebuffer();
			sprintf (buffer, "%02d", i + 1);
			filename.str("");
			filename << "action_" << action_to_string(curr_act) << "_" 
					 << buffer << ".png";
			p_osystem->p_export_screen->save_png(pm_sim_scr_matrix, filename.str());
		}
	}
	end_game();
	return UNDEFINED;
	
}
Ejemplo n.º 9
0
    void average_down (MultiFab& S_fine, MultiFab& S_crse, 
                       int scomp, int ncomp, const IntVect& ratio)
    {
        BL_ASSERT(S_crse.nComp() == S_fine.nComp());

        //
        // Coarsen() the fine stuff on processors owning the fine data.
        //
        BoxArray crse_S_fine_BA = S_fine.boxArray(); crse_S_fine_BA.coarsen(ratio);

        MultiFab crse_S_fine(crse_S_fine_BA,ncomp,0);

#ifdef _OPENMP
#pragma omp parallel
#endif
        for (MFIter mfi(crse_S_fine,true); mfi.isValid(); ++mfi)
        {
            //  NOTE: The tilebox is defined at the coarse level.
            const Box& tbx = mfi.tilebox();

            //  NOTE: We copy from component scomp of the fine fab into component 0 of the crse fab
            //        because the crse fab is a temporary which was made starting at comp 0, it is
            //        not part of the actual crse multifab which came in.

            BL_FORT_PROC_CALL(BL_AVGDOWN,bl_avgdown)
                (tbx.loVect(), tbx.hiVect(),
                 BL_TO_FORTRAN_N(S_fine[mfi],scomp),
                 BL_TO_FORTRAN_N(crse_S_fine[mfi],0),
                 ratio.getVect(),&ncomp);
        }

        S_crse.copy(crse_S_fine,0,scomp,ncomp);
   }
Ejemplo n.º 10
0
T1* FoldFingerprint(const T1& bv1, unsigned int factor) {
  if (factor <= 0 || factor >= bv1.getNumBits())
    throw ValueErrorException("invalid fold factor");

  int initSize = bv1.getNumBits();
  int resSize = initSize / factor;
  T1* res = new T1(resSize);

  IntVect onBits;
  bv1.getOnBits(onBits);
  for (IntVectIter iv = onBits.begin(); iv != onBits.end(); iv++) {
    int pos = (*iv) % resSize;
    res->setBit(pos);
  }
  return res;
}
Ejemplo n.º 11
0
void
Box::next (IntVect& p) const
{
    BL_ASSERT(contains(p));

    p.shift(0,1);
#if BL_SPACEDIM==2
    if (!(p <= bigend))
    {
        p.setVal(0,smallend[0]);
        p.shift(1,1);
    }
#elif BL_SPACEDIM==3
    if (!(p <= bigend))
    {
        p.setVal(0,smallend[0]);
        p.shift(1,1);
        if (!(p <= bigend))
        {
            p.setVal(1,smallend[1]);
            p.shift(2,1);
        }
    }
#endif
}
Ejemplo n.º 12
0
/* *********************************************************************
	Initilizes the Simulation Engine
	This involves generating a new OSystem and loadign settings for it
 ******************************************************************** */
void SearchAgent::init_simulation_engine() {
	p_sim_event_obj = p_osystem->event();
	p_sim_console = &(p_osystem->console());
	p_sim_system = &(p_sim_console->system());

	// Initilize the screen matrix and RAM vector
	if (p_game_settings->b_uses_screen_matrix) {
		pm_sim_scr_matrix = new IntMatrix;
		assert(i_screen_height > 0);
		assert(i_screen_width > 0);
		for (int i = 0; i < i_screen_height; i++) {
			IntVect row;
			for (int j = 0; j < i_screen_width; j++) {
				row.push_back(-1);
			}
			pm_sim_scr_matrix->push_back(row);
		}
	} else {
		pm_sim_scr_matrix = NULL;
	}
	pv_sim_ram_content = new IntVect(RAM_LENGTH);
}
Ejemplo n.º 13
0
void
CellBilinear::interp (const FArrayBox&  crse,
                      int               crse_comp,
                      FArrayBox&        fine,
                      int               fine_comp,
                      int               ncomp,
                      const Box&        fine_region,
                      const IntVect &   ratio,
                      const Geometry& /*crse_geom*/,
                      const Geometry& /*fine_geom*/,
                      Array<BCRec>&   /*bcr*/,
                      int               actual_comp,
                      int               actual_state)
{
    BL_PROFILE("CellBilinear::interp()");
#if (BL_SPACEDIM == 3)
    BoxLib::Error("interp: not implemented");
#endif
    //
    // Set up to call FORTRAN.
    //
    const int* clo = crse.box().loVect();
    const int* chi = crse.box().hiVect();
    const int* flo = fine.loVect();
    const int* fhi = fine.hiVect();
    const int* lo  = fine_region.loVect();
    const int* hi  = fine_region.hiVect();
    int num_slope  = D_TERM(2,*2,*2)-1;
    int len0       = crse.box().length(0);
    int slp_len    = num_slope*len0;

    Array<Real> slope(slp_len);

    int strp_len = len0*ratio[0];

    Array<Real> strip(strp_len);

    int strip_lo = ratio[0] * clo[0];
    int strip_hi = ratio[0] * chi[0];

    const Real* cdat  = crse.dataPtr(crse_comp);
    Real*       fdat  = fine.dataPtr(fine_comp);
    const int* ratioV = ratio.getVect();

    FORT_CBINTERP (cdat,ARLIM(clo),ARLIM(chi),ARLIM(clo),ARLIM(chi),
                   fdat,ARLIM(flo),ARLIM(fhi),ARLIM(lo),ARLIM(hi),
                   D_DECL(&ratioV[0],&ratioV[1],&ratioV[2]),&ncomp,
                   slope.dataPtr(),&num_slope,strip.dataPtr(),&strip_lo,&strip_hi,
                   &actual_comp,&actual_state);
}
Ejemplo n.º 14
0
    void average_down (MultiFab& S_fine, MultiFab& S_crse, const Geometry& fgeom, const Geometry& cgeom, 
                       int scomp, int ncomp, const IntVect& ratio)
    {
  
        if (S_fine.is_nodal() || S_crse.is_nodal())
        {
            BoxLib::Error("Can't use BoxLib::average_down for nodal MultiFab!");
        }

#if (BL_SPACEDIM == 3)
	BoxLib::average_down(S_fine, S_crse, scomp, ncomp, ratio);
	return;
#else

        BL_ASSERT(S_crse.nComp() == S_fine.nComp());

        //
        // Coarsen() the fine stuff on processors owning the fine data.
        //
	const BoxArray& fine_BA = S_fine.boxArray();
        BoxArray crse_S_fine_BA = fine_BA; 
	crse_S_fine_BA.coarsen(ratio);

        MultiFab crse_S_fine(crse_S_fine_BA,ncomp,0);

	MultiFab fvolume;
	fgeom.GetVolume(fvolume, fine_BA, 0);

#ifdef _OPENMP
#pragma omp parallel
#endif
        for (MFIter mfi(crse_S_fine,true); mfi.isValid(); ++mfi)
        {
            //  NOTE: The tilebox is defined at the coarse level.
            const Box& tbx = mfi.tilebox();

            //  NOTE: We copy from component scomp of the fine fab into component 0 of the crse fab
            //        because the crse fab is a temporary which was made starting at comp 0, it is
            //        not part of the actual crse multifab which came in.
            BL_FORT_PROC_CALL(BL_AVGDOWN_WITH_VOL,bl_avgdown_with_vol)
                (tbx.loVect(), tbx.hiVect(),
                 BL_TO_FORTRAN_N(S_fine[mfi],scomp),
                 BL_TO_FORTRAN_N(crse_S_fine[mfi],0),
                 BL_TO_FORTRAN(fvolume[mfi]),
                 ratio.getVect(),&ncomp);
	}

        S_crse.copy(crse_S_fine,0,scomp,ncomp);
#endif
   }
Ejemplo n.º 15
0
// -----------------------------------------------------------------------------
// Adds coarse cell values directly to all overlying fine cells.
// -----------------------------------------------------------------------------
void ConstInterpPS::prolongIncrement (LevelData<FArrayBox>&       a_phiThisLevel,
                                      const LevelData<FArrayBox>& a_correctCoarse)
{
    CH_TIME("ConstInterpPS::prolongIncrement");

    // Gather grids, domains, refinement ratios...
    const DisjointBoxLayout& fineGrids = a_phiThisLevel.getBoxes();
    const DisjointBoxLayout& crseGrids = a_correctCoarse.getBoxes();
    CH_assert(fineGrids.compatible(crseGrids));

    const ProblemDomain& fineDomain = fineGrids.physDomain();
    const ProblemDomain& crseDomain = crseGrids.physDomain();

    const IntVect mgRefRatio = fineDomain.size() / crseDomain.size();
    CH_assert(mgRefRatio.product() > 1);

    DataIterator dit = fineGrids.dataIterator();
    for (dit.reset(); dit.ok(); ++dit) {
        // Create references for convenience
        FArrayBox& fineFAB = a_phiThisLevel[dit];
        const FArrayBox& crseFAB = a_correctCoarse[dit];
        const Box& fineValid = fineGrids[dit];

        // To make things easier, we will offset the
        // coarse and fine data boxes to zero.
        const IntVect& fiv = fineValid.smallEnd();
        const IntVect civ = coarsen(fiv, mgRefRatio);

        // Correct the fine data
        FORT_CONSTINTERPPS (
            CHF_FRA_SHIFT(fineFAB, fiv),
            CHF_CONST_FRA_SHIFT(crseFAB, civ),
            CHF_BOX_SHIFT(fineValid, fiv),
            CHF_CONST_INTVECT(mgRefRatio));
    }
}
Ejemplo n.º 16
0
void DenseIntVectSet::refine(int iref)
{
  if (iref == 1) return;
  if (isEmpty()) return;
  CH_assert(iref >= 1);
  //int refinements = iref/2;
  CH_assert((iref/2)*2 == iref); // check iref for power of 2
  Box newDomain(m_domain);
  newDomain.refine(iref);
  DenseIntVectSet newSet(newDomain, false);
  IntVect iv;
  BoxIterator bit(newDomain);
  int count=0;
  for (bit.begin(); bit.ok(); ++bit, ++count)
    {
      iv = bit();
      iv.coarsen(iref);
      if (this->operator[](iv))
        {
          newSet.m_bits.setTrue(count);
        }
    }
  *this = newSet;
}
Ejemplo n.º 17
0
/**
   @brief Compute the norm of a dual vector (specified by coefficients in the dual basis).

   @param A              input lattice
   @param b              coefficients of shortest dual vector
   @return
*/
template <class ZT> int dual_length(Float &norm, ZZ_mat<ZT> &A, const IntVect &coords)
{
  int d = coords.size();
  if (A.get_rows() != d)
  {
    cerr << "DSVP length error: Coefficient vector has wrong dimension: ";
    cerr << A.get_rows() << " vs " << d << endl;
    return 1;
  }
  FloatVect coords_d(d);
  for (int i = 0; i < d; i++)
  {
    coords_d[i] = coords[i].get_d();
  }

  IntMatrix empty_mat;
  MatGSO<Integer, Float> gso(A, empty_mat, empty_mat, GSO_INT_GRAM);
  if (!gso.update_gso())
  {
    cerr << "GSO Failure." << endl;
    return 1;
  }
  Float tmp;
  gso.get_r(tmp, d - 1, d - 1);
  tmp.pow_si(tmp, -1);

  FloatVect alpha(d);
  Float mu, alpha2, r_inv;
  norm = 0.0;
  for (int i = 0; i < d; i++)
  {
    alpha[i] = coords_d[i];
    for (int j = 0; j < i; j++)
    {
      gso.get_mu(mu, i, j);
      alpha[i] -= mu * alpha[j];
    }
    gso.get_r(r_inv, i, i);
    r_inv.pow_si(r_inv, -1);
    alpha2.pow_si(alpha[i], 2);
    norm += alpha2 * r_inv;
  }

  return 0;
}
Ejemplo n.º 18
0
bool RSIBC::tagCellsInit(FArrayBox& markFAB,const Real& threshold)
{
    // If grid spacing > R0 refine otherwise only refine the nucleation patch
    if(m_dx > m_R0)
    {
        // pout() << m_dx << "  " << m_R0 << endl;
        markFAB.setVal(1,bdryLo(m_domain.domainBox(),1,1) & markFAB.box(),0);
    }
    else
    {
        IntVect nucSm;
        IntVect nucBg;
        if(SpaceDim > 0)
        {
            nucSm.setVal(0,floor(m_x0/m_dx));
            nucBg.setVal(0, ceil(m_x0/m_dx));
        }
        if(SpaceDim > 1)
        {
            nucSm.setVal(1,0);
            nucBg.setVal(1,0);
        }
        if(SpaceDim > 2)
        {
            nucSm.setVal(2,floor(m_x0/m_dx));
            nucBg.setVal(2, ceil(m_x0/m_dx));
        }
        markFAB.setVal(1,Box(nucSm,nucBg)& markFAB.box(),0);
    }

    // pout() << m_domain << endl;
    // FORT_ALLBOUNDREFINE(
    //     CHF_FRA1(markFAB,0),
    //     CHF_CONST_REAL(threshold),
    //     CHF_BOX(markFAB.box()));
    return true;
}
Ejemplo n.º 19
0
void
NodeBilinear::interp (const FArrayBox&  crse,
                      int               crse_comp,
                      FArrayBox&        fine,
                      int               fine_comp,
                      int               ncomp,
                      const Box&        fine_region,
                      const IntVect&    ratio,
                      const Geometry& /*crse_geom */,
                      const Geometry& /*fine_geom */,
                      Array<BCRec>&   /*bcr*/,
                      int               actual_comp,
                      int               actual_state)
{
    BL_PROFILE("NodeBilinear::interp()");
    //
    // Set up to call FORTRAN.
    //
    const int* clo = crse.box().loVect();
    const int* chi = crse.box().hiVect();
    const int* flo = fine.loVect();
    const int* fhi = fine.hiVect();
    const int* lo  = fine_region.loVect();
    const int* hi  = fine_region.hiVect();
    int num_slope  = D_TERM(2,*2,*2)-1;
    int len0       = crse.box().length(0);
    int slp_len    = num_slope*len0;

    Array<Real> strip(slp_len);

    const Real* cdat  = crse.dataPtr(crse_comp);
    Real*       fdat  = fine.dataPtr(fine_comp);
    const int* ratioV = ratio.getVect();

    FORT_NBINTERP (cdat,ARLIM(clo),ARLIM(chi),ARLIM(clo),ARLIM(chi),
                   fdat,ARLIM(flo),ARLIM(fhi),ARLIM(lo),ARLIM(hi),
                   D_DECL(&ratioV[0],&ratioV[1],&ratioV[2]),&ncomp,
                   strip.dataPtr(),&num_slope,&actual_comp,&actual_state);
}
Ejemplo n.º 20
0
    // Average fine face-based MultiFab onto crse fine-centered MultiFab.
    // This routine assumes that the crse BoxArray is a coarsened version of the fine BoxArray.
    void average_down_faces (PArray<MultiFab>& fine, PArray<MultiFab>& crse, IntVect& ratio)
    {
	BL_ASSERT(crse.size()  == BL_SPACEDIM);
	BL_ASSERT(fine.size()  == BL_SPACEDIM);
	BL_ASSERT(crse[0].nComp() == 1);
	BL_ASSERT(fine[0].nComp() == 1);

#ifdef _OPENMP
#pragma omp parallel
#endif
        for (int n=0; n<BL_SPACEDIM; ++n) {
            for (MFIter mfi(crse[n],true); mfi.isValid(); ++mfi)
            {
                const Box& tbx = mfi.tilebox();

                BL_FORT_PROC_CALL(BL_AVGDOWN_FACES,bl_avgdown_faces)
                    (tbx.loVect(),tbx.hiVect(),
                     BL_TO_FORTRAN(fine[n][mfi]),
                     BL_TO_FORTRAN(crse[n][mfi]),
                     ratio.getVect(),n);
            }
        }
    }
Ejemplo n.º 21
0
bool SWIBC::tagCellsInit(FArrayBox& markFAB,const Real& threshold)
{
    // We do this here becauase we need m_dx to be set, and it isn't set when
    // the object is defined
    if(!m_isPatchBoxSet)
    {
        m_patchBoxes.resize(m_numPatches);
        // Loop over all the patches and figure out the boxes
        for(int itor = 0; itor < m_numPatches; itor ++)
        {
            IntVect nucSm;
            IntVect nucBg;
            int offSet = 0;
            if(SpaceDim > 0)
            {
                nucSm.setVal(0,floor((m_fricBoxCenter[0]+m_xcPatches[itor]-m_xwPatches[itor])/m_dx));
                nucBg.setVal(0, ceil((m_fricBoxCenter[0]+m_xcPatches[itor]+m_xwPatches[itor])/m_dx));
            }
            if(SpaceDim > 1)
            {
                nucSm.setVal(1,0);
                nucBg.setVal(1,0);
            }
            if(SpaceDim > 2)
            {
                nucSm.setVal(2,floor((m_fricBoxCenter[1]+m_zcPatches[itor]-m_zwPatches[itor])/m_dx));
                nucBg.setVal(2, ceil((m_fricBoxCenter[1]+m_zcPatches[itor]+m_zwPatches[itor])/m_dx));
            }
            m_patchBoxes[itor] = Box(nucSm,nucBg);
            m_smoothWidthNumCells = ceil(m_smoothValue / m_dx / 2);
            m_isPatchBoxSet = true;
        }
    }

    for(int itor = 0; itor < m_numPatches; itor ++)
    {
        markFAB.setVal(1,m_patchBoxes[itor] & markFAB.box(),0);
    }
    // markFAB.setVal(1,markFAB.box(),0);
    // for(int itor = 0; itor < m_patchBoxes.capacity(); itor++)
    // {
    //     markFAB.setVal(1,adjCellLo(m_patchBoxes[itor],0, m_smoothWidthNumCells) & markFAB.box(),0);
    //     markFAB.setVal(1,adjCellHi(m_patchBoxes[itor],0, m_smoothWidthNumCells) & markFAB.box(),0);
    //     markFAB.setVal(1,adjCellLo(m_patchBoxes[itor],0,-m_smoothWidthNumCells) & markFAB.box(),0);
    //     markFAB.setVal(1,adjCellHi(m_patchBoxes[itor],0,-m_smoothWidthNumCells) & markFAB.box(),0);
    //     if(SpaceDim > 2)
    //     {
    //         markFAB.setVal(1,adjCellLo(m_patchBoxes[itor],2, m_smoothWidthNumCells) & markFAB.box(),0);
    //         markFAB.setVal(1,adjCellHi(m_patchBoxes[itor],2, m_smoothWidthNumCells) & markFAB.box(),0);
    //         markFAB.setVal(1,adjCellLo(m_patchBoxes[itor],2,-m_smoothWidthNumCells) & markFAB.box(),0);
    //         markFAB.setVal(1,adjCellHi(m_patchBoxes[itor],2,-m_smoothWidthNumCells) & markFAB.box(),0);
    //     }
    // }

    // FORT_BOUNDREFINE(
    //     CHF_FRA1(markFAB,0),
    //     CHF_CONST_REAL(refLocation),
    //     CHF_CONST_REAL(m_dx),
    //     CHF_BOX(b));
    return true;
}
Ejemplo n.º 22
0
// clean out BC from stencil of cell a_iv
void 
PetscCompGridVTO::applyBCs( IntVect a_iv, int a_ilev, const DataIndex &di_dummy, Box a_dombox, 
                            StencilTensor &a_sten )
{
  CH_TIME("PetscCompGridVTO::applyBCs");
  Vector<Vector<StencilNode> > new_vals; // StencilTensorValue
  
  RefCountedPtr<BCFunction> bc = m_bc.getBCFunction();
  CompGridVTOBC *mybc = dynamic_cast<CompGridVTOBC*>(&(*bc));
  
  // count degrees, add to 'corners'
  Vector<IntVectSet> corners(CH_SPACEDIM);
  StencilTensor::const_iterator end2 = a_sten.end(); 
  for (StencilTensor::const_iterator it = a_sten.begin(); it != end2; ++it) 
    {
      const IntVect &jiv = it->first.iv();
      if (!a_dombox.contains(jiv) && it->first.level()==a_ilev) // a BC
        {
          int degree = CH_SPACEDIM-1;
          for (int dir=0;dir<CH_SPACEDIM;++dir)
            {
              if (jiv[dir] >= a_dombox.smallEnd(dir) && jiv[dir] <= a_dombox.bigEnd(dir)) degree--;
            }
          CH_assert(degree>=0);
          corners[degree] |= jiv;
        }
    }
  // move ghosts starting at with high degree corners and cascade to lower degree
  for (int ideg=CH_SPACEDIM-1;ideg>=0;ideg--)
    {
      // iterate through list
      for (IVSIterator ivit(corners[ideg]); ivit.ok(); ++ivit)
        {
          const IntVect &jiv = ivit(); // get rid of this bc ghost
          // get layer of ghost
          Box gbox(IntVect::Zero,IntVect::Zero); gbox.shift(jiv);
          Box inter = a_dombox & gbox;    CH_assert(inter.numPts()==0);
          int igid = -1; // find which layer of ghost I am
          do{
            igid++;
            gbox.grow(1);
            inter = a_dombox & gbox;
          }while (inter.numPts()==0);
	  if (igid!=0) MayDay::Error("PetscCompGridVTO::applyBCs layer???");
          for (int dir=0;dir<CH_SPACEDIM;++dir)
            {
              if (jiv[dir] < a_dombox.smallEnd(dir) || jiv[dir] > a_dombox.bigEnd(dir))
		{ // have a BC, get coefs on demand
		  int iside = 1; // hi
		  int isign = 1;
                  if (jiv[dir] < a_dombox.smallEnd(dir)) isign = -1;
		  if (jiv[dir] < a_dombox.smallEnd(dir)) iside = 0; // lo
		  if (!mybc) MayDay::Error("PetscCompGridVTO::applyBCs: wrong BC!!!!");
		  new_vals.resize(1);
		  new_vals[0].resize(1); 
		  //new_vals[i][j].second.setValue(mybc->getCoef(j,i));
                  for (int comp=0; comp<SpaceDim; comp++)
                    {
		      new_vals[0][0].second.define(1);
                      if (mybc->m_bcDiri[dir][iside][comp]) new_vals[0][0].second.setValue(comp,comp,-1.); // simple diagonal 
                      else new_vals[0][0].second.setValue(comp,comp,1.);
                    } // end loop over components
                  new_vals[0][0].first.setLevel(a_ilev);
		  
		  IndexML kill(jiv,a_ilev);
		  IntVect biv = jiv;
		  biv.shift(dir,-isign*(igid+1));                 
		  new_vals[igid][0].first.setIV(biv);
		  if (ideg>0 && !a_dombox.contains(biv)) // this could be a new stencil value for high order BCs
		    {
		      corners[ideg-1] |= biv; // send down to lower list for later removal
		    }
		  else CH_assert(a_dombox.contains(biv));
		
		  StencilProject(kill,new_vals[igid],a_sten);
		  int nrm = a_sten.erase(kill); CH_assert(nrm==1);
		  break;
		} // BC
	    } // spacedim
	} // ghosts
    } // degree
}
Ejemplo n.º 23
0
void EBPoissonOp::
getOpFaceStencil(VoFStencil&             a_stencil,
                 const Vector<VolIndex>& a_allMonotoneVoFs,
                 const EBISBox&          a_ebisbox,
                 const VolIndex&         a_VoF,
                 int                     a_dir,
                 const Side::LoHiSide&   a_side,
                 const FaceIndex&        a_face,
                 const bool&             a_lowOrder)
{
  a_stencil.clear();

  const RealVect& faceCentroid = a_ebisbox.centroid(a_face);
  const IntVect& origin = a_VoF.gridIndex();

  IntVect dirs = IntVect::Zero;

  for (int idir = 0; idir < SpaceDim; idir++)
    {
      if (idir != a_dir)
        {
          IntVect ivPlus = origin;
          ivPlus[idir] += 1;
          if (faceCentroid[idir] < 0.0)
            {
              dirs[idir] = -1;
            }
          else if (faceCentroid[idir] > 0.0)
            {
              dirs[idir] = 1;
            }
          else if (m_eblg.getDomain().contains(ivPlus))
            {
              dirs[idir] = 1;
            }
          else
            {
              dirs[idir] = -1;
            }
        }
    }

  bool orderOne = true;

  if (m_orderEB == 0 || a_lowOrder)
    {
      orderOne = false;
    }
  else
    {
      IntVect loVect = dirs;
      loVect.min(IntVect::Zero);

      IntVect hiVect = dirs;
      hiVect.max(IntVect::Zero);

      Box fluxBox(loVect,hiVect);
      IntVectSet fluxIVS(fluxBox);

      IVSIterator ivsit(fluxIVS);
      for (ivsit.begin(); ivsit.ok(); ++ivsit)
        {
          bool curOkay;

          IntVect ivDelta = ivsit();

          IntVect iv1 = ivDelta;
          iv1 += origin;

          VolIndex VoF1;

          curOkay = EBArith::isVoFHere(VoF1,a_allMonotoneVoFs,iv1);

          IntVect iv2 = iv1;
          iv2[a_dir] += sign(a_side);

          VolIndex VoF2;

          curOkay = curOkay && EBArith::isVoFHere(VoF2,a_allMonotoneVoFs,iv2);

          orderOne = orderOne && curOkay;

          if (curOkay)
            {
              VoFStencil curPair;
              curPair.add(VoF1,-m_invDx2[a_dir]);
              curPair.add(VoF2, m_invDx2[a_dir]);

              for (int idir = 0; idir < SpaceDim; idir++)
                {
                  if (idir != a_dir)
                    {
                      if (ivDelta[idir] == 0)
                        {
                          curPair *= 1 - abs(faceCentroid[idir]);
                        }
                      else
                        {
                          curPair *= abs(faceCentroid[idir]);
                        }
                    }
                }
              a_stencil += curPair;
            }
        }
    }

  if (!orderOne)
    {
      VolIndex VoF1 = a_VoF;
      VolIndex VoF2 = a_face.getVoF(a_side);

      if (a_ebisbox.getRegion().contains(VoF2.gridIndex()))
        {
          a_stencil.clear();

          a_stencil.add(VoF1,-m_invDx2[a_dir]);
          a_stencil.add(VoF2, m_invDx2[a_dir]);
        }
    }
  if (!a_lowOrder)
    {
      a_stencil *= a_ebisbox.areaFrac(a_face);
    }
}
Ejemplo n.º 24
0
void TestSortTable()
{
	{
		typedef std::pair<int, int> IntPair;
		typedef std::vector<IntPair> IntVect;
		typedef IntVect::iterator IntVectIter;


		IntVect test;
		IntVect checked;

 		test.push_back(make_pair(10, 0));
		test.push_back(make_pair(9, 1));
		test.push_back(make_pair(3, 2));
		test.push_back(make_pair(3, 3));
		test.push_back(make_pair(5, 4));
		test.push_back(make_pair(5, 5));
		test.push_back(make_pair(5, 6));
		test.push_back(make_pair(1, 7));


		
		checked.push_back( make_pair(1, 7)); 
		checked.push_back( make_pair(3, 2)); 
		checked.push_back( make_pair(3, 3)); 
		checked.push_back( make_pair(5, 4)); 
		checked.push_back( make_pair(5, 5)); 
		checked.push_back( make_pair(5, 6)); 
		checked.push_back( make_pair(9, 1)); 
		checked.push_back( make_pair(10, 0)); 
		
		stable_sort(test.begin(), test.end());


		bool res = std::equal(test.cbegin(), test.cend(), checked.cbegin(),
			[](const IntPair& left, const IntPair& right)->bool
			{
				return (left.first == right.first) && (left.second == right.second);
			}
		);
		CHECK_RESULTS(res);
	}
}
Ejemplo n.º 25
0
IntVect
iMultiFab::maxIndex (int comp,
                    int nghost) const
{
    BL_ASSERT(nghost >= 0 && nghost <= n_grow);

    IntVect loc;

    int mx = -std::numeric_limits<int>::max();

#ifdef _OPENMP
#pragma omp parallel
#endif
    {
	IntVect priv_loc;
	int priv_mx = -std::numeric_limits<int>::max();

	for (MFIter mfi(*this); mfi.isValid(); ++mfi)
	{
	    const Box& box = BoxLib::grow(mfi.validbox(),nghost);
	    const int  lmx = get(mfi).max(box,comp);
	    
	    if (lmx > priv_mx)
	    {
		priv_mx  = lmx;
		priv_loc = get(mfi).maxIndex(box,comp);
	    }
	}

#ifdef _OPENMP
#pragma omp critical (imultifab_maxindex)
#endif
	{
	    if (priv_mx > mx) {
		mx = priv_mx;
		loc = priv_loc;
	    }
	}
    }

    const int NProcs = ParallelDescriptor::NProcs();

    if (NProcs > 1)
    {
        Array<int> mxs(1);
        Array<int>  locs(1);

        if (ParallelDescriptor::IOProcessor())
        {
            mxs.resize(NProcs);
            locs.resize(NProcs*BL_SPACEDIM);
        }

        const int IOProc = ParallelDescriptor::IOProcessorNumber();

        ParallelDescriptor::Gather(&mx, 1, mxs.dataPtr(), 1, IOProc);

        BL_ASSERT(sizeof(IntVect) == sizeof(int)*BL_SPACEDIM);

        ParallelDescriptor::Gather(loc.getVect(), BL_SPACEDIM, locs.dataPtr(), BL_SPACEDIM, IOProc);

        if (ParallelDescriptor::IOProcessor())
        {
            mx  = mxs[0];
            loc = IntVect(D_DECL(locs[0],locs[1],locs[2]));

            for (int i = 1; i < NProcs; i++)
            {
                if (mxs[i] > mx)
                {
                    mx = mxs[i];

                    const int j = BL_SPACEDIM * i;

                    loc = IntVect(D_DECL(locs[j+0],locs[j+1],locs[j+2]));
                }
            }
        }

        ParallelDescriptor::Bcast(const_cast<int*>(loc.getVect()), BL_SPACEDIM, IOProc);
    }

    return loc;
}
Ejemplo n.º 26
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 ;
}
Ejemplo n.º 27
0
// -----------------------------------------------------------------------------
// Adds coarse cell values directly to all overlying fine cells,
// then removes the average from the fine result.
// -----------------------------------------------------------------------------
void ZeroAvgConstInterpPS::prolongIncrement (LevelData<FArrayBox>&       a_phiThisLevel,
                                             const LevelData<FArrayBox>& a_correctCoarse)
{
    CH_TIME("ZeroAvgConstInterpPS::prolongIncrement");

    // Gather grids, domains, refinement ratios...
    const DisjointBoxLayout& fineGrids = a_phiThisLevel.getBoxes();
    const DisjointBoxLayout& crseGrids = a_correctCoarse.getBoxes();
    CH_assert(fineGrids.compatible(crseGrids));

    const ProblemDomain& fineDomain = fineGrids.physDomain();
    const ProblemDomain& crseDomain = crseGrids.physDomain();

    const IntVect mgRefRatio = fineDomain.size() / crseDomain.size();
    CH_assert(mgRefRatio.product() > 1);

    // These will accumulate averaging data.
    Real localSum = 0.0;
    Real localVol = 0.0;
    CH_assert(!m_CCJinvPtr.isNull());
    CH_assert(m_dxProduct > 0.0);

    DataIterator dit = fineGrids.dataIterator();
    for (dit.reset(); dit.ok(); ++dit) {
        // Create references for convenience
        FArrayBox& fineFAB = a_phiThisLevel[dit];
        const FArrayBox& crseFAB = a_correctCoarse[dit];
        const Box& fineValid = fineGrids[dit];
        const FArrayBox& JinvFAB = (*m_CCJinvPtr)[dit];

        // To make things easier, we will offset the
        // coarse and fine data boxes to zero.
        const IntVect& fiv = fineValid.smallEnd();
        const IntVect civ = coarsen(fiv, mgRefRatio);

        // Correct the fine data
        FORT_CONSTINTERPWITHAVGPS (
            CHF_FRA_SHIFT(fineFAB, fiv),
            CHF_CONST_FRA_SHIFT(crseFAB, civ),
            CHF_BOX_SHIFT(fineValid, fiv),
            CHF_CONST_INTVECT(mgRefRatio),
            CHF_CONST_FRA1_SHIFT(JinvFAB,0,fiv),
            CHF_CONST_REAL(m_dxProduct),
            CHF_REAL(localVol),
            CHF_REAL(localSum));
    }

    // Compute global sum (this is where the MPI communication happens)
#ifdef CH_MPI
    Real globalSum = 0.0;
    int result = MPI_Allreduce(&localSum, &globalSum, 1, MPI_CH_REAL, MPI_SUM, Chombo_MPI::comm);

    if (result != MPI_SUCCESS) {
        MayDay::Error("Sorry, but I had a communication error in ZeroAvgConstInterpPS::prolongIncrement");
    }

    Real globalVol = 0.0;
    result = MPI_Allreduce(&localVol, &globalVol, 1, MPI_CH_REAL, MPI_SUM, Chombo_MPI::comm);

    if (result != MPI_SUCCESS) {
        MayDay::Error("Sorry, but I had a communication error in ZeroAvgConstInterpPS::prolongIncrement");
    }

#else
    Real globalSum = localSum;
    Real globalVol = localVol;
#endif

    // Remove the average from phi.
    Real avgPhi = globalSum / globalVol;
    for (dit.reset(); dit.ok(); ++dit) {
        a_phiThisLevel[dit] -= avgPhi;
    }
}