Electrolyte NRTL¶
DWSIM Plus
Available with a DWSIM Plus (Patreon) subscription.
Electrolyte NRTL (Chen and Evans) activity-coefficient package for aqueous electrolyte solutions, with the speciation solved by a chemical-equilibrium solver over the equilibrium reactions of the flowsheet.
DWSIM.Extensions.PropertyPackages.Electrolytes.PropertyPackages.ElectrolyteNRTLPropertyPackage
Assembly DWSIM.Extensions.PropertyPackages.Electrolytes.dll · Object ← PropertyPackage ← ElectrolyteBasePropertyPackage ← BaseElectrolytePropertyPackage ← ElectrolyteNRTLPropertyPackage
Name in the flowsheet Electrolyte NRTL (Aqueous Electrolytes) · FluentAPI PropertyPackages.Plus.ElectrolyteNRTL
Scope¶
The package describes aqueous electrolyte solutions: brines and process waters, cooling-water and
corrosion chemistry, salt crystallization, and acid-gas waters where the dissociation reactions are part
of the flowsheet. Water is the only solvent. Ions are compounds of their own (Sodium (ion),
Chloride (ion), Hydron, Hydroxide, ...) from the electrolyte compound database, and a salt that can
precipitate is a compound as well (Sodium Chloride). The same compounds and the same speciation are
used by the Extended UNIQUAC package; the two differ in the activity model.
The activity coefficients follow Chen and Evans: a long-range Pitzer-Debye-Hückel term for the electrostatic forces between ions and a short-range NRTL local-composition term, with local electroneutrality and like-ion repulsion. Ions take the unsymmetric (infinite dilution) reference and water the symmetric one; the stream reports the ion activity coefficients on the molality scale. The mean ionic activity coefficient is ln γ± = (ν+ ln γc + ν- ln γa)/(ν+ + ν-).
Speciation. A flash solves the chemical equilibrium of the liquid together with the phase split: the
equilibrium reactions of the flowsheet (water self-ionization, acid and base dissociations, ion pairs,
salt dissolution), Henry's law for the dissolved gases and Raoult's law for water. Without reactions the
ions stay as fed. The option GenerateSolubilityReactions adds a dissolution equilibrium for every salt
in the compound list that no reaction covers, with K from the Gibbs energies of formation of the salt and
its ions. The pH is the one of the speciation, -log10 of the hydrogen ion activity.
Parameters. Each salt carries two water-electrolyte parameters, τw,ca and
τca,w, with the temperature dependence τ(T) = Δg + Δh (1/T - 1/Tref)
+ Δcp ((Tref - T)/T + ln(T/Tref)), Tref = 298.15 K. The
shipped enrtl_parameters.json holds 137 pairs: 45 from the Chen and Evans fit (NaCl, KCl, LiCl, HCl, NaBr,
KBr, NaI, NaOH, KOH, NaNO3, KNO3, NH4Cl, Na2SO4,
K2SO4, CaCl2, MgCl2, BaCl2, MgSO4,
CaSO4, H2SO4 and other 1-1, 1-2, 2-1 and 3-1 salts) and 92 fitted to the
Kim and Frederick single-salt Pitzer parameters (transition-metal halides, perchlorates, nitrates,
sulfates). The scalar parameters are α = 0.2, the dielectric constant 78.54 and density 997 kg/m3
of water at 25 °C, and the closest-approach parameter ρ = 14.9. A salt without a τ pair gets
τ = 0, so only the long-range term acts on it; when the companion pitzer_parameters.json (107 salts)
has the salt, the package writes its Pitzer parameters to the log. Parameters can be edited or replaced
in the package editor.
Transport properties. The liquid viscosity is the viscosity of the ion-free solvent (water and the molecular solutes) times the Jones-Dole correction, 1 + A√I + Σ Bici + D c2, with ion B-coefficients from Marcus and Jenkins and c the salt concentration; the thermal conductivity is that of the ion-free solvent times the Riedel ion-additive correction 1 - Σ αici. At 25 °C, 1 mol/kg NaCl gives 0.979 mPa·s (0.974 measured) and 0.604 W/(m·K).
Colligative properties. The osmotic coefficient and the freezing point come from the water activity of the package's own model, aw = xwγw; the freezing point depression is ΔT = -R Tf2/ΔHfus ln aw. For 1 mol/kg NaCl the osmotic coefficient is 0.933 (0.936 in Robinson and Stokes) and the freezing point -3.48 °C.
Accuracy. For the Chen and Evans salts the package reproduces the published correlations; for the Kim and Frederick salts the fit to the Robinson and Stokes data has χ2 < 10-2 from 5 to 95 % of the saturation molality, with the largest deviations at high molality for strongly ion-paired salts (FeCl3, ZnBr2, ZnI2).
Limitations¶
- Recommended for 0 to 200 °C, ionic strength up to 6 mol/kg for the fitted salts, and 1 to 500 bar (no pressure parameters).
- Water is the only solvent: other neutral compounds (dissolved gases, amines, alcohols) take part as solutes with no interaction parameters (τ = 0).
- The vapor is ideal unless
VaporPhaseFugacityCalculationModeis set to Peng-Robinson, which is advisable above about 30 bar or for a vapor rich in CO2, N2 or methane. - The pH comes from the activity of the hydrogen ion,
Hydron(H+) orHydronium(H3O+).
Example¶
This code runs on every build of this site, and the output below is what it printed.
fs = (Flowsheet.Create("ENRTLExample")
.WithCompounds("Water", "Sodium (ion)", "Chloride (ion)", "Hydron", "Hydroxide")
.WithPropertyPackage(PropertyPackages.Plus.ElectrolyteNRTL))
# The package takes its chemical equilibria from the reactions of the flowsheet. The
# self-ionization of water sets the pH: log10 Kw = -4470.99/T + 6.0875 - 0.01706 T
kw = Dictionary[String, Double]()
kw["Water"] = -1.0
kw["Hydron"] = 1.0
kw["Hydroxide"] = 1.0
fs.ReactionSet("Water").Add(fs.DefineEquilibriumReaction(
"Kw", kw, "Water", "Liquid", "Activity", "", "2.302585*(-4470.99/T + 6.0875 - 0.01706*T)"))
# 1 mol of NaCl (as its ions) per kg of water, and 0.01 mol of HCl per kg of water
brine = (fs.AddMaterialStream("Brine").At(Q.Celsius(25.0), Q.Bar(1.01325))
.SetCompoundMolarFlow("Water", 1.0 / 0.018015)
.SetCompoundMolarFlow("Sodium (ion)", 1.0)
.SetCompoundMolarFlow("Chloride (ion)", 1.0))
acid = (fs.AddMaterialStream("Acid").At(Q.Celsius(25.0), Q.Bar(1.01325))
.SetCompoundMolarFlow("Water", 1.0 / 0.018015)
.SetCompoundMolarFlow("Hydron", 0.01)
.SetCompoundMolarFlow("Chloride (ion)", 0.01))
fs.Solve()
liq = brine.Object.Phases[3]
# ions on the molality scale, water on the mole-fraction scale
g = {name: liq.Compounds[name].ActivityCoeff for name in ("Water", "Sodium (ion)", "Chloride (ion)")}
gamma_pm = math.sqrt(g["Sodium (ion)"] * g["Chloride (ion)"])
a_w = g["Water"] * liq.Compounds["Water"].MoleFraction
phi = -math.log(a_w) / (2 * 1.0 * 0.018015) # osmotic coefficient, 2 ions at 1 mol/kg
print(f"NaCl mean activity coefficient = {gamma_pm:.3f}")
print(f"Water activity = {a_w:.4f} (osmotic coefficient {phi:.3f})")
print(f"Brine density = {liq.Properties.density:.1f} kg/m3")
print(f"Brine pH = {liq.Properties.pH:.2f}")
print(f"pH of the acid = {acid.Object.Phases[3].Properties.pH:.2f}")
Output
NaCl mean activity coefficient = 0.643
Water activity = 0.9669 (osmotic coefficient 0.933)
Brine density = 1035.4 kg/m3
Brine pH = 7.00
pH of the acid = 2.04
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 | eNRTL Activity Coefficient + Henry's Law / Vapor Pressure |
| Vapor enthalpy, entropy, Cp/Cv | Ideal Gas / Lee-Kesler |
| Liquid enthalpy, entropy, Cp/Cv | Ideal Gas - Vaporization Enthalpy; the eNRTL excess enthalpy is added when IncludeExcessEnthalpy is on |
| Vapor density | Ideal Gas / Peng-Robinson EOS |
| Liquid density | Water density correlation plus the molar volumes of the ions (with an ionic-strength term), from the electrolyte database; molecular solutes as pure liquids |
| 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.
| Element | Content in the example | What it holds |
|---|---|---|
ElectrolyteFlash_ReactionSetID |
DefaultSet |
Reaction set of the electrolyte flash of the base package; this package's flash takes every equilibrium reaction of the flowsheet and does not read it |
ElectrolyteFlash_Tolerance |
1E-07 |
Tolerance of the same base flash, not used by this package |
ElectrolyteFlash_MaximumIterations |
200 |
Iteration limit of the same base flash, not used by this package |
IncludeExcessEnthalpy |
false |
Adds the excess enthalpy and entropy of the activity model to the liquid (off by default; the numerical temperature derivative slows PH and PS flashes) |
GenerateSolubilityReactions |
false |
Gives every salt of the compound list that no flowsheet reaction covers a dissolution equilibrium with its ions, with K from the Gibbs energies of formation (off by default) |
UseReactiveKvalues |
false |
When on, the rigorous column takes its K-values from the speciation (off by default; much slower than the generic activity route) |
UseCustomParameters |
false |
Whether the parameter set in CustomParametersJson replaces the shipped database |
CustomParametersJson |
empty | The custom parameter set (τ pairs and their temperature coefficients) as JSON, empty when the shipped database is used |
ModelAlpha |
0.2 |
Non-randomness parameter α (default 0.2) |
ModelDielectricConstant |
78.54 |
Dielectric constant of the solvent at 25 °C (default 78.54); the model follows the temperature dependence of water from it |
ModelSolventDensity |
997 |
Solvent density at 25 °C in kg/m3 (default 997.0) |
ModelDHClosestApproach |
14.9 |
Closest-approach parameter ρ of the Pitzer-Debye-Hückel term (default 14.9) |
Settings common to every property package, as saved for the example
| Element | Value |
|---|---|
Type |
94 characters |
ComponentName |
Electrolyte NRTL (Aqueous Electrolytes) |
ComponentDescription |
Electrolyte NRTL model |
Tag |
Electrolyte NRTL (Aqueous Electrolytes) |
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 |
LeeKesler |
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¶
-
User guide
- Electrolyte NRTL (eNRTL)
- Aqueous-Phase pH and Ionic Strength
- Aqueous-Phase Transport Properties
- Electrolyte Compound Database (
electrolyte.xml) - Pitzer Single-Salt Parameter Database (
pitzer_parameters.json) - Vapour-Phase Fugacity Convention
- From the activity coefficients to the K-values
- Electrolyte Phase Diagram
-
Used with
-
FluentAPI
API members¶
Public members declared by this class. Inherited members are documented on the base classes.
Constructors¶
ElectrolyteNRTLPropertyPackage(bool)
| Parameter | Type | Description |
|---|---|---|
comode |
Boolean |
Properties¶
CustomParametersJson: JSON-serialized ENRTLDatabaseRoot with custom parameters.
JSON-serialized ENRTLDatabaseRoot with custom parameters.
ImplementsCrossPlatformEditor
LegacyTauDefault: When true, unknown (i,j) ion pairs in the eNRTL short-range term receive a default τ = 2.0 (legacy behavior of the...
When true, unknown (i,j) ion pairs in the eNRTL short-range term receive a default τ = 2.0 (legacy behavior of the original implementation). When false (default), they receive τ = 0, which collapses the SR contribution of that pair to ideality — much safer when running with ions that have no measured parameters in enrtl_parameters.json. A one-time warning is logged for each missing pair regardless.
ModelAlpha: Default non-randomness parameter α (ion–water: 0.2).
Default non-randomness parameter α (ion–water: 0.2).
ModelDHClosestApproach: Pitzer–Debye–Hückel closest-approach parameter ρ, dimensionless (default 14.9).
Pitzer–Debye–Hückel closest-approach parameter ρ, dimensionless (default 14.9).
ModelDielectricConstant: Solvent dielectric constant at 25 °C (water: 78.54).
Solvent dielectric constant at 25 °C (water: 78.54). The model follows water's ε(T) from it, see ElectrolyteNRTL.WaterProperties.
ModelSolventDensity: Solvent density at 25 °C in kg/m³ (water: 997.0).
Solvent density at 25 °C in kg/m³ (water: 997.0). The model follows water's ρ(T) from it.
UseCustomParameters: Whether custom parameters are in effect.
Whether custom parameters are in effect.
Methods¶
CalculateChemicalEquilibria(double, double): Monta e resolve o sistema de equilíbrio químico eNRTL para a corrente atual.
Monta e resolve o sistema de equilíbrio químico eNRTL para a corrente atual. O trabalho pesado (parsing do banco JSON, resolução de nomes, varredura de reações) é feito uma única vez em BuildEquilibriumCache, chamado automaticamente por RunPostMaterialStreamSetRoutine. Por chamada, apenas operações T-dependentes são executadas: · db.GetTauAtT(salt, T) — aritmética A + B/T · dwRxn.EvaluateK(T, this) — retorna K; convertido para log₁₀(K)
| Parameter | Type | Description |
|---|---|---|
T |
Double |
Temperatura [K]. |
P |
Double |
Pressão [Pa]. |
CalculateChemicalEquilibria(double, double, double[]): Sobrecarga de CalculateChemicalEquilibria que aceita a composição molar da mistura explicitamente, sem modificar a...
Sobrecarga de CalculateChemicalEquilibria que aceita a composição molar da mistura explicitamente, sem modificar a corrente. O vetor x deve ter o mesmo comprimento e a mesma ordem que _equilSpecies, preenchido por BuildEquilibriumCache() ao final de RunPostMaterialStreamSetRoutine. Essa ordem coincide com a de CurrentMaterialStream.Phases[0].Compounds.Values no momento em que a rotina foi chamada. O fator de escala de molalidade (base 1 kg de solvente) é recompensado a partir de x, de modo que a chamada é completamente independente da composição armazenada na corrente.
| Parameter | Type | Description |
|---|---|---|
T |
Double |
Temperatura [K]. |
P |
Double |
Pressão [Pa]. |
x |
Double[] |
Frações molares na ordem de _equilSpecies. Comprimento deve ser igual a _equilSpecies.Count. |
Clone()
ConvertIonsToSaltsInPlace(double[], double): Converts a solid-phase amount vector (indexed by RET_VNAMES) from ionic species to their parent salts using...
Converts a solid-phase amount vector (indexed by RET_VNAMES) from ionic species to their parent salts using precipitation reactions, least soluble first. Amounts in, amounts out, on the same basis and without renormalising: each salt formed takes its ions away, so every element is kept. Called by DryStateSolids. Default implementation is a no-op; overridden by each PP that has access to the resolved precipitation reactions.
| Parameter | Type | Description |
|---|---|---|
vs |
Double[] |
|
T |
Double |
DisplayEditingForm()
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) |
GetEditingForm(): Returns the binary interaction parameter editor of this package.
Returns the binary interaction parameter editor of this package.
LoadData(List<XElement>): Reads back what SaveParameterData writes.
Reads back what SaveParameterData writes. A file saved before these elements existed leaves the values at their defaults (built-in database).
| Parameter | Type | Description |
|---|---|---|
data |
List<XElement> |
PopulateCrossPlatformEditor(object): The Avalonia editor; see AvaloniaPackageEditors.
The Avalonia editor; see AvaloniaPackageEditors.
| Parameter | Type | Description |
|---|---|---|
container |
Object |
ReturnInstance(string)
| Parameter | Type | Description |
|---|---|---|
typename |
String |
RunPostMaterialStreamSetRoutine()
SaveData(): Writes IncludeExcessEnthalpy, GenerateSolubilityReactions and UseReactiveKvalues after the data the base package...
Writes IncludeExcessEnthalpy, GenerateSolubilityReactions and UseReactiveKvalues after the data the base package saves, so the three options travel with the flowsheet file and with Clone.
Fields¶