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  * Return the mask value for the relax region.
102  */
103  int GetRelaxMaskVal () { return m_relax_mask; }
104 
105  /**
106  * Return the coarse-fine mask.
107  */
108  amrex::iMultiFab* GetMask () { return m_cf_mask.get(); }
109 
110  /**
111  * Fill fine data in the set region.
112  *
113  * @param[in,out] mf MultiFab to be filled
114  * @param[in] time time at which to fill data
115  * @param[in] cbc coarse boundary condition
116  * @param[in] bcs vector of boundary conditions
117  */
118  template <typename BC>
119  void FillSet (amrex::MultiFab& mf, double time,
120  BC& cbc, amrex::Vector<amrex::BCRec> const& bcs);
121 
122  /**
123  * Fill fine data in the relax region.
124  *
125  * @param[in,out] mf MultiFab to be filled
126  * @param[in] time time at which to fill data
127  * @param[in] cbc coarse boundary condition
128  * @param[in] bcs vector of boundary conditions
129  */
130  template <typename BC>
131  void FillRelax (amrex::MultiFab& mf, double time,
132  BC& cbc, amrex::Vector<amrex::BCRec> const& bcs);
133 
134  /**
135  * Fill fine data in the selected mask region.
136  *
137  * @param[in,out] mf MultiFab to be filled
138  * @param[in] time time at which to fill data
139  * @param[in] cbc coarse boundary condition
140  * @param[in] bcs vector of boundary conditions
141  * @param[in] mask_val mask value selecting cells to fill
142  */
143  template <typename BC>
144  void Fill (amrex::MultiFab& mf, double time,
145  BC& cbc, amrex::Vector<amrex::BCRec> const& bcs, int mask_val);
146 
147 private:
148 
149  amrex::BoxArray m_fba;
150  amrex::BoxArray m_cba;
151  amrex::DistributionMapping m_fdm;
152  amrex::DistributionMapping m_cdm;
153  amrex::Geometry m_fgeom;
154  amrex::Geometry m_cgeom;
155  int m_nghost;
157  int m_ncomp;
158  amrex::InterpBase* m_interp;
159  amrex::IntVect m_ratio;
160  std::unique_ptr<amrex::MultiFab> m_cf_crse_data_old;
161  std::unique_ptr<amrex::MultiFab> m_cf_crse_data_new;
162  std::unique_ptr<amrex::iMultiFab> m_cf_mask;
163  amrex::Vector<double> m_crse_times;
164  double m_dt_crse;
165  int m_set_mask{2};
166  int m_relax_mask{1};
167 };
168 
169 /**
170  * Fill fine data in the set region
171  *
172  * @param[in,out] mf MultiFab to be filled
173  * @param[in] time Time at which to fill data
174  * @param[in] cbc Coarse boundary condition
175  * @param[in] bcs Vector of boundary conditions
176  */
177 template <typename BC>
178 void
179 ERFFillPatcher::FillSet (amrex::MultiFab& mf, double time,
180  BC& cbc, amrex::Vector<amrex::BCRec> const& bcs)
181 {
182  Fill(mf,time,cbc,bcs,m_set_mask);
183 }
184 
185 /**
186  * Fill fine data in the relax region
187  *
188  * @param[in,out] mf MultiFab to be filled
189  * @param[in] time Time at which to fill data
190  * @param[in] cbc Coarse boundary condition
191  * @param[in] bcs Vector of boundary conditions
192  */
193 template <typename BC>
194 void
195 ERFFillPatcher::FillRelax (amrex::MultiFab& mf, double time,
196  BC& cbc, amrex::Vector<amrex::BCRec> const& bcs)
197 {
198  Fill(mf,time,cbc,bcs,m_relax_mask);
199 }
200 
201 /**
202  * Fill fine data in the relax region
203  *
204  * @param[in,out] mf MultiFab to be filled
205  * @param[in] time_d Time at which to fill data
206  * @param[in] cbc Coarse boundary condition
207  * @param[in] bcs Vector of boundary conditions
208  * @param[in] mask_val Mask value selecting cells to fill
209  */
210 template <typename BC>
211 void
212 ERFFillPatcher::Fill (amrex::MultiFab& mf, double time_d,
213  BC& cbc, amrex::Vector<amrex::BCRec> const& bcs, int mask_val)
214 {
215  constexpr double eps = std::numeric_limits<float>::epsilon();
216 
217  AMREX_ALWAYS_ASSERT((time_d >= m_crse_times[0]-eps) && (time_d <= m_crse_times[1]+eps));
218 
219  amrex::Real time = static_cast<amrex::Real>(time_d);
220 
221  // Time interpolation factors
222  amrex::Real fac_new = amrex::Real(0);
223  amrex::Real fac_old = amrex::Real(1);
224  if (amrex::Math::abs(m_dt_crse) > eps) {
225  fac_new = static_cast<amrex::Real>((time_d - m_crse_times[0]) / m_dt_crse);
226  fac_old = amrex::Real(1) - fac_new;
227  }
228 
229  // Boundary condition operator
230  cbc(*(m_cf_crse_data_old), 0, m_ncomp, amrex::IntVect(0), time, 0);
231 
232  // Coarse MF to hold time interpolated data
233  amrex::MultiFab crse_data_time_interp(m_cf_crse_data_old->boxArray(),
234  m_cf_crse_data_old->DistributionMap(),
235  m_ncomp, amrex::IntVect{0});
236 
237  // Time interpolate the coarse data
238  amrex::MultiFab::LinComb(crse_data_time_interp,
239  fac_old, *(m_cf_crse_data_old), 0,
240  fac_new, *(m_cf_crse_data_new), 0,
241  0, m_ncomp, amrex::IntVect{0});
242 
243  // Call correct spatial interpolation type
244  amrex::IndexType m_ixt = mf.boxArray().ixType();
245  int ixt_sum = m_ixt[0]+m_ixt[1]+m_ixt[2];
246  if (ixt_sum == 0) {
247  InterpCell(mf,crse_data_time_interp,bcs,mask_val);
248  } else if (ixt_sum == 1) {
249  InterpFace(mf,crse_data_time_interp,mask_val);
250  } else {
251  amrex::Abort("ERF_FillPatcher only supports face linear and cell cons linear interp!");
252  }
253 }
254 #endif
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:153
void Fill(amrex::MultiFab &mf, double time, BC &cbc, amrex::Vector< amrex::BCRec > const &bcs, int mask_val)
Definition: ERF_FillPatcher.H:212
void RegisterCoarseData(amrex::Vector< amrex::MultiFab const * > const &crse_data, amrex::Vector< double > const &crse_time)
Definition: ERF_FillPatcher.cpp:231
amrex::BoxArray m_fba
Definition: ERF_FillPatcher.H:149
amrex::iMultiFab * GetMask()
Definition: ERF_FillPatcher.H:108
amrex::InterpBase * m_interp
Definition: ERF_FillPatcher.H:158
amrex::BoxArray m_cba
Definition: ERF_FillPatcher.H:150
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:59
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:22
amrex::DistributionMapping m_cdm
Definition: ERF_FillPatcher.H:152
amrex::Geometry m_cgeom
Definition: ERF_FillPatcher.H:154
int m_ncomp
Definition: ERF_FillPatcher.H:157
void InterpFace(amrex::MultiFab &fine, amrex::MultiFab const &crse, int mask_val)
Definition: ERF_FillPatcher.cpp:262
int m_nghost_subset
Definition: ERF_FillPatcher.H:156
void FillRelax(amrex::MultiFab &mf, double time, BC &cbc, amrex::Vector< amrex::BCRec > const &bcs)
Definition: ERF_FillPatcher.H:195
std::unique_ptr< amrex::iMultiFab > m_cf_mask
Definition: ERF_FillPatcher.H:162
std::unique_ptr< amrex::MultiFab > m_cf_crse_data_new
Definition: ERF_FillPatcher.H:161
int m_set_mask
Definition: ERF_FillPatcher.H:165
amrex::Vector< double > m_crse_times
Definition: ERF_FillPatcher.H:163
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:388
amrex::IntVect m_ratio
Definition: ERF_FillPatcher.H:159
int m_relax_mask
Definition: ERF_FillPatcher.H:166
void BuildMask(amrex::BoxArray const &fba, int nghost, int nghost_set)
Definition: ERF_FillPatcher.cpp:128
void FillSet(amrex::MultiFab &mf, double time, BC &cbc, amrex::Vector< amrex::BCRec > const &bcs)
Definition: ERF_FillPatcher.H:179
double m_dt_crse
Definition: ERF_FillPatcher.H:164
std::unique_ptr< amrex::MultiFab > m_cf_crse_data_old
Definition: ERF_FillPatcher.H:160
int GetRelaxMaskVal()
Definition: ERF_FillPatcher.H:103
int m_nghost
Definition: ERF_FillPatcher.H:155
amrex::DistributionMapping m_fdm
Definition: ERF_FillPatcher.H:151
real(c_double), parameter epsilon
Definition: ERF_module_model_constants.F90:12