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 :
8 : #include "DataStructures/DataBox/Protocols/Mutator.hpp"
9 : #include "DataStructures/DataVector.hpp"
10 : #include "DataStructures/Tensor/Tensor.hpp"
11 : #include "DataStructures/Variables.hpp"
12 : #include "DataStructures/VariablesTag.hpp"
13 : #include "Domain/Block.hpp"
14 : #include "Domain/Creators/Tags/Domain.hpp"
15 : #include "Domain/Domain.hpp"
16 : #include "Domain/Structure/Element.hpp"
17 : #include "Domain/Structure/ElementId.hpp"
18 : #include "Domain/Tags.hpp"
19 : #include "Evolution/Initialization/InitialData.hpp"
20 : #include "NumericalAlgorithms/Spectral/Mesh.hpp"
21 : #include "PointwiseFunctions/AnalyticData/Tags.hpp"
22 : #include "PointwiseFunctions/InitialDataUtilities/InitialData.hpp"
23 : #include "PointwiseFunctions/InitialDataUtilities/Tags/InitialData.hpp"
24 : #include "Time/Tags/Time.hpp"
25 : #include "Utilities/CallWithDynamicType.hpp"
26 : #include "Utilities/Gsl.hpp"
27 : #include "Utilities/ProtocolHelpers.hpp"
28 : #include "Utilities/TMPL.hpp"
29 : #include "Utilities/TypeTraits/CreateGetTypeAliasOrDefault.hpp"
30 :
31 : namespace evolution::dg {
32 :
33 : /*!
34 : * \brief Allocate or assign background general relativity quantities needed
35 : * for evolution systems run on a curved spacetime without solving Einstein
36 : * equations (e.g. ValenciaDivclean, ForceFree).
37 : *
38 : * \warning This mutator assumes that the GR analytic data or solution
39 : * specifying background spacetime metric is time-independent.
40 : *
41 : */
42 : template <typename System, typename Metavariables>
43 1 : struct BackgroundGrVars : tt::ConformsTo<db::protocols::Mutator> {
44 : private:
45 : CREATE_GET_TYPE_ALIAS_OR_DEFAULT(flux_spacetime_variables_tag)
46 :
47 0 : struct EmptyStruct {
48 0 : using tags_list = tmpl::list<>;
49 : };
50 :
51 : public:
52 0 : static constexpr size_t volume_dim = System::volume_dim;
53 :
54 : // Collect all the GR quantities used in the templated evolution system
55 0 : using gr_variables_tag = ::Tags::Variables<tmpl::remove_duplicates<
56 : tmpl::append<typename System::spacetime_variables_tag::tags_list,
57 : typename get_flux_spacetime_variables_tag_or_default_t<
58 : System, EmptyStruct>::tags_list,
59 : tmpl::list<typename System::inverse_spatial_metric_tag>>>>;
60 :
61 0 : using GrVars = typename gr_variables_tag::type;
62 :
63 0 : using argument_tags =
64 : tmpl::list<::Tags::Time, domain::Tags::Domain<volume_dim>,
65 : domain::Tags::Coordinates<volume_dim, Frame::Inertial>,
66 : domain::Tags::Mesh<volume_dim>,
67 : domain::Tags::Element<volume_dim>,
68 : evolution::initial_data::Tags::InitialData>;
69 :
70 0 : using return_tags = tmpl::list<gr_variables_tag>;
71 :
72 : template <typename T>
73 0 : static void apply(
74 : const gsl::not_null<GrVars*> background_gr_vars, const double time,
75 : const Domain<volume_dim>& domain,
76 : const tnsr::I<DataVector, volume_dim, Frame::Inertial>& inertial_coords,
77 : const Mesh<volume_dim>& mesh, const Element<volume_dim>& element,
78 : const T& solution_or_data) {
79 : const size_t num_grid_pts = mesh.number_of_grid_points();
80 :
81 : if (background_gr_vars->number_of_grid_points() != 0) { // Evolution phase
82 : ASSERT((*background_gr_vars).number_of_grid_points() == num_grid_pts,
83 : "The size of GR variables ("
84 : << (*background_gr_vars).number_of_grid_points()
85 : << ") is not equal to the number of grid points ("
86 : << mesh.number_of_grid_points() << ").");
87 :
88 : // Check if the mesh is actually moving i.e. block coordinate map is
89 : // time-dependent. If not, we can skip the evaluation of GR variables
90 : // since they may stay with their values assigned at the initialization
91 : // phase.
92 : const auto& element_id = element.id();
93 : const size_t block_id = element_id.block_id();
94 : const Block<volume_dim>& block = domain.blocks()[block_id];
95 : if (block.is_time_dependent()) {
96 : impl(background_gr_vars, time, inertial_coords, solution_or_data);
97 : }
98 : } else {
99 : // Initialization phase
100 : (*background_gr_vars).initialize(num_grid_pts);
101 : impl(background_gr_vars, time, inertial_coords, solution_or_data);
102 : }
103 : }
104 :
105 : private:
106 : template <typename T>
107 0 : static void impl(
108 : const gsl::not_null<GrVars*> background_gr_vars, const double time,
109 : const tnsr::I<DataVector, volume_dim, Frame::Inertial>& inertial_coords,
110 : const T& solution_or_data) {
111 : using derived_classes =
112 : tmpl::at<typename Metavariables::factory_creation::factory_classes,
113 : evolution::initial_data::InitialData>;
114 : call_with_dynamic_type<void, derived_classes>(
115 : &solution_or_data, [&background_gr_vars, &inertial_coords,
116 : &time](const auto* const solution_or_data_ptr) {
117 : (*background_gr_vars)
118 : .assign_subset(evolution::Initialization::initial_data(
119 : *solution_or_data_ptr, inertial_coords, time,
120 : typename GrVars::tags_list{}));
121 : });
122 : }
123 : };
124 :
125 : } // namespace evolution::dg
|