Skip to content

Multi-Phase Flow

Overview

The FluidDynamics module supports multi-phase and multi-component flow via pseudo-potential methods. These methods introduce a short-range non-ideal force between fluid nodes that drives phase separation into liquid and vapor phases without tracking an explicit interface.

Two pseudo-potential models are available:

ModelControlled byEOS
BenziDo_Benzi = trueShan–Chen pseudo-potential
KupershtokhDo_Kupershtokh = trueVan der Waals (or custom EOS)

Both models are implemented inside FlowSolverLBM and are configured via the input file.


Benzi pseudo-potential model

Physics

The Benzi (Shan–Chen) model introduces a cohesive force between fluid nodes of the same component via a scalar pseudo-potential:

(1)ψ(ρ)=1eρ/ρ0

The resulting interaction force on a node at x is:

(2)FBenzi(x)=Gbψ(ρ(x))xyzwxyzψ(ρ(x+exyz))exyz

where:

  • Gb — Benzi interaction strength parameter (Gb matrix, per component pair)
  • ρ0 — reference density controlling the shape of ψ (rho_0 per component)
  • wxyz — D3Q27 lattice weights
  • exyz — lattice velocity vectors

The force FBenzi drives like-component molecules together and repels different components, producing phase separation.

BenziGas helper

BenziGas provides a lookup table of pre-computed equilibrium state values as a function of the Benzi parameter Gb:

cpp
struct BenziGas
{
    struct EquilibriumValues_t {
        double BenziParameter;
        double lbVaporDensity;
        double lbLiquidDensity;
        double lbSurfaceTension;
    };

    static EquilibriumValues_t EquilibriumValues(double BenziParameter);
};

The table covers Gb[4.02,5.86]. Values outside this range cause the simulation to abort. Linear interpolation is used between table entries.

Usage: call BenziGas::EquilibriumValues(Gb) before setting up the FlowSolverLBM to determine the correct LiquidDensity, VaporDensity, and SurfaceTension input values.


Kupershtokh two-phase model

Physics

The Kupershtokh model is based on the Equation of State (EOS) approach. A potential Φ derived from the EOS determines a non-ideal pressure correction:

(3)Φ(ρ)=(GKpEOS(ρ)ρ3)

The interaction force is:

(4)FKuper(x)=2Φ(ρ(x))xyzwxyzΦ(ρ(x+exyz))exyz

where GK is the Kupershtokh parameter (lbGK matrix) and pEOS is the reduced pressure from the Van der Waals (or a user-specified) EOS.

Optimal parameter

The static helper OptimalParaKuper computes the optimal Kupershtokh parameter for a given reduced temperature:

cpp
static double OptimalParaKuper(double ReducedTemperature,
                                double GasParameter = 0.01);

This is essential for numerical stability: choosing a sub-optimal GK causes parasitic currents or instability near phase boundaries.

VanDerWaalsGas helper

VanDerWaalsGas provides the Van der Waals EOS and a lookup table of equilibrium coexistence values:

cpp
struct VanDerWaalsGas
{
    // Reduced Van der Waals equation of state
    static double ReducedPressure(double Density, double Temperature,
                                  double CriticalDensity = 1.0,
                                  double CriticalTemperature = 1.0);

    struct EquilibriumValues_t {
        double Temperature;
        double VaporDensity;
        double LiquidDensity;
    };

    static EquilibriumValues_t EquilibriumValues(
        double Temperature,
        double CriticalTemperature = 1.0,
        double LaplacePressure = 0.0);
};

The Van der Waals EOS in reduced form:

(5)p=8ρT3ρ3(ρ)2

where starred quantities are normalized by their critical values. The equilibrium table covers T[0.01,1.00] (all in reduced units).


Phase density profile

For initialization, a smooth hyperbolic tangent profile is provided:

cpp
double DensityProfile(double x, size_t n = 0) const;

This generates a liquid–vapor interface profile for component n at position x.


Wetting at solid surfaces

Wetting between fluid components and solid phases is controlled via the Wetting parameter matrix. A non-zero wetting parameter modifies the effective density used in the force calculation at solid nodes, implementing contact-angle control.

The DensityWetting field stores this modified density:

cpp
Storage3D<double, 1> DensityWetting; ///< ρ / wetting parameter per component

InteractionFluidFluid

InteractionFluidFluid is a lightweight companion class for future extensions of fluid–fluid interaction models beyond what is built into FlowSolverLBM.

cpp
class InteractionFluidFluid : public OPObject
{
public:
    void Initialize(Settings& locSettings) override;
    void ReadInput(std::string InputFileName) override;
};

Currently this class provides the initialization/input interface; the core interaction forces are computed directly in FlowSolverLBM::CalculateForceTwoPhase().


Fluid redistribution

In two-phase flow with moving solids, small fluid parcels can become trapped inside obstacles. FluidRedistributionRange controls the distance over which fluid is redistributed when this occurs, preventing mass loss.


Numerical considerations

  • Surface tension and interface width are coupled: sharper interfaces require larger |Gb| or GK but increase numerical artifacts (parasitic currents).
  • The Benzi model is stable for Gb[4.02,5.86] (enforced by BenziGas).
  • The Kupershtokh model requires T<1 (below critical temperature) for phase separation; at T1 the phases merge.
  • EnforceMassConservation() should be called every timestep in two-phase simulations to prevent drift in total fluid mass.
  • Do_FixPopulations = true is recommended for high density ratio (>10) simulations.

Released under the GNU GPLv3 License.