SpECTRE Documentation Coverage Report
Current view: top level - NumericalAlgorithms/DiscontinuousGalerkin - LiftFromBoundary.hpp Hit Total Coverage
Commit: 361cb8d8406bb752684a5f31c27320ec444a50e3 Lines: 3 4 75.0 %
Date: 2025-11-09 02:02:04
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/DataVector.hpp"
      10             : #include "DataStructures/Tensor/Tensor.hpp"
      11             : #include "DataStructures/Variables.hpp"
      12             : #include "Domain/Structure/Direction.hpp"
      13             : #include "Domain/Structure/Side.hpp"
      14             : #include "NumericalAlgorithms/Spectral/BoundaryInterpolationMatrices.hpp"
      15             : #include "NumericalAlgorithms/Spectral/BoundaryLiftingTerm.hpp"
      16             : #include "NumericalAlgorithms/Spectral/Mesh.hpp"
      17             : #include "NumericalAlgorithms/Spectral/Quadrature.hpp"
      18             : #include "Utilities/Algorithm.hpp"
      19             : #include "Utilities/Gsl.hpp"
      20             : 
      21             : namespace dg {
      22             : namespace detail {
      23             : template <typename ValueType, size_t Dim>
      24             : void lift_boundary_terms_gauss_points_impl(
      25             :     gsl::not_null<ValueType*> volume_dt_vars, size_t num_independent_components,
      26             :     const Mesh<Dim>& volume_mesh, size_t dimension,
      27             :     const Scalar<DataVector>& volume_det_inv_jacobian, size_t num_boundary_pts,
      28             :     const gsl::span<const ValueType>& boundary_corrections,
      29             :     const DataVector& boundary_lifting_term,
      30             :     const Scalar<DataVector>& magnitude_of_face_normal,
      31             :     const Scalar<DataVector>& face_det_jacobian);
      32             : 
      33             : template <typename ValueType, size_t Dim>
      34             : void lift_boundary_terms_gauss_points_impl(
      35             :     gsl::not_null<ValueType*> volume_dt_vars, size_t num_independent_components,
      36             :     const Mesh<Dim>& volume_mesh, size_t dimension,
      37             :     const Scalar<DataVector>& volume_det_inv_jacobian, size_t num_boundary_pts,
      38             :     const gsl::span<const ValueType>& upper_boundary_corrections,
      39             :     const DataVector& upper_boundary_lifting_term,
      40             :     const Scalar<DataVector>& upper_magnitude_of_face_normal,
      41             :     const Scalar<DataVector>& upper_face_det_jacobian,
      42             :     const gsl::span<const ValueType>& lower_boundary_corrections,
      43             :     const DataVector& lower_boundary_lifting_term,
      44             :     const Scalar<DataVector>& lower_magnitude_of_face_normal,
      45             :     const Scalar<DataVector>& lower_face_det_jacobian);
      46             : 
      47             : template <typename ValueType, size_t Dim>
      48             : void lift_boundary_terms_gauss_points_impl(
      49             :     gsl::not_null<ValueType*> volume_data, size_t num_independent_components,
      50             :     const Mesh<Dim>& volume_mesh, const Direction<Dim>& direction,
      51             :     const gsl::span<const ValueType>& boundary_corrections);
      52             : }  // namespace detail
      53             : 
      54             : /*!
      55             :  * \brief Lift the boundary corrections to the volume time derivatives in the
      56             :  * specified direction.
      57             :  *
      58             :  * The general lifting term (for the \f$\xi\f$-dimension) is:
      59             :  *
      60             :  * \f{align*}{
      61             :  * \partial_t u_{\alpha\breve{\imath}\breve{\jmath}\breve{k}}=\cdots
      62             :  * -\frac{\ell_{\breve{\imath}}\left(\xi=1\right)}
      63             :  *   {w_{\breve{\imath}}J_{\breve{\imath}\breve{\jmath}\breve{k}}}
      64             :  *   \left[J\sqrt{
      65             :  *   \frac{\partial\xi}{\partial x^i} \gamma^{ij}
      66             :  *   \frac{\partial\xi}{\partial x^j}}
      67             :  *   \left(G_{\alpha} + D_{\alpha}\right)
      68             :  *   \right]_{\breve{\jmath}\breve{k}}\left(\xi=1\right),
      69             :  * \f}
      70             :  *
      71             :  * where \f$\breve{\imath}\f$, \f$\breve{\jmath}\f$, and \f$\breve{k}\f$ are
      72             :  * indices in the logical \f$\xi\f$, \f$\eta\f$, and \f$\zeta\f$ dimensions.
      73             :  * The \f$G+D\f$ terms correspond to the `boundary_corrections` function
      74             :  * argument, and the function Spectral::boundary_lifting_term() is used to
      75             :  * compute and cache the terms from the lifting terms
      76             :  * \f$\ell_{\breve{\imath}}(\xi=\pm1)/w_{\breve{\imath}}\f$.
      77             :  *
      78             :  * \note that normal vectors are pointing out of the element.
      79             :  *
      80             :  * \param dt_vars The volume time derivatives
      81             :  * $\partial_t u_{\alpha\breve{\imath}\breve{\jmath}\breve{k}}$ to be updated
      82             :  * \param volume_det_inv_jacobian The inverse Jacobian determinant in the volume
      83             :  * $J^{-1}_{\breve{\imath}\breve{\jmath}\breve{k}}$
      84             :  * \param volume_mesh The mesh of the volume
      85             :  * \param direction The direction of the face on which the boundary corrections
      86             :  * are defined
      87             :  * \param boundary_corrections The boundary corrections
      88             :  * $\left(G_{\alpha} + D_{\alpha}\right)$
      89             :  * \param magnitude_of_face_normal The term $\sqrt{
      90             :  * \frac{\partial\xi}{\partial x^i} \gamma^{ij}
      91             :  * \frac{\partial\xi}{\partial x^j}}$
      92             :  * \param face_det_jacobian The volume Jacobian determinant $J$ evaluated on the
      93             :  * face (not the surface Jacobian determinant)
      94             :  */
      95             : template <size_t Dim, typename DtTagsList, typename BoundaryCorrectionTagsList>
      96           1 : void lift_boundary_terms_gauss_points(
      97             :     const gsl::not_null<Variables<DtTagsList>*> dt_vars,
      98             :     const Scalar<DataVector>& volume_det_inv_jacobian,
      99             :     const Mesh<Dim>& volume_mesh, const Direction<Dim>& direction,
     100             :     const Variables<BoundaryCorrectionTagsList>& boundary_corrections,
     101             :     const Scalar<DataVector>& magnitude_of_face_normal,
     102             :     const Scalar<DataVector>& face_det_jacobian) {
     103             :   ASSERT(alg::all_of(volume_mesh.quadrature(),
     104             :                      [](const Spectral::Quadrature quadrature) {
     105             :                        return quadrature == Spectral::Quadrature::Gauss;
     106             :                      }),
     107             :          "Must use Gauss points in all directions but got the mesh: "
     108             :              << volume_mesh);
     109             :   const Mesh<Dim - 1> boundary_mesh =
     110             :       volume_mesh.slice_away(direction.dimension());
     111             :   const Mesh<1> volume_stripe_mesh =
     112             :       volume_mesh.slice_through(direction.dimension());
     113             :   const size_t num_boundary_grid_points = boundary_mesh.number_of_grid_points();
     114             :   detail::lift_boundary_terms_gauss_points_impl(
     115             :       make_not_null(dt_vars->data()), dt_vars->number_of_independent_components,
     116             :       volume_mesh, direction.dimension(), volume_det_inv_jacobian,
     117             :       num_boundary_grid_points,
     118             :       gsl::make_span(boundary_corrections.data(), boundary_corrections.size()),
     119             :       direction.side() == Side::Upper
     120             :           ? Spectral::boundary_lifting_term(volume_stripe_mesh).second
     121             :           : Spectral::boundary_lifting_term(volume_stripe_mesh).first,
     122             :       magnitude_of_face_normal, face_det_jacobian);
     123             : }
     124             : 
     125             : /*!
     126             :  * \brief Lift both the upper and lower (in logical coordinates) boundary
     127             :  * corrections to the volume time derivatives in the specified logical
     128             :  * dimension.
     129             :  *
     130             :  * The upper and lower boundary corrections in the logical `dimension` are
     131             :  * lifted together in order to reduce the amount of striding through data that
     132             :  * is needed and to improve cache-friendliness.
     133             :  *
     134             :  * The general lifting term (for the \f$\xi\f$-dimension) is:
     135             :  *
     136             :  * \f{align*}{
     137             :  * \partial_t u_{\alpha\breve{\imath}\breve{\jmath}\breve{k}}=\cdots
     138             :  * -\frac{\ell_{\breve{\imath}}\left(\xi=1\right)}
     139             :  *   {w_{\breve{\imath}}J_{\breve{\imath}\breve{\jmath}\breve{k}}}
     140             :  *   \left[J\sqrt{
     141             :  *   \frac{\partial\xi}{\partial x^i} \gamma^{ij}
     142             :  *   \frac{\partial\xi}{\partial x^j}}
     143             :  *   \left(G_{\alpha} + D_{\alpha}\right)
     144             :  *   \right]_{\breve{\jmath}\breve{k}}\left(\xi=1\right)
     145             :  * - \frac{\ell_{\breve{\imath}}\left(\xi=-1\right)}
     146             :  *   {w_{\breve{\imath}}J_{\breve{\imath}\breve{\jmath}\breve{k}}}
     147             :  *   \left[J\sqrt{
     148             :  *   \frac{\partial\xi}{\partial x^i} \gamma^{ij}
     149             :  *   \frac{\partial\xi}{\partial x^j}}
     150             :  *   \left(G_{\alpha} + D_{\alpha}\right)
     151             :  *   \right]_{\breve{\jmath}\breve{k}}\left(\xi=-1\right),
     152             :  * \f}
     153             :  *
     154             :  * where \f$\breve{\imath}\f$, \f$\breve{\jmath}\f$, and \f$\breve{k}\f$ are
     155             :  * indices in the logical \f$\xi\f$, \f$\eta\f$, and \f$\zeta\f$ dimensions.
     156             :  * The \f$G+D\f$ terms correspond to the `upper_boundary_corrections` and
     157             :  * `lower_boundary_corrections` function arguments, and the function
     158             :  * Spectral::boundary_lifting_term() is used to compute and cache the terms
     159             :  * from the lifting terms
     160             :  * \f$\ell_{\breve{\imath}}(\xi=\pm1)/w_{\breve{\imath}}\f$.
     161             :  *
     162             :  * \note that normal vectors are pointing out of the element and therefore both
     163             :  * terms have the same sign.
     164             :  */
     165             : template <size_t Dim, typename DtTagsList, typename BoundaryCorrectionTagsList>
     166           1 : void lift_boundary_terms_gauss_points(
     167             :     const gsl::not_null<Variables<DtTagsList>*> dt_vars,
     168             :     const Scalar<DataVector>& volume_det_inv_jacobian,
     169             :     const Mesh<Dim>& volume_mesh, const size_t dimension,
     170             :     const Variables<BoundaryCorrectionTagsList>& upper_boundary_corrections,
     171             :     const Scalar<DataVector>& upper_magnitude_of_face_normal,
     172             :     const Scalar<DataVector>& upper_face_det_jacobian,
     173             :     const Variables<BoundaryCorrectionTagsList>& lower_boundary_corrections,
     174             :     const Scalar<DataVector>& lower_magnitude_of_face_normal,
     175             :     const Scalar<DataVector>& lower_face_det_jacobian) {
     176             :   ASSERT(alg::all_of(volume_mesh.quadrature(),
     177             :                      [](const Spectral::Quadrature quadrature) {
     178             :                        return quadrature == Spectral::Quadrature::Gauss;
     179             :                      }),
     180             :          "Must use Gauss points in all directions but got the mesh: "
     181             :              << volume_mesh);
     182             :   const Mesh<Dim - 1> boundary_mesh = volume_mesh.slice_away(dimension);
     183             :   const Mesh<1> volume_stripe_mesh = volume_mesh.slice_through(dimension);
     184             :   const size_t num_boundary_grid_points = boundary_mesh.number_of_grid_points();
     185             :   detail::lift_boundary_terms_gauss_points_impl(
     186             :       make_not_null(dt_vars->data()), dt_vars->number_of_independent_components,
     187             :       volume_mesh, dimension, volume_det_inv_jacobian, num_boundary_grid_points,
     188             :       gsl::make_span(upper_boundary_corrections.data(),
     189             :                      upper_boundary_corrections.size()),
     190             :       Spectral::boundary_lifting_term(volume_stripe_mesh).second,
     191             :       upper_magnitude_of_face_normal, upper_face_det_jacobian,
     192             :       gsl::make_span(lower_boundary_corrections.data(),
     193             :                      lower_boundary_corrections.size()),
     194             :       Spectral::boundary_lifting_term(volume_stripe_mesh).first,
     195             :       lower_magnitude_of_face_normal, lower_face_det_jacobian);
     196             : }
     197             : 
     198             : /*!
     199             :  * \brief Lift the boundary corrections from the face to the volume for Gauss
     200             :  * points in the direction perpendicular to the face
     201             :  *
     202             :  * This function doesn't apply any Jacobians or quadrature weights. It only
     203             :  * applies the lifting matrix $\ell_{\breve{\imath}}(\xi=\pm1)$ to the
     204             :  * `boundary_corrections` and adds the result to the `volume_data`.
     205             :  */
     206             : template <size_t Dim, typename... VolumeTags,
     207             :           typename... BoundaryCorrectionTags>
     208           1 : void lift_boundary_terms_gauss_points(
     209             :     const gsl::not_null<Variables<tmpl::list<VolumeTags...>>*> volume_data,
     210             :     const Variables<tmpl::list<BoundaryCorrectionTags...>>&
     211             :         boundary_corrections,
     212             :     const Mesh<Dim>& volume_mesh, const Direction<Dim>& direction) {
     213             :   detail::lift_boundary_terms_gauss_points_impl(
     214             :       make_not_null(volume_data->data()),
     215             :       volume_data->number_of_independent_components, volume_mesh, direction,
     216             :       gsl::make_span(boundary_corrections.data(), boundary_corrections.size()));
     217             : }
     218             : }  // namespace dg

Generated by: LCOV version 1.14