130 lines
8.2 KiB
Markdown
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]'`.
|