|
SERiF v0.0.1a
Stellar Evolution and Rotation in Four Dimensions
|
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 |
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).
| TermT | Term Type (e.g. gravitational potential, mass density) |
| OperationT | The operation to associate to that term, must be one of the operations from Operation (enforced by satisfying IsOperation). |
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:
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.
| using serif::discretization::forms::Operand< TermT, OperationT >::operation_type = OperationT |
| using serif::discretization::forms::Operand< TermT, OperationT >::term_type = TermT |