Line data Source code
1 0 : // Distributed under the MIT License. 2 : // See LICENSE.txt for details. 3 : 4 : #pragma once 5 : 6 : #include <algorithm> 7 : 8 : #include "DataStructures/DataBox/DataBox.hpp" 9 : #include "DataStructures/Variables.hpp" 10 : #include "Domain/Tags.hpp" 11 : #include "ParallelAlgorithms/Interpolation/InterpolationTargetDetail.hpp" 12 : #include "ParallelAlgorithms/Interpolation/Tags.hpp" 13 : #include "Parallel/GlobalCache.hpp" 14 : #include "Parallel/Invoke.hpp" 15 : #include "ParallelAlgorithms/Interpolation/Actions/SendPointsToInterpolator.hpp" 16 : #include "ParallelAlgorithms/Interpolation/Actions/VerifyTemporalIdsAndSendPoints.hpp" 17 : #include "Utilities/TaggedTuple.hpp" 18 : 19 : namespace intrp { 20 : 21 1 : namespace Actions { 22 : /// \ingroup ActionsGroup 23 : /// \brief Adds `temporal_id`s on which this InterpolationTarget 24 : /// should be triggered. 25 : /// 26 : /// Invoked on an InterpolationTarget. 27 : /// 28 : /// In more detail, does the following: 29 : /// - Adds the passed-in `temporal_id`s to PendingTemporalIds. 30 : /// - If the InterpolationTarget is sequential 31 : /// - If TemporalIds and PendingTemporalIds were both initially empty, 32 : /// invokes Actions::VerifyTemporalIdsAndSendPoints. (Otherwise there 33 : /// is an interpolation in progress and nothing needs to be done.) 34 : /// - If the InterpolationTarget is not sequential 35 : /// - Invokes Actions::SendPointsToInterpolator on all TemporalIds 36 : /// - Invokes Actions::VerifyTemporalIdsAndSendPoints if PendingTemporalIds 37 : /// is non-empty. 38 : /// 39 : /// Uses: 40 : /// - DataBox: 41 : /// - `Tags::TemporalIds<TemporalId>` 42 : /// - `Tags::CompletedTemporalIds<TemporalId>` 43 : /// 44 : /// DataBox changes: 45 : /// - Adds: nothing 46 : /// - Removes: nothing 47 : /// - Modifies: 48 : /// - `Tags::TemporalIds<TemporalId>` 49 : template <typename InterpolationTargetTag> 50 1 : struct AddTemporalIdsToInterpolationTarget { 51 : template <typename ParallelComponent, typename DbTags, typename Metavariables, 52 : typename ArrayIndex, typename TemporalId> 53 0 : static void apply(db::DataBox<DbTags>& box, 54 : Parallel::GlobalCache<Metavariables>& cache, 55 : const ArrayIndex& /*array_index*/, 56 : std::vector<TemporalId>&& temporal_ids) { 57 : if constexpr (InterpolationTargetTag::compute_target_points::is_sequential:: 58 : value) { 59 : // InterpolationTarget is sequential. 60 : // - If Tags::TemporalIds is non-empty, then there is an 61 : // interpolation in progress, so do nothing here. (If there's 62 : // an interpolation in progress, then a later interpolation 63 : // will be started as soon as the earlier one finishes (in 64 : // InterpolationTargetReceiveVars)). 65 : // - If not pending_temporal_ids_was_empty_on_entry, then 66 : // there are pending temporal_ids waiting inside a 67 : // VerifyTemporalIdsAndSendPoints callback, so do nothing here. 68 : // (A later interpolation will be started on the callback). 69 : // - If Tags::PendingTemporalIds is empty, then we didn't actually 70 : // add any pending temporal_ids above, so do nothing here. 71 : // - Otherwise, there is no interpolation in progress and there 72 : // is no pending_temporal_ids waiting. So initiate waiting and 73 : // interpolation on the pending_temporal_ids. 74 : 75 : const bool pending_temporal_ids_was_empty_on_entry = 76 : db::get<Tags::PendingTemporalIds<TemporalId>>(box).empty(); 77 : 78 : InterpolationTarget_detail::flag_temporal_ids_as_pending< 79 : InterpolationTargetTag>(make_not_null(&box), temporal_ids); 80 : 81 : if (db::get<Tags::TemporalIds<TemporalId>>(box).empty() and 82 : pending_temporal_ids_was_empty_on_entry and 83 : not db::get<Tags::PendingTemporalIds<TemporalId>>(box).empty()) { 84 : auto& my_proxy = 85 : Parallel::get_parallel_component<ParallelComponent>(cache); 86 : Parallel::simple_action< 87 : Actions::VerifyTemporalIdsAndSendPoints<InterpolationTargetTag>>( 88 : my_proxy); 89 : } 90 : } else { 91 : // InterpolationTarget is not sequential. So everything in 92 : // Tags::TemporalIds should have had interpolation started on it 93 : // already. So begin interpolation on every new pending 94 : // temporal_id. 95 : 96 : const std::vector<TemporalId> new_pending_temporal_ids = 97 : InterpolationTarget_detail::flag_temporal_ids_as_pending< 98 : InterpolationTargetTag>(make_not_null(&box), temporal_ids); 99 : 100 : if (not new_pending_temporal_ids.empty()) { 101 : auto& my_proxy = 102 : Parallel::get_parallel_component<ParallelComponent>(cache); 103 : Parallel::simple_action< 104 : Actions::VerifyTemporalIdsAndSendPoints<InterpolationTargetTag>>( 105 : my_proxy); 106 : } 107 : } 108 : } 109 : }; 110 : } // namespace Actions 111 : } // namespace intrp