ERF
Energy Research and Forecasting: An Atmospheric Modeling Code
ERF_EB.H
Go to the documentation of this file.
1 /**
2  * \file ERF_EB.H
3  * \brief Declares the embedded-boundary factory manager used by ERF levels.
4  */
5 #ifndef ERF_EB_H_
6 #define ERF_EB_H_
7 
8 #include <AMReX_Geometry.H>
9 #include <AMReX_DistributionMapping.H>
10 #include <AMReX_BoxArray.H>
11 
12 #include <AMReX_EB2.H>
13 #include <AMReX_EBFabFactory.H>
14 #include <AMReX_Dim3.H>
15 #include <AMReX_GpuContainers.H>
16 
17 #include <ERF_EBAux.H>
18 
19 /**
20  * \brief Owns and exposes cell-centered and face-centered EB factories.
21  *
22  * The class builds AMReX EB factories for cell-centered state data and, depending
23  * on USE_FC_FACTORY, either native AMReX or ERF auxiliary factories for staggered
24  * velocity components.
25  */
26 class eb_ {
27 
28  public:
29 
30  using CutCellList = amrex::Gpu::DeviceVector<amrex::Dim3>;
31 
32  //! Destroy the EB factory manager.
33  ~eb_ ();
34 
35  /**
36  * \brief Construct an EB description from terrain data.
37  * \param a_geom Geometry used to place the terrain EB.
38  * \param terrain_fab Terrain height data.
39  * \param a_dz_stretched Device vector containing stretched vertical spacing.
40  * \param is_anelastic Whether the owning level is using anelastic dynamics.
41  */
42  eb_ (amrex::Geometry const& a_geom,
43  amrex::FArrayBox const& terrain_fab,
44  amrex::Gpu::DeviceVector<amrex::Real>& a_dz_stretched,
45  bool is_anelastic);
46  //! Construct an empty EB factory manager.
47  eb_ ();
48 
49  /**
50  * \brief Define the EB level metadata used by this factory manager.
51  * \param level AMR level index.
52  * \param a_geom Geometry for the level.
53  * \param a_eb_level AMReX EB level owned by the global EB index space.
54  * \param is_anelastic Whether the owning level is using anelastic dynamics.
55  */
56  void define (int level,
57  amrex::Geometry const& a_geom,
58  amrex::EB2::Level const* a_eb_level,
59  bool is_anelastic);
60 
61  /**
62  * \brief Build cell-centered and staggered EB factories for the level.
63  * \param level AMR level index.
64  * \param a_geom Geometry for the level.
65  * \param ba BoxArray over which factories are defined.
66  * \param dm DistributionMapping for the BoxArray.
67  * \param a_eb_level AMReX EB level used to populate factory data.
68  */
69  void make_all_factories ( int level,
70  amrex::Geometry const& a_geom,
71  amrex::BoxArray const& ba,
72  amrex::DistributionMapping const& dm,
73  amrex::EB2::Level const& a_eb_level);
74 
75  /**
76  * \brief Build only the cell-centered EB factory for the level.
77  * \param level AMR level index.
78  * \param a_geom Geometry for the level.
79  * \param ba BoxArray over which the factory is defined.
80  * \param dm DistributionMapping for the BoxArray.
81  * \param a_eb_level AMReX EB level used to populate factory data.
82  */
83  void make_cc_factory ( int level,
84  amrex::Geometry const& a_geom,
85  amrex::BoxArray const& ba,
86  amrex::DistributionMapping const& dm,
87  amrex::EB2::Level const& a_eb_level);
88 
89  //! Number of ghost cells needed for basic EB flags.
90  int nghost_basic () const { return 5; } // nghost_eb_basic ()
91  //! Number of ghost cells needed for EB volume data.
92  int nghost_volume () const { return 5; } // nghost_eb_volume ()
93  //! Number of ghost cells needed for full EB geometric data.
94  int nghost_full () const { return 4; } // nghost_eb_full ()
95 
96  // Toggle between eb_aux_ and native AMReX FC factories
97  #ifndef USE_FC_FACTORY
98  /**
99  * \def USE_FC_FACTORY
100  * \brief Select native AMReX face-centered factories instead of ERF auxiliary factories.
101  */
102  #define USE_FC_FACTORY 1 // Default to 1: use amrex native FC factory
103  #endif
104 
105  //! Return cut x-faces owned by a grid, cached when the EB factories are built.
106  [[nodiscard]] CutCellList const& get_u_cut_cells (int grid_index) const noexcept
107  {
108  return m_u_cut_cells[grid_index];
109  }
110 
111  //! Return cut y-faces owned by a grid, cached when the EB factories are built.
112  [[nodiscard]] CutCellList const& get_v_cut_cells (int grid_index) const noexcept
113  {
114  return m_v_cut_cells[grid_index];
115  }
116 
117  //! Return cut z-faces owned by a grid, cached when the EB factories are built.
118  [[nodiscard]] CutCellList const& get_w_cut_cells (int grid_index) const noexcept
119  {
120  return m_w_cut_cells[grid_index];
121  }
122 
123  //! Return the cell-centered EB factory.
124  const std::unique_ptr<amrex::EBFArrayBoxFactory>& get_const_factory () const noexcept { return m_factory; }
125 
126  /**
127  * \brief Disconnect covered neighbors in an EB factory's cell flags.
128  * \param factory Factory whose non-const flag data are updated.
129  */
130  void set_connection_flags (amrex::EBFArrayBoxFactory* factory);
131 
132  /**
133  * \brief Enforce FC-CC consistency by marking FC faces as covered when both CC neighbors are covered.
134  * \param fc_factory Face-centered factory to modify (non-const)
135  * \param cc_factory Cell-centered factory to read neighbor states (const)
136  * \param idim Direction of face centering (0=x, 1=y, 2=z)
137  */
138  void mask_fc_from_cc (amrex::EBFArrayBoxFactory* fc_factory,
139  const amrex::EBFArrayBoxFactory* cc_factory,
140  int idim);
141 
142  #if USE_FC_FACTORY
143  //! Return the native AMReX x-face EB factory.
144  amrex::EBFArrayBoxFactory const* get_u_const_factory () const noexcept { return m_u_factory_fc.get(); }
145  //! Return the native AMReX y-face EB factory.
146  amrex::EBFArrayBoxFactory const* get_v_const_factory () const noexcept { return m_v_factory_fc.get(); }
147  //! Return the native AMReX z-face EB factory.
148  amrex::EBFArrayBoxFactory const* get_w_const_factory () const noexcept { return m_w_factory_fc.get(); }
149  #else
150  //! Return the ERF auxiliary x-face EB factory.
151  eb_aux_ const* get_u_const_factory () const noexcept { return &m_u_factory; }
152  //! Return the ERF auxiliary y-face EB factory.
153  eb_aux_ const* get_v_const_factory () const noexcept { return &m_v_factory; }
154  //! Return the ERF auxiliary z-face EB factory.
155  eb_aux_ const* get_w_const_factory () const noexcept { return &m_w_factory; }
156  #endif
157 
158  //! Forward declaration for EB surface output.
159  class EBToPVD;
160 
161  private:
162 
163  int m_has_eb;
164  std::string m_type;
165 
166  amrex::EBSupport m_support_level;
167 
169 
170  amrex::FabArray<amrex::EBCellFlagFab>* m_cellflags = nullptr;
171 
172  //! EB level constructed from building GeometryShop
173  amrex::EB2::Level const* m_eb_level;
174 
175  std::unique_ptr<amrex::EBFArrayBoxFactory> m_factory = nullptr;
176 
177  // Original eb_aux_ factories (USE_FC_FACTORY=0)
181 
182  // New native AMReX FC factories (USE_FC_FACTORY=1)
183  std::unique_ptr<amrex::EBFArrayBoxFactory> m_u_factory_fc = nullptr;
184  std::unique_ptr<amrex::EBFArrayBoxFactory> m_v_factory_fc = nullptr;
185  std::unique_ptr<amrex::EBFArrayBoxFactory> m_w_factory_fc = nullptr;
186 
187  // Persistent per-grid cut-face lists for sparse GPU wall-correction launches.
188  amrex::Vector<CutCellList> m_u_cut_cells;
189  amrex::Vector<CutCellList> m_v_cut_cells;
190  amrex::Vector<CutCellList> m_w_cut_cells;
191 
192  void build_cut_cell_lists (
193  amrex::FabArray<amrex::EBCellFlagFab> const& flags,
194  amrex::Vector<CutCellList>& cut_cells);
195 
196  /**
197  * \brief Build terrain EB geometry for the supplied Geometry.
198  * \param a_geom Geometry used to define the EB index space.
199  */
200  void make_terrain (amrex::Geometry const& a_geom);
201 
202  /**
203  * \brief Construct EB levels from an AMReX GeometryShop.
204  * \tparam F Implicit-function type stored by the GeometryShop.
205  * \param a_geom Geometry used to build the EB index space.
206  * \param a_gshop GeometryShop describing the implicit EB.
207  */
208  template<class F>
209  void build_level (amrex::Geometry const& a_geom,
210  amrex::EB2::GeometryShop<F> a_gshop)
211  {
212  int const req_lev(0);
213  int const max_lev(2);
214 
215  amrex::EB2::Build(a_gshop, a_geom, req_lev, max_lev);
216  const amrex::EB2::IndexSpace& ebis = amrex::EB2::IndexSpace::top();
217  m_eb_level = &(ebis.getLevel(a_geom));
218  }
219 
220  //! Return mutable EB cell flags from an AMReX factory.
221  inline amrex::FabArray<amrex::EBCellFlagFab>&
222  getNonConstEBCellFlags (const amrex::EBFArrayBoxFactory& ebfact)
223  {
224  const amrex::FabArray<amrex::EBCellFlagFab>& flags_const = ebfact.getMultiEBCellFlagFab();
225  return const_cast<amrex::FabArray<amrex::EBCellFlagFab>&>(flags_const);
226  }
227 
228  //! Return mutable volume fractions from an AMReX factory.
229  inline amrex::MultiFab&
230  getNonConstVolFrac (const amrex::EBFArrayBoxFactory& ebfact)
231  {
232  const amrex::MultiFab& vfrac_const = ebfact.getVolFrac();
233  return const_cast<amrex::MultiFab&>(vfrac_const);
234  }
235 
236  //! Return mutable cell centroids from an AMReX factory.
237  inline amrex::MultiCutFab&
238  getNonConstCentroid (const amrex::EBFArrayBoxFactory& ebfact)
239  {
240  const amrex::MultiCutFab& vcent_const = ebfact.getCentroid();
241  return const_cast<amrex::MultiCutFab&>(vcent_const);
242  }
243 
244  //! Return mutable area-fraction arrays from an AMReX factory.
245  inline amrex::Array<amrex::MultiCutFab*, AMREX_SPACEDIM>
246  getNonConstAreaFrac (const amrex::EBFArrayBoxFactory& ebfact)
247  {
248  auto afrac_const = ebfact.getAreaFrac();
249  amrex::Array<amrex::MultiCutFab*, AMREX_SPACEDIM> afrac;
250  for (int dir = 0; dir < AMREX_SPACEDIM; ++dir) {
251  afrac[dir] = const_cast<amrex::MultiCutFab*>(afrac_const[dir]);
252  }
253  return afrac;
254  }
255 
256  //! Return mutable face-centroid arrays from an AMReX factory.
257  inline amrex::Array<amrex::MultiCutFab*, AMREX_SPACEDIM>
258  getNonConstFaceCent (const amrex::EBFArrayBoxFactory& ebfact)
259  {
260  auto fcent_const = ebfact.getFaceCent();
261  amrex::Array<amrex::MultiCutFab*, AMREX_SPACEDIM> fcent;
262  for (int dir = 0; dir < AMREX_SPACEDIM; ++dir) {
263  fcent[dir] = const_cast<amrex::MultiCutFab*>(fcent_const[dir]);
264  }
265  return fcent;
266  }
267 
268 };
269 #endif
Declares auxiliary EB factories for face-centered data.
Owns and exposes cell-centered and face-centered EB factories.
Definition: ERF_EB.H:26
amrex::FabArray< amrex::EBCellFlagFab > & getNonConstEBCellFlags(const amrex::EBFArrayBoxFactory &ebfact)
Return mutable EB cell flags from an AMReX factory.
Definition: ERF_EB.H:222
CutCellList const & get_u_cut_cells(int grid_index) const noexcept
Return cut x-faces owned by a grid, cached when the EB factories are built.
Definition: ERF_EB.H:106
eb_()
Construct an empty EB factory manager.
Definition: ERF_EB.cpp:60
void define(int level, amrex::Geometry const &a_geom, amrex::EB2::Level const *a_eb_level, bool is_anelastic)
Define the EB level metadata used by this factory manager.
amrex::Vector< CutCellList > m_w_cut_cells
Definition: ERF_EB.H:190
void make_terrain(amrex::Geometry const &a_geom)
Build terrain EB geometry for the supplied Geometry.
CutCellList const & get_v_cut_cells(int grid_index) const noexcept
Return cut y-faces owned by a grid, cached when the EB factories are built.
Definition: ERF_EB.H:112
void build_level(amrex::Geometry const &a_geom, amrex::EB2::GeometryShop< F > a_gshop)
Construct EB levels from an AMReX GeometryShop.
Definition: ERF_EB.H:209
amrex::Array< amrex::MultiCutFab *, AMREX_SPACEDIM > getNonConstAreaFrac(const amrex::EBFArrayBoxFactory &ebfact)
Return mutable area-fraction arrays from an AMReX factory.
Definition: ERF_EB.H:246
CutCellList const & get_w_cut_cells(int grid_index) const noexcept
Return cut z-faces owned by a grid, cached when the EB factories are built.
Definition: ERF_EB.H:118
void build_cut_cell_lists(amrex::FabArray< amrex::EBCellFlagFab > const &flags, amrex::Vector< CutCellList > &cut_cells)
Definition: ERF_EB.cpp:179
amrex::Vector< CutCellList > m_v_cut_cells
Definition: ERF_EB.H:189
void mask_fc_from_cc(amrex::EBFArrayBoxFactory *fc_factory, const amrex::EBFArrayBoxFactory *cc_factory, int idim)
Enforce FC-CC consistency by marking FC faces as covered when both CC neighbors are covered.
Definition: ERF_EB.cpp:260
amrex::EB2::Level const * m_eb_level
EB level constructed from building GeometryShop.
Definition: ERF_EB.H:173
void make_all_factories(int level, amrex::Geometry const &a_geom, amrex::BoxArray const &ba, amrex::DistributionMapping const &dm, amrex::EB2::Level const &a_eb_level)
Build cell-centered and staggered EB factories for the level.
Definition: ERF_EB.cpp:67
amrex::Vector< CutCellList > m_u_cut_cells
Definition: ERF_EB.H:188
amrex::FabArray< amrex::EBCellFlagFab > * m_cellflags
Definition: ERF_EB.H:170
const std::unique_ptr< amrex::EBFArrayBoxFactory > & get_const_factory() const noexcept
Return the cell-centered EB factory.
Definition: ERF_EB.H:124
amrex::MultiFab & getNonConstVolFrac(const amrex::EBFArrayBoxFactory &ebfact)
Return mutable volume fractions from an AMReX factory.
Definition: ERF_EB.H:230
eb_aux_ m_w_factory
Definition: ERF_EB.H:180
std::unique_ptr< amrex::EBFArrayBoxFactory > m_factory
Definition: ERF_EB.H:175
amrex::EBSupport m_support_level
Definition: ERF_EB.H:166
amrex::EBFArrayBoxFactory const * get_w_const_factory() const noexcept
Return the native AMReX z-face EB factory.
Definition: ERF_EB.H:148
amrex::EBFArrayBoxFactory const * get_u_const_factory() const noexcept
Return the native AMReX x-face EB factory.
Definition: ERF_EB.H:144
int nghost_volume() const
Number of ghost cells needed for EB volume data.
Definition: ERF_EB.H:92
amrex::Array< amrex::MultiCutFab *, AMREX_SPACEDIM > getNonConstFaceCent(const amrex::EBFArrayBoxFactory &ebfact)
Return mutable face-centroid arrays from an AMReX factory.
Definition: ERF_EB.H:258
void make_cc_factory(int level, amrex::Geometry const &a_geom, amrex::BoxArray const &ba, amrex::DistributionMapping const &dm, amrex::EB2::Level const &a_eb_level)
Build only the cell-centered EB factory for the level.
Definition: ERF_EB.cpp:158
amrex::Gpu::DeviceVector< amrex::Dim3 > CutCellList
Definition: ERF_EB.H:30
amrex::EBFArrayBoxFactory const * get_v_const_factory() const noexcept
Return the native AMReX y-face EB factory.
Definition: ERF_EB.H:146
amrex::MultiCutFab & getNonConstCentroid(const amrex::EBFArrayBoxFactory &ebfact)
Return mutable cell centroids from an AMReX factory.
Definition: ERF_EB.H:238
eb_aux_ m_u_factory
Definition: ERF_EB.H:178
~eb_()
Destroy the EB factory manager.
Definition: ERF_EB.cpp:55
std::unique_ptr< amrex::EBFArrayBoxFactory > m_w_factory_fc
Definition: ERF_EB.H:185
eb_(amrex::Geometry const &a_geom, amrex::FArrayBox const &terrain_fab, amrex::Gpu::DeviceVector< amrex::Real > &a_dz_stretched, bool is_anelastic)
Construct an EB description from terrain data.
eb_aux_ m_v_factory
Definition: ERF_EB.H:179
std::unique_ptr< amrex::EBFArrayBoxFactory > m_v_factory_fc
Definition: ERF_EB.H:184
int m_has_eb
Definition: ERF_EB.H:159
int nghost_full() const
Number of ghost cells needed for full EB geometric data.
Definition: ERF_EB.H:94
int nghost_basic() const
Number of ghost cells needed for basic EB flags.
Definition: ERF_EB.H:90
int m_write_eb_surface
Definition: ERF_EB.H:168
std::unique_ptr< amrex::EBFArrayBoxFactory > m_u_factory_fc
Definition: ERF_EB.H:183
std::string m_type
Definition: ERF_EB.H:164
void set_connection_flags(amrex::EBFArrayBoxFactory *factory)
Disconnect covered neighbors in an EB factory's cell flags.
Definition: ERF_EB.cpp:216
Stores face-centered EB geometry reconstructed from a cell-centered factory.
Definition: ERF_EBAux.H:24