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 <pup.h> 8 : #include <string> 9 : #include <type_traits> 10 : 11 : #include "Options/String.hpp" 12 : #include "Parallel/ArrayCollection/IsDgElementCollection.hpp" 13 : #include "Parallel/ArrayCollection/PerformAlgorithmOnElement.hpp" 14 : #include "Parallel/ArrayCollection/Tags/ElementLocations.hpp" 15 : #include "Parallel/GlobalCache.hpp" 16 : #include "ParallelAlgorithms/Actions/GetItemFromDistributedObject.hpp" 17 : #include "ParallelAlgorithms/EventsAndTriggers/Event.hpp" 18 : #include "ParallelAlgorithms/Interpolation/Events/GetComputeItemsOnSource.hpp" 19 : #include "ParallelAlgorithms/Interpolation/Interpolate.hpp" 20 : #include "ParallelAlgorithms/Interpolation/Tags.hpp" 21 : #include "Utilities/PrettyType.hpp" 22 : #include "Utilities/Serialization/CharmPupable.hpp" 23 : #include "Utilities/TMPL.hpp" 24 : 25 : /// \cond 26 : template <size_t Dim> 27 : class Mesh; 28 : template <size_t VolumeDim> 29 : class ElementId; 30 : namespace Parallel { 31 : template <typename Metavariables> 32 : class GlobalCache; 33 : } // namespace Parallel 34 : namespace Tags { 35 : struct Time; 36 : } // namespace Tags 37 : namespace Events::Tags { 38 : template <size_t Dim> 39 : struct ObserverMesh; 40 : } // namespace Events::Tags 41 : namespace ah::Tags { 42 : struct BlocksForInterpolation; 43 : } // namespace ah::Tags 44 : /// \endcond 45 : 46 : namespace intrp { 47 : namespace Events { 48 : /// Does an interpolation onto InterpolationTargetTag by calling Actions on 49 : /// the Interpolator and InterpolationTarget components. 50 : template <size_t VolumeDim, typename InterpolationTargetTag, 51 : typename InterpolatorSourceVarTags> 52 1 : class Interpolate; 53 : 54 : template <size_t VolumeDim, typename InterpolationTargetTag, 55 : typename... InterpolatorSourceVarTags> 56 0 : class Interpolate<VolumeDim, InterpolationTargetTag, 57 : tmpl::list<InterpolatorSourceVarTags...>> : public Event { 58 : public: 59 : /// \cond 60 : explicit Interpolate(CkMigrateMessage* /*unused*/) {} 61 : using PUP::able::register_constructor; 62 : WRAPPED_PUPable_decl_template(Interpolate); // NOLINT 63 : /// \endcond 64 : 65 0 : using options = tmpl::list<>; 66 0 : static constexpr Options::String help = 67 : "Starts interpolation onto the given InterpolationTargetTag."; 68 : 69 0 : static std::string name() { 70 : return pretty_type::name<InterpolationTargetTag>(); 71 : } 72 : 73 0 : Interpolate() = default; 74 : 75 : /// This constructor is not available through options 76 1 : explicit Interpolate(std::optional<std::string> dependency) 77 : : dependency_(std::move(dependency)) {} 78 : 79 0 : using compute_tags_for_observation_box = 80 : detail::get_compute_items_on_source_or_default_t<InterpolationTargetTag, 81 : tmpl::list<>>; 82 : 83 0 : using return_tags = tmpl::list<>; 84 0 : using argument_tags = tmpl::list<typename InterpolationTargetTag::temporal_id, 85 : ::Events::Tags::ObserverMesh<VolumeDim>, 86 : InterpolatorSourceVarTags...>; 87 : 88 : template <typename Metavariables, typename ParallelComponent> 89 0 : void operator()( 90 : const typename InterpolationTargetTag::temporal_id::type& temporal_id, 91 : const Mesh<VolumeDim>& mesh, 92 : const typename InterpolatorSourceVarTags:: 93 : type&... interpolator_source_vars, 94 : Parallel::GlobalCache<Metavariables>& cache, 95 : const ElementId<VolumeDim>& array_index, 96 : const ParallelComponent* const /*meta*/, 97 : const ObservationValue& /*observation_value*/) const { 98 : static_assert( 99 : std::is_same_v<typename Metavariables::interpolator_source_vars, 100 : tmpl::list<InterpolatorSourceVarTags...>>); 101 : 102 : const auto& blocks_to_interpolate = 103 : Parallel::get<ah::Tags::BlocksForInterpolation>(cache); 104 : ASSERT(blocks_to_interpolate.contains(name()), 105 : "Blocks to interpolate doesn't contain target " << name()); 106 : const auto& blocks_to_interpolate_for_this_target = 107 : blocks_to_interpolate.at(name()); 108 : const auto& blocks = 109 : Parallel::get<domain::Tags::Domain<VolumeDim>>(cache).blocks(); 110 : const auto& block_name = blocks[array_index.block_id()].name(); 111 : 112 : // Only send data if this target needs this blocks data 113 : if (not blocks_to_interpolate_for_this_target.contains(block_name)) { 114 : return; 115 : } 116 : 117 : if constexpr (Parallel::is_dg_element_collection_v<ParallelComponent>) { 118 : const auto core_id = static_cast<int>( 119 : Parallel::local_synchronous_action< 120 : Parallel::Actions::GetItemFromDistributedOject< 121 : typename ParallelComponent::element_collection_tag>>( 122 : Parallel::get_parallel_component<ParallelComponent>(cache)) 123 : ->at(array_index) 124 : .get_core()); 125 : interpolate<InterpolationTargetTag>(temporal_id, mesh, cache, array_index, 126 : core_id, dependency_, 127 : interpolator_source_vars...); 128 : } else { 129 : interpolate<InterpolationTargetTag>(temporal_id, mesh, cache, array_index, 130 : std::nullopt, dependency_, 131 : interpolator_source_vars...); 132 : } 133 : } 134 : 135 0 : using is_ready_argument_tags = tmpl::list<>; 136 : 137 : template <typename Metavariables, typename ArrayIndex, typename Component> 138 0 : bool is_ready(Parallel::GlobalCache<Metavariables>& /*cache*/, 139 : const ArrayIndex& /*array_index*/, 140 : const Component* const /*component*/) const { 141 : return true; 142 : } 143 : 144 1 : bool needs_evolved_variables() const override { return true; } 145 : 146 0 : void pup(PUP::er& p) override { 147 : Event::pup(p); 148 : p | dependency_; 149 : } 150 : 151 : private: 152 0 : std::optional<std::string> dependency_; 153 : }; 154 : 155 : /// \cond 156 : template <size_t VolumeDim, typename InterpolationTargetTag, 157 : typename... InterpolatorSourceVarTags> 158 : PUP::able::PUP_ID 159 : Interpolate<VolumeDim, InterpolationTargetTag, 160 : tmpl::list<InterpolatorSourceVarTags...>>::my_PUP_ID = 161 : 0; // NOLINT 162 : /// \endcond 163 : 164 : } // namespace Events 165 : } // namespace intrp