agentleFS
equinorequinor/neqsim/.github/skills/neqsim-flow-accelerated-corrosion/SKILL.md

neqsim-flow-accelerated-corrosion

Skill167 starsChanged 7 months agoApache-2.0View on GitHub

Flow-accelerated corrosion and high-temperature pH in closed heating/cooling-medium loops - magnetite stability, wall thinning at bends and welds, wall shear, in-situ vs lab pH, Cr-Mo upgrade screening. USE WHEN: localised thinning or leaks at bends, elbows or welds in carbon-steel tubing; a glycol/water, boiler-feedwater or condensate loop; a WHRU or economiser bundle; amine pH control; or 'is the fluid alkaline enough at temperature?'. Anchors on neqsim.process.corrosion.

The file

We split this skill into the rules it gives an agent

2 rules. About 0 are common, 1 is distinctive, and 1 is very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈1

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 1

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Do not use water tables — glycol changes density and viscosity substantially, and viscosity roughly halves between 100 °C and 150 °C, which …

    line 79
  2. Very specific:

    Call calculateAlkalineReserve() with no arguments when no acid analysis exists.

    line 136

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

NeqSim Flow-Accelerated Corrosion and High-Temperature pH Skill

Screening for flow-accelerated corrosion (FAC) — dissolution of the protective magnetite film under mass-transfer control — and for the in-situ pH that governs it.

When this skill applies

  • Localised wall thinning or leaks at bends, elbows or circumferential welds in carbon-steel tube bundles, with intact surfaces nearby.
  • Closed heating- or cooling-medium loops (glycol/water or water), boiler-feedwater, condensate, WHRU / economiser / steam-generator tubes.
  • Operating temperature roughly 90–250 °C, peaking near 150 °C.
  • Questions about pH control of an amine-buffered loop, or whether measured chemistry is adequate.

Two mistakes to avoid before anything else

1. Do not judge a hot system by its laboratory pH.

Laboratory pH is measured on a cooled sample, typically at 20–25 °C. Corrosion happens at 150 °C. Two things move, by different amounts:

  • The amine pK$_a$ falls, so the buffered fluid becomes less alkaline.
  • Neutrality itself falls: neutral water is pH 7.00 at 25 °C but about pH 5.85 at 150 °C.

So the meaningful quantity is the alkaline margin, $\text{pH}(T) - \text{pH}_{neutral}(T)$, not the raw pH. Use AmineBufferedPH.

2. Do not confuse FAC with erosion-corrosion. They occur at the same locations and need different mitigation:

FACErosion-corrosion
MechanismElectrochemical dissolution, mass-transfer limitedMechanical removal by particles/cavitation
SurfaceSmooth, wavy, scallopedDirectional grooves, impingement craters
FixChemistry, temperature, Cr alloyingRemove particles / impingement

RootCauseAnalyser now raises both as separate candidates.

3. Do not read a CFD wall-shear map as a FAC map at a separated feature.

FAC is mass-transfer controlled. FlowAcceleratedCorrosion gets there through Berger-Hau, $Sh = 0.0165,Re^{0.86}Sc^{0.33}$, with a Stokes-Einstein diffusivity — for a hot glycol/water loop $Sc$ lands near 280, so the concentration boundary layer is roughly $Sc^{1/3}\approx 6.5$ times thinner than the momentum one.

CFD studies usually deliver wall shear, and the tempting conversion is $k_m\propto u^{*}\propto\sqrt{\tau_w}$. That is only valid where the boundary layer stays attached — a bend, a gentle taper. At a weld root protrusion, an orifice or any sudden expansion the flow separates and reattaches, and at reattachment $\tau_w$ passes through zero while $k_m$ peaks. A shear map there puts its minimum close to where the metal loss is worst, so:

  • a shear-derived geometry factor is defensible for ELBOW_BEND, not for WELD_ROOT_PROTRUSION or DOWNSTREAM_ORIFICE;
  • a low-shear separated wake in a CFD figure must not be described as low-risk.

To compute a weld factor honestly you need a passive scalar at the real $Sc$ on a wall-resolved mesh, validated by reproducing the Berger-Hau $Sh$ in a straight run first — the mass-transfer analogue of checking the straight-pipe $\tau_w$. The cfd-coupling skill solves momentum only today, so state the screening factor and its basis rather than substituting a shear ratio.

Workflow

1. Get fluid properties from the actual fluid

Do not use water tables — glycol changes density and viscosity substantially, and viscosity roughly halves between 100 °C and 150 °C, which nearly doubles the Reynolds number at constant velocity.

SystemInterface f = new SystemSrkCPAstatoil(273.15 + 150.0, 19.6);
f.addComponent("TEG", 45.0, "kg/sec");
f.addComponent("water", 55.0, "kg/sec");
f.setMixingRule(10);
new ThermodynamicOperations(f).TPflash();
f.initProperties();
double rho = f.getDensity("kg/m3");
double mu = f.getViscosity("cP");

2. Convert laboratory pH to in-situ pH

