Finite Volume Solver  prototype
A framework to build finite volume solvers for the AG Klein at the Freie Universität Berlin.
AMReX/cutcell/PatchHierarchy.hpp
Go to the documentation of this file.
1 // Copyright (c) 2019 Maikel Nadolski
2 //
3 // Permission is hereby granted, free of charge, to any person obtaining a copy
4 // of this software and associated documentation files (the "Software"), to deal
5 // in the Software without restriction, including without limitation the rights
6 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 // copies of the Software, and to permit persons to whom the Software is
8 // furnished to do so, subject to the following conditions:
9 //
10 // The above copyright notice and this permission notice shall be included in
11 // all copies or substantial portions of the Software.
12 //
13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19 // SOFTWARE.
20 
21 #ifndef FUB_AMREX_CUTCELL_PATCH_HIERARCHY_HPP
22 #define FUB_AMREX_CUTCELL_PATCH_HIERARCHY_HPP
23 
26 #include "fub/CutCellData.hpp"
27 #include "fub/Duration.hpp"
28 #include "fub/Equation.hpp"
29 #include "fub/ext/Eigen.hpp"
30 
31 #include <AMReX_EBFabFactory.H>
32 #include <AMReX_FluxRegister.H>
33 #include <AMReX_Geometry.H>
34 #include <AMReX_MultiCutFab.H>
35 #include <AMReX_MultiFab.H>
36 #include <AMReX_PlotFileUtil.H>
37 
38 #include <fmt/format.h>
39 
40 #include <functional>
41 #include <iosfwd>
42 #include <vector>
43 
44 /// \brief The cutcell namespace
45 namespace fub::amrex {
46 class DebugStorage;
47 }
48 
49 namespace fub::amrex::cutcell {
50 
51 /// \ingroup PatchHierarchy
52 /// This class holds state data arrays for each refinement level of a patch
53 /// hierarchy.
54 ///
55 /// This cut-cell version stores some embedded boundary informations in addition
56 /// to the normal patch level type.
58  PatchLevel() = default;
59  ~PatchLevel() = default;
60 
61  /// \brief Deeply copy a patch level on each MPI Rank and recompute shielded
62  /// fractions.
64 
65  /// \brief Deeply copy a patch level on each MPI Rank and recompute shielded
66  /// fractions.
68 
69  /// @{
70  /// \brief Moves a patch level without any allocations happening.
71  PatchLevel(PatchLevel&&) noexcept = default;
72  PatchLevel& operator=(PatchLevel&&) noexcept = default;
73  /// @}
74 
75  /// \brief Constructs a patch level and computes shielded fractions.
76  ///
77  /// \param[in] level the refinement level number in a hierarchy
78  /// \param[in] tp the time point associated with this level
79  /// \param[in] ba the box array describing all boxes of this level
80  /// \param[in] dm the distribution mapping for all boxes of this level
81  /// \param[in] factory the boundary informations for cut cells.
82  PatchLevel(int level, Duration tp, const ::amrex::BoxArray& ba,
83  const ::amrex::DistributionMapping& dm, int n_components,
84  std::shared_ptr<::amrex::EBFArrayBoxFactory> factory, int ngrow);
85 
86  using MultiCutFabs =
87  std::array<std::shared_ptr<::amrex::MultiCutFab>, AMREX_SPACEDIM>;
88 
89  /// \brief This stores the EB factory for this refinement level.
90  std::shared_ptr<::amrex::EBFArrayBoxFactory> factory;
91 
92  /// \brief Store unshielded face fractions for all faces which touch a cut
93  /// cell.
95 
96  /// \brief Store singly shielded from left face fractions for all faces which
97  /// touch a cut cell.
99 
100  /// \brief Store singly shielded from right face fractions for all faces which
101  /// touch a cut cell.
103 
104  /// \brief Store doubly shielded face fractions for all faces which touch a
105  /// cut cell.
107 };
108 
109 /// \ingroup PatchHierarchy
110 /// This class extents the normal hierarchy options with a pointer to an
111 /// embedded boundary index space for each possible refinement level.
115  : ::fub::amrex::PatchHierarchyOptions(options) {
116  ngrow_eb_level_set =
117  GetOptionOr(options, "ngrow_eb_level_set", ngrow_eb_level_set);
118  cutcell_load_balance_weight = GetOptionOr(
119  options, "cutcell_load_balance_weight", cutcell_load_balance_weight);
120  remove_covered_grids =
121  GetOptionOr(options, "remove_covered_grids", remove_covered_grids);
122  }
123 
124  template <typename Log> void Print(Log& log) {
126  BOOST_LOG(log) << " - ngrow_eb_level_set = " << ngrow_eb_level_set;
127  BOOST_LOG(log) << " - cutcell_load_balance_weight = "
128  << cutcell_load_balance_weight;
129  BOOST_LOG(log) << " - remove_covered_grids = " << remove_covered_grids;
130  }
131 
132  std::vector<const ::amrex::EB2::IndexSpace*> index_spaces{};
133  int ngrow_eb_level_set{5};
134  double cutcell_load_balance_weight{6.0};
135  bool remove_covered_grids{true};
136 };
137 
138 /// \ingroup PatchHierarchy
140 public:
141  /// \brief Constructs a PatchHierarchy object which is capable of holding data
142  /// described by the secified data description on given geometry extents.
143  template <typename Equation>
144  PatchHierarchy(const Equation& equation,
145  const CartesianGridGeometry& geometry,
146  const PatchHierarchyOptions& options);
147 
148  /// \brief Constructs a PatchHierarchy object which is capable of holding data
149  /// described by the secified data description on given geometry extents.
151  const CartesianGridGeometry& geometry,
152  const PatchHierarchyOptions& options);
153 
154  /// @{
155  /// \name Member Acccess
156 
157  const DataDescription& GetDataDescription() const noexcept;
158 
159  /// \brief Return some additional patch hierarchy options.
160  const PatchHierarchyOptions& GetOptions() const noexcept;
161 
162  /// \brief Returns the Grid Geometry which was used to create the hierarchy
163  /// with.
164  const CartesianGridGeometry& GetGridGeometry() const noexcept;
165 
166  [[nodiscard]] const std::shared_ptr<CounterRegistry>&
167  GetCounterRegistry() const noexcept;
168 
169  void SetCounterRegistry(std::shared_ptr<CounterRegistry> registry);
170  /// @}
171 
172  /// @{
173  /// \name Observers
174 
175  int GetNumberOfLevels() const noexcept;
176 
177  int GetMaxNumberOfLevels() const noexcept;
178  /// @}
179 
180  /// @{
181  /// \name Level specific Access
182 
183  /// \brief Returns the number of cycles done for a specific level.
184  ///
185  /// \param[in] level the refinement level number
186  std::ptrdiff_t GetCycles(int level = 0) const;
187 
188  /// \brief Returns the time point of a specified level number.
189  ///
190  /// \param[in] level the refinement level number
191  Duration GetTimePoint(int level = 0) const;
192 
193  /// \brief Returns the ratio from fine to coarse for specified fine level
194  /// number and direction.
195  ///
196  /// \param[in] level the fine refinement level number
197  /// \param[in] dir the direction
198  int GetRatioToCoarserLevel(int level, Direction dir) const;
199 
200  ::amrex::IntVect GetRatioToCoarserLevel(int level) const;
201 
202  const ::amrex::Geometry& GetGeometry(int level) const;
203 
204  PatchLevel& GetPatchLevel(int level);
205 
206  const PatchLevel& GetPatchLevel(int level) const;
207 
208  const std::shared_ptr<::amrex::EBFArrayBoxFactory>&
209  GetEmbeddedBoundary(int level) const;
210 
211  CutCellData<AMREX_SPACEDIM> GetCutCellData(int level,
212  const ::amrex::MFIter& mfi) const;
213 
214  /// \brief Returns a shared pointer to the debug storage.
215  [[nodiscard]] const std::shared_ptr<DebugStorage>&
216  GetDebugStorage() const noexcept;
217 
218  /// @}
219 
220 private:
221  DataDescription description_;
222  CartesianGridGeometry grid_geometry_;
224  std::vector<PatchLevel> patch_level_;
225  std::vector<::amrex::Geometry> patch_level_geometry_;
226  std::shared_ptr<CounterRegistry> registry_;
227  std::shared_ptr<DebugStorage> debug_storage_;
228 };
229 
230 template <typename Equation>
232  const CartesianGridGeometry& geometry,
233  const PatchHierarchyOptions& options)
234  : PatchHierarchy(MakeDataDescription(equation), geometry, options) {}
235 
236 template <typename Equation>
237 void WritePlotFile(const std::string& plotfilename, const PatchHierarchy& hier,
238  const Equation& equation) {
239  const int nlevels = hier.GetNumberOfLevels();
240  const double time_point = hier.GetTimePoint().count();
241  FUB_ASSERT(nlevels >= 0);
242  std::size_t size = static_cast<std::size_t>(nlevels);
243  ::amrex::Vector<const ::amrex::MultiFab*> mf(size);
244  ::amrex::Vector<::amrex::Geometry> geoms(size);
245  ::amrex::Vector<int> level_steps(size);
246  ::amrex::Vector<::amrex::IntVect> ref_ratio(size - 1);
247  for (std::size_t i = 0; i < size; ++i) {
248  mf[i] = &hier.GetPatchLevel(static_cast<int>(i)).data;
249  geoms[i] = hier.GetGeometry(static_cast<int>(i));
250  level_steps[i] = static_cast<int>(hier.GetCycles(static_cast<int>(i)));
251  }
252  for (std::size_t i = 1; i < size; ++i) {
253  ref_ratio[i - 1] = hier.GetRatioToCoarserLevel(static_cast<int>(i));
254  }
255  using Traits = StateTraits<Complete<Equation>>;
256  constexpr auto names = Traits::names;
257  const auto depths = Depths(equation, Type<Complete<Equation>>{});
258  const std::size_t n_names =
259  std::tuple_size<remove_cvref_t<decltype(names)>>::value;
260  ::amrex::Vector<std::string> varnames;
261  varnames.reserve(n_names);
262  boost::mp11::tuple_for_each(Zip(names, StateToTuple(depths)), [&](auto xs) {
263  const int ncomp = std::get<1>(xs);
264  if (ncomp == 1) {
265  varnames.push_back(std::get<0>(xs));
266  } else {
267  for (int i = 0; i < ncomp; ++i) {
268  varnames.push_back(fmt::format("{}_{}", std::get<0>(xs), i));
269  }
270  }
271  });
272  ::amrex::EB_WriteMultiLevelPlotfile(plotfilename, nlevels, mf, varnames,
273  geoms, time_point, level_steps,
274  ref_ratio);
275 }
276 
277 template <int Rank>
278 void WritePlotFile(const std::string& plotfilename, const PatchHierarchy& hier,
279  const IdealGasMix<Rank>& equation) {
280  using Equation = IdealGasMix<Rank>;
281  const int nlevels = hier.GetNumberOfLevels();
282  const double time_point = hier.GetTimePoint().count();
283  FUB_ASSERT(nlevels >= 0);
284  std::size_t size = static_cast<std::size_t>(nlevels);
285  ::amrex::Vector<const ::amrex::MultiFab*> mf(size);
286  ::amrex::Vector<::amrex::Geometry> geoms(size);
287  ::amrex::Vector<int> level_steps(size);
288  ::amrex::Vector<::amrex::IntVect> ref_ratio(size - 1);
289  for (std::size_t i = 0; i < size; ++i) {
290  mf[i] = &hier.GetPatchLevel(static_cast<int>(i)).data;
291  geoms[i] = hier.GetGeometry(static_cast<int>(i));
292  level_steps[i] = static_cast<int>(hier.GetCycles(static_cast<int>(i)));
293  }
294  for (std::size_t i = 1; i < size; ++i) {
295  ref_ratio[i - 1] = hier.GetRatioToCoarserLevel(static_cast<int>(i));
296  }
297  using Traits = StateTraits<Complete<Equation>>;
298  constexpr auto names = Traits::names;
299  const auto depths = Depths(equation, Type<Complete<Equation>>{});
300  const std::size_t n_names =
301  std::tuple_size<remove_cvref_t<decltype(names)>>::value;
302  ::amrex::Vector<std::string> varnames;
303  varnames.reserve(n_names);
304  boost::mp11::tuple_for_each(Zip(names, StateToTuple(depths)), [&](auto xs) {
305  const int ncomp = std::get<1>(xs);
306  if (ncomp == 1) {
307  varnames.push_back(std::get<0>(xs));
308  } else {
309  span<const std::string> species = equation.GetReactor().GetSpeciesNames();
310  for (int i = 0; i < ncomp; ++i) {
311  if (std::get<0>(xs) == std::string{"Species"}) {
312  varnames.push_back(species[i]);
313  } else {
314  varnames.push_back(fmt::format("{}_{}", std::get<0>(xs), i));
315  }
316  }
317  }
318  });
319  ::amrex::EB_WriteMultiLevelPlotfile(plotfilename, nlevels, mf, varnames,
320  geoms, time_point, level_steps,
321  ref_ratio);
322 }
323 
324 void WriteCheckpointFile(const std::string& checkpointname,
325  const PatchHierarchy& hier);
326 
327 PatchHierarchy ReadCheckpointFile(const std::string& checkpointname,
328  DataDescription desc,
329  const CartesianGridGeometry& geometry,
330  const PatchHierarchyOptions& options);
331 
332 // void Write2Dfrom3D(std::ostream* out, const PatchHierarchy& hierarchy, const
333 // ::amrex::Box& finest_box,
334 // const IdealGasMix<3>& eq, fub::Duration time_point,
335 // std::ptrdiff_t cycle_number, MPI_Comm comm);
336 
337 void WriteMatlabData(const std::string& name, const PatchHierarchy& hierarchy,
338  fub::Duration time_point, std::ptrdiff_t cycle_number,
339  MPI_Comm comm);
340 
341 void Write2Dfrom3D(const std::string& name, const PatchHierarchy& hierarchy,
342  const ::amrex::Box& finest_box, const IdealGasMix<3>& eq,
343  fub::Duration time_point, std::ptrdiff_t cycle_number,
344  MPI_Comm comm);
345 
346 std::vector<double> GatherStates(
347  const PatchHierarchy& hierarchy,
349  MPI_Comm comm);
350 
351 } // namespace fub::amrex::cutcell
352 
353 #endif
#define FUB_ASSERT(x)
Definition: assert.hpp:39
span< const std::string > GetSpeciesNames() const
Return the name of the ith species.
Definition: FlameMasterReactor.hpp:338
FlameMasterReactor & GetReactor() noexcept
Definition: IdealGasMix.hpp:140
This class stores a list of snapshots and returns proxy objects to those.
Definition: output/DebugOutput.hpp:201
Definition: AMReX/Geometry.hpp:30
Definition: AMReX/cutcell/PatchHierarchy.hpp:139
PatchLevel & GetPatchLevel(int level)
Returns the number of cycles done for a specific level.
int GetRatioToCoarserLevel(int level, Direction dir) const
Returns the ratio from fine to coarse for specified fine level number and direction.
Duration GetTimePoint(int level=0) const
Returns the time point of a specified level number.
int GetNumberOfLevels() const noexcept
std::ptrdiff_t GetCycles(int level=0) const
Returns the number of cycles done for a specific level.
PatchHierarchy(DataDescription description, const CartesianGridGeometry &geometry, const PatchHierarchyOptions &options)
Constructs a PatchHierarchy object which is capable of holding data described by the secified data de...
const DataDescription & GetDataDescription() const noexcept
Return some additional patch hierarchy options.
const ::amrex::Geometry & GetGeometry(int level) const
Returns the number of cycles done for a specific level.
Definition: mdspan.hpp:573
An extents object defines a multidimensional index space which is the Cartesian product of integers e...
Definition: mdspan.hpp:208
A span is a view over a contiguous sequence of objects, the storage of which is owned by some other o...
Definition: span.hpp:81
Definition: FillCutCellData.hpp:30
PatchHierarchy ReadCheckpointFile(const std::string &checkpointname, DataDescription desc, const CartesianGridGeometry &geometry, const PatchHierarchyOptions &options)
void WriteMatlabData(const std::string &name, const PatchHierarchy &hierarchy, fub::Duration time_point, std::ptrdiff_t cycle_number, MPI_Comm comm)
std::vector< double > GatherStates(const PatchHierarchy &hierarchy, basic_mdspan< const double, extents< AMREX_SPACEDIM, dynamic_extent >> xs, MPI_Comm comm)
void WritePlotFile(const std::string &plotfilename, const PatchHierarchy &hier, const Equation &equation)
Definition: AMReX/cutcell/PatchHierarchy.hpp:237
void Write2Dfrom3D(const std::string &name, const PatchHierarchy &hierarchy, const ::amrex::Box &finest_box, const IdealGasMix< 3 > &eq, fub::Duration time_point, std::ptrdiff_t cycle_number, MPI_Comm comm)
void WriteCheckpointFile(const std::string &checkpointname, const PatchHierarchy &hier)
The amrex namespace.
Definition: AverageState.hpp:33
DataDescription MakeDataDescription(const Equation &equation)
Definition: AMReX/PatchHierarchy.hpp:248
std::decay_t< decltype(std::declval< T >().GetEquation())> Equation
A template typedef to detect the member function.
Definition: Meta.hpp:59
The fub namespace.
Definition: AnyBoundaryCondition.hpp:31
typename remove_cvref< T >::type remove_cvref_t
Definition: type_traits.hpp:226
void Log(std::string message, Duration timepoint, boost::log::trivial::severity_level level=boost::log::trivial::severity_level::info)
std::chrono::duration< double > Duration
Definition: Duration.hpp:31
constexpr struct fub::DepthsFn Depths
Direction
This is a type safe type to denote a dimensional split direction.
Definition: Direction.hpp:30
constexpr auto Zip(Ts &&... ts)
Definition: State.hpp:65
ProgramOptions GetOptions(const ProgramOptions &options, const std::string &name)
T GetOptionOr(const ProgramOptions &map, const std::string &name, const T &value)
Definition: ProgramOptions.hpp:48
auto StateToTuple(const State &x)
Definition: State.hpp:322
IndexBox< Rank > Box(const BasicView< State, Layout, Rank > &view)
Definition: State.hpp:486
std::map< std::string, pybind11::object > ProgramOptions
Definition: ProgramOptions.hpp:40
Definition: CutCellData.hpp:34
Definition: State.hpp:35
Definition: State.hpp:162
Definition: CartesianGridGeometry.hpp:37
The DataDescription class contains all information which is neccessary to describe the complete and c...
Definition: AMReX/PatchHierarchy.hpp:73
void Print(Log &log)
Definition: AMReX/PatchHierarchy.hpp:385
The PatchLevel represents a distributed grid containing plain simulation data without a ghost cell la...
Definition: AMReX/PatchHierarchy.hpp:90
Duration time_point
Definition: AMReX/PatchHierarchy.hpp:141
::amrex::MultiFab data
Definition: AMReX/PatchHierarchy.hpp:145
This class extents the normal hierarchy options with a pointer to an embedded boundary index space fo...
Definition: AMReX/cutcell/PatchHierarchy.hpp:112
void Print(Log &log)
Definition: AMReX/cutcell/PatchHierarchy.hpp:124
PatchHierarchyOptions(const ProgramOptions &options)
Definition: AMReX/cutcell/PatchHierarchy.hpp:114
This class holds state data arrays for each refinement level of a patch hierarchy.
Definition: AMReX/cutcell/PatchHierarchy.hpp:57
MultiCutFabs shielded_left
Store singly shielded from left face fractions for all faces which touch a cut cell.
Definition: AMReX/cutcell/PatchHierarchy.hpp:98
std::array< std::shared_ptr<::amrex::MultiCutFab >, AMREX_SPACEDIM > MultiCutFabs
Definition: AMReX/cutcell/PatchHierarchy.hpp:87
PatchLevel(PatchLevel &&) noexcept=default
Moves a patch level without any allocations happening.
MultiCutFabs doubly_shielded
Store doubly shielded face fractions for all faces which touch a cut cell.
Definition: AMReX/cutcell/PatchHierarchy.hpp:106
PatchLevel(const PatchLevel &)
Deeply copy a patch level on each MPI Rank and recompute shielded fractions.
PatchLevel & operator=(const PatchLevel &)
Deeply copy a patch level on each MPI Rank and recompute shielded fractions.
MultiCutFabs unshielded
Store unshielded face fractions for all faces which touch a cut cell.
Definition: AMReX/cutcell/PatchHierarchy.hpp:94
MultiCutFabs shielded_right
Store singly shielded from right face fractions for all faces which touch a cut cell.
Definition: AMReX/cutcell/PatchHierarchy.hpp:102
std::shared_ptr<::amrex::EBFArrayBoxFactory > factory
This stores the EB factory for this refinement level.
Definition: AMReX/cutcell/PatchHierarchy.hpp:90