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 : #include <sstream> 8 : #include <string> 9 : #include <type_traits> 10 : 11 : #include "DataStructures/DataBox/DataBox.hpp" 12 : #include "DataStructures/LinkedMessageId.hpp" 13 : #include "DataStructures/Variables.hpp" 14 : #include "Domain/Tags.hpp" 15 : #include "IO/Logging/Verbosity.hpp" 16 : #include "Parallel/GlobalCache.hpp" 17 : #include "Parallel/Invoke.hpp" 18 : #include "Parallel/Printf/Printf.hpp" 19 : #include "ParallelAlgorithms/Interpolation/Actions/SendPointsToInterpolator.hpp" 20 : #include "ParallelAlgorithms/Interpolation/Actions/VerifyTemporalIdsAndSendPoints.hpp" 21 : #include "ParallelAlgorithms/Interpolation/InterpolationTargetDetail.hpp" 22 : #include "ParallelAlgorithms/Interpolation/Tags.hpp" 23 : #include "Utilities/PrettyType.hpp" 24 : #include "Utilities/TaggedTuple.hpp" 25 : 26 1 : namespace intrp::Actions { 27 : /// \ingroup ActionsGroup 28 : /// \brief Adds a `temporal_id` on which this InterpolationTarget 29 : /// should be triggered. 30 : /// 31 : /// Invoked on an InterpolationTarget. 32 : /// 33 : /// In more detail, does the following: 34 : /// - Adds the passed-in `temporal_id` to PendingTemporalIds. 35 : /// - If all the following conditions are met: 36 : /// - CurrentTemporalId doesn't have a value 37 : /// - PendingTemporalIds is not empty, 38 : /// - The temporal id is a LinkedMessageId or PendingTemporalIds was empty 39 : /// upon entry 40 : /// call Actions::VerifyTemporalIdsAndSendPoints. (Otherwise there 41 : /// is an interpolation in progress and nothing needs to be done.) 42 : /// 43 : /// Uses: 44 : /// - DataBox: 45 : /// - `Tags::CurrentTemporalId<TemporalId>` 46 : /// - `Tags::CompletedTemporalIds<TemporalId>` 47 : /// 48 : /// DataBox changes: 49 : /// - Adds: nothing 50 : /// - Removes: nothing 51 : /// - Modifies: 52 : /// - `Tags::PendingTemporalIds<TemporalId>` 53 : template <typename InterpolationTargetTag> 54 1 : struct AddTemporalIdsToInterpolationTarget { 55 : template <typename ParallelComponent, typename DbTags, typename Metavariables, 56 : typename ArrayIndex, typename TemporalId> 57 0 : static void apply(db::DataBox<DbTags>& box, 58 : Parallel::GlobalCache<Metavariables>& cache, 59 : const ArrayIndex& array_index, 60 : const TemporalId& temporal_id, 61 : std::optional<std::string> dependency) { 62 : static_assert( 63 : InterpolationTargetTag::compute_target_points::is_sequential::value, 64 : "Actions::AddTemporalIdsToInterpolationTarget can be used only with " 65 : "sequential targets."); 66 : 67 : const bool pending_temporal_ids_was_empty_on_entry = 68 : db::get<Tags::PendingTemporalIds<TemporalId>>(box).empty(); 69 : InterpolationTarget_detail::flag_temporal_id_as_pending< 70 : InterpolationTargetTag>(make_not_null(&box), temporal_id, 71 : std::move(dependency)); 72 : 73 : // - If Tags::CurrentTemporalIds has a value, then there is an 74 : // interpolation in progress, so do nothing here. (If there's 75 : // an interpolation in progress, then a later interpolation 76 : // will be started as soon as the earlier one finishes (in 77 : // InterpolationTargetReceiveVars)). 78 : // - If Tags::PendingTemporalIds is empty, then we didn't actually 79 : // add any pending temporal_ids above, so do nothing here. 80 : // - After we check if TemporalIds is empty and PendingIds isn't, if this is 81 : // not a LinkedMessageId, then our indication for sending points was 82 : // whether the pending ids was empty at the beginning of this action. But 83 : // if this is a LinkedMessageId, it doesn't matter if pending was empty on 84 : // entry because of receiving messages out of order. We have to check the 85 : // pending id regardless 86 : if (not db::get<Tags::CurrentTemporalId<TemporalId>>(box).has_value() and 87 : not db::get<Tags::PendingTemporalIds<TemporalId>>(box).empty() and 88 : (std::is_same_v<LinkedMessageId<double>, TemporalId> or 89 : pending_temporal_ids_was_empty_on_entry)) { 90 : if (Parallel::get<intrp::Tags::Verbosity>(cache) >= 91 : ::Verbosity::Verbose) { 92 : Parallel::printf( 93 : "%s, Verifying temporal id %s.\n", 94 : InterpolationTarget_detail::target_output_prefix< 95 : AddTemporalIdsToInterpolationTarget, InterpolationTargetTag>(), 96 : temporal_id); 97 : } 98 : 99 : // Call directly 100 : Actions::VerifyTemporalIdsAndSendPoints<InterpolationTargetTag>:: 101 : template apply<ParallelComponent>(box, cache, array_index); 102 : 103 : } else if (Parallel::get<intrp::Tags::Verbosity>(cache) >= 104 : ::Verbosity::Debug) { 105 : std::stringstream ss{}; 106 : ss << InterpolationTarget_detail::target_output_prefix< 107 : AddTemporalIdsToInterpolationTarget, InterpolationTargetTag>() 108 : << ", "; 109 : using ::operator<<; 110 : if (db::get<Tags::CurrentTemporalId<TemporalId>>(box).has_value()) { 111 : ss << "Current temporal id has a value. " 112 : << db::get<Tags::CurrentTemporalId<TemporalId>>(box).value(); 113 : } else if (db::get<Tags::PendingTemporalIds<TemporalId>>(box).empty()) { 114 : ss << "Pending temporal ids is empty after insertion."; 115 : } else { 116 : if constexpr (std::is_same_v<LinkedMessageId<double>, TemporalId>) { 117 : ss << "Id is LinkedMessageId<double>."; 118 : } else { 119 : ss << "Pending temporal ids was empty on entry"; 120 : } 121 : } 122 : 123 : Parallel::printf("%s\n", ss.str()); 124 : } 125 : } 126 : }; 127 : } // namespace intrp::Actions