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 <vector> 10 : 11 : #include "DataStructures/DataBox/ObservationBox.hpp" 12 : #include "DataStructures/FloatingPointType.hpp" 13 : #include "DataStructures/Tensor/IndexType.hpp" 14 : #include "DataStructures/Tensor/Tensor.hpp" 15 : #include "DataStructures/Tensor/TypeAliases.hpp" 16 : #include "Domain/Amr/Flag.hpp" 17 : #include "IO/H5/TensorData.hpp" 18 : #include "Options/String.hpp" 19 : #include "ParallelAlgorithms/Amr/Criteria/Criterion.hpp" 20 : #include "ParallelAlgorithms/Amr/Criteria/Tags/Criteria.hpp" 21 : #include "ParallelAlgorithms/Events/ObserveConstantsPerElement.hpp" 22 : #include "ParallelAlgorithms/EventsAndTriggers/Event.hpp" 23 : #include "Utilities/Gsl.hpp" 24 : #include "Utilities/Serialization/CharmPupable.hpp" 25 : #include "Utilities/TMPL.hpp" 26 : 27 : /// \cond 28 : template <size_t VolumeDim> 29 : class Domain; 30 : template <size_t VolumeDim> 31 : class ElementId; 32 : namespace domain { 33 : namespace FunctionsOfTime { 34 : class FunctionOfTime; 35 : } // namespace FunctionsOfTime 36 : namespace Tags { 37 : template <size_t VolumeDim> 38 : struct Domain; 39 : struct FunctionsOfTime; 40 : } // namespace Tags 41 : } // namespace domain 42 : namespace Parallel { 43 : template <typename Metavariables> 44 : class GlobalCache; 45 : } // namespace Parallel 46 : namespace Tags { 47 : struct Time; 48 : struct TimeStep; 49 : } // namespace Tags 50 : /// \endcond 51 : 52 : namespace amr::Events { 53 : namespace detail { 54 : template <typename Criterion> 55 : struct get_compute_tags { 56 : using type = typename Criterion::compute_tags_for_observation_box; 57 : }; 58 : } // namespace detail 59 : 60 : /// \brief Observe the desired decisions of AMR criteria 61 : /// 62 : /// \details The event will return a vector of decisions (an independent choice 63 : /// in each logical dimension) for each of the AMR criteria. These are the raw 64 : /// choices made by each AMR critera, not taking into account any AMR policies. 65 : /// Each element is output as a single cell with two points per dimension and 66 : /// the observation constant on all those points. The decisions are converted 67 : /// to values as follows (in each logical dimension): 68 : /// - -2.0 is for join with sibling (if possible) 69 : /// - -1.0 is for decrease number of grid points 70 : /// - 0.0 is for no change 71 : /// - 1.0 is for increase number of grid points 72 : /// - 2.0 is for splitting the element 73 : template <typename Metavariables> 74 1 : class ObserveAmrCriteria 75 : : public dg::Events::ObserveConstantsPerElement<Metavariables::volume_dim> { 76 : public: 77 0 : static constexpr size_t volume_dim = Metavariables::volume_dim; 78 : /// \cond 79 : explicit ObserveAmrCriteria(CkMigrateMessage* m) 80 : : dg::Events::ObserveConstantsPerElement<volume_dim>(m) {} 81 : using PUP::able::register_constructor; 82 : WRAPPED_PUPable_decl_template(ObserveAmrCriteria); // NOLINT 83 : /// \endcond 84 : 85 0 : static constexpr Options::String help = 86 : "Observe the desired decisions of AMR criteria in the volume."; 87 : 88 0 : ObserveAmrCriteria() = default; 89 : 90 0 : ObserveAmrCriteria(const std::string& subfile_name, 91 : ::FloatingPointType coordinates_floating_point_type, 92 : ::FloatingPointType floating_point_type) 93 : : dg::Events::ObserveConstantsPerElement<volume_dim>( 94 : subfile_name, coordinates_floating_point_type, 95 : floating_point_type) {} 96 : 97 0 : using compute_tags_for_observation_box = 98 : tmpl::remove_duplicates<tmpl::flatten<tmpl::transform< 99 : tmpl::at<typename Metavariables::factory_creation::factory_classes, 100 : Criterion>, 101 : detail::get_compute_tags<tmpl::_1>>>>; 102 : 103 0 : using return_tags = tmpl::list<>; 104 0 : using argument_tags = tmpl::list<::Tags::ObservationBox>; 105 : 106 : template <typename DataBoxType, typename ComputeTagsList, 107 : typename ParallelComponent> 108 0 : void operator()(const ObservationBox<DataBoxType, ComputeTagsList>& box, 109 : Parallel::GlobalCache<Metavariables>& cache, 110 : const ElementId<Metavariables::volume_dim>& element_id, 111 : const ParallelComponent* const component, 112 : const Event::ObservationValue& observation_value) const { 113 : const auto& refinement_criteria = get<amr::Criteria::Tags::Criteria>(box); 114 : const double time = get<::Tags::Time>(box); 115 : const auto& functions_of_time = get<::domain::Tags::FunctionsOfTime>(box); 116 : const Domain<volume_dim>& domain = 117 : get<::domain::Tags::Domain<volume_dim>>(box); 118 : 119 : std::vector<TensorComponent> components = this->allocate_and_insert_coords( 120 : volume_dim * refinement_criteria.size(), time, functions_of_time, 121 : domain, element_id); 122 : 123 : for (const auto& criterion : refinement_criteria) { 124 : const auto decision = criterion->evaluate(box, cache, element_id); 125 : for (size_t d = 0; d < volume_dim; ++d) { 126 : this->add_constant( 127 : make_not_null(&components), 128 : criterion->observation_name() + 129 : tnsr::i<double, volume_dim, 130 : Frame::ElementLogical>::component_suffix(d), 131 : static_cast<double>(gsl::at(decision, d)) - 3.0); 132 : } 133 : } 134 : 135 : this->observe(components, cache, element_id, component, observation_value); 136 : } 137 : 138 1 : bool needs_evolved_variables() const override { return true; } 139 : 140 0 : void pup(PUP::er& p) override { 141 : dg::Events::ObserveConstantsPerElement<volume_dim>::pup(p); 142 : } 143 : }; 144 : 145 : /// \cond 146 : template <typename Metavariables> 147 : PUP::able::PUP_ID ObserveAmrCriteria<Metavariables>::my_PUP_ID = 0; // NOLINT 148 : /// \endcond 149 : } // namespace amr::Events