115 bool is_solver_igf_on_lev0,
116 bool eb_enabled =
false,
117 bool do_single_precision_comms =
false,
119 [[maybe_unused]] T_PostPhiCalculationFunctor post_phi_calculation = std::nullopt,
120 [[maybe_unused]] T_BoundaryHandler
const boundary_handler = std::nullopt,
121 [[maybe_unused]] std::optional<amrex::Real const> current_time = std::nullopt,
128 if (!rel_ref_ratio.has_value()) {
130 "rel_ref_ratio must be set if mesh-refinement is used");
134#if !defined(AMREX_USE_EB)
136 "Embedded boundary solve requested but not compiled in");
138 if (eb_enabled && std::is_same_v<void, T_FArrayBoxFactory>) {
139 throw std::runtime_error(
"EB requested by eb_farray_box_factory not provided!");
143 "FFT solver cannot be used with effective potential Poisson solve");
146 constexpr bool is_rz =
true;
148 constexpr bool is_rz =
false;
151 auto const finest_level =
static_cast<int>(rho.
size() - 1);
155 for (
int lev=0; lev<=finest_level; lev++) {
161 std::unique_ptr<amrex::MLNodeLinOp> linop;
165#if defined(AMREX_USE_EB)
166 auto linop_nodelap = std::make_unique<amrex::MLEBNodeFDLaplacian>();
167 linop_nodelap->define(
174 if constexpr (!std::is_same_v<T_BoundaryHandler, std::nullopt_t>) {
177 if (boundary_handler.phi_EB_only_t) {
178 linop_nodelap->setEBDirichlet(boundary_handler.potential_eb_t(current_time.value()));
180 linop_nodelap->setEBDirichlet(boundary_handler.getPhiEB(current_time.value()));
183 linop_nodelap->setSigma(lev, sigma);
184 linop = std::move(linop_nodelap);
189 auto linop_nodelap = std::make_unique<amrex::MLEBNodeFDLaplacian>();
190 linop_nodelap->define(
196 linop_nodelap->setRZ(
true);
197 linop_nodelap->setSigma(lev, sigma);
198 linop = std::move(linop_nodelap);
202 auto linop_nodelap = std::make_unique<amrex::MLNodeLaplacian>();
203 linop_nodelap->define(
209 linop_nodelap->setSigma(lev, sigma);
210 linop = std::move(linop_nodelap);
214 if constexpr (std::is_same_v<T_BoundaryHandler, std::nullopt_t>) {
216 amrex::LinOpBCType::Dirichlet,
217 amrex::LinOpBCType::Dirichlet,
218 amrex::LinOpBCType::Dirichlet
221 linop->setDomainBC(lobc, hibc);
223 linop->setDomainBC(boundary_handler.lobc, boundary_handler.hibc);
240 mlmg.
solve( {phi[lev]}, {rho[lev]},
241 relative_tolerance, absolute_tolerance );
248 if (lev < finest_level) {
250 const int ncomp = linop->getNComp();
254 do_single_precision_comms,
261 if constexpr (!std::is_same_v<T_PostPhiCalculationFunctor, std::nullopt_t>) {
262 if (post_phi_calculation.has_value()) {
263 post_phi_calculation.value()(mlmg, lev);