SpECTRE Documentation Coverage Report
Current view: top level - Evolution/Systems/ScalarWave/BoundaryConditions - ConstraintPreservingSphericalRadiation.hpp Hit Total Coverage
Commit: 52f20d7d69c179a8fabd675cc9d8c5355c7d621c Lines: 1 22 4.5 %
Date: 2024-04-17 15:32:38
Legend: Lines: hit not hit

          Line data    Source code
       1           0 : // Distributed under the MIT License.
       2             : // See LICENSE.txt for details.
       3             : 
       4             : #pragma once
       5             : 
       6             : #include <memory>
       7             : #include <optional>
       8             : #include <pup.h>
       9             : #include <string>
      10             : #include <type_traits>
      11             : 
      12             : #include "DataStructures/DataBox/Prefixes.hpp"
      13             : #include "DataStructures/DataVector.hpp"
      14             : #include "DataStructures/Tensor/Tensor.hpp"
      15             : #include "DataStructures/Variables.hpp"
      16             : #include "Evolution/BoundaryConditions/Type.hpp"
      17             : #include "Evolution/Systems/ScalarWave/BoundaryConditions/BoundaryCondition.hpp"
      18             : #include "Evolution/Systems/ScalarWave/Tags.hpp"
      19             : #include "NumericalAlgorithms/LinearOperators/PartialDerivatives.hpp"
      20             : #include "Options/Options.hpp"
      21             : #include "Options/String.hpp"
      22             : #include "PointwiseFunctions/AnalyticData/Tags.hpp"
      23             : #include "PointwiseFunctions/AnalyticSolutions/AnalyticSolution.hpp"
      24             : #include "Utilities/Gsl.hpp"
      25             : #include "Utilities/Serialization/CharmPupable.hpp"
      26             : #include "Utilities/TMPL.hpp"
      27             : 
      28             : /// \cond
      29             : namespace domain::Tags {
      30             : template <size_t Dim, typename Frame>
      31             : struct Coordinates;
      32             : }  // namespace domain::Tags
      33             : /// \endcond
      34             : 
      35             : namespace ScalarWave::BoundaryConditions {
      36             : namespace detail {
      37             : /// The type of spherical radiation boundary condition to impose
      38             : enum class ConstraintPreservingSphericalRadiationType {
      39             :   /// Impose \f$(\partial_t + \partial_r)\Psi=0\f$
      40             :   Sommerfeld,
      41             :   /// Impose \f$(\partial_t + \partial_r + r^{-1})\Psi=0\f$
      42             :   FirstOrderBaylissTurkel,
      43             :   /// Imposes a second-order Bayliss-Turkel boundary condition
      44             :   SecondOrderBaylissTurkel
      45             : };
      46             : 
      47             : ConstraintPreservingSphericalRadiationType
      48             : convert_constraint_preserving_spherical_radiation_type_from_yaml(
      49             :     const Options::Option& options);
      50             : }  // namespace detail
      51             : 
      52             : /*!
      53             :  * \brief Constraint-preserving spherical radiation boundary condition that
      54             :  * seeks to avoid ingoing constraint violations and radiation.
      55             :  *
      56             :  * The constraint-preserving part of the boundary condition imposes the
      57             :  * following condition on the time derivatives of the characteristic fields:
      58             :  *
      59             :  * \f{align*}{
      60             :  *   d_tw^\Psi&\to d_tw^{\Psi}+\lambda_{\Psi}n^i\mathcal{C}_i, \\
      61             :  *   d_tw^0_i&\to d_tw^{0}_i+\lambda_{0}n^jP^k_i\mathcal{C}_{ik},
      62             :  * \f}
      63             :  *
      64             :  * where
      65             :  *
      66             :  * \f{align*}{
      67             :  * P^k{}_i=\delta^k_i-n^kn_i
      68             :  * \f}
      69             :  *
      70             :  * projects a tensor onto the spatial surface to which \f$n_i\f$ is normal, and
      71             :  * \f$d_t w\f$ is the evolved to characteristic field transformation applied to
      72             :  * the time derivatives of the evolved fields. That is,
      73             :  *
      74             :  * \f{align*}{
      75             :  * d_t w^\Psi&=\partial_t \Psi, \\
      76             :  * d_t w_i^0&=(\delta^k_i-n^k n_i)\partial_t \Phi_k, \\
      77             :  * d_t w^{\pm}&=\partial_t\Pi\pm n^k\partial_t\Phi_k - \gamma_2\partial_t\Psi.
      78             :  * \f}
      79             :  *
      80             :  * The constraints are defined as:
      81             :  *
      82             :  * \f{align*}{
      83             :  *  \mathcal{C}_i&=\partial_i\Psi - \Phi_i=0, \\
      84             :  *  \mathcal{C}_{ij}&=\partial_{[i}\Phi_{j]}=0
      85             :  * \f}
      86             :  *
      87             :  * Radiation boundary conditions impose a condition on \f$\Pi\f$ or its time
      88             :  * derivative. We denote the boundary condition value of the time derivative of
      89             :  * \f$\Pi\f$ by \f$\partial_t\Pi^{\mathrm{BC}}\f$. With this, we can impose
      90             :  * boundary conditions on the time derivatives of the evolved variables as
      91             :  * follows:
      92             :  *
      93             :  * \f{align*}{
      94             :  * \partial_{t} \Psi&\to\partial_{t}\Psi +
      95             :  *                    \lambda_\Psi n^i \mathcal{C}_i, \\
      96             :  * \partial_{t}\Pi&\to\partial_{t}\Pi-\left(\partial_t\Pi
      97             :  *                  - \partial_t\Pi^{\mathrm{BC}}\right)
      98             :  *                  +\gamma_2\lambda_\Psi n^i \mathcal{C}_i
      99             :  *                  =\partial_t\Pi^{\mathrm{BC}}
     100             :  *                  +\gamma_2\lambda_\Psi n^i \mathcal{C}_i, \\
     101             :  * \partial_{t}\Phi_i&\to\partial_{t}\Phi_i+ 2 \lambda_0n^j \mathcal{C}_{ji}.
     102             :  * \f}
     103             :  *
     104             :  * Below we assume the normal vector \f$n^i\f$ is the radial unit normal vector.
     105             :  * That is, we assume the outer boundary is spherical. A Sommerfeld
     106             :  * \cite Sommerfeld1949 radiation condition is given by
     107             :  *
     108             :  * \f{align*}{
     109             :  *  \partial_t\Psi=n^i\Phi_i
     110             :  * \f}
     111             :  *
     112             :  * Or, assuming that \f$\partial_tn^i=0\f$ (or is very small),
     113             :  *
     114             :  * \f{align*}{
     115             :  *  \partial_t\Pi^{\mathrm{BC}}=n^i\partial_t\Phi_i
     116             :  * \f}
     117             :  *
     118             :  * The Bayliss-Turkel \cite BaylissTurkel boundary conditions are given by:
     119             :  *
     120             :  * \f{align*}{
     121             :  *  \prod_{l=1}^m\left(\partial_t + \partial_r + \frac{2l-1}{r}\right)\Psi=0
     122             :  * \f}
     123             :  *
     124             :  * The first-order form is
     125             :  *
     126             :  * \f{align*}{
     127             :  *  \partial_t\Pi^{\mathrm{BC}}=n^i\partial_t\Phi_i + \frac{1}{r}\partial_t\Psi,
     128             :  * \f}
     129             :  *
     130             :  * assuming \f$\partial_t n^i=0\f$ and \f$\partial_t r=0\f$.
     131             :  *
     132             :  * The second-order boundary condition is given by,
     133             :  *
     134             :  * \f{align*}{
     135             :  *  \partial_t\Pi^{\mathrm{BC}}
     136             :  *   &=\left(\partial_t\partial_r + \partial_r\partial_t +
     137             :  *     \partial_r^2+\frac{4}{r}\partial_t
     138             :  *     +\frac{4}{r}\partial_r + \frac{2}{r^2}\right)\Psi \notag \\
     139             :  *     &=n^i(\partial_t\Phi_i-\partial_i\Pi) + n^i n^j\partial_i\Phi_j -
     140             :  *     \frac{4}{r}\Pi+\frac{4}{r}n^i\Phi_i + \frac{2}{r^2}\Psi \notag \\
     141             :  *     &=n^i(\gamma_2(\partial_i\Psi - \Phi_i)-2\partial_i\Pi)
     142             :  *     + n^i n^j\partial_i\Phi_j -
     143             :  *     \frac{4}{r}\Pi+\frac{4}{r}n^i\Phi_i + \frac{2}{r^2}\Psi,
     144             :  * \f}
     145             :  *
     146             :  * where \f$\partial_t\f$ is the derivative with respect to the inertial frame
     147             :  * time, and we are assuming \f$\partial_t n^i=0\f$ and \f$\partial_t r=0\f$.
     148             :  *
     149             :  * The moving mesh can be accounted for by using
     150             :  *
     151             :  * \f{align*}{
     152             :  * \partial_t r = \frac{1}{r}x^i\delta_{ij}\partial_t x^j
     153             :  * \f}
     154             :  *
     155             :  * \note It is not clear if \f$\partial_t\Phi_i\f$ should be replaced by
     156             :  * \f$-\partial_i\Pi\f$, which is the evolution equation but without the
     157             :  * constraint.
     158             :  *
     159             :  * \note On a moving mesh the characteristic speeds change according to
     160             :  * \f$\lambda\to\lambda-v^i_gn_i\f$ where \f$v^i_g\f$ is the mesh velocity.
     161             :  *
     162             :  * \note For the scalar wave system \f$\lambda_0 = \lambda_\psi\f$
     163             :  *
     164             :  * \warning The boundary conditions are implemented assuming the outer boundary
     165             :  * is spherical. It might be possible to generalize the condition to
     166             :  * non-spherical boundaries by using \f$x^i/r\f$ instead of \f$n^i\f$, but this
     167             :  * hasn't been tested.
     168             :  *
     169             :  * \warning The received time derivatives are in the logical frame, not the
     170             :  * inertial frame and would need to first be corrected by subtracting the mesh
     171             :  * velocity. Similarly, the time derivative correction is in the logical frame.
     172             :  * We instead substitute the evolution equations directly in since the scalar
     173             :  * wave system is quite simple.
     174             :  */
     175             : template <size_t Dim>
     176           1 : class ConstraintPreservingSphericalRadiation final
     177             :     : public BoundaryCondition<Dim> {
     178             :  public:
     179           0 :   struct TypeOptionTag {
     180           0 :     using type = detail::ConstraintPreservingSphericalRadiationType;
     181           0 :     static std::string name() { return "Type"; }
     182           0 :     static constexpr Options::String help{
     183             :         "Whether to impose Sommerfeld, first-order Bayliss-Turkel, or "
     184             :         "second-order Bayliss-Turkel spherical radiation boundary conditions."};
     185             :   };
     186             : 
     187           0 :   using options = tmpl::list<TypeOptionTag>;
     188           0 :   static constexpr Options::String help{
     189             :       "Constraint-preserving spherical radiation boundary conditions setting "
     190             :       "the time derivatives of Psi, Phi, and Pi to avoid incoming constraint "
     191             :       "violations, and imposing radiation boundary conditions."};
     192             : 
     193           0 :   ConstraintPreservingSphericalRadiation(
     194             :       detail::ConstraintPreservingSphericalRadiationType type);
     195             : 
     196           0 :   ConstraintPreservingSphericalRadiation() = default;
     197             :   /// \cond
     198             :   ConstraintPreservingSphericalRadiation(
     199             :       ConstraintPreservingSphericalRadiation&&) = default;
     200             :   ConstraintPreservingSphericalRadiation& operator=(
     201             :       ConstraintPreservingSphericalRadiation&&) = default;
     202             :   ConstraintPreservingSphericalRadiation(
     203             :       const ConstraintPreservingSphericalRadiation&) = default;
     204             :   ConstraintPreservingSphericalRadiation& operator=(
     205             :       const ConstraintPreservingSphericalRadiation&) = default;
     206             :   /// \endcond
     207           0 :   ~ConstraintPreservingSphericalRadiation() override = default;
     208             : 
     209           0 :   explicit ConstraintPreservingSphericalRadiation(CkMigrateMessage* msg);
     210             : 
     211           0 :   WRAPPED_PUPable_decl_base_template(
     212             :       domain::BoundaryConditions::BoundaryCondition,
     213             :       ConstraintPreservingSphericalRadiation);
     214             : 
     215           0 :   auto get_clone() const -> std::unique_ptr<
     216             :       domain::BoundaryConditions::BoundaryCondition> override;
     217             : 
     218           0 :   static constexpr evolution::BoundaryConditions::Type bc_type =
     219             :       evolution::BoundaryConditions::Type::TimeDerivative;
     220             : 
     221           0 :   void pup(PUP::er& p) override;
     222             : 
     223           0 :   using dg_interior_evolved_variables_tags =
     224             :       tmpl::list<ScalarWave::Tags::Psi, ScalarWave::Tags::Pi,
     225             :                  ScalarWave::Tags::Phi<Dim>>;
     226           0 :   using dg_interior_temporary_tags =
     227             :       tmpl::list<domain::Tags::Coordinates<Dim, Frame::Inertial>,
     228             :                  Tags::ConstraintGamma2>;
     229             :   // using dg_interior_dt_vars_tags = tmpl::list<>;
     230           0 :   using dg_interior_deriv_vars_tags = tmpl::list<
     231             :       ::Tags::deriv<ScalarWave::Tags::Psi, tmpl::size_t<Dim>, Frame::Inertial>,
     232             :       ::Tags::deriv<ScalarWave::Tags::Pi, tmpl::size_t<Dim>, Frame::Inertial>,
     233             :       ::Tags::deriv<ScalarWave::Tags::Phi<Dim>, tmpl::size_t<Dim>,
     234             :                     Frame::Inertial>>;
     235           0 :   using dg_gridless_tags = tmpl::list<>;
     236             : 
     237           0 :   std::optional<std::string> dg_time_derivative(
     238             :       gsl::not_null<Scalar<DataVector>*> dt_psi_correction,
     239             :       gsl::not_null<Scalar<DataVector>*> dt_pi_correction,
     240             :       gsl::not_null<tnsr::i<DataVector, Dim, Frame::Inertial>*>
     241             :           dt_phi_correction,
     242             : 
     243             :       const std::optional<tnsr::I<DataVector, Dim, Frame::Inertial>>&
     244             :           face_mesh_velocity,
     245             :       const tnsr::i<DataVector, Dim, Frame::Inertial>& normal_covector,
     246             : 
     247             :       const Scalar<DataVector>& psi, const Scalar<DataVector>& pi,
     248             :       const tnsr::i<DataVector, Dim, Frame::Inertial>& phi,
     249             : 
     250             :       const tnsr::I<DataVector, Dim, Frame::Inertial>& coords,
     251             :       const Scalar<DataVector>& gamma2,
     252             : 
     253             :       const tnsr::i<DataVector, Dim, Frame::Inertial>& d_psi,
     254             :       const tnsr::i<DataVector, Dim, Frame::Inertial>& d_pi,
     255             :       const tnsr::ij<DataVector, Dim, Frame::Inertial>& d_phi) const;
     256             : 
     257             :  private:
     258           0 :   detail::ConstraintPreservingSphericalRadiationType type_{
     259             :       detail::ConstraintPreservingSphericalRadiationType::Sommerfeld};
     260             : };
     261             : }  // namespace ScalarWave::BoundaryConditions
     262             : 
     263             : template <>
     264             : struct Options::create_from_yaml<
     265             :     ScalarWave::BoundaryConditions::detail::
     266             :         ConstraintPreservingSphericalRadiationType> {
     267             :   template <typename Metavariables>
     268             :   static typename ScalarWave::BoundaryConditions::detail::
     269             :       ConstraintPreservingSphericalRadiationType
     270             :       create(const Options::Option& options) {
     271             :     return ScalarWave::BoundaryConditions::detail::
     272             :         convert_constraint_preserving_spherical_radiation_type_from_yaml(
     273             :             options);
     274             :   }
     275             : };

Generated by: LCOV version 1.14