From 8154949bb7ad3ccad667c818fe9de2f169c99373 Mon Sep 17 00:00:00 2001 From: Emily Boudreaux Date: Fri, 9 Oct 2026 15:55:57 -0400 Subject: [PATCH] docs(discretization/forms): expanded operand documentation with example --- .../serif/discretization/forms/operands.hpp | 39 ++++++++++++++++++- tests/sandbox/lane-emden_sandbox.cpp | 0 2 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 tests/sandbox/lane-emden_sandbox.cpp diff --git a/src/include/serif/discretization/forms/operands.hpp b/src/include/serif/discretization/forms/operands.hpp index c88ce9f7..305bea23 100644 --- a/src/include/serif/discretization/forms/operands.hpp +++ b/src/include/serif/discretization/forms/operands.hpp @@ -53,7 +53,44 @@ namespace serif::discretization::forms { * * @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 overhead, in order to run the correct computations. Do not be fooled into thinking - * that this actually has any computations burried within it. + * that this actually has any computations buried within it. + * + * As I say in teh 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 integrate point-wise contributions. Consider some scalar field \f$\lambda\f$ 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 + * + * \f[ + * \int_{\Omega_{\text{stellar}}} q \lambda dV \approx \sum_{i=1}^{N} q_i \lambda_i w_i + * \f] + * + * or for some vector field \f$\mathbf\lambda}\f$ over the stellar domain which describes local point-wise residual contributions + * + * \f[ + * \int_{\Omega_{\text{stellar}}} \mathbf{v}\cdot\lambda dV \approx \sum_{i=1}^{N} \mathbf{v}_i\cdot\lambda_i w_i + * \f] + * + * However, there may be some different inner product between the test function and the point-wise residual contribution which emerges from the derivation. Say for + * example you find that really you need the divergence of the test function, e.g. + * + * \f[ + * \int_{\Omega_{\text{stellar}}} \left(\nabla\cdot\mathbf{v}\right)\mathbf{\lambda} dV \approx \sum_{i=1}^{N} \left(\nabla\cdot\mathbf{v}_i\right)\cdot\lambda_i w_i + * \f] + * + * As there are a series of different, though effectively enumerable, options here, we can use a compile time tag to let the backend + * select, at 0 runtime cost, what operation needs to be applied to the test function. + * + * By default, if you do not specify an operation type (the second template parameter) then the operation type + * will default to @ref Operation::Value, which seems to be the most common case, at least for this class of problems. In addition you may select + * + * - @ref Operation::Gradient (\f$\int_{\Omega} \nabla q \cdot \lambda dV\f$) + * - @ref Operation::Divergence (\f$\int_{\Omega} \left(\nabla\cdot\mathbf{v}\right)\mathbf{\lambda} dV\f$) + * - @ref Operation::Curl (\f$\int_{\Omega} \left(\nabla\times\mathbf{v}\right)\cdot\mathbf{\lambda} dV\f$) + * - @ref Operation::NormalTrace (\f$\int_{\partial\Omega} \hat{n}\cdot\mathbf{v}\lambda dS\f$) + * + * In the equation system you may find documentation for the "contributions" system which makes heavy use of Operations to determine + * what residual blocks to contribute the actual residuals to. */ template // We choose to default to the value operation because it is the most common. struct Operand final { diff --git a/tests/sandbox/lane-emden_sandbox.cpp b/tests/sandbox/lane-emden_sandbox.cpp new file mode 100644 index 00000000..e69de29b