Block-Structured AMR Software Framework
Loading...
Searching...
No Matches
AMReX_MLNodeLaplacian.H
Go to the documentation of this file.
1#ifndef AMREX_ML_NODE_LAPLACIAN_H_
2#define AMREX_ML_NODE_LAPLACIAN_H_
3#include <AMReX_Config.H>
4
5#include <AMReX_iMultiFab.H>
6#include <AMReX_MLNodeLinOp.H>
7#include <AMReX_MultiFab.H>
8#include <AMReX_Vector.H>
9
10// Feature macro: when defined, MLNodeLaplacian::updateVelocity and
11// MLNodeLaplacian::getFluxes correctly route through the anisotropic
12// (harmonic-average) mknewu kernel when setMapped(true) was used. Prior
13// to this, both functions only used sigma component 0 (sigma_x) for all
14// velocity/flux components, producing the wrong correction for
15// non-identity mesh mappings. EB and RAP coarsening are not covered by
16// this feature (see comments in AMReX_MLNodeLaplacian_misc.cpp).
17#define AMREX_MLNODELAP_HAS_MKNEWU_HA 1
18
19namespace amrex {
20
26
27// del dot (sigma grad phi) = rhs
28// where phi and rhs are nodal, and sigma is cell-centered.
29
32 : public MLNodeLinOp
33{
34public :
35
36 friend class HypreMLNodeLap;
37
39 MLNodeLaplacian () = default;
51 MLNodeLaplacian (const Vector<Geometry>& a_geom,
52 const Vector<BoxArray>& a_grids,
53 const Vector<DistributionMapping>& a_dmap,
54 const LPInfo& a_info = LPInfo(),
55 const Vector<FabFactory<FArrayBox> const*>& a_factory = {},
56 Real a_const_sigma = Real(0.0));
57#ifdef AMREX_USE_EB
59 MLNodeLaplacian (const Vector<Geometry>& a_geom,
60 const Vector<BoxArray>& a_grids,
61 const Vector<DistributionMapping>& a_dmap,
62 const LPInfo& a_info,
63 const Vector<EBFArrayBoxFactory const*>& a_factory,
64 Real a_const_sigma = Real(0.0));
65#endif
66 ~MLNodeLaplacian () override = default;
67
72
84 void define (const Vector<Geometry>& a_geom,
85 const Vector<BoxArray>& a_grids,
86 const Vector<DistributionMapping>& a_dmap,
87 const LPInfo& a_info = LPInfo(),
88 const Vector<FabFactory<FArrayBox> const*>& a_factory = {},
89 Real a_const_sigma = Real(0.0));
90
91#ifdef AMREX_USE_EB
92 void define (const Vector<Geometry>& a_geom,
93 const Vector<BoxArray>& a_grids,
94 const Vector<DistributionMapping>& a_dmap,
95 const LPInfo& a_info,
96 const Vector<EBFArrayBoxFactory const*>& a_factory,
97 Real a_const_sigma = Real(0.0));
98#endif
99
100 std::string name () const override { return std::string("MLNodeLaplacian"); }
101
107 void setRZCorrection (bool rz) noexcept { m_is_rz = rz; }
108
114 void setNormalizationThreshold (Real t) noexcept {
115 if (m_normalization_threshold != t) {
116 m_normalization_threshold = t;
117 m_needs_update = true;
118 }
119 }
120
128 void setSigma (int amrlev, const MultiFab& a_sigma);
129
131 void compDivergence (const Vector<MultiFab*>& rhs, const Vector<MultiFab*>& vel);
132
134 void compRHS (const Vector<MultiFab*>& rhs, const Vector<MultiFab*>& vel,
135 const Vector<const MultiFab*>& rhnd,
136 const Vector<MultiFab*>& rhcc);
137
139 void updateVelocity (const Vector<MultiFab*>& vel, const Vector<MultiFab const*>& sol) const;
140
142 void compSyncResidualCoarse (MultiFab& sync_resid, const MultiFab& phi,
143 const MultiFab& vold, const MultiFab* rhcc,
144 const BoxArray& fine_grids, const IntVect& ref_ratio);
145
147 void compSyncResidualFine (MultiFab& sync_resid, const MultiFab& phi, const MultiFab& vold,
148 const MultiFab* rhcc);
149
155 void setGaussSeidel (bool flag) noexcept { m_use_gauss_seidel = flag; }
161 void setHarmonicAverage (bool flag) noexcept {
162 if (m_use_harmonic_average != flag) {
163 m_use_harmonic_average = flag;
164 m_needs_update = true;
165 }
166 }
167
173 void setMapped (bool flag) noexcept {
174 if (m_use_mapped != flag) {
175 m_use_mapped = flag;
176 m_needs_update = true;
177 }
178 }
179
186 if (m_const_sigma == Real(0.0) && m_coarsening_strategy != cs) {
188 m_masks_built = false;
189 m_precond_weight_mask.clear();
190 m_needs_update = true;
191 }
192 }
193
198
200 void restriction (int amrlev, int cmglev, MultiFab& crse, MultiFab& fine) const final;
202 void interpolation (int amrlev, int fmglev, MultiFab& fine, const MultiFab& crse) const final;
204 void averageDownSolutionRHS (int camrlev, MultiFab& crse_sol, MultiFab& crse_rhs,
205 const MultiFab& fine_sol, const MultiFab& fine_rhs) final;
206
217 void interpCoarseFineSolution (int famrlev, MultiFab& fine_sol,
218 const MultiFab& crse_sol) const final;
219
224 void reflux (int crse_amrlev,
225 MultiFab& res, const MultiFab& crse_sol, const MultiFab& crse_rhs,
226 MultiFab& fine_res, MultiFab& fine_sol, const MultiFab& fine_rhs) const final;
227
229 void prepareForSolve () final;
231 [[nodiscard]] bool needsUpdate () const final { return m_needs_update; }
233 void update () final;
235 void Fapply (int amrlev, int mglev, MultiFab& out, const MultiFab& in) const final;
244 void Fsmooth (int amrlev, int mglev, MultiFab& sol, const MultiFab& rhs) const final;
246 void normalize (int amrlev, int mglev, MultiFab& mf) const final;
247
249 void fixUpResidualMask (int amrlev, iMultiFab& resmsk) final;
250
258 void getFluxes (const Vector<Array<MultiFab*,AMREX_SPACEDIM> >& a_flux,
259 const Vector<MultiFab*>& a_sol,
260 Location a_loc) const final {
261 amrex::ignore_unused(a_flux, a_sol, a_loc);
262 amrex::Abort("MLNodeLaplacian::getFluxes: How did we get here?");
263 }
264
265 void getFluxes (const Vector<MultiFab*>& a_flux,
266 const Vector<MultiFab*>& a_sol) const final;
268 void unimposeNeumannBC (int amrlev, MultiFab& rhs) const final;
270 Vector<Real> getSolvabilityOffset (int amrlev, int mglev,
271 MultiFab const& rhs) const override;
273 void fixSolvabilityByOffset (int amrlev, int mglev, MultiFab& rhs,
274 Vector<Real> const& offset) const override;
275
284 void compGrad (int amrlev, const Array<MultiFab*,AMREX_SPACEDIM>& grad,
285 MultiFab& sol, Location loc) const final {
286 amrex::ignore_unused(amrlev, grad, sol, loc);
287 amrex::Abort("MLNodeLaplacian::compGrad: How did we get here?");
288 }
289
296 void compGrad (int amrlev, MultiFab& grad, MultiFab& sol) const;
297
299 void averageDownCoeffs ();
301 void averageDownCoeffsToCoarseAmrLevel (int flev);
303 void averageDownCoeffsSameAmrLevel (int amrlev);
304
306 void restrictInteriorNodes (int camrlev, MultiFab& crhs, MultiFab& frhs) const;
307
309 void FillBoundaryCoeff (MultiFab& sigma, const Geometry& geom);
310
312 void buildStencil ();
313
314#ifdef AMREX_USE_EB
315 void buildIntegral ();
316 void buildSurfaceIntegral ();
317
318 // Tells the solver that EB boundaries have inflow specified by "eb_vel"
319 void setEBInflowVelocity (int amrlev, const MultiFab& eb_vel);
320
321#endif
322
323#if (AMREX_SPACEDIM > 1)
324#if defined(AMREX_USE_HYPRE)
325 void fillIJMatrix (MFIter const& mfi,
327 Array4<int const> const& lid,
328 HypreNodeLap::Int* ncols,
329 HypreNodeLap::Int* cols,
330 Real* mat) const override;
331#endif
332
333 [[nodiscard]] bool supportsAlgMG () const override { return true; }
334 void fillAlgMatrix (int mglev, MFIter const& mfi,
335 Array4<Long const> const& gid,
336 Array4<int const> const& lid,
337 Long* ncols, Long* cols, Real* mat) const override;
338
339 void fillRHS (int mglev, MFIter const& mfi, Array4<int const> const& lid,
340 Real* rhs, Array4<Real const> const& bfab) const override;
341
342 // Public for nvcc. AlgGid is the global row id type: Long for AlgMG,
343 // HypreNodeLap::AtomicInt for hypre.
344 template <typename AlgInt, typename AlgGid>
345 void fillMatrix_doit (int mglev, MFIter const& mfi,
346 Array4<AlgGid const> const& gid,
347 Array4<int const> const& lid,
348 AlgInt* ncols, AlgInt* cols, Real* mat) const;
349#ifdef AMREX_USE_GPU
350 template <typename AlgInt, typename AlgGid>
351 void fillMatrix_gpu (int mglev, MFIter const& mfi,
352 Array4<AlgGid const> const& gid,
353 Array4<int const> const& lid,
354 AlgInt* ncols, AlgInt* cols, Real* mat) const;
355#endif
356 template <typename AlgInt, typename AlgGid>
357 void fillMatrix_cpu (int mglev, MFIter const& mfi,
358 Array4<AlgGid const> const& gid,
359 Array4<int const> const& lid,
360 AlgInt* ncols, AlgInt* cols, Real* mat) const;
361#endif
362
363protected:
364
365 void resizeMultiGrid (int new_size) final;
366
367private:
368
369 int m_is_rz = 0;
370
371 Real m_const_sigma = Real(0.0);
372 Vector<Vector<Array<std::unique_ptr<MultiFab>,AMREX_SPACEDIM> > > m_sigma;
374 Vector<std::unique_ptr<MultiFab> > m_nosigma_stencil;
375 Vector<Vector<Real> > m_s0_norm0;
376
377 Real m_normalization_threshold = Real(1.e-8);
378
379#ifdef AMREX_USE_EB
380 // they could be MultiCutFab
382 bool m_integral_built = false;
383
384 Vector<std::unique_ptr<MultiFab> > m_surface_integral;
385 bool m_surface_integral_built = false;
386 bool m_build_surface_integral = false;
387 Vector<std::unique_ptr<MultiFab> > m_eb_vel_dot_n;
388#endif
389
390 bool m_use_gauss_seidel = true;
391 bool m_use_harmonic_average = false;
392 bool m_use_mapped = false;
393 bool m_needs_update = true;
394
395 void checkPoint (std::string const& file_name) const final;
396};
397
398}
399
400#endif
Reference-counted collection of Boxes.
Definition AMReX_BoxArray.H:681
Abstract factory interface for creating, aliasing, and destroying FAB objects.
Definition AMReX_FabFactory.H:73
Rectangular problem domain geometry.
Definition AMReX_Geometry.H:87
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
friend class HypreMLNodeLap
Definition AMReX_MLNodeLaplacian.H:36
void restrictInteriorNodes(int camrlev, MultiFab &crhs, MultiFab &frhs) const
Restrict interior-node RHS from fine to coarse when syncing.
Definition AMReX_MLNodeLaplacian.cpp:810
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_MLNodeLaplacian.cpp:904
void FillBoundaryCoeff(MultiFab &sigma, const Geometry &geom)
Fill ghost cells of sigma using geom for BC inference.
Definition AMReX_MLNodeLaplacian.cpp:409
void define(const Vector< Geometry > &a_geom, const Vector< BoxArray > &a_grids, const Vector< DistributionMapping > &a_dmap, const LPInfo &a_info=LPInfo(), const Vector< FabFactory< FArrayBox > const * > &a_factory={}, Real a_const_sigma=Real(0.0))
Bind the nodal operator (no EB data).
Definition AMReX_MLNodeLaplacian.cpp:39
void setHarmonicAverage(bool flag) noexcept
Toggle harmonic averaging when coarsening sigma.
Definition AMReX_MLNodeLaplacian.H:161
void averageDownSolutionRHS(int camrlev, MultiFab &crse_sol, MultiFab &crse_rhs, const MultiFab &fine_sol, const MultiFab &fine_rhs) final
Average solution/RHS pairs from fine AMR levels onto (camrlev).
Definition AMReX_MLNodeLaplacian.cpp:755
std::string name() const override
Definition AMReX_MLNodeLaplacian.H:100
void prepareForSolve() final
Finalize metric terms, sigma averages, and BC caches before solving.
Definition AMReX_MLNodeLaplacian.cpp:457
void fixUpResidualMask(int amrlev, iMultiFab &resmsk) final
Adjust residual masks so EB Dirichlet nodes remain constrained.
Definition AMReX_MLNodeLaplacian.cpp:435
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_MLNodeLaplacian_matrix.cpp:24
MLNodeLaplacian(const MLNodeLaplacian &)=delete
void compSyncResidualFine(MultiFab &sync_resid, const MultiFab &phi, const MultiFab &vold, const MultiFab *rhcc)
Build fine-level sync residuals for multilevel projections.
Definition AMReX_MLNodeLaplacian_sync.cpp:413
void Fapply(int amrlev, int mglev, MultiFab &out, const MultiFab &in) const final
Apply the nodal Laplacian to in at (amrlev,mglev).
Definition AMReX_MLNodeLaplacian_misc.cpp:212
void setSigma(int amrlev, const MultiFab &a_sigma)
Provide per-level conductivity (cell-centered MultiFab). A multi-component input also triggers mapped...
Definition AMReX_MLNodeLaplacian.cpp:381
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_MLNodeLaplacian_matrix.cpp:34
void setNormalizationThreshold(Real t) noexcept
Threshold for normalization (prevents dividing by tiny averages).
Definition AMReX_MLNodeLaplacian.H:114
void buildStencil()
Build nodal operator stencils reflecting current sigma and metrics.
Definition AMReX_MLNodeLaplacian_sten.cpp:18
void compRHS(const Vector< MultiFab * > &rhs, const Vector< MultiFab * > &vel, const Vector< const MultiFab * > &rhnd, const Vector< MultiFab * > &rhcc)
Assemble RHS including nodal/cell-centered forcing terms.
Definition AMReX_MLNodeLaplacian_misc.cpp:1072
MLNodeLaplacian()=default
Construct an empty operator; call define() before solving.
void setEBInflowVelocity(int amrlev, const MultiFab &eb_vel)
Definition AMReX_MLNodeLaplacian.cpp:1089
void buildIntegral()
Definition AMReX_MLNodeLaplacian_eb.cpp:15
void updateVelocity(const Vector< MultiFab * > &vel, const Vector< MultiFab const * > &sol) const
Update velocities using the Poisson solution (projection correction).
Definition AMReX_MLNodeLaplacian_misc.cpp:732
void update() final
Refresh sigma averages/stencils and clear the dirty flag.
Definition AMReX_MLNodeLaplacian.cpp:478
~MLNodeLaplacian() override=default
Vector< Real > getSolvabilityOffset(int amrlev, int mglev, MultiFab const &rhs) const override
Compute component-wise offsets needed for solvability enforcement.
Definition AMReX_MLNodeLaplacian.cpp:169
void getFluxes(const Vector< Array< MultiFab *, 3 > > &a_flux, const Vector< MultiFab * > &a_sol, Location a_loc) const final
This overload is unused for nodal Laplacians (only cell-centered flux extraction is supported).
Definition AMReX_MLNodeLaplacian.H:258
void fillMatrix_cpu(int mglev, MFIter const &mfi, Array4< AlgGid const > const &gid, Array4< int const > const &lid, AlgInt *ncols, AlgInt *cols, Real *mat) const
Definition AMReX_MLNodeLaplacian_matrix.cpp:191
MLNodeLaplacian(MLNodeLaplacian &&)=delete
void setMapped(bool flag) noexcept
Enable mapped-coordinate metrics (non-orthogonal grids).
Definition AMReX_MLNodeLaplacian.H:173
void setGaussSeidel(bool flag) noexcept
Choose red-black Gauss-Seidel instead of Jacobi smoothing.
Definition AMReX_MLNodeLaplacian.H:155
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_MLNodeLaplacian.cpp:604
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_MLNodeLaplacian_matrix.cpp:249
BottomSolver getDefaultBottomSolver() const final
Definition AMReX_MLNodeLaplacian.H:194
void restriction(int amrlev, int cmglev, MultiFab &crse, MultiFab &fine) const final
Restrict nodal data from fine grids to coarse MG level cmglev.
Definition AMReX_MLNodeLaplacian.cpp:489
void Fsmooth(int amrlev, int mglev, MultiFab &sol, const MultiFab &rhs) const final
Execute the smoother on (amrlev,mglev).
Definition AMReX_MLNodeLaplacian_misc.cpp:360
MLNodeLaplacian & operator=(const MLNodeLaplacian &)=delete
void reflux(int crse_amrlev, MultiFab &res, const MultiFab &crse_sol, const MultiFab &crse_rhs, MultiFab &fine_res, MultiFab &fine_sol, const MultiFab &fine_rhs) const final
Flux register reflux coupling coarse/fine nodal solves (updates res using the solution and RHS arrays...
Definition AMReX_MLNodeLaplacian_sync.cpp:779
void averageDownCoeffs()
Average conductivity down across all AMR and MG levels.
Definition AMReX_MLNodeLaplacian_misc.cpp:17
void buildSurfaceIntegral()
Definition AMReX_MLNodeLaplacian_eb.cpp:84
void compGrad(int amrlev, const Array< MultiFab *, 3 > &grad, MultiFab &sol, Location loc) const final
Unsupported flux-style gradient extractor (kept for interface completeness).
Definition AMReX_MLNodeLaplacian.H:284
void setRZCorrection(bool rz) noexcept
Enable cylindrical (RZ) metric terms.
Definition AMReX_MLNodeLaplacian.H:107
void interpCoarseFineSolution(int famrlev, MultiFab &fine_sol, const MultiFab &crse_sol) const final
Set the coarse/fine nodes of fine AMR level famrlev (Dirichlet mask set, not on a Dirichlet domain fa...
Definition AMReX_MLNodeLaplacian.cpp:771
void fillMatrix_gpu(int mglev, MFIter const &mfi, Array4< AlgGid const > const &gid, Array4< int const > const &lid, AlgInt *ncols, AlgInt *cols, Real *mat) const
Definition AMReX_MLNodeLaplacian_matrix.cpp:53
void compDivergence(const Vector< MultiFab * > &rhs, const Vector< MultiFab * > &vel)
Compute rhs = div(vel) on nodal grids (used for projections).
Definition AMReX_MLNodeLaplacian_misc.cpp:1066
void fixSolvabilityByOffset(int amrlev, int mglev, MultiFab &rhs, Vector< Real > const &offset) const override
Subtract solvability offsets from rhs.
Definition AMReX_MLNodeLaplacian.cpp:284
void averageDownCoeffsToCoarseAmrLevel(int flev)
Average coefficients from fine AMR level flev to coarse AMR level flev-1.
Definition AMReX_MLNodeLaplacian_misc.cpp:86
void unimposeNeumannBC(int amrlev, MultiFab &rhs) const final
Remove Neumann contributions previously imposed on rhs.
Definition AMReX_MLNodeLaplacian.cpp:147
void resizeMultiGrid(int new_size) final
Definition AMReX_MLNodeLaplacian.cpp:123
bool needsUpdate() const final
True if sigma-derived data need to be refreshed before reuse.
Definition AMReX_MLNodeLaplacian.H:231
void setCoarseningStrategy(CoarseningStrategy cs) noexcept
Pick between sigma-weighted or RAP coarsening (ignored if sigma constant).
Definition AMReX_MLNodeLaplacian.H:185
bool supportsAlgMG() const override
True if makeAlgMG is implemented for this operator.
Definition AMReX_MLNodeLaplacian.H:333
void compSyncResidualCoarse(MultiFab &sync_resid, const MultiFab &phi, const MultiFab &vold, const MultiFab *rhcc, const BoxArray &fine_grids, const IntVect &ref_ratio)
Build coarse-level sync residuals for multilevel projections.
Definition AMReX_MLNodeLaplacian_sync.cpp:16
void averageDownCoeffsSameAmrLevel(int amrlev)
Average coefficients across MG levels within AMR level amrlev.
Definition AMReX_MLNodeLaplacian_misc.cpp:115
bool m_masks_built
Definition AMReX_MLNodeLinOp.H:307
CoarseningStrategy
Definition AMReX_MLNodeLinOp.H:28
@ RAP
Definition AMReX_MLNodeLinOp.H:28
MLNodeLinOp()
Definition AMReX_MLNodeLinOp.cpp:18
Vector< MultiFab > m_precond_weight_mask
Definition AMReX_MLNodeLinOp.H:297
CoarseningStrategy m_coarsening_strategy
Definition AMReX_MLNodeLinOp.H:302
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
ArrayND< T, 4, true > Array4
Convenient alias for a 4D ArrayND with three spatial dimensions plus a component dimension.
Definition AMReX_Array4.H:1340
std::array< T, N > Array
Definition AMReX_Array.H:31
Definition AMReX_Amr.cpp:50
__host__ __device__ void ignore_unused(const Ts &...)
No-op helper that marks variables as intentionally unused.
Definition AMReX.H:273
BottomSolver
Definition AMReX_MLLinOp.H:42
@ bicgcg
Definition AMReX_MLLinOp.H:43
@ bicgstab
Definition AMReX_MLLinOp.H:43
IntVectND< 3 > IntVect
IntVect is an alias for amrex::IntVectND instantiated with AMREX_SPACEDIM.
Definition AMReX_BaseFwd.H:38
void Abort(const std::string &msg)
Print a fatal-error message to stderr and abort execution.
Definition AMReX.cpp:244
Configuration knobs for multilevel linear operators (grid agglomeration, metrics, etc....
Definition AMReX_MLLinOp.H:53