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> 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 : 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