Class SpinodalDecompositionDetector
Spinodal decomposition occurs when the system is inside the spinodal curve (thermodynamically unstable region), where the second derivative of the Gibbs free energy with respect to composition becomes negative. In this regime, phase separation is barrierless — any infinitesimal fluctuation grows spontaneously, unlike classical nucleation which requires overcoming a free energy barrier.
The phase transition regions are:
- Stable (outside binodal): Single-phase, no phase transition possible
- Metastable (between binodal and spinodal): Classical nucleation applies — phase
transition requires a nucleation barrier. Use
ClassicalNucleationTheory. - Unstable (inside spinodal): Spinodal decomposition — barrierless, spontaneous phase separation with characteristic wavelength selection.
This class uses the EOS-computed Helmholtz free energy derivatives to determine the stability of the mixture. For a binary mixture, spinodal decomposition occurs when:
$$\frac{\partial^2 A}{\partial n_i \partial n_j} \leq 0$$ for the unstable component pair (i,j)
For multicomponent systems, the full Hessian matrix of the Helmholtz free energy with respect to composition is computed, and the minimum eigenvalue is checked.
Usage:
// Flash the system first
ThermodynamicOperations ops = new ThermodynamicOperations(system);
ops.TPflash();
system.initProperties();
SpinodalDecompositionDetector detector = new SpinodalDecompositionDetector(system);
detector.analyze();
if (detector.isInsideSpinodal()) {
// Barrierless phase separation — spinodal decomposition
double wavelength = detector.getDominantWavelength();
} else if (detector.isMetastable()) {
// Classical nucleation applies
ClassicalNucleationTheory cnt = ...;
} else {
// Stable single phase
}
References:
- Cahn, J.W. and Hilliard, J.E. (1958). Free Energy of a Nonuniform System. I. Interfacial Free Energy. J. Chem. Phys. 28, 258-267.
- Binder, K. (1987). Theory of first-order phase transitions. Rep. Prog. Phys. 50, 783-859.
- Michelsen, M.L. (1982). The isothermal flash problem. Part I. Stability. Fluid Phase Equilib. 9, 1-19.
- Version:
- 1.0
- Author:
- esol
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic enumEnumeration of thermodynamic stability states. -
Field Summary
FieldsModifier and TypeFieldDescriptionprivate booleanWhether analysis has been performed.private doubleEstimated dominant wavelength of spinodal decomposition in m.private double[][]The Hessian matrix d2A/(dNi*dNj) — second derivatives of Helmholtz free energy with respect to mole numbers.private doubleMinimum eigenvalue of the Hessian matrix of the Helmholtz free energy.private intPhase index to analyze (default 0 = first phase).private doubleStability margin: positive means stable, negative means unstable.Stability state of the system.private SystemInterfaceThe NeqSim thermodynamic system.private intThe component pair (i,j) with the most negative Hessian element.private intThe component pair (i,j) with the most negative Hessian element.private StringName of the most unstable component pair. -
Constructor Summary
ConstructorsConstructorDescriptionCreates a SpinodalDecompositionDetector for the given thermodynamic system. -
Method Summary
Modifier and TypeMethodDescriptionvoidanalyze()Performs the spinodal stability analysis.private voidanalyzeFugacityBased(PhaseInterface phase, int numComp) Performs a fugacity-based stability check as fallback when EOS derivatives are not available.private voidAnalyzes mechanical stability for a pure component.private voidEstimates the dominant wavelength of spinodal decomposition using the Cahn-Hilliard theory.private doublefindMinEigenvalue(double[][] matrix, int n) Finds the minimum eigenvalue of a symmetric matrix using the Jacobi eigenvalue algorithm.doubleReturns the estimated dominant wavelength of spinodal decomposition.double[][]Returns the Hessian matrix d2A/(dNi*dNj).doubleReturns the minimum eigenvalue of the Hessian matrix.Returns a recommendation for which nucleation model to use.doubleReturns the stability margin.Returns the stability state of the system.Returns the name of the most unstable component pair.booleanReturns whether the analysis has been performed.booleanReturns whether the system is inside the spinodal (thermodynamically unstable).booleanReturns whether the system is metastable (between binodal and spinodal).booleanisStable()Returns whether the system is thermodynamically stable (single phase).voidsetPhaseIndex(int phaseIndex) Sets the phase index to analyze.toJson()Returns a JSON report of all results.toMap()Returns all results as a Map for serialization.toString()
-
Field Details
-
system
The NeqSim thermodynamic system. -
phaseIndex
private int phaseIndexPhase index to analyze (default 0 = first phase). -
stabilityState
Stability state of the system. -
minEigenvalue
private double minEigenvalueMinimum eigenvalue of the Hessian matrix of the Helmholtz free energy. -
hessianMatrix
private double[][] hessianMatrixThe Hessian matrix d2A/(dNi*dNj) — second derivatives of Helmholtz free energy with respect to mole numbers. -
unstableComponentI
private int unstableComponentIThe component pair (i,j) with the most negative Hessian element. -
unstableComponentJ
private int unstableComponentJThe component pair (i,j) with the most negative Hessian element. -
unstableComponentPair
Name of the most unstable component pair. -
dominantWavelength
private double dominantWavelengthEstimated dominant wavelength of spinodal decomposition in m. Only valid when inside the spinodal. -
stabilityMargin
private double stabilityMarginStability margin: positive means stable, negative means unstable. Equal to the minimum eigenvalue of the Hessian. -
analyzed
private boolean analyzedWhether analysis has been performed.
-
-
Constructor Details
-
SpinodalDecompositionDetector
Creates a SpinodalDecompositionDetector for the given thermodynamic system.The system should be initialized (flash + initProperties) before analysis.
- Parameters:
system- the NeqSim thermodynamic system
-
-
Method Details
-
setPhaseIndex
public void setPhaseIndex(int phaseIndex) Sets the phase index to analyze.- Parameters:
phaseIndex- the phase index (0-based)
-
analyze
public void analyze()Performs the spinodal stability analysis.Computes the Hessian matrix of the Helmholtz free energy with respect to mole numbers using the EOS component derivatives (dFdNdN). Then checks the eigenvalues to determine stability.
-
analyzePureComponent
Analyzes mechanical stability for a pure component.For a pure substance, the spinodal is defined by (dP/dV)_T = 0. If the system is at a density where (dP/dV)_T is positive, the phase is mechanically unstable.
- Parameters:
phase- the phase to analyze
-
analyzeFugacityBased
Performs a fugacity-based stability check as fallback when EOS derivatives are not available.This is a simplified check: if the system has two phases and the fugacity coefficients indicate the gas phase is significantly supersaturated relative to the liquid, the system may be inside or near the spinodal.
- Parameters:
phase- the phase to analyzenumComp- number of components
-
findMinEigenvalue
private double findMinEigenvalue(double[][] matrix, int n) Finds the minimum eigenvalue of a symmetric matrix using the Jacobi eigenvalue algorithm.For small matrices (typical for thermodynamic systems with 2-20 components), this is efficient and robust.
- Parameters:
matrix- the symmetric matrixn- matrix dimension- Returns:
- the minimum eigenvalue
-
estimateDominantWavelength
Estimates the dominant wavelength of spinodal decomposition using the Cahn-Hilliard theory.The dominant wavelength is:
$$\lambda_{max} = 2\pi \sqrt{\frac{-2\kappa}{d^2 f / dx^2}}$$
where kappa is the gradient energy coefficient (related to surface tension and interfacial thickness) and d2f/dx2 is the second derivative of the free energy density with respect to composition.
- Parameters:
phase- the phase to analyze
-
isInsideSpinodal
public boolean isInsideSpinodal()Returns whether the system is inside the spinodal (thermodynamically unstable).- Returns:
- true if the system is unstable (spinodal decomposition will occur)
-
isMetastable
public boolean isMetastable()Returns whether the system is metastable (between binodal and spinodal).- Returns:
- true if the system is metastable (classical nucleation applies)
-
isStable
public boolean isStable()Returns whether the system is thermodynamically stable (single phase).- Returns:
- true if the system is stable
-
getStabilityState
Returns the stability state of the system.- Returns:
- the stability state enum
-
getMinEigenvalue
public double getMinEigenvalue()Returns the minimum eigenvalue of the Hessian matrix.Positive = stable, negative = inside spinodal. The magnitude indicates the distance from the spinodal boundary.
- Returns:
- minimum eigenvalue
-
getStabilityMargin
public double getStabilityMargin()Returns the stability margin.Positive = stable (distance from spinodal), negative = unstable (depth inside spinodal).
- Returns:
- stability margin
-
getHessianMatrix
public double[][] getHessianMatrix()Returns the Hessian matrix d2A/(dNi*dNj).- Returns:
- the Hessian matrix
-
getUnstableComponentPair
Returns the name of the most unstable component pair.- Returns:
- component pair string (e.g., "methane / n-heptane")
-
getDominantWavelength
public double getDominantWavelength()Returns the estimated dominant wavelength of spinodal decomposition.This is the characteristic length scale of the concentration fluctuations that grow fastest during spinodal decomposition. Only valid when the system is inside the spinodal.
- Returns:
- dominant wavelength in m
-
isAnalyzed
public boolean isAnalyzed()Returns whether the analysis has been performed.- Returns:
- true if analyzed
-
getRecommendation
Returns a recommendation for which nucleation model to use.- Returns:
- recommendation string
-
toMap
-
toJson
-
toString
-