Line data Source code
1 0 : // Distributed under the MIT License. 2 : // See LICENSE.txt for details. 3 : 4 : #pragma once 5 : 6 : #include <cstddef> 7 : #include <optional> 8 : #include <tuple> 9 : 10 : #include "DataStructures/DataBox/DataBox.hpp" 11 : #include "Domain/Structure/ElementId.hpp" 12 : #include "Domain/Tags.hpp" 13 : #include "IO/Importers/Tags.hpp" 14 : #include "Parallel/AlgorithmExecution.hpp" 15 : #include "Parallel/ArrayComponentId.hpp" 16 : #include "Parallel/ArrayIndex.hpp" 17 : #include "Parallel/GlobalCache.hpp" 18 : #include "Parallel/Invoke.hpp" 19 : #include "Parallel/Local.hpp" 20 : #include "Utilities/Gsl.hpp" 21 : #include "Utilities/Literals.hpp" 22 : #include "Utilities/MakeString.hpp" 23 : #include "Utilities/Requires.hpp" 24 : #include "Utilities/TMPL.hpp" 25 : #include "Utilities/TaggedTuple.hpp" 26 : 27 : /// \cond 28 : namespace importers { 29 : template <typename Metavariables> 30 : struct ElementDataReader; 31 : namespace Actions { 32 : struct RegisterElementWithSelf; 33 : } // namespace Actions 34 : } // namespace importers 35 : namespace evolution::dg::subcell { 36 : template <typename DgTag, typename SubcellTag, typename DbTagsList> 37 : const typename DgTag::type& get_active_tag(const db::DataBox<DbTagsList>& box); 38 : namespace Tags { 39 : template <size_t Dim, typename Frame> 40 : struct Coordinates; 41 : template <size_t Dim> 42 : struct Mesh; 43 : struct ActiveGrid; 44 : } // namespace Tags 45 : } // namespace evolution::dg::subcell 46 : /// \endcond 47 : 48 : namespace importers::Actions { 49 : 50 : /*! 51 : * \brief Register an element with the volume data reader component. 52 : * 53 : * Invoke this action on each element of an array parallel component to register 54 : * them for receiving imported volume data. 55 : * 56 : * \note If the tags `evolution::dg::subcell::Tags::ActiveGrid` and 57 : * `evolution::dg::subcell::Tags::Coordinates<Dim, Frame::Inertial>` are 58 : * retrievable from the DataBox, then interpolation to the FD/subcell grid is 59 : * possible. 60 : * 61 : * \see Dev guide on \ref dev_guide_importing 62 : */ 63 1 : struct RegisterWithElementDataReader { 64 : template <typename DbTagsList, typename... InboxTags, typename Metavariables, 65 : size_t Dim, typename ActionList, typename ParallelComponent> 66 0 : static Parallel::iterable_action_return_t apply( 67 : db::DataBox<DbTagsList>& box, 68 : const tuples::TaggedTuple<InboxTags...>& /*inboxes*/, 69 : Parallel::GlobalCache<Metavariables>& cache, 70 : const ElementId<Dim>& array_index, const ActionList /*meta*/, 71 : const ParallelComponent* const /*meta*/) { 72 : auto& local_reader_component = *Parallel::local_branch( 73 : Parallel::get_parallel_component< 74 : importers::ElementDataReader<Metavariables>>(cache)); 75 : auto coords_and_mesh = [&box]() { 76 : if constexpr (db::tag_is_retrievable_v< 77 : evolution::dg::subcell::Tags::ActiveGrid, 78 : db::DataBox<DbTagsList>> and 79 : db::tag_is_retrievable_v< 80 : evolution::dg::subcell::Tags::Coordinates< 81 : Dim, Frame::Inertial>, 82 : db::DataBox<DbTagsList>>) { 83 : return std::make_pair( 84 : evolution::dg::subcell::get_active_tag< 85 : domain::Tags::Coordinates<Dim, Frame::Inertial>, 86 : evolution::dg::subcell::Tags::Coordinates<Dim, 87 : Frame::Inertial>>( 88 : box), 89 : evolution::dg::subcell::get_active_tag< 90 : domain::Tags::Mesh<Dim>, 91 : evolution::dg::subcell::Tags::Mesh<Dim>>(box)); 92 : } else { 93 : return std::make_pair( 94 : db::get<domain::Tags::Coordinates<Dim, Frame::Inertial>>(box), 95 : db::get<domain::Tags::Mesh<Dim>>(box)); 96 : } 97 : }(); 98 : Parallel::simple_action<importers::Actions::RegisterElementWithSelf>( 99 : local_reader_component, 100 : Parallel::make_array_component_id<ParallelComponent>(array_index), 101 : std::move(coords_and_mesh)); 102 : return {Parallel::AlgorithmExecution::Continue, std::nullopt}; 103 : } 104 : }; 105 : 106 : /*! 107 : * \brief Invoked on the `importers::ElementDataReader` component to store the 108 : * registered data. 109 : * 110 : * The `importers::Actions::RegisterWithElementDataReader` action, which is 111 : * performed on each element of an array parallel component, invokes this action 112 : * on the `importers::ElementDataReader` component. 113 : * 114 : * \see Dev guide on \ref dev_guide_importing 115 : */ 116 1 : struct RegisterElementWithSelf { 117 : template <typename ParallelComponent, typename DbTagsList, 118 : typename Metavariables, typename ArrayIndex, size_t Dim> 119 0 : static void apply( 120 : db::DataBox<DbTagsList>& box, 121 : const Parallel::GlobalCache<Metavariables>& /*cache*/, 122 : const ArrayIndex& /*array_index*/, 123 : const Parallel::ArrayComponentId& array_component_id, 124 : std::pair<tnsr::I<DataVector, Dim, Frame::Inertial>, Mesh<Dim>> 125 : coords_and_mesh) { 126 : db::mutate<Tags::RegisteredElements<Dim>>( 127 : [&array_component_id, 128 : &coords_and_mesh](const auto registered_elements) { 129 : (*registered_elements)[array_component_id] = 130 : std::move(coords_and_mesh); 131 : }, 132 : make_not_null(&box)); 133 : } 134 : }; 135 : 136 : } // namespace importers::Actions