SERiF v0.0.1a
Stellar Evolution and Rotation in Four Dimensions
Loading...
Searching...
No Matches
serif::discretization::forms::Operand< TermT, OperationT > Struct Template Referencefinal

Compile time representation of some operand. An operand associates a term to an operation type (e.g. the gradient of gravitational potential where gravitational potential is the term and gradient is the operation). More...

#include <operands.hpp>

Public Types

using term_type = TermT
 
using operation_type = OperationT
 

Detailed Description

template<blocks::Term TermT, IsOperation OperationT = Operation::Value>
struct serif::discretization::forms::Operand< TermT, OperationT >

Compile time representation of some operand. An operand associates a term to an operation type (e.g. the gradient of gravitational potential where gravitational potential is the term and gradient is the operation).

Template Parameters
TermTTerm Type (e.g. gravitational potential, mass density)
OperationTThe operation to associate to that term, must be one of the operations from Operation (enforced by satisfying IsOperation).
Note
An operand does not know how to do anything. Like a lot of the other parts of SERiF at this level this is compile time metadata which allows the compiler to select the correct overloads, without runtime dispatch overhead, in order to run the correct computations. Do not be fooled into thinking that this actually has any computations buried within it.

As I say in the note this is a compile time representation of some metadata; however, because of that it may be challenging for a new developer to track where exactly this is used. Broadly this system is used so that a developer can inform the backend how to evaluate physical inputs and integrate point-wise contributions.

When used as the test operand of a Contribution, the operation applies to the test function. When used in a contribution's Operands list, it applies to a physical input field whose evaluated value is supplied to evaluate().

Consider some scalar field \(\lambda\) over the stellar domain which describes local point-wise residual contributions. A weak residual can be computed a number of ways; however, the most natural might be something like

\[R_i = \int_{\Omega_{\text{stellar}}} q_i \lambda\,dV \approx \sum_{k=1}^{N_q} q_i(x_k)\lambda(x_k)W_k \]

Here, \(i\) identifies the test function and corresponding residual entry, while \(k\) identifies a quadrature point. The weight \(W_k\) includes both the quadrature weight and the geometric volume factor.

Or, for some vector field \(\boldsymbol{\lambda}\) over the stellar domain which describes local point-wise residual contributions,

\[R_i = \int_{\Omega_{\text{stellar}}} \mathbf{v}_i\cdot\boldsymbol{\lambda}\,dV \approx \sum_{k=1}^{N_q} \mathbf{v}_i(x_k)\cdot\boldsymbol{\lambda}(x_k)W_k \]

However, a different operation on the test function may emerge from the weak-form derivation. Say, for example, you find that really you need the divergence of the test function paired with a scalar contribution \(\lambda\), e.g.

\[R_i = \int_{\Omega_{\text{stellar}}} \left(\nabla\cdot\mathbf{v}_i\right)\lambda\,dV \approx \sum_{k=1}^{N_q} \left(\nabla\cdot\mathbf{v}_i\right)(x_k)\lambda(x_k)W_k \]

As there are a series of different, though effectively enumerable, options here, we can use a compile time tag to let the backend select, without runtime dispatch overhead, what operation needs to be applied to the test function. Evaluating that operation and performing the integration still require numerical work at runtime.

By default, if you do not specify an operation type (the second template parameter) then the operation type will default to Operation::Value, which seems to be the most common case, at least for this class of problems. In addition, the operand vocabulary includes the following tags, whose meanings when applied to test functions are:

  • Operation::Gradient ( \(\int_{\Omega} \nabla q_i \cdot \boldsymbol{\lambda}\,dV\))
  • Operation::Divergence ( \(\int_{\Omega} \left(\nabla\cdot\mathbf{v}_i\right)\lambda\,dV\))
  • Operation::Curl ( \(\int_{\Omega} \left(\nabla\times\mathbf{v}_i\right)\cdot\boldsymbol{\lambda}\,dV\))
  • Operation::NormalTrace ( \(\int_{\partial\Omega} \left(\hat{\mathbf{n}}\cdot\mathbf{v}_i\right)\lambda\,dS\))
Note
Declaring an operation tag does not itself provide a backend implementation. The current MFEM volume-equation backend supports Value and Divergence for its supported field spaces, and Gradient for scalar/vector H1 fields. Curl and NormalTrace require additional backend support; NormalTrace also requires an appropriate boundary integration path.

In the equation system you may find documentation for the "contributions" system, which uses the term in the test operand to determine which residual block receives the contribution, and its operation to determine how the test function enters the integrand.

Member Typedef Documentation

◆ operation_type

template<blocks::Term TermT, IsOperation OperationT = Operation::Value>
using serif::discretization::forms::Operand< TermT, OperationT >::operation_type = OperationT

◆ term_type

template<blocks::Term TermT, IsOperation OperationT = Operation::Value>
using serif::discretization::forms::Operand< TermT, OperationT >::term_type = TermT

The documentation for this struct was generated from the following file: