pub struct FvVectorMatrix {
pub mesh: Arc<FvMesh>,
pub ldu: LduMatrix,
pub source: Field<Vector3>,
}Expand description
Implicit vector equation A·U = b for a VolVectorField.
Mirrors Foam::fvVectorMatrix (fvMatrix<vector>).
The LDU coefficients are scalar — they multiply the entire velocity
vector equally in all three directions. The source vector is a
Field<Vector3>. Solving decomposes into three independent scalar
Gauss-Seidel solves (one per component).
Fields§
§mesh: Arc<FvMesh>Mesh the equation is defined on (shares the face addressing).
ldu: LduMatrixScalar LDU coefficients of the operator A (shared by all 3 components).
source: Field<Vector3>Right-hand-side vector source per cell, length n_cells.
Implementations§
Source§impl FvVectorMatrix
impl FvVectorMatrix
Sourcepub fn new(mesh: Arc<FvMesh>) -> Self
pub fn new(mesh: Arc<FvMesh>) -> Self
Allocate a zero-initialised vector matrix for mesh (zero coefficients,
zero source).
As with FvMatrix::new, the LDU face
addressing holds the internal faces, then one slot per
CyclicCoupling, then one slot per
AmiWeight of each
AmiCoupling, so every vector matrix on a
given mesh shares one structure and the +/− operators line up.
Sourcepub fn add_to_diag(&mut self, coeff: &Field<f64>)
pub fn add_to_diag(&mut self, coeff: &Field<f64>)
Add coeff[c] to the diagonal of cell c (e.g. a time-derivative term).
Sourcepub fn add_to_source(&mut self, term: &Field<Vector3>)
pub fn add_to_source(&mut self, term: &Field<Vector3>)
Add term[c] to the vector source of cell c.
Sourcepub fn set_reference(&mut self, cell: usize, value: Vector3)
pub fn set_reference(&mut self, cell: usize, value: Vector3)
Pin one cell’s velocity to a fixed value (reference cell for closed domains).
Sourcepub fn a_field(&self) -> VolScalarField
pub fn a_field(&self) -> VolScalarField
Diagonal coefficient per cell: A[c] = diag[c].
Used in PISO: rAU = 1 / UEqn.a_field().
Sourcepub fn h_field(&self, u: &VolVectorField) -> VolVectorField
pub fn h_field(&self, u: &VolVectorField) -> VolVectorField
Off-diagonal + source residual: H[c] = source[c] − Σ off-diag · U.
For a zero field x this returns source[c] directly.
Used in PISO: HbyA = rAU * UEqn.h_field(U).
Sourcepub fn solve(
&self,
name: &str,
settings: SolverSettings,
) -> (VolVectorField, SolverPerformance)
pub fn solve( &self, name: &str, settings: SolverSettings, ) -> (VolVectorField, SolverPerformance)
Solve each component (x, y, z) as an independent scalar Gauss-Seidel problem.
Sourcepub fn solve_bicgstab(
&self,
name: &str,
options: KrylovOptions,
settings: SolverSettings,
) -> (VolVectorField, SolverPerformance)
pub fn solve_bicgstab( &self, name: &str, options: KrylovOptions, settings: SolverSettings, ) -> (VolVectorField, SolverPerformance)
Solve each velocity component with preconditioned BiCGStab,
cold-started from U = 0.
The momentum matrix assembled by fvm::div_vec(phi, U) − fvm::laplacian_vec(nu, U) is asymmetric — upwind convection puts the
face flux on the donor side only, so lower[f] != upper[f]. That rules
out PCG and GAMG, and before this method the only option was the
Gauss-Seidel solve, whose sweep count grows like the
matrix condition number. With the default KrylovOptions this is
ILU(0)-preconditioned BiCGStab — the analogue of OpenFOAM’s PBiCGStab
with DILU on the U equation.
Because the LDU coefficients are scalar and identical for all three
components, this runs three independent scalar Krylov solves sharing one
preconditioner build per component. The returned
SolverPerformance reports the worst of the three: the largest
iteration count and the largest relative 2-norm residual
||b − A·U||₂ / ||b||₂, and converged only if all three converged.
Units: U is a velocity [m·s⁻¹]; the matrix and source carry whatever
units the assembling operators produced. The solve itself is
dimensionless.
Sourcepub fn solve_gmres(
&self,
name: &str,
options: KrylovOptions,
settings: SolverSettings,
) -> (VolVectorField, SolverPerformance)
pub fn solve_gmres( &self, name: &str, options: KrylovOptions, settings: SolverSettings, ) -> (VolVectorField, SolverPerformance)
Solve each velocity component with restarted GMRES(m), cold-started
from U = 0.
See solve_bicgstab for why an asymmetric solver
is needed at all. GMRES cannot break down and its residual is monotone,
but it stores options.restart basis vectors per component; prefer it
when BiCGStab reports converged = false.
Sourcepub fn solve_krylov(
&self,
name: &str,
initial: Option<&VolVectorField>,
method: KrylovMethod,
options: KrylovOptions,
settings: SolverSettings,
) -> (VolVectorField, SolverPerformance)
pub fn solve_krylov( &self, name: &str, initial: Option<&VolVectorField>, method: KrylovMethod, options: KrylovOptions, settings: SolverSettings, ) -> (VolVectorField, SolverPerformance)
Solve each velocity component with the Krylov method named by method,
optionally warm-started from initial (typically the previous time
step’s velocity field).
The general form behind solve_bicgstab and
solve_gmres. Each component x, y, z of
initial seeds the corresponding scalar solve; None starts from zero.
Trait Implementations§
Source§impl Add for FvVectorMatrix
impl Add for FvVectorMatrix
Source§impl AddAssign for FvVectorMatrix
impl AddAssign for FvVectorMatrix
Source§fn add_assign(&mut self, rhs: Self)
fn add_assign(&mut self, rhs: Self)
+= operation. Read moreSource§impl Clone for FvVectorMatrix
impl Clone for FvVectorMatrix
Source§impl Debug for FvVectorMatrix
impl Debug for FvVectorMatrix
Source§impl Neg for FvVectorMatrix
impl Neg for FvVectorMatrix
Source§impl Sub for FvVectorMatrix
impl Sub for FvVectorMatrix
Source§impl SubAssign for FvVectorMatrix
impl SubAssign for FvVectorMatrix
Source§fn sub_assign(&mut self, rhs: Self)
fn sub_assign(&mut self, rhs: Self)
-= operation. Read more