SpECTRE Documentation Coverage Report
Current view: top level - Elliptic/Protocols - FirstOrderSystem.hpp Hit Total Coverage
Commit: 2ae2b99409ac582030d56a4560a92a3e066a7e54 Lines: 2 16 12.5 %
Date: 2022-01-15 08:40: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 <cstddef>
       7             : #include <type_traits>
       8             : 
       9             : #include "DataStructures/Tensor/Tensor.hpp"
      10             : #include "Domain/BoundaryConditions/BoundaryCondition.hpp"
      11             : #include "Utilities/TMPL.hpp"
      12             : #include "Utilities/TypeTraits/IsA.hpp"
      13             : 
      14             : /// \ref protocols related to elliptic systems
      15           1 : namespace elliptic::protocols {
      16             : 
      17             : namespace FirstOrderSystem_detail {
      18             : template <size_t Dim, typename PrimalFields, typename AuxiliaryFields,
      19             :           typename PrimalFluxes, typename AuxiliaryFluxes>
      20             : struct test_primal_and_auxiliary_fields_and_fluxes;
      21             : template <size_t Dim, typename... PrimalFields, typename... AuxiliaryFields,
      22             :           typename... PrimalFluxes, typename... AuxiliaryFluxes>
      23             : struct test_primal_and_auxiliary_fields_and_fluxes<
      24             :     Dim, tmpl::list<PrimalFields...>, tmpl::list<AuxiliaryFields...>,
      25             :     tmpl::list<PrimalFluxes...>, tmpl::list<AuxiliaryFluxes...>>
      26             :     : std::true_type {
      27             :   static_assert(sizeof...(PrimalFields) == sizeof...(AuxiliaryFields) and
      28             :                     sizeof...(PrimalFluxes) == sizeof...(PrimalFields) and
      29             :                     sizeof...(AuxiliaryFluxes) == sizeof...(PrimalFields),
      30             :                 "The system must have the same number of primal and auxiliary "
      31             :                 "fields and fluxes.");
      32             :   static_assert(
      33             :       ((tmpl::size<typename AuxiliaryFields::type::index_list>::value ==
      34             :         tmpl::size<typename PrimalFields::type::index_list>::value + 1) and
      35             :        ...),
      36             :       "Auxiliary fields and primal fields must correspond to each "
      37             :       "other. In particular, each auxiliary field must have one "
      38             :       "index more than its corresponding primal field.");
      39             :   static_assert(
      40             :       ((tmpl::size<typename PrimalFluxes::type::index_list>::value ==
      41             :         tmpl::size<typename PrimalFields::type::index_list>::value + 1) and
      42             :        ...) and
      43             :           (std::is_same_v<tmpl::front<typename PrimalFluxes::type::index_list>,
      44             :                           SpatialIndex<Dim, UpLo::Up, Frame::Inertial>> and
      45             :            ...),
      46             :       "Primal fluxes and primal fields must correspond to each "
      47             :       "other. In particular, each primal flux must have one "
      48             :       "index more than its corresponding primal field and an upper-spatial "
      49             :       "first index.");
      50             :   static_assert(
      51             :       ((tmpl::size<typename AuxiliaryFluxes::type::index_list>::value ==
      52             :         tmpl::size<typename AuxiliaryFields::type::index_list>::value + 1) and
      53             :        ...) and
      54             :           (std::is_same_v<
      55             :                tmpl::front<typename AuxiliaryFluxes::type::index_list>,
      56             :                SpatialIndex<Dim, UpLo::Up, Frame::Inertial>> and
      57             :            ...),
      58             :       "Auxiliary fluxes and auxiliary fields must correspond to each "
      59             :       "other. In particular, each auxiliary flux must have one "
      60             :       "index more than its corresponding auxiliary field and an upper-spatial "
      61             :       "first index.");
      62             : };
      63             : }  // namespace FirstOrderSystem_detail
      64             : 
      65             : /*!
      66             :  * \brief A system of elliptic equations in first-order "flux" formulation
      67             :  *
      68             :  * Classes conforming to this protocol represent a set of elliptic partial
      69             :  * differential equations in first-order "flux" formulation:
      70             :  *
      71             :  * \f{equation}
      72             :  * -\partial_i F^i_\alpha + S_\alpha = f_\alpha(x)
      73             :  * \f}
      74             :  *
      75             :  * in terms of fluxes \f$F_\alpha^i\f$, sources \f$S_\alpha\f$ and fixed-sources
      76             :  * \f$f_\alpha(x)\f$. It resembles closely formulations of hyperbolic
      77             :  * conservation laws but allows the fluxes \f$F_\alpha^i\f$ to be higher-rank
      78             :  * tensor fields. The fluxes and sources are functionals of the "primal" system
      79             :  * variables \f$u_A(x)\f$ and their corresponding "auxiliary" variables
      80             :  * \f$v_A(x)\f$. The fixed-sourced \f$f_\alpha(x)\f$ are independent of the
      81             :  * system variables. We enumerate the variables with uppercase letters such that
      82             :  * \f$v_A\f$ is the auxiliary variable corresponding to \f$u_A\f$. Greek letters
      83             :  * enumerate _all_ variables. In documentation related to particular elliptic
      84             :  * systems we generally use the canonical system-specific symbols for the fields
      85             :  * in place of these indices. See the `Poisson::FirstOrderSystem` and the
      86             :  * `Elasticity::FirstOrderSystem` for examples.
      87             :  *
      88             :  * Conforming classes must have these static member variables:
      89             :  *
      90             :  * - `size_t volume_dim`: The number of spatial dimensions.
      91             :  *
      92             :  * Conforming classes must have these type aliases:
      93             :  *
      94             :  * - `primal_fields`: A list of tags representing the primal fields. These are
      95             :  *   the fields we solve for, e.g. \f$u\f$ for a Poisson equation.
      96             :  *
      97             :  * - `auxiliary_fields`: A list of tags representing the auxiliary fields, which
      98             :  *   are typically gradients of the primal fields, e.g. \f$v_i = \partial_i u\f$
      99             :  *   for a Poisson equation. These must follow the order of the `primal_fields`.
     100             :  *   Specifically, each auxiliary field must have one rank higher than its
     101             :  *   corresponding primal field.
     102             :  *
     103             :  * - `primal_fluxes`: A list of tags representing the primal fluxes
     104             :  *   \f$F_{u_A}^i\f$. These are typically some linear combination of the
     105             :  *   auxiliary fields with raised indices, e.g. \f$v^i = g^{ij}v_j\f$ for a
     106             :  *   curved-space Poisson equation on a background metric \f$g_{ij}\f$. They
     107             :  *   must have the same rank as the `auxiliary_fields` but with an upper-spatial
     108             :  *   first index, because their divergence defines the elliptic equation.
     109             :  *
     110             :  * - `auxiliary_fluxes`: A list of tags representing the auxiliary fluxes
     111             :  *   \f$F_{v_A}^i\f$, e.g. \f$\delta^i_j u\f$ for a Poisson equation. These must
     112             :  *   have one rank higher than the `auxiliary_fields` and have an upper-spatial
     113             :  *   first index because their divergence defines the auxiliary fields.
     114             :  *
     115             :  * - `background_fields`: A list of tags representing the variable-independent
     116             :  *   background fields in the equations. Examples are a background metric,
     117             :  *   associated fixed geometry quantities such as Christoffel symbols or the
     118             :  *   Ricci scalar, or any other fixed field that determines the problem to be
     119             :  *   solved such as matter sources in the Einstein constraint equations.
     120             :  *
     121             :  * - `inv_metric_tag`: The tag that defines the background geometry, i.e. the
     122             :  *   the geometry that the elliptic equations are formulated on. This is the
     123             :  *   metric responsible for normalizing one-forms, such as face normals.
     124             :  *
     125             :  * - `fluxes_computer`: A class that defines the primal and auxiliary fluxes
     126             :  *   \f$F_\alpha^i\f$. Must have an `argument_tags` type alias and two `apply`
     127             :  *   function overloads: One that computes the primal fluxes and another that
     128             :  *   computes the auxiliary fluxes. The first `apply` function takes these
     129             :  *   arguments in this order:
     130             :  *
     131             :  *   1. The `primal_fluxes` as not-null pointer
     132             :  *   2. The `argument_tags`
     133             :  *   3. The `auxiliary_fields`
     134             :  *
     135             :  *   The second `apply` function takes these arguments in this order:
     136             :  *
     137             :  *   1. The `auxiliary_fluxes` as not-null pointer
     138             :  *   2. The `argument_tags`
     139             :  *   3. The `primal_fields`
     140             :  *
     141             :  *   The functions can assume the output buffers are already correctly sized,
     142             :  *   but no guarantee is made on the values that the buffers hold at input. The
     143             :  *   class must have an additional `volume_tags` type alias that lists the
     144             :  *   subset of `argument_tags` that will be retrieved directly from the DataBox,
     145             :  *   instead of retrieving it from the face of an element.
     146             :  *
     147             :  * - `sources_computer`: A class that defines the primal and auxiliary sources
     148             :  *   \f$S_\alpha\f$. Must have an `argument_tags` type alias and two `apply`
     149             :  *   function overloads: One that adds the primal sources and another that adds
     150             :  *   the auxiliary sources to the equations. The first `apply` function takes
     151             :  *   these arguments in this order:
     152             :  *
     153             :  *   1. The types of the `primal_fields` as not-null pointer. These are the
     154             :  *      primal equations.
     155             :  *   2. The `argument_tags`
     156             :  *   3. The `primal_fields`
     157             :  *   4. The `primal_fluxes`
     158             :  *
     159             :  *   The second `apply` function takes these arguments in this order:
     160             :  *
     161             :  *   1. The types of the `auxiliary_fields` as not-null pointer. These are the
     162             :  *      auxiliary equations.
     163             :  *   2. The `argument_tags`
     164             :  *   3. The `primal_fields`
     165             :  *
     166             :  *   The functions are expected to _add_ the sources \f$S_\alpha\f$ to the
     167             :  *   output buffers.
     168             :  *
     169             :  * - `boundary_conditions_base`: A base class representing the supported
     170             :  *   boundary conditions. Boundary conditions can be factory-created from this
     171             :  *   base class. Currently this should be a specialization of
     172             :  *   `elliptic::BoundaryConditions::BoundaryCondition`.
     173             :  */
     174           1 : struct FirstOrderSystem {
     175             :   template <typename ConformingType>
     176           0 :   struct test {
     177           0 :     static constexpr size_t volume_dim = ConformingType::volume_dim;
     178             : 
     179           0 :     using primal_fields = typename ConformingType::primal_fields;
     180           0 :     using auxiliary_fields = typename ConformingType::auxiliary_fields;
     181           0 :     using primal_fluxes = typename ConformingType::primal_fluxes;
     182           0 :     using auxiliary_fluxes = typename ConformingType::auxiliary_fluxes;
     183             :     static_assert(
     184             :         FirstOrderSystem_detail::test_primal_and_auxiliary_fields_and_fluxes<
     185             :             volume_dim, primal_fields, auxiliary_fields, primal_fluxes,
     186             :             auxiliary_fluxes>::value);
     187             : 
     188           0 :     using background_fields = typename ConformingType::background_fields;
     189             :     static_assert(tt::is_a_v<tmpl::list, background_fields>);
     190           0 :     using inv_metric_tag = typename ConformingType::inv_metric_tag;
     191             :     static_assert(std::is_same_v<inv_metric_tag, void> or
     192             :                   tmpl::list_contains_v<background_fields, inv_metric_tag>);
     193             : 
     194           0 :     using fluxes_computer = typename ConformingType::fluxes_computer;
     195           0 :     using sources_computer = typename ConformingType::sources_computer;
     196           0 :     using fluxes_argument_tags = typename fluxes_computer::argument_tags;
     197           0 :     using sources_argument_tags = typename sources_computer::argument_tags;
     198             :     static_assert(tt::is_a_v<tmpl::list, fluxes_argument_tags>);
     199             :     static_assert(tt::is_a_v<tmpl::list, sources_argument_tags>);
     200             : 
     201           0 :     using boundary_conditions_base =
     202             :         typename ConformingType::boundary_conditions_base;
     203             :     static_assert(
     204             :         std::is_base_of_v<domain::BoundaryConditions::BoundaryCondition,
     205             :                           boundary_conditions_base>);
     206             :   };
     207             : };
     208             : 
     209             : }  // namespace elliptic::protocols

Generated by: LCOV version 1.14