ERF
Energy Research and Forecasting: An Atmospheric Modeling Code
ERF_FillPatcher.H
Go to the documentation of this file.
1 #ifndef ERF_FILLPATCHER_H_
2 #define ERF_FILLPATCHER_H_
3 
4 #include <AMReX_FillPatchUtil.H>
5 #include <AMReX_Interp_C.H>
6 #include <AMReX_MFInterp_C.H>
7 
9 {
10 public:
11 
12  /**
13  * Construct a coarse-fine fill patcher.
14  *
15  * @param[in] fba fine-level BoxArray
16  * @param[in] fdm fine-level DistributionMapping
17  * @param[in] fgeom fine-level Geometry
18  * @param[in] cba coarse-level BoxArray
19  * @param[in] cdm coarse-level DistributionMapping
20  * @param[in] cgeom coarse-level Geometry
21  * @param[in] nghost number of ghost cells in the fill region
22  * @param[in] nghost_set number of ghost cells in the set region
23  * @param[in] ncomp number of components
24  * @param[in] interp interpolation operator
25  */
26  ERFFillPatcher (amrex::BoxArray const& fba, amrex::DistributionMapping const& fdm,
27  amrex::Geometry const& fgeom,
28  amrex::BoxArray const& cba, amrex::DistributionMapping const& cdm,
29  amrex::Geometry const& cgeom,
30  int nghost, int nghost_set, int ncomp, amrex::InterpBase* interp);
31 
32  /**
33  * Define the coarse-fine fill patcher.
34  *
35  * @param[in] fba fine-level BoxArray
36  * @param[in] fdm fine-level DistributionMapping
37  * @param[in] fgeom fine-level Geometry
38  * @param[in] cba coarse-level BoxArray
39  * @param[in] cdm coarse-level DistributionMapping
40  * @param[in] cgeom coarse-level Geometry
41  * @param[in] nghost number of ghost cells in the fill region
42  * @param[in] nghost_set number of ghost cells in the set region
43  * @param[in] ncomp number of components
44  * @param[in] interp interpolation operator
45  */
46  void Define (amrex::BoxArray const& fba, amrex::DistributionMapping const& fdm,
47  amrex::Geometry const& fgeom,
48  amrex::BoxArray const& cba, amrex::DistributionMapping const& cdm,
49  amrex::Geometry const& cgeom,
50  int nghost, int nghost_set, int ncomp,
51  amrex::InterpBase* interp);
52 
53  /**
54  * Build the coarse-fine mask.
55  *
56  * @param[in] fba fine-level BoxArray
57  * @param[in] nghost number of ghost cells in the fill region
58  * @param[in] nghost_set number of ghost cells in the set region
59  */
60  void BuildMask (amrex::BoxArray const& fba, int nghost, int nghost_set);
61 
62  /**
63  * Register coarse data bracketing the fill time.
64  *
65  * @param[in] crse_data coarse MultiFabs
66  * @param[in] crse_time times associated with crse_data
67  */
68  void RegisterCoarseData (amrex::Vector<amrex::MultiFab const*> const& crse_data,
69  amrex::Vector<double> const& crse_time);
70 
71  /**
72  * Interpolate coarse data to fine face data.
73  *
74  * @param[in,out] fine fine-level data to fill
75  * @param[in] crse coarse-level source data
76  * @param[in] mask_val mask value selecting cells to fill
77  */
78  void InterpFace (amrex::MultiFab& fine,
79  amrex::MultiFab const& crse,
80  int mask_val);
81 
82  /**
83  * Interpolate coarse data to fine cell-centered data.
84  *
85  * @param[in,out] fine fine-level data to fill
86  * @param[in] crse coarse-level source data
87  * @param[in] bcr boundary-condition records
88  * @param[in] mask_val mask value selecting cells to fill
89  */
90  void InterpCell (amrex::MultiFab& fine,
91  amrex::MultiFab const& crse,
92  amrex::Vector<amrex::BCRec> const& bcr,
93  int mask_val);
94 
95  /**
96  * Return the mask value for the set region.
97  */
98  int GetSetMaskVal () { return m_set_mask; }
99 
100  /**
101  * Log-law fill of the lateral coarse/fine faces next to a wall (erf.cf_loglaw_fill): the flux
102  * of the first coarse face above the wall is shared among its fine sub-faces in proportion to
103  * the integral of ln(1 + z/z0) over the fluid part of each, so the flux of every coarse face
104  * is kept. Acts on the set fills of fine boxes that reach the bottom of the domain.
105  *
106  * @param[in] on enable the log-law fill (constant dz only)
107  * @param[in] z0 roughness length [m]
108  * @param[in] wall_tblank fine solid fraction giving the wall height (immersed forcing), or
109  * nullptr for a wall at the bottom of the domain
110  */
111  void SetLogLawFill (bool on, amrex::Real z0, amrex::MultiFab const* wall_tblank)
112  {
113  m_loglaw = on; m_loglaw_z0 = z0; m_loglaw_tblank = wall_tblank;
114  }
115 
116  /**
117  * Return the mask value for the relax region.
118  */
119  int GetRelaxMaskVal () { return m_relax_mask; }
120 
121  /**
122  * Return the coarse-fine mask.
123  */
124  amrex::iMultiFab* GetMask () { return m_cf_mask.get(); }
125 
126  /**
127  * Fill fine data in the set region.
128  *
129  * @param[in,out] mf MultiFab to be filled
130  * @param[in] time time at which to fill data
131  * @param[in] cbc coarse boundary condition
132  * @param[in] bcs vector of boundary conditions
133  */
134  template <typename BC>
135  void FillSet (amrex::MultiFab& mf, double time,
136  BC& cbc, amrex::Vector<amrex::BCRec> const& bcs);
137 
138  /**
139  * Fill fine data in the relax region.
140  *
141  * Not currently used: nothing calls it, and two-way coupling requires cf_width = 0, which
142  * leaves the relax region empty. Kept so that relaxation can be re-enabled.
143  *
144  * @param[in,out] mf MultiFab to be filled
145  * @param[in] time time at which to fill data
146  * @param[in] cbc coarse boundary condition
147  * @param[in] bcs vector of boundary conditions
148  */
149  template <typename BC>
150  void FillRelax (amrex::MultiFab& mf, double time,
151  BC& cbc, amrex::Vector<amrex::BCRec> const& bcs);
152 
153  /**
154  * Fill fine data in the selected mask region.
155  *
156  * @param[in,out] mf MultiFab to be filled
157  * @param[in] time time at which to fill data
158  * @param[in] cbc coarse boundary condition
159  * @param[in] bcs vector of boundary conditions
160  * @param[in] mask_val mask value selecting cells to fill
161  */
162  template <typename BC>
163  void Fill (amrex::MultiFab& mf, double time,
164  BC& cbc, amrex::Vector<amrex::BCRec> const& bcs, int mask_val);
165 
166  //! The times of the coarse data last registered (RegisterCoarseData)
167  [[nodiscard]] amrex::Vector<double> const& crse_times () const { return m_crse_times; }
168 
169 private:
170 
171  amrex::BoxArray m_fba;
172  amrex::BoxArray m_cba;
173  amrex::DistributionMapping m_fdm;
174  amrex::DistributionMapping m_cdm;
175  amrex::Geometry m_fgeom;
176  amrex::Geometry m_cgeom;
177  int m_nghost;
179  int m_ncomp;
180  amrex::InterpBase* m_interp;
181  amrex::IntVect m_ratio;
182  std::unique_ptr<amrex::MultiFab> m_cf_crse_data_old;
183  std::unique_ptr<amrex::MultiFab> m_cf_crse_data_new;
184  std::unique_ptr<amrex::iMultiFab> m_cf_mask;
185  bool m_loglaw = false; // log-law c/f fill (SetLogLawFill)
187  amrex::MultiFab const* m_loglaw_tblank = nullptr;
188  amrex::Vector<double> m_crse_times;
189  double m_dt_crse;
190  int m_set_mask{2};
191  int m_relax_mask{1};
192 };
193 
194 /**
195  * Fill fine data in the set region
196  *
197  * @param[in,out] mf MultiFab to be filled
198  * @param[in] time Time at which to fill data
199  * @param[in] cbc Coarse boundary condition
200  * @param[in] bcs Vector of boundary conditions
201  */
202 template <typename BC>
203 void
204 ERFFillPatcher::FillSet (amrex::MultiFab& mf, double time,
205  BC& cbc, amrex::Vector<amrex::BCRec> const& bcs)
206 {
207  Fill(mf,time,cbc,bcs,m_set_mask);
208 }
209 
210 /**
211  * Fill fine data in the relax region
212  *
213  * @param[in,out] mf MultiFab to be filled
214  * @param[in] time Time at which to fill data
215  * @param[in] cbc Coarse boundary condition
216  * @param[in] bcs Vector of boundary conditions
217  */
218 template <typename BC>
219 void
220 ERFFillPatcher::FillRelax (amrex::MultiFab& mf, double time,
221  BC& cbc, amrex::Vector<amrex::BCRec> const& bcs)
222 {
223  Fill(mf,time,cbc,bcs,m_relax_mask);
224 }
225 
226 /**
227  * Fill fine data in the relax region
228  *
229  * @param[in,out] mf MultiFab to be filled
230  * @param[in] time_d Time at which to fill data
231  * @param[in] cbc Coarse boundary condition
232  * @param[in] bcs Vector of boundary conditions
233  * @param[in] mask_val Mask value selecting cells to fill
234  */
235 template <typename BC>
236 void
237 ERFFillPatcher::Fill (amrex::MultiFab& mf, double time_d,
238  BC& cbc, amrex::Vector<amrex::BCRec> const& bcs, int mask_val)
239 {
240  constexpr double eps = std::numeric_limits<float>::epsilon();
241 
242  AMREX_ALWAYS_ASSERT((time_d >= m_crse_times[0]-eps) && (time_d <= m_crse_times[1]+eps));
243 
244  amrex::Real time = static_cast<amrex::Real>(time_d);
245 
246  // Time interpolation factors
247  amrex::Real fac_new = amrex::Real(0);
248  amrex::Real fac_old = amrex::Real(1);
249  if (amrex::Math::abs(m_dt_crse) > eps) {
250  fac_new = static_cast<amrex::Real>((time_d - m_crse_times[0]) / m_dt_crse);
251  fac_old = amrex::Real(1) - fac_new;
252  }
253 
254  // Coarse MF to hold time interpolated data
255  amrex::MultiFab crse_data_time_interp(m_cf_crse_data_old->boxArray(),
256  m_cf_crse_data_old->DistributionMap(),
257  m_ncomp, amrex::IntVect{0});
258 
259  // Time interpolate the coarse data
260  amrex::MultiFab::LinComb(crse_data_time_interp,
261  fac_old, *(m_cf_crse_data_old), 0,
262  fac_new, *(m_cf_crse_data_new), 0,
263  0, m_ncomp, amrex::IntVect{0});
264 
265  // Boundary condition operator, at the time it is asked for, on the data at that time.
266  // Applied to the old coarse data before the interpolation it would be weighted by
267  // fac_old -- and vanish at the new coarse time -- and would overwrite the registered
268  // old data the next fill interpolates from.
269  cbc(crse_data_time_interp, 0, m_ncomp, amrex::IntVect(0), time, 0);
270 
271  // Call correct spatial interpolation type
272  amrex::IndexType m_ixt = mf.boxArray().ixType();
273  int ixt_sum = m_ixt[0]+m_ixt[1]+m_ixt[2];
274  if (ixt_sum == 0) {
275  InterpCell(mf,crse_data_time_interp,bcs,mask_val);
276  } else if (ixt_sum == 1) {
277  InterpFace(mf,crse_data_time_interp,mask_val);
278  } else {
279  amrex::Abort("ERF_FillPatcher only supports face linear and cell cons linear interp!");
280  }
281 }
282 #endif
Real z0
Definition: ERF_InitCustomPertVels_ScalarAdvDiff.H:12
AMREX_ALWAYS_ASSERT(bx.length()[2]==khi+1)
amrex::Real Real
Definition: ERF_ShocInterface.H:19
Definition: ERF_FillPatcher.H:9
amrex::Geometry m_fgeom
Definition: ERF_FillPatcher.H:175
void Fill(amrex::MultiFab &mf, double time, BC &cbc, amrex::Vector< amrex::BCRec > const &bcs, int mask_val)
Definition: ERF_FillPatcher.H:237
void RegisterCoarseData(amrex::Vector< amrex::MultiFab const * > const &crse_data, amrex::Vector< double > const &crse_time)
Definition: ERF_FillPatcher.cpp:316
amrex::BoxArray m_fba
Definition: ERF_FillPatcher.H:171
amrex::iMultiFab * GetMask()
Definition: ERF_FillPatcher.H:124
amrex::InterpBase * m_interp
Definition: ERF_FillPatcher.H:180
amrex::BoxArray m_cba
Definition: ERF_FillPatcher.H:172
bool m_loglaw
Definition: ERF_FillPatcher.H:185
void Define(amrex::BoxArray const &fba, amrex::DistributionMapping const &fdm, amrex::Geometry const &fgeom, amrex::BoxArray const &cba, amrex::DistributionMapping const &cdm, amrex::Geometry const &cgeom, int nghost, int nghost_set, int ncomp, amrex::InterpBase *interp)
Definition: ERF_FillPatcher.cpp:108
ERFFillPatcher(amrex::BoxArray const &fba, amrex::DistributionMapping const &fdm, amrex::Geometry const &fgeom, amrex::BoxArray const &cba, amrex::DistributionMapping const &cdm, amrex::Geometry const &cgeom, int nghost, int nghost_set, int ncomp, amrex::InterpBase *interp)
Definition: ERF_FillPatcher.cpp:71
amrex::MultiFab const * m_loglaw_tblank
Definition: ERF_FillPatcher.H:187
amrex::DistributionMapping m_cdm
Definition: ERF_FillPatcher.H:174
amrex::Vector< double > const & crse_times() const
The times of the coarse data last registered (RegisterCoarseData)
Definition: ERF_FillPatcher.H:167
amrex::Geometry m_cgeom
Definition: ERF_FillPatcher.H:176
int m_ncomp
Definition: ERF_FillPatcher.H:179
void InterpFace(amrex::MultiFab &fine, amrex::MultiFab const &crse, int mask_val)
Definition: ERF_FillPatcher.cpp:348
int m_nghost_subset
Definition: ERF_FillPatcher.H:178
void FillRelax(amrex::MultiFab &mf, double time, BC &cbc, amrex::Vector< amrex::BCRec > const &bcs)
Definition: ERF_FillPatcher.H:220
std::unique_ptr< amrex::iMultiFab > m_cf_mask
Definition: ERF_FillPatcher.H:184
std::unique_ptr< amrex::MultiFab > m_cf_crse_data_new
Definition: ERF_FillPatcher.H:183
void SetLogLawFill(bool on, amrex::Real z0, amrex::MultiFab const *wall_tblank)
Definition: ERF_FillPatcher.H:111
int m_set_mask
Definition: ERF_FillPatcher.H:190
amrex::Vector< double > m_crse_times
Definition: ERF_FillPatcher.H:188
int GetSetMaskVal()
Definition: ERF_FillPatcher.H:98
void InterpCell(amrex::MultiFab &fine, amrex::MultiFab const &crse, amrex::Vector< amrex::BCRec > const &bcr, int mask_val)
Definition: ERF_FillPatcher.cpp:544
amrex::Real m_loglaw_z0
Definition: ERF_FillPatcher.H:186
amrex::IntVect m_ratio
Definition: ERF_FillPatcher.H:181
int m_relax_mask
Definition: ERF_FillPatcher.H:191
void BuildMask(amrex::BoxArray const &fba, int nghost, int nghost_set)
Definition: ERF_FillPatcher.cpp:181
void FillSet(amrex::MultiFab &mf, double time, BC &cbc, amrex::Vector< amrex::BCRec > const &bcs)
Definition: ERF_FillPatcher.H:204
double m_dt_crse
Definition: ERF_FillPatcher.H:189
std::unique_ptr< amrex::MultiFab > m_cf_crse_data_old
Definition: ERF_FillPatcher.H:182
int GetRelaxMaskVal()
Definition: ERF_FillPatcher.H:119
int m_nghost
Definition: ERF_FillPatcher.H:177
amrex::DistributionMapping m_fdm
Definition: ERF_FillPatcher.H:173
real(c_double), parameter epsilon
Definition: ERF_module_model_constants.F90:12