29. Solver Framework Reference#

This appendix maps the mathematical stages used in the theory chapters to the principal Stream/Loci facts and sparse-row stores. It is a navigation aid for developers, not a replacement for the derivations or for schedule inspection. The same suffix can mean different stages for different facts, so names must be interpreted from their producing and consuming rules rather than from spelling alone.

29.1. Iteration Dataflow#

The ordinary compressible SIMPLE-family path can be summarized by the following fact transitions:

Mathematical role

Representative Stream facts

Interpretation

Current outer-iteration state

p{n,it}, v{n,it}, rho{n,it}, eos_state{n,it}

Known state used to assemble the current equation blocks

Scalar and thermal updates

eStar, hStar, temperatureStarLimited, yStar

Updated non-pressure variables used by the EOS reconstruction

Momentum predictor

vStar, volFluxStar

Provisional velocity and face volumetric flux before pressure correction

Pressure correction

pPrime

Solution of the pressure-correction linear system

Corrected primary fields

pStarLimited, vCorrected, volFluxCorrected

Pressure, velocity, and flux after applying the selected correction

Corrected EOS state

eos_state_star, rhoStar, temperatureStar

Complete thermodynamic state rebuilt after the corrected fields are available

Outer-iteration advance

rhoStar{n,it} -> rho{n,it+1} and analogous advances

State supplied to the next nonlinear iteration

The rhoStar fact is therefore not the density estimate \(\rho^k+p'/a_s^2\) used to linearize the pressure equation. It is the density extracted from the corrected EOS state. Likewise, pStar denotes the separate preliminary-pressure unknown in the SIMPLER path, whereas vStar denotes the momentum predictor. The word Star is a local naming convention, not a universal algorithmic time level.

29.2. Mesh and Connectivity Landmarks#

Name

Type

Meaning

pos

store<vector3d>

Cartesian coordinates of grid nodes

face2node

multiMap

Ordered nodes defining each face

cl, cr

Map

Cells on the left and right of a face; the stored face normal points from cl to cr

upper, lower

multiMap

Cell-to-face maps defined in Loci Face Orientation and Cell Incidence

geom_cells

constraint

Physical computational cells, excluding non-geometric entities

29.3. Math-to-Code Naming Map#

Mathematical meaning

Theory notation

Common code name

Qualification

Cell velocity

\(\vec u\)

v

Cell-centered vector

Provisional momentum velocity

\(\vec u^*\)

vStar

Result of the momentum predictor solve

Corrected velocity

\(\vec u^{k+1}\)

vCorrected

Starts from vStar and receives pressure-correction contributions

Current pressure

\(p^k\)

p

Pressure entering the current equation assembly

Pressure correction

\(p'\)

pPrime

Linear-system solution used by velocity and flux corrections

SIMPLE/SIMPLEC corrected pressure

\(p^k+\alpha_p p'\)

pStarLimited

Relaxed and clipped pressure update

SIMPLER preliminary pressure

\(\tilde p\)

pStar, pStarLimited

Separate pressure-equation path; not the pressure correction

Current density

\(\rho^k\)

rho{n,it}

Density consumed by pressure correction

EOS-rebuilt density

\(\rho^{k+1}\)

rhoStar{n,it}

Extracted from eos_state_star, then advanced

Central momentum coefficient

\({}^{(u)}\!a_P\)

vMainCoefficient

Raw assembled diagonal before predictor relaxation

Predictor diagonal

\({}^{(u)}\!a_P/\alpha_v\)

vStar_D

Diagonal passed to the provisional-velocity solve

Face pressure-response coefficient

\(d_f\)

pPrimeCoefficient

Formula depends on momentum-interpolation and algorithm constraints

Provisional face volume flux

\(\dot V_f^*\)

volFluxStar

Multiply by the selected face density when a mass flux is required

Corrected face volume flux

\(\dot V_f^{k+1}\)

volFluxCorrected

Post-pressure-correction flux

Velocity relaxation

\(\alpha_v\)

vStar_RelaxationFactor

Used in predictor and correction coefficients

Pressure relaxation

\(\alpha_p\)

pPrime_RelaxationFactor

Used in the SIMPLE/SIMPLEC pressure update, not as a blanket divisor of the pressure-correction matrix

The theory chapters normally use mass flux \(\dot m_f\). Much of the source stores volumetric flux and forms mass flux as faceDensity*volFlux or rho_f*volFlux. Moving-grid paths use the flux relative to gridVolFlux.

The stored cl-to-cr orientation, the calligraphic upper and lower face sets, and their relationship to cell-outward theory quantities are defined in Loci Face Orientation and Cell Incidence. Rule bodies must supply the corresponding signs explicitly.

29.4. Momentum-Predictor Stores#

The raw momentum diagonal is accumulated in vMainCoefficient. The under-relaxed predictor diagonal is then

(29.4.1)#\[vStar\_D = \frac{vMainCoefficient}{vStar\_RelaxationFactor},\]

except that blanked cells are assigned a decoupling value. The off-diagonal entries are stored in vStar_L and vStar_U; vStar_B is the corresponding predictor right-hand side. Solving this row produces vStar.

The hatted SIMPLER velocity is vHat. It is built from the non-pressure momentum source and neighbor contributions divided by vMainCoefficient; it should not be inferred from a generic H(v) store name.

29.5. Pressure-Correction Stores#

The pressure-correction system is stored as

(29.5.1)#\[pPrime\_D\,p' + \sum_{\mathrm{nbr}}pPrime\_{off}\,p'_{\mathrm{nbr}} = pPrime\_B.\]

The main landmarks are:

Store

Role

pPrimeCoefficient

Face coefficient supplied by momentum interpolation

pPrimeTemp_D

Additive diagonal accumulator

pPrime_D

Final pressure-correction diagonal

pPrime_L, pPrime_U, pPrime_I

Stored off-diagonal or interface entries, with neighbor signs absorbed

pPrimeTemp_B

Additive continuity-defect and time-history accumulator

pPrime_B

Final pressure-correction right-hand side

pPrime

Solved pressure correction

Pressure relaxation is applied when SIMPLE or SIMPLEC updates the primary pressure. It is not, in the main pressure-correction path, a universal \(1/\alpha_p\) scaling of pPrime_D, pPrime_L, or pPrime_U. The separate SIMPLER pStar_* pressure system does apply its own pStar_RelaxationFactor during preliminary-pressure assembly.

The detailed sign convention, face additions, compressible terms, temporal right-hand side, and code landmarks follow.

29.6. Pressure-Correction Matrix Storage#

The pressure-correction equation is derived in Pressure-Correction Equation on Unstructured Grids. This section does not derive a different equation; it explains how the assembled coefficients are stored and accumulated in the linear solver. The same \({}^{(p')}\!a_P\), \({}^{(p')}\!a_{\text{nbr}}\), and \({}^{(p')}\!b_P\) contributions remain; only the sign convention and storage layout change.

29.6.1. Stored Sign Convention and Temporary Accumulation#

The pressure-correction chapter writes the equation in the usual Patankar form,

(29.6.1.1)#\[{}^{(p')}\!a_P p_P^{'} = \sum_{\text{nbr}} {}^{(p')}\!a_{\text{nbr}} p_{\text{nbr}}^{'} + {}^{(p')}\!b_P,\]

with positive neighbor coefficients \({}^{(p')}\!a_{\text{nbr}}\). The implementation stores the same equation with the neighbor signs already absorbed into the sparse off-diagonal entries. For a cell \(P\), the row sent to the linear solver is therefore better written as

(29.6.1.2)#\[{}^{(p')}\!D_P p_P^{'} + \sum_{\text{nbr}} {}^{(p')}\!A_{P,\text{nbr}} p_{\text{nbr}}^{'} = {}^{(p')}\!B_P ,\]

where \({}^{(p')}\!D_P\) is the diagonal entry, \({}^{(p')}\!A_{P,\text{nbr}} \le 0\) are the stored off-diagonal entries, and \({}^{(p')}\!B_P\) is the right-hand side. The subscript pair on \({}^{(p')}\!A_{P,\text{nbr}}\) is therefore a row/column index pair: row \(P\), column \(\text{nbr}\). In the implementation these correspond to the stores pPrime_D, pPrime_L / pPrime_U, and pPrime_B, respectively. Thus, relative to Eq. (6.5.6),

(29.6.1.3)#\[{}^{(p')}\!A_{P,\text{nbr}} = - {}^{(p')}\!a_{\text{nbr}}.\]

This sign change is the first source of confusion when reading the assembly rules. The second is that the code first accumulates contributions into temporary stores such as pPrimeTemp_D and pPrimeTemp_B and only later copies them into the final sparse row. The many unit/apply rules are therefore not separate equations; they are separate additions to the same final row.

29.6.2. Interior-Face Storage Pattern#

The numerous face-coefficient rules should be read in the same spirit. They do not define different matrix structures. They all compute the same abstract face coefficient \(d_f\), although the implementation names that quantity pPrimeCoefficient. Different momentum-interpolation variants simply provide different formulas for \(d_f\). Once \(d_f\) has been computed, the storage pattern is unchanged.

For a compact description of that pattern, define

(29.6.2.1)#\[\begin{split}\beta_f = \begin{cases} 1, & \text{SIMPLE}, \\[3pt] 1+\kappa_f, & \text{SIMPLEC}, \end{cases} \qquad \kappa_f = \frac{\alpha_v}{1-\alpha_v+\delta_f},\end{split}\]

where \(\alpha_v\) is the velocity relaxation factor and \(\delta_f\) is the face-interpolated transient correction factor used by SIMPLEC.

For the selected continuity form, let \(\tau_L\) and \(\tau_R\) denote the density-scaling factors applied when the pressure-difference coupling is inserted into the left and right cell rows. In simple mass-based forms these are just unity; in normalized variable-density forms they contain the corresponding local density normalization. The implementation controls those choices through options such as pPrimeFactor or rhoNormFactor, but the algebra below does not depend on the particular parameterization. For an interior face \(f\) between cells \(L\) and \(R\), define

(29.6.2.2)#\[a_{f,L}^{\mathrm{press}} = \beta_f \frac{d_f}{\tau_L}, \qquad a_{f,R}^{\mathrm{press}} = \beta_f \frac{d_f}{\tau_R}.\]

These are not new physical coefficients; they are just the left-row and right-row versions of the same pressure-difference face coupling after whatever local density scaling the selected formulation uses. The stored interior-face contributions are therefore

(29.6.2.3)#\[\begin{split}\begin{aligned} {}^{(p')}\!D_L &\mathrel{+}= a_{f,L}^{\mathrm{press}}, & {}^{(p')}\!A_{L R} &= -a_{f,L}^{\mathrm{press}}, \\ {}^{(p')}\!D_R &\mathrel{+}= a_{f,R}^{\mathrm{press}}, & {}^{(p')}\!A_{R L} &= -a_{f,R}^{\mathrm{press}} . \end{aligned}\end{split}\]

This is the stored-row version of the same algebra already summarized in the assembled-row discussion. In particular, the SIMPLEC modification does not create a different pressure equation; it simply scales the face coupling by the factor \(1+\kappa_f\).

29.6.3. Compressible Additions in the Stored Row#

This subsection is still not deriving a new pressure equation. It is only translating the extra compressible coefficient update from Eq. (6.6.5) into the stored-row notation above.

Let \(c_f\) denote the same upwind acoustic face coefficient introduced in Eq. (6.6.1), after any branch-specific scaling factors have been absorbed into it. Using the same row-normalization factors \(\tau_L\) and \(\tau_R\) as above, define

(29.6.3.1)#\[\tilde{c}_{f,L} = \frac{c_f}{\tau_L}, \qquad \tilde{c}_{f,R} = \frac{c_f}{\tau_R}.\]

Then the additional stored-row contributions are

(29.6.3.2)#\[\begin{split}\begin{aligned} {}^{(p')}\!D_L &\mathrel{+}= \tilde{c}_{f,L}, & {}^{(p')}\!A_{R L} &\mathrel{-}= \tilde{c}_{f,R}, \qquad && \hat{m}_f^{*} > 0, \\ {}^{(p')}\!D_R &\mathrel{+}= \tilde{c}_{f,R}, & {}^{(p')}\!A_{L R} &\mathrel{-}= \tilde{c}_{f,L}, \qquad && \hat{m}_f^{*} < 0. \end{aligned}\end{split}\]

So the storage rule mirrors the assembled-row statement exactly: the extra compressible contribution is added to the diagonal of the upwind row and to the off-diagonal entry of the downwind row. When the mesh moves, the implementation evaluates the upwind direction using the flux relative to the grid motion; in the code this relative flux is formed from volFluxStar - gridVolFlux. The implementation also folds branch-specific scaling choices, such as compressiblePPrimeFactor, into the coefficient \(c_f\).

29.6.4. Right-Hand-Side Assembly#

The right-hand side is assembled in the same additive way. Let \(\tau_P\) denote the local row-normalization factor for cell \(P\), consistent with the left/right factors introduced above. Then the stored right-hand side can be written as

(29.6.4.1)#\[{}^{(p')}\!B_P = - \sum_f \frac{\hat{m}_f^{*}}{\tau_P} + {}^{(p')}\!b_{P,\mathrm{time}},\]

where \(\hat{m}_f^{*}\) denotes the predicted face mass flux appearing in the selected form of the continuity equation. For a fixed grid this is simply built from the starred face flux. For moving-grid or normalized volumetric forms, the implementation instead uses the corresponding flux relative to the grid motion; this is where gridVolFlux enters the bookkeeping.

For first-order BDF in the compressible form, the explicit unsteady contribution added to the right-hand side is

(29.6.4.2)#\[{}^{(p')}\!b_{P,\mathrm{time,BDF1}} = \frac{\rho_P^{n}\Omega_P^{n}-\rho_P^{k}\Omega_P^{k}} {\Delta t\,\tau_P}.\]

For BDF2, the code adds the same first-order defect plus the lagged second-order correction, giving

(29.6.4.3)#\[{}^{(p')}\!b_{P,\mathrm{time,BDF2}} = \frac{1}{\tau_P} \left[ \frac{\rho_P^{n}\Omega_P^{n}-\rho_P^{k}\Omega_P^{k}}{\Delta t} - c_2 \left( c_{F2}\rho_P^{k}\Omega_P^{k} - c_{F1}\rho_P^{n}\Omega_P^{n} + c_{F0}\rho_P^{n-1}\Omega_P^{n-1} \right) \right],\]

where the coefficients \(c_2\), \(c_{F0}\), \(c_{F1}\), and \(c_{F2}\) are the time-integration weights introduced in Chapter 10; in the code these appear as the timeIntegratorFactor* values. In other words, the time scheme enters the final pressure-correction row in two places:

  1. through the face coefficient \(d_f\),

  2. through the explicit unsteady part of the right-hand side and the implicit acoustic diagonal contribution.

29.6.5. Boundary Summary and Code Landmarks#

Finally, boundary-specific rules are just one-sided versions of the same assembly logic. A specified-pressure boundary contributes only to the adjacent cell diagonal and right-hand side, a total-pressure inlet uses a specialized boundary coefficient, and the fixed-pressure reference cell is anchored by zeroing the appropriate source/off-diagonal entries. Reading the code this way turns the long list of apply rules into a bookkeeping exercise: each rule is simply adding one physically identifiable term to the same final linear system row.

If you want to look those objects up in the source, the most important math-to-code identifications are:

  • pPrimeCoefficient \(\leftrightarrow d_f\)

  • pPrimeCoefficientTotalPressureInlet \(\leftrightarrow\) specialized boundary coefficient \(d_{\mathrm{bnd}}\)

  • pPrimeTemp_D \(\leftrightarrow\) accumulator for the diagonal \({}^{(p')}\!a_P\) before copy to pPrime_D

  • pPrime_L / pPrime_U / pPrime_I \(\leftrightarrow\) stored off-diagonals \({}^{(p')}\!A_{P,\text{nbr}}\)

  • pPrimeTemp_B \(\leftrightarrow\) accumulator for the right-hand side \({}^{(p')}\!b_P\) before copy to pPrime_B

At this point the pressure-correction equation has been fully assembled, interpreted, and translated into the solver’s storage convention. The next step is therefore not further assembly, but applying the solved correction field to the flow variables.