ERF
Energy Research and Forecasting: An Atmospheric Modeling Code
ERF_TerrainPoisson.H
Go to the documentation of this file.
1 /**
2  * \file ERF_TerrainPoisson.H
3  */
4 #ifndef ERF_TERRAIN_POISSON_H_
5 #define ERF_TERRAIN_POISSON_H_
6 
7 #include <AMReX_Geometry.H>
8 #include <AMReX_MultiFab.H>
9 #include <AMReX_BCRec.H>
10 
11 #ifdef ERF_USE_FFT
12 
14 #include <AMReX_FFT_Poisson.H>
15 
16 /**
17  * Matrix-vector interface for the terrain Poisson operator used by GMRES.
18  */
19 class TerrainPoisson
20 {
21 public:
22 
23  using RT = amrex::Real;
24 
25  /**
26  * Construct a terrain Poisson operator and its FFT preconditioner metadata.
27  *
28  * @param geom Geometry for the subdomain being solved
29  * @param ba BoxArray for operator and vector allocation
30  * @param dm DistributionMapping for operator and vector allocation
31  * @param domain_bcs_type Domain boundary-condition names
32  * @param stretched_dz_lev_d Device stretched-dz spacing for the level
33  * @param ax Terrain metric coefficient on x-faces
34  * @param ay Terrain metric coefficient on y-faces
35  * @param az Terrain metric coefficient on z-faces
36  * @param dJ Cell-centered Jacobian determinant
37  * @param z_phys_nd Node-centered physical height field
38  * @param use_real_bcs Whether real lateral boundary conditions are active
39  */
40  TerrainPoisson (amrex::Geometry const& geom, amrex::Geometry const& lev_geom,
41  amrex::BoxArray const& ba,
42  amrex::DistributionMapping const& dm,
43  amrex::Array<std::string,2*AMREX_SPACEDIM>& domain_bcs_type,
44  amrex::Gpu::DeviceVector<amrex::Real>& stretched_dz_lev_d,
45  const amrex::MultiFab& ax, const amrex::MultiFab& ay,
46  const amrex::MultiFab& az, const amrex::MultiFab& dJ,
47  amrex::MultiFab const* z_phys_nd,
48  bool use_real_bcs);
49 
50  /**
51  * Apply the terrain Poisson operator.
52  *
53  * @param lhs Destination for the operator result
54  * @param rhs Input vector with ghost cells available for boundary fills
55  */
56  void apply (amrex::MultiFab& lhs, amrex::MultiFab const& rhs);
57 
58  /**
59  * Fill ghost cells according to the configured Poisson boundary conditions.
60  *
61  * @param phi Field whose ghost cells are updated
62  */
63  void apply_bcs (amrex::MultiFab& phi);
64 
65  /**
66  * Enable or disable the FFT preconditioner.
67  *
68  * @param precond_flag True to use the FFT preconditioner
69  */
70  void usePrecond (bool precond_flag);
71 
72  /**
73  * Faces of the solve region whose flux is zero (its Neumann faces), as a sum of
74  * TerrainPoissonFaceBit values.
75  *
76  * @return The face mask
77  */
78  [[nodiscard]] int zeroFluxFaces () const { return m_zero_flux_faces; }
79 
80  /**
81  * Compute face-centered terrain Poisson fluxes from a solution field.
82  *
83  * @param phi Solution field used to compute gradients
84  * @param fluxes Face-centered fluxes to fill
85  */
86  void getFluxes (amrex::MultiFab& phi, amrex::Array<amrex::MultiFab,AMREX_SPACEDIM>& fluxes);
87 
88  /**
89  * Copy one vector into another.
90  *
91  * @param lhs Destination vector
92  * @param rhs Source vector
93  */
94  void assign (amrex::MultiFab& lhs, amrex::MultiFab const& rhs);
95 
96  /**
97  * Scale a vector in place.
98  *
99  * @param lhs Vector to scale
100  * @param fac Multiplicative scale factor
101  */
102  void scale (amrex::MultiFab& lhs, amrex::Real fac);
103 
104  /**
105  * Compute the vector dot product.
106  *
107  * @param v1 First input vector
108  * @param v2 Second input vector
109  * @return Dot product of v1 and v2
110  */
111  amrex::Real dotProduct (amrex::MultiFab const& v1, amrex::MultiFab const& v2);
112 
113  /**
114  * Add a scaled vector into another vector.
115  *
116  * @param lhs Destination vector to increment
117  * @param rhs Source vector
118  * @param a Scale factor applied to rhs
119  */
120  void increment (amrex::MultiFab& lhs, amrex::MultiFab const& rhs, amrex::Real a);
121 
122  /**
123  * Compute a linear combination of two source vectors.
124  *
125  * @param lhs Destination vector
126  * @param a Scale factor applied to rhs_a
127  * @param rhs_a First source vector
128  * @param b Scale factor applied to rhs_b
129  * @param rhs_b Second source vector
130  */
131  void linComb (amrex::MultiFab& lhs, amrex::Real a, amrex::MultiFab const& rhs_a,
132  amrex::Real b, amrex::MultiFab const& rhs_b);
133 
134  /**
135  * Allocate a vector with the right-hand-side ghost-cell layout.
136  *
137  * @return Newly allocated right-hand-side vector
138  */
139  amrex::MultiFab makeVecRHS ();
140 
141  /**
142  * Allocate a vector with the solution ghost-cell layout.
143  *
144  * @return Newly allocated solution vector
145  */
146  amrex::MultiFab makeVecLHS ();
147 
148  /**
149  * Compute the L2 norm of a vector.
150  *
151  * @param v Input vector
152  * @return L2 norm of v
153  */
154  amrex::Real norm2 (amrex::MultiFab const& v);
155 
156  /**
157  * Apply the configured preconditioner.
158  *
159  * @param lhs Destination for the preconditioned result
160  * @param rhs Input vector to precondition
161  */
162  void precond (amrex::MultiFab& lhs, amrex::MultiFab const& rhs);
163 
164  /**
165  * Set a vector to zero.
166  *
167  * @param v Vector to zero
168  */
169  void setToZero (amrex::MultiFab& v);
170 
171 private:
172  bool m_use_precond = false;
173  amrex::Geometry m_geom;
174  amrex::BoxArray m_grids;
175  amrex::DistributionMapping m_dmap;
176  amrex::Array<std::string,2*AMREX_SPACEDIM> m_domain_bcs_type;
177  amrex::Gpu::DeviceVector<amrex::Real> m_stretched_dz_d;
178  const amrex::MultiFab& m_ax;
179  const amrex::MultiFab& m_ay;
180  const amrex::MultiFab& m_az;
181  const amrex::MultiFab& m_dJ;
182  const amrex::MultiFab* m_zphys;
183 
184  std::unique_ptr<amrex::FFT::PoissonHybrid<amrex::MultiFab>> m_2D_fft_precond;
185  amrex::Array<std::pair<amrex::FFT::Boundary,amrex::FFT::Boundary>,AMREX_SPACEDIM> bc_fft;
186 
187  //! Faces of the solve region with zero flux (TerrainPoissonFaceBit values)
188  int m_zero_flux_faces = 0;
189 };
190 
191 #endif
192 #endif
amrex::Real Real
Definition: ERF_ShocInterface.H:19
auto apply_bcs
Definition: ERF_TI_utils.H:34
void apply(const amrex::Box &bx, const amrex::Box &domain, const int quantity, const int flux_comp, const amrex::Array4< const amrex::Real > &state, const amrex::Array4< const amrex::Real > &prim, const amrex::Array4< const amrex::Real > &base_state, const amrex::Array4< const amrex::Real > &u, const amrex::Array4< const amrex::Real > &v, const amrex::Array4< const amrex::Real > &w, const amrex::Array4< amrex::Real > &rhs, const amrex::Array4< amrex::Real > &xflux, const amrex::Array4< amrex::Real > &yflux, const amrex::Array4< amrex::Real > &zflux, const amrex::GpuArray< amrex::Real, AMREX_SPACEDIM > &dx_inv, const erf_wall_thermodynamics::Boundary &walls, const amrex::Real alpha_T, const amrex::Real alpha_C, const amrex::Real rdOcp, const bool cloudy=false)
Definition: ERF_CloudChamberWallFlux.H:1037