dragonfly_sim.utils.gradient_condensation
Newton problems whose residual reads a gradient field that is eliminated from the unknowns.
At p = 0 the RANS model reconstructs a DG0 gradient G of the state by Green-Gauss (core/reconstruction.py),
M_G G = b(U), b(U; tau) = sum over facets of int u_f (x) n : tau ds,
with M_G the diagonal (cell-volume) DG0 mass matrix. G is linear in the facet states, so it is eliminated exactly instead of being carried as an unknown:
R(U) = R_U(U, G(U)), dR/dU = A_UU + A_UG M_G^-1 B_GU,
with A_UU = dR_U/dU at fixed G, A_UG = dR_U/dG and B_GU = db/dU. The product widens the Jacobian’s stencil to the neighbours’ neighbours, which is the stencil of the reconstructed scheme. Everything downstream (SNES, the positivity limiter, the time integrator) still sees a single-field problem in U.
jacobian_mode selects what Newton’s linear solve uses (configure_snes wires it into an existing SNES):
exact operator = preconditioning matrix = A_UU + A_UG M^-1 B_GU compact_pc operator exact, preconditioning matrix A_UU: the compact,
nearest-neighbour part (gradients frozen), as finite-volume codes precondition with their first-order Jacobian. The default: on the coarse SA NACA0012 C-grid it takes the same PTC path as MUMPS, 5x faster, and scales to the 181k-cell STW wing where every exact factorization runs out of memory.
- compact operator = preconditioning matrix = A_UU: approximate Newton
(defect correction); converges linearly
Classes
NonlinearProblem_mod for R_U(U, G(U)). |
|
A = A_UU + A_UG M^-1 B_GU for a residual form F(U, G), with b_G the UFL |
|
Python-Mat context of the transposed condensed Jacobian without forming it: |
Module Contents
- class dragonfly_sim.utils.gradient_condensation.CondensedGradientProblem(F, J, u, G, b_G, update_G, inv_mass, jit_options={})
Bases:
dragonfly_sim.utils.Nonlinear_utils.NonlinearProblem_modNonlinearProblem_mod for R_U(U, G(U)).
G is the gradient Function the residual reads, b_G the UFL form of the Green-Gauss right-hand side, update_G() recomputes G from the current u in place and inv_mass is M_G^-1 as a Vec in G’s layout.
- F(x, b)
Assemble the residual F into the vector b.
- Args:
x: The vector containing the latest solution b: Vector to assemble the residual into
- J(x, A)
Assemble the Jacobian matrix.
- Args:
x: The vector containing the latest solution A: The matrix that will hold the Jacobian matrix
- configure_snes(snes, mode)
Re-wire snes’s Jacobian for jacobian_mode mode (see the module docstring). Call after the solver is built.
- G
- MODES = ('exact', 'compact_pc', 'compact')
- _A
- _A_UU
- _condensed
- jacobian_mode = 'exact'
- update_G
- class dragonfly_sim.utils.gradient_condensation.CondensedJacobian(F, u, G, b_G, inv_mass, jit_options={}, A_UU=None, a_UU=None)
A = A_UU + A_UG M^-1 B_GU for a residual form F(U, G), with b_G the UFL Green-Gauss right-hand side (test function on G’s space) and inv_mass M_G^-1 as a Vec in G’s layout. The matrices are plain aij: MatMatMult does not take baij here. The product’s sparsity is fixed by the operands’, so one symbolic product sizes A for good.
- _assemble_blocks()
- assemble()
Assemble A_UU, A_UG, M^-1 B_GU and A at the current state; G must be up to date.
- A
- A_UG
- A_UU
- B_GU
- _C
- _a
- _a_GU
- _a_UG
- _inv_mass
- class dragonfly_sim.utils.gradient_condensation.TransposedCondensedOperator(P, A_UG, B, release_B)
Python-Mat context of the transposed condensed Jacobian without forming it:
A^T x = (A_UU + A_UG B)^T x = P x + B^T (A_UG^T x), P = A_UU^T
with B = M_G^-1 dG/dU (any Mat with mult / multTranspose, e.g. the structured GreenGaussStateOperator). Neither A nor the product A_UG B is ever assembled. It owns P (also the preconditioning matrix), A_UG and B (released through release_B, a callable) and frees them in destroy().
- create_mat(comm)
- destroy(mat=None)
- mult(mat, x, y)
- _w