89 amrex::Real relative_tolerance,
90 amrex::Real absolute_tolerance,
96 T_BoundaryHandler
const boundary_handler,
97 bool eb_enabled =
false,
98 bool do_single_precision_comms =
false,
100 [[maybe_unused]] T_PostACalculationFunctor post_A_calculation = std::nullopt,
101 [[maybe_unused]] std::optional<amrex::Real const> current_time = std::nullopt,
105 using namespace amrex::literals;
107 if (!rel_ref_ratio.has_value()) {
109 "rel_ref_ratio must be set if mesh-refinement is used");
113 auto const finest_level =
static_cast<int>(curr.size()) - 1;
116 amrex::Real max_comp_J = 0.0;
117 for (
int lev=0; lev<=finest_level; lev++) {
118 for (
int adim=0; adim<3; adim++) {
120 max_comp_J =
amrex::max(max_comp_J, curr[lev][adim]->norm0());
125 const bool always_use_bnorm = (max_comp_J > 0);
126 if (!always_use_bnorm) {
127 if (absolute_tolerance == 0.0) { absolute_tolerance = amrex::Real(1e-6); }
129 "MagnetostaticSolver",
130 "Max norm of J is 0",
136 for (
int lev=0; lev<=finest_level; lev++) {
140 constexpr bool is_rz =
true;
142 constexpr bool is_rz =
false;
147 geom[lev].CellSize(1),
148 geom[lev].CellSize(2))};
151 if (!eb_enabled && !is_rz) {
153 int max_semicoarsening_level = 0;
154 int semicoarsening_direction = -1;
155 const auto min_dir =
static_cast<int>(std::distance(dx.begin(),
156 std::min_element(dx.begin(), dx.end())));
157 const auto max_dir =
static_cast<int>(std::distance(dx.begin(),
158 std::max_element(dx.begin(), dx.end())));
159 if (dx[max_dir] > dx[min_dir]) {
160 semicoarsening_direction = max_dir;
161 max_semicoarsening_level =
static_cast<int>(std::log2(dx[max_dir] / dx[min_dir]));
163 if (max_semicoarsening_level > 0) {
173 linopx.
define({geom[lev]}, {grids[lev]}, {dmap[lev]}, info, {eb_farray_box_factory.value()[lev]});
174 linopy.
define({geom[lev]}, {grids[lev]}, {dmap[lev]}, info, {eb_farray_box_factory.value()[lev]});
175 linopz.
define({geom[lev]}, {grids[lev]}, {dmap[lev]}, info, {eb_farray_box_factory.value()[lev]});
178 linopx.
define({geom[lev]}, {grids[lev]}, {dmap[lev]}, info);
179 linopy.
define({geom[lev]}, {grids[lev]}, {dmap[lev]}, info);
180 linopz.
define({geom[lev]}, {grids[lev]}, {dmap[lev]}, info);
186 for (
int adim=0; adim<3; adim++) {
191 linop[adim]->setSigma({
AMREX_D_DECL(1._rt, 1._rt, 1._rt)});
194#if defined(AMREX_USE_EB)
195 if (eb_enabled) { linop[adim]->setEBDirichlet(0_rt); }
199 linop[adim]->setRZ(
true);
202 linop[adim]->setDomainBC( boundary_handler.lobc[adim], boundary_handler.hibc[adim] );
204 mlmg[adim] = std::make_unique<amrex::MLMG>(*linop[adim]);
206 mlmg[adim]->setVerbose(verbosity);
207 mlmg[adim]->setMaxIter(max_iters);
208 mlmg[adim]->setConvergenceNormType(always_use_bnorm ? amrex::MLMGNormType::bnorm : amrex::MLMGNormType::greater);
211 mlmg[adim]->solve( {A[lev][adim]}, {curr[lev][adim]},
212 relative_tolerance, absolute_tolerance );
216 *A[lev][adim], A[lev][adim]->nGrowVect(),
217 do_single_precision_comms,
218 geom[lev].periodicity(),
false);
225 if (lev < finest_level) {
231 const int ncomp = linop[adim]->getNComp();
246 do_single_precision_comms,
252#pragma omp parallel if (amrex::Gpu::notInLaunchRegion())
261 amrex::Box const b = mfi.tilebox(A[lev + 1][adim]->ixType().toIntVect());
271 if constexpr (!std::is_same_v<T_PostACalculationFunctor, std::nullopt_t>) {
272 if (post_A_calculation.has_value()) {
273 post_A_calculation.value()(mlmg, lev);
#define ABLASTR_ALWAYS_ASSERT_WITH_MESSAGE(EX, MSG)
Definition TextMsg.H:75
void computeVectorPotential(amrex::Vector< amrex::Array< amrex::MultiFab *, 3 > > const &curr, amrex::Vector< amrex::Array< amrex::MultiFab *, 3 > > &A, amrex::Real relative_tolerance, amrex::Real absolute_tolerance, int max_iters, int verbosity, amrex::Vector< amrex::Geometry > const &geom, amrex::Vector< amrex::DistributionMapping > const &dmap, amrex::Vector< amrex::BoxArray > const &grids, T_BoundaryHandler const boundary_handler, bool eb_enabled=false, bool do_single_precision_comms=false, std::optional< amrex::Vector< amrex::IntVect > > rel_ref_ratio=std::nullopt, T_PostACalculationFunctor post_A_calculation=std::nullopt, std::optional< amrex::Real const > current_time=std::nullopt, std::optional< amrex::Vector< T_FArrayBoxFactory const * > > eb_farray_box_factory=std::nullopt)
Definition VectorPoissonSolver.H:87
void ParallelCopy(amrex::MultiFab &dst, const amrex::MultiFab &src, int src_comp, int dst_comp, int num_comp, const amrex::IntVect &src_nghost, const amrex::IntVect &dst_nghost, bool do_single_precision_comms, const amrex::Periodicity &period, amrex::FabArrayBase::CpOp op)
Definition Communication.cpp:28