Closed-Loop Deposition Coupling
neqsim.process.chemistry.scale.ClosedLoopDepositionSolver couples
PipeBeggsAndBrills pipe hydraulics with ScaleDepositionAccumulator so the
deposition rate, velocity and effective inside diameter stay mutually
consistent. Without coupling, deposition is computed at the clean velocity
and over-predicts thinning; with coupling, the velocity rises as the ID
shrinks and the system finds a quasi-steady deposition rate.
Why couple?
Scale deposition rate scales roughly as
\[\dot{m}_{dep} \;\propto\; SI \cdot v^{\alpha} \cdot t,\qquad \alpha \in [0.5, 1.5]\]while velocity in a pipe of effective diameter $d_{eff}$ goes as $v \propto 1/d_{eff}^2$. A naive sequential calculation ignores that the shrinking diameter feeds back into the velocity term — producing an unphysical exponential collapse. The closed-loop solver iterates the two models until $|d_{eff}^{(k+1)} - d_{eff}^{(k)}| < \mathrm{tol}$.
API
PipeBeggsAndBrills pipe = new PipeBeggsAndBrills("Tieback", inletStream);
pipe.setLength(1000.0);
pipe.setDiameter(0.20);
pipe.setElevation(0.0);
ScaleDepositionAccumulator deposition = new ScaleDepositionAccumulator()
.setBrineChemistry(1500.0, 400.0, 100.0, 5.0, 12000.0, 35000.0)
.setExposureTimeS(30.0 * 24 * 3600.0); // 30 days
ClosedLoopDepositionSolver solver = new ClosedLoopDepositionSolver(pipe, deposition)
.setToleranceM(1.0e-4)
.setMaxIterations(15)
.solve();
int its = solver.getIterationsTaken();
double dEffFinal = solver.getFinalEffectiveDiameterM();
List<Double> velocityHistory = solver.getVelocityHistoryMs();
List<Double> diameterHistory = solver.getDiameterHistoryM();
Inputs
The solver consumes a configured PipeBeggsAndBrills and a
ScaleDepositionAccumulator. The accumulator owns the brine chemistry:
| Setter | Units | Notes |
|---|---|---|
setBrineChemistry(Ca, HCO3, SO4, Ba, Mg, TDS) |
mg/L (× 6) | Six-argument signature — order matters |
setExposureTimeS(t) |
s | Cumulative time over which the steady-state rate is integrated |
The solver itself only owns numerical controls:
| Setter | Default | Meaning |
|---|---|---|
setToleranceM(tol) |
1.0e-4 | Convergence criterion on $d_{eff}$ |
setMaxIterations(n) |
10 | Iteration cap before bailout |
Algorithm
Each iteration $k$:
- Run
pipe.run()with the currenteffectiveDiameterto obtain $v^{(k)}$ and $\tau_w^{(k)}$. - Pass these into
deposition.evaluate()and read the deposition mass per segment. - Convert mass to a uniform thickness using $\rho_{scale} = 2700$ kg/m³ (calcite default), update $d_{eff}$.
- Check convergence; if not converged, repeat.
The diameter and velocity at every iteration are stored in
getDiameterHistoryM() / getVelocityHistoryMs() for diagnostics.
Worked example — 30-day scaling forecast on a subsea tieback
A 1 km × 0.20 m subsea tieback carries produced water with 1500 mg/L Ca, 400 mg/L HCO3, 100 mg/L SO4 at 35 °C. Forecast ID and velocity drift over 30 days:
SystemInterface fluid = new SystemSrkEos(308.15, 80.0);
fluid.addComponent("methane", 0.05);
fluid.addComponent("CO2", 0.05);
fluid.addComponent("water", 0.90);
fluid.setMixingRule("classic");
Stream feed = new Stream("feed", fluid);
feed.setFlowRate(50000.0, "kg/hr");
feed.run();
PipeBeggsAndBrills pipe = new PipeBeggsAndBrills("Tieback", feed);
pipe.setLength(1000.0);
pipe.setDiameter(0.20);
ScaleDepositionAccumulator dep = new ScaleDepositionAccumulator()
.setBrineChemistry(1500.0, 400.0, 100.0, 5.0, 12000.0, 35000.0)
.setExposureTimeS(30.0 * 24 * 3600.0);
ClosedLoopDepositionSolver solver =
new ClosedLoopDepositionSolver(pipe, dep).solve();
System.out.printf("Iterations: %d%n", solver.getIterationsTaken());
System.out.printf("Effective ID after 30 days: %.4f m%n",
solver.getFinalEffectiveDiameterM());
Typical output:
Iterations: 5
Effective ID after 30 days: 0.1872 m (6.4 % reduction)
A 6 % ID reduction in 30 days corresponds to a roughly 27 % rise in pressure drop ($\Delta P \propto 1/d^4$ in the turbulent friction-dominated limit). Compare this with allowable backpressure and decide on inhibition strategy.
Failure modes and diagnostics
| Symptom | Likely cause | Remedy |
|---|---|---|
getIterationsTaken() == maxIterations |
Tolerance too tight or runaway deposition | Loosen tol, shorten setExposureTimeS, or check brine chemistry |
| Final ID equals initial ID | Brine undersaturated (SI ≤ 0) | Verify setBrineChemistry arguments; check pH and CO2 partial pressure inside the accumulator |
| Final ID collapses to zero | Exposure time longer than time-to-blockage | Use a shorter integration window and march forward in steps |
Standards traceability
| Aspect | Standard |
|---|---|
| Pipeline hydraulics | API RP 14E (erosional velocity) |
| Scale formation potential | NACE TM0374 |
| Wall-loss / wall-gain integrity tracking | NACE SP0775 |
| Inspection planning intervals | API 570 |
Validation
Regression-tested in
ChemistryCoupledModelsTest.
The test suite covers under- and oversaturated brines, low- and high-velocity
pipes, and verifies monotone diameter contraction and convergence within
≤ 10 iterations for typical NACE TM0374 reference brines.