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_LayoutData.H>
10#include <AMReX_MLNodeLinOp.H>
11
12#include <limits>
13
14namespace amrex {
15
23// Although the class has EB in the name, it works for non-EB build too.
24//
25// del dot (sigma grad phi) = rhs, for non-RZ
26// where phi and rhs are nodal multifab, and sigma is a tensor constant
27// with only diagonal components. The EB is assumed to be Dirichlet.
28//
29// del dot (sigma grad phi) - alpha/r^2 phi = rhs, for RZ where alpha is a
30// scalar constant that is zero by default.
31//
32// New feature: sigma can also be a single-component cell-centered multifab.
33//
34// The EB information needed on the coarse MG levels (covered nodes and open
35// EB positions on edges) is built here from the level-0 factory, so multigrid
36// coarsening is not limited by the EB index space. Coarsening stops at the
37// last level that still has a handful of open nodes.
38
49 : public MLNodeLinOp
50{
51public:
52
53 MLEBNodeFDLaplacian () = default;
54
55#ifdef AMREX_USE_EB
58 const Vector<BoxArray>& a_grids,
59 const Vector<DistributionMapping>& a_dmap,
60 const LPInfo& a_info,
61 const Vector<EBFArrayBoxFactory const*>& a_factory);
62#endif
63
66 const Vector<BoxArray>& a_grids,
67 const Vector<DistributionMapping>& a_dmap,
68 const LPInfo& a_info);
69
70 ~MLEBNodeFDLaplacian () override = default;
71
76
84 void setSigma (Array<Real,AMREX_SPACEDIM> const& a_sigma) noexcept;
85
87 void setSigma (int amrlev, MultiFab const& a_sigma);
88
90 void setRZ (bool flag);
91
93 void setAlpha (Real a_alpha);
94
95#ifdef AMREX_USE_EB
96
98 void setEBDirichlet (Real a_phi_eb);
105 template <typename F>
106 requires (IsCallableR<Real,F,AMREX_D_DECL(Real,Real,Real)>::value)
107 void setEBDirichlet (F const& f);
108
118 void define (const Vector<Geometry>& a_geom,
119 const Vector<BoxArray>& a_grids,
120 const Vector<DistributionMapping>& a_dmap,
121 const LPInfo& a_info,
122 const Vector<EBFArrayBoxFactory const*>& a_factory);
123
124 [[nodiscard]] bool scaleRHS (int amrlev, MultiFab* rhs) const final;
125
126#endif
127
136 void define (const Vector<Geometry>& a_geom,
137 const Vector<BoxArray>& a_grids,
138 const Vector<DistributionMapping>& a_dmap,
139 const LPInfo& a_info);
140
141 [[nodiscard]] std::string name () const override { return std::string("MLEBNodeFDLaplacian"); }
142
151 void restriction (int amrlev, int cmglev, MultiFab& crse, MultiFab& fine) const final;
161 void interpolation (int amrlev, int fmglev, MultiFab& fine, const MultiFab& crse) const final;
162
163 [[nodiscard]] bool needsUpdate () const override {
164 return (m_needs_update || MLNodeLinOp::needsUpdate());
165 }
166 void update () override;
167
169 void prepareForSolve () final;
171 void Fapply (int amrlev, int mglev, MultiFab& out, const MultiFab& in) const final;
180 void Fsmooth (int amrlev, int mglev, MultiFab& sol, const MultiFab& rhs) const final;
182 void normalize (int amrlev, int mglev, MultiFab& mf) const final;
183
185 void fixUpResidualMask (int amrlev, iMultiFab& resmsk) final;
186
187 [[nodiscard]] bool isSingular (int) const final { return false; }
188 [[nodiscard]] bool isBottomSingular () const final { return false; }
189
197 void compGrad (int amrlev, const Array<MultiFab*,AMREX_SPACEDIM>& grad,
198 MultiFab& sol, Location /*loc*/) const override;
199
200 void compGrad_doit (int amrlev, const Array<MultiFab*,AMREX_SPACEDIM>& grad,
201 MultiFab& sol) const;
202
203#if (AMREX_SPACEDIM > 1)
204#if defined(AMREX_USE_HYPRE)
205 void fillIJMatrix (MFIter const& mfi,
207 Array4<int const> const& lid,
208 HypreNodeLap::Int* ncols,
209 HypreNodeLap::Int* cols,
210 Real* mat) const override;
211#endif
212
213 [[nodiscard]] bool supportsAnisotropicCoarsening () const override { return true; }
214
216 anisotropicCoarseningCellSize (Geometry const& geom) const override;
217
218 [[nodiscard]] bool supportsAlgMG () const override { return !m_rz; }
219
220 void fillAlgMatrix (int mglev, MFIter const& mfi,
221 Array4<Long const> const& gid,
222 Array4<int const> const& lid,
223 Long* ncols, Long* cols, Real* mat) const override;
224
225 void fillRHS (int mglev, MFIter const& mfi,
226 Array4<int const> const& lid,
227 Real* rhs,
228 Array4<Real const> const& bfab) const override;
229
230 // Public for nvcc.
231 template <typename AlgInt, typename AlgGid>
232 void fillMatrix_doit (int mglev, MFIter const& mfi,
233 Array4<AlgGid const> const& gid,
234 Array4<int const> const& lid,
235 AlgInt* ncols, AlgInt* cols, Real* mat) const;
236#endif
237
239 void postSolve (Vector<MultiFab*> const& sol) const override;
240
241 [[nodiscard]] BottomSolver getDefaultBottomSolver () const override {
243 }
244
245 [[nodiscard]] bool supportCustomBottomSolver () const override { return true; }
246
247 void customBottomSolve (MLMGT<MultiFab>* mlmg, MultiFab& x, const MultiFab& b,
248 Real eps_rel, Real eps_abs, int maxiter) override;
249
250protected:
251 void buildMGHierarchy () override;
252
253private:
254 GpuArray<Real,AMREX_SPACEDIM> m_sigma{{AMREX_D_DECL(1_rt,1_rt,1_rt)}};
256 Vector<std::unique_ptr<MultiFab>> m_sigma_mf;
258 Vector<Vector<Array<MultiFab,AMREX_SPACEDIM>>> m_sigma_edge;
259 bool m_has_sigma_mf = false;
260 bool m_needs_update = true;
261 Real m_s_phi_eb = std::numeric_limits<Real>::lowest();
262 Vector<MultiFab> m_phi_eb;
263 int m_rz = false;
264 Real m_rz_alpha = 0._rt;
265
266#ifdef AMREX_USE_EB
268 Vector<Vector<MultiFab>> m_levset;
271 Vector<Vector<Array<MultiFab,AMREX_SPACEDIM>>> m_eb_pos;
274 Vector<Vector<LayoutData<int>>> m_has_eb;
275#ifdef AMREX_USE_GPU
277 Vector<Vector<Gpu::DeviceVector<int>>> m_has_eb_d;
278#endif
281 Vector<Vector<int>> m_eb_lost;
283 Vector<Vector<MultiFab>> m_row_scale;
285 Vector<Vector<MultiFab>> m_row_scale_crse;
286#endif
287
288public:
289 // These are public only because they launch GPU kernels.
290#ifdef AMREX_USE_EB
291 void build_eb_data ();
293 void limit_coarsening ();
294#endif
295 void update_sigma ();
296};
297
298#ifdef AMREX_USE_EB
299
300template <typename F>
301requires (IsCallableR<Real,F,AMREX_D_DECL(Real,Real,Real)>::value)
303{
304 // Select m_phi_eb again, in case a previous prepareForSolve defaulted
305 // to homogeneous Dirichlet or a scalar value was set earlier.
306 m_s_phi_eb = std::numeric_limits<Real>::lowest();
307 m_phi_eb.resize(m_num_amr_levels);
308 for (int amrlev = 0; amrlev < m_num_amr_levels; ++amrlev) {
309 auto const* factory = dynamic_cast<EBFArrayBoxFactory const*>(m_factory[amrlev][0].get());
310 if (factory) {
311 Geometry const& geom = m_geom[amrlev][0];
312 auto const problo = geom.ProbLoArray();
313 auto const cellsize = geom.CellSizeArray();
314 if (m_phi_eb[amrlev].empty()) {
315 m_phi_eb[amrlev].define(amrex::convert(m_grids[amrlev][0],IntVect(1)),
316 m_dmap[amrlev][0], 1, 1);
317 m_phi_eb[amrlev].setVal(0.0);
318 }
319 auto const& flags = factory->getMultiEBCellFlagFab();
320 auto const& levset = factory->getLevelSet();
321#ifdef AMREX_USE_OMP
322#pragma omp parallel if (Gpu::notInLaunchRegion())
323#endif
324 for (MFIter mfi(m_phi_eb[amrlev],TilingIfNotGPU()); mfi.isValid(); ++mfi)
325 {
326 const Box& ndbx = mfi.growntilebox();
327 const auto& flag = flags[mfi];
328 if (flag.getType() != FabType::regular) {
329 Array4<Real const> const lstarr = levset.const_array(mfi);
330 Array4<Real> const& phi = m_phi_eb[amrlev].array(mfi);
331 AMREX_HOST_DEVICE_FOR_3D(ndbx, i, j, k,
332 {
333 if (lstarr(i,j,k) >= Real(0.0)) {
334 phi(i,j,k) = f(AMREX_D_DECL(problo[0]+Real(i)*cellsize[0],
335 problo[1]+Real(j)*cellsize[1],
336 problo[2]+Real(k)*cellsize[2]));
337 }
338 });
339 }
340 }
341 }
342 }
343}
344
345#endif
346
347}
348
349#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:2065
#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:50
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:802
std::string name() const override
Definition AMReX_MLEBNodeFDLaplacian.H:141
bool isBottomSingular() const final
Is the bottom of the multigrid hierarchy singular?
Definition AMReX_MLEBNodeFDLaplacian.H:188
void fillRHS(int mglev, MFIter const &mfi, Array4< int const > const &lid, Real *rhs, Array4< Real const > const &bfab) const override
Fill the right-hand side of the rows of one box on MG level mglev.
Definition AMReX_MLEBNodeFDLaplacian.cpp:1600
void buildMGHierarchy() override
Build the MG levels of AMR level 0 below the finest one.
Definition AMReX_MLEBNodeFDLaplacian.cpp:789
MLEBNodeFDLaplacian & operator=(const MLEBNodeFDLaplacian &)=delete
bool needsUpdate() const override
Does it need update if it's reused?
Definition AMReX_MLEBNodeFDLaplacian.H:163
void compGrad(int amrlev, const Array< MultiFab *, 3 > &grad, MultiFab &sol, Location) const override
Compute gradients of sol into grad.
Definition AMReX_MLEBNodeFDLaplacian.cpp:1342
void Fsmooth(int amrlev, int mglev, MultiFab &sol, const MultiFab &rhs) const final
Perform the nodal smoother on (amrlev,mglev).
Definition AMReX_MLEBNodeFDLaplacian.cpp:1210
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:897
void setAlpha(Real a_alpha)
Set the radial alpha/r^2 term used when RZ is enabled.
Definition AMReX_MLEBNodeFDLaplacian.cpp:362
void setEBDirichlet(Real a_phi_eb)
Override phi on embedded boundaries (constant value).
Definition AMReX_MLEBNodeFDLaplacian.cpp:374
MLEBNodeFDLaplacian(const MLEBNodeFDLaplacian &)=delete
bool supportCustomBottomSolver() const override
Does this operator provide its own bottom solver (BottomSolver::custom)?
Definition AMReX_MLEBNodeFDLaplacian.H:245
bool scaleRHS(int amrlev, MultiFab *rhs) const final
Optionally scale the RHS to fix solvability.
Definition AMReX_MLEBNodeFDLaplacian.cpp:1085
BottomSolver getDefaultBottomSolver() const override
Definition AMReX_MLEBNodeFDLaplacian.H:241
void setRZ(bool flag)
Enable/disable RZ corrections (radial metrics).
Definition AMReX_MLEBNodeFDLaplacian.cpp:352
bool supportsAlgMG() const override
True if makeAlgMG is implemented for this operator.
Definition AMReX_MLEBNodeFDLaplacian.H:218
bool supportsAnisotropicCoarsening() const override
True if the operator supports MG levels coarsened in any subset of directions. Then MLMG coarsens str...
Definition AMReX_MLEBNodeFDLaplacian.H:213
GpuArray< Real, 3 > anisotropicCoarseningCellSize(Geometry const &geom) const override
Cell size used to pick the directions to coarsen when supportsAnisotropicCoarsening() is true....
Definition AMReX_MLEBNodeFDLaplacian.cpp:323
void customBottomSolve(MLMGT< MultiFab > *mlmg, MultiFab &x, const MultiFab &b, Real eps_rel, Real eps_abs, int maxiter) override
Definition AMReX_MLEBNodeFDLaplacian.cpp:2073
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:380
void build_eb_data()
Definition AMReX_MLEBNodeFDLaplacian.cpp:435
void limit_coarsening()
Drop coarse MG levels with too few unknowns, no EB, or a hidden EB feature.
Definition AMReX_MLEBNodeFDLaplacian.cpp:648
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:1120
void fillMatrix_doit(int mglev, MFIter const &mfi, Array4< AlgGid const > const &gid, Array4< int const > const &lid, AlgInt *ncols, AlgInt *cols, Real *mat) const
Definition AMReX_MLEBNodeFDLaplacian.cpp:1477
void update_sigma()
Definition AMReX_MLEBNodeFDLaplacian.cpp:1667
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:1330
void setSigma(Array< Real, 3 > const &a_sigma) noexcept
Assign constant diagonal conductivity tensor sigma.
Definition AMReX_MLEBNodeFDLaplacian.cpp:313
void update() override
Update for reuse.
Definition AMReX_MLEBNodeFDLaplacian.cpp:1654
MLEBNodeFDLaplacian(MLEBNodeFDLaplacian &&)=delete
void prepareForSolve() final
Finalize sigma/alpha/EB data prior to invoking MLMG.
Definition AMReX_MLEBNodeFDLaplacian.cpp:962
~MLEBNodeFDLaplacian() override=default
void fillAlgMatrix(int mglev, MFIter const &mfi, Array4< Long const > const &gid, Array4< int const > const &lid, Long *ncols, Long *cols, Real *mat) const override
Fill the matrix rows of one box for the algebraic solver.
Definition AMReX_MLEBNodeFDLaplacian.cpp:1467
void compGrad_doit(int amrlev, const Array< MultiFab *, 3 > &grad, MultiFab &sol) const
Definition AMReX_MLEBNodeFDLaplacian.cpp:1363
void fixUpResidualMask(int amrlev, iMultiFab &resmsk) final
Adjust the residual mask resmsk to honor EB Dirichlet nodes (not yet implemented).
Definition AMReX_MLEBNodeFDLaplacian.cpp:1336
void postSolve(Vector< MultiFab * > const &sol) const override
Post-process the solution hierarchy.
Definition AMReX_MLEBNodeFDLaplacian.cpp:1617
bool isSingular(int) const final
Is it singular on AMR level amrlev?
Definition AMReX_MLEBNodeFDLaplacian.H:187
virtual bool needsUpdate() const
Does it need update if it's reused?
Definition AMReX_MLLinOp.H:362
LinOpEnumType::Location Location
Definition AMReX_MLLinOp.H:155
Definition AMReX_MLMG.H:39
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
amrex_long Long
Definition AMReX_INT.H:30
@ 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:42
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:53