Files
MeanField_SERiF/docs/static/equations.md
Emily Boudreaux 6b57738330 docs(docs): built docs
Note for now much of the docs is LLM written. This was done to save time and focus on code development. The docs have been LOOSLEY reviewed. However, the code itself has been either fully written by hand or fully reviewed. Therefore, the docs should at the moment be seen as a loose resource rather than authoratiative (and this is on top of the general ability for docs to drift)
2026-11-09 14:09:44 -05:00

130 lines
8.2 KiB
Markdown

# Equation MVP
Start with [the consumer sandbox](../tests/sandbox/equations_sandbox.cpp), then read
[the barotropic density balance](../src/include/serif/equations/barotropic_density.hpp) and
[primal gravity](../src/include/serif/equations/primal_gravity.hpp).
The sandbox assembles a manufactured equilibrium on a box; it is not a stellar solver.
## Physics and execution
Physics lives in `serif/equations/<name>.hpp`. An equation declares its test term,
existing `Operand` dependencies, local residual, explicit partial derivatives,
admissibility, and a numerical-order hint. EOS calls occur here, never in assembly.
`EquationPoint` and `PointLinearization` are the author-facing input and output types.
The `Equation` concept checks this interface without selecting a backend.
`EquationRegistry{...}` is the model's list of equations and validates unique residual
rows. It does not own coefficients, prepared data, or solver layout. Scalar H1/L2
values and gradients, and vector H1 values/divergences/gradients are executable volume operations. Declaring
another operation does not make it executable.
Execution lives in `serif/operators`. `EquationPlan` interprets the description;
`operators::backend::mfem::make_volume_equation_cache` declares a graph whose ordinary
dependency cache owns the accepted linearization. `prepare_volume` supplies current
inputs; free residual and Jacobian functions consume the accepted data. `Workspace`
is reusable scratch, separate from frozen element data. All equations use
the same graph construction and application functions. The physics files do not
include MFEM or an operator backend.
See [the operator architecture and extension guide](operators.md) for ownership,
restrictions, and the numerical implementation. Start with the consumer sandbox to
see how a model connects MFEM term bindings, named caches, and the MFEM Jacobian adapter.
## Mathematics and state
The density balance is `integral (A(rho) - A(rho_s) + Phi - Omega^2 Psi - U_s) q_rho dV` on stellar
domains, with the EOS pressure potential `A`. It reads `Omega` and the surface level `U_s` from global
scalar coefficients in the numerical state; its constructor specifies the rotation axis and center.
The generic Jacobian applies `d(w f) = w df + f dw`, including the equation's explicit
position derivative. Scalar pullback basis functions stay fixed when displacement varies;
gradients and divergences also differentiate the mapped operand and test. Packed Jacobian
columns follow `EquationPlan::Columns` (unique terms), then displacement.
Default preparation uses `PreparationMode::reuse_unchanged` and refreshes only changed
dependencies. Explicit `PreparationMode::rebuild` forces the requested graph to refresh. Caller vectors may change or be destroyed after
preparation without changing that snapshot. A rejected preparation invalidates the previous
snapshot; residual and Jacobian calls then fail until a successful preparation.
`try_prepare_volume` returns numerical rejections with element/point context. Incorrect bindings
and sizes remain programming errors reported through SERiF's always-active checks.
Mesh, spaces, mapping object, term bindings, and compactification grid function must outlive
the cache and any accepted data still in use. Rebuild term bindings after mesh topology or space changes. For coordinate
edits, notify MFEM with `NodesUpdated()` and prepare again. In-place coordinate changes that bypass
MFEM's update notification cannot be detected. Calls sharing MFEM spaces/mapper are serial.
`discretization::backend::mfem::TermBinding` associates an existing term with an MFEM
space, using its registered support and domain schema. It owns only its supported-DOF indices. It does not define
another field catalog. When a general DOF implementation is migrated, consolidate this
binding with it rather than retaining two maps.
The existing quadrature policy can override each equation's quadrature estimate. The shared rule
covers every operand form and includes an estimate for the displacement determinant's degree.
Fractional/tabulated EOS and curved mappings still require quadrature convergence checks.
## Gravity contributions
[`primal_gravity.hpp`](../src/include/serif/equations/primal_gravity.hpp) contains
`PrimalPoissonBalance{four_pi_G}`. The coefficient is supplied by the caller so dimensional
and normalized units use the same equation. Its volume residual is
```text
integral_all grad(v) . grad(Phi) + four_pi_G integral_star v rho
```
A row can return `contributions()` as a tuple. Each contribution declares a
`TestOperand`, `Support`, `Operands`, and a point evaluator returning the coefficient
of its test. `Contribution<Operand<Test, Operation>, Support>` supplies the first two
aliases and the row term. This keeps the gradient on the test and the restricted source
visible in the physics file. The zero potential at infinity is imposed separately.
Values are selected with `point.fields.get<Term>()` when a term appears once, or
`point.fields.get<Operand<Term, Operation>>()` when sampling more than one operation.
The divergence of a vector is a scalar. For a vector result use
`PointLinearization<Operands, discretization::forms::VectorValue>`; a derivative with
respect to a scalar is a three-vector, and with respect to a vector is a 3x3 matrix
indexed `[output_component][input_component]`. Existing scalar equations retain their
original interface.
Use the scalar binding for `gravity::potential` and the restricted density binding. The row uses
the same `make_volume_equation_cache` and numerical application functions as every other
equation; no gravity-specific MFEM operator is required.
## Scope and regression coverage
The backend handles scalar H1/L2 **value**, scalar H1 **gradient** and vector H1 **value/divergence/gradient** volume
equations in three dimensions on conforming serial meshes. It rejects unsupported
operations and spaces. Scalar boundary constraints, point constraints, global scalars, tensor contractions
and complete serial transpose actions are implemented; see [the operator guide](operators.md).
H(div), H(curl), surface integrals and MPI assembly remain deferred.
The closure numerical tests were in **MeanField**, not yet SERiF. The following contracts are
ported using SERiF naming/style and a small serial mesh with core, envelope and vacuum attributes.
They exercise the shared volume machinery through a test-only two-field closure,
`rho - rho_EOS(h)`, declared in `tests/include/serif/tests/equations/test_equations.hpp`; it is
not a production equation:
| MeanField test contract | SERiF coverage |
| --- | --- |
| Representable constant closure; stellar mass matrix | `closure_kernels.cpp` |
| Thermodynamic and geometry centered differences | `closure_kernels.cpp`, `closure_conditions.cpp` |
| Mapped volume, vacuum exclusion, directional linearity | `closure_kernels.cpp` |
| Supported dimensions; reduced/full restriction | `closure_prepared.cpp`, `state_validation.cpp` |
| EOS and folded-geometry rejection, then recovery | `closure_prepared.cpp` |
| Residual, individual columns, combined and packed actions vs manual assembly | `closure_prepared.cpp` |
| Frozen ownership and fresh preparation after rho/h/geometry changes | `closure_prepared.cpp` |
| n=1, 1.5, 3 and deformation conditions; balanced combined differences | `closure_conditions.cpp` |
| Exact closure remains zero under deformation | `closure_conditions.cpp` |
| Context identity/revision invalidation | Shared exact snapshots and binding/mesh validation; explicit full refresh remains available |
`manual_closure.cpp` ports the direct quadrature algorithm and evaluates the analytic polytrope
independently of the new equation evaluator and cached basis contractions. It is a test reference,
not a second production operator. The shared serial tests additionally compare tensor and dense
contractions and complete transpose actions; MPI assembly remains outside this port.
Additional checks cover tetrahedra/hexahedra, both displacement orderings, analytic dilation volume
and derivative, stale bindings, quadrature overrides and a compatible non-polytropic EOS.
No new convergence experiments or resolution study are part of this change.
Build with `meson compile -C build`, run the full suite with `meson test -C build --print-errorlogs`,
or select the new cases with `build/tests/serif_tests '[equations]'`.