SpECTRE Documentation Coverage Report
Current view: top level - Elliptic/BoundaryConditions - BoundaryCondition.hpp Hit Total Coverage
Commit: 817e13c5144619b701c7cd870655d8dbf94ab8ce Lines: 1 11 9.1 %
Date: 2024-07-19 22:17:05
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 <pup.h>
       8             : #include <vector>
       9             : 
      10             : #include "DataStructures/DataBox/DataBox.hpp"
      11             : #include "Domain/BoundaryConditions/BoundaryCondition.hpp"
      12             : #include "Elliptic/BoundaryConditions/BoundaryConditionType.hpp"
      13             : #include "Utilities/Serialization/CharmPupable.hpp"
      14             : #include "Utilities/TMPL.hpp"
      15             : 
      16             : namespace elliptic {
      17             : /// Boundary conditions for elliptic systems
      18             : namespace BoundaryConditions {
      19             : 
      20             : /*!
      21             :  * \brief Base class for boundary conditions for elliptic systems
      22             :  *
      23             :  * Boundary conditions for elliptic systems derive from this abstract base
      24             :  * class. This allows boundary conditions to be factory-created from input-file
      25             :  * options. Specific systems may implement further abstract base classes that
      26             :  * derive from this class and add additional requirements.
      27             :  *
      28             :  * Each derived class represents one kind of boundary conditions. For example,
      29             :  * one derived class might implement homogeneous (zero) Dirichlet or Neumann
      30             :  * boundary conditions, another might implement Dirichlet fields procured from
      31             :  * an analytic solution, and yet another might set the boundary fields as a
      32             :  * function of the dynamic variables on the domain boundary (e.g. Robin-type
      33             :  * boundary conditions).
      34             :  *
      35             :  * Note that almost all boundary conditions are actually nonlinear because even
      36             :  * those that depend only linearly on the dynamic fields typically contribute
      37             :  * non-zero field values. For example, a standard Dirichlet boundary condition
      38             :  * \f$u(x=0)=u_0\f$ is nonlinear for any \f$u_0\neq 0\f$. Boundary conditions
      39             :  * for linear systems may have exactly this nonlinearity (a constant non-zero
      40             :  * contribution) but must depend at most linearly on the dynamic fields.
      41             :  * Boundary conditions for nonlinear systems may have any nonlinearity. Either
      42             :  * must implement their linearization as a separate function (see below). For
      43             :  * linear systems the nonlinear (constant) contribution is typically added to
      44             :  * the fixed-source part of the discretized equations and the linearized
      45             :  * boundary conditions are being employed throughout the solve so the
      46             :  * discretized operator remains linear. For nonlinear systems we typically solve
      47             :  * the linearized equations repeatedly for a correction quantity, so we apply
      48             :  * the linearized boundary conditions when solving for the correction quantity
      49             :  * and apply the nonlinear boundary conditions when dealing with the nonlinear
      50             :  * fields that are being corrected (see e.g.
      51             :  * `NonlinearSolver::newton_raphson::NewtonRaphson`).
      52             :  *
      53             :  * Derived classes are expected to implement the following compile-time
      54             :  * interface:
      55             :  *
      56             :  * - They are option-creatable.
      57             :  * - They have type aliases `argument_tags`, `volume_tags`,
      58             :  *   `argument_tags_linearized` and `volume_tags_linearized`. Those aliases list
      59             :  *   the tags required for computing nonlinear and linearized boundary
      60             :  *   conditions, respectively. The tags are always taken to represent quantities
      61             :  *   on the _interior_ side of the domain boundary, i.e. whenever normal vectors
      62             :  *   are involved they point _out_ of the computational domain. The
      63             :  *   `volume_tags` list the subset of the `argument_tags` that are _not_
      64             :  *   evaluated on the boundary but taken from the element directly.
      65             :  * - They have `apply` and `apply_linearized` member functions that take these
      66             :  *   arguments (in this order):
      67             :  *
      68             :  *   1. The dynamic fields as not-null pointers.
      69             :  *   2. The normal-dot-fluxes corresponding to the dynamic fields as not-null
      70             :  *      pointers. These have the same types as the dynamic fields.
      71             :  *   3. The field derivatives as const-refs.
      72             :  *   4. The types held by the argument tags.
      73             :  *
      74             :  *   For example, boundary conditions for a first-order Poisson system might
      75             :  *   have an `apply` function signature that looks like this:
      76             :  *
      77             :  *   \snippet Elliptic/BoundaryConditions/Test_BoundaryCondition.cpp example_poisson_fields
      78             :  *
      79             :  * The fields and normal-dot-fluxes passed to the `apply` and `apply_linearized`
      80             :  * functions hold data which the implementations of the functions can use, and
      81             :  * also serve as return variables. Modifying the fields means applying
      82             :  * Dirichlet-type boundary conditions and modifying the normal-dot-fluxes means
      83             :  * applying Neumann-type boundary conditions. Just like the arguments evaluated
      84             :  * on the boundary, the normal-dot-fluxes involve normal vectors that point
      85             :  * _out_ of the computation domain. Note that linearized boundary conditions, as
      86             :  * well as nonlinear boundary conditions for linear systems, may only depend
      87             :  * linearly on the field data, since these are the fields the linearization is
      88             :  * performed for.
      89             :  */
      90             : template <size_t Dim>
      91           1 : class BoundaryCondition : public domain::BoundaryConditions::BoundaryCondition {
      92             :  private:
      93           0 :   using Base = domain::BoundaryConditions::BoundaryCondition;
      94             : 
      95             :  public:
      96           0 :   static constexpr size_t volume_dim = Dim;
      97             : 
      98           0 :   BoundaryCondition() = default;
      99           0 :   BoundaryCondition(const BoundaryCondition&) = default;
     100           0 :   BoundaryCondition(BoundaryCondition&&) = default;
     101           0 :   BoundaryCondition& operator=(const BoundaryCondition&) = default;
     102           0 :   BoundaryCondition& operator=(BoundaryCondition&&) = default;
     103           0 :   ~BoundaryCondition() override = default;
     104             : 
     105             :   /// \cond
     106             :   explicit BoundaryCondition(CkMigrateMessage* m) : Base(m) {}
     107             :   WRAPPED_PUPable_abstract(BoundaryCondition);  // NOLINT
     108             :   /// \endcond
     109             : 
     110             :   // The type of boundary condition (Dirichlet or Neumann) for every tensor
     111             :   // component. For example, if the derived class imposes Neumann-type
     112             :   // conditions on a Scalar and Dirichlet-type conditions on a 2D vector, then
     113             :   // it should return `{Dirichlet, Neumann, Neumann}`.
     114             :   virtual std::vector<elliptic::BoundaryConditionType>
     115           0 :   boundary_condition_types() const = 0;
     116             : };
     117             : 
     118             : }  // namespace BoundaryConditions
     119             : }  // namespace elliptic

Generated by: LCOV version 1.14