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 0 : namespace { 34 : CREATE_GET_TYPE_ALIAS_OR_DEFAULT(flux_spacetime_variables_tag) 35 : 36 : struct EmptyStruct { 37 : using tags_list = tmpl::list<>; 38 : }; 39 : } // namespace 40 : 41 : /*! 42 : * \brief Allocate or assign background general relativity quantities needed 43 : * for evolution systems run on a curved spacetime without solving Einstein 44 : * equations (e.g. ValenciaDivclean, ForceFree). 45 : * 46 : * \warning This mutator assumes that the GR analytic data or solution 47 : * specifying background spacetime metric is time-independent. 48 : * 49 : */ 50 : template <typename System, typename Metavariables, bool UsingRuntimeId> 51 1 : struct BackgroundGrVars : tt::ConformsTo<db::protocols::Mutator> { 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 : tmpl::conditional_t<UsingRuntimeId, 69 : evolution::initial_data::Tags::InitialData, 70 : ::Tags::AnalyticSolutionOrData>>; 71 : 72 0 : using return_tags = tmpl::list<gr_variables_tag>; 73 : 74 : template <typename T> 75 0 : static void apply( 76 : const gsl::not_null<GrVars*> background_gr_vars, const double time, 77 : const Domain<volume_dim>& domain, 78 : const tnsr::I<DataVector, volume_dim, Frame::Inertial>& inertial_coords, 79 : const Mesh<volume_dim>& mesh, const Element<volume_dim>& element, 80 : const T& solution_or_data) { 81 : const size_t num_grid_pts = mesh.number_of_grid_points(); 82 : 83 : if (background_gr_vars->number_of_grid_points() != 0) { // Evolution phase 84 : ASSERT((*background_gr_vars).number_of_grid_points() == num_grid_pts, 85 : "The size of GR variables (" 86 : << (*background_gr_vars).number_of_grid_points() 87 : << ") is not equal to the number of grid points (" 88 : << mesh.number_of_grid_points() << ")."); 89 : 90 : // Check if the mesh is actually moving i.e. block coordinate map is 91 : // time-dependent. If not, we can skip the evaluation of GR variables 92 : // since they may stay with their values assigned at the initialization 93 : // phase. 94 : const auto& element_id = element.id(); 95 : const size_t block_id = element_id.block_id(); 96 : const Block<volume_dim>& block = domain.blocks()[block_id]; 97 : if (block.is_time_dependent()) { 98 : impl(background_gr_vars, time, inertial_coords, solution_or_data); 99 : } 100 : } else { 101 : // Initialization phase 102 : (*background_gr_vars).initialize(num_grid_pts); 103 : impl(background_gr_vars, time, inertial_coords, solution_or_data); 104 : } 105 : } 106 : 107 : private: 108 : template <typename T> 109 0 : static void impl( 110 : const gsl::not_null<GrVars*> background_gr_vars, const double time, 111 : const tnsr::I<DataVector, volume_dim, Frame::Inertial>& inertial_coords, 112 : const T& solution_or_data) { 113 : if constexpr (UsingRuntimeId) { 114 : using derived_classes = 115 : tmpl::at<typename Metavariables::factory_creation::factory_classes, 116 : evolution::initial_data::InitialData>; 117 : call_with_dynamic_type<void, derived_classes>( 118 : &solution_or_data, [&background_gr_vars, &inertial_coords, 119 : &time](const auto* const solution_or_data_ptr) { 120 : (*background_gr_vars) 121 : .assign_subset(evolution::Initialization::initial_data( 122 : *solution_or_data_ptr, inertial_coords, time, 123 : typename GrVars::tags_list{})); 124 : }); 125 : } else { 126 : (*background_gr_vars) 127 : .assign_subset(evolution::Initialization::initial_data( 128 : solution_or_data, inertial_coords, time, 129 : typename GrVars::tags_list{})); 130 : } 131 : } 132 : }; 133 : 134 : } // namespace evolution::dg