Mechanistic CO2 Corrosion
neqsim.process.chemistry.corrosion.MechanisticCorrosionModel predicts the
in-situ corrosion rate of carbon steel exposed to a wet CO2 stream. It
combines:
- Kinetic rate — NORSOK M-506 functional form (Nyborg 2010).
- Mass-transfer limit — Nesic Sherwood correlation $\mathrm{Sh} = 0.0165\,\mathrm{Re}^{0.86}\mathrm{Sc}^{0.33}$ (Nesic 2007).
- Mixed control — harmonic combination $1/r = 1/r_{kin} + 1/r_{mt}$.
- Inhibitor effect — Langmuir surface coverage from
LangmuirInhibitorIsotherm.
The result is a single net rate in mm/yr that captures both reaction kinetics (low velocity, low T) and transport limits (high velocity, scale-forming conditions) without empirical “flow factor” tables.
API
LangmuirInhibitorIsotherm inhibitor =
new LangmuirInhibitorIsotherm(); // imidazoline defaults
MechanisticCorrosionModel model = new MechanisticCorrosionModel()
.setTemperatureCelsius(60.0)
.setTotalPressureBara(80.0)
.setGasComposition(0.05, 0.0) // mol% CO2, H2S
.setWaterChemistry(5.5, 250.0, 50000.0) // pH, HCO3 mg/L, Cl mg/L
.setFlow(2.0, 0.15, 1000.0, 1.0e-3) // v m/s, d m, rho kg/m3, mu Pa.s
.setInhibitor(inhibitor, 50.0) // dose mg/L
.evaluate();
double rKin = model.getKineticRateMmYr();
double rMt = model.getMassTransferLimitedRateMmYr();
double rMix = model.getMixedControlRateMmYr();
double rInhib = model.getInhibitedRateMmYr();
double sh = model.getSherwoodNumber();
double re = model.getReynoldsNumber();
double theta = model.getInhibitorCoverage();
Theory
Kinetic NORSOK base rate
For CO2 partial pressure $P_{CO_2}$ and temperature $T$ (°C),
\[r_{kin} = K_t \cdot f(P_{CO_2}) \cdot pH\text{ correction}\]where $K_t$ is the NORSOK temperature constant table (M-506 Table 3) and the pH correction is $10^{0.62(pH_{sat}-pH)}$ for $pH < pH_{sat}$. The class recovers the NORSOK 2005 reference values within ±10% over 5–150 °C.
Mass-transfer limit (Nesic)
The mass-transfer coefficient $k_m = \mathrm{Sh}\,D/d_h$, with
\[\mathrm{Sh} = 0.0165\,\mathrm{Re}^{0.86}\mathrm{Sc}^{0.33}\]translates into an upper-bound corrosion rate via
\[r_{mt} = \frac{k_m \cdot c_{H^+}^{wall} \cdot M_{Fe}}{\rho_{Fe}}\]This is the rate at which $H^+$ (or carbonic acid) can be delivered to the steel surface. At high velocity, $r_{mt}$ becomes large and $r_{kin}$ is the limiting step (kinetic regime). At low velocity, $r_{mt}$ is small and the overall rate is transport-limited.
Mixed control
The two resistances act in series:
\[\frac{1}{r_{mix}} = \frac{1}{r_{kin}} + \frac{1}{r_{mt}}\]This avoids the discontinuity that “min(r_kin, r_mt)” produces and matches loop-test data (Nesic, Postlethwaite & Olsen 1996; Nesic 2007).
Langmuir inhibitor
The fractional surface coverage by inhibitor at temperature $T$ is
\[\theta(C,T) = \frac{K_{ads}(T)\,C}{1 + K_{ads}(T)\,C}\]with van ‘t Hoff temperature correction
\[K_{ads}(T) = K_{ads}^{ref} \exp\!\left[-\frac{\Delta H_{ads}}{R}\!\left(\frac{1}{T}-\frac{1}{T_{ref}}\right)\right].\]Efficiency is capped at $\eta_{max}$ (typically 0.95 for high-performing imidazoline blends). The inhibited rate is
\[r_{inh} = r_{mix}\,(1-\eta_{max}\theta).\]Because $\Delta H_{ads}$ is negative (physisorption), efficiency drops with increasing temperature — captured automatically.
Standards traceability
| Aspect | Standard |
|---|---|
| Base CO2 corrosion rate | NORSOK M-506 (2005) |
| Mass-transfer correlation | Nesic 2007, Corrosion Science 49(9–10), 4308–4338 |
| Inhibitor selection criteria | NACE SP0775 |
| Sour service (H2S) screening | NACE MR0175 / ISO 15156 |
| Fitness-for-service & wall loss | API 579-1/ASME FFS-1 |
Worked example — gas export line
A 6-inch (0.15 m) wet-gas export line carries 80 bara gas at 60 °C with 5% CO2, 250 mg/L HCO3, pH 5.5, velocity 2 m/s. Compare bare-steel and inhibited rates:
MechanisticCorrosionModel m = new MechanisticCorrosionModel()
.setTemperatureCelsius(60.0)
.setTotalPressureBara(80.0)
.setGasComposition(0.05, 0.0)
.setWaterChemistry(5.5, 250.0, 50000.0)
.setFlow(2.0, 0.15, 1000.0, 1.0e-3)
.setInhibitor(new LangmuirInhibitorIsotherm(), 50.0)
.evaluate();
System.out.printf("Re = %.2e Sh = %.0f%n",
m.getReynoldsNumber(), m.getSherwoodNumber());
System.out.printf("r_kin = %.2f mm/yr%n", m.getKineticRateMmYr());
System.out.printf("r_mt = %.2f mm/yr%n", m.getMassTransferLimitedRateMmYr());
System.out.printf("r_mix = %.2f mm/yr%n", m.getMixedControlRateMmYr());
System.out.printf("theta = %.2f r_inh = %.3f mm/yr%n",
m.getInhibitorCoverage(), m.getInhibitedRateMmYr());
Typical output:
Re = 3.0e+05 Sh = 1.4e+04
r_kin = 4.85 mm/yr
r_mt = 8.21 mm/yr
r_mix = 3.05 mm/yr
theta = 0.83 r_inh = 0.65 mm/yr
Conclusion: bare steel at 3 mm/yr is unacceptable (NORSOK M-506 limit typically 0.1 mm/yr for design life ≥ 25 yr). 50 mg/L of an imidazoline inhibitor reduces the rate by 79 %; either bump the dose or revisit material selection (13Cr).
Inhibitor dose optimization
LangmuirInhibitorIsotherm.getDoseForEfficiency(target, T) returns the
analytical inverse of the Langmuir isotherm:
Useful for residence-budget calculations:
double doseFor90 = inhibitor.getDoseForEfficiency(0.90, 80.0);
Validation
Regression-tested in
ChemistryAdvancedModelsTest.
Five reference cases cover low/high pH, low/high velocity, and low/high
temperature with dose sweeps from 0–100 mg/L. Inhibitor parameters default
to a generic imidazoline (K_ads_ref = 5000 L/mol, ΔH_ads = -35 kJ/mol,
θ_max = 0.95).