Line data Source code
1 0 : // Distributed under the MIT License. 2 : // See LICENSE.txt for details. 3 : 4 : #pragma once 5 : 6 : #include <array> 7 : #include <pup.h> 8 : #include <type_traits> 9 : 10 : #include "DataStructures/DataBox/ObservationBox.hpp" 11 : #include "Domain/Amr/Flag.hpp" 12 : #include "Domain/Structure/ElementId.hpp" 13 : #include "Parallel/GlobalCache.hpp" 14 : #include "Parallel/Tags/Metavariables.hpp" 15 : #include "Utilities/CallWithDynamicType.hpp" 16 : #include "Utilities/Serialization/CharmPupable.hpp" 17 : #include "Utilities/TMPL.hpp" 18 : 19 : namespace amr { 20 : /// \ingroup AmrGroup 21 : /// \brief Base class for something that determines how an adaptive mesh should 22 : /// be changed 23 : /// 24 : /// \details Each class derived from this class should (see the examples below): 25 : /// - Be option-creatable 26 : /// - Be serializable 27 : /// - Define a call operator that returns a std::array<amr::Flag, Dim> 28 : /// containing the recommended refinement choice in each logical dimension of 29 : /// the Element. 30 : /// - Define the type aliases `argument_tags` and 31 : /// `compute_tags_for_observation_box` that are type lists of tags used in the 32 : /// call operator. 33 : /// The call operator should take as arguments the values corresponding to each 34 : /// tag in `argument_tags` (in order), followed by the Parallel::GlobalCache, 35 : /// and the ElementId. The tags listed in `argument_tags` should either be tags 36 : /// in the DataBox of the array component, or listed in 37 : /// `compute_tags_for_observation_box`. 38 : /// 39 : /// \example 40 : /// \snippet Test_Criterion.cpp criterion_examples 41 1 : class Criterion : public PUP::able { 42 : protected: 43 : /// \cond 44 : Criterion() = default; 45 : Criterion(const Criterion&) = default; 46 : Criterion(Criterion&&) = default; 47 : Criterion& operator=(const Criterion&) = default; 48 : Criterion& operator=(Criterion&&) = default; 49 : /// \endcond 50 : 51 : public: 52 0 : ~Criterion() override = default; 53 0 : explicit Criterion(CkMigrateMessage* msg) : PUP::able(msg) {} 54 : 55 0 : WRAPPED_PUPable_abstract(Criterion); // NOLINT 56 : 57 0 : virtual std::string observation_name() = 0; 58 : 59 : /// Evaluates the AMR criteria by selecting the appropriate derived class 60 : /// and forwarding its `argument_tags` from the ObservationBox (along with the 61 : /// GlobalCache and ArrayIndex) to the call operator of the derived class 62 : /// 63 : /// \note In order to be available, a derived Criterion must be listed in 64 : /// the entry for Criterion in 65 : /// Metavarialbes::factory_creation::factory_classes 66 : /// 67 : /// \note The ComputeTagsList of the ObservationBox should contain the union 68 : /// of the tags listed in `compute_tags_for_observation_box` for each derived 69 : /// Criterion listed in the `factory_classes`. 70 : template <typename ComputeTagsList, typename DataBoxType, 71 : typename Metavariables> 72 1 : auto evaluate(const ObservationBox<ComputeTagsList, DataBoxType>& box, 73 : Parallel::GlobalCache<Metavariables>& cache, 74 : const ElementId<Metavariables::volume_dim>& element_id) const { 75 : using factory_classes = 76 : typename std::decay_t<Metavariables>::factory_creation::factory_classes; 77 : return call_with_dynamic_type< 78 : std::array<amr::Flag, Metavariables::volume_dim>, 79 : tmpl::at<factory_classes, Criterion>>( 80 : this, [&box, &cache, &element_id](auto* const criterion) { 81 : return apply(*criterion, box, cache, element_id); 82 : }); 83 : } 84 : }; 85 : } // namespace amr