SpECTRE Documentation Coverage Report
Current view: top level - Evolution/Systems/SecondOrderScalarWave/BoundaryConditions - DirichletCharacteristics.hpp Coverage Total Hit
Commit: 0d1d717af84a81fb1284a20c4013708fe85cc2f0 Lines: 12.1 % 33 4
Test Date: 2026-10-22 17:29:42
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 <cstddef>
       7              : #include <memory>
       8              : #include <optional>
       9              : #include <string>
      10              : 
      11              : #include "DataStructures/DataVector.hpp"
      12              : #include "DataStructures/Tensor/TypeAliases.hpp"
      13              : #include "Evolution/BoundaryConditions/Type.hpp"
      14              : #include "Evolution/Systems/SecondOrderScalarWave/BoundaryConditions/BoundaryCondition.hpp"
      15              : #include "Evolution/Systems/SecondOrderScalarWave/Tags.hpp"
      16              : #include "Options/Auto.hpp"
      17              : #include "Options/String.hpp"
      18              : #include "PointwiseFunctions/InitialDataUtilities/InitialData.hpp"
      19              : #include "Utilities/Gsl.hpp"
      20              : #include "Utilities/Serialization/CharmPupable.hpp"
      21              : #include "Utilities/TMPL.hpp"  // IWYU pragma: keep
      22              : 
      23              : /// \cond
      24              : namespace PUP {
      25              : class er;
      26              : }  // namespace PUP
      27              : namespace Tags {
      28              : struct Time;
      29              : }  // namespace Tags
      30              : namespace domain::Tags {
      31              : template <size_t Dim, typename Frame>
      32              : struct Coordinates;
      33              : }  // namespace domain::Tags
      34              : /// \endcond
      35              : 
      36              : namespace SecondOrderScalarWave::BoundaryConditions {
      37              : /*!
      38              :  * \brief Sets boundary conditions using the characteristic decomposition: the
      39              :  * incoming mode is set from analytic data, the outgoing and zero-speed modes
      40              :  * from the interior.
      41              :  *
      42              :  * If \f$n^i\f$ is the outward pointing unit normal at the external boundary,
      43              :  * the characteristic fields and their speeds are (see
      44              :  * `SecondOrderScalarWave::characteristic_fields`):
      45              :  * - \f$v^+ = \Pi + n^i\Phi_i\f$: speed \f$+1\f$ (outgoing, taken from the
      46              :  *   interior)
      47              :  * - \f$v^- = \Pi - n^i\Phi_i\f$: speed \f$-1\f$ (incoming, taken from the
      48              :  *   analytic data, or set to zero if `AnalyticPrescription` is
      49              :  *   `ZeroIncomingMode`)
      50              :  * - \f$v^0_i\f$: speed \f$0\f$ (taken from the interior)
      51              :  *
      52              :  * The ghost \f$\Pi\f$ and \f$\Phi_i\f$ are reconstructed from these modes.
      53              :  * The ghost \f$\Psi\f$ by default is the boundary-evolved
      54              :  * `evolution::dg::Tags::BoundaryValue<Tags::Psi>`, integrated per face using
      55              :  * the interior evolution equation defined in `boundary_field_time_derivatives`.
      56              :  * If `CopyPsiFromInterior` is true the ghost \f$\Psi\f$ is instead the interior
      57              :  * evolved \f$\Psi\f$; the boundary value is still integrated but unused.
      58              :  *
      59              :  * Moving meshes are not supported: the characteristic speeds are defined
      60              :  * without a mesh velocity, so both member functions return an error if a face
      61              :  * mesh velocity is supplied.
      62              :  */
      63              : template <size_t Dim>
      64            1 : class DirichletCharacteristics final : public BoundaryCondition<Dim> {
      65              :  public:
      66              :   /// \brief Label for `AnalyticPrescription` setting the incoming
      67              :   /// characteristic mode \f$v^-\f$ to zero.
      68            1 :   struct ZeroIncomingMode {};
      69              : 
      70              :   /// \brief What analytic solution to prescribe.
      71            1 :   struct AnalyticPrescription {
      72            0 :     static constexpr Options::String help =
      73              :         "What analytic solution to prescribe, or ZeroIncomingMode to set the "
      74              :         "incoming characteristic mode to zero.";
      75            0 :     using type =
      76              :         Options::Auto<std::unique_ptr<evolution::initial_data::InitialData>,
      77              :                       ZeroIncomingMode>;
      78              :   };
      79              : 
      80              :   /// \brief If true, the ghost Psi is copied from the interior
      81              :   /// instead of the boundary-evolved value.
      82            1 :   struct CopyPsiFromInterior {
      83            0 :     static constexpr Options::String help =
      84              :         "If true, ghost Psi is copied from the interior instead of the "
      85              :         "boundary-evolved value.";
      86            0 :     using type = bool;
      87              :   };
      88              : 
      89            0 :   using options = tmpl::list<AnalyticPrescription, CopyPsiFromInterior>;
      90              : 
      91            0 :   static constexpr Options::String help{
      92              :       "Analytic boundary condition using the characteristic decomposition. The "
      93              :       "incoming mode is set from analytic data, the outgoing and zero-speed "
      94              :       "modes copied from the interior. The evolved variable Pi and the "
      95              :       "auxiliary variable Phi are reconstructed from the characteristic modes. "
      96              :       "The ghost Psi is the boundary-evolved value if CopyPsiFromInterior is "
      97              :       "false. Otherwise, the ghost Psi is copied from the interior."};
      98              : 
      99            0 :   DirichletCharacteristics() = default;
     100            0 :   DirichletCharacteristics(DirichletCharacteristics&&) = default;
     101            0 :   DirichletCharacteristics& operator=(DirichletCharacteristics&&) = default;
     102            0 :   DirichletCharacteristics(const DirichletCharacteristics&);
     103            0 :   DirichletCharacteristics& operator=(const DirichletCharacteristics&);
     104            0 :   ~DirichletCharacteristics() override = default;
     105              : 
     106            0 :   DirichletCharacteristics(
     107              :       std::optional<std::unique_ptr<evolution::initial_data::InitialData>>
     108              :           analytic_prescription,
     109              :       bool copy_psi_from_interior);
     110              : 
     111            0 :   explicit DirichletCharacteristics(CkMigrateMessage* msg);
     112              : 
     113            0 :   WRAPPED_PUPable_decl_base_template(  // NOLINT
     114              :       domain::BoundaryConditions::BoundaryCondition, DirichletCharacteristics);
     115              : 
     116            0 :   auto get_clone() const -> std::unique_ptr<
     117              :       domain::BoundaryConditions::BoundaryCondition> override;
     118              : 
     119            0 :   static constexpr evolution::BoundaryConditions::Type bc_type =
     120              :       evolution::BoundaryConditions::Type::Ghost;
     121              : 
     122            0 :   void pup(PUP::er& p) override;
     123              : 
     124            0 :   static constexpr bool evolves_boundary_variables = true;
     125              : 
     126            0 :   using dg_interior_evolved_variables_tags =
     127              :       tmpl::list<Tags::Psi, Tags::Pi, Tags::Phi<Dim>>;
     128            0 :   using dg_interior_temporary_tags =
     129              :       tmpl::list<domain::Tags::Coordinates<Dim, Frame::Inertial>>;
     130            0 :   using dg_gridless_tags = tmpl::list<::Tags::Time>;
     131              : 
     132            0 :   using boundary_field_time_derivatives_evolved_variables_tags =
     133              :       tmpl::list<Tags::Pi, Tags::Phi<Dim>>;
     134            0 :   using boundary_field_time_derivatives_temporary_tags =
     135              :       tmpl::list<domain::Tags::Coordinates<Dim, Frame::Inertial>>;
     136              : 
     137            0 :   std::optional<std::string> dg_ghost(
     138              :       gsl::not_null<Scalar<DataVector>*> psi,
     139              :       gsl::not_null<Scalar<DataVector>*> pi,
     140              :       gsl::not_null<tnsr::i<DataVector, Dim, Frame::Inertial>*> phi,
     141              :       const std::optional<tnsr::I<DataVector, Dim, Frame::Inertial>>&
     142              :           face_mesh_velocity,
     143              :       const tnsr::i<DataVector, Dim, Frame::Inertial>& normal_covector,
     144              :       const Scalar<DataVector>& boundary_psi,
     145              :       const Scalar<DataVector>& interior_psi,
     146              :       const Scalar<DataVector>& interior_pi,
     147              :       const tnsr::i<DataVector, Dim, Frame::Inertial>& interior_phi,
     148              :       const tnsr::I<DataVector, Dim, Frame::Inertial>& coords,
     149              :       double time) const;
     150              : 
     151            0 :   std::optional<std::string> boundary_field_time_derivatives(
     152              :       gsl::not_null<Scalar<DataVector>*> dt_boundary_psi,
     153              :       const std::optional<tnsr::I<DataVector, Dim, Frame::Inertial>>&
     154              :           face_mesh_velocity,
     155              :       const tnsr::i<DataVector, Dim, Frame::Inertial>& normal_covector,
     156              :       const Scalar<DataVector>& boundary_psi,
     157              :       const Scalar<DataVector>& interior_pi,
     158              :       const tnsr::i<DataVector, Dim, Frame::Inertial>& interior_phi,
     159              :       const tnsr::I<DataVector, Dim, Frame::Inertial>& coords,
     160              :       double time) const;
     161              : 
     162              :  private:
     163            0 :   std::unique_ptr<evolution::initial_data::InitialData> analytic_prescription_;
     164            0 :   bool copy_psi_from_interior_{false};
     165              : };
     166              : }  // namespace SecondOrderScalarWave::BoundaryConditions
        

Generated by: LCOV version 2.0-1