Class PhaseSrkCPABroydenImplicit
- All Implemented Interfaces:
Serializable, Cloneable, PhaseCPAInterface, PhaseEosInterface, PhaseInterface, ThermodynamicConstantsInterface
Improves on the fully implicit coupled Newton-Raphson approach of Igben et al. (2026) by using Broyden's rank-1 update of the inverse Jacobian after the first full Newton step. This reduces the per-iteration cost from O(n_s^3) (Gaussian elimination) to O(n_s^2) (rank-1 update via the Sherman-Morrison formula), while maintaining superlinear convergence.
Algorithm:
- Iteration 1: Compute full analytic Jacobian J, invert to get H = J^{-1}, solve delta_x = -H * R
- Iterations 2+: Update H via Broyden's "good" formula: H_{k+1} = H_k + (dx - H_k*df) * (dx^T * H_k) / (dx^T * H_k * df)
- Periodic refresh: Recompute full Jacobian when convergence stalls (||R_new||/||R_old|| > 0.5 for 2 consecutive steps)
References:
- C.G. Broyden, A class of methods for solving nonlinear simultaneous equations, Math. Comput. 19 (1965) 577-593.
- O.N. Igben et al., Fully implicit algorithm for CPA EOS, Fluid Phase Equilib. 608 (2026) 114734.
- Version:
- 1.0
- Author:
- Even Solbraa
- See Also:
-
Field Summary
FieldsModifier and TypeFieldDescriptionprivate static final doubleResidual threshold below which Broyden updates are allowed.private static longTotal Broyden updates (quasi-Newton steps).private static longTotal molarVolume calls.private static final doubleConvergence tolerance for the coupled system.private static longTotal fallbacks to nested solver.private static longTotal Jacobian evaluations (full Newton steps).private static final org.apache.logging.log4j.LoggerLogger object for class.private static final intMaximum iterations for the coupled solver.private static final doubleMaximum relative step size per iteration.private static final intMinimum iterations before allowing Broyden updates.private static final doubleRestart threshold parameter alpha.private static final longSerialization version UID.private static final doubleStall detection: refresh Jacobian if ratio exceeds this for consecutive steps.private static longTotal iterations across all calls.private double[][]private double[][]private double[]private double[]private double[]private intprivate double[]Fields inherited from class PhaseSrkCPA
activeAccosComp, assSiteNumber, cpamix, cpaon, cpaSelect, crossAccociationScheme, delta, deltaNog, dFCPAdT, dFCPAdTdT, dFCPAdTdV, dFCPAdV, dFCPAdVdV, dFCPAdVdVdV, dFdNtemp, FCPA, gcpa, gcpav, gcpavv, gcpavvv, hcpatot, Klkni, moleculeNumber, oldTotalNumberOfAccociationSites, selfAccociationScheme, totalNumberOfAccociationSitesFields inherited from class Phase
beta, calcMolarVolume, chemSyst, componentArray, diElectricConstant, mixingRuleType, molarVolume, numberOfComponents, numberOfMolesInPhase, phaseVolume, physicalPropertyHandler, pressure, pt, refPhase, temperature, thermoPropertyModelName, useVolumeCorrection, ZFields inherited from interface ThermodynamicConstantsInterface
atm, avagadroNumber, boltzmannConstant, electronCharge, faradayConstant, gravity, molarMassAir, normalStateTemperature, pi, planckConstant, R, referencePressure, referenceTemperature, standardStateTemperature, vacumPermittivity -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionvoidaddComponent(String name, double moles, double molesInPhase, int compNumber) Add component to component array and update moles variables.private static voidbroydenUpdate(double[][] invJ, double[] dxVec, double[] dfVec, int n) Broyden's "good" rank-1 update of the inverse Jacobian H.private voidbuildJacobian(double[][] jac, double[] xSite, double[] siteMoles, double totalVol, double gdv1, double zeta, double btemp, int dim, int ns) Build the analytic Jacobian for the coupled (n_s+1)-dimensional system.clone()clone.private voidensureWorkArrays(int ns) Ensure work arrays are allocated for the given association site count.static StringGet profiling summary string.voidinitCPAMatrix(int type) initCPAMatrix.private static booleaninvertMatrix(double[][] a, double[][] ainv, int n) Invert matrix A into Ainv using Gauss-Jordan elimination with partial pivoting.doublemolarVolume(double pressure, double temperature, double A, double B, PhaseType pt) molarVolume.doublemolarVolumeChangePhase(double pressure, double temperature, double A, double B, PhaseType pt) molarVolumeChangePhase.private voidreadXsiteFromComponents(double[] xSite) Read XA site fractions from component objects into flat array.static voidReset profiling counters.private voidsetXsiteOnComponents(double[] xSite) Set XA site fractions from flat array onto component objects.private static booleansolveLinearSystem(double[][] a, double[] b, int n) Solve a linear system Ax = b in-place using Gaussian elimination with partial pivoting.private voidUpdate delta = deltaNog * g.Methods inherited from class PhaseSrkCPAs
calc_g, calc_lngV, calc_lngVV, calc_lngVVVMethods inherited from class PhaseSrkCPA
calcDelta, calcdFdNtemp, calcPressure, calcRootVolFinder, calcXsitedV, croeneckerProduct, dFCPAdT, dFCPAdTdT, dFCPAdTdV, dFCPAdV, dFCPAdVdV, dFCPAdVdVdV, dFdT, dFdTdT, dFdTdV, dFdV, dFdVdV, dFdVdVdV, FCPA, getCpaMixingRule, getCrossAssosiationScheme, getdFdNtemp, getF, getGcpa, getGcpav, getHcpatot, getTotalNumberOfAccociationSites, init, initCPAMatrixOld, initOld2, molarVolume2, molarVolumeOld, setGcpav, setHcpatot, setMixingRule, setTotalNumberOfAccociationSites, solveX, solveX2, solveX2Old, solveXOldMethods inherited from class PhaseEos
calcA, calcAi, calcAij, calcAiT, calcAT, calcATT, calcB, calcBi, calcBij, calcf, calcg, calcPressuredV, dFdN, dFdNdN, dFdNdT, dFdNdV, dFdxdxMatrix, dFdxdxMatrixSimple, dFdxMatrix, dFdxMatrixSimple, displayInteractionCoefficients, equals, F, fb, FB, fBB, FBB, FBD, FBT, fBV, FBV, FD, FDT, FDV, Fn, FnB, FnV, FT, FTT, FTV, fv, FV, fVV, FVV, fVVV, FVVV, gb, gBB, gBV, geta, geta, getA, getAresTV, getAT, getATT, getb, getb, getB, getCpres, getCvres, getdPdrho, getdPdTVn, getdPdVTn, getdrhodN, getdrhodP, getdrhodT, getdTVndSVnJaobiMatrix, getdUdSdSVn, getdUdSdVn, getdUdSVn, getdUdVdVSn, getdUdVSn, getdVdrho, getEosMixingRule, getf_loc, getg, getGradientVector, getGresTP, getHresdP, getHresTP, getJouleThomsonCoefficient, getKappa, getMixingRule, getMixingRuleName, getPressureAttractive, getPressureRepulsive, getSoundSpeed, getSresTP, getSresTV, getUSVHessianMatrix, gV, gVV, gVVV, resetMixingRule, setMixingRuleGEModelMethods inherited from class Phase
addComponent, addMoles, addMolesChemReac, calcA, calcAT, calcDiElectricConstant, calcDiElectricConstantdT, calcDiElectricConstantdTdT, calcMolarVolume, calcR, getActivityCoefficient, getActivityCoefficient, getActivityCoefficient, getActivityCoefficientSymetric, getActivityCoefficientUnSymetric, getAiT, getAlpha0_EOSCG, getAlpha0_GERG2008, getAlpha0_Leachman, getAlpha0_Leachman, getAlpha0_Vega, getAlphares_EOSCG, getAlphares_GERG2008, getAlphares_Leachman, getAlphares_Leachman, getAlphares_Vega, getAntoineVaporPressure, getBeta, getBi, getComponent, getComponent, getcomponentArray, getComponentNames, getComponents, getComponentWithIndex, getComposition, getCompressibilityX, getCompressibilityY, getCorrectedVolume, getCp, getCp, getCp0, getCv, getCv, getDensity, getDensity, getDensity_AGA8, getDensity_EOSCG, getDensity_GERG2008, getDensity_Leachman, getDensity_Leachman, getDensity_Vega, getDielectricConstant, getEnthalpy, getEnthalpy, getEnthalpydP, getEnthalpydT, getEntropy, getEntropy, getEntropydP, getEntropydT, getExcessGibbsEnergy, getExcessGibbsEnergySymetric, getFlowRate, getFugacity, getFugacity, getGamma, getGibbsEnergy, getHelmholtzEnergy, getHID, getInfiniteDiluteFugacity, getInfiniteDiluteFugacity, getInitType, getInternalEnergy, getInternalEnergy, getIsobaricThermalExpansivity, getIsothermalCompressibility, getJouleThomsonCoefficient, getLogActivityCoefficient, getLogInfiniteDiluteFugacity, getLogInfiniteDiluteFugacity, getLogPureComponentFugacity, getLogPureComponentFugacity, getMass, getMeanIonicActivity, getMixGibbsEnergy, getMixingRuleType, getModelName, getMolalMeanIonicActivity, getMolarComposition, getMolarMass, getMolarMass, getMolarVolume, getMolarVolume, getMoleFraction, getNumberOfComponents, getNumberOfIonicComponents, getNumberOfMolecularComponents, getNumberOfMolesInPhase, getOsmoticCoefficient, getOsmoticCoefficientOfWater, getOsmoticCoefficientOfWaterMolality, getpH, getpH, getPhase, getPhysicalProperties, getPhysicalPropertyModel, getPressure, getPressure, getProperties_EOSCG, getProperties_GERG2008, getProperties_Leachman, getProperties_Leachman, getProperties_Vega, getPseudoCriticalPressure, getPseudoCriticalTemperature, getPureComponentFugacity, getPureComponentFugacity, getRefPhase, getRefPhase, getSoundSpeed, getTemperature, getTemperature, getThermalConductivity, getThermalConductivity, getThermoPropertyModelName, getTotalVolume, getType, getViscosity, getViscosity, getVolume, getVolume, getWaterDensity, getWtFrac, getWtFrac, getWtFraction, getWtFractionOfWaxFormingComponents, getZ, getZvolcorr, groupTBPfractions, hasComponent, hasPlusFraction, hasTBPFraction, initPhysicalProperties, initPhysicalProperties, initRefPhases, initRefPhases, isConstantPhaseVolume, isMixingRuleDefined, normalize, removeComponent, resetPhysicalProperties, setAttractiveTerm, setBeta, setComponentArray, setConstantPhaseVolume, setEmptyFluid, setInitType, setMolarVolume, setMoleFractions, setNumberOfComponents, setParams, setPhysicalProperties, setPhysicalPropertyModel, setPpm, setPressure, setProperties, setRefPhase, setRefPhase, setTemperature, setTotalVolume, setType, useVolumeCorrection, useVolumeCorrectionMethods inherited from class Object
finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, waitMethods inherited from interface PhaseCPAInterface
calc_hCPAMethods inherited from interface PhaseEosInterface
calcPressuredV, dFdN, dFdNdN, dFdNdT, dFdNdV, displayInteractionCoefficients, F, getAresTV, getEosMixingRule, getMixingRuleName, getMolarVolume, getPressureAttractive, getPressureRepulsive, getSresTVMethods inherited from interface PhaseInterface
addMoles, addMolesChemReac, addMolesChemReac, calcA, calcAi, calcAij, calcAiT, calcAT, calcB, calcBi, calcBij, calcMolarVolume, calcR, fb, FB, fBB, FBB, FBD, FBT, fBV, FBV, FD, FDT, FDV, Fn, FnB, FnV, FT, FTT, FTV, fv, FV, fVV, FVV, gb, gBB, gBV, geta, getA, getActivityCoefficient, getActivityCoefficient, getActivityCoefficient, getActivityCoefficientSymetric, getActivityCoefficientUnSymetric, getAlpha0_EOSCG, getAlpha0_GERG2008, getAlpha0_Leachman, getAlpha0_Leachman, getAlpha0_Vega, getAlphares_EOSCG, getAlphares_GERG2008, getAlphares_Leachman, getAlphares_Leachman, getAlphares_Vega, getAntoineVaporPressure, getAT, getATT, getb, getB, getBeta, getComponent, getComponent, getcomponentArray, getComponentNames, getComponents, getComponentWithIndex, getComposition, getCompressibilityX, getCompressibilityY, getCorrectedVolume, getCp, getCp, getCp0, getCpres, getCv, getCv, getDensity, getDensity, getDensity_AGA8, getDensity_EOSCG, getDensity_GERG2008, getDensity_Leachman, getDensity_Leachman, getDensity_Vega, getdPdrho, getdPdTVn, getdPdVTn, getdrhodN, getdrhodP, getdrhodT, getEnthalpy, getEnthalpy, getEnthalpydP, getEnthalpydT, getEntropy, getEntropy, getEntropydP, getEntropydT, getExcessGibbsEnergy, getExcessGibbsEnergySymetric, getFlowRate, getFugacity, getFugacity, getg, getGamma, getGamma2, getGibbsEnergy, getGresTP, getHelmholtzEnergy, getHresTP, getInfiniteDiluteFugacity, getInitType, getInternalEnergy, getInternalEnergy, getIsobaricThermalExpansivity, getIsothermalCompressibility, getJouleThomsonCoefficient, getJouleThomsonCoefficient, getKappa, getLogActivityCoefficient, getLogInfiniteDiluteFugacity, getLogInfiniteDiluteFugacity, getLogPureComponentFugacity, getMass, getMeanIonicActivity, getMixGibbsEnergy, getMixingRule, getMixingRuleType, getModelName, getMolalMeanIonicActivity, getMolarComposition, getMolarMass, getMolarMass, getMolarVolume, getMoleFraction, getNumberOfComponents, getNumberOfIonicComponents, getNumberOfMolecularComponents, getNumberOfMolesInPhase, getOsmoticCoefficient, getOsmoticCoefficientOfWater, getOsmoticCoefficientOfWaterMolality, getpH, getpH, getPhase, getPhaseFraction, getPhaseTypeName, getPhysicalProperties, getPhysicalPropertyModel, getPressure, getPressure, getProperties_EOSCG, getProperties_GERG2008, getProperties_Leachman, getProperties_Leachman, getProperties_Vega, getPseudoCriticalPressure, getPseudoCriticalTemperature, getPureComponentFugacity, getPureComponentFugacity, getRefPhase, getRefPhase, getSoundSpeed, getSoundSpeed, getSresTP, getTemperature, getTemperature, getThermalConductivity, getThermalConductivity, getTotalVolume, getType, getViscosity, getViscosity, getVolume, getVolume, getWaterDensity, getWtFrac, getWtFrac, getWtFraction, getWtFractionOfWaxFormingComponents, getZ, getZvolcorr, gV, gVV, hasComponent, hasComponent, hasIons, hasPlusFraction, hasTBPFraction, init, init, initPhysicalProperties, initPhysicalProperties, initPhysicalProperties, initRefPhases, isAsphalteneRich, isConstantPhaseVolume, isMixingRuleDefined, normalize, removeComponent, resetMixingRule, resetPhysicalProperties, setAttractiveTerm, setBeta, setComponentArray, setConstantPhaseVolume, setEmptyFluid, setInitType, setMixingRule, setMixingRuleGEModel, setMolarVolume, setMoleFractions, setNumberOfComponents, setParams, setPhaseTypeName, setPhysicalProperties, setPhysicalProperties, setPhysicalPropertyModel, setPpm, setPressure, setProperties, setRefPhase, setRefPhase, setTemperature, setTotalVolume, setType, useVolumeCorrection, useVolumeCorrection
-
Field Details
-
serialVersionUID
private static final long serialVersionUIDSerialization version UID.- See Also:
-
logger
private static final org.apache.logging.log4j.Logger loggerLogger object for class. -
MAX_ITERATIONS
private static final int MAX_ITERATIONSMaximum iterations for the coupled solver.- See Also:
-
CONVERGENCE_TOL
private static final double CONVERGENCE_TOLConvergence tolerance for the coupled system.- See Also:
-
MAX_REL_STEP
private static final double MAX_REL_STEPMaximum relative step size per iteration.- See Also:
-
RESTART_ALPHA
private static final double RESTART_ALPHARestart threshold parameter alpha.- See Also:
-
MIN_NEWTON_STEPS
private static final int MIN_NEWTON_STEPSMinimum iterations before allowing Broyden updates.- See Also:
-
BROYDEN_SWITCH_TOL
private static final double BROYDEN_SWITCH_TOLResidual threshold below which Broyden updates are allowed.- See Also:
-
STALL_RATIO
private static final double STALL_RATIOStall detection: refresh Jacobian if ratio exceeds this for consecutive steps.- See Also:
-
callCount
private static volatile long callCountTotal molarVolume calls. -
totalIters
private static volatile long totalItersTotal iterations across all calls. -
jacobianEvals
private static volatile long jacobianEvalsTotal Jacobian evaluations (full Newton steps). -
broydenUpdates
private static volatile long broydenUpdatesTotal Broyden updates (quasi-Newton steps). -
fallbackCount
private static volatile long fallbackCountTotal fallbacks to nested solver. -
workKlk
private transient double[][] workKlk -
workHess
private transient double[][] workHess -
workKsi
private transient double[] workKsi -
workM
private transient double[] workM -
workKlkKsi
private transient double[] workKlkKsi -
workXV
private transient double[] workXV -
workNs
private transient int workNs
-
-
Constructor Details
-
PhaseSrkCPABroydenImplicit
public PhaseSrkCPABroydenImplicit()Constructor for PhaseSrkCPABroydenImplicit.
-
-
Method Details
-
resetProfileCounters
public static void resetProfileCounters()Reset profiling counters. -
getProfileSummary
Get profiling summary string.- Returns:
- a summary of profiling data
-
clone
clone.
- Specified by:
clonein interfacePhaseInterface- Overrides:
clonein classPhaseSrkCPAs- Returns:
- a
PhaseInterfaceobject
-
addComponent
Add component to component array and update moles variables.
- Specified by:
addComponentin interfacePhaseInterface- Overrides:
addComponentin classPhaseSrkCPAs- Parameters:
name- Name of component.moles- Total number of moles of component.molesInPhase- Number of moles in phase.compNumber- Index number of component in phase object component array.
-
molarVolume
public double molarVolume(double pressure, double temperature, double A, double B, PhaseType pt) throws IsNaNException, TooManyIterationsException molarVolume.
Broyden quasi-Newton implicit molar volume calculation. Uses the coupled (n_s+1)-dimensional system but replaces full Jacobian evaluation with Broyden rank-1 updates after the first Newton step. The inverse Jacobian H is maintained directly and updated via the Sherman-Morrison formula.
- Specified by:
molarVolumein interfacePhaseInterface- Overrides:
molarVolumein classPhaseSrkCPA- Parameters:
pressure- a doubletemperature- a doubleA- a doubleB- a doublept- the PhaseType of the phase- Returns:
- a double
- Throws:
IsNaNException- if any.TooManyIterationsException- if any.
-
buildJacobian
private void buildJacobian(double[][] jac, double[] xSite, double[] siteMoles, double totalVol, double gdv1, double zeta, double btemp, int dim, int ns) Build the analytic Jacobian for the coupled (n_s+1)-dimensional system.- Parameters:
jac- the Jacobian matrix to populate (dim x dim)xSite- site fraction valuessiteMoles- moles per sitetotalVol- total volume Vgdv1- g'(V) - 1/Vzeta- current B/(nV)btemp- co-volume Bdim- system dimension (ns+1)ns- number of association sites
-
invertMatrix
private static boolean invertMatrix(double[][] a, double[][] ainv, int n) Invert matrix A into Ainv using Gauss-Jordan elimination with partial pivoting.- Parameters:
a- input matrix (will be modified)ainv- output inverse matrixn- matrix dimension- Returns:
- true if successful, false if singular
-
broydenUpdate
private static void broydenUpdate(double[][] invJ, double[] dxVec, double[] dfVec, int n) Broyden's "good" rank-1 update of the inverse Jacobian H.Updates H in-place using: H_new = H + (dx - H*df) * (dx^T * H) / (dx^T * H * df)
This is the Sherman-Morrison formula applied to the secant condition. Cost: O(n^2).
- Parameters:
invJ- inverse Jacobian matrix H (updated in-place)dxVec- step vector: x_{k+1} - x_kdfVec- residual change vector: R(x_{k+1}) - R(x_k)n- system dimension
-
updateDeltaWithG
private void updateDeltaWithG()Update delta = deltaNog * g. -
setXsiteOnComponents
private void setXsiteOnComponents(double[] xSite) Set XA site fractions from flat array onto component objects.- Parameters:
xSite- array of site fractions
-
readXsiteFromComponents
private void readXsiteFromComponents(double[] xSite) Read XA site fractions from component objects into flat array.- Parameters:
xSite- array to fill
-
ensureWorkArrays
private void ensureWorkArrays(int ns) Ensure work arrays are allocated for the given association site count.- Parameters:
ns- number of association sites
-
initCPAMatrix
public void initCPAMatrix(int type) initCPAMatrix.
Override CPA matrix initialization for efficient volume derivative computation.
- Overrides:
initCPAMatrixin classPhaseSrkCPA- Parameters:
type- 1 for volume derivatives, 2+ for temperature/composition
-
molarVolumeChangePhase
public double molarVolumeChangePhase(double pressure, double temperature, double A, double B, PhaseType pt) throws IsNaNException, TooManyIterationsException molarVolumeChangePhase.
- Overrides:
molarVolumeChangePhasein classPhaseSrkCPA- Parameters:
pressure- a doubletemperature- a doubleA- a doubleB- a doublept- the PhaseType of the phase- Returns:
- a double
- Throws:
IsNaNException- if any.TooManyIterationsException- if any.
-
solveLinearSystem
private static boolean solveLinearSystem(double[][] a, double[] b, int n) Solve a linear system Ax = b in-place using Gaussian elimination with partial pivoting.- Parameters:
a- coefficient matrix (modified in place)b- right-hand side (solution on return)n- system dimension- Returns:
- true if solve succeeded
-