5 #include <AMReX_ParmParse.H>
6 #include <AMReX_Interpolater.H>
16 for (
int d = 0; d < AMREX_SPACEDIM; ++d) {
17 bc_m[2 * d] = MGT_BC_DIR;
18 bc_m[2 * d + 1] = MGT_BC_DIR;
27 unsigned short baseLevel,
28 unsigned short finestLevel,
33 if (AmrGeometry_t::isAllPeriodic()) {
34 for (
int d = 0; d < AMREX_SPACEDIM; ++d) {
35 bc_m[2 * d] = MGT_BC_PER;
36 bc_m[2 * d + 1] = MGT_BC_PER;
38 }
else if ( AmrGeometry_t::isAnyPeriodic() ) {
39 for (
int d = 0; d < AMREX_SPACEDIM; ++d) {
40 if ( AmrGeometry_t::isPeriodic(d) ) {
41 bc_m[2 * d] = MGT_BC_PER;
42 bc_m[2 * d + 1] = MGT_BC_PER;
47 amrex::Vector< AmrScalarFieldContainer_t > grad_phi_edge(rho.size());
49 amrex::Vector< AmrField_t > tmp(rho.size());
51 assert(baseLevel <= finestLevel);
52 assert(finestLevel < (
int)rho.size());
54 for (
int lev = baseLevel; lev <= finestLevel ; ++lev) {
56 grad_phi_edge[lev].resize(AMREX_SPACEDIM);
57 tmp[lev].define(rho[lev]->boxArray(), dmap, AMREX_SPACEDIM, 1);
59 for (
int n = 0;
n < AMREX_SPACEDIM; ++
n) {
61 grad_phi_edge[lev][
n].reset(
new AmrField_t(ba.surroundingNodes(
n), dmap, 1, 1));
62 grad_phi_edge[lev][
n]->setVal(0.0, 1);
66 for (
int i = 0; i <= finestLevel; ++i) {
67 phi[i]->setVal(0.0, 1);
68 tmp[i].setVal(0.0, 1);
72 amrex::GetVecOfPtrs(phi),
73 amrex::GetVecOfVecOfPtrs(grad_phi_edge),
80 ss <<
"Residual norm: " << std::setprecision(16) << residNorm
81 <<
" > " <<
abstol_m <<
" (absolute tolerance)";
83 "Multigrid solver did not converge. " + ss.str());
86 for (
int lev = baseLevel; lev <= finestLevel; ++lev) {
87 amrex::average_face_to_cellcenter(tmp[lev],
88 amrex::GetVecOfConstPtrs(grad_phi_edge[lev]),
91 for (
int j = 0; j < AMREX_SPACEDIM; ++j) {
92 efield[lev][j]->setVal(0.0, 1);
93 amr::AmrField_t::Copy(*(efield[lev][j].
get()),
94 tmp[lev], j, 0, 1, 1);
95 efield[lev][j]->FillBoundary(0, 1, geom[lev].periodicity());
97 efield[lev][j]->mult(-1.0, 0, 1);
134 os <<
"* ************* F M G P o i s s o n S o l v e r ************************************ " <<
endl
135 <<
"* relative tolerance " <<
reltol_m <<
'\n'
137 <<
"* ******************************************************************** " <<
endl;
156 amrex::ParmParse pp_mg(
"mg");
159 pp_mg.add(
"maxiter", 200);
162 pp_mg.add(
"maxiter_b", 200);
165 pp_mg.add(
"nu_1", 2);
168 pp_mg.add(
"nu_2", 2);
171 pp_mg.add(
"nu_b", 0);
174 pp_mg.add(
"nu_f", 8);
181 pp_mg.add(
"usecg", 1);
184 pp_mg.add(
"rtol_b", 0.0001);
187 pp_mg.add(
"cg_solver", 1);
190 pp_mg.add(
"numLevelsMAX", 1024);
198 pp_mg.add(
"smoother", 1);
207 pp_mg.add(
"cycle_type", 1);
224 pp_mg.add(
"bottom_solver", 1);
227 amrex::ParmParse pp_cg(
"cg");
237 amrex::MGT_Solver::def_min_width = 2;
238 amrex::MGT_Solver::def_max_L0_growth = -1.0;
244 const amrex::Vector< AmrFieldContainer_pt > & grad_phi_edge,
249 int nlevs = finestLevel - baseLevel + 1;
255 for (
int ilev = 0; ilev < nlevs; ++ilev) {
256 geom_p[ilev] = geom[ilev + baseLevel];
257 rho_p[ilev] = rho[ilev + baseLevel];
258 phi_p[ilev] = phi[ilev + baseLevel];
262 amrex::IntVect crse_ratio = (baseLevel == 0) ?
265 amrex::FMultiGrid fmg(geom_p, baseLevel, crse_ratio);
268 fmg.set_bc(
bc_m, *phi_p[baseLevel]);
270 fmg.set_bc(
bc_m, *phi_p[baseLevel-1], *phi_p[baseLevel]);
280 fmg.set_const_gravity_coeffs();
285 int always_use_bnorm = 0;
286 int need_grad_phi = 1;
288 double residNorm = fmg.solve(phi_p, rho_p,
reltol_m,
abstol_m, always_use_bnorm, need_grad_phi);
290 for (
int ilev = 0; ilev < nlevs; ++ilev) {
291 int amr_level = ilev + baseLevel;
292 fmg.get_fluxes(grad_phi_edge[amr_level], ilev);
int bc_m[2 *AMREX_SPACEDIM]
Boundary conditions.
AmrBoxLib::AmrVectorFieldContainer_t AmrVectorFieldContainer_t
double abstol_m
Absolute tolerance for solver.
amrex::Vector< AmrBoxLib::AmrField_t * > AmrFieldContainer_pt
constexpr double e
The value of .
double getXRangeMax(unsigned short level=0)
AmrBoxLib::AmrGeomContainer_t GeomContainer_t
The base class for all OPAL exceptions.
Inform & print(Inform &os) const
AmrBoxLib::AmrScalarFieldContainer_t AmrScalarFieldContainer_t
double solveWithF90_m(const AmrFieldContainer_pt &rho, const AmrFieldContainer_pt &phi, const amrex::Vector< AmrFieldContainer_pt > &grad_phi_edge, const GeomContainer_t &geom, int baseLevel, int finestLevel)
double getYRangeMax(unsigned short level=0)
FMGPoissonSolver(AmrBoxLib *itsAmrObject_p)
AmrBoxLib::AmrGrid_t AmrGrid_t
double reltol_m
Relative tolearance for solver.
double getZRangeMin(unsigned short level=0)
AmrBoxLib::AmrProcMap_t AmrProcMap_t
double getYRangeMin(unsigned short level=0)
double getXRangeMin(unsigned short level=0)
AmrBoxLib * itsAmrObject_mp
double getZRangeMax(unsigned short level=0)
void solve(AmrScalarFieldContainer_t &rho, AmrScalarFieldContainer_t &phi, AmrVectorFieldContainer_t &efield, unsigned short baseLevel, unsigned short finestLevel, bool prevAsGuess=true)
Inform & endl(Inform &inf)
amr::AmrField_t AmrField_t