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/DataBoxTag.hpp" 9 : #include "DataStructures/DataBox/Tag.hpp" 10 : #include "DataStructures/DataVector.hpp" 11 : #include "DataStructures/Tensor/Tensor.hpp" 12 : #include "Evolution/Systems/CurvedScalarWave/Constraints.hpp" 13 : #include "Evolution/Systems/CurvedScalarWave/Tags.hpp" 14 : #include "NumericalAlgorithms/LinearOperators/PartialDerivatives.hpp" 15 : #include "Options/String.hpp" 16 : #include "Utilities/TMPL.hpp" 17 : 18 : /*! 19 : * \brief Tags for the scalar tensor system. 20 : */ 21 : namespace ScalarTensor { 22 : namespace Tags { 23 : /*! 24 : * \brief Represents the trace-reversed stress-energy tensor of the scalar 25 : * field. 26 : */ 27 : template <typename DataType, size_t Dim, typename Fr = Frame::Inertial> 28 1 : struct TraceReversedStressEnergy : db::SimpleTag { 29 0 : using type = tnsr::aa<DataType, Dim, Fr>; 30 : }; 31 : 32 : /*! 33 : * \brief Tag holding the source term of the scalar equation. 34 : * 35 : * \details This tag hold the source term \f$ \mathcal{S} \f$, 36 : * entering a wave equation of the form 37 : * \f[ 38 : * \Box \Psi = \mathcal{S} ~. 39 : * \f] 40 : */ 41 1 : struct ScalarSource : db::SimpleTag { 42 0 : using type = Scalar<DataVector>; 43 : }; 44 : 45 : } // namespace Tags 46 : 47 0 : namespace OptionTags { 48 : /*! 49 : * \brief Scalar mass parameter. 50 : */ 51 1 : struct ScalarMass { 52 0 : static std::string name() { return "ScalarMass"; } 53 0 : using type = double; 54 0 : static constexpr Options::String help{ 55 : "Mass of the scalar field in code units"}; 56 : }; 57 : } // namespace OptionTags 58 : 59 : namespace Tags { 60 0 : struct ScalarMass : db::SimpleTag { 61 0 : using type = double; 62 0 : using option_tags = tmpl::list<OptionTags::ScalarMass>; 63 0 : static constexpr bool pass_metavariables = false; 64 0 : static double create_from_options(const double mass_psi) { return mass_psi; } 65 : }; 66 : 67 : /*! 68 : * \brief Prefix tag to avoid ambiguities when observing variables with the same 69 : * name in both parent systems. 70 : * \note Since we also add compute tags for these quantities, we do not make 71 : * this a derived class of `Tag`. Otherwise, we would have tags with repeated 72 : * base tags in the `ObservationBox`. 73 : */ 74 : template <typename Tag> 75 1 : struct Csw : db::PrefixTag, db::SimpleTag { 76 0 : using type = typename Tag::type; 77 0 : using tag = Tag; 78 : }; 79 : 80 : /*! 81 : * \brief Compute tag to retrieve the values of CurvedScalarWave variables 82 : * with the same name as in the ::gh systems. 83 : * \note Since we also add compute tags for these quantities, we do not make 84 : * this a derived class of `Tag`. Otherwise, we would have tags with repeated 85 : * base tags in the `ObservationBox`. 86 : */ 87 : template <typename Tag> 88 1 : struct CswCompute : Csw<Tag>, db::ComputeTag { 89 0 : using argument_tags = tmpl::list<Tag>; 90 0 : using base = Csw<Tag>; 91 0 : using return_type = typename base::type; 92 0 : static constexpr void function(const gsl::not_null<return_type*> result, 93 : const return_type& csw_var) { 94 : for (size_t i = 0; i < csw_var.size(); ++i) { 95 : make_const_view(make_not_null(&std::as_const((*result)[i])), csw_var[i], 96 : 0, csw_var[i].size()); 97 : } 98 : } 99 : }; 100 : 101 : /*! 102 : * \brief Computes the scalar-wave one-index constraint. 103 : * \details The one-index constraint is assigned to a wrapped tag to avoid 104 : * clashes with the ::gh constraints during observation. 105 : * \note We do not use ScalarTensor::Tags::CswCompute to retrieve the 106 : * CurvedScalarWave constraints since we do not want to add the bare compute 107 : * tags (::CurvedScalarWave::Tags::OneIndexConstraintCompute and 108 : * ::CurvedScalarWave::Tags::TwoIndexConstraintCompute) directly in the 109 : * ObservationBox, since that will make them observable and would lead to a 110 : * clash with the ::gh constraint tags. 111 : */ 112 : template <size_t Dim> 113 1 : struct CswOneIndexConstraintCompute 114 : : Csw<CurvedScalarWave::Tags::OneIndexConstraint<Dim>>, 115 : db::ComputeTag { 116 0 : using argument_tags = 117 : tmpl::list<::Tags::deriv<CurvedScalarWave::Tags::Psi, tmpl::size_t<Dim>, 118 : Frame::Inertial>, 119 : CurvedScalarWave::Tags::Phi<Dim>>; 120 0 : using return_type = tnsr::i<DataVector, Dim>; 121 0 : static constexpr void (*function)(const gsl::not_null<return_type*> result, 122 : const tnsr::i<DataVector, Dim>&, 123 : const tnsr::i<DataVector, Dim>&) = 124 : &CurvedScalarWave::one_index_constraint<Dim>; 125 0 : using base = Csw<CurvedScalarWave::Tags::OneIndexConstraint<Dim>>; 126 : }; 127 : 128 : /*! 129 : * \brief Computes the scalar-wave two-index constraint. 130 : * \details The two-index constraint is assigned to a wrapped tag to avoid 131 : * clashes with the ::gh constraints during observation. 132 : * \note We do not use ScalarTensor::Tags::CswCompute to retrieve the 133 : * CurvedScalarWave constraints since we do not want to add the bare compute 134 : * tags (::CurvedScalarWave::Tags::OneIndexConstraintCompute and 135 : * ::CurvedScalarWave::Tags::TwoIndexConstraintCompute) directly in the 136 : * ObservationBox, since that will make them observable and would lead to a 137 : * clash with the ::gh constraint tags. 138 : */ 139 : template <size_t Dim> 140 1 : struct CswTwoIndexConstraintCompute 141 : : Csw<CurvedScalarWave::Tags::TwoIndexConstraint<Dim>>, 142 : db::ComputeTag { 143 0 : using argument_tags = 144 : tmpl::list<::Tags::deriv<CurvedScalarWave::Tags::Phi<Dim>, 145 : tmpl::size_t<Dim>, Frame::Inertial>>; 146 0 : using return_type = tnsr::ij<DataVector, Dim>; 147 0 : static constexpr void (*function)(const gsl::not_null<return_type*> result, 148 : const tnsr::ij<DataVector, Dim>&) = 149 : &CurvedScalarWave::two_index_constraint<Dim>; 150 0 : using base = Csw<CurvedScalarWave::Tags::TwoIndexConstraint<Dim>>; 151 : }; 152 : 153 : } // namespace Tags 154 : 155 : } // namespace ScalarTensor