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 "Domain/Tags.hpp" 12 : #include "Evolution/Initialization/InitialData.hpp" 13 : #include "Evolution/Initialization/Tags.hpp" 14 : #include "Evolution/Systems/CurvedScalarWave/BackgroundSpacetime.hpp" 15 : #include "Evolution/Systems/CurvedScalarWave/System.hpp" 16 : #include "Evolution/Systems/ScalarWave/System.hpp" 17 : #include "Evolution/Systems/ScalarWave/TagsDeclarations.hpp" 18 : #include "NumericalAlgorithms/Spectral/Mesh.hpp" 19 : #include "PointwiseFunctions/AnalyticData/Tags.hpp" 20 : #include "Utilities/ProtocolHelpers.hpp" 21 : 22 : /// \cond 23 : namespace Tags { 24 : struct Time; 25 : } // namespace Tags 26 : /// \endcond 27 : 28 0 : namespace CurvedScalarWave::Initialization { 29 : /// \ingroup InitializationGroup 30 : /// \brief Mutator meant to be used with 31 : /// `Initialization::Actions::AddSimpleTags` to initialize the constraint 32 : /// damping parameters of the CurvedScalarWave system 33 : /// 34 : /// DataBox changes: 35 : /// - Adds: 36 : /// * `CurvedScalarWave::Tags::ConstraintGamma1` 37 : /// * `CurvedScalarWave::Tags::ConstraintGamma2` 38 : /// - Removes: nothing 39 : /// - Modifies: nothing 40 : 41 : template <size_t Dim> 42 1 : struct InitializeConstraintDampingGammas 43 : : tt::ConformsTo<db::protocols::Mutator> { 44 0 : using return_tags = 45 : tmpl::list<Tags::ConstraintGamma1, Tags::ConstraintGamma2>; 46 0 : using argument_tags = tmpl::list<domain::Tags::Mesh<Dim>>; 47 : 48 0 : static void apply(const gsl::not_null<Scalar<DataVector>*> gamma1, 49 : const gsl::not_null<Scalar<DataVector>*> gamma2, 50 : const Mesh<Dim>& mesh) { 51 : const size_t number_of_grid_points = mesh.number_of_grid_points(); 52 : *gamma1 = Scalar<DataVector>{number_of_grid_points, 0.}; 53 : *gamma2 = Scalar<DataVector>{number_of_grid_points, 1.}; 54 : } 55 : }; 56 : 57 : /*! 58 : * \brief Analytic initial data for scalar waves in curved spacetime 59 : * 60 : * \details When evolving a scalar field propagating through curved spacetime, 61 : * this mutator initializes the scalar field and spacetime variables using 62 : * 63 : * 1. analytic solution(s) or data of the flat or curved scalar wave equation 64 : * for the evolution variables 65 : * 2. solutions of the Einstein equations for the spacetime background. 66 : * 67 : * If the scalar field initial data returns `CurvedScalarWave` tags, \f$\Psi\f$, 68 : * \f$\Pi\f$ and \f$\Phi_i\f$ will simply be forwarded from the initial data 69 : * class. Alternatively, the scalar field initial data can be provided using any 70 : * member class of `ScalarWave::Solutions` which return `ScalarWave` tags. In 71 : * this case, \f$\Phi_i\f$ and \f$\Psi\f$ will also be forwarded but 72 : * \f$\Pi\f$ will be adjusted to account for the curved background. Its 73 : * definition comes from requiring it to be the future-directed time derivative 74 : * of the scalar field in curved spacetime: 75 : * 76 : * \f{align} 77 : * \Pi :=& -n^a \partial_a \Psi \\ 78 : * =& \frac{1}{\alpha}\left(\beta^k \Phi_k - {\partial_t\Psi}\right),\\ 79 : * =& \frac{1}{\alpha}\left(\beta^k \Phi_k + {\Pi}_{\mathrm{flat}}\right), 80 : * \f} 81 : * 82 : * where \f$n^a\f$ is the unit normal to spatial slices of the spacetime 83 : * foliation, and \f${\Pi}_{\mathrm{flat}}\f$ comes from the flat spacetime 84 : * solution. 85 : * 86 : * DataBox changes: 87 : * - Adds: nothing 88 : * - Removes: nothing 89 : * - Modifies: Tags::Variables<tmpl::list<CurvedScalarWave::Tags::Psi, 90 : * CurvedScalarWave::Tags::Pi, CurvedScalarWave::Tags::Phi<Dim>>> 91 : */ 92 : 93 : template <size_t Dim> 94 1 : struct InitializeEvolvedVariables : tt::ConformsTo<db::protocols::Mutator> { 95 0 : using flat_variables_tag = typename ScalarWave::System<Dim>::variables_tag; 96 0 : using curved_variables_tag = 97 : typename CurvedScalarWave::System<Dim>::variables_tag; 98 0 : using return_tags = tmpl::list<curved_variables_tag>; 99 0 : using argument_tags = 100 : tmpl::list<::Tags::Time, domain::Tags::Coordinates<Dim, Frame::Inertial>, 101 : ::Tags::AnalyticSolutionOrData, gr::Tags::Lapse<DataVector>, 102 : gr::Tags::Shift<DataVector, Dim>>; 103 : template <typename AnalyticSolutionOrData> 104 0 : static void apply( 105 : const gsl::not_null<typename curved_variables_tag::type*> evolved_vars, 106 : const double initial_time, 107 : const tnsr::I<DataVector, Dim>& inertial_coords, 108 : const AnalyticSolutionOrData& solution_or_data, 109 : [[maybe_unused]] const Scalar<DataVector>& lapse, 110 : [[maybe_unused]] const tnsr::I<DataVector, Dim>& shift) { 111 : if constexpr (tmpl::list_contains_v<typename AnalyticSolutionOrData::tags, 112 : CurvedScalarWave::Tags::Psi>) { 113 : // for analytic solutions/data of the CurvedScalarWave system, the evolved 114 : // variables are all initialized directly from the solution. 115 : evolved_vars->assign_subset(evolution::Initialization::initial_data( 116 : solution_or_data, inertial_coords, initial_time, 117 : typename curved_variables_tag::tags_list{})); 118 : } else { 119 : // for analytic solutions/data of the ScalarWave system,`Psi` and `Phi` 120 : // are initialized directly from the solution but `Pi` will be adjusted to 121 : // account for the curved background. 122 : static_assert(tmpl::list_contains_v<typename AnalyticSolutionOrData::tags, 123 : ScalarWave::Tags::Psi>, 124 : "The initial data class must either calculate ScalarWave " 125 : "or CurvedScalarWave variables."); 126 : const auto initial_data = evolution::Initialization::initial_data( 127 : solution_or_data, inertial_coords, initial_time, 128 : typename flat_variables_tag::tags_list{}); 129 : 130 : get<CurvedScalarWave::Tags::Psi>(*evolved_vars) = 131 : get<ScalarWave::Tags::Psi>(initial_data); 132 : get<CurvedScalarWave::Tags::Phi<Dim>>(*evolved_vars) = 133 : get<ScalarWave::Tags::Phi<Dim>>(initial_data); 134 : const auto shift_dot_dpsi = 135 : dot_product(shift, get<ScalarWave::Tags::Phi<Dim>>(initial_data)); 136 : get(get<CurvedScalarWave::Tags::Pi>(*evolved_vars)) = 137 : (get(shift_dot_dpsi) + get(get<ScalarWave::Tags::Pi>(initial_data))) / 138 : get(lapse); 139 : } 140 : } 141 : }; 142 : 143 : } // namespace CurvedScalarWave::Initialization