AmineBufferedPHResult ph = new AmineBufferedPH()
    .setAmine(BufferAmine.DEA)
    .setMeasuredPH(8.7, 20.0)        // lab value and lab temperature
    .setOperatingTemperature(150.0)
    .setGlycolMassFraction(0.45)     // records a warning; not corrected
    .calculate();

ph.getOperatingPH();          // in-situ pH at 150 C
ph.getMarginAtOperating();    // the number that matters
ph.getVerdict();              // ROBUST / ADEQUATE / MARGINAL / INSUFFICIENT

2b. Ask how much buffer is left, not just how much margin

A positive margin does not say whether it sits on a fresh buffer or on the remnant of a nearly exhausted one, and those call for different actions. calculateAlkalineReserve locates the titration end point — the laboratory pH at which the margin at the operating temperature reaches zero — and reports how much of the usable reserve has already been consumed. The amine concentration cancels out, so no dosing record is needed: a fluid sample is enough.

AmineBufferedPH calc = new AmineBufferedPH()
    .setAmine(BufferAmine.DEA)
    .setMeasuredPH(8.7, 20.0)
    .setOperatingTemperature(150.0)
    .setGlycolMassFraction(0.45);

// 310 mg/L total organic acids, formate/acetate average molar mass 52.03 g/mol
AlkalineReserveResult r = calc.calculateAlkalineReserve(310.0, 52.03);

r.getMeasuredPHAtZeroMargin();          // 8.33 - the real control floor, not pH 7
r.getFreeBaseFractionAsFound();         // 0.31
r.getReserveSpentFraction();            // 0.82 - four fifths already gone
r.getRemainingAcidCapacityMgPerL();     // 68 mg/L of further acid
r.getRemainingAcidCapacityMmolPerL();   // 1.31 mmol/L - also prices a CO2 ingress
r.getDerivedAmineInventoryMmolPerL();   // cross-check against the dosing record

Call calculateAlkalineReserve() with no arguments when no acid analysis exists; the fractions still come out, only the capacity fields are NaN. Use AmineBufferedPH.freeBaseFraction(pH, pKa) to draw the titration curve.

Why this changes the recommendation. A margin of +0.37 reads as a small but positive number. Expressed as a reserve it is the span from pH 8.7 down to pH 8.33, with 82 % already spent — so total organic acid belongs in the control limits, not in a trend plot, and a single sub-9 pH excursion is most of what is left.

2c. Price a CO2 or O2 ingress against that reserve

Dissolved CO2 titrates the same buffer mole for mole at these pH values, and O2 titrates it indirectly by oxidising the glycol to organic acids. Both therefore convert into the same mmol/L currency as the remaining capacity. Get the solubility from a flash of the actual glycol/water rather than a water table, and ask for the concentration unit directly:

double hCO2 = fluid.calcHenrysConstant("CO2", "mol/m3/bar");   // == mmol/L/bar
double hO2 = fluid.calcHenrysConstant("oxygen", "mol/m3/bar");
double dissolvedCO2mmolPerL = hCO2 * partialPressureBar;

Supported units are bar (the default, f_i / x_i per mole fraction), mol/m3/bar, mmol/L/bar, mol/L/bar and mg/L/bar. One mol/m3 is one mmol/L — dividing by 1000 between them is the most common error in this calculation, which is why both spellings are accepted. The method needs exactly two phases and throws rather than returning zero if that is not the case.

3. Rank the FAC contributors

FlowAcceleratedCorrosionResult fac = new FlowAcceleratedCorrosion()
    .setFlow(2.66, 0.025)
    .setFluidProperties(rho, mu)
    .setTemperature(150.0)
    .setInSituPH(ph.getOperatingPH())     // in-situ, never the lab value
    .setGeometry(FacGeometry.WELD_AT_BEND)
    .setChromiumContent(0.02)             // carbon steel; P11 is 1.25
    .calculate();

fac.getDominantFactor();       // which lever actually controls the outcome
fac.getWallShearStressPa();
fac.ratioTo(otherCase);        // quantify a proposed change

The index is for comparison only — ratios between cases are meaningful, the absolute value is not a wall-loss rate.

Things worth checking that investigations routinely miss

CheckWhy
Express a velocity exceedance as shear$\tau \propto v^{1.75}$, so a 3 % velocity overshoot is a ~13 % shear overshoot. A "3 %" framing makes a real exceedance look like noise
Correlate damage with the hot endRe rises ~70 % from 100 → 150 °C at constant velocity, and 150 °C is the solubility peak. Damage should concentrate at the outlet end — a cheap, testable prediction
Check the filter micron ratingMagnetite fines are 1–10 µm. An 80 µm element removes essentially none of them. "Improve filtration" must carry a rating
Check the boiling marginCompute the bubble point; if bulk boiling is impossible, that hypothesis is closed off
Flow reduction is not freeCutting flow to reduce shear reduces recovered duty, and at fixed duty raises metal temperature towards the 150 °C peak. Quantify the trade-off rather than asserting it
Ask what the loop actually ran atA design basis says what the flow should be in stand-by; only the historian says how long it was there. See below — this is usually the cheapest decisive evidence in the whole study

Measure the exposure instead of assuming it

A closed heating-medium loop is usually served by two or more identical units on an N+1 duty/stand-by rota, and the stand-by one runs at a small fraction of design flow. That makes the loop a natural experiment: same fluid, same pH history, same material, different duty. If some units have leaked and others have not, the historian settles whether duty is the difference.

Resolve the tag family from the plant's tag database (all three of flow, outlet temperature and outlet pressure exist for each unit), then report, per unit:

  • the fraction of live-loop time below each design threshold — the stand-by flows the data sheet specifies, and the min-flow protection levels;
  • the median flow as a fraction of design;
  • the maximum outlet temperature against the high-temperature protection setting and the data sheet film limit.

On one WHRU loop this turned "the unit that runs continuously has not leaked" from an absence of maintenance records into a measured 4 % versus 40-46 % of time below 20 % of design flow. It also removed a competing hypothesis: cycle count did not discriminate at all, which corroborated a separate fatigue screening.

See enterprise-plant-data for the unit-reconciliation, outage-exclusion and cycle-aliasing traps that decide whether those percentages mean anything.

Find out how the bend is actually built before modelling it

Damage reported "at circumferential welds adjacent to bends" is a construction question first and a fluid-dynamics question second. Retrieve the bundle description and the Return bends block of the equipment data sheet before assuming anything:

What to look forWhy it changes the analysis
Bend angleA 180° return is the norm in serpentine coils, not a 90° elbow. Dean secondary flow needs roughly a quarter to a half turn to develop, so a 90° case releases the flow before the vortex pair is established and understates both the extrados enhancement and its downstream persistence. A geometry factor computed on 90° is a lower bound for a 180° return
Formed bend or separate fittingIf the data sheet says the return bends are forged fittings (e.g. ASTM A234 WPB) rather than formed tube, then a circumferential butt weld exists at each end of every bend by construction. WELD_AT_BEND stops being a screening assumption and becomes the documented geometry
Fitting grade vs tube gradeA106 Gr. B tube welded to an A234 WPB fitting is a dissimilar-heat joint. Neither grade specifies chromium, and FAC rate is controlled by residual Cr at the hundredths of a percent level, so the lower-Cr side wastes preferentially and produces sharp thinning at the weld rather than general loss. The material certificates carry the analysis — this is a document retrieval, not a study
Bend radiusFrequently absent from the data sheet. If no R/D is documented, say so; do not let an assumed long-radius default pass as a retrieved value

Provenance trap that produced this entry. A CFD script carried bend_angle_deg = 90.0 and BEND_RADIUS_RATIO = 1.5 under a block comment reading "all from the task (data sheet geometry)". The bore genuinely was from the data sheet; the bend was not, and the controlled documents said 180°. A comment that covers a block of constants can be true for one line and false for the next — source each geometry constant individually, and put the document number next to it rather than at the top of the block.

And the angle moves where you inspect. Re-solving that case at the documented 180° changed more than the number. At R/D = 1.5, Re ≈ 1.7 × 10⁵:

90° bend180° return
Peak wall shear ratio2.332.74
Geometry factor √R1.531.66
Where the peak sitsintrados, near the entry55° off the intrados, past mid-turn

Over a half turn the Dean vortex pair becomes fully developed and convects high-momentum core fluid outward along the side walls, so the maximum migrates off the intrados towards the quarter position and is delayed to beyond the mid-point of the arc. Downstream over 15–25 D the pattern inverts — extrados ≈ 1.5, intrados ≈ 0.9 in the separated wake. Inspecting the intrados entry, which is the right answer for a 90° elbow, is the wrong answer for a 180° return.

Material upgrade

About 1 % Cr gives roughly an order-of-magnitude improvement. NORSOK M-001 specifies ASTM A335 P11 for WHRU heat-exchanger tubes; API RP 571 and API RP 661 both point to low-alloy Cr-Mo steel for FAC-prone service. If plain carbon steel is installed where a standard specifies P11, that is a compliance finding, not just an observation — check it explicitly with neqsim-standards-lookup.

Reporting

results.json should carry: in_situ_pH, alkaline_margin, wall_shear_stress_Pa, fac_index_ratio for each case compared, dominant_factor, and every entry of getWarnings() in the assumptions/gaps register. Declare the ideal-solution basis of the pH shift and the comparison-only nature of the FAC index.

Related skills

  • neqsim-flow-assurance — CO2/H2S corrosion in production systems (a different mechanism; NORSOK M-506 does not apply to a CO2-free closed loop)
  • neqsim-root-cause-analysis — ranking FAC against other candidates
  • neqsim-standards-lookup — NORSOK M-001, API RP 571 §3.9, API RP 669, API RP 661
  • neqsim-self-heating-ignition — the same Arrhenius framework applied to glycol oxidative degradation, which generates the organic acids that consume alkalinity
  • neqsim-plant-data / enterprise-plant-data — measured stand-by exposure, the duty comparison between units, and the traps in quoting "% of design flow"
  • enterprise-maintenance-api — leak distribution per tag and equipment-availability history (filter outages), which pairs with the historian evidence

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.