FilterAction.hpp
1 // Distributed under the MIT License.
2 // See LICENSE.txt for details.
3 
4 #pragma once
5 
6 #include <array>
7 #include <cstddef>
8 #include <string>
9 #include <tuple>
10 
12 #include "DataStructures/DataVector.hpp"
14 #include "Domain/Mesh.hpp"
15 #include "Domain/Tags.hpp"
16 #include "ErrorHandling/Error.hpp"
17 #include "NumericalAlgorithms/LinearOperators/ApplyMatrices.hpp"
18 #include "NumericalAlgorithms/LinearOperators/Tags.hpp"
20 #include "Utilities/Gsl.hpp"
21 #include "Utilities/StdHelpers.hpp"
22 #include "Utilities/TMPL.hpp"
23 #include "Utilities/TypeTraits.hpp"
24 
25 namespace dg {
26 namespace Actions {
27 namespace Filter_detail {
28 template <bool SameSize, bool SameList>
29 struct FilterAllEvolvedVars {
30  template <typename EvolvedVarsTagList, typename... FilterTags>
32 };
33 
34 template <>
35 struct FilterAllEvolvedVars<true, false> {
36  template <typename EvolvedVarsTagList, typename... FilterTags>
37  using f =
38  std::integral_constant<bool, tmpl2::flat_all_v<tmpl::list_contains_v<
39  EvolvedVarsTagList, FilterTags>...>>;
40 };
41 
42 template <>
43 struct FilterAllEvolvedVars<true, true> {
44  template <typename EvolvedVarsTagList, typename... FilterTags>
46 };
47 } // namespace Filter_detail
48 
49 /// \cond
50 template <typename FilterType, typename TagsToFilterList>
51 struct Filter;
52 /// \endcond
53 
54 /*!
55  * \ingroup DiscontinuousGalerkinGroup
56  * \brief Applies a filter to the specified tags.
57  *
58  * If different Filters are desired for different tags then multiple `Filter`
59  * actions must be inserted into the action list with different `FilterType`.
60  * Here is an example of an action list with two different exponential filters:
61  *
62  * \snippet LinearOperators/Test_Filtering.cpp action_list_example
63  *
64  * Uses:
65  * - ConstGlobalCache:
66  * - `Filter`
67  * - DataBox:
68  * - `Tags::Mesh`
69  * - DataBox changes:
70  * - Adds: nothing
71  * - Removes: nothing
72  * - Modifies:
73  * - `TagsToFilter`
74  * - System:
75  * - `volume_dim`
76  * - `variables_tag`
77  *
78  */
79 template <typename FilterType, typename... TagsToFilter>
80 class Filter<FilterType, tmpl::list<TagsToFilter...>> {
81  public:
82  using const_global_cache_tags =
83  tmpl::list<::Filters::Tags::Filter<FilterType>>;
84 
85  template <typename DbTags, typename... InboxTags, typename ArrayIndex,
86  typename ActionList, typename ParallelComponent,
87  typename Metavariables>
90  const tuples::TaggedTuple<InboxTags...>& /*inboxes*/,
92  const ArrayIndex& /*array_index*/, const ActionList /*meta*/,
93  const ParallelComponent* const /*meta*/) noexcept {
94  constexpr size_t volume_dim = Metavariables::system::volume_dim;
95  using evolved_vars_tag = typename Metavariables::system::variables_tag;
96  using evolved_vars_tags_list = typename evolved_vars_tag::tags_list;
97  const FilterType& filter_helper =
98  Parallel::get<::Filters::Tags::Filter<FilterType>>(cache);
99  if (UNLIKELY(filter_helper.disable_for_debugging())) {
100  return {std::move(box)};
101  }
102  const Mesh<volume_dim> mesh = db::get<::Tags::Mesh<volume_dim>>(box);
103  const Matrix empty{};
104  auto filter = make_array<volume_dim>(std::cref(empty));
105  for (size_t d = 0; d < volume_dim; d++) {
106  gsl::at(filter, d) =
107  std::cref(filter_helper.filter_matrix(mesh.slice_through(d)));
108  }
109 
110  // In the case that the tags we are filtering are all the evolved variables
111  // we filter the entire Variables at once to be more efficient. This case is
112  // the first branch of the `if-else`.
113  if (Filter_detail::FilterAllEvolvedVars<
114  sizeof...(TagsToFilter) ==
115  tmpl::size<evolved_vars_tags_list>::value,
116  cpp17::is_same_v<evolved_vars_tags_list,
117  tmpl::list<TagsToFilter...>>>::
118  template f<evolved_vars_tags_list, TagsToFilter...>::value) {
119  db::mutate<typename Metavariables::system::variables_tag>(
120  make_not_null(&box),
121  [&filter](
122  const gsl::not_null<
124  vars,
125  const auto& local_mesh) noexcept {
126  *vars = apply_matrices(filter, *vars, local_mesh.extents());
127  },
128  mesh);
129  } else {
130  db::mutate<TagsToFilter...>(
131  make_not_null(&box),
132  [&filter](const gsl::not_null<
133  db::item_type<TagsToFilter>*>... tensors_to_filter,
134  const auto& local_mesh) noexcept {
135  DataVector temp(local_mesh.number_of_grid_points(), 0.0);
136  const auto helper =
137  [&local_mesh, &filter, &temp ](const auto tensor) noexcept {
138  for (auto& component : *tensor) {
139  temp = 0.0;
140  apply_matrices(make_not_null(&temp), filter, component,
141  local_mesh.extents());
142  component = temp;
143  }
144  };
145  EXPAND_PACK_LEFT_TO_RIGHT(helper(tensors_to_filter));
146  },
147  mesh);
148  }
149  return {std::move(box)};
150  }
151 };
152 } // namespace Actions
153 } // namespace dg
Defines class Matrix.
Defines helper functions for the standard library.
void mutate(const gsl::not_null< DataBox< TagList > *> box, Invokable &&invokable, Args &&... args) noexcept
Allows changing the state of one or more non-computed elements in the DataBox.
Definition: DataBox.hpp:1092
#define EXPAND_PACK_LEFT_TO_RIGHT(...)
Expand a parameter pack evaluating the terms from left to right.
Definition: TMPL.hpp:562
constexpr bool flat_all_v
A non-short-circuiting logical AND between bools &#39;B"".
Definition: TMPL.hpp:505
Definition: Digraph.hpp:11
#define UNLIKELY(x)
Definition: Gsl.hpp:72
Definition: ApplyBoundaryFluxesLocalTimeStepping.hpp:33
Holds the number of grid points, basis, and quadrature in each direction of the computational grid...
Definition: Mesh.hpp:49
void apply_matrices(const gsl::not_null< Variables< VariableTags > *> result, const std::array< MatrixType, Dim > &matrices, const Variables< VariableTags > &u, const Index< Dim > &extents) noexcept
Multiply by matrices in each dimension.
Definition: ApplyMatrices.hpp:67
Mesh< sizeof...(D)> slice_through(D... d) const noexcept
Returns a Mesh with the dimensions d, ... present (zero-indexed).
Definition: Mesh.hpp:186
An associative container that is indexed by structs.
Definition: TaggedTuple.hpp:273
Defines classes and functions used for manipulating DataBox&#39;s.
constexpr bool is_same_v
Variable template for is_same.
Definition: TypeTraits.hpp:221
A dynamically sized matrix of doubles with column-major storage.
Definition: Matrix.hpp:19
Definition: InterpolationTargetWedgeSectionTorus.hpp:24
A Charm++ chare that caches constant data once per Charm++ node.
Definition: ConstGlobalCache.hpp:135
Defines the class template Mesh.
constexpr auto apply(F &&f, const DataBox< BoxTags > &box, Args &&... args) noexcept
Apply the invokable f with argument Tags TagsList from DataBox box
Definition: DataBox.hpp:1623
Stores a collection of function values.
Definition: DataVector.hpp:42
Wraps the template metaprogramming library used (brigand)
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:461
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 tags related to domain quantities.
Defines class template ConstGlobalCache.
Defines macro ERROR.
Defines type traits, some of which are future STL type_traits header.
Definition: ComputeTimeDerivative.hpp:28
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