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 <cmath> 8 : #include <cstddef> 9 : #include <pup.h> 10 : #include <string> 11 : 12 : #include "DataStructures/DataVector.hpp" 13 : #include "Evolution/Systems/GeneralizedHarmonic/Bbh/CompletionCriteria.hpp" 14 : #include "Evolution/Systems/GeneralizedHarmonic/Bbh/CompletionSingleton.hpp" 15 : #include "Evolution/Systems/GeneralizedHarmonic/Constraints.hpp" 16 : #include "Evolution/Systems/GeneralizedHarmonic/Tags.hpp" 17 : #include "Options/String.hpp" 18 : #include "Parallel/ArrayCollection/IsDgElementCollection.hpp" 19 : #include "Parallel/GlobalCache.hpp" 20 : #include "Parallel/Reduction.hpp" 21 : #include "ParallelAlgorithms/EventsAndTriggers/Event.hpp" 22 : #include "Time/Tags/Time.hpp" 23 : #include "Utilities/ErrorHandling/Error.hpp" 24 : #include "Utilities/Serialization/CharmPupable.hpp" 25 : #include "Utilities/TMPL.hpp" 26 : 27 0 : namespace gh::bbh::Events { 28 : /*! 29 : * \brief Computes per-element Linf norms of the generalized-harmonic 30 : * constraints, latching BBH completion criteria when thresholds are exceeded. 31 : * 32 : * \details This event is intended to run once common-horizon finding is 33 : * active (typically behind a separation-based trigger). It monitors the gauge 34 : * and three-index constraints, using a reduction to determine if their Linf 35 : * norms exceed completion thresholds. 36 : */ 37 1 : class CheckConstraintThresholds : public Event { 38 0 : using ReductionData = Parallel::ReductionData< 39 : Parallel::ReductionDatum<double, funcl::AssertEqual<>>, 40 : Parallel::ReductionDatum<double, funcl::Max<>>, 41 : Parallel::ReductionDatum<double, funcl::Max<>>>; 42 : 43 : public: 44 : /// \cond 45 : explicit CheckConstraintThresholds(CkMigrateMessage* /*unused*/) {} 46 : using PUP::able::register_constructor; 47 : WRAPPED_PUPable_decl_template(CheckConstraintThresholds); // NOLINT 48 : /// \endcond 49 : 50 0 : using compute_tags_for_observation_box = 51 : tmpl::list<gh::Tags::GaugeConstraintCompute<3, Frame::Inertial>, 52 : gh::Tags::ThreeIndexConstraintCompute<3, Frame::Inertial>>; 53 0 : using options = tmpl::list<>; 54 0 : static constexpr Options::String help = 55 : "Checks local Linf norms of constraints against BBH completion " 56 : "thresholds and forwards reduced maxima to the BBH completion singleton " 57 : "reduction callback."; 58 0 : static std::string name() { return "BbhCheckConstraintThresholds"; } 59 : 60 0 : CheckConstraintThresholds() = default; 61 : 62 0 : using return_tags = tmpl::list<>; 63 0 : using argument_tags = tmpl::list< 64 : ::Tags::Time, gh::Tags::GaugeConstraint<DataVector, 3, Frame::Inertial>, 65 : gh::Tags::ThreeIndexConstraint<DataVector, 3, Frame::Inertial>>; 66 : 67 : template <typename Metavariables, typename ArrayIndex, typename Component> 68 0 : void operator()( 69 : const double time, 70 : const tnsr::a<DataVector, 3, Frame::Inertial>& gauge_constraint, 71 : const tnsr::iaa<DataVector, 3, Frame::Inertial>& three_index_constraint, 72 : Parallel::GlobalCache<Metavariables>& cache, 73 : const ArrayIndex& array_index, const Component* const /*component*/, 74 : const ObservationValue& /*observation_value*/) const { 75 : const double local_gauge_linf = local_linf_norm(gauge_constraint); 76 : const double local_three_index_linf = 77 : local_linf_norm(three_index_constraint); 78 : if constexpr (Parallel::is_dg_element_collection_v<Component>) { 79 : ERROR( 80 : "BbhCheckConstraintThresholds currently requires array components " 81 : "(not DgElementCollection)."); 82 : } else { 83 : const auto& self_proxy = 84 : Parallel::get_parallel_component<Component>(cache)[array_index]; 85 : auto& reduction_target_proxy = Parallel::get_parallel_component< 86 : gh::bbh::CompletionSingleton<Metavariables>>(cache); 87 : Parallel::contribute_to_reduction< 88 : gh::bbh::Actions::ProcessConstraintMaxima>( 89 : ReductionData{time, local_gauge_linf, local_three_index_linf}, 90 : self_proxy, reduction_target_proxy); 91 : } 92 : } 93 : 94 0 : using is_ready_argument_tags = tmpl::list<>; 95 : template <typename Metavariables, typename ArrayIndex, typename Component> 96 0 : bool is_ready(Parallel::GlobalCache<Metavariables>& /*cache*/, 97 : const ArrayIndex& /*array_index*/, 98 : const Component* const /*meta*/) const { 99 : return true; 100 : } 101 : 102 1 : bool needs_evolved_variables() const override { return true; } 103 : 104 : private: 105 : template <typename TensorType> 106 0 : static double local_linf_norm(const TensorType& tensor) { 107 : double result = 0.0; 108 : for (size_t storage_index = 0; storage_index < tensor.size(); 109 : ++storage_index) { 110 : const auto& component = tensor[storage_index]; 111 : result = std::max(result, max(abs(component))); 112 : } 113 : return result; 114 : } 115 : }; 116 : } // namespace gh::bbh::Events