Skip to main content

neqsim-flow-assurance

Flow assurance patterns for NeqSim. USE WHEN: predicting hydrate, wax, asphaltene, CO2/H2S corrosion (NORSOK M-506), mineral scale and brine mixing, valve scale drift and remediation, sulfur S8 deposition, metal-loss screening, pipeline hydraulics, DNV-RP-F109/F105/F104/F110/F114 screening, water hammer, slug flow, thermal analysis or inhibitor dosing. Code patterns plus the governing standards for every threat.

معلومات المصدر

المستودع
equinor/neqsim
آخر نشاط في المصدر
٢٩ أكتوبر ٢٠٢٦ في ٢١:٢٢
لغة SKILL.md المكتشفة
الإنجليزية
النجوم
١٦١
التفرعات
٧٧

خيارات التثبيت

يُحدَّد Prompt الذي يراجع المصدر أولًا بشكل افتراضي. يمكنك التبديل إلى أمر مباشر أو تنزيل نسخة محلية.

مراجعة ملفات المصدر

اقرأ SKILL.md وأي ملفات مرافقة يعرضها SkillsMP قبل أن تقرر التثبيت.

عرض SKILL.md

SKILL.md
تعليمات المصدر · معاينة للقراءة فقط
name
neqsim-flow-assurance
description
Flow assurance patterns for NeqSim. USE WHEN: predicting hydrate, wax, asphaltene, CO2/H2S corrosion (NORSOK M-506), mineral scale and brine mixing, valve scale drift and remediation, sulfur S8 deposition, metal-loss screening, pipeline hydraulics, DNV-RP-F109/F105/F104/F110/F114 screening, water hammer, slug flow, thermal analysis or inhibitor dosing. Code patterns plus the governing standards for every threat.
last_verified
2026-09-07
# Flow Assurance Analysis with NeqSim Consolidated guide for all flow assurance threats — hydrate, wax, asphaltene, corrosion, hydraulics, water/liquid hammer screening, slugging, and thermal management — with NeqSim code patterns. > A complete study report with pipeline drawings (route, profiles, hydrate margin, threat matrix, > validation) is produced by `neqsim flow-assurance-report` — see the > `neqsim-flow-assurance-study-report` skill. This skill stays the calculation reference. > A whole subsea SURF network (templates, injection, risers, umbilical, concept comparison) is > generated, solved and documented by `neqsim surf-study` — see the `neqsim-surf-design-study` skill. ## When to Use This Skill - Hydrate formation temperature/pressure prediction - Hydrate inhibitor dosing (MEG, methanol, ethanol) - Wax appearance temperature (WAT) and wax deposition risk - Asphaltene stability screening (de Boer, CII) - CO2 and H2S corrosion rate estimation - Elemental sulfur (S8) deposition risk at pressure/temperature letdown (compressor inlets, control/letdown valves, dry-gas seals, filters) - Pipeline pressure drop and temperature profile - DNV-RP-F109 vertical and lateral on-bottom stability screening - Water hammer/liquid hammer screening for fast valve closure, pump trip, or check-valve slam - Multiphase flow pattern prediction (slug, annular, stratified) - Thermal insulation sizing for subsea pipelines - Arrival temperature and cooldown calculations ## Applicable Standards | Domain | Standards | Key Requirements | |--------|-----------|-----------------| | Pipeline design | DNV-ST-F101, DNV-RP-F104 for CO2, NORSOK L-001, ASME B31.4/B31.8 | Structural design plus composition-specific CO2 phase/hydraulic and lifecycle basis | | Corrosion | NORSOK M-001, DNV-RP-F112, ISO 21457 | Material selection, CO2/H2S corrosion rates | | On-bottom stability | DNV-RP-F109 | Vertical stability, absolute lateral stability, displacement acceptance | | Free spans | DNV-RP-F105 | Free-span response and fatigue assessment | | Global buckling and pipe-soil interaction | DNV-RP-F110, DNV-RP-F114 | Caller-controlled external response and demand-resistance screening | | Subsea systems | NORSOK U-001 | Subsea production-system requirements | | Hydrate management | DNV-RP-F116 | Hydrate prevention and remediation | | GRP piping | ISO 14692 | Non-metallic pipe design | | Pipeline integrity | DNV-RP-F101, DNV-RP-F116, API 1160 | Inspected metal-loss remaining strength and integrity management | For fast acoustic transients, also load `neqsim-water-hammer`. Use `WaterHammerStudy` or MCP `runWaterHammer` with STID route geometry, tagreader event windows, and valve/pump event schedules; use this flow-assurance skill for the broader operating-envelope and mitigation context. For on-bottom stability, load `neqsim-subsea-and-wells` and use the typed `DnvRpF109OnBottomStabilityKernel`. It provides a transparent absolute-static screen and checks externally calculated response displacements. It does not contain generalized design tables, produce dynamic response, qualify environmental or soil models, or claim DNV conformity. A pass still requires independent review. This skill quantifies the **threat** (hydrate curve, WAT, SI, corrosion rate). For the **chemical** answer — which product, minimum effective dose, cocktail compatibility, H2S/O2 scavenger sizing, demulsifier vs oil-in-water spec, and chemical root-cause of a deposit — load `neqsim-production-chemistry` (`neqsim.process.chemistry`) and feed it the numbers computed here. For local dry hydrocarbon gas/oil interface investigations, the existing film boundary has a default-off `setCoupledMassHeatTransferEnabled(true)` numerical option. Read `docs/fluidmechanics/InterphaseHeatMassTransfer.md` for its residual gates and limited positive-composition/finite-transport range. It is not connected to the transient `TwoFluidPipe` source. Zero liquid Reynolds number currently gives an unsupported stratified transfer coefficient and rejects; never interpret the old unit-matrix fallback as stationary-pool evaporation. Keep #4674 physical boundary/full-cycle and #4675 heat/area/diffusion qualification separate from numerical convergence. ## 1. Hydrate Analysis ### EOS Selection for Hydrate Calculations | Aqueous phase | NeqSim Class | Mixing Rule | |---------------|-------------|-------------| | Pure water / fresh water | `SystemSrkCPAstatoil` | `10` | | Water + MEG / methanol / ethanol | `SystemSrkCPAstatoil` | `10` | | **Salt brine / formation water (NaCl, CaCl2, ...)** | `SystemElectrolyteCPAstatoil` | `10` | | Pitzer salt-brine water activity | `SystemPitzer` | `"classic"` | CPA or a consistent activity-based aqueous model is needed for water–hydrocarbon hydrate modeling. **When dissolved salts / electrolytes are present, use `SystemElectrolyteCPAstatoil` or a parameterized `SystemPitzer`** so the salt thermodynamic (hydrate-suppression) effect is captured — plain `SystemSrkCPAstatoil` ignores ion activity and underestimates subcooling margin. For Pitzer hydrate onset, load `neqsim-electrolyte-systems` and read `docs/thermo/pitzer_hydrate_equilibrium.md`. Accept its hand-off of salt mole basis, dataset, explicit CO2-chloride zeta values (and K-Mg theta when both ions are present), pressure grid and operating temperature. Use the standard temperature/pressure/curve operations; the Pitzer route checks the fugacity residual and throws on failed points. Preserve the aqueous reference-state convention and guest Henry limits. Do not label onset calculations as hydrate amounts, kinetics or validated complete drilling-mud predictions. Carry forward the experimental assessment separately from convergence: the mixed-chloride high-pressure cases include errors exceeding 1 K. Do not generalize the NaCl benchmark to all salts, concentrations or pressures. ### Hydrate Formation Temperature ```java // CPA EOS required for accurate water-hydrocarbon modeling SystemInterface fluid = new SystemSrkCPAstatoil(273.15 + 10, 100.0); fluid.addComponent("methane", 0.80); fluid.addComponent("ethane", 0.05); fluid.addComponent("propane", 0.03); fluid.addComponent("CO2", 0.02); fluid.addComponent("water", 0.10); fluid.setMixingRule(10); // CPA mixing rule fluid.setMultiPhaseCheck(true); fluid.setHydrateCheck(true); ThermodynamicOperations ops = new ThermodynamicOperations(fluid); ops.hydrateFormationTemperature(); double hydrateT_C = fluid.getTemperature() - 273.15; ``` `setHydrateCheck(true)` is mandatory: without it `hydrateFormationTemperature()` fails (no hydrate phase) and any wrapper that swallows the exception reports NaN. The fluid must contain `water`. `HydrateRiskMapper` (and MCP `runFlowAssurance` `hydrateRiskMap`) now sets the flag itself and returns `RiskLevel.UNKNOWN` / `RESULT_NOT_AVAILABLE` with `failureReasons` when no equilibrium temperature exists — never treat an unavailable hydrate temperature as safe. ### Hydrate Equilibrium Curve (Multiple Pressures) ```java // Calculate hydrate T at several pressures for the full curve double[] pressures = {20, 40, 60, 80, 100, 120, 150, 200}; double[] hydrateTemps = new double[pressures.length]; for (int i = 0; i < pressures.length; i++) { SystemInterface testFluid = fluid.clone(); testFluid.setPressure(pressures[i]); ThermodynamicOperations testOps = new ThermodynamicOperations(testFluid); testOps.hydrateFormationTemperature(); hydrateTemps[i] = testFluid.getTemperature() - 273.15; } ``` ### Hydrate Inhibitor Dosing (MEG) ```java // Add MEG to suppress hydrate formation temperature SystemInterface inhibitedFluid = new SystemSrkCPAstatoil(273.15 + 4, 100.0); inhibitedFluid.addComponent("methane", 0.80); inhibitedFluid.addComponent("water", 0.15); // 25 wt% MEG in the water + MEG phase: n_MEG = n_water * 18.015 * 0.25 / 0.75 / 62.07 = 0.0145 mol // (0.05 mol MEG per 0.15 mol water would be 53 wt%: amounts are MOLES, never weight percentages) inhibitedFluid.addComponent("MEG", 0.0145); inhibitedFluid.setMixingRule(10); inhibitedFluid.setMultiPhaseCheck(true); inhibitedFluid.setHydrateCheck(true); ThermodynamicOperations ops = new ThermodynamicOperations(inhibitedFluid); ops.hydrateFormationTemperature(); double inhibitedHydrateT = inhibitedFluid.getTemperature() - 273.15; // Compare with uninhibited to get subcooling margin ``` For the **injection rate** that delivers a required wt% in the water phase (including purity and lean/rich MEG bookkeeping), use `neqsim.process.chemistry.hydrate.ThermodynamicHydrateInhibitorPerformance` — see `neqsim-production-chemistry`. Use the CPA curve above for the design concentration and the chemistry model for the rate. ### Salt-Inhibited Hydrate (Formation Water / Brine) ```java // Dissolved salts depress the hydrate temperature — use the electrolyte CPA model SystemInterface brineGas = new SystemElectrolyteCPAstatoil(273.15 + 4, 100.0); brineGas.addComponent("methane", 0.80); brineGas.addComponent("water", 0.18); brineGas.addComponent("Na+", 0.01); // dissociated NaCl brineGas.addComponent("Cl-", 0.01); brineGas.setMixingRule(10); brineGas.setMultiPhaseCheck(true); brineGas.setHydrateCheck(true); ThermodynamicOperations ops = new ThermodynamicOperations(brineGas); ops.hydrateFormationTemperature(); double brineHydrateT = brineGas.getTemperature() - 273.15; // SystemSrkCPAstatoil would miss the salt suppression — always use electrolyte CPA with ions ``` ### MEG Concentration Sweep ```java // Find required MEG concentration for target subcooling double[] megWtPct = {0, 10, 20, 30, 40, 50}; for (double wt : megWtPct) { // wt % MEG is a MASS fraction of the water + MEG mixture: convert to moles (M_water 18.015, M_MEG 62.07 g/mol) double waterMol = 0.20 * (1.0 - wt / 100.0) / 18.015; double megMol = 0.20 * (wt / 100.0) / 62.07; double waterFrac = waterMol / (waterMol + megMol) * 0.20; double megFrac = megMol / (waterMol + megMol) * 0.20; SystemInterface testFluid = new SystemSrkCPAstatoil(273.15, 100.0); testFluid.addComponent("methane", 0.80); testFluid.addComponent("water", waterFrac); testFluid.addComponent("MEG", megFrac); testFluid.setMixingRule(10); testFluid.setHydrateCheck(true); ThermodynamicOperations testOps = new ThermodynamicOperations(testFluid); testOps.hydrateFormationTemperature(); // Record hydrate T vs MEG concentration } ``` **Sweep gotchas (found building an HPHT tie-back, Fogelberg VPbo task):** `hydrateFormationTemperature()` with a rich gas condensate (C7+ pseudo-components) plus water and MEG at 40 wt % MEG did not return (CPA hydrate solver loop, no exception, no timeout). Run every MEG/pressure point of a sweep in a watchdog thread or subprocess with a hard time limit and keep the sweep to at most 30 wt % MEG. If a 40-50 wt % row is still needed, a linear extrapolation (about -4.5 K per 10 wt % at 30-400 bara) is an UNVALIDATED screening number: label it as extrapolated, never use it for a pass/fail margin, and do not let the whole script hang for it. Write the intermediate JSON before the hydrate loop so a kill does not lose the fluid and CVD results. For flowline hydraulics with `PipeBeggsAndBrills` a trial inlet pressure that is too low throws `HydraulicDomainException: Non-positive pipeline pressure` instead of returning a low outlet pressure: catch it inside the chain function and return outlet 0 (infeasible). Letting it propagate out of a bisection silently turns a whole row of the inlet-pressure table into NaN. `ThermodynamicOperations.hydrateFormationTemperature()` is `void`: the answer is left in the fluid temperature, so read `fluid.getTemperature() - 273.15` after the call (`float(ops.hydrateFormationTemperature())` fails with `NoneType`; found in the Mistral Nord VPbo task). A wellstream built with `SystemSrkEos` plus `setHydrateCheck(true)` also under-predicts the hydrate temperature (methane benchmark about -8 K): rebuild the composition in `SystemSrkCPAstatoil` (mixing rule 10) and benchmark methane at 43/76/140 bara against 5/10/15 C before using the numbers (CPA gives -0.03/+0.33/+0.58 K). To benchmark `PipeBeggsAndBrills` against Darcy-Weisbach use a dry single-phase gas (pure methane, 60 C, `setHeatTransferCoefficient` large): the deviation is then 0.2-0.4 %. A lean-gas condensate line cooled to seabed temperature differs by 25-50 % because the liquid holdup is real, so that difference is not a defect. Gas-condensate saturation pressure (Tyrihans cellar task): a bubble-point search on a lean gas-condensate fluid returns a wrong value because the fluid has a dew point; take the saturation pressure of GOR above about 1500 Sm3/Sm3 fluids from the CVD first step (dew point) and record it as a limitation. `hydrateFormationTemperature()` on a GOR 250 oil fluid with 3 mol % water at 200 bara did not converge and left the temperature unchanged: check that the returned temperature differs from the start temperature before reporting it and report `None` as a gap, not as a hydrate-free result. HPHT wellstream hydrates (Erlend / Kristin study): the CPA hydrate solver also stalls (no exception) with the C7+ TBP/plus pseudo-components at 50 bara and 1 mol % water, even without MEG. Rebuild the CPA mixture from the light components only (C1-C6, N2, CO2, water, renormalised), as C7+ barely moves the hydrate temperature; a Kristin-type gas (CGR 300 Sm3/MSm3) with 1 mol % water gave 17.2 / 21.2 / 26.6 / 31.9 C at 50 / 100 / 300 / 600 bara. Do not iterate `PipeBeggsAndBrills` inlet pressure by a fixed point `p_in += p_out_target - p_out`: it stalls at high pressure drop (unconverged tables looked like data). Use a secant solve, treat a `HydraulicDomainException` as outlet pressure 0, store an `ok` flag and exclude `ok == False` rows when interpolating; beyond the last converged rate extend the table with dp proportional to q^2 instead of the last slope. ### MEG/Water Film Conditioned by Dry Gas (pipeline drying after glycol swabbing) Question pattern: "what MEG:H2O ratio does a residual film reach under dry export gas, and why is the gas above the dew-point spec?" Worked task: `2026-09-29_steady_state_megh2o_ratio_during_dry_gas_drying_of_a_meg`. - **Direction:** a 99 wt% MEG film is *drier* than the plateau (about 90 wt% at 6 C, 140 bara), so the gas is the wetter side and the film **absorbs** water. It "dries" only if it starts wetter than the plateau. - **Equilibrium curve:** two-phase `SystemSrkCPAstatoil` TPflashes over an MEG sweep give gas water *and MEG* content versus film composition (gas composition depends on the liquid composition, T and P only). Report film composition on a **gas-free** basis, MEG/(MEG+water); dissolved CO2/CH4 is ~0.8 wt%. MEG is not strictly non-volatile: about 5 ppm wt in the gas at 140 bara. - **Dew-point spec fixes only the water mole fraction** y_in, not the pipe condition. Hand chain: water fugacity continuity, `a_w = y_in * phiV_w(T,P) * P / f0_w(T,P)`, with `f0_w` = IAPWS vapour pressure x Poynting; `a_w` from the CPA liquid fugacity coefficient divided by the pure-water coefficient. Use binary (gas-free) mole fractions when fitting `ln gamma_w` or the fit mis-predicts at high MEG. - **Plateau offset by mass balance:** with a stationary film the gas leaves carrying water and MEG in the film's own ratio, so `(y_out - y_in)/y_in = r * y_MEG / y_in` (about 1.7 %), independent of `K_G` at large NTU. The film inlet zone is stripped of MEG first (a film-free zone grows at ~200 m/day in a 0.4 m, 60 kg/s example). - **Flash per time step is backward Euler:** unconditionally stable, plateau independent of step size; an explicit coding is stable only below `2 / (d y*_H2O / d r)` kg gas per kg film MEG per step. - **Dew point is logarithmic** (~6 % in water content per K at these conditions) and, for CPA, nearly pressure independent at 70-140 bara: reading the same gas as a dew point at pipe pressure adds ~0.9 K. - **Basis traps:** CPA liquid-water dew point is a supercooled-liquid reference below freezing; ISO 18453 / GERG-water uses an ice reference below 273.16 K. These are different phase boundaries. For GERG-water, use `SystemGERGwaterEos`, `setMixingRule(8)`, and a `ThermodynamicOperations` instance's `waterDewPointTemperatureFlash()`; follow the ISO 18453 execution rule in `neqsim-standards-lookup` and the [dew-point guide](../../../docs/standards/dew_point_standards.md). Recalculate outputs from the former non-convergent solver before comparing models. Neither an ideal-gas estimate nor a CPA/GERG difference alone identifies an ISO implementation error. - **Numerics:** for N >= 100 film cells use `solve_ivp(method="BDF")`; LSODA stalls on the film-exhaustion switch. Regularise `r = W/(M + delta)` so a film-free cell cannot return a spurious composition. ## 2. Wax Analysis ### Wax Appearance Temperature (WAT) ```java // Oil system with C7+ fractions for wax prediction SystemInterface oil = new SystemSrkEos(273.15 + 60, 50.0); oil.addComponent("methane", 0.30); oil.addComponent("ethane", 0.10); oil.addTBPfraction("C7", 0.10, 92.0 / 1000, 0.727); oil.addTBPfraction("C10", 0.15, 134.0 / 1000, 0.78); oil.addTBPfraction("C15", 0.15, 206.0 / 1000, 0.83); oil.addPlusFraction("C20", 0.20, 350.0 / 1000, 0.88); oil.getCharacterization().setWaxModel(true); oil.getCharacterization().characterisePlusFraction(); oil.setMixingRule("classic"); ThermodynamicOperations ops = new ThermodynamicOperations(oil); ops.calcWAT(); double wat_C = oil.getTemperature() - 273.15; ``` ### Wax Fraction vs Temperature (PVT Simulation) ```java import neqsim.pvtsimulation.simulation.WaxFractionSim; WaxFractionSim waxSim = new WaxFractionSim(oil); waxSim.setTemperatures(new double[]{333.15, 313.15, 293.15, 273.15}); waxSim.run(); double[] waxFractions = waxSim.getWaxFraction();
عرض على GitHub
ملف SKILL.md هذا كبير جدا، لذلك يعرض SkillsMP القسم الاول فقط هنا. عرض على GitHub