54 amrex::Vector<std::unique_ptr<amrex::MultiFab> >& a_rhs,
55 Real a_tol_rel, Real a_tol_abs,
bool copyrhs =
false,
56 const char* checkpoint_file =
nullptr)
59 amrex::Vector<amrex::MultiFab*> rhs_tmp(a_rhs.size());
60 amrex::Vector<amrex::MultiFab*> zero_tmp(a_rhs.size());
61 for (
int i = 0; i < rhs_tmp.size(); i++)
63 rhs_tmp[i] =
new amrex::MultiFab(a_rhs[i]->boxArray(), a_rhs[i]->DistributionMap(), a_rhs[i]->nComp(), a_rhs[i]->nGrow());
64 zero_tmp[i] =
new amrex::MultiFab(a_rhs[i]->boxArray(), a_rhs[i]->DistributionMap(), a_rhs[i]->nComp(), a_rhs[i]->nGrow());
65 rhs_tmp[i]->setVal(0.0);
66 zero_tmp[i]->setVal(0.0);
71 mlmg->apply(rhs_tmp, zero_tmp);
73 for (
int lev = 0; lev < rhs_tmp.size(); lev++)
75 amrex::Box domain =
linop->
Geom(lev).Domain();
76 domain.convert(amrex::IntVect::TheNodeVector());
77 const Dim3 lo = amrex::lbound(domain), hi = amrex::ubound(domain);
78 for (MFIter mfi(*rhs_tmp[lev], amrex::TilingIfNotGPU());mfi.isValid();++mfi)
80 amrex::Box bx = mfi.growntilebox(rhs_tmp[lev]->nGrow());
82 amrex::Array4<amrex::Real>
const& rhstmp = rhs_tmp[lev]->array(mfi);
83 for (
int n = 0; n < rhs_tmp[lev]->nComp(); n++)
85 amrex::ParallelFor(bx, [=] AMREX_GPU_DEVICE(
int i,
int j,
int k)
87 bool AMREX_D_DECL(xmin = (i == lo.x), ymin = (j == lo.y), zmin = (k == lo.z)),
88 AMREX_D_DECL(xmax = (i == hi.x), ymax = (j == hi.y), zmax = (k == hi.z));
89 if (AMREX_D_TERM(xmax || xmin, || ymax || ymin, || zmax || zmin))
90 rhstmp(i, j, k, n) = 0.0;
92 rhstmp(i, j, k, n) *= -1.0;
97 rhs_tmp[lev]->setMultiGhost(
true);
98 rhs_tmp[lev]->FillBoundaryAndSync(
linop->
Geom(lev).periodicity());
101 for (
int lev = 0; lev < rhs_tmp.size(); lev++)
104 amrex::Add(*rhs_tmp[lev], *a_rhs[lev], 0, 0, rhs_tmp[lev]->nComp(), rhs_tmp[lev]->nGrow());
106 amrex::Copy(*a_rhs[lev], *rhs_tmp[lev], 0, 0, rhs_tmp[lev]->nComp(), rhs_tmp[lev]->nGrow());
115 retval =
mlmg->solve(GetVecOfPtrs(a_sol), GetVecOfConstPtrs(rhs_tmp), a_tol_rel, a_tol_abs, checkpoint_file);
117 catch (
const std::exception& e)
122 if (a_sol[0]->contains_nan())
187 const amrex::Vector<amrex::MultiFab const*>& a_rhs_mf)
189 int nlevs = a_sol_mf.size();
190 int ncomps = a_sol_mf[0]->nComp();
192 amrex::Vector<amrex::Geometry> geom;
193 amrex::Vector<int> iter;
194 amrex::Vector<amrex::IntVect> refratio;
195 amrex::Vector<std::string> names;
196 for (
int i = 0; i < nlevs; i++)
200 if (i > 0) refratio.push_back(amrex::IntVect(2));
202 for (
int n = 0; n < ncomps; n++)
204 names.push_back(
"var" + std::to_string(n));
208 WriteMultiLevelPlotfile(outputdir +
"/mlmg_sol", nlevs,
209 amrex::GetVecOfConstPtrs(a_sol_mf),
210 names, geom, 0, iter, refratio);
211 WriteMultiLevelPlotfile(outputdir +
"/mlmg_rhs", nlevs,
212 amrex::GetVecOfConstPtrs(a_rhs_mf),
213 names, geom, 0, iter, refratio);
216 for (
int lev = 0; lev < nlevs; lev++)
218 res_mf.
Define(lev, a_sol_mf[lev]->boxArray(), a_sol_mf[lev]->DistributionMap(),
219 ncomps, a_sol_mf[lev]->nGrow());
222 mlmg->compResidual(amrex::GetVecOfPtrs(res_mf), a_sol_mf, a_rhs_mf);
224 WriteMultiLevelPlotfile(outputdir +
"/mlmg_res", nlevs,
225 amrex::GetVecOfConstPtrs(res_mf),
226 names, geom, 0, iter, refratio);