void MultiGrid::interpolate (MultiFab& f, const MultiFab& c) { BL_PROFILE("MultiGrid::interpolate()"); // // Use fortran function to interpolate up (prolong) c to f // Note: returns f=f+P(c) , i.e. ADDS interp'd c to f. // // OMP over boxes #ifdef _OPENMP #pragma omp parallel #endif for (MFIter mfi(c); mfi.isValid(); ++mfi) { const int k = mfi.index(); const Box& bx = c.boxArray()[k]; const int nc = f.nComp(); const FArrayBox& cfab = c[mfi]; FArrayBox& ffab = f[mfi]; FORT_INTERP(ffab.dataPtr(), ARLIM(ffab.loVect()), ARLIM(ffab.hiVect()), cfab.dataPtr(), ARLIM(cfab.loVect()), ARLIM(cfab.hiVect()), bx.loVect(), bx.hiVect(), &nc); } }
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); }
void MultiGrid::average (MultiFab& c, const MultiFab& f) { BL_PROFILE("MultiGrid::average()"); // // Use Fortran function to average down (restrict) f to c. // const bool tiling = true; #ifdef _OPENMP #pragma omp parallel #endif for (MFIter cmfi(c,tiling); cmfi.isValid(); ++cmfi) { BL_ASSERT(c.boxArray().get(cmfi.index()) == cmfi.validbox()); const int nc = c.nComp(); const Box& bx = cmfi.tilebox(); FArrayBox& cfab = c[cmfi]; const FArrayBox& ffab = f[cmfi]; FORT_AVERAGE(cfab.dataPtr(), ARLIM(cfab.loVect()), ARLIM(cfab.hiVect()), ffab.dataPtr(), ARLIM(ffab.loVect()), ARLIM(ffab.hiVect()), bx.loVect(), bx.hiVect(), &nc); } }
void Nyx::strang_second_step (Real time, Real dt, MultiFab& S_new, MultiFab& D_new) { BL_PROFILE("Nyx::strang_second_step()"); Real half_dt = 0.5*dt; int min_iter = 100000; int max_iter = 0; int min_iter_grid; int max_iter_grid; // Set a at the half of the time step in the second strang const Real a = get_comoving_a(time-half_dt); MultiFab reset_e_src(S_new.boxArray(), S_new.DistributionMap(), 1, NUM_GROW); reset_e_src.setVal(0.0); reset_internal_energy(S_new,D_new,reset_e_src); compute_new_temp (S_new,D_new); #ifndef FORCING { const Real z = 1.0/a - 1.0; fort_interp_to_this_z(&z); } #endif #ifdef _OPENMP #pragma omp parallel private(min_iter_grid,max_iter_grid) reduction(min:min_iter) reduction(max:max_iter) #endif for (MFIter mfi(S_new,true); mfi.isValid(); ++mfi) { // Here bx is just the valid region const Box& bx = mfi.tilebox(); min_iter_grid = 100000; max_iter_grid = 0; integrate_state (bx.loVect(), bx.hiVect(), BL_TO_FORTRAN(S_new[mfi]), BL_TO_FORTRAN(D_new[mfi]), &a, &half_dt, &min_iter_grid, &max_iter_grid); if (S_new[mfi].contains_nan(bx,0,S_new.nComp())) { std::cout << "NANS IN THIS GRID " << bx << std::endl; } min_iter = std::min(min_iter,min_iter_grid); max_iter = std::max(max_iter,max_iter_grid); } ParallelDescriptor::ReduceIntMax(max_iter); ParallelDescriptor::ReduceIntMin(min_iter); if (heat_cool_type == 1) if (ParallelDescriptor::IOProcessor()) std::cout << "Min/Max Number of Iterations in Second Strang: " << min_iter << " " << max_iter << std::endl; }
void ABec4::aCoefficients (const MultiFab& _a) { BL_ASSERT(_a.ok()); BL_ASSERT(_a.boxArray() == (acoefs[0])->boxArray()); invalidate_a_to_level(0); MultiFab::Copy(*acoefs[0],_a,0,0,acoefs[0]->nComp(),acoefs[0]->nGrow()); }
void ABec4::bCoefficients (const MultiFab& _b) { BL_ASSERT(_b.ok()); BL_ASSERT(_b.boxArray() == (bcoefs[0])->boxArray()); invalidate_b_to_level(0); MultiFab::Copy(*bcoefs[0],_b,0,0,bcoefs[0]->nComp(),bcoefs[0]->nGrow()); }
void advance (MultiFab& old_phi, MultiFab& new_phi, PArray<MultiFab>& flux, Real time, Real dt, const Geometry& geom, PhysBCFunct& physbcf, BCRec& bcr) { // Fill the ghost cells of each grid from the other grids // includes periodic domain boundaries old_phi.FillBoundary(geom.periodicity()); // Fill physical boundaries physbcf.FillBoundary(old_phi, time); int Ncomp = old_phi.nComp(); int ng_p = old_phi.nGrow(); int ng_f = flux[0].nGrow(); const Real* dx = geom.CellSize(); // // Note that this simple example is not optimized. // The following two MFIter loops could be merged // and we do not have to use flux MultiFab. // // Compute fluxes one grid at a time for ( MFIter mfi(old_phi); mfi.isValid(); ++mfi ) { const Box& bx = mfi.validbox(); compute_flux(old_phi[mfi].dataPtr(), &ng_p, flux[0][mfi].dataPtr(), flux[1][mfi].dataPtr(), #if (BL_SPACEDIM == 3) flux[2][mfi].dataPtr(), #endif &ng_f, bx.loVect(), bx.hiVect(), (geom.Domain()).loVect(), (geom.Domain()).hiVect(), bcr.vect(), &dx[0]); } // Advance the solution one grid at a time for ( MFIter mfi(old_phi); mfi.isValid(); ++mfi ) { const Box& bx = mfi.validbox(); update_phi(old_phi[mfi].dataPtr(), new_phi[mfi].dataPtr(), &ng_p, flux[0][mfi].dataPtr(), flux[1][mfi].dataPtr(), #if (BL_SPACEDIM == 3) flux[2][mfi].dataPtr(), #endif &ng_f, bx.loVect(), bx.hiVect(), &dx[0] , &dt); } }
// // What's the slowest way I can think of to compute all the norms?? // Real MFNorm (const MultiFab& mfab, const int exponent, const int srcComp, const int numComp, const int numGrow) { BL_ASSERT (numGrow <= mfab.nGrow()); BoxArray boxes = mfab.boxArray(); boxes.grow(numGrow); // // Get a copy of the multifab // MultiFab mftmp(mfab.boxArray(), numComp, 0); MultiFab::Copy(mftmp,mfab,srcComp,0,numComp,numGrow); // // Calculate the Norms // Real myNorm = 0; if ( exponent == 0 ) { for ( MFIter mftmpmfi(mftmp); mftmpmfi.isValid(); ++mftmpmfi) { mftmp[mftmpmfi].abs(boxes[mftmpmfi.index()], 0, numComp); myNorm = std::max(myNorm, mftmp[mftmpmfi].norm(0, 0, numComp)); } ParallelDescriptor::ReduceRealMax(myNorm); } else if ( exponent == 1 ) { for ( MFIter mftmpmfi(mftmp); mftmpmfi.isValid(); ++mftmpmfi) { mftmp[mftmpmfi].abs(boxes[mftmpmfi.index()], 0, numComp); myNorm += mftmp[mftmpmfi].norm(1, 0, numComp); } ParallelDescriptor::ReduceRealSum(myNorm); } else if ( exponent == 2 ) { for ( MFIter mftmpmfi(mftmp); mftmpmfi.isValid(); ++mftmpmfi) { mftmp[mftmpmfi].abs(boxes[mftmpmfi.index()], 0, numComp); myNorm += pow(mftmp[mftmpmfi].norm(2, 0, numComp), 2); } ParallelDescriptor::ReduceRealSum(myNorm); myNorm = sqrt( myNorm ); } else { BoxLib::Error("Invalid exponent to norm function"); } return myNorm; }
void fill_boundary(MultiFab& mf, int scomp, int ncomp, const Geometry& geom, bool cross) { if (mf.nGrow() <= 0) return; bool local = false; // Don't think we ever want it to be true. mf.FillBoundary(scomp, ncomp, local, cross); bool do_corners = !cross; geom.FillPeriodicBoundary(mf, scomp, ncomp, do_corners, local); }
void AuxBoundaryData::copyTo (MultiFab& mf, int src_comp, int dst_comp, int num_comp) const { BL_ASSERT(m_initialized); if (!m_empty && mf.size() > 0) { mf.copy(m_fabs,src_comp,dst_comp,num_comp); } }
void MCLinOp::residual (MultiFab& residL, const MultiFab& rhsL, MultiFab& solnL, int level, MCBC_Mode bc_mode) { apply(residL, solnL, level, bc_mode); for (MFIter solnLmfi(solnL); solnLmfi.isValid(); ++solnLmfi) { int nc = residL.nComp(); const Box& vbox = solnLmfi.validbox(); FArrayBox& resfab = residL[solnLmfi]; const FArrayBox& rhsfab = rhsL[solnLmfi]; FORT_RESIDL( resfab.dataPtr(), ARLIM(resfab.loVect()), ARLIM(resfab.hiVect()), rhsfab.dataPtr(), ARLIM(rhsfab.loVect()), ARLIM(rhsfab.hiVect()), resfab.dataPtr(), ARLIM(resfab.loVect()), ARLIM(resfab.hiVect()), vbox.loVect(), vbox.hiVect(), &nc); } }
void average_face_to_cellcenter (MultiFab& cc, const PArray<MultiFab>& fc, const Geometry& geom) { BL_ASSERT(cc.nComp() >= BL_SPACEDIM); BL_ASSERT(fc.size() == BL_SPACEDIM); BL_ASSERT(fc[0].nComp() == 1); // We only expect fc to have the gradient perpendicular to the face const Real* dx = geom.CellSize(); const Real* problo = geom.ProbLo(); int coord_type = Geometry::Coord(); #ifdef _OPENMP #pragma omp parallel #endif for (MFIter mfi(cc,true); mfi.isValid(); ++mfi) { const Box& bx = mfi.tilebox(); BL_FORT_PROC_CALL(BL_AVG_FC_TO_CC,bl_avg_fc_to_cc) (bx.loVect(), bx.hiVect(), BL_TO_FORTRAN(cc[mfi]), D_DECL(BL_TO_FORTRAN(fc[0][mfi]), BL_TO_FORTRAN(fc[1][mfi]), BL_TO_FORTRAN(fc[2][mfi])), dx, problo, coord_type); } }
void average_face_to_cellcenter (MultiFab& cc, int dcomp, const std::vector<MultiFab*>& fc) { BL_ASSERT(cc.nComp() >= dcomp + BL_SPACEDIM); BL_ASSERT(fc.size() == BL_SPACEDIM); BL_ASSERT(fc[0]->nComp() == 1); Real dx[3] = {1.0,1.0,1.0}; Real problo[3] = {0.,0.,0.}; int coord_type = 0; #ifdef _OPENMP #pragma omp parallel #endif for (MFIter mfi(cc,true); mfi.isValid(); ++mfi) { const Box& bx = mfi.tilebox(); BL_FORT_PROC_CALL(BL_AVG_FC_TO_CC,bl_avg_fc_to_cc) (bx.loVect(), bx.hiVect(), BL_TO_FORTRAN_N(cc[mfi],dcomp), D_DECL(BL_TO_FORTRAN((*fc[0])[mfi]), BL_TO_FORTRAN((*fc[1])[mfi]), BL_TO_FORTRAN((*fc[2])[mfi])), dx, problo, coord_type); } }
void solve(MultiFab& soln, const MultiFab& anaSoln, Real a, Real b, MultiFab& alpha, MultiFab beta[], MultiFab& rhs, const BoxArray& bs, const Geometry& geom, solver_t solver) { BL_PROFILE("solve"); soln.setVal(0.0); const Real run_strt = ParallelDescriptor::second(); BndryData bd(bs, 1, geom); set_boundary(bd, rhs); ABecLaplacian abec_operator(bd, dx); abec_operator.setScalars(a, b); abec_operator.setCoefficients(alpha, beta); MultiGrid mg(abec_operator); mg.setMaxIter(maxiter); mg.setVerbose(verbose); mg.setFixedIter(1); mg.solve(soln, rhs, tolerance_rel, tolerance_abs); Real run_time = ParallelDescriptor::second() - run_strt; ParallelDescriptor::ReduceRealMax(run_time, ParallelDescriptor::IOProcessorNumber()); if (ParallelDescriptor::IOProcessor()) { std::cout << "Run time : " << run_time << std::endl; } }
void solve_with_Cpp(MultiFab& soln, MultiFab& gphi, Real a, Real b, MultiFab& alpha, PArray<MultiFab>& beta, MultiFab& rhs, const BoxArray& bs, const Geometry& geom) { BL_PROFILE("solve_with_Cpp()"); BndryData bd(bs, 1, geom); set_boundary(bd, rhs, 0); ABecLaplacian abec_operator(bd, dx); abec_operator.setScalars(a, b); abec_operator.setCoefficients(alpha, beta); MultiGrid mg(abec_operator); mg.setVerbose(verbose); mg.solve(soln, rhs, tolerance_rel, tolerance_abs); PArray<MultiFab> grad_phi(BL_SPACEDIM, PArrayManage); for (int n = 0; n < BL_SPACEDIM; ++n) grad_phi.set(n, new MultiFab(BoxArray(soln.boxArray()).surroundingNodes(n), 1, 0)); #if (BL_SPACEDIM == 2) abec_operator.compFlux(grad_phi[0],grad_phi[1],soln); #elif (BL_SPACEDIM == 3) abec_operator.compFlux(grad_phi[0],grad_phi[1],grad_phi[2],soln); #endif // Average edge-centered gradients to cell centers. BoxLib::average_face_to_cellcenter(gphi, grad_phi, geom); }
void MultiFab_C_to_F::share (MultiFab& cmf, const std::string& fmf_name) { const Box& bx = cmf.boxArray()[0]; int nodal[BL_SPACEDIM]; for ( int i = 0; i < BL_SPACEDIM; ++i ) { nodal[i] = (bx.type(i) == IndexType::NODE) ? 1 : 0; } share_multifab_with_f (fmf_name.c_str(), cmf.nComp(), cmf.nGrow(), nodal); for (MFIter mfi(cmf); mfi.isValid(); ++mfi) { int li = mfi.LocalIndex(); const FArrayBox& fab = cmf[mfi]; share_fab_with_f (li, fab.dataPtr()); } }
// // Do a one-component dot product of r & z using supplied components. // static Real dotxy (const MultiFab& r, int rcomp, const MultiFab& z, int zcomp, bool local) { BL_PROFILE("CGSolver::dotxy()"); BL_ASSERT(r.nComp() > rcomp); BL_ASSERT(z.nComp() > zcomp); BL_ASSERT(r.boxArray() == z.boxArray()); const int ncomp = 1; const int nghost = 0; return MultiFab::Dot(r,rcomp,z,zcomp,ncomp,nghost,local); }
static void Write_N_Read (const MultiFab& mf, const std::string& mf_name) { if (ParallelDescriptor::IOProcessor()) { std::cout << "Writing the MultiFab to disk ...\n"; } double start, end; ParallelDescriptor::Barrier(); if (ParallelDescriptor::IOProcessor()) { start = BoxLib::wsecond(); } ParallelDescriptor::Barrier(); if (ParallelDescriptor::IOProcessor()) { end = BoxLib::wsecond(); std::cout << "\nWallclock time for MF write: " << (end-start) << '\n'; std::cout << "Reading the MultiFab from disk ...\n"; } VisMF vmf(mf_name); BL_ASSERT(vmf.size() == mf.boxArray().size()); for (MFIter mfi(mf); mfi.isValid(); ++mfi) { //const FArrayBox& fab = vmf[mfi.index()]; const FArrayBox& fab = vmf.GetFab(mfi.index(), 0); std::cout << "\tCPU #" << ParallelDescriptor::MyProc() << " read FAB #" << mfi.index() << '\n'; } ParallelDescriptor::Barrier(); if (ParallelDescriptor::IOProcessor()) { std::cout << "Building new MultiFab from disk version ....\n\n"; } MultiFab new_mf; VisMF::Read(new_mf, mf_name); }
static Real norm_inf (const MultiFab& res, bool local = false) { Real restot = res.norm0(0, true); if ( !local ) ParallelDescriptor::ReduceRealMax(restot); return restot; }
void MCMultiGrid::interpolate (MultiFab& f, const MultiFab& c) { // // Use fortran function to interpolate up (prolong) c to f // Note: returns f=f+P(c) , i.e. ADDS interp'd c to f // for (MFIter fmfi(f); fmfi.isValid(); ++fmfi) { const Box& bx = c.boxArray()[fmfi.index()]; int nc = f.nComp(); const FArrayBox& cfab = c[fmfi]; FArrayBox& ffab = f[fmfi]; FORT_INTERP( ffab.dataPtr(),ARLIM(ffab.loVect()),ARLIM(ffab.hiVect()), cfab.dataPtr(),ARLIM(cfab.loVect()),ARLIM(cfab.hiVect()), bx.loVect(), bx.hiVect(), &nc); } }
void average_cellcenter_to_face (PArray<MultiFab>& fc, const MultiFab& cc, const Geometry& geom) { BL_ASSERT(cc.nComp() == 1); BL_ASSERT(cc.nGrow() >= 1); BL_ASSERT(fc.size() == BL_SPACEDIM); BL_ASSERT(fc[0].nComp() == 1); // We only expect fc to have the gradient perpendicular to the face const Real* dx = geom.CellSize(); const Real* problo = geom.ProbLo(); int coord_type = Geometry::Coord(); #ifdef _OPENMP #pragma omp parallel #endif for (MFIter mfi(cc,true); mfi.isValid(); ++mfi) { const Box& xbx = mfi.nodaltilebox(0); #if (BL_SPACEDIM > 1) const Box& ybx = mfi.nodaltilebox(1); #endif #if (BL_SPACEDIM == 3) const Box& zbx = mfi.nodaltilebox(2); #endif BL_FORT_PROC_CALL(BL_AVG_CC_TO_FC,bl_avg_cc_to_fc) (xbx.loVect(), xbx.hiVect(), #if (BL_SPACEDIM > 1) ybx.loVect(), ybx.hiVect(), #endif #if (BL_SPACEDIM == 3) zbx.loVect(), zbx.hiVect(), #endif D_DECL(BL_TO_FORTRAN(fc[0][mfi]), BL_TO_FORTRAN(fc[1][mfi]), BL_TO_FORTRAN(fc[2][mfi])), BL_TO_FORTRAN(cc[mfi]), dx, problo, coord_type); } }
static Real norm_inf (const MultiFab& res, bool local = false) { Real restot = 0.0; for (MFIter mfi(res); mfi.isValid(); ++mfi) { restot = std::max(restot, res[mfi].norm(mfi.validbox(), 0, 0, res.nComp())); } if ( !local ) ParallelDescriptor::ReduceRealMax(restot); return restot; }
void solve_with_F90(MultiFab& soln, MultiFab& gphi, Real a, Real b, MultiFab& alpha, PArray<MultiFab>& beta, MultiFab& rhs, const BoxArray& bs, const Geometry& geom) { BL_PROFILE("solve_with_F90()"); FMultiGrid fmg(geom); int mg_bc[2*BL_SPACEDIM]; if (bc_type == Periodic) { // Define the type of boundary conditions to be periodic for ( int n = 0; n < BL_SPACEDIM; ++n ) { mg_bc[2*n + 0] = MGT_BC_PER; mg_bc[2*n + 1] = MGT_BC_PER; } } else if (bc_type == Neumann) { // Define the type of boundary conditions to be Neumann for ( int n = 0; n < BL_SPACEDIM; ++n ) { mg_bc[2*n + 0] = MGT_BC_NEU; mg_bc[2*n + 1] = MGT_BC_NEU; } } else if (bc_type == Dirichlet) { // Define the type of boundary conditions to be Dirichlet for ( int n = 0; n < BL_SPACEDIM; ++n ) { mg_bc[2*n + 0] = MGT_BC_DIR; mg_bc[2*n + 1] = MGT_BC_DIR; } } fmg.set_bc(mg_bc); fmg.set_maxorder(maxorder); fmg.set_scalars(a, b); fmg.set_coefficients(alpha, beta); int always_use_bnorm = 0; int need_grad_phi = 1; fmg.solve(soln, rhs, tolerance_rel, tolerance_abs, always_use_bnorm, need_grad_phi); PArray<MultiFab> grad_phi(BL_SPACEDIM, PArrayManage); for (int n = 0; n < BL_SPACEDIM; ++n) grad_phi.set(n, new MultiFab(BoxArray(soln.boxArray()).surroundingNodes(n), 1, 0)); fmg.get_fluxes(grad_phi); // Average edge-centered gradients to cell centers. BoxLib::average_face_to_cellcenter(gphi, grad_phi, geom); }
void MCMultiGrid::residualCorrectionForm (MultiFab& resL, const MultiFab& rhsL, MultiFab& solnL, const MultiFab& inisol, MCBC_Mode bc_mode, int level) { // // Using the linearity of the operator, Lp, we can solve this system // instead by solving for the correction required to the initial guess. // initialsolution->copy(inisol); solnL.copy(inisol); Lp.residual(resL, rhsL, solnL, level, bc_mode); }
void MCMultiGrid::solve (MultiFab& _sol, const MultiFab& _rhs, Real _eps_rel, Real _eps_abs, MCBC_Mode bc_mode) { BL_ASSERT(numcomps == _sol.nComp()); // // Prepare memory for new level, and solve the general boundary // value problem to within relative error _eps_rel. Customized // to solve at level=0 // int level = 0; prepareForLevel(level); residualCorrectionForm(*rhs[level],_rhs,*cor[level],_sol,bc_mode,level); if (!solve_(_sol, _eps_rel, _eps_abs, MCHomogeneous_BC, level)) BoxLib::Error("MCMultiGrid::solve(): failed to converge!"); }
void MCMultiGrid::average (MultiFab& c, const MultiFab& f) { // // Use Fortran function to average down (restrict) f to c. // for (MFIter cmfi(c); cmfi.isValid(); ++cmfi) { const Box& bx = cmfi.validbox(); int nc = c.nComp(); FArrayBox& cfab = c[cmfi]; const FArrayBox& ffab = f[cmfi]; FORT_AVERAGE( cfab.dataPtr(),ARLIM(cfab.loVect()),ARLIM(cfab.hiVect()), ffab.dataPtr(),ARLIM(ffab.loVect()),ARLIM(ffab.hiVect()), bx.loVect(), bx.hiVect(), &nc); } }
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 }
void LinOp::residual (MultiFab& residL, const MultiFab& rhsL, MultiFab& solnL, int level, LinOp::BC_Mode bc_mode, bool local) { BL_PROFILE("LinOp::residual()"); apply(residL, solnL, level, bc_mode, local); const bool tiling = true; #ifdef _OPENMP #pragma omp parallel #endif for (MFIter solnLmfi(solnL,tiling); solnLmfi.isValid(); ++solnLmfi) { const int nc = residL.nComp(); // // Only single-component solves supported (verified) by this class. // BL_ASSERT(nc == 1); const Box& tbx = solnLmfi.tilebox(); BL_ASSERT(gbox[level][solnLmfi.index()] == solnLmfi.validbox()); FArrayBox& residfab = residL[solnLmfi]; const FArrayBox& rhsfab = rhsL[solnLmfi]; FORT_RESIDL( residfab.dataPtr(), ARLIM(residfab.loVect()), ARLIM(residfab.hiVect()), rhsfab.dataPtr(), ARLIM(rhsfab.loVect()), ARLIM(rhsfab.hiVect()), residfab.dataPtr(), ARLIM(residfab.loVect()), ARLIM(residfab.hiVect()), tbx.loVect(), tbx.hiVect(), &nc); } }
void average_edge_to_cellcenter (MultiFab& cc, int dcomp, const std::vector<MultiFab*>& edge) { BL_ASSERT(cc.nComp() >= dcomp + BL_SPACEDIM); BL_ASSERT(edge.size() == BL_SPACEDIM); BL_ASSERT(edge[0]->nComp() == 1); #ifdef _OPENMP #pragma omp parallel #endif for (MFIter mfi(cc,true); mfi.isValid(); ++mfi) { const Box& bx = mfi.tilebox(); BL_FORT_PROC_CALL(BL_AVG_EG_TO_CC,bl_avg_eg_to_cc) (bx.loVect(), bx.hiVect(), BL_TO_FORTRAN_N(cc[mfi],dcomp), D_DECL(BL_TO_FORTRAN((*edge[0])[mfi]), BL_TO_FORTRAN((*edge[1])[mfi]), BL_TO_FORTRAN((*edge[2])[mfi]))); } }
void MacOperator::setCoefficients (MultiFab* area, MultiFab& rho, int rho_comp, const Real* dx) { // // Should check that all BoxArrays are consistant. // const BoxArray& ba = gbox[0]; BL_ASSERT(rho.boxArray() == ba); // // First set scalar coeficients. // setScalars(0.0,1.0); // // Don't need to set a because alpha is set to zero. // const int n_grow = 0; D_TERM(MultiFab bxcoef(area[0].boxArray(),area[0].nComp(),n_grow);,