Alamo
Operator.H
Go to the documentation of this file.
1#ifndef OPERATOR_H
2#define OPERATOR_H
3
4#include <AMReX_MLNodeLinOp.H>
5#include <AMReX_MLCellLinOp.H>
6#include <AMReX_MultiFabUtil.H>
7#include <AMReX_BaseFab.H>
8
9#include "BC/BC.H"
10
11using namespace amrex;
12
13enum Grid { Cell, Node};
14
15/// \brief Documentation for operator namespace
16namespace Operator
17{
18
19template <Grid G> class Operator;
20
21//
22//
23// NODE-BASED OPERATOR
24//
25//
26
27template <>
28class Operator<Grid::Node> : public amrex::MLNodeLinOp
29{
30 //
31 // Public: Constructor/Destructor/Operators/defines
32 //
33public :
35 Operator (const amrex::Vector<amrex::Geometry>& a_geom,
36 const amrex::Vector<amrex::BoxArray>& a_grids,
37 const Vector<DistributionMapping>& a_dmap,
38 const LPInfo& a_info = LPInfo(),
39 const Vector<FabFactory<FArrayBox> const*>& a_factory = {});
40 virtual ~Operator ();
41 Operator (const Operator&) = delete;
42 Operator (Operator&&) = delete;
43 Operator& operator= (const Operator&) = delete;
44 Operator& operator= (Operator&&) = delete;
45 void define (const Vector<Geometry>& a_geom, const Vector<BoxArray>& a_grids,
46 const Vector<DistributionMapping>& a_dmap,
47 const LPInfo& a_info = LPInfo(),
48 const Vector<FabFactory<FArrayBox> const*>& a_factory = {});
49 const Geometry& Geom (int amr_lev, int mglev=0) const noexcept { return m_geom[amr_lev][mglev]; }
50
51 void Reflux(int crse_amrlev,
52 MultiFab& res, const MultiFab& crse_sol, const MultiFab& crse_rhs,
53 MultiFab& fine_res, MultiFab& fine_sol, const MultiFab& fine_rhs)
54 {reflux(crse_amrlev, res, crse_sol, crse_rhs,fine_res, fine_sol, fine_rhs);}
55 void Apply (int amrlev, int mglev, MultiFab& out, const MultiFab& in) const { Fapply(amrlev,mglev,out,in);}
56
57 void SetOmega(Set::Scalar a_omega) {m_omega = a_omega;}
58 virtual void SetAverageDownCoeffs(bool) {Util::Abort(INFO,"Not implemented!");}
59 void SetNormalizeDDW(bool a_normalize_ddw) {m_normalize_ddw = a_normalize_ddw;}
60 // MLMG prepares an operator only once. Call this after replacing nonlinear
61 // coefficients so coarse MG levels and the smoother diagonal stay current.
62 void SyncCoefficients() { averageDownCoeffs(); Diagonal(true); }
63
64 //
65 // Public Utilty functions
66 //
67public:
68 void RegisterNewFab(amrex::Vector<amrex::MultiFab> &input);
69 void RegisterNewFab(amrex::Vector<std::unique_ptr<amrex::MultiFab> > &input);
70 const amrex::FArrayBox & GetFab(const int num, const int amrlev, const int mglev, const amrex::MFIter &mfi) const;
71 virtual void SetHomogeneous (bool) {};
72 //
73 // Pure Virtual: you MUST override these functions
74 //
75protected:
76 virtual void Fapply (int amrlev, int mglev,MultiFab& out,const MultiFab& in) const override =0;
77 virtual void averageDownCoeffs () = 0;
78 virtual bool useQuadraticAmrInterpolation() const { return false; }
79 virtual bool relaxCoarseFineGhostRows() const { return true; }
80 //
81 // Virtual: you SHOULD override these functions
82 //
83public:
84 virtual void Diagonal (bool recompute=false);
85 virtual void Diagonal (int amrlev, int mglev, amrex::MultiFab& diag);
86 //
87 // Virtual: you CAN override these functions (but probably don't need to)
88 //
89 virtual void Fsmooth (int amrlev, int mglev, MultiFab& x,const MultiFab& b) const override;
90 virtual void normalize (int amrlev, int mglev, MultiFab& mf) const override;
91 virtual void reflux (int crse_amrlev, MultiFab& res, const MultiFab& crse_sol, const MultiFab& crse_rhs,
92 MultiFab& fine_res, MultiFab& fine_sol, const MultiFab& fine_rhs) const override;
93 //
94 // Virtual: you CAN'T override these functions (they take care of AMReX business) and you SHOULDN'T
95 //
96public:
97 virtual void restriction (int amrlev, int cmglev, MultiFab& crse, MultiFab& fine) const final;
98 virtual void interpolation (int amrlev, int fmglev, MultiFab& fine, const MultiFab& crse) const override final;
99 virtual void interpolationAmr (int famrlev, MultiFab& fine,
100 const MultiFab& crse, IntVect const& nghost) const override final;
101 virtual void averageDownSolutionRHS (int camrlev, MultiFab& crse_sol, MultiFab& crse_rhs, const MultiFab& fine_sol, const MultiFab& fine_rhs) final;
102 virtual void prepareForSolve () override;
103 virtual bool isSingular (int amrlev) const final {return (amrlev == 0) ? m_is_bottom_singular : false; }
104 virtual bool isBottomSingular () const final { return m_is_bottom_singular; }
105 virtual void applyBC (int amrlev, int mglev, MultiFab& phi, BCMode bc_mode, amrex::MLLinOp::StateMode /**/, bool skip_fillboundary=false) const final;
106 virtual void fixUpResidualMask (int amrlev, iMultiFab& resmsk) final;
107public:
108 virtual int getNGrow(int /*alev*/=0,int /*mglev*/=0) const override final {return 2;}
109 virtual void solutionResidual (int amrlev, MultiFab& resid, MultiFab& x, const MultiFab& b,
110 const MultiFab* crse_bcdata=nullptr) override final;
111 virtual void correctionResidual (int amrlev, int mglev, MultiFab& resid, MultiFab& x, const MultiFab& b,
112 BCMode bc_mode, const MultiFab* crse_bcdata=nullptr) override final;
113
114
115public:
116 static void realFillBoundary(MultiFab &phi, const Geometry &geom);
117
118private:
119 bool m_is_bottom_singular = false;
120 bool m_masks_built = false;
121 /// \todo we need to get rid of this
122 // static constexpr amrex::IntVect AMREX_D_DECL(dx = {AMREX_D_DECL(1,0,0)},
123 // dy = {AMREX_D_DECL(0,1,0)},
124 // dz = {AMREX_D_DECL(0,0,1)});
125protected:
126 int m_num_a_fabs = 0;
127 bool m_diagonal_computed = false;
128 amrex::Vector<amrex::Vector<amrex::Vector<amrex::MultiFab> > > m_a_coeffs;
129 amrex::Vector<amrex::Vector<std::unique_ptr<amrex::MultiFab> > > m_diag;
130 Set::Scalar m_omega = 2./3.;
131 bool m_normalize_ddw = false;
132};
133
134
135
136//
137//
138// CELL-BASED OPERATOR
139//
140//
141
142
143template<>
144class Operator<Grid::Cell> : public amrex::MLCellLinOp
145{
146public:
147
148 friend class MLMG;
149 friend class MLCGSolver;
150
151 Operator ();
152 virtual ~Operator () {};
153
154 Operator (const Operator&) = delete;
155 Operator (Operator&&) = delete;
156 Operator& operator= (const Operator&) = delete;
157 Operator& operator= (Operator&&) = delete;
158
159 void define (amrex::Vector<amrex::Geometry> a_geom,
160 const amrex::Vector<amrex::BoxArray>& a_grids,
161 const amrex::Vector<amrex::DistributionMapping>& a_dmap,
163 const amrex::LPInfo& a_info = amrex::LPInfo(),
164 const amrex::Vector<amrex::FabFactory<amrex::FArrayBox> const*>& a_factory = {});
165
166 // virtual void setLevelBC (int amrlev, const amrex::MultiFab* levelbcdata) override final;
167
168protected:
169
171
172 amrex::Vector<std::unique_ptr<amrex::MLMGBndry> > m_bndry_sol;
173 amrex::Vector<std::unique_ptr<amrex::BndryRegister> > m_crse_sol_br;
174
175 amrex::Vector<std::unique_ptr<amrex::MLMGBndry> > m_bndry_cor;
176 amrex::Vector<std::unique_ptr<amrex::BndryRegister> > m_crse_cor_br;
177
178 // In case of agglomeration, coarse MG grids on amr level 0 are
179 // not simply coarsened from fine MG grids. So we need to build
180 // bcond and bcloc for each MG level.
181 using RealTuple = std::array<amrex::Real,2*BL_SPACEDIM>;
182 using BCTuple = std::array<amrex::BoundCond,2*BL_SPACEDIM>;
183 class BndryCondLoc
184 {
185 public:
186 BndryCondLoc (const amrex::BoxArray& ba, const amrex::DistributionMapping& dm);
187 void setLOBndryConds (const amrex::Geometry& geom, const amrex::Real* dx,
188 const amrex::Array<BCType,AMREX_SPACEDIM>& lobc,
189 const amrex::Array<BCType,AMREX_SPACEDIM>& hibc,
190 int ratio, const amrex::RealVect& a_loc);
191 const BCTuple& bndryConds (const amrex::MFIter& mfi) const {
192 return bcond[mfi];
193 }
194 const RealTuple& bndryLocs (const amrex::MFIter& mfi) const {
195 return bcloc[mfi];
196 }
197 private:
198 amrex::LayoutData<BCTuple> bcond;
199 amrex::LayoutData<RealTuple> bcloc;
200 };
201 amrex::Vector<amrex::Vector<std::unique_ptr<BndryCondLoc> > > m_bcondloc;
202
203 // used to save interpolation coefficients of the first interior cells
204 mutable amrex::Vector<amrex::Vector<amrex::BndryRegister> > m_undrrelxr;
205
206 // boundary cell flags for covered, not_covered, outside_domain
207 amrex::Vector<amrex::Vector<std::array<amrex::MultiMask,2*AMREX_SPACEDIM> > > m_maskvals;
208
209 //
210 // functions
211 //
212
213 void updateSolBC (int amrlev, const amrex::MultiFab& crse_bcdata) const;
214 void updateCorBC (int amrlev, const amrex::MultiFab& crse_bcdata) const;
215
216 virtual void prepareForSolve () override;
217
218
219 // PURE VIRTUAL METHODS
220
221 virtual void Fapply (int amrlev, int mglev, amrex::MultiFab& out, const amrex::MultiFab& in) const override = 0;
222 virtual void Fsmooth (int amrlev, int mglev, amrex::MultiFab& sol, const amrex::MultiFab& rsh, int redblack) const override = 0;
223 virtual void FFlux (int amrlev, const MFIter& mfi,
224 const Array<FArrayBox*,AMREX_SPACEDIM>& flux,
225 const FArrayBox& sol, Location loc, const int face_only=0) const override = 0;
226
227 void RegisterNewFab(amrex::Vector<amrex::MultiFab> &input);
228 void RegisterNewFab(amrex::Vector<std::unique_ptr<amrex::MultiFab> > &input);
229 const amrex::FArrayBox & GetFab(const int num, const int amrlev, const int mglev, const amrex::MFIter &mfi) ;
230
231 virtual bool isSingular (int /*amrlev*/) const final { return false; }
232 virtual bool isBottomSingular () const final { return false; }
233
234 virtual amrex::Real getAScalar () const final { return 0.0; }
235 virtual amrex::Real getBScalar () const final { return 0.0; }
236
237 virtual amrex::MultiFab const* getACoeffs (int /*amrlev*/, int /*mglev*/) const final { return nullptr;}
238 virtual std::array<amrex::MultiFab const*,AMREX_SPACEDIM> getBCoeffs (int /*amrlev*/, int /*mglev*/) const final {
239 std::array<amrex::MultiFab const*,AMREX_SPACEDIM> ret;
240 AMREX_D_TERM(ret[0] = nullptr;, ret[1] = nullptr;,ret[2] = nullptr;);
241 return ret;}
242
243 virtual std::unique_ptr<amrex::MLLinOp> makeNLinOp (int /*grid_size*/) const final {
244 Util::Abort("MLABecLaplacian::makeNLinOp: Not implmented");
245 return std::unique_ptr<MLLinOp>{};
246 }
247
248 void averageDownCoeffs ();
249 void averageDownCoeffsSameAmrLevel (amrex::Vector<amrex::MultiFab>&);
250 const amrex::FArrayBox & GetFab(const int num, const int amrlev, const int mglev, const amrex::MFIter &mfi) const;
251
252 static constexpr amrex::IntVect AMREX_D_DECL(dx = {AMREX_D_DECL(1,0,0)},
253 dy = {AMREX_D_DECL(0,1,0)},
254 dz = {AMREX_D_DECL(0,0,1)});
255private:
256
257 int m_num_a_fabs = 0;
258 amrex::Vector<amrex::Vector<amrex::Vector<amrex::MultiFab> > > m_a_coeffs;
259
260};
261
262
263
264}
265
266
267#endif
Grid
Definition Operator.H:13
@ Node
Definition Operator.H:13
@ Cell
Definition Operator.H:13
#define INFO
Definition Util.H:24
Definition BC.H:43
const RealTuple & bndryLocs(const amrex::MFIter &mfi) const
Definition Operator.H:194
amrex::LayoutData< RealTuple > bcloc
Definition Operator.H:199
const BCTuple & bndryConds(const amrex::MFIter &mfi) const
Definition Operator.H:191
amrex::LayoutData< BCTuple > bcond
Definition Operator.H:198
amrex::Vector< amrex::Vector< std::unique_ptr< BndryCondLoc > > > m_bcondloc
Definition Operator.H:201
void updateSolBC(int amrlev, const amrex::MultiFab &crse_bcdata) const
std::array< amrex::BoundCond, 2 *BL_SPACEDIM > BCTuple
Definition Operator.H:182
virtual std::unique_ptr< amrex::MLLinOp > makeNLinOp(int) const final
Definition Operator.H:243
amrex::Vector< amrex::Vector< amrex::BndryRegister > > m_undrrelxr
Definition Operator.H:204
virtual bool isBottomSingular() const final
Definition Operator.H:232
amrex::Vector< std::unique_ptr< amrex::MLMGBndry > > m_bndry_cor
Definition Operator.H:175
static constexpr amrex::IntVect AMREX_D_DECL(dx={AMREX_D_DECL(1, 0, 0)}, dy={AMREX_D_DECL(0, 1, 0)}, dz={AMREX_D_DECL(0, 0, 1)})
void updateCorBC(int amrlev, const amrex::MultiFab &crse_bcdata) const
Operator(Operator &&)=delete
amrex::Vector< amrex::Vector< amrex::Vector< amrex::MultiFab > > > m_a_coeffs
Definition Operator.H:258
virtual amrex::Real getAScalar() const final
Definition Operator.H:234
virtual void Fsmooth(int amrlev, int mglev, amrex::MultiFab &sol, const amrex::MultiFab &rsh, int redblack) const override=0
Operator(const Operator &)=delete
amrex::Vector< std::unique_ptr< amrex::BndryRegister > > m_crse_cor_br
Definition Operator.H:176
amrex::Vector< std::unique_ptr< amrex::MLMGBndry > > m_bndry_sol
Definition Operator.H:172
virtual bool isSingular(int) const final
Definition Operator.H:231
amrex::Vector< std::unique_ptr< amrex::BndryRegister > > m_crse_sol_br
Definition Operator.H:173
amrex::Vector< amrex::Vector< std::array< amrex::MultiMask, 2 *AMREX_SPACEDIM > > > m_maskvals
Definition Operator.H:207
virtual void Fapply(int amrlev, int mglev, amrex::MultiFab &out, const amrex::MultiFab &in) const override=0
virtual void FFlux(int amrlev, const MFIter &mfi, const Array< FArrayBox *, AMREX_SPACEDIM > &flux, const FArrayBox &sol, Location loc, const int face_only=0) const override=0
virtual std::array< amrex::MultiFab const *, AMREX_SPACEDIM > getBCoeffs(int, int) const final
Definition Operator.H:238
std::array< amrex::Real, 2 *BL_SPACEDIM > RealTuple
Definition Operator.H:181
virtual amrex::MultiFab const * getACoeffs(int, int) const final
Definition Operator.H:237
BC::BC< Set::Scalar > * m_bc
Definition Operator.H:170
const amrex::FArrayBox & GetFab(const int num, const int amrlev, const int mglev, const amrex::MFIter &mfi)
virtual amrex::Real getBScalar() const final
Definition Operator.H:235
virtual bool isSingular(int amrlev) const final
Definition Operator.H:103
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)
Definition Operator.H:51
const Geometry & Geom(int amr_lev, int mglev=0) const noexcept
Definition Operator.H:49
void SetNormalizeDDW(bool a_normalize_ddw)
Definition Operator.H:59
virtual void SetHomogeneous(bool)
Definition Operator.H:71
void Apply(int amrlev, int mglev, MultiFab &out, const MultiFab &in) const
Definition Operator.H:55
virtual void Fapply(int amrlev, int mglev, MultiFab &out, const MultiFab &in) const override=0
void SetOmega(Set::Scalar a_omega)
Definition Operator.H:57
virtual bool relaxCoarseFineGhostRows() const
Definition Operator.H:79
Operator(Operator &&)=delete
virtual bool isBottomSingular() const final
Definition Operator.H:104
virtual bool useQuadraticAmrInterpolation() const
Definition Operator.H:78
Operator(const amrex::Vector< amrex::Geometry > &a_geom, const amrex::Vector< amrex::BoxArray > &a_grids, const Vector< DistributionMapping > &a_dmap, const LPInfo &a_info=LPInfo(), const Vector< FabFactory< FArrayBox > const * > &a_factory={})
virtual void averageDownCoeffs()=0
virtual void SetAverageDownCoeffs(bool)
Definition Operator.H:58
Operator(const Operator &)=delete
Documentation for operator namespace.
Definition Diagonal.cpp:14
constexpr amrex::IntVect AMREX_D_DECL(Operator< Grid::Cell >::dx, Operator< Grid::Cell >::dy, Operator< Grid::Cell >::dz)
A collection of data types and symmetry-reduced data structures.
Definition Base.H:18
amrex::Real Scalar
Definition Base.H:19
AMREX_GPU_HOST_DEVICE void Abort(const char *msg)
Definition Util.cpp:406