DgElementArray.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/InitialElementIds.hpp"
9 #include "Domain/Tags.hpp"
10 #include "Elliptic/DiscontinuousGalerkin/InitializeElement.hpp"
11 #include "IO/Observer/TypeOfObservation.hpp"
13 #include "Parallel/Info.hpp"
14 #include "Parallel/Invoke.hpp"
15 #include "Parallel/ParallelComponentHelpers.hpp"
16 #include "Utilities/TMPL.hpp"
17 
18 /// \cond
19 namespace observers {
20 namespace Actions {
21 template <observers::TypeOfObservation TypeOfObservation>
22 struct RegisterWithObservers;
23 } // namespace Actions
24 } // namespace observers
25 /// \endcond
26 
27 namespace Elliptic {
28 
29 /*!
30  * \brief The parallel component responsible for managing the DG elements that
31  * compose the computational domain
32  *
33  * This parallel component will perform the following phases:
34  *
35  * - `Phase::Initialize`: Create the domain and execute
36  * `Elliptic::dg::Actions::InitializeElement` on all elements.
37  * - `Phase::RegisterWithObservers` (optional)
38  * - `Phase::Solve`: Execute the actions in `ActionList` on all elements. Repeat
39  * until an action terminates the algorithm.
40  *
41  * \note This parallel component is nearly identical to
42  * `Evolution/DiscontinuousGalerkin/DgElementArray.hpp` right now, but will
43  * likely diverge in the future, for instance to support a multigrid domain.
44  *
45  * Uses:
46  * - Metavariables:
47  * - `domain_creator_tag`
48  * - System:
49  * - `volume_dim`
50  * - ConstGlobalCache:
51  * - All items required by the actions in `ActionList`
52  */
53 template <class Metavariables, class ActionList>
55  static constexpr size_t volume_dim = Metavariables::system::volume_dim;
56 
57  using chare_type = Parallel::Algorithms::Array;
59  using action_list = ActionList;
61 
62  using const_global_cache_tag_list =
64 
65  using initial_databox = db::compute_databox_type<
67  volume_dim>::template return_tag_list<Metavariables>>;
68 
69  using options = tmpl::list<typename Metavariables::domain_creator_tag>;
70 
71  static void initialize(
72  Parallel::CProxy_ConstGlobalCache<Metavariables>& global_cache,
74  domain_creator) noexcept;
75 
76  static void execute_next_phase(
77  const typename Metavariables::Phase next_phase,
78  Parallel::CProxy_ConstGlobalCache<Metavariables>& global_cache) {
79  auto& local_cache = *(global_cache.ckLocalBranch());
80  auto& dg_element_array =
81  Parallel::get_parallel_component<DgElementArray>(local_cache);
82  switch (next_phase) {
83  case Metavariables::Phase::Solve:
84  dg_element_array.perform_algorithm();
85  break;
86  default:
87  try_register_with_observers(next_phase, global_cache);
88  break;
89  }
90  }
91 
92  private:
93  template <typename PhaseType,
95  nullptr>
96  static void try_register_with_observers(
97  const PhaseType /*next_phase*/,
98  Parallel::CProxy_ConstGlobalCache<
99  Metavariables>& /*global_cache*/) noexcept {}
100 
101  template <
102  typename PhaseType,
104  static void try_register_with_observers(
105  const PhaseType next_phase,
106  Parallel::CProxy_ConstGlobalCache<Metavariables>& global_cache) noexcept {
107  if (next_phase == Metavariables::Phase::RegisterWithObserver) {
108  auto& local_cache = *(global_cache.ckLocalBranch());
109  // We currently use a fake temporal id when registering observers but in
110  // the future when we start doing load balancing and elements migrate
111  // around the system they will need to register and unregister themselves
112  // at specific times.
113  const size_t fake_temporal_id = 0;
116  Parallel::get_parallel_component<DgElementArray>(local_cache),
117  fake_temporal_id);
118  }
119  }
120 };
121 
122 template <class Metavariables, class ActionList>
124  Parallel::CProxy_ConstGlobalCache<Metavariables>& global_cache,
126  domain_creator) noexcept {
127  auto& dg_element_array = Parallel::get_parallel_component<DgElementArray>(
128  *(global_cache.ckLocalBranch()));
129 
130  auto domain = domain_creator->create_domain();
131  for (const auto& block : domain.blocks()) {
132  const auto initial_ref_levs =
133  domain_creator->initial_refinement_levels()[block.id()];
134  const std::vector<ElementId<volume_dim>> element_ids =
135  initial_element_ids(block.id(), initial_ref_levs);
136  int which_proc = 0;
138  for (size_t i = 0; i < element_ids.size(); ++i) {
139  dg_element_array(ElementIndex<volume_dim>(element_ids[i]))
140  .insert(global_cache, which_proc);
141  which_proc = which_proc + 1 == number_of_procs ? 0 : which_proc + 1;
142  }
143  }
144  dg_element_array.doneInserting();
145 
146  dg_element_array.template simple_action<
148  std::make_tuple(domain_creator->initial_extents(), std::move(domain)));
149 }
150 } // namespace Elliptic
Definition: Actions.hpp:20
Defines functions for interfacing with the parallelization framework.
The sender will perform both reduction and volume observations.
Definition: BlockId.hpp:16
Registers itself with the local observer parallel component so the observer knows to expect data from...
Definition: Actions.hpp:97
int number_of_procs()
Number of processing elements.
Definition: Info.hpp:16
Definition: ComputeOperatorAction.hpp:28
Base class for creating Domains from an option string.
Definition: DomainCreator.hpp:87
tmpl::remove_duplicates< tmpl::join< tmpl::transform< ActionsList, Parallel_detail::get_const_global_cache_tags_from_action< tmpl::_1 > >> > get_const_global_cache_tags
Given a list of Actions, get a list of the unique tags specified in the actions&#39; const_global_cache_t...
Definition: ParallelComponentHelpers.hpp:72
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
The parallel component responsible for managing the DG elements that compose the computational domain...
Definition: DgElementArray.hpp:54
Defines class ElementIndex.
Wraps the template metaprogramming library used (brigand)
Initializes the DataBox of each element in the DgElementArray.
Definition: InitializeElement.hpp:54
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:1827
Definition: SolvePoissonProblem.hpp:38
A class for indexing a Charm array by Element.
Definition: ElementIndex.hpp:53
Defines class template ConstGlobalCache.
Definition: ComputeTimeDerivative.hpp:28