Electrolyser Brine Acidification Simulation Using Reaktoro
Table of Contents
In chlor-alkali electrolysis, controlling feed brine pH via acidification is crucial to minimize byproduct formation (like chlorate) and optimize current efficiency. However, raw brine contains impurities such as carbonates (\( \text{CO}_3^{2-} \)) and sulfates (\( \text{SO}_4^{2-} \)) that act as buffers, altering the expected pH response curve.
This post uses Reaktoro, a powerful computational framework for geochemical and chemical equilibrium modeling, to simulate HCl dosage and predict exact pH drops while accounting for operating temperatures, aqueous complexation and speciation.
How Reaktoro Operates #
When modeling complex geochemistry or high-salinity process chemistry (like chlor-alkali brines), Reaktoro structures the calculation into four distinct phases:
- Definition of the Chemical System: Choosing the thermodynamic engine (
SupcrtDatabase), selecting the specific chemical species that will participate in the reactions, and applying an activity model (likePitzer) to correct for non-ideal high-ionic-strength interactions. - State Construction & Loading: Defining the physical conditions (temperature, pressure) and feeding the raw chemical inventory mass into a baseline
ChemicalStateobject. - Equilibrium Resolution: Compiling specialized numerical specifications (
EquilibriumSpecs) and bringing the unstable starting composition into a state of minimum Gibbs free energy via theEquilibriumSolver. - Perturbation / Step Titration: Cloning the stable baseline state, adding mass increments (such as \( \text{H}^+ \) and \( \text{Cl}^- \)), and re-solving thermodynamic equilibrium at every incremental step to trace out species tracking histories.
Below is the execution flow represented as a Mermaid diagram for your blog:
rkt.SupcrtDatabase('supcrtbl')"] Species["Define Aqueous Phase
rkt.speciate(...)"] Model["Set Activity Model
rkt.ActivityModelPitzer()"] Sys["Compile Chemical System
rkt.ChemicalSystem(db, phase)"] DB --> Species Species --> Model Model --> Sys end subgraph Phase_2 ["Chemical State & Inventory Initialization"] CState["Instantiate State Block
rkt.ChemicalState(system)"] BC["Set Boundary Conditions
Temperature (60°C) & Pressure (1 bar)"] Mass["Define Mass Inventory Constraints
H₂O, Na⁺, Cl⁻, CO₃²⁻, SO₄²⁻"] Sys --> CState CState --> BC BC --> Mass end subgraph Phase_3 ["Baseline Equilibrium Resolution"] Specs["Define Equilibrium Specs
rkt.EquilibriumSpecs(system)"] Solver["Instantiate Solver Block
rkt.EquilibriumSolver(specs)"] Equil["Execute Initial Solve
solver.solve(state)"] BasePH["Output Initial Baseline pH"] Mass --> Specs Specs --> Solver Solver --> Equil Equil --> BasePH end subgraph Phase_4 ["Titration Loop (Perturbation)"] LoopStart["For each HCl Increment in Array
np.linspace(0.0, 0.02, 100)"] Clone["Clone Baseline State Obj
step_state = rkt.ChemicalState(state)"] Inject["Perturb System Mass Matrix
step_state.add('H+'), step_state.add('Cl-')"] ReSolve["Re-equilibrate Thermodynamic State
solver.solve(step_state)"] Harvest["Extract Speciation Vectors
pH, HCO₃⁻, CO₂(aq), HSO₄⁻"] LoopEnd["Append to list or array"] BasePH --> LoopStart LoopStart --> Clone Clone --> Inject Inject --> ReSolve ReSolve --> Harvest Harvest --> LoopEnd LoopEnd -- "Next Step" --> LoopStart end %% Styling nodes for a clean process block look style Sys fill:#f97316,color:#fff,stroke:#333,stroke-width:2px style Equil fill:#2563eb,color:#fff,stroke:#333,stroke-width:2px style ReSolve fill:#16a34a,color:#fff,stroke:#333,stroke-width:2px
Speciation & Buffer Intensity Analysis #
When plotting the titration curve, distinct phases emerge based on the decomposition of impurities:
1. The Carbonate to Bicarbonate Transition #
Initial acid drops transform carbonate ions into bicarbonate: \[ \text{CO}_3^{2-} + \text{H}^+ \rightarrow \text{HCO}_3^- \]
2. The Bicarbonate Plateau (pH 6.5 - 4.5) #
A prominent flattening occurs where pH drops slowly. This is the primary buffering zone where bicarbonate is converted into aqueous carbon dioxide: \[ \text{HCO}_3^- + \text{H}^+ \rightarrow \text{CO}_2\text{(aq)} + \text{H}_2\text{O} \]
In an open industrial system, this phase is followed by vacuum dechlorination or air-stripping towers to physically remove gas bubbles, breaking the buffer.
3. The Bisulfate Buffer (pH < 2) #
At highly acidic values, secondary buffering is encountered as sulfate converts to bisulfate: \[ \text{SO}_4^{2-} + \text{H}^+ \rightarrow \text{HSO}_4^- \]
| Brine Impurity | Active pH Range | Chemical Transformation |
|---|---|---|
| Carbonate | \( > 8.0 \) | Converts into soluble bicarbonate species. |
| Bicarbonate | \( 6.5 \rightarrow 4.5 \) | Converts to aqueous \( \text{CO}_2 \); forms main buffering plateau. |
| Sulfate | \( < 2.5 \) | Absorbs protons to yield intermediate bisulfate ion. |