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
|