pub struct SolidificationPorosity { /* private fields */ }Expand description
Simple solidification as a porous blockage — upstream
porosityModels::solidification.
§The model
The solid phase is represented purely as a drag on the momentum equation,
S = -α ρ D(T) U,
with D(T) a user-supplied table of drag against temperature and α an
optional phase fraction of the solidifying phase. Nothing else happens:
upstream states plainly that the latent heat of solidification is not
included and the temperature is unchanged by the modelled change of phase.
§When to use this instead of the enthalpy-porosity model
SolidificationMelting is the physically
complete model — it tracks a liquid fraction, absorbs latent heat, and
carries its own Boussinesq buoyancy. This one does none of that. It exists
because it is cheap and because it needs no thermophysical model at all: it
only ever reads a temperature field. Use it to freeze flow out of a region
whose thermal history you do not care about; use the enthalpy-porosity model
when the phase change itself is the physics of interest.
A gallium melting calculation, for instance, cannot be run with this model — without latent heat the melt front advances at entirely the wrong rate.
§State
Stateless, unlike SolidificationMelting.
The drag depends only on the current temperature, so there is no history to
carry and no per-timestep update to guard.
Implementations§
Source§impl SolidificationPorosity
impl SolidificationPorosity
Sourcepub fn new(
name: impl Into<String>,
velocity_name: impl Into<String>,
selection: CellSelection,
drag: TemperatureTable,
form: MomentumEquationForm,
) -> Self
pub fn new( name: impl Into<String>, velocity_name: impl Into<String>, selection: CellSelection, drag: TemperatureTable, form: MomentumEquationForm, ) -> Self
Build the model.
name— identifier for diagnostics, upstream’s dictionary key.velocity_name— the velocity field whose equation gains the drag.selection— the cells acted on, upstream’scellZone.drag— theD(T)table.form— whether the momentum equation is kinematic or density-weighted; seeMomentumEquationForm.
The optional phase fraction (upstream’s alpha, default none) is not
set here; use
with_phase_fraction if the drag should
act only on a fraction of each cell.
Sourcepub fn with_phase_fraction(self, alpha_name: impl Into<String>) -> Self
pub fn with_phase_fraction(self, alpha_name: impl Into<String>) -> Self
Name the optional phase fraction field of the solidifying phase,
upstream’s alpha keyword.
The drag is scaled by this field, so a cell only half occupied by the
solidifying phase feels half the blockage. Without it upstream
substitutes geometricOneField(), i.e. α = 1 everywhere.
Sourcepub fn velocity_name(&self) -> &str
pub fn velocity_name(&self) -> &str
The velocity field this adds drag to.
Sourcepub fn phase_fraction_name(&self) -> Option<&str>
pub fn phase_fraction_name(&self) -> Option<&str>
The name of the optional solidifying-phase fraction field, if one was set.
Sourcepub fn selection(&self) -> &CellSelection
pub fn selection(&self) -> &CellSelection
The cells acted on.
Sourcepub fn drag_table(&self) -> &TemperatureTable
pub fn drag_table(&self) -> &TemperatureTable
The D(T) table.
Sourcepub fn form(&self) -> MomentumEquationForm
pub fn form(&self) -> MomentumEquationForm
Which momentum-equation form this model was built for.
Sourcepub fn add_momentum_source(
&self,
temperature: &VolScalarField,
rho: &VolScalarField,
phase_fraction: Option<&VolScalarField>,
eqn: &mut FvVectorMatrix,
)
pub fn add_momentum_source( &self, temperature: &VolScalarField, rho: &VolScalarField, phase_fraction: Option<&VolScalarField>, eqn: &mut FvVectorMatrix, )
Add the porous drag to a velocity equation.
Upstream’s correct(fvVectorMatrix& UEqn), which does
Udiag[celli] += V[celli]*alpha[celli]*rho[celli]*D_->value(T[celli]);rho is used only in the DensityWeighted
form and ignored otherwise; pass any field in the kinematic case.
phase_fraction is Some only if the model was built with
with_phase_fraction — passing None when
one was named silently drops the scaling, so callers should keep the two
together.
§Sign convention — this one is not negated, unlike the fvModel
This is the trap when reading the two solidification models side by
side. Upstream’s fvModel solidificationMelting writes into an
intermediate matrix that solve(UEqn == fvModels.source(...)) then
subtracts, so its Sp[celli] += Vc*S with a negative S reaches
the solved system as a positive diagonal contribution. Upstream’s
porosityModel, by contrast, is handed the solver’s own UEqn and
mutates UEqn.diag() in place — nothing negates it afterwards, which is
exactly why upstream writes += here with a positive D.
The two upstream files therefore look like they disagree about the sign
of a Darcy drag, and they do not. This port writes
diag += V·α·ρ·D(T) — upstream’s expression unchanged — because
eqn here, like upstream’s UEqn, is the system being solved.
Increasing the diagonal damps the velocity, which is the intended sink.
Sourcepub fn force_diagonal(
&self,
temperature: &VolScalarField,
rho: &VolScalarField,
phase_fraction: Option<&VolScalarField>,
cell_volumes: &[f64],
) -> Vec<f64>
pub fn force_diagonal( &self, temperature: &VolScalarField, rho: &VolScalarField, phase_fraction: Option<&VolScalarField>, cell_volumes: &[f64], ) -> Vec<f64>
The diagonal drag coefficient per cell, upstream’s Udiag inside
calcForce.
This is V·α·ρ·D(T) — the same quantity
add_momentum_source adds to the diagonal,
exposed on its own so a caller can form upstream’s diagnostic
force = Udiag·U (units [N] in the density-weighted form, [m⁴/s²]
in the kinematic one) without re-deriving it. The cell volume is
included, because upstream’s calcForce passes mesh_.V() into the
same apply the momentum correction uses.
It is a diagnostic only: no equation gains a term from calling this.
Returns one value per selected cell, in selection order, not one per mesh cell.