ExportCoordinates.hpp
1 // Distributed under the MIT License.
2 // See LICENSE.txt for details.
3 
4 #pragma once
5 
6 #include "AlgorithmArray.hpp"
8 #include "Domain/Creators/RegisterDerivedWithCharm.hpp"
10 #include "Domain/InitialElementIds.hpp"
11 #include "Domain/Tags.hpp"
12 #include "Elliptic/Initialization/Domain.hpp"
14 #include "IO/Observer/Actions.hpp"
15 #include "IO/Observer/ArrayComponentId.hpp"
16 #include "IO/Observer/Helpers.hpp"
17 #include "IO/Observer/ObservationId.hpp"
18 #include "IO/Observer/ObserverComponent.hpp"
19 #include "IO/Observer/VolumeActions.hpp"
20 #include "Options/Options.hpp"
22 #include "Parallel/Info.hpp"
23 #include "Parallel/InitializationFunctions.hpp"
24 #include "Parallel/Invoke.hpp"
25 #include "Parallel/Printf.hpp"
26 #include "Time/Time.hpp"
27 #include "Utilities/MakeString.hpp"
28 #include "Utilities/Requires.hpp"
29 #include "Utilities/TMPL.hpp"
30 
31 namespace {
32 struct ObservationType {};
33 } // namespace
34 
35 namespace Actions {
36 
37 template <size_t Dim>
39  using return_tag_list = tmpl::append<
40  typename Elliptic::Initialization::Domain<Dim>::simple_tags,
41  typename Elliptic::Initialization::Domain<Dim>::compute_tags>;
42 
43  template <typename... InboxTags, typename Metavariables, typename ActionList,
44  typename ParallelComponent>
45  static auto apply(const db::DataBox<tmpl::list<>>& /*box*/,
46  const tuples::TaggedTuple<InboxTags...>& /*inboxes*/,
48  const ElementIndex<Dim>& array_index,
49  const ActionList /*meta*/,
50  const ParallelComponent* const /*meta*/,
51  std::vector<std::array<size_t, Dim>> initial_extents,
54  db::DataBox<tmpl::list<>>{}, array_index, initial_extents, domain);
55  return std::make_tuple(std::move(domain_box));
56  }
57 };
58 
59 template <size_t Dim>
61  template <typename... DbTags, typename... InboxTags, typename Metavariables,
62  typename ArrayIndex, typename ActionList,
63  typename ParallelComponent,
64  Requires<sizeof...(DbTags) != 0> = nullptr>
65  static void apply(db::DataBox<tmpl::list<DbTags...>>& box,
68  const ArrayIndex& array_index, const ActionList /*meta*/,
69  const ParallelComponent* const /*meta*/) {
70  const auto& mesh = get<Tags::Mesh<Dim>>(box);
71  const auto& inertial_coordinates =
72  db::get<::Tags::Coordinates<Dim, Frame::Inertial>>(box);
73  const std::string element_name = MakeString{} << ElementId<Dim>(array_index)
74  << '/';
75  // Collect volume data
76  // Remove tensor types, only storing individual components
78  components.reserve(Dim);
79  for (size_t d = 0; d < Dim; d++) {
80  components.emplace_back(element_name + "InertialCoordinates_" +
81  inertial_coordinates.component_name(
82  inertial_coordinates.get_tensor_index(d)),
83  inertial_coordinates.get(d));
84  }
85  // Send data to volume observer
86  auto& local_observer =
87  *Parallel::get_parallel_component<observers::Observer<Metavariables>>(
88  cache)
89  .ckLocalBranch();
90  Parallel::simple_action<observers::Actions::ContributeVolumeData>(
91  local_observer, observers::ObservationId(0., ObservationType{}),
92  std::string{"/element_data"},
96  std::move(components), mesh.extents());
97  }
98 };
99 } // namespace Actions
100 
101 template <size_t Dim, typename Metavariables>
102 struct ElementArray {
103  using chare_type = Parallel::Algorithms::Array;
105  using action_list = tmpl::list<>;
107  using const_global_cache_tag_list = tmpl::list<>;
108  using options = tmpl::list<OptionTags::DomainCreator<Dim, Frame::Inertial>>;
109  using initial_databox = db::compute_databox_type<
110  typename Actions::InitializeElement<Dim>::return_tag_list>;
111 
112  static void initialize(
113  Parallel::CProxy_ConstGlobalCache<Metavariables>& global_cache,
115  domain_creator) noexcept {
116  auto& local_cache = *(global_cache.ckLocalBranch());
117  auto& element_array =
118  Parallel::get_parallel_component<ElementArray>(local_cache);
119 
120  auto domain = domain_creator->create_domain();
121  for (const auto& block : domain.blocks()) {
122  const auto initial_ref_levs =
123  domain_creator->initial_refinement_levels()[block.id()];
124  const std::vector<ElementId<Dim>> element_ids =
125  initial_element_ids(block.id(), initial_ref_levs);
126  int which_proc = 0;
128  for (size_t i = 0; i < element_ids.size(); ++i) {
129  element_array(ElementIndex<Dim>(element_ids[i]))
130  .insert(global_cache, which_proc);
131  which_proc = which_proc + 1 == number_of_procs ? 0 : which_proc + 1;
132  }
133  }
134  element_array.doneInserting();
135 
136  element_array.template simple_action<Actions::InitializeElement<Dim>>(
137  std::make_tuple(domain_creator->initial_extents(), std::move(domain)));
138  }
139 
140  static void execute_next_phase(
141  const typename Metavariables::Phase next_phase,
142  Parallel::CProxy_ConstGlobalCache<Metavariables>& global_cache) {
143  auto& local_cache = *(global_cache.ckLocalBranch());
144  auto& element_array =
145  Parallel::get_parallel_component<ElementArray>(local_cache);
146  switch (next_phase) {
147  case Metavariables::Phase::RegisterWithObserver:
150  element_array, observers::ObservationId(0., ObservationType{}));
151  break;
152  case Metavariables::Phase::Export:
153  element_array.template simple_action<Actions::ExportCoordinates<Dim>>();
154  break;
155  default:
156  break;
157  }
158  }
159 };
160 
161 template <size_t Dim>
162 struct Metavariables {
163  static constexpr OptionString help{
164  "Export the inertial coordinates of the Domain specified in the input "
165  "file. The output can be used to compute initial data externally, for "
166  "instance."};
167 
168  using const_global_cache_tag_list = tmpl::list<>;
169  using component_list = tmpl::list<ElementArray<Dim, Metavariables>,
172  using observed_reduction_data_tags = tmpl::list<>;
173 
174  enum class Phase { Initialization, RegisterWithObserver, Export, Exit };
175 
176  static Phase determine_next_phase(
177  const Phase& current_phase,
178  const Parallel::CProxy_ConstGlobalCache<
179  Metavariables>& /*cache_proxy*/) noexcept {
180  switch (current_phase) {
181  case Phase::Initialization:
182  return Phase::RegisterWithObserver;
183  case Phase::RegisterWithObserver:
184  return Phase::Export;
185  case Phase::Export:
186  return Phase::Exit;
187  case Phase::Exit:
188  ERROR(
189  "Should never call determine_next_phase with the current phase "
190  "being 'Exit'");
191  default:
192  ERROR("Unknown type of phase.");
193  }
194  }
195 };
196 
197 static const std::vector<void (*)()> charm_init_node_funcs{
198  &setup_error_handling, &domain::creators::register_derived_with_charm};
199 static const std::vector<void (*)()> charm_init_proc_funcs{
#define ERROR(m)
prints an error message to the standard error stream and aborts the program.
Definition: Error.hpp:35
Defines functions for interfacing with the parallelization framework.
Items for initializing the DataBoxes of parallel components.
Definition: ConservativeSystem.hpp:21
Definition: BlockId.hpp:16
Registers itself with the local observer parallel component so the observer knows to expect data from...
Definition: Actions.hpp:236
int number_of_procs()
Number of processing elements.
Definition: Info.hpp:16
Defines classes and functions for making classes creatable from input files.
The nodegroup parallel component that is responsible for writing data to disk.
Definition: ObserverComponent.hpp:55
Defines the type alias Requires.
Base class for creating Domains from an option string.
Definition: DomainCreator.hpp:91
constexpr auto apply(F &&f, const DataBox< BoxTags > &box, Args &&... args)
Apply the function f with argument Tags TagsList from DataBox box
Definition: DataBox.hpp:1609
An ID type that identifies both the parallel component and the index in the parallel component...
Definition: ArrayComponentId.hpp:27
Defines Time and TimeDelta.
Definition: ExportCoordinates.hpp:102
const char *const OptionString
The string used in option structs.
Definition: Options.hpp:27
Make a string by streaming into object.
Definition: MakeString.hpp:16
The group parallel component that is responsible for reducing data to be observed.
Definition: ObserverComponent.hpp:25
Definition: ExportCoordinates.hpp:60
An associative container that is indexed by structs.
Definition: TaggedTuple.hpp:272
Defines classes and functions used for manipulating DataBox&#39;s.
void enable_floating_point_exceptions()
After a call to this function, the code will terminate with a floating point exception on overflow...
Definition: FloatingPointExceptions.cpp:27
std::vector< ElementId< VolumeDim > > initial_element_ids(const std::vector< std::array< size_t, VolumeDim >> &initial_refinement_levels) noexcept
Create the ElementIds of the initial computational domain.
Definition: InitialElementIds.cpp:67
Defines Parallel::printf for writing to stdout.
Definition: InterpolationTargetWedgeSectionTorus.hpp:24
Initializes the DataBox tag related to the computational domain.
Definition: Domain.hpp:49
Definition: ExportCoordinates.hpp:38
A Charm++ chare that caches constant data once per Charm++ node.
Definition: ConstGlobalCache.hpp:76
Functions to enable/disable termination on floating point exceptions.
A wrapper around a vector of Blocks that represent the computational domain.
Definition: Domain.hpp:38
Defines class ElementIndex.
Wraps the template metaprogramming library used (brigand)
Defines tags related to domain quantities.
void simple_action(Proxy &&proxy) noexcept
Invoke a simple action on proxy
Definition: Invoke.hpp:112
typename Requires_detail::requires_impl< B >::template_error_type_failed_to_meet_requirements_on_template_parameters Requires
Express requirements on the template parameters of a function or class, replaces std::enable_if_t ...
Definition: Requires.hpp:67
typename DataBox_detail::compute_dbox_type< get_items< TagList >, get_compute_items< TagList > >::type compute_databox_type
Returns the type of the DataBox that would be constructed from the TagList of tags.
Definition: DataBox.hpp:1830
Definition: SolvePoissonProblem.hpp:37
A class for indexing a Charm array by Element.
Definition: ElementIndex.hpp:53
A type-erased identifier that combines the identifier&#39;s type and hash used to uniquely identify an ob...
Definition: ObservationId.hpp:42
Defines class template ConstGlobalCache.
The sender will only perform volume observations.
Definition: ComputeTimeDerivative.hpp:28
The array index used for indexing Chare Arrays, mostly an implementation detail.
Definition: ArrayIndex.hpp:20