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 dioxideandHydrogen 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
VaporPhaseFugacityCalculationModeis 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(bool)
| Parameter | Type | Description |
|---|---|---|
comode |
Boolean |
Properties¶
FlashBase: Returns the FlashAlgorithm object instance for this property package.
Returns the FlashAlgorithm object instance for this property package.
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.
ShouldUseKvalueMethod3
Methods¶
CheckMissingInteractionParameters(double[])
| Parameter | Type | Description |
|---|---|---|
Vx |
Double[] |
Clone()
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 |
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 |
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). |
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). |
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) |
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 |
DW_CalcPhaseProps(Phase)
| Parameter | Type | Description |
|---|---|---|
Phase |
Phase |
GetArguments()
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> |
ReturnInstance(string)
| Parameter | Type | Description |
|---|---|---|
typename |
String |
RunPostMaterialStreamSetRoutine()