Block-Structured AMR Software Framework
Loading...
Searching...
No Matches
AMReX_MLEBNodeFDLaplacian.H
Go to the documentation of this file.
1#ifndef AMREX_MLEBNODEFDLAPLACIAN_H_
2#define AMREX_MLEBNODEFDLAPLACIAN_H_
3#include <AMReX_Config.H>
4
5#include <AMReX_Array.H>
6#ifdef AMREX_USE_EB
8#endif
9#include <AMReX_MLNodeLinOp.H>
10
11#include <limits>
12
13namespace amrex {
14
22// Although the class has EB in the name, it works for non-EB build too.
23//
24// del dot (sigma grad phi) = rhs, for non-RZ
25// where phi and rhs are nodal multifab, and sigma is a tensor constant
26// with only diagonal components. The EB is assumed to be Dirichlet.
27//
28// del dot (sigma grad phi) - alpha/r^2 phi = rhs, for RZ where alpha is a
29// scalar constant that is zero by default.
30//
31// New feature: sigma can also be a single-component cell-centered multifab.
32
43 : public MLNodeLinOp
44{
45public:
46
47 MLEBNodeFDLaplacian () = default;
48
49#ifdef AMREX_USE_EB
52 const Vector<BoxArray>& a_grids,
53 const Vector<DistributionMapping>& a_dmap,
54 const LPInfo& a_info,
55 const Vector<EBFArrayBoxFactory const*>& a_factory);
56#endif
57
60 const Vector<BoxArray>& a_grids,
61 const Vector<DistributionMapping>& a_dmap,
62 const LPInfo& a_info);
63
64 ~MLEBNodeFDLaplacian () override = default;
65
70
72 void setSigma (Array<Real,AMREX_SPACEDIM> const& a_sigma) noexcept;
73
75 void setSigma (int amrlev, MultiFab const& a_sigma);
76
78 void setRZ (bool flag);
79
81 void setAlpha (Real a_alpha);
82
83#ifdef AMREX_USE_EB
84
86 void setEBDirichlet (Real a_phi_eb);
93 template <typename F>
94 requires (IsCallableR<Real,F,AMREX_D_DECL(Real,Real,Real)>::value)
95 void setEBDirichlet (F const& f);
96
106 void define (const Vector<Geometry>& a_geom,
107 const Vector<BoxArray>& a_grids,
108 const Vector<DistributionMapping>& a_dmap,
109 const LPInfo& a_info,
110 const Vector<EBFArrayBoxFactory const*>& a_factory);
111
113 [[nodiscard]] std::unique_ptr<FabFactory<FArrayBox> > makeFactory (int amrlev, int mglev) const final;
114
115 [[nodiscard]] bool scaleRHS (int amrlev, MultiFab* rhs) const final;
116
117#endif
118
127 void define (const Vector<Geometry>& a_geom,
128 const Vector<BoxArray>& a_grids,
129 const Vector<DistributionMapping>& a_dmap,
130 const LPInfo& a_info);
131
132 [[nodiscard]] std::string name () const override { return std::string("MLEBNodeFDLaplacian"); }
133
142 void restriction (int amrlev, int cmglev, MultiFab& crse, MultiFab& fine) const final;
152 void interpolation (int amrlev, int fmglev, MultiFab& fine, const MultiFab& crse) const final;
153
154 [[nodiscard]] bool needsUpdate () const override {
155 return (m_needs_update || MLNodeLinOp::needsUpdate());
156 }
157 void update () override;
158
160 void prepareForSolve () final;
162 void Fapply (int amrlev, int mglev, MultiFab& out, const MultiFab& in) const final;
171 void Fsmooth (int amrlev, int mglev, MultiFab& sol, const MultiFab& rhs) const final;
173 void normalize (int amrlev, int mglev, MultiFab& mf) const final;
174
176 void fixUpResidualMask (int amrlev, iMultiFab& resmsk) final;
177
178 [[nodiscard]] bool isSingular (int) const final { return false; }
179 [[nodiscard]] bool isBottomSingular () const final { return false; }
180
188 void compGrad (int amrlev, const Array<MultiFab*,AMREX_SPACEDIM>& grad,
189 MultiFab& sol, Location /*loc*/) const override;
190
191 void compGrad_doit (int amrlev, const Array<MultiFab*,AMREX_SPACEDIM>& grad,
192 MultiFab& sol) const;
193
194#if defined(AMREX_USE_HYPRE) && (AMREX_SPACEDIM > 1)
195 void fillIJMatrix (MFIter const& mfi,
197 Array4<int const> const& lid,
198 HypreNodeLap::Int* ncols,
199 HypreNodeLap::Int* cols,
200 Real* mat) const override;
201
202 void fillRHS (MFIter const& mfi,
203 Array4<int const> const& lid,
204 Real* rhs,
205 Array4<Real const> const& bfab) const override;
206#endif
207
209 void postSolve (Vector<MultiFab*> const& sol) const override;
210
211 [[nodiscard]] BottomSolver getDefaultBottomSolver () const override {
213 }
214
215 [[nodiscard]] bool supportCustomBottomSolver () const override { return true; }
216
217 void customBottomSolve (MLMGT<MultiFab>* mlmg, MultiFab& x, const MultiFab& b,
218 Real eps_rel, Real eps_abs, int maxiter) override;
219
220private:
221 GpuArray<Real,AMREX_SPACEDIM> m_sigma{{AMREX_D_DECL(1_rt,1_rt,1_rt)}};
222 Vector<Vector<std::unique_ptr<MultiFab>>> m_sigma_mf;
223 bool m_has_sigma_mf = false;
224 bool m_needs_update = true;
225 Real m_s_phi_eb = std::numeric_limits<Real>::lowest();
226 Vector<MultiFab> m_phi_eb;
227 int m_rz = false;
228 Real m_rz_alpha = 0._rt;
229
230 void update_sigma ();
231};
232
233#ifdef AMREX_USE_EB
234
235template <typename F>
236requires (IsCallableR<Real,F,AMREX_D_DECL(Real,Real,Real)>::value)
238{
239 // Select m_phi_eb again, in case a previous prepareForSolve defaulted
240 // to homogeneous Dirichlet or a scalar value was set earlier.
241 m_s_phi_eb = std::numeric_limits<Real>::lowest();
242 m_phi_eb.resize(m_num_amr_levels);
243 for (int amrlev = 0; amrlev < m_num_amr_levels; ++amrlev) {
244 auto const* factory = dynamic_cast<EBFArrayBoxFactory const*>(m_factory[amrlev][0].get());
245 if (factory) {
246 Geometry const& geom = m_geom[amrlev][0];
247 auto const problo = geom.ProbLoArray();
248 auto const cellsize = geom.CellSizeArray();
249 if (m_phi_eb[amrlev].empty()) {
250 m_phi_eb[amrlev].define(amrex::convert(m_grids[amrlev][0],IntVect(1)),
251 m_dmap[amrlev][0], 1, 1);
252 m_phi_eb[amrlev].setVal(0.0);
253 }
254 auto const& flags = factory->getMultiEBCellFlagFab();
255 auto const& levset = factory->getLevelSet();
256#ifdef AMREX_USE_OMP
257#pragma omp parallel if (Gpu::notInLaunchRegion())
258#endif
259 for (MFIter mfi(m_phi_eb[amrlev],TilingIfNotGPU()); mfi.isValid(); ++mfi)
260 {
261 const Box& ndbx = mfi.growntilebox();
262 const auto& flag = flags[mfi];
263 if (flag.getType() != FabType::regular) {
264 Array4<Real const> const lstarr = levset.const_array(mfi);
265 Array4<Real> const& phi = m_phi_eb[amrlev].array(mfi);
266 AMREX_HOST_DEVICE_FOR_3D(ndbx, i, j, k,
267 {
268 if (lstarr(i,j,k) >= Real(0.0)) {
269 phi(i,j,k) = f(AMREX_D_DECL(problo[0]+Real(i)*cellsize[0],
270 problo[1]+Real(j)*cellsize[1],
271 problo[2]+Real(k)*cellsize[2]));
272 }
273 });
274 }
275 }
276 }
277 }
278}
279
280#endif
281
282}
283
284#endif
Fixed-size array types for use on GPU and CPU.
#define AMREX_HOST_DEVICE_FOR_3D(...)
Definition AMReX_GpuLaunchMacrosC.nolint.H:106
Array4< Real > fine
Definition AMReX_InterpFaceRegister.cpp:90
Array4< Real const > crse
Definition AMReX_InterpFaceRegister.cpp:92
Array4< Real const > levset
Definition AMReX_MLEBNodeFDLaplacian.cpp:1556
#define AMREX_D_DECL(a, b, c)
Definition AMReX_SPACE.H:171
GpuArray< Real, 3 > CellSizeArray() const noexcept
Returns the cell sizes as a GpuArray for use on host or device.
Definition AMReX_CoordSys.H:85
Definition AMReX_EBFabFactory.H:32
Rectangular problem domain geometry.
Definition AMReX_Geometry.H:85
GpuArray< Real, 3 > ProbLoArray() const noexcept
Return the lo end of the problem domain in a GpuArray for device code.
Definition AMReX_Geometry.H:217
HYPRE_Int Int
Definition AMReX_HypreNodeLap.H:59
Iterator for looping ever tiles and boxes of amrex::FabArray based containers.
Definition AMReX_MFIter.H:88
bool isValid() const noexcept
Is the iterator valid i.e. is it associated with a FAB?
Definition AMReX_MFIter.H:176
Nodal finite-difference Laplacian with optional embedded boundaries.
Definition AMReX_MLEBNodeFDLaplacian.H:44
void restriction(int amrlev, int cmglev, MultiFab &crse, MultiFab &fine) const final
Restrict nodal data from fine to coarse MG levels.
Definition AMReX_MLEBNodeFDLaplacian.cpp:176
std::string name() const override
Definition AMReX_MLEBNodeFDLaplacian.H:132
bool isBottomSingular() const final
Is the bottom of the multigrid hierarchy singular?
Definition AMReX_MLEBNodeFDLaplacian.H:179
MLEBNodeFDLaplacian & operator=(const MLEBNodeFDLaplacian &)=delete
bool needsUpdate() const override
Does it need update if it's reused?
Definition AMReX_MLEBNodeFDLaplacian.H:154
void compGrad(int amrlev, const Array< MultiFab *, 3 > &grad, MultiFab &sol, Location) const override
Compute gradients of sol into grad.
Definition AMReX_MLEBNodeFDLaplacian.cpp:699
void Fsmooth(int amrlev, int mglev, MultiFab &sol, const MultiFab &rhs) const final
Perform the nodal smoother on (amrlev,mglev).
Definition AMReX_MLEBNodeFDLaplacian.cpp:563
void interpolation(int amrlev, int fmglev, MultiFab &fine, const MultiFab &crse) const final
Add the prolongation of coarse data onto the fine grid (fine += prolong(crse)).
Definition AMReX_MLEBNodeFDLaplacian.cpp:235
void setAlpha(Real a_alpha)
Set the radial alpha/r^2 term used when RZ is enabled.
Definition AMReX_MLEBNodeFDLaplacian.cpp:74
void setEBDirichlet(Real a_phi_eb)
Override phi on embedded boundaries (constant value).
Definition AMReX_MLEBNodeFDLaplacian.cpp:86
MLEBNodeFDLaplacian(const MLEBNodeFDLaplacian &)=delete
bool supportCustomBottomSolver() const override
Does this operator provide its own bottom solver (BottomSolver::custom)?
Definition AMReX_MLEBNodeFDLaplacian.H:215
bool scaleRHS(int amrlev, MultiFab *rhs) const final
Definition AMReX_MLEBNodeFDLaplacian.cpp:376
BottomSolver getDefaultBottomSolver() const override
Definition AMReX_MLEBNodeFDLaplacian.H:211
void setRZ(bool flag)
Enable/disable RZ corrections (radial metrics).
Definition AMReX_MLEBNodeFDLaplacian.cpp:64
void customBottomSolve(MLMGT< MultiFab > *mlmg, MultiFab &x, const MultiFab &b, Real eps_rel, Real eps_abs, int maxiter) override
Definition AMReX_MLEBNodeFDLaplacian.cpp:1563
void define(const Vector< Geometry > &a_geom, const Vector< BoxArray > &a_grids, const Vector< DistributionMapping > &a_dmap, const LPInfo &a_info, const Vector< EBFArrayBoxFactory const * > &a_factory)
Define the hierarchy using EB factories (captures cut-cell layout).
Definition AMReX_MLEBNodeFDLaplacian.cpp:92
void Fapply(int amrlev, int mglev, MultiFab &out, const MultiFab &in) const final
Apply the nodal operator to in and write to out.
Definition AMReX_MLEBNodeFDLaplacian.cpp:412
void normalize(int amrlev, int mglev, MultiFab &mf) const final
Divide mf by the diagonal of the operator (used by CG-family bottom solvers).
Definition AMReX_MLEBNodeFDLaplacian.cpp:687
void setSigma(Array< Real, 3 > const &a_sigma) noexcept
Assign constant diagonal conductivity tensor sigma.
Definition AMReX_MLEBNodeFDLaplacian.cpp:42
void update() override
Update for reuse.
Definition AMReX_MLEBNodeFDLaplacian.cpp:1000
MLEBNodeFDLaplacian(MLEBNodeFDLaplacian &&)=delete
void prepareForSolve() final
Finalize sigma/alpha/EB data prior to invoking MLMG.
Definition AMReX_MLEBNodeFDLaplacian.cpp:291
std::unique_ptr< FabFactory< FArrayBox > > makeFactory(int amrlev, int mglev) const final
EB-aware factory allocator for (amrlev,mglev).
Definition AMReX_MLEBNodeFDLaplacian.cpp:160
~MLEBNodeFDLaplacian() override=default
void compGrad_doit(int amrlev, const Array< MultiFab *, 3 > &grad, MultiFab &sol) const
Definition AMReX_MLEBNodeFDLaplacian.cpp:720
void fixUpResidualMask(int amrlev, iMultiFab &resmsk) final
Adjust the residual mask resmsk to honor EB Dirichlet nodes (not yet implemented).
Definition AMReX_MLEBNodeFDLaplacian.cpp:693
void postSolve(Vector< MultiFab * > const &sol) const override
Post-process the solution hierarchy.
Definition AMReX_MLEBNodeFDLaplacian.cpp:963
bool isSingular(int) const final
Is it singular on AMR level amrlev?
Definition AMReX_MLEBNodeFDLaplacian.H:178
virtual bool needsUpdate() const
Does it need update if it's reused?
Definition AMReX_MLLinOp.H:353
LinOpEnumType::Location Location
Definition AMReX_MLLinOp.H:153
Definition AMReX_MLMG.H:26
Definition AMReX_MLNodeLinOp.H:23
A collection (stored as an array) of FArrayBox objects.
Definition AMReX_MultiFab.H:40
This class is a thin wrapper around std::vector. Unlike vector, Vector::operator[] provides bound che...
Definition AMReX_Vector.H:29
A Collection of IArrayBoxes.
Definition AMReX_iMultiFab.H:34
amrex_real Real
Floating Point Type for Fields.
Definition AMReX_REAL.H:80
@ regular
Every cell in the region is regular.
__host__ __device__ BoxND< dim > convert(const BoxND< dim > &b, const IntVectND< dim > &typ) noexcept
Return a copy of b converted to the nodal flags typ.
Definition AMReX_Box.H:1630
std::array< T, N > Array
Definition AMReX_Array.H:31
Definition AMReX_Amr.cpp:50
BottomSolver
Definition AMReX_MLLinOp.H:40
IntVectND< 3 > IntVect
IntVect is an alias for amrex::IntVectND instantiated with AMREX_SPACEDIM.
Definition AMReX_BaseFwd.H:38
bool TilingIfNotGPU() noexcept
Definition AMReX_MFIter.H:12
A multidimensional array accessor.
Definition AMReX_Array4.H:289
Fixed-size array that can be used on GPU.
Definition AMReX_Array.H:52
Test if a given type T is callable with arguments of type Args...
Definition AMReX_TypeTraits.H:214
Configuration knobs for multilevel linear operators (grid agglomeration, metrics, etc....
Definition AMReX_MLLinOp.H:51