SimpleWenoImpl.hpp
1 // Distributed under the MIT License.
2 // See LICENSE.txt for details.
3 
4 #pragma once
5 
6 #include <array>
7 #include <boost/functional/hash.hpp> // IWYU pragma: keep
8 #include <cstddef>
9 #include <limits>
10 #include <string>
11 #include <type_traits>
12 #include <unordered_map>
13 #include <utility>
14 
18 #include "Domain/Direction.hpp"
19 #include "Domain/Element.hpp"
20 #include "Domain/ElementId.hpp"
21 #include "Domain/Mesh.hpp"
22 #include "Evolution/DiscontinuousGalerkin/Limiters/WenoGridHelpers.hpp"
23 #include "Evolution/DiscontinuousGalerkin/Limiters/WenoHelpers.hpp"
24 #include "Evolution/DiscontinuousGalerkin/Limiters/WenoOscillationIndicator.hpp"
25 #include "NumericalAlgorithms/Interpolation/RegularGridInterpolant.hpp"
27 #include "Utilities/Gsl.hpp"
28 
29 namespace Limiters {
30 namespace Weno_detail {
31 
32 // Compute the Simple WENO solution for one tensor component
33 //
34 // This interface is intended for use in limiters that check the troubled-cell
35 // indicator independently for each tensor component. These limiters generally
36 // need to limit only a subset of the tensor components.
37 template <typename Tag, size_t VolumeDim, typename PackagedData>
38 void simple_weno_impl(
43  interpolator_buffer,
47  modified_neighbor_solution_buffer,
48  const gsl::not_null<db::item_type<Tag>*> tensor,
49  const double neighbor_linear_weight, const size_t tensor_storage_index,
50  const Mesh<VolumeDim>& mesh, const Element<VolumeDim>& element,
51  const std::unordered_map<
54  neighbor_data) noexcept {
55  // Compute the modified neighbor solutions.
56  // First extrapolate neighbor data onto local grid points, then shift the
57  // extrapolated data so its mean matches the local mean.
58  DataVector& component_to_limit = (*tensor)[tensor_storage_index];
59  const double local_mean = mean_value(component_to_limit, mesh);
60  for (const auto& neighbor_and_data : neighbor_data) {
61  const auto& neighbor = neighbor_and_data.first;
62  const auto& data = neighbor_and_data.second;
63 
64  if (interpolator_buffer->find(neighbor) == interpolator_buffer->end()) {
65  // No interpolator found => create one
66  const auto& direction = neighbor.first;
67  const auto& source_mesh = data.mesh;
68  const auto target_1d_logical_coords =
69  Weno_detail::local_grid_points_in_neighbor_logical_coords(
70  mesh, source_mesh, element, direction);
71  interpolator_buffer->insert(std::make_pair(
72  neighbor, intrp::RegularGrid<VolumeDim>(source_mesh, mesh,
73  target_1d_logical_coords)));
74  }
75 
76  // Avoid allocations by working directly in the preallocated buffer
77  DataVector& buffer = modified_neighbor_solution_buffer->at(neighbor);
78 
79  interpolator_buffer->at(neighbor).interpolate(
80  make_not_null(&buffer),
81  get<Tag>(data.volume_data)[tensor_storage_index]);
82  const double neighbor_mean = mean_value(buffer, mesh);
83  buffer += (local_mean - neighbor_mean);
84  }
85 
86  // Sum local and modified neighbor polynomials for the WENO reconstruction
87  Weno_detail::reconstruct_from_weighted_sum(
88  make_not_null(&component_to_limit), neighbor_linear_weight,
89  Weno_detail::DerivativeWeight::PowTwoEll, mesh,
90  *modified_neighbor_solution_buffer);
91 }
92 
93 // Compute the Simple WENO solution for one tensor
94 //
95 // This interface is intended for use in limiters that check the troubled-cell
96 // indicator for the whole cell, and apply the limiter to all fields.
97 template <typename Tag, size_t VolumeDim, typename PackagedData>
98 void simple_weno_impl(
103  interpolator_buffer,
107  modified_neighbor_solution_buffer,
108  const gsl::not_null<db::item_type<Tag>*> tensor,
109  const double neighbor_linear_weight, const Mesh<VolumeDim>& mesh,
110  const Element<VolumeDim>& element,
111  const std::unordered_map<
114  neighbor_data) noexcept {
115  for (size_t tensor_storage_index = 0; tensor_storage_index < tensor->size();
116  ++tensor_storage_index) {
117  simple_weno_impl<Tag>(interpolator_buffer,
118  modified_neighbor_solution_buffer, tensor,
119  neighbor_linear_weight, tensor_storage_index, mesh,
120  element, neighbor_data);
121  }
122 }
123 
124 } // namespace Weno_detail
125 } // namespace Limiters
Defines class template Direction.
An ElementId uniquely labels an Element. It is constructed from the BlockId of the Block to which the...
Definition: ElementId.hpp:36
Defines class ElementId.
T data(T... args)
A particular Side along a particular coordinate Axis.
Definition: Direction.hpp:23
double mean_value(const DataVector &f, const Mesh< Dim > &mesh) noexcept
Compute the mean value of a function over a manifold.
Definition: MeanValue.hpp:47
A spectral element with knowledge of its neighbors.
Definition: Element.hpp:29
Defines class Variables.
Interpolate data from a Mesh onto a regular grid of points.
Definition: RegularGridInterpolant.hpp:46
Defines the class template Mesh.
Defines classes for Tensor.
Stores a collection of function values.
Definition: DataVector.hpp:42
typename DataBox_detail::item_type_impl< TagList, Tag >::type item_type
Get the type that can be written to the Tag. If it is a base tag then a TagList must be passed as a s...
Definition: DataBoxTag.hpp:246
Defines functions and classes from the GSL.
gsl::not_null< T * > make_not_null(T *ptr) noexcept
Construct a not_null from a pointer. Often this will be done as an implicit conversion, but it may be necessary to perform the conversion explicitly when type deduction is desired.
Definition: Gsl.hpp:879
Defines functions mean_value and mean_value_on_boundary.
Things relating to limiting.
Definition: HwenoImpl.cpp:109
Defines classes SimpleTag, PrefixTag, ComputeTag and several functions for retrieving tag info...
Require a pointer to not be a nullptr
Definition: Gsl.hpp:182
Defines class Element.