MinmodHelpers.hpp
1 // Distributed under the MIT License.
2 // See LICENSE.txt for details.
3 
4 #pragma once
5 
6 #include <array>
7 #include <cstdlib>
8 #include <memory>
9 #include <unordered_map>
10 #include <utility>
11 
12 #include "DataStructures/Tags.hpp" // IWYU pragma: keep
13 #include "Domain/Direction.hpp"
14 #include "Domain/DirectionMap.hpp"
15 #include "Utilities/Gsl.hpp"
17 
18 /// \cond
19 class DataVector;
20 template <size_t VolumeDim>
21 class Element;
22 template <size_t VolumeDim>
23 class ElementId;
24 template <size_t VolumeDim>
25 class Mesh;
26 
27 namespace boost {
28 template <class T>
29 struct hash;
30 } // namespace boost
31 /// \endcond
32 
33 namespace SlopeLimiters {
34 namespace Minmod_detail {
35 
36 // Allocate the buffers `u_lin_buffer` and `boundary_buffer` to the correct
37 // sizes expected by `troubled_cell_indicator` for its arguments
38 template <size_t VolumeDim>
39 void allocate_buffers(
40  gsl::not_null<std::unique_ptr<double[], decltype(&free)>*>
41  contiguous_buffer,
42  gsl::not_null<DataVector*> u_lin_buffer,
44  const Mesh<VolumeDim>& mesh) noexcept;
45 
46 // In each direction, average the size of all different neighbors in that
47 // direction. Note that only the component of neighor_size that is normal
48 // to the face is needed (and, therefore, computed).
49 //
50 // Expects type `PackagedData` to contain a variable `element_size` that is a
51 // `std::array<double, VolumeDim>`.
52 template <size_t VolumeDim, typename PackagedData>
53 DirectionMap<VolumeDim, double> compute_effective_neighbor_sizes(
54  const Element<VolumeDim>& element,
55  const std::unordered_map<
58  neighbor_data) noexcept {
60  for (const auto& dir : Direction<VolumeDim>::all_directions()) {
61  const auto& externals = element.external_boundaries();
62  const bool neighbors_in_this_dir = (externals.find(dir) == externals.end());
63  if (neighbors_in_this_dir) {
64  const double effective_neighbor_size =
65  [&dir, &element, &neighbor_data ]() noexcept {
66  const size_t dim = dir.dimension();
67  const auto& neighbor_ids = element.neighbors().at(dir).ids();
68  double size_accumulate = 0.;
69  for (const auto& id : neighbor_ids) {
70  size_accumulate += gsl::at(
71  neighbor_data.at(std::make_pair(dir, id)).element_size, dim);
72  }
73  return size_accumulate / neighbor_ids.size();
74  }
75  ();
76  result.insert(std::make_pair(dir, effective_neighbor_size));
77  }
78  }
79  return result;
80 }
81 
82 // In each direction, average the mean of the specified tensor component over
83 // all different neighbors that direction. This produces one effective neighbor
84 // per direction.
85 //
86 // Expects type `PackagedData` to contain a variable `means` that is a
87 // `TaggedTuple<Tags::Mean<Tags>...>`. Tags... must contain Tag, the tag
88 // specifying the tensor to work with.
89 template <typename Tag, size_t VolumeDim, typename PackagedData>
90 DirectionMap<VolumeDim, double> compute_effective_neighbor_means(
91  const Element<VolumeDim>& element, const size_t tensor_storage_index,
92  const std::unordered_map<
95  neighbor_data) noexcept {
97  for (const auto& dir : Direction<VolumeDim>::all_directions()) {
98  const auto& externals = element.external_boundaries();
99  const bool neighbors_in_this_dir = (externals.find(dir) == externals.end());
100  if (neighbors_in_this_dir) {
101  const double effective_neighbor_mean =
102  [&dir, &element, &neighbor_data, &tensor_storage_index ]() noexcept {
103  const auto& neighbor_ids = element.neighbors().at(dir).ids();
104  double mean_accumulate = 0.0;
105  for (const auto& id : neighbor_ids) {
106  mean_accumulate += tuples::get<::Tags::Mean<Tag>>(
107  neighbor_data.at(std::make_pair(dir, id))
108  .means)[tensor_storage_index];
109  }
110  return mean_accumulate / neighbor_ids.size();
111  }
112  ();
113  result.insert(std::make_pair(dir, effective_neighbor_mean));
114  }
115  }
116  return result;
117 }
118 
119 } // namespace Minmod_detail
120 } // namespace SlopeLimiters
Defines class template Direction.
Defines class tuples::TaggedTuple.
Definition: BoostMultiArray.hpp:11
An ElementId uniquely labels an Element. It is constructed from the BlockId of the Block to which the...
Definition: ElementId.hpp:36
An optimized map with Direction keys.
Definition: DirectionMap.hpp:15
Holds the number of grid points, basis, and quadrature in each direction of the computational grid...
Definition: Mesh.hpp:49
A particular Side along a particular coordinate Axis.
Definition: Direction.hpp:23
Things relating to slope limiting.
Definition: Krivodonova.hpp:52
A spectral element with knowledge of its neighbors.
Definition: Element.hpp:29
Stores a collection of function values.
Definition: DataVector.hpp:42
Defines functions and classes from the GSL.
std::pair< iterator, bool > insert(const value_type &value) noexcept
Inserts the element if it does not exists.
Definition: FixedHashMap.hpp:131
Require a pointer to not be a nullptr
Definition: ConservativeFromPrimitive.hpp:12
constexpr T & at(std::array< T, N > &arr, Size index)
Retrieve a entry from a container, with checks in Debug mode that the index being retrieved is valid...
Definition: Gsl.hpp:124