SpECTRE Documentation Coverage Report
Current view: top level - Evolution/DiscontinuousGalerkin/Initialization - BoundaryEvolvedVariables.hpp Hit Total Coverage
Commit: 107e15b340886ae54549b1baa4bfc92e676f667e Lines: 2 11 18.2 %
Date: 2026-09-17 16:38:56
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 <utility>
       8             : 
       9             : #include "DataStructures/DataBox/DataBox.hpp"
      10             : #include "DataStructures/Variables.hpp"
      11             : #include "Domain/BoundaryVariables.hpp"
      12             : #include "Domain/BoundaryVariablesTag.hpp"
      13             : #include "Domain/Creators/Tags/ExternalBoundaryConditions.hpp"
      14             : #include "Domain/Structure/Direction.hpp"
      15             : #include "Domain/Structure/DirectionMap.hpp"
      16             : #include "Domain/Structure/Element.hpp"
      17             : #include "Domain/Tags.hpp"
      18             : #include "Evolution/DiscontinuousGalerkin/BoundaryEvolvedVariables.hpp"
      19             : #include "NumericalAlgorithms/DiscontinuousGalerkin/ProjectToBoundary.hpp"
      20             : #include "NumericalAlgorithms/Spectral/Mesh.hpp"
      21             : #include "Parallel/AlgorithmExecution.hpp"
      22             : #include "Time/LtsMode.hpp"
      23             : #include "Time/Tags/LtsMode.hpp"
      24             : #include "Utilities/CallWithDynamicType.hpp"
      25             : #include "Utilities/ErrorHandling/Error.hpp"
      26             : #include "Utilities/Gsl.hpp"
      27             : #include "Utilities/TMPL.hpp"
      28             : 
      29             : /// \cond
      30             : namespace Parallel {
      31             : template <typename Metavariables>
      32             : class GlobalCache;
      33             : }  // namespace Parallel
      34             : namespace tuples {
      35             : template <class... Tags>
      36             : class TaggedTuple;
      37             : }  // namespace tuples
      38             : /// \endcond
      39             : 
      40           1 : namespace evolution::dg::Initialization {
      41             : /// \ingroup ActionsGroup
      42             : /// \ingroup DiscontinuousGalerkinGroup
      43             : /// \brief Allocates and initializes the system's boundary-evolved variables
      44             : /// (the `::Tags::BoundaryVariables` entry of the list-valued
      45             : /// `System::variables_tag`) on each opting external face.
      46             : ///
      47             : /// Iterates the element's external boundaries and gives each face whose
      48             : /// boundary condition opts in (declares the `evolves_boundary_variables`
      49             : /// marker) a face-sized entry in the `BoundaryVariables` storage. Each
      50             : /// `Tags::BoundaryValue<Source>` is initialized by projecting its interior
      51             : /// `Source` from the volume variables to the face. Interior and non-opting
      52             : /// faces get no entry.
      53             : ///
      54             : /// Runs after the domain and the initial data are set, and before
      55             : /// `Initialization::TimeStepperHistory`, which sizes the `::Tags::dt` twin of
      56             : /// the storage from the per-face storage initialized here.
      57             : ///
      58             : /// \tparam Dim the spatial dimension
      59             : /// \tparam System the evolution system (supplies `variables_tag`)
      60             : /// \tparam DerivedBoundaryConditionsList the concrete boundary condition
      61             : /// types; it must contain every type that can appear on an external boundary
      62             : template <size_t Dim, typename System, typename DerivedBoundaryConditionsList>
      63           1 : struct BoundaryEvolvedVariables {
      64             :  private:
      65             :   static_assert(
      66             :       evolution::dg::system_has_boundary_variables_v<System>,
      67             :       "Boundary-evolved variables can only be initialized for a system whose "
      68             :       "variables_tag is a tmpl::list with a ::Tags::BoundaryVariables entry "
      69             :       "holding the boundary-evolved variables.");
      70           0 :   using boundary_variables_tag = evolution::dg::boundary_variables_tag<System>;
      71           0 :   using boundary_field_tags_list = typename boundary_variables_tag::tags_list;
      72           0 :   using volume_variables_tag = tmpl::front<typename System::variables_tag>;
      73             : 
      74             :  public:
      75           0 :   using const_global_cache_tags =
      76             :       tmpl::list<domain::Tags::ExternalBoundaryConditions<Dim>>;
      77           0 :   using simple_tags_from_options = tmpl::list<>;
      78           0 :   using simple_tags = tmpl::list<boundary_variables_tag>;
      79           0 :   using compute_tags = tmpl::list<>;
      80             : 
      81             :   template <typename DbTagsList, typename... InboxTags, typename Metavariables,
      82             :             typename ArrayIndex, typename ActionList,
      83             :             typename ParallelComponent>
      84           0 :   static Parallel::iterable_action_return_t apply(
      85             :       db::DataBox<DbTagsList>& box,
      86             :       const tuples::TaggedTuple<InboxTags...>& /*inboxes*/,
      87             :       const Parallel::GlobalCache<Metavariables>& /*cache*/,
      88             :       const ArrayIndex& /*array_index*/, ActionList /*meta*/,
      89             :       const ParallelComponent* const /*meta*/) {
      90             :     if (db::get<::Tags::LtsMode>(box) != LtsMode::Off) {
      91             :       ERROR(
      92             :           "Boundary-evolved variables are unverified with local time "
      93             :           "stepping.");
      94             :     }
      95             :     const auto& element = db::get<::domain::Tags::Element<Dim>>(box);
      96             :     const auto& mesh = db::get<::domain::Tags::Mesh<Dim>>(box);
      97             :     if (db::get<volume_variables_tag>(box).number_of_grid_points() !=
      98             :         mesh.number_of_grid_points()) {
      99             :       ERROR("The volume variables are not allocated to the mesh size ("
     100             :             << db::get<volume_variables_tag>(box).number_of_grid_points()
     101             :             << " variables grid points vs " << mesh.number_of_grid_points()
     102             :             << " mesh grid points). This action projects the volume "
     103             :                "variables onto the opting external faces, so it must run "
     104             :                "after the volume variables are allocated and set from the "
     105             :                "initial data.");
     106             :     }
     107             :     const auto& external_boundary_conditions =
     108             :         db::get<domain::Tags::ExternalBoundaryConditions<Dim>>(box).at(
     109             :             element.id().block_id());
     110             : 
     111             :     DirectionMap<Dim, size_t> points_per_direction{};
     112             :     for (const Direction<Dim>& direction : element.external_boundaries()) {
     113             :       call_with_dynamic_type<void, DerivedBoundaryConditionsList>(
     114             :           &*external_boundary_conditions.at(direction),
     115             :           [&direction, &mesh,
     116             :            &points_per_direction]<typename DerivedBoundaryCondition>(
     117             :               const DerivedBoundaryCondition* const /*boundary_condition*/) {
     118             :             if constexpr (evolution::dg::evolves_boundary_variables_v<
     119             :                               DerivedBoundaryCondition>) {
     120             :               points_per_direction.insert(
     121             :                   {direction, mesh.slice_away(direction.dimension())
     122             :                                   .number_of_grid_points()});
     123             :             }
     124             :           });
     125             :     }
     126             : 
     127             :     db::mutate<boundary_variables_tag>(
     128             :         [&mesh, &points_per_direction](
     129             :             const gsl::not_null<typename boundary_variables_tag::type*>
     130             :                 boundary_vars,
     131             :             const typename volume_variables_tag::type& volume_variables) {
     132             :           boundary_vars->initialize(std::move(points_per_direction));
     133             :           for (auto& direction_and_face_values : boundary_vars->variables()) {
     134             :             const auto& direction = direction_and_face_values.first;
     135             :             auto& face_values = direction_and_face_values.second;
     136             :             tmpl::for_each<boundary_field_tags_list>(
     137             :                 [&direction, &mesh, &volume_variables,
     138             :                  &face_values]<typename BoundaryTag>(
     139             :                     tmpl::type_<BoundaryTag> /*meta*/) {
     140             :                   using source_tag = typename BoundaryTag::tag;
     141             :                   auto& face_field = get<BoundaryTag>(face_values);
     142             :                   ::dg::project_tensor_to_boundary(
     143             :                       make_not_null(&face_field),
     144             :                       get<source_tag>(volume_variables), mesh, direction);
     145             :                 });
     146             :           }
     147             :         },
     148             :         make_not_null(&box), db::get<volume_variables_tag>(box));
     149             :     return {Parallel::AlgorithmExecution::Continue, std::nullopt};
     150             :   }
     151             : };
     152             : }  // namespace evolution::dg::Initialization

Generated by: LCOV version 1.14