ElementActions.hpp
1 // Distributed under the MIT License.
2 // See LICENSE.txt for details.
3 
4 #pragma once
5 
6 #include <cstddef>
7 #include <map>
8 #include <string>
9 #include <tuple>
10 #include <unordered_map>
11 #include <utility>
12 #include <vector>
13 
15 #include "DataStructures/DataBox/PrefixHelpers.hpp"
16 #include "DataStructures/DataBox/Tag.hpp"
17 #include "DataStructures/Index.hpp"
18 #include "Domain/InterfaceComputeTags.hpp"
19 #include "Domain/InterfaceHelpers.hpp"
22 #include "Domain/Structure/OrientationMapHelpers.hpp"
23 #include "Domain/Tags.hpp"
24 #include "IO/Observer/Actions/RegisterWithObservers.hpp"
25 #include "IO/Observer/ArrayComponentId.hpp"
26 #include "IO/Observer/ObservationId.hpp"
27 #include "IO/Observer/Protocols/ReductionDataFormatter.hpp"
28 #include "IO/Observer/ReductionActions.hpp"
29 #include "IO/Observer/TypeOfObservation.hpp"
30 #include "Informer/Tags.hpp"
31 #include "Informer/Verbosity.hpp"
32 #include "NumericalAlgorithms/Convergence/Tags.hpp"
33 #include "NumericalAlgorithms/LinearSolver/ExplicitInverse.hpp"
34 #include "NumericalAlgorithms/LinearSolver/Gmres.hpp"
37 #include "Options/Options.hpp"
38 #include "Parallel/GlobalCache.hpp"
39 #include "Parallel/InboxInserters.hpp"
40 #include "Parallel/Invoke.hpp"
41 #include "Parallel/ParallelComponentHelpers.hpp"
42 #include "Parallel/Printf.hpp"
43 #include "Parallel/Reduction.hpp"
44 #include "ParallelAlgorithms/DiscontinuousGalerkin/HasReceivedFromAllMortars.hpp"
45 #include "ParallelAlgorithms/Initialization/MergeIntoDataBox.hpp"
46 #include "ParallelAlgorithms/Initialization/MutateAssign.hpp"
48 #include "ParallelAlgorithms/LinearSolver/Schwarz/ComputeTags.hpp"
49 #include "ParallelAlgorithms/LinearSolver/Schwarz/ElementCenteredSubdomainData.hpp"
50 #include "ParallelAlgorithms/LinearSolver/Schwarz/OverlapHelpers.hpp"
51 #include "ParallelAlgorithms/LinearSolver/Schwarz/Tags.hpp"
53 #include "Utilities/Gsl.hpp"
54 #include "Utilities/PrettyType.hpp"
55 #include "Utilities/ProtocolHelpers.hpp"
56 #include "Utilities/TMPL.hpp"
57 #include "Utilities/TaggedTuple.hpp"
58 
59 namespace LinearSolver::Schwarz::detail {
60 
61 using reduction_data = Parallel::ReductionData<
62  // Iteration
64  // Number of subdomains (= number of elements)
66  // Average number of subdomain solver iterations
69  // Minimum number of subdomain solver iterations
71  // Maximum number of subdomain solver iterations
73 
74 template <typename OptionsGroup>
75 struct SubdomainStatsFormatter
76  : tt::ConformsTo<observers::protocols::ReductionDataFormatter> {
77  using reduction_data = Schwarz::detail::reduction_data;
78  std::string operator()(const size_t iteration_id, const size_t num_subdomains,
79  const size_t avg_subdomain_its,
80  const size_t min_subdomain_its,
81  const size_t max_subdomain_its) const noexcept {
82  return Options::name<OptionsGroup>() + "(" + get_output(iteration_id) +
83  ") completed all " + get_output(num_subdomains) +
84  " subdomain solves. Average of number of iterations: " +
85  get_output(avg_subdomain_its) + " (min " +
86  get_output(min_subdomain_its) + ", max " +
87  get_output(max_subdomain_its) + ").";
88  }
89  // NOLINTNEXTLINE(google-runtime-references)
90  void pup(PUP::er& /*p*/) noexcept {}
91 };
92 
93 template <typename OptionsGroup>
94 struct RegisterObservers {
95  template <typename ParallelComponent, typename DbTagsList,
96  typename ArrayIndex>
98  register_info(const db::DataBox<DbTagsList>& /*box*/,
99  const ArrayIndex& /*array_index*/) noexcept {
101  observers::ObservationKey{pretty_type::get_name<OptionsGroup>() +
102  "SubdomainSolves"}};
103  }
104 };
105 
106 template <typename FieldsTag, typename OptionsGroup, typename SourceTag>
107 using RegisterElement =
109 
110 template <typename OptionsGroup, typename ParallelComponent,
111  typename Metavariables, typename ArrayIndex>
112 void contribute_to_subdomain_stats_observation(
113  const size_t iteration_id, const size_t subdomain_solve_num_iterations,
115  const ArrayIndex& array_index) noexcept {
116  auto& local_observer =
117  *Parallel::get_parallel_component<observers::Observer<Metavariables>>(
118  cache)
119  .ckLocalBranch();
120  auto formatter =
122  ::Verbosity::Verbose)
123  ? std::make_optional(SubdomainStatsFormatter<OptionsGroup>{})
124  : std::nullopt;
125  Parallel::simple_action<observers::Actions::ContributeReductionData>(
126  local_observer,
128  iteration_id,
129  pretty_type::get_name<OptionsGroup>() + "SubdomainSolves"),
132  Parallel::ArrayIndex<ArrayIndex>(array_index)},
133  std::string{"/" + Options::name<OptionsGroup>() + "SubdomainSolves"},
134  std::vector<std::string>{"Iteration", "NumSubdomains", "AvgNumIterations",
135  "MinNumIterations", "MaxNumIterations"},
136  reduction_data{iteration_id, 1, subdomain_solve_num_iterations,
137  subdomain_solve_num_iterations,
138  subdomain_solve_num_iterations},
139  std::move(formatter));
140 }
141 
142 template <typename SubdomainDataType, typename OptionsGroup>
143 struct SubdomainDataBufferTag : db::SimpleTag {
144  static std::string name() noexcept {
145  return "SubdomainData(" + Options::name<OptionsGroup>() + ")";
146  }
147  using type = SubdomainDataType;
148 };
149 
150 // Allow factory-creating any of these serial linear solvers for use as
151 // subdomain solver
152 template <typename FieldsTag, typename SubdomainOperator,
153  typename SubdomainData = ElementCenteredSubdomainData<
154  SubdomainOperator::volume_dim,
156  FieldsTag>::tags_list>>
157 using subdomain_solver = LinearSolver::Serial::LinearSolver<
158  tmpl::list<::LinearSolver::Serial::Registrars::Gmres<SubdomainData>,
160 
161 template <typename FieldsTag, typename OptionsGroup, typename SubdomainOperator>
162 struct InitializeElement {
163  private:
164  using fields_tag = FieldsTag;
165  using residual_tag =
167  static constexpr size_t Dim = SubdomainOperator::volume_dim;
168  using SubdomainData =
169  ElementCenteredSubdomainData<Dim, typename residual_tag::tags_list>;
170  using subdomain_solver_tag = Tags::SubdomainSolver<
172  OptionsGroup>;
173 
174  public:
175  using initialization_tags =
176  tmpl::list<domain::Tags::InitialExtents<Dim>, subdomain_solver_tag>;
177  using initialization_tags_to_keep = tmpl::list<subdomain_solver_tag>;
178  using const_global_cache_tags = tmpl::list<Tags::MaxOverlap<OptionsGroup>>;
179 
180  using simple_tags =
181  tmpl::list<Tags::Overlaps<residual_tag, Dim, OptionsGroup>,
182  SubdomainDataBufferTag<SubdomainData, OptionsGroup>>;
183  using compute_tags = tmpl::list<
191  Tags::IntrudingExtentsCompute<Dim, OptionsGroup>,
192  Tags::IntrudingOverlapWidthsCompute<Dim, OptionsGroup>,
194  Tags::ElementWeightCompute<Dim, OptionsGroup>,
197  Tags::IntrudingOverlapWeightCompute<Dim, OptionsGroup>>>;
198  template <typename DbTagsList, typename... InboxTags, typename Metavariables,
199  typename ActionList, typename ParallelComponent>
200  static auto apply(db::DataBox<DbTagsList>& box,
201  const tuples::TaggedTuple<InboxTags...>& /*inboxes*/,
202  const Parallel::GlobalCache<Metavariables>& /*cache*/,
203  const ElementId<Dim>& /*element_id*/,
204  const ActionList /*meta*/,
205  const ParallelComponent* const /*meta*/) noexcept {
206  const auto& element_mesh = db::get<domain::Tags::Mesh<Dim>>(box);
207  const size_t element_num_points = element_mesh.number_of_grid_points();
209  tmpl::list<SubdomainDataBufferTag<SubdomainData, OptionsGroup>>>(
210  make_not_null(&box), SubdomainData{element_num_points});
211  return std::make_tuple(std::move(box));
212  }
213 };
214 
215 // Restrict the residual to neighboring subdomains that overlap with this
216 // element and send the data to those elements
217 template <typename FieldsTag, typename OptionsGroup, typename SubdomainOperator>
219  tmpl::list<db::add_tag_prefix<LinearSolver::Tags::Residual, FieldsTag>>,
220  OptionsGroup, true>;
221 
222 // Wait for the residual data on regions of this element's subdomain that
223 // overlap with other elements.
224 template <typename FieldsTag, typename OptionsGroup, typename SubdomainOperator>
226  SubdomainOperator::volume_dim,
227  tmpl::list<db::add_tag_prefix<LinearSolver::Tags::Residual, FieldsTag>>,
228  OptionsGroup>;
229 
230 template <size_t Dim, typename OptionsGroup, typename OverlapSolution>
231 struct OverlapSolutionInboxTag
233  OverlapSolutionInboxTag<Dim, OptionsGroup, OverlapSolution>> {
234  using temporal_id = size_t;
236 };
237 
238 // Once the residual data is available on all overlaps, solve the restricted
239 // problem for this element-centered subdomain. Apply the weighted solution on
240 // this element directly and send the solution on overlap regions to the
241 // neighbors that they overlap with.
242 template <typename FieldsTag, typename OptionsGroup, typename SubdomainOperator>
243 struct SolveSubdomain {
244  private:
245  using fields_tag = FieldsTag;
246  using residual_tag =
248  static constexpr size_t Dim = SubdomainOperator::volume_dim;
249  using SubdomainData =
250  ElementCenteredSubdomainData<Dim, typename residual_tag::tags_list>;
251  using OverlapData = typename SubdomainData::OverlapData;
252  using overlap_solution_inbox_tag =
253  OverlapSolutionInboxTag<Dim, OptionsGroup, OverlapData>;
254 
255  public:
256  using const_global_cache_tags =
257  tmpl::list<Tags::MaxOverlap<OptionsGroup>,
259 
260  template <typename DbTagsList, typename... InboxTags, typename Metavariables,
261  typename ActionList, typename ParallelComponent>
263  db::DataBox<DbTagsList>& box,
264  const tuples::TaggedTuple<InboxTags...>& /*inboxes*/,
266  const ElementId<Dim>& element_id, const ActionList /*meta*/,
267  const ParallelComponent* const /*meta*/) noexcept {
268  const size_t iteration_id =
269  get<Convergence::Tags::IterationId<OptionsGroup>>(box);
270 
271  // Do some logging
273  ::Verbosity::Debug)) {
274  Parallel::printf("%s %s(%zu): Solve subdomain\n", element_id,
275  Options::name<OptionsGroup>(), iteration_id);
276  }
277 
278  const auto& element = db::get<domain::Tags::Element<Dim>>(box);
279  const size_t max_overlap = db::get<Tags::MaxOverlap<OptionsGroup>>(box);
280 
281  // Assemble the subdomain data from the data on the element and the
282  // communicated overlap data
283  db::mutate<SubdomainDataBufferTag<SubdomainData, OptionsGroup>,
284  Tags::Overlaps<residual_tag, Dim, OptionsGroup>>(
285  make_not_null(&box),
286  [max_overlap, &element](
287  const gsl::not_null<SubdomainData*> subdomain_data,
288  const auto overlap_residuals, const auto& residual) noexcept {
289  subdomain_data->element_data = residual;
290  // Nothing was communicated if the overlaps are empty
291  if (LIKELY(max_overlap > 0 and element.number_of_neighbors() > 0)) {
292  subdomain_data->overlap_data = std::move(*overlap_residuals);
293  }
294  },
295  db::get<residual_tag>(box));
296  const auto& subdomain_residual =
297  db::get<SubdomainDataBufferTag<SubdomainData, OptionsGroup>>(box);
298 
299  // Allocate workspace memory for repeatedly applying the subdomain operator
300  SubdomainOperator subdomain_operator{};
301 
302  // Construct the subdomain operator
303  const auto apply_subdomain_operator =
304  [&box, &subdomain_operator](const gsl::not_null<SubdomainData*> result,
305  const SubdomainData& operand) noexcept {
306  // The subdomain operator can retrieve any information on the subdomain
307  // geometry that is available through the DataBox. The user is responsible
308  // for communicating this information across neighbors if necessary.
309  subdomain_operator(result, operand, box);
310  };
311 
312  // Solve the subdomain problem
313  const auto& subdomain_solver =
314  get<Tags::SubdomainSolverBase<OptionsGroup>>(box);
315  auto subdomain_solve_initial_guess_in_solution_out =
316  make_with_value<SubdomainData>(subdomain_residual, 0.);
317  const auto subdomain_solve_has_converged = subdomain_solver.solve(
318  make_not_null(&subdomain_solve_initial_guess_in_solution_out),
319  apply_subdomain_operator, subdomain_residual);
320  // Re-naming the solution buffer for the code below
321  auto& subdomain_solution = subdomain_solve_initial_guess_in_solution_out;
322 
323  // Do some logging and observing
325  ::Verbosity::Quiet)) {
326  if (not subdomain_solve_has_converged or
327  subdomain_solve_has_converged.reason() ==
330  "%s %s(%zu): WARNING: Subdomain solver did not converge in %zu "
331  "iterations: %e -> %e\n",
332  element_id, Options::name<OptionsGroup>(), iteration_id,
333  subdomain_solve_has_converged.num_iterations(),
334  subdomain_solve_has_converged.initial_residual_magnitude(),
335  subdomain_solve_has_converged.residual_magnitude());
337  ::Verbosity::Debug)) {
339  "%s %s(%zu): Subdomain solver converged in %zu iterations (%s): %e "
340  "-> %e\n",
341  element_id, Options::name<OptionsGroup>(), iteration_id,
342  subdomain_solve_has_converged.num_iterations(),
343  subdomain_solve_has_converged.reason(),
344  subdomain_solve_has_converged.initial_residual_magnitude(),
345  subdomain_solve_has_converged.residual_magnitude());
346  }
347  }
348  contribute_to_subdomain_stats_observation<OptionsGroup, ParallelComponent>(
349  iteration_id + 1, subdomain_solve_has_converged.num_iterations(), cache,
350  element_id);
351 
352  // Apply weighting
353  if (LIKELY(max_overlap > 0)) {
354  subdomain_solution.element_data *=
355  get(db::get<Tags::Weight<OptionsGroup>>(box));
356  }
357 
358  // Apply solution to central element
359  db::mutate<fields_tag>(make_not_null(&box),
360  [&subdomain_solution](const auto fields) noexcept {
361  *fields += subdomain_solution.element_data;
362  });
363 
364  // Send overlap solutions back to the neighbors that they are on
365  if (LIKELY(max_overlap > 0)) {
366  auto& receiver_proxy =
367  Parallel::get_parallel_component<ParallelComponent>(cache);
368  for (auto& [overlap_id, overlap_solution] :
369  subdomain_solution.overlap_data) {
370  const auto& direction = overlap_id.first;
371  const auto& neighbor_id = overlap_id.second;
372  const auto& orientation =
373  element.neighbors().at(direction).orientation();
374  const auto direction_from_neighbor = orientation(direction.opposite());
375  Parallel::receive_data<overlap_solution_inbox_tag>(
376  receiver_proxy[neighbor_id], iteration_id,
377  std::make_pair(
378  OverlapId<Dim>{direction_from_neighbor, element.id()},
379  std::move(overlap_solution)));
380  }
381  }
382  return {std::move(box)};
383  }
384 };
385 
386 // Wait for the subdomain solutions on regions within this element that overlap
387 // with neighboring element-centered subdomains. Combine the solutions as a
388 // weighted sum.
389 template <typename FieldsTag, typename OptionsGroup, typename SubdomainOperator>
390 struct ReceiveOverlapSolution {
391  private:
392  using fields_tag = FieldsTag;
393  using residual_tag =
395  static constexpr size_t Dim = SubdomainOperator::volume_dim;
396  using SubdomainData =
397  ElementCenteredSubdomainData<Dim, typename residual_tag::tags_list>;
398  using OverlapSolution = typename SubdomainData::OverlapData;
399  using overlap_solution_inbox_tag =
400  OverlapSolutionInboxTag<Dim, OptionsGroup, OverlapSolution>;
401 
402  public:
403  using const_global_cache_tags = tmpl::list<Tags::MaxOverlap<OptionsGroup>>;
404  using inbox_tags = tmpl::list<overlap_solution_inbox_tag>;
405 
406  template <typename DbTagsList, typename... InboxTags, typename Metavariables,
407  size_t Dim>
408  static bool is_ready(const db::DataBox<DbTagsList>& box,
409  const tuples::TaggedTuple<InboxTags...>& inboxes,
410  const Parallel::GlobalCache<Metavariables>& /*cache*/,
411  const ElementId<Dim>& /*element_id*/) noexcept {
412  if (UNLIKELY(db::get<Tags::MaxOverlap<OptionsGroup>>(box) == 0)) {
413  return true;
414  }
415  return dg::has_received_from_all_mortars<overlap_solution_inbox_tag>(
417  get<domain::Tags::Element<Dim>>(box), inboxes);
418  }
419 
420  template <typename DbTagsList, typename... InboxTags, typename Metavariables,
421  typename ActionList, typename ParallelComponent>
423  db::DataBox<DbTagsList>& box, tuples::TaggedTuple<InboxTags...>& inboxes,
424  const Parallel::GlobalCache<Metavariables>& /*cache*/,
425  const ElementId<Dim>& element_id, const ActionList /*meta*/,
426  const ParallelComponent* const /*meta*/) noexcept {
427  const size_t iteration_id =
428  get<Convergence::Tags::IterationId<OptionsGroup>>(box);
429  const auto& element = db::get<domain::Tags::Element<Dim>>(box);
430 
431  // Nothing to do if overlap is empty
432  if (UNLIKELY(db::get<Tags::MaxOverlap<OptionsGroup>>(box) == 0 or
433  element.number_of_neighbors() == 0)) {
434  return {std::move(box)};
435  }
436 
437  // Do some logging
439  ::Verbosity::Debug)) {
440  Parallel::printf("%s %s(%zu): Receive overlap solution\n", element_id,
441  Options::name<OptionsGroup>(), iteration_id);
442  }
443 
444  // Add solutions on overlaps to this element's solution in a weighted sum
445  const auto received_overlap_solutions =
446  std::move(tuples::get<overlap_solution_inbox_tag>(inboxes)
447  .extract(iteration_id)
448  .mapped());
449  db::mutate<fields_tag>(
450  make_not_null(&box),
451  [&received_overlap_solutions](
452  const auto fields, const Index<Dim>& full_extents,
453  const std::array<size_t, Dim>& all_intruding_extents,
455  all_intruding_overlap_weights) noexcept {
456  for (const auto& [overlap_id, overlap_solution] :
457  received_overlap_solutions) {
458  const auto& direction = overlap_id.first;
459  const auto& intruding_extents =
460  gsl::at(all_intruding_extents, direction.dimension());
461  const auto& overlap_weight =
462  all_intruding_overlap_weights.at(direction);
464  fields, overlap_solution * get(overlap_weight), full_extents,
465  intruding_extents, direction);
466  }
467  },
468  db::get<domain::Tags::Mesh<Dim>>(box).extents(),
469  db::get<Tags::IntrudingExtents<Dim, OptionsGroup>>(box),
471  Tags::Weight<OptionsGroup>>>(box));
472  return {std::move(box)};
473  }
474 };
475 
476 } // namespace LinearSolver::Schwarz::detail
LinearSolver::Serial::LinearSolver
Base class for serial linear solvers that supports factory-creation.
Definition: LinearSolver.hpp:37
gsl::at
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:125
observers::ObservationId
A unique identifier for an observation representing the type of observation and the instance (e....
Definition: ObservationId.hpp:71
std::apply
T apply(T... args)
funcl::Divides
Functional for computing / of two objects.
Definition: Functional.hpp:235
std::string
utility
UNLIKELY
#define UNLIKELY(x)
Definition: Gsl.hpp:73
get
constexpr Tag::type & get(Variables< TagList > &v) noexcept
Return Tag::type pointing into the contiguous array.
Definition: Variables.hpp:660
Parallel::GlobalCache
Definition: ElementReceiveInterpPoints.hpp:15
Parallel::ReductionDatum
The data to be reduced, and invokables to be called whenever two reduction messages are combined and ...
Definition: Reduction.hpp:63
std::pair
GlobalCache.hpp
std::index_sequence
Options.hpp
CommunicateOverlapFields.hpp
Tags.hpp
vector
domain::Tags::Element
Definition: Tags.hpp:97
LinearSolver::Schwarz::Actions::ReceiveOverlapFields
Receive data from regions of this element's subdomain that overlap with other elements.
Definition: CommunicateOverlapFields.hpp:159
PrettyType.hpp
Parallel::printf
void printf(const std::string &format, Args &&... args)
Print an atomic message to stdout with C printf usage.
Definition: Printf.hpp:103
db::add_tag_prefix
typename detail::add_tag_prefix_impl< Prefix, Tag, Args... >::type add_tag_prefix
Definition: PrefixHelpers.hpp:51
observers::ObservationKey
Used as a key in maps to keep track of how many elements have registered.
Definition: ObservationId.hpp:28
tuple
db::get
const auto & get(const DataBox< TagList > &box) noexcept
Retrieve the item with tag Tag from the DataBox.
Definition: DataBox.hpp:786
Index
Definition: Index.hpp:31
db::SimpleTag
Mark a struct as a simple tag by inheriting from this.
Definition: Tag.hpp:36
domain::Tags::InternalDirectionsCompute
Definition: Tags.hpp:276
domain::Tags::BoundaryDirectionsInterior
Definition: Tags.hpp:297
Spectral.hpp
Tags.hpp
Direction< Dim >
LinearSolver::Schwarz::Actions::SendOverlapFields
Send data on regions that overlap with other subdomains to their corresponding elements.
Definition: CommunicateOverlapFields.hpp:68
get_output
std::string get_output(const T &t) noexcept
Get the streamed output of t as a std::string
Definition: GetOutput.hpp:14
Registration::Registrar
A template for defining a registrar.
Definition: Registration.hpp:42
Initialization::mutate_assign
constexpr void mutate_assign(const gsl::not_null< db::DataBox< BoxTags > * > box, Args &&... args) noexcept
Perform a mutation to the DataBox box, assigning the args to the tags in MutateTagList in order.
Definition: MutateAssign.hpp:40
ElementId< Dim >
ElementId.hpp
std::add_pointer_t
LinearSolver::Schwarz::add_overlap_data
void add_overlap_data(const gsl::not_null< Variables< VolumeTagsList > * > volume_data, const Variables< OverlapTagsList > &overlap_data, const Index< Dim > &volume_extents, const size_t overlap_extent, const Direction< Dim > &direction) noexcept
Add the overlap_data to the volume_data
Definition: OverlapHelpers.hpp:226
ActionTesting::is_ready
bool is_ready(MockRuntimeSystem< Metavariables > &runner, const typename Component::array_index &array_index) noexcept
Runs the is_ready function and returns the result for the next action in the current phase on the arr...
Definition: MockRuntimeSystemFreeFunctions.hpp:286
Printf.hpp
DataBox.hpp
cstddef
logging::Tags::Verbosity
Tag for putting Verbosity in a DataBox.
Definition: Tags.hpp:33
std::array< size_t, Dim >
domain::Tags::LogicalCoordinates
Definition: LogicalCoordinates.hpp:78
Index.hpp
tuples::TaggedTuple
An associative container that is indexed by structs.
Definition: TaggedTuple.hpp:271
map
Element.hpp
Convergence::Tags::IterationId
Identifies a step in an iterative algorithm.
Definition: Tags.hpp:74
ActionTesting::cache
Parallel::GlobalCache< Metavariables > & cache(MockRuntimeSystem< Metavariables > &runner, const ArrayIndex &array_index) noexcept
Returns the GlobalCache of Component with index array_index.
Definition: MockRuntimeSystemFreeFunctions.hpp:380
Scalar
Tensor< T, Symmetry<>, index_list<> > Scalar
Definition: TypeAliases.hpp:21
PhaseControl::reduction_data
Parallel::ReductionData< Parallel::ReductionDatum< tuples::tagged_tuple_from_typelist< TagsAndCombinesPresent >, TaggedTupleCombine > > reduction_data
A Parallel::ReductionData with a single Parallel::ReductionDatum for a given tagged tuple type determ...
Definition: PhaseControlTags.hpp:92
Gsl.hpp
domain::Tags::Interface
Tag which is either a SimpleTag for quantities on an interface, base tag to a compute item which acts...
Definition: Tags.hpp:366
domain::Tags::InterfaceCompute
Compute tag for representing items computed on a set of interfaces. Can be retrieved using Tags::Inte...
Definition: InterfaceComputeTags.hpp:67
domain::Tags::Direction
Definition: Tags.hpp:382
LinearSolver::Tags::Residual
The residual .
Definition: Tags.hpp:67
domain::Tags::InternalDirections
Definition: Tags.hpp:270
observers::TypeOfObservation::Reduction
@ Reduction
The sender will only perform reduction observations.
LIKELY
#define LIKELY(x)
Definition: Gsl.hpp:67
observers::ArrayComponentId
An ID type that identifies both the parallel component and the index in the parallel component.
Definition: ArrayComponentId.hpp:27
make_not_null
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,...
Definition: Gsl.hpp:880
Parallel::ArrayIndex
The array index used for indexing Chare Arrays, mostly an implementation detail.
Definition: ArrayIndex.hpp:28
domain::Tags::BoundaryDirectionsInteriorCompute
Definition: Tags.hpp:303
std::unique_ptr
unordered_map
tt::ConformsTo
Indicate a class conforms to the Protocol.
Definition: ProtocolHelpers.hpp:22
Convergence::Reason::MaxIterations
@ MaxIterations
Reached the maximum number of iterations. Can be interpreted as an error condition.
TMPL.hpp
Mesh.hpp
gsl::not_null
Require a pointer to not be a nullptr
Definition: ReadSpecThirdOrderPiecewisePolynomial.hpp:13
Parallel::InboxInserters::Map
Inserter for inserting data that is received as the value_type (with non-const key_type) of a map dat...
Definition: InboxInserters.hpp:36
observers::Actions::RegisterWithObservers
Register an observation ID with the observers.
Definition: RegisterWithObservers.hpp:47
string