Skip to content

Sour Water

DWSIM Plus

Available with a DWSIM Plus (Patreon) subscription.

Sour water package (Edwards, Maurer, Newman and Prausnitz) for water with dissolved H2S, NH3, CO2 and HCN, with the ionic speciation and the pH built into the K-values.

DWSIM.Extensions.PropertyPackages.Electrolytes.PropertyPackages.SourWaterPropertyPackage
Assembly DWSIM.Extensions.PropertyPackages.Electrolytes.dll · Object ← PropertyPackage ← ActivityCoefficientPropertyPackage ← SourWaterPropertyPackage
Name in the flowsheet Sour Water · FluentAPI PropertyPackages.Plus.SourWater

Scope

The package describes refinery and gas-plant sour water: water with dissolved hydrogen sulfide, ammonia, carbon dioxide and hydrogen cyanide, as fed to sour water strippers and found in overhead condensates and wash waters. The four solutes are molecular compounds of the flowsheet; the ions they form in the liquid (HS-, S2-, NH4+, HCO3-, CO32-, CN-, H+, OH-) are not compounds: the speciation is computed inside the K-values, and the flash conserves the moles of each compound. The ammonia that binds H2S as NH4+HS- lowers the volatility of both, which is what the example shows.

The model follows Edwards, Maurer, Newman and Prausnitz (1978). Only the molecular form of each solute is volatile, pi = Hi(T) ci γi, with ln γi = βi I (β = -0.324 for H2S, -0.190 for NH3, -0.292 for CO2, -0.160 for HCN, kg/mol). The molecular fraction of each solute comes from its dissociation constants at the solution pH, and the pH from the charge balance of all the ions. The equilibrium constants at 25 °C (Ka1 and Ka2 of H2S, Kb of NH3, Ka1 and Ka2 of CO2, Ka of HCN and Kw) are carried to temperature by van't Hoff, and the Henry constants by H(T) = H25 exp[-C(1/T - 1/298.15)]. Water follows its vapor pressure; other compounds (hydrocarbons, nitrogen) take their vapor pressure or Henry constant.

Stream properties. The liquid pH and ionic strength are those of the speciation. The liquid viscosity and thermal conductivity take the Jones-Dole and Riedel ion corrections, with the ion concentrations of the speciation. Enthalpies are referred to the liquid at 298.15 K: the liquid is the integral of its heat capacity, the vapor the heat of vaporization at 298.15 K plus the ideal-gas heat capacity integral, so the vapor heat capacity stays the ideal-gas value at every temperature. Heats of solution and reaction of the solutes are not included.

Limitations

  • The model finds the compounds by name: Water, Hydrogen sulfide, Ammonia, Carbon dioxide and Hydrogen cyanide. Any subset of them, in any order and with other compounds, is accepted.
  • Concentrations are taken as c = 55.5 xi/xw mol/L (dilute solution).
  • The vapor is ideal unless VaporPhaseFugacityCalculationMode is set to Peng-Robinson.
  • For strong electrolytes (NaCl, caustic) in the water use Electrolyte NRTL or Extended UNIQUAC.

Example

This code runs on every build of this site, and the output below is what it printed.

fs = (Flowsheet.Create("SourWaterExample")
      .WithCompounds("Water", "Hydrogen sulfide", "Ammonia", "Carbon dioxide", "Hydrogen cyanide")
      .WithPropertyPackage(PropertyPackages.Plus.SourWater))

kg_water = 1.0 / 0.018015          # mol of water in 1 kg
# Stripper feed: 0.6 mol/kg NH3 (1.0 wt%) and 0.45 mol/kg H2S (1.5 wt%), at 40 C and 10 bar
feed = (fs.AddMaterialStream("Sour water").At(Q.Celsius(40.0), Q.Bar(10.0))
        .SetCompoundMolarFlow("Water", kg_water)
        .SetCompoundMolarFlow("Ammonia", 0.6)
        .SetCompoundMolarFlow("Hydrogen sulfide", 0.45))
