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
15// Although the class has EB in the name, it works for non-EB build too.
16//
17// del dot (sigma grad phi) = rhs, for non-RZ
18// where phi and rhs are nodal multifab, and sigma is a tensor constant
19// with only diagonal components. The EB is assumed to be Dirichlet.
20//
21// del dot (sigma grad phi) - alpha/r^2 phi = rhs, for RZ where alpha is a
22// scalar constant that is zero by default.
23//
24// New feature: for non-RZ, sigma can also be a single-component
25// cell-centered multifab.
26
28 : public MLNodeLinOp
29{
30public:
31
32 MLEBNodeFDLaplacian () = default;
33
34#ifdef AMREX_USE_EB
36 const Vector<BoxArray>& a_grids,
37 const Vector<DistributionMapping>& a_dmap,
38 const LPInfo& a_info,
39 const Vector<EBFArrayBoxFactory const*>& a_factory);
40#endif
41
43 const Vector<BoxArray>& a_grids,
44 const Vector<DistributionMapping>& a_dmap,
45 const LPInfo& a_info);
46
47 ~MLEBNodeFDLaplacian () override = default;
48
53
54 void setSigma (Array<Real,AMREX_SPACEDIM> const& a_sigma) noexcept;
55
56 void setSigma (int amrlev, MultiFab const& a_sigma);
57
58 void setRZ (bool flag);
59
60 void setAlpha (Real a_alpha);
61
62#ifdef AMREX_USE_EB
63
64 // Phi on EB
65 void setEBDirichlet (Real a_phi_eb);
66 //
67 template <typename F>
68 std::enable_if_t<IsCallableR<Real,F,AMREX_D_DECL(Real,Real,Real)>::value>
69 setEBDirichlet (F const& f);
70
71 void define (const Vector<Geometry>& a_geom,
72 const Vector<BoxArray>& a_grids,
73 const Vector<DistributionMapping>& a_dmap,
74 const LPInfo& a_info,
75 const Vector<EBFArrayBoxFactory const*>& a_factory);
76
77 [[nodiscard]] std::unique_ptr<FabFactory<FArrayBox> > makeFactory (int amrlev, int mglev) const final;
78
79 [[nodiscard]] bool scaleRHS (int amrlev, MultiFab* rhs) const final;
80
81#endif
82
83 void define (const Vector<Geometry>& a_geom,
84 const Vector<BoxArray>& a_grids,
85 const Vector<DistributionMapping>& a_dmap,
86 const LPInfo& a_info);
87
88 [[nodiscard]] std::string name () const override { return std::string("MLEBNodeFDLaplacian"); }
89
90 void restriction (int amrlev, int cmglev, MultiFab& crse, MultiFab& fine) const final;
91 void interpolation (int amrlev, int fmglev, MultiFab& fine, const MultiFab& crse) const final;
92
93 [[nodiscard]] bool needsUpdate () const override {
95 }
96 void update () override;
97
98 void prepareForSolve () final;
99 void Fapply (int amrlev, int mglev, MultiFab& out, const MultiFab& in) const final;
100 void Fsmooth (int amrlev, int mglev, MultiFab& sol, const MultiFab& rhs) const final;
101 void normalize (int amrlev, int mglev, MultiFab& mf) const final;
102
103 void fixUpResidualMask (int amrlev, iMultiFab& resmsk) final;
104
105 [[nodiscard]] bool isSingular (int) const final { return false; }
106 [[nodiscard]] bool isBottomSingular () const final { return false; }
107
108 void compGrad (int amrlev, const Array<MultiFab*,AMREX_SPACEDIM>& grad,
109 MultiFab& sol, Location /*loc*/) const override;
110
111#if defined(AMREX_USE_HYPRE) && (AMREX_SPACEDIM > 1)
112 void fillIJMatrix (MFIter const& mfi,
114 Array4<int const> const& lid,
115 HypreNodeLap::Int* ncols,
116 HypreNodeLap::Int* cols,
117 Real* mat) const override;
118
119 void fillRHS (MFIter const& mfi,
120 Array4<int const> const& lid,
121 Real* rhs,
122 Array4<Real const> const& bfab) const override;
123#endif
124
125 void postSolve (Vector<MultiFab*> const& sol) const override;
126
127private:
130 bool m_has_sigma_mf = false;
131 bool m_needs_update = true;
132 Real m_s_phi_eb = std::numeric_limits<Real>::lowest();
134 int m_rz = false;
135 Real m_rz_alpha = 0._rt;
136
137 void update_sigma ();
138};
139
140#ifdef AMREX_USE_EB
141
142template <typename F>
143std::enable_if_t<IsCallableR<Real,F,AMREX_D_DECL(Real,Real,Real)>::value>
145{
147 for (int amrlev = 0; amrlev < m_num_amr_levels; ++amrlev) {
148 auto const* factory = dynamic_cast<EBFArrayBoxFactory const*>(m_factory[amrlev][0].get());
149 if (factory) {
150 Geometry const& geom = m_geom[amrlev][0];
151 auto const problo = geom.ProbLoArray();
152 auto const cellsize = geom.CellSizeArray();
153 if (m_phi_eb[amrlev].empty()) {
154 m_phi_eb[amrlev].define(amrex::convert(m_grids[amrlev][0],IntVect(1)),
155 m_dmap[amrlev][0], 1, 1);
156 m_phi_eb[amrlev].setVal(0.0);
157 }
158 auto const& flags = factory->getMultiEBCellFlagFab();
159 auto const& levset = factory->getLevelSet();
160#ifdef AMREX_USE_OMP
161#pragma omp parallel if (Gpu::notInLaunchRegion())
162#endif
163 for (MFIter mfi(m_phi_eb[amrlev],TilingIfNotGPU()); mfi.isValid(); ++mfi)
164 {
165 const Box& ndbx = mfi.growntilebox();
166 const auto& flag = flags[mfi];
167 if (flag.getType() != FabType::regular) {
168 Array4<Real const> const lstarr = levset.const_array(mfi);
169 Array4<Real> const& phi = m_phi_eb[amrlev].array(mfi);
170 AMREX_HOST_DEVICE_FOR_3D(ndbx, i, j, k,
171 {
172 if (lstarr(i,j,k) >= Real(0.0)) {
173 phi(i,j,k) = f(AMREX_D_DECL(problo[0]+i*cellsize[0],
174 problo[1]+j*cellsize[1],
175 problo[2]+k*cellsize[2]));
176 }
177 });
178 }
179 }
180 }
181 }
182}
183
184#endif
185
186}
187
188#endif
#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
#define AMREX_D_DECL(a, b, c)
Definition AMReX_SPACE.H:171
GpuArray< Real, 3 > CellSizeArray() const noexcept
Definition AMReX_CoordSys.H:76
Definition AMReX_EBFabFactory.H:24
Rectangular problem domain geometry.
Definition AMReX_Geometry.H:73
GpuArray< Real, 3 > ProbLoArray() const noexcept
Definition AMReX_Geometry.H:186
HYPRE_Int Int
Definition AMReX_HypreNodeLap.H:36
Definition AMReX_MFIter.H:57
bool isValid() const noexcept
Is the iterator valid i.e. is it associated with a FAB?
Definition AMReX_MFIter.H:141
Definition AMReX_MLEBNodeFDLaplacian.H:29
GpuArray< Real, 3 > m_sigma
Definition AMReX_MLEBNodeFDLaplacian.H:128
void restriction(int amrlev, int cmglev, MultiFab &crse, MultiFab &fine) const final
Definition AMReX_MLEBNodeFDLaplacian.cpp:168
std::string name() const override
Definition AMReX_MLEBNodeFDLaplacian.H:88
bool isBottomSingular() const final
Is the bottom of MG singular?
Definition AMReX_MLEBNodeFDLaplacian.H:106
MLEBNodeFDLaplacian & operator=(const MLEBNodeFDLaplacian &)=delete
bool needsUpdate() const override
Does it need update if it's reused?
Definition AMReX_MLEBNodeFDLaplacian.H:93
void compGrad(int amrlev, const Array< MultiFab *, 3 > &grad, MultiFab &sol, Location) const override
Definition AMReX_MLEBNodeFDLaplacian.cpp:604
int m_rz
Definition AMReX_MLEBNodeFDLaplacian.H:134
void Fsmooth(int amrlev, int mglev, MultiFab &sol, const MultiFab &rhs) const final
Definition AMReX_MLEBNodeFDLaplacian.cpp:487
void interpolation(int amrlev, int fmglev, MultiFab &fine, const MultiFab &crse) const final
Definition AMReX_MLEBNodeFDLaplacian.cpp:215
void setAlpha(Real a_alpha)
Definition AMReX_MLEBNodeFDLaplacian.cpp:68
void setEBDirichlet(Real a_phi_eb)
Definition AMReX_MLEBNodeFDLaplacian.cpp:80
MLEBNodeFDLaplacian(const MLEBNodeFDLaplacian &)=delete
bool scaleRHS(int amrlev, MultiFab *rhs) const final
Definition AMReX_MLEBNodeFDLaplacian.cpp:328
Real m_rz_alpha
Definition AMReX_MLEBNodeFDLaplacian.H:135
void setRZ(bool flag)
Definition AMReX_MLEBNodeFDLaplacian.cpp:58
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)
Definition AMReX_MLEBNodeFDLaplacian.cpp:86
bool m_needs_update
Definition AMReX_MLEBNodeFDLaplacian.H:131
void Fapply(int amrlev, int mglev, MultiFab &out, const MultiFab &in) const final
Definition AMReX_MLEBNodeFDLaplacian.cpp:364
void update_sigma()
Definition AMReX_MLEBNodeFDLaplacian.cpp:770
Vector< MultiFab > m_phi_eb
Definition AMReX_MLEBNodeFDLaplacian.H:133
void normalize(int amrlev, int mglev, MultiFab &mf) const final
Definition AMReX_MLEBNodeFDLaplacian.cpp:592
void setSigma(Array< Real, 3 > const &a_sigma) noexcept
Definition AMReX_MLEBNodeFDLaplacian.cpp:36
void update() override
Update for reuse.
Definition AMReX_MLEBNodeFDLaplacian.cpp:757
MLEBNodeFDLaplacian(MLEBNodeFDLaplacian &&)=delete
Real m_s_phi_eb
Definition AMReX_MLEBNodeFDLaplacian.H:132
void prepareForSolve() final
Definition AMReX_MLEBNodeFDLaplacian.cpp:259
std::unique_ptr< FabFactory< FArrayBox > > makeFactory(int amrlev, int mglev) const final
Definition AMReX_MLEBNodeFDLaplacian.cpp:154
~MLEBNodeFDLaplacian() override=default
bool m_has_sigma_mf
Definition AMReX_MLEBNodeFDLaplacian.H:130
Vector< Vector< std::unique_ptr< MultiFab > > > m_sigma_mf
Definition AMReX_MLEBNodeFDLaplacian.H:129
void fixUpResidualMask(int amrlev, iMultiFab &resmsk) final
Definition AMReX_MLEBNodeFDLaplacian.cpp:598
void postSolve(Vector< MultiFab * > const &sol) const override
Definition AMReX_MLEBNodeFDLaplacian.cpp:720
bool isSingular(int) const final
Is it singular on given AMR level?
Definition AMReX_MLEBNodeFDLaplacian.H:105
Vector< Vector< std::unique_ptr< FabFactory< FAB > > > > m_factory
Definition AMReX_MLLinOp.H:613
virtual bool needsUpdate() const
Does it need update if it's reused?
Definition AMReX_MLLinOp.H:266
Vector< Vector< BoxArray > > m_grids
Definition AMReX_MLLinOp.H:611
Vector< Vector< DistributionMapping > > m_dmap
Definition AMReX_MLLinOp.H:612
Vector< Vector< Geometry > > m_geom
first Vector is for amr level and second is mg level
Definition AMReX_MLLinOp.H:610
LinOpEnumType::Location Location
Definition AMReX_MLLinOp.H:114
int m_num_amr_levels
Definition AMReX_MLLinOp.H:595
Definition AMReX_MLNodeLinOp.H:16
A collection (stored as an array) of FArrayBox objects.
Definition AMReX_MultiFab.H:38
This class is a thin wrapper around std::vector. Unlike vector, Vector::operator[] provides bound che...
Definition AMReX_Vector.H:28
Definition AMReX_iMultiFab.H:32
Definition AMReX_Amr.cpp:49
__host__ __device__ BoxND< dim > convert(const BoxND< dim > &b, const IntVectND< dim > &typ) noexcept
Returns a BoxND with different type.
Definition AMReX_Box.H:1453
IntVectND< 3 > IntVect
Definition AMReX_BaseFwd.H:30
bool TilingIfNotGPU() noexcept
Definition AMReX_MFIter.H:12
std::array< T, N > Array
Definition AMReX_Array.H:24
Definition AMReX_Array4.H:61
Definition AMReX_Array.H:34
Test if a given type T is callable with arguments of type Args...
Definition AMReX_TypeTraits.H:215
Definition AMReX_MLLinOp.H:35