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 <tuple> 8 : #include <type_traits> 9 : #include <vector> 10 : 11 : #include "DataStructures/Variables.hpp" 12 : #include "NumericalAlgorithms/Spectral/Mesh.hpp" 13 : #include "Parallel/GlobalCache.hpp" 14 : #include "Parallel/Invoke.hpp" 15 : #include "Parallel/Local.hpp" 16 : #include "ParallelAlgorithms/Interpolation/Actions/AddTemporalIdsToInterpolationTarget.hpp" 17 : #include "ParallelAlgorithms/Interpolation/Actions/InterpolatorReceiveVolumeData.hpp" 18 : #include "Utilities/TMPL.hpp" 19 : 20 : /// \cond 21 : template <size_t VolumeDim> 22 : class ElementId; 23 : namespace intrp { 24 : template <typename Metavariables, typename Tag> 25 : struct InterpolationTarget; 26 : template <typename Metavariables> 27 : struct Interpolator; 28 : } // namespace intrp 29 : /// \endcond 30 : 31 : namespace intrp { 32 : /// \brief Send data to the interpolator for interpolation. 33 : /// 34 : /// \note if `interpolator_id` is not `std::nullopt` then we send to the 35 : /// `interpolator_id.value()` index of the `Interpolator` parallel 36 : /// component. This can be used to keep a specific element always sending to 37 : /// the same `Interpolator` element. 38 : template <typename InterpolationTargetTag, size_t VolumeDim, 39 : typename Metavariables, typename... InterpolatorSourceVars> 40 1 : void interpolate( 41 : const typename InterpolationTargetTag::temporal_id::type& temporal_id, 42 : const Mesh<VolumeDim>& mesh, Parallel::GlobalCache<Metavariables>& cache, 43 : const ElementId<VolumeDim>& array_index, 44 : const std::optional<int> interpolator_id, 45 : const std::optional<std::string>& dependency, 46 : const InterpolatorSourceVars&... interpolator_source_vars_input) { 47 : Variables<typename Metavariables::interpolator_source_vars> 48 : interpolator_source_vars(mesh.number_of_grid_points()); 49 : const std::tuple<const InterpolatorSourceVars&...> 50 : interpolator_source_vars_tuple{interpolator_source_vars_input...}; 51 : tmpl::for_each< 52 : tmpl::make_sequence<tmpl::size_t<0>, sizeof...(InterpolatorSourceVars)>>( 53 : [&interpolator_source_vars, 54 : &interpolator_source_vars_tuple](auto index_v) { 55 : constexpr size_t index = tmpl::type_from<decltype(index_v)>::value; 56 : get<tmpl::at_c<typename Metavariables::interpolator_source_vars, 57 : index>>(interpolator_source_vars) = 58 : get<index>(interpolator_source_vars_tuple); 59 : }); 60 : 61 : // Send volume data to the Interpolator, to trigger interpolation. 62 : if (interpolator_id.has_value()) { 63 : auto interpolator = 64 : ::Parallel::get_parallel_component<Interpolator<Metavariables>>( 65 : cache)[interpolator_id.value()]; 66 : Parallel::simple_action<Actions::InterpolatorReceiveVolumeData< 67 : typename InterpolationTargetTag::temporal_id>>( 68 : interpolator, temporal_id, array_index, mesh, interpolator_source_vars); 69 : } else { 70 : auto& interpolator = *Parallel::local_branch( 71 : ::Parallel::get_parallel_component<Interpolator<Metavariables>>(cache)); 72 : Parallel::simple_action<Actions::InterpolatorReceiveVolumeData< 73 : typename InterpolationTargetTag::temporal_id>>( 74 : interpolator, temporal_id, array_index, mesh, interpolator_source_vars); 75 : } 76 : 77 : // Tell the interpolation target that it should interpolate. 78 : auto& target = Parallel::get_parallel_component< 79 : InterpolationTarget<Metavariables, InterpolationTargetTag>>(cache); 80 : Parallel::simple_action< 81 : Actions::AddTemporalIdsToInterpolationTarget<InterpolationTargetTag>>( 82 : target, temporal_id, dependency); 83 : } 84 : } // namespace intrp