# The same H2S without ammonia
h2s = (fs.AddMaterialStream("H2S water").At(Q.Celsius(40.0), Q.Bar(10.0))
       .SetCompoundMolarFlow("Water", kg_water)
       .SetCompoundMolarFlow("Hydrogen sulfide", 0.45))

fs.Solve()

def partial_pressure(stream, name):
    # equilibrium partial pressure over the liquid: x * phi * P
    liq = stream.Object.Phases[3]
    c = liq.Compounds[name]
    return c.MoleFraction * c.FugacityCoeff * stream.Object.Phases[0].Properties.pressure / 1000.0

liq = feed.Object.Phases[3]
print(f"Vapor fraction                = {feed.Object.Phases[2].Properties.molarfraction or 0.0:.3f}")
print(f"pH                            = {liq.Properties.pH:.2f}")
print(f"H2S partial pressure          = {partial_pressure(feed, 'Hydrogen sulfide'):.1f} kPa")
print(f"NH3 partial pressure          = {partial_pressure(feed, 'Ammonia'):.2f} kPa")
print(f"Without NH3: H2S partial pressure = {partial_pressure(h2s, 'Hydrogen sulfide'):.0f} kPa, "
      f"pH {h2s.Object.Phases[3].Properties.pH:.2f}")

Output

Vapor fraction                = 0.000
pH                            = 8.38
H2S partial pressure          = 14.3 kPa
NH3 partial pressure          = 0.51 kPa
Without NH3: H2S partial pressure = 638 kPa, pH 3.58

DWSIM 10.2.11.0, generated 2026-10-08.

Property methods

How the package calculates each property, as it reports it in PropertyMethodsInfo (the property package editor shows the same list).

Property Method
Vapor fugacity Ideal / Peng-Robinson EOS
Liquid fugacity Edwards Activity Coefficient + Henry's Law / Vapor Pressure
Vapor enthalpy, entropy, Cp/Cv Vaporization Enthalpy at 298.15 K + Ideal Gas Cp (liquid at 298.15 K as the reference)
Liquid enthalpy, entropy, Cp/Cv Liquid Cp integral from 298.15 K (liquid at 298.15 K as the reference)
Vapor density Ideal Gas / Peng-Robinson EOS
Liquid density Experimental Data / Rackett
Vapor viscosity Experimental / Lucas / Jossi-Stiel-Thodos
Liquid viscosity Experimental / Letsou-Stiel
Vapor thermal conductivity Experimental / Ely-Hanley
Liquid thermal conductivity Experimental / Latini
Surface tension Experimental / Brock-Bird
Solid density Experimental Data / User-Defined
Solid enthalpy, entropy, Cp/Cv Experimental Solid Cp / From Liquid Phase Enthalpy + Enthalpy of Fusion

Default flash algorithm: Nested_Loops_VLE.

Configuration saved with the flowsheet

The package writes its settings to the simulation file (SaveData) and reads them back on load (LoadData). The elements below are the ones this package adds to those of every property package, as written for the example.

This package adds no elements of its own.

Settings common to every property package, as saved for the example
Element Value
Type 88 characters
ComponentName Sour Water
ComponentDescription Sour Water model
Tag Sour Water
UseHenryConstants true
AutoEstimateMissingNRTLUNIQUACParameters true
UseImmiscibleListForLiquid2InitialEstimates true
SingleCompoundCheckThreshold 0.99999
OverrideKvalFugCoeff false
OverrideEnthalpyCalculation false
OverrideEntropyCalculation false
LiquidDensityCalculationMode_Subcritical Rackett_and_ExpData
LiquidDensityCalculationMode_Supercritical Rackett_and_ExpData
LiquidDensity_CorrectExpDataForPressure true
LiquidDensity_UsePenelouxVolumeTranslation true
LiquidViscosityCalculationMode_Subcritical ExpData
LiquidViscosityCalculationMode_Supercritical Letsou_Stiel
LiquidViscosity_CorrectExpDataForPressure true
LiquidViscosity_MixingRule MoleAverage
VaporPhaseFugacityCalculationMode Ideal
SolidPhaseFugacityCalculationMethod FromLiquidFugacity
SolidPhaseFugacity_UseIdealLiquidPhaseFugacity false
SolidPhaseEnthalpy_UsesCp false
EnthalpyEntropyCpCvCalculationMode ExpData
LiquidEnthalpyEntropyCpCvCalculationMode_EOS EOS
LiquidFugacity_UsePoyntingCorrectionFactor true
ActivityCoefficientModels_IgnoreMissingInteractionParameters false
IgnoreVaporFractionLimit false
IgnoreSalinityLimit false
CalculateAdditionalMaterialStreamProperties true
FlashCalculationApproach NestedLoops
DisplayMissingCompoundPropertiesWarning false
ForcedSolids []
PropertyOverrides {}
FlashSettings 36 Setting entries

Learn more

API members

Public members declared by this class. Inherited members are documented on the base classes.

Constructors

SourWaterPropertyPackage()
public SourWaterPropertyPackage()
Public Sub New()

SourWaterPropertyPackage(bool)
Parameter Type Description
comode Boolean
public SourWaterPropertyPackage(bool comode)
Public Sub New(comode As Boolean)

Properties

FlashBase: Returns the FlashAlgorithm object instance for this property package.

Returns the FlashAlgorithm object instance for this property package.

public override FlashAlgorithm FlashBase { get; }
Public Overrides ReadOnly Property FlashBase As FlashAlgorithm

ImplementsAnalyticalDerivatives: Advertises analytical derivatives (activating the NestedLoops PV/TV flash branch and the column-solver analytical...

Advertises analytical derivatives (activating the NestedLoops PV/TV flash branch and the column-solver analytical Jacobian) only for models with a closed-form GAMMA_DERIVS, and only when the runtime kill-switch is not set.

public override bool ImplementsAnalyticalDerivatives { get; }
Public Overrides ReadOnly Property ImplementsAnalyticalDerivatives As Boolean

ShouldUseKvalueMethod3
public override bool ShouldUseKvalueMethod3 { get; }
Public Overrides ReadOnly Property ShouldUseKvalueMethod3 As Boolean

Methods

CheckMissingInteractionParameters(double[])
Parameter Type Description
Vx Double[]
public override bool CheckMissingInteractionParameters(double[] Vx)
Public Overrides Function CheckMissingInteractionParameters(Vx As Double()) As Boolean

Clone()
public override PropertyPackage Clone()
Public Overrides Function Clone() As PropertyPackage

DW_CalcdKdComposition(double[], double[], double, double, State, string): Composition (mole-number) derivative of the equilibrium K-values, d(K_i)/dn_j, with respect to the mole numbers of...

Composition (mole-number) derivative of the equilibrium K-values, d(K_i)/dn_j, with respect to the mole numbers of the phase indicated by withRespectTo (State.Liquid perturbs Vx, State.Vapor perturbs Vy), on a total-moles = 1 basis. Returns an (nc x nc) matrix. Base implementation is a finite difference; EOS/activity packages override it using the analytical d(ln phi)/dn (or d(ln gamma)/dx) building blocks.

Parameter Type Description
Vx Double[]
Vy Double[]
T Double
P Double
withRespectTo State
type String
public override double[,] DW_CalcdKdComposition(double[] Vx, double[] Vy, double T, double P, State withRespectTo, string type = "LV")
Public Overrides Function DW_CalcdKdComposition(Vx As Double(), Vy As Double(), T As Double, P As Double, withRespectTo As State, type As String = "LV") As Double(,)

DW_CalcdKdT(double[], double[], double, double, string): Analytical temperature derivative of the K-values for the activity-model packages, assembled from the liquid/vapour...

Analytical temperature derivative of the K-values for the activity-model packages, assembled from the liquid/vapour d(ln phi)/dT above: dK_i/dT = K_i * (d ln phi_i^L/dT - d ln phi_i^V/dT). This is what the analytical branch of the NestedLoops PV/TV flashes consumes. Falls back to finite differences for non-standard (non-"LV") requests or near-critical mixtures.

Parameter Type Description
Vx Double[]
Vy Double[]
T Double
P Double
type String
public override double[] DW_CalcdKdT(double[] Vx, double[] Vy, double T, double P, string type = "LV")
Public Overrides Function DW_CalcdKdT(Vx As Double(), Vy As Double(), T As Double, P As Double, type As String = "LV") As Double()

DW_CalcEnthalpy(Array, double, double, State): Calculates the enthalpy of a mixture.

Calculates the enthalpy of a mixture.

Parameter Type Description
Vx Array Vector of doubles containing the molar composition of the mixture.
T Double Temperature (K)
P Double Pressure (Pa)
st State State enum indicating the state of the mixture (liquid or vapor).
public override double DW_CalcEnthalpy(Array Vx, double T, double P, State st)
Public Overrides Function DW_CalcEnthalpy(Vx As Array, T As Double, P As Double, st As State) As Double

DW_CalcEntropy(Array, double, double, State): Calculates the entropy of a mixture.

Calculates the entropy of a mixture.

Parameter Type Description
Vx Array Vector of doubles containing the molar composition of the mixture.
T Double Temperature (K)
P Double Pressure (Pa)
st State State enum indicating the state of the mixture (liquid or vapor).
public override double DW_CalcEntropy(Array Vx, double T, double P, State st)
Public Overrides Function DW_CalcEntropy(Vx As Array, T As Double, P As Double, st As State) As Double

DW_CalcFugCoeff(Array, double, double, State): Calculates fugacity coefficients for the specified composition at the specified conditions.

Calculates fugacity coefficients for the specified composition at the specified conditions.

Parameter Type Description
Vx Array Vector of doubles containing the molar composition of the mixture.
T Double Temperature in K
P Double Pressure in Pa
st State Mixture state (Liquid or Vapor)
public override double[] DW_CalcFugCoeff(Array Vx, double T, double P, State st)
Public Overrides Function DW_CalcFugCoeff(Vx As Array, T As Double, P As Double, st As State) As Double()

DW_CalcKvalue3(double[], double[], double, double): Calculates K-values using the Edwards sour water model for H2S, CO2, NH3, and HCN.

Calculates K-values using the Edwards sour water model for H2S, CO2, NH3, and HCN. For other compounds, falls back to standard fugacity coefficient K-values.

Parameter Type Description
Vnx Double[] Molar flows of the liquid phase
Vny Double[] Molar flows of the vapor phase
T Double Temperature in K
P Double Pressure in Pa
public override double[] DW_CalcKvalue3(double[] Vnx, double[] Vny, double T, double P)
Public Overrides Function DW_CalcKvalue3(Vnx As Double(), Vny As Double(), T As Double, P As Double) As Double()

DW_CalcPhaseProps(Phase)
Parameter Type Description
Phase Phase
public override void DW_CalcPhaseProps(Phase Phase)
Public Overrides Sub DW_CalcPhaseProps(Phase As Phase)

GetArguments()
public override object GetArguments()
Public Overrides Function GetArguments() As Object

LoadData(List<XElement>): Loads the saved package data.

Loads the saved package data. The liquid density default is the compounds' experimental liquid density data (water within 0.1 % of IAPWS-95 from 0 to 100 C), where COSTALD put water at 1007 kg/m3 at 25 C. A file that does not record a liquid density mode keeps COSTALD, the mode it was solved with.

Parameter Type Description
data List<XElement>
public override bool LoadData(List<XElement> data)
Public Overrides Function LoadData(data As List(Of XElement)) As Boolean

ReturnInstance(string)
Parameter Type Description
typename String
public override object ReturnInstance(string typename)
Public Overrides Function ReturnInstance(typename As String) As Object

RunPostMaterialStreamSetRoutine()
public override void RunPostMaterialStreamSetRoutine()
Public Overrides Sub RunPostMaterialStreamSetRoutine()

SaveData()
public override List<XElement> SaveData()
Public Overrides Function SaveData() As List(Of XElement)