ObserveFields.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 <optional>
9 #include <string>
10 #include <vector>
11 
13 #include "DataStructures/DataBox/PrefixHelpers.hpp"
14 #include "DataStructures/DataBox/Tag.hpp"
15 #include "DataStructures/DataVector.hpp"
16 #include "DataStructures/Index.hpp"
19 #include "DataStructures/VariablesTag.hpp"
21 #include "Framework/ActionTesting.hpp"
22 #include "IO/Observer/ArrayComponentId.hpp"
23 #include "IO/Observer/ObservationId.hpp"
24 #include "IO/Observer/ObserverComponent.hpp"
26 #include "Options/Protocols/FactoryCreation.hpp"
27 #include "ParallelAlgorithms/EventsAndTriggers/Event.hpp"
28 #include "PointwiseFunctions/AnalyticSolutions/AnalyticSolution.hpp"
29 #include "PointwiseFunctions/AnalyticSolutions/Tags.hpp"
30 #include "Utilities/NoSuchType.hpp"
31 #include "Utilities/ProtocolHelpers.hpp"
32 #include "Utilities/TMPL.hpp"
33 #include "Utilities/TaggedTuple.hpp"
34 
35 /// \cond
36 namespace PUP {
37 class er;
38 } // namespace PUP
39 namespace Parallel {
40 template <typename Metavariables>
41 class GlobalCache;
42 } // namespace Parallel
43 namespace observers::Actions {
44 struct ContributeVolumeData;
45 } // namespace observers::Actions
46 /// \endcond
47 
48 namespace TestHelpers::dg::Events::ObserveFields {
50  using type = double;
51 };
52 
54  struct Results {
55  observers::ObservationId observation_id{};
56  std::string subfile_name{};
57  observers::ArrayComponentId array_component_id{};
58  std::vector<TensorComponent> in_received_tensor_data{};
59  std::vector<size_t> received_extents{};
60  std::vector<Spectral::Basis> received_basis{};
61  std::vector<Spectral::Quadrature> received_quadrature{};
62  };
63  static Results results;
64 
65  template <typename ParallelComponent, typename... DbTags,
66  typename Metavariables, typename ArrayIndex, size_t Dim>
67  static void apply(db::DataBox<tmpl::list<DbTags...>>& /*box*/,
69  const ArrayIndex& /*array_index*/,
70  const observers::ObservationId& observation_id,
71  const std::string& subfile_name,
72  const observers::ArrayComponentId& array_component_id,
73  std::vector<TensorComponent>&& in_received_tensor_data,
74  const Index<Dim>& received_extents,
75  const std::array<Spectral::Basis, Dim>& received_basis,
77  received_quadrature) noexcept {
78  results.observation_id = observation_id;
79  results.subfile_name = subfile_name;
80  results.array_component_id = array_component_id;
81  results.in_received_tensor_data = in_received_tensor_data;
82  results.received_extents.assign(received_extents.indices().begin(),
83  received_extents.indices().end());
84  results.received_basis.assign(received_basis.begin(), received_basis.end());
85  results.received_quadrature.assign(received_quadrature.begin(),
86  received_quadrature.end());
87  }
88 };
89 
90 inline MockContributeVolumeData::Results MockContributeVolumeData::results{};
91 
92 template <typename Metavariables>
94  using component_being_mocked = void;
95 
99  using phase_dependent_action_list =
100  tmpl::list<Parallel::PhaseActions<typename Metavariables::Phase,
101  Metavariables::Phase::Initialization,
102  tmpl::list<>>>;
103 };
104 
105 template <typename Metavariables>
108  using replace_these_simple_actions =
109  tmpl::list<observers::Actions::ContributeVolumeData>;
110  using with_these_simple_actions = tmpl::list<MockContributeVolumeData>;
111 
114  using array_index = int;
115  using phase_dependent_action_list =
116  tmpl::list<Parallel::PhaseActions<typename Metavariables::Phase,
117  Metavariables::Phase::Initialization,
118  tmpl::list<>>>;
119 };
120 
121 template <typename System, bool HasAnalyticSolution>
123  using system = System;
124  using component_list = tmpl::list<ElementComponent<Metavariables>,
126  using const_global_cache_tags =
127  tmpl::list<Tags::AnalyticSolution<typename System::solution_for_test>>;
128  using initial_data =
129  tmpl::conditional_t<HasAnalyticSolution,
130  typename System::solution_for_test, NoSuchType>;
132  : tt::ConformsTo<Options::protocols::FactoryCreation> {
133  using factory_classes =
134  tmpl::map<tmpl::pair<Event, tmpl::list<typename system::ObserveEvent>>>;
135  };
136  enum class Phase { Initialization, Testing, Exit };
137 };
138 
139 // Test systems
140 
141 template <template <size_t, class...> class ObservationEvent>
142 struct ScalarSystem {
144  static std::string name() noexcept { return "Scalar"; }
145  using type = Scalar<DataVector>;
146  };
147 
148  static constexpr size_t volume_dim = 1;
150 
151  template <typename CheckComponent>
152  static void check_data(const CheckComponent& check_component) noexcept {
153  check_component("Scalar", ScalarVar{});
154  }
155 
156  using all_vars_for_test = tmpl::list<ScalarVar>;
157  struct solution_for_test : public MarkAsAnalyticSolution {
158  using vars_for_test = typename variables_tag::tags_list;
159 
160  template <typename CheckComponent>
161  static void check_data(const CheckComponent& check_component) noexcept {
162  check_component("Error(Scalar)", ScalarVar{});
163  }
164  static tuples::tagged_tuple_from_typelist<vars_for_test> variables(
165 
166  const tnsr::I<DataVector, 1>& x, const double t,
167  const vars_for_test /*meta*/) noexcept {
168  return {Scalar<DataVector>{1.0 - t * get<0>(x)}};
169  }
170 
171  void pup(PUP::er& /*p*/) noexcept {} // NOLINT
172  };
173 
174  using ObserveEvent =
175  ObservationEvent<volume_dim, ObservationTimeTag, all_vars_for_test,
176  typename solution_for_test::vars_for_test>;
177  static constexpr auto creation_string_for_test =
178  "ObserveFields:\n"
179  " SubfileName: element_data\n"
180  " VariablesToObserve: [Scalar]\n";
181  static ObserveEvent make_test_object(
182  const std::optional<Mesh<volume_dim>>& interpolating_mesh) noexcept {
183  return ObserveEvent{"element_data", {"Scalar"}, interpolating_mesh};
184  }
185 };
186 
187 template <template <size_t, class...> class ObservationEvent>
190  static std::string name() noexcept { return "Scalar"; }
191  using type = Scalar<DataVector>;
192  };
193 
195  static std::string name() noexcept { return "Vector"; }
196  using type = tnsr::I<DataVector, 2>;
197  };
198 
200  static std::string name() noexcept { return "Tensor"; }
201  using type = tnsr::ii<DataVector, 2>;
202  };
203 
205  static std::string name() noexcept { return "Tensor2"; }
206  using type = tnsr::ii<DataVector, 2>;
207  };
208 
210  static std::string name() noexcept { return "Unobserved"; }
211  using type = Scalar<DataVector>;
212  };
213 
215  static std::string name() noexcept { return "Unobserved2"; }
216  using type = Scalar<DataVector>;
217  };
218 
219  static constexpr size_t volume_dim = 2;
220  using variables_tag =
224 
225  template <typename CheckComponent>
226  static void check_data(const CheckComponent& check_component) noexcept {
227  check_component("Scalar", ScalarVar{});
228  check_component("Tensor_xx", TensorVar{}, 0, 0);
229  check_component("Tensor_yx", TensorVar{}, 0, 1);
230  check_component("Tensor_yy", TensorVar{}, 1, 1);
231  check_component("Vector_x", VectorVar{}, 0);
232  check_component("Vector_y", VectorVar{}, 1);
233  check_component("Tensor2_xx", TensorVar2{}, 0, 0);
234  check_component("Tensor2_yx", TensorVar2{}, 0, 1);
235  check_component("Tensor2_yy", TensorVar2{}, 1, 1);
236  }
237 
238  using all_vars_for_test = tmpl::list<TensorVar, ScalarVar, UnobservedVar,
239  VectorVar, TensorVar2, UnobservedVar2>;
240  struct solution_for_test : public MarkAsAnalyticSolution {
241  using vars_for_test = typename primitive_variables_tag::tags_list;
242 
243  template <typename CheckComponent>
244  static void check_data(const CheckComponent& check_component) noexcept {
245  check_component("Error(Vector)_x", VectorVar{}, 0);
246  check_component("Error(Vector)_y", VectorVar{}, 1);
247  check_component("Error(Tensor2)_xx", TensorVar2{}, 0, 0);
248  check_component("Error(Tensor2)_yx", TensorVar2{}, 0, 1);
249  check_component("Error(Tensor2)_yy", TensorVar2{}, 1, 1);
250  }
251 
252  static tuples::tagged_tuple_from_typelist<vars_for_test> variables(
253  const tnsr::I<DataVector, 2>& x, const double t,
254  const vars_for_test /*meta*/) noexcept {
255  auto vector = make_with_value<tnsr::I<DataVector, 2>>(x, 0.0);
256  auto tensor = make_with_value<tnsr::ii<DataVector, 2>>(x, 0.0);
257  auto unobserved = make_with_value<Scalar<DataVector>>(x, 0.0);
258  // Arbitrary functions
259  get<0>(vector) = 1.0 - t * get<0>(x);
260  get<1>(vector) = 1.0 - t * get<1>(x);
261  get<0, 0>(tensor) = get<0>(x) + get<1>(x);
262  get<0, 1>(tensor) = get<0>(x) - get<1>(x);
263  get<1, 1>(tensor) = get<0>(x) * get<1>(x);
264  get(unobserved) = 2.0 * get<0>(x);
265  return {std::move(vector), std::move(tensor), std::move(unobserved)};
266  }
267 
268  void pup(PUP::er& /*p*/) noexcept {} // NOLINT
269  };
270 
271  using ObserveEvent =
272  ObservationEvent<volume_dim, ObservationTimeTag, all_vars_for_test,
273  typename solution_for_test::vars_for_test>;
274  static constexpr auto creation_string_for_test =
275  "ObserveFields:\n"
276  " SubfileName: element_data\n"
277  " VariablesToObserve: [Scalar, Vector, Tensor, Tensor2]\n";
278 
279  static ObserveEvent make_test_object(
280  const std::optional<Mesh<volume_dim>>& interpolating_mesh) noexcept {
281  return ObserveEvent("element_data",
282  {"Scalar", "Vector", "Tensor", "Tensor2"},
283  interpolating_mesh);
284  }
285 };
286 } // namespace TestHelpers::dg::Events::ObserveFields
NoSuchType
Used to mark "no type" or "bad state" for metaprogramming.
Definition: NoSuchType.hpp:10
observers::ObservationId
A unique identifier for an observation representing the type of observation and the instance (e....
Definition: ObservationId.hpp:71
TestHelpers::dg::Events::ObserveFields::Metavariables
Definition: ObserveFields.hpp:122
std::string
ActionTesting::MockGroupChare
A mock class for the CMake-generated Parallel::Algorithms::Group
Definition: ActionTesting.hpp:657
Parallel::GlobalCache
Definition: ElementReceiveInterpPoints.hpp:15
TestHelpers::dg::Events::ObserveFields::ScalarSystem
Definition: ObserveFields.hpp:142
vector
TestHelpers::dg::Events::ObserveFields::MockContributeVolumeData
Definition: ObserveFields.hpp:53
Tags::Variables
Definition: VariablesTag.hpp:21
TestHelpers::dg::Events::ObserveFields::ComplicatedSystem::solution_for_test
Definition: ObserveFields.hpp:240
db::get
const auto & get(const DataBox< TagList > &box) noexcept
Retrieve the item with tag Tag from the DataBox.
Definition: DataBox.hpp:791
Index
Definition: Index.hpp:31
db::SimpleTag
Mark a struct as a simple tag by inheriting from this.
Definition: Tag.hpp:36
Spectral.hpp
TestHelpers::dg::Events::ObserveFields::Metavariables::factory_creation
Definition: ObserveFields.hpp:131
TestHelpers::dg::Events::ObserveFields::MockObserverComponent
Definition: ObserveFields.hpp:106
TestHelpers::dg::Events::ObserveFields::ComplicatedSystem::TensorVar2
Definition: ObserveFields.hpp:204
ElementId
An ElementId uniquely labels an Element.
Definition: ElementId.hpp:51
ElementId.hpp
TestHelpers::dg::Events::ObserveFields::MockContributeVolumeData::Results
Definition: ObserveFields.hpp:54
Parallel::PhaseActions
List of all the actions to be executed in the specified phase.
Definition: PhaseDependentActionList.hpp:16
TestHelpers::dg::Events::ObserveFields::ScalarSystem::solution_for_test
Definition: ObserveFields.hpp:157
TestHelpers::dg::Events::ObserveFields::ComplicatedSystem::UnobservedVar2
Definition: ObserveFields.hpp:214
DataBox.hpp
cstddef
TestHelpers::dg::Events::ObserveFields::ComplicatedSystem::UnobservedVar
Definition: ObserveFields.hpp:209
TestHelpers::dg::Events::ObserveFields::ComplicatedSystem::VectorVar
Definition: ObserveFields.hpp:194
array
Index.hpp
observers::Observer
The group parallel component that is responsible for reducing data to be observed.
Definition: ObserverComponent.hpp:29
ActionTesting::MockArrayChare
A mock class for the CMake-generated Parallel::Algorithms::Array
Definition: ActionTesting.hpp:649
Variables.hpp
TestHelpers::dg::Events::ObserveFields::ElementComponent
Definition: ObserveFields.hpp:93
Mesh
Holds the number of grid points, basis, and quadrature in each direction of the computational grid.
Definition: Mesh.hpp:49
Scalar
Tensor< T, Symmetry<>, index_list<> > Scalar
Definition: TypeAliases.hpp:21
Tensor.hpp
TestHelpers::dg::Events::ObserveFields::ObservationTimeTag
Definition: ObserveFields.hpp:49
TestHelpers::dg::Events::ObserveFields::ComplicatedSystem::ScalarVar
Definition: ObserveFields.hpp:189
optional
observers::ArrayComponentId
An ID type that identifies both the parallel component and the index in the parallel component.
Definition: ArrayComponentId.hpp:27
TestHelpers::dg::Events::ObserveFields::ComplicatedSystem::TensorVar
Definition: ObserveFields.hpp:199
observers::Actions
Actions used by the observer parallel component
Definition: GetLockPointer.hpp:13
tt::ConformsTo
Indicate a class conforms to the Protocol.
Definition: ProtocolHelpers.hpp:22
Parallel
Functionality for parallelization.
Definition: ElementReceiveInterpPoints.hpp:13
TestHelpers::dg::Events::ObserveFields::ScalarSystem::ScalarVar
Definition: ObserveFields.hpp:143
TMPL.hpp
TestHelpers::dg::Events::ObserveFields::ComplicatedSystem
Definition: ObserveFields.hpp:188
string