| name | neqsim-electrolyte-systems |
| description | Electrolyte and brine chemistry guidance for NeqSim. USE WHEN: modeling produced water, scale prediction, CO2/H2S in aqueous systems, MEG/DEG injection, hydrate inhibitor dosing, or any system with ions, salts, or electrolytes. Covers SystemElectrolyteCPAstatoil setup, ion components, scale risk assessment, and brine handling patterns. |
| last_verified | 2026-07-04 |
Electrolyte Systems Guide
Guide for modeling electrolyte/brine systems in NeqSim.
When to Use Electrolyte Models
- Produced water with dissolved salts (NaCl, CaCl2, BaCl4)
- Scale prediction (CaCO3, BaSO4, CaSO4)
- CO2/H2S solubility in brines
- MEG injection rate calculations
- Hydrate inhibitor dosing
- Seawater injection and mixing
- Desalination process modeling
EOS Selection for Electrolyte Systems
| System | NeqSim Class | Mixing Rule |
|---|
| Water + salt + HC gas | SystemElectrolyteCPAstatoil | 10 |
| MEG/DEG + water + gas | SystemSrkCPAstatoil | 10 |
| Pure water + gas | SystemSrkCPAstatoil | 10 |
| Brine + multiple salts | SystemElectrolyteCPAstatoil | 10 |
Basic Electrolyte Setup
import neqsim.thermo.system.SystemElectrolyteCPAstatoil;
SystemInterface brine = new SystemElectrolyteCPAstatoil(273.15 + 80.0, 200.0);
brine.addComponent("CO2", 0.05);
brine.addComponent("methane", 0.80);
brine.addComponent("water", 0.10);
brine.addComponent("Na+", 0.02);
brine.addComponent("Cl-", 0.02);
brine.addComponent("Ca++", 0.005);
brine.addComponent("SO4--", 0.005);
brine.setMixingRule(10);
brine.setMultiPhaseCheck(true);
Common Ion Components in NeqSim
| Ion | NeqSim Name | Common Source |
|---|
| Sodium | "Na+" | NaCl |
| Chloride | "Cl-" | NaCl, CaCl2 |
| Calcium | "Ca++" | CaCl2, CaCO3 |
| Barium | "Ba++" | BaSO4, BaCl2 |
| Strontium | "Sr++" | SrSO4 |
| Sulfate | "SO4--" | Na2SO4, BaSO4 |
| Bicarbonate | "HCO3-" | NaHCO3 |
| Carbonate | "CO3--" | CaCO3, Na2CO3 |
| Magnesium | "Mg++" | MgCl2 |
| Potassium | "K+" | KCl |
| Iron(II) | "Fe++" | FeCl2, FeS |
Produced Water Modeling
SystemInterface prodWater = new SystemElectrolyteCPAstatoil(273.15 + 80.0, 50.0);
prodWater.addComponent("CO2", 0.01);
prodWater.addComponent("H2S", 0.001);
prodWater.addComponent("methane", 0.005);
prodWater.addComponent("water", 0.90);
prodWater.addComponent("Na+", 0.03);
prodWater.addComponent("Cl-", 0.035);
prodWater.addComponent("Ca++", 0.003);
prodWater.addComponent("Ba++", 0.0001);
prodWater.addComponent("SO4--", 0.001);
prodWater.addComponent("HCO3-", 0.005);
prodWater.setMixingRule(10);
prodWater.setMultiPhaseCheck(true);
ThermodynamicOperations ops = new ThermodynamicOperations(prodWater);
ops.TPflash();
prodWater.initProperties();
Scale Risk Assessment
Higher-level scale helpers (prefer for screening)
Before hand-rolling the flash, note these ready-made helpers (see the
neqsim-flow-assurance skill for full patterns):
ElectrolyteScaleCalculator — activity-corrected SI for CaCO3, BaSO4, CaSO4,
SrSO4 from ion mg/L (Davies + Ksp(T)).
ScaleKinetics — induction time and reaction-vs-transport growth regime on top
of an SI (SI says if, kinetics says how fast).
BrineMixingScaleEvaluator — seawater/formation-water mixing sweep; finds the
worst mixing fraction and mineral (sulphate scale often peaks mid-mix).
ScaleDepositionAccumulator / PipeSegmentIntegrity — deposition and coupled
corrosion+scale along a PipeBeggsAndBrills profile.
- Rigorous scale potential (saturation ratio SR = IAP/Ksp per salt):
ops.checkScalePotential(phaseNumber) then ops.getResultTable(). This uses
in-situ ion molalities, so it needs chemical reactions + speciation — call
system.chemicalReactionInit() before createDatabase(true)/setMixingRule(10)
and flash first (otherwise carbonate/bicarbonate/pH speciation is missing and
the SR is wrong).
CaCO3 (Calcite) Scaling
Scale forms when the product of ion activities exceeds the solubility product:
$$
SI = \log_{10}\left(\frac{a_{Ca^{2+}} \cdot a_{CO_3^{2-}}}{K_{sp}}\right)
$$
Where $SI > 0$ indicates supersaturation (scaling risk).
SystemInterface mixed = new SystemElectrolyteCPAstatoil(273.15 + 80.0, 50.0);
mixed.chemicalReactionInit();
mixed.createDatabase(true);
mixed.setMixingRule(10);
mixed.setMultiPhaseCheck(true);
ThermodynamicOperations ops = new ThermodynamicOperations(mixed);
ops.TPflash();
mixed.initProperties();
int aq = mixed.getPhaseNumberOfPhase("aqueous");
ops.checkScalePotential(aq);
String[][] sr = ops.getResultTable();
double pH = mixed.getpH();
if (mixed.hasPhaseType("solid")) {
double solidMoles = mixed.getPhase("solid").getNumberOfMolesInPhase();
double solidMassKg = solidMoles * mixed.getPhase("solid").getMolarMass();
}
BaSO4 (Barite) Scaling
Most problematic scale in oil production — forms when Ba++ meets SO4--.
SystemInterface formWater = new SystemElectrolyteCPAstatoil(273.15 + 90.0, 200.0);
formWater.addComponent("water", 0.95);
formWater.addComponent("Na+", 0.025);
formWater.addComponent("Cl-", 0.020);
formWater.addComponent("Ba++", 0.001);
formWater.addComponent("Sr++", 0.0005);
formWater.setMixingRule(10);
SystemInterface injWater = new SystemElectrolyteCPAstatoil(273.15 + 20.0, 200.0);
injWater.addComponent("water", 0.96);
injWater.addComponent("Na+", 0.015);
injWater.addComponent("Cl-", 0.015);
injWater.addComponent("SO4--", 0.01);
injWater.setMixingRule(10);
MEG Injection Calculations
SystemInterface wetGas = new SystemSrkCPAstatoil(273.15 + 5.0, 100.0);
wetGas.addComponent("methane", 0.85);
wetGas.addComponent("ethane", 0.08);
wetGas.addComponent("propane", 0.03);
wetGas.addComponent("water", 0.03);
wetGas.addComponent("MEG", 0.01);
wetGas.setMixingRule(10);
wetGas.setMultiPhaseCheck(true);
ThermodynamicOperations ops = new ThermodynamicOperations(wetGas);
ops.hydrateFormationTemperature();
double hydrateT = wetGas.getTemperature() - 273.15;
CO2 Solubility in Brine
Important for CCS and EOR projects:
SystemInterface co2Brine = new SystemElectrolyteCPAstatoil(273.15 + 50.0, 100.0);
co2Brine.addComponent("CO2", 0.10);
co2Brine.addComponent("water", 0.80);
co2Brine.addComponent("Na+", 0.05);
co2Brine.addComponent("Cl-", 0.05);
co2Brine.setMixingRule(10);
ThermodynamicOperations ops = new ThermodynamicOperations(co2Brine);
ops.TPflash();
co2Brine.initProperties();
double co2InWater = co2Brine.getPhase("aqueous").getComponent("CO2").getx();
double pH = co2Brine.getpH();
For a rigorous speciated pH in a buffered brine (explicit H3O+/HCO3-/OH-),
run system.chemicalReactionInit() before createDatabase(true) /
setMixingRule(10). The getpH("acidgas") fallback is a screening estimate that
ignores bicarbonate buffering and salt-ion alkalinity — see the electrolyte-CPA
model docs and the flow-assurance skill for corrosion use.
Key Units and Conversions
| Quantity | Unit | Conversion |
|---|
| Ion concentration | mol fraction | ppm = x × MW_solution / MW_ion × 1e6 |
| TDS | mg/L | Sum of all dissolved ion concentrations |
| Salinity | wt% NaCl equiv | Based on Na+/Cl- content |
| pH | dimensionless | From H+ activity |
Common Pitfalls
- Charge balance: Total positive charges must equal total negative charges
- Mixing rule must be numeric
10: Not "classic" — CPA requires numeric mixing rule
- Ion names are case-sensitive:
"Na+" not "na+" or "NA+"
- Multi-phase check: Always enable for electrolyte systems (
setMultiPhaseCheck(true))
- Temperature limits: Electrolyte models may have narrower valid T range than HC models
- Convergence: Electrolyte flashes can be slow — be patient or reduce component count
- Missing counter-ions: Always add both cation and anion (e.g., Na+ with Cl-)