Source profileQuality 91/100

equinor/neqsim/.github/skills/neqsim-production-optimization/SKILL.md

neqsim-production-optimization

Production optimization, bottleneck analysis, decline modeling, decline-curve history matching (Arps + Duong), reservoir material balance surveillance (OGIP/OOIP, drive indices, aquifer influx), and IOR/EOR screening with NeqSim. USE WHEN: optimizing production rates, identifying facility bottlenecks, forecasting production profiles, fitting decline curves to production history, estimating reserves from pressure/production data, analyzing gas lift allocation, evaluating IOR/EOR options, or runni

Source repository stars
147
Declared platforms
0
Static risk flags
0
Last source update
2026-08-28
Source checked
2026-08-28

Decision brief

What it does: where it fits

Reference for production forecasting, optimization, bottleneck analysis, and improved recovery using NeqSim's field development and process simulation tools.

Best for

  • USE WHEN: optimizing production rates, identifying facility bottlenecks, forecasting production profiles, fitting decline curves to production history, estimating reserves from pressure/production data, analyzing gas li…

Not for

  • Tasks that require unconfirmed production actions or broad system permissions.
  • Environments where the pinned source and install steps cannot be inspected.

Compatibility matrix

Platform support, with evidence labels

PlatformStatusEvidenceWhat to check
CodexNot declaredNo explicit evidencePortability before use
Claude CodeNot declaredNo explicit evidencePortability before use
CursorNot declaredNo explicit evidencePortability before use
Gemini CLINot declaredNo explicit evidencePortability before use
Open the compatibility checker

Installation

Inspect first. Install second.

The source command is displayed only when detected. A safe inspection prompt is always available so your agent can explain every action before execution.

Source-detected install commandSource
npx skills add https://github.com/equinor/neqsim --skill ".github/skills/neqsim-production-optimization"
Safe inspection promptEditorial

Inspect the Agent Skill "neqsim-production-optimization" from https://github.com/equinor/neqsim/blob/9e4e36d4b6a59404ac9aa629740fbc312610d3c8/.github/skills/neqsim-production-optimization/SKILL.md at commit 9e4e36d4b6a59404ac9aa629740fbc312610d3c8. List every install step, command, network request, credential, file read/write, external action, and rollback step. Explain whether it fits my task. Do not install or execute anything until I approve.

Workflow

What the source asks the agent to do

  1. 01

    Production Profile Modeling

    Review the “Production Profile Modeling” section in the pinned source before continuing.

    Review and apply the “Production Profile Modeling” source section.
  2. 02

    Decline Curve Types

    Review the “Decline Curve Types” section in the pinned source before continuing.

    Review and apply the “Decline Curve Types” source section.
  3. 03

    Production Profile Generation

    Review the “Production Profile Generation” section in the pinned source before continuing.

    Review and apply the “Production Profile Generation” source section.
  4. 04

    Multi-Well Drill Schedule

    Review the “Multi-Well Drill Schedule” section in the pinned source before continuing.

    Review and apply the “Multi-Well Drill Schedule” source section.
  5. 05

    Decline Curve Fitting & History Matching (DeclineCurveAnalysis)

    neqsim.pvtsimulation.util.DeclineCurveAnalysis is a static, unit-agnostic Arps + Duong decline toolkit. Besides the forward rate(...), cumulativeProduction(...), eur(...) and forecast(...) methods it now least-squares fits decline parameters to a measured rate-time history — the…

    neqsim.pvtsimulation.util.DeclineCurveAnalysis is a static, unit-agnostic Arps + Duong decline toolkit. Besides the forward rate(...), cumulativeProduction(...), eur(...) and forecast(...) methods it now least-squares f…The fitArps overloads grid-search the exponent b over [0, 1] (coarse then fine), analytically solving qi and di for each candidate by linearising in rate space (ln q vs t for b≈0; q^-b vs t otherwise). Use the windowed…For fracture-dominated tight-gas and shale wells the Arps model over-estimates reserves. The Duong (2011) model is included:

Permission review

Static risk signals and limitations

No configured static risk pattern was detected

This is not proof of safety. Runtime behavior, indirect dependencies, and hidden external systems are outside the static scan.

Evidence record

Why each signal appears

EvidenceSourceComputedTestedEditorial
SignalValueEvidence typeMeaning
Quality score91/100ComputedDocumentation, specificity, maintenance, and trust rules
Repository stars147SourceRepository attention, not individual Skill quality
Compatibility0 platformsSourceDeclared in the catalog source record
Usage guideautomated source guideEditorialGenerated or reviewed according to the visible evidence level

Pinned source

Provenance and original SKILL.md

Repository
equinor/neqsim
Skill path
.github/skills/neqsim-production-optimization/SKILL.md
Commit
9e4e36d4b6a59404ac9aa629740fbc312610d3c8
License
Apache-2.0
Collected
2026-08-28
Default branch
master
View the original SKILL.md

NeqSim Production Optimization Skill

Reference for production forecasting, optimization, bottleneck analysis, and improved recovery using NeqSim's field development and process simulation tools.


Production Profile Modeling

Decline Curve Types

ModelFormulaUse Case
Exponential$q(t) = q_i e^{-Dt}$Gas wells, constant decline
Hyperbolic$q(t) = q_i (1 + bDt)^{-1/b}$Oil wells, b = 0.3-0.8
Harmonic$q(t) = q_i / (1 + Dt)$Hyperbolic with b = 1
Plateau + exponentialBuild-up → plateau → declineConstrained by facility

Production Profile Generation

ProductionProfile profile = new ProductionProfile();

// Method 1: Arps decline
profile.setDeclineModel(ProductionProfile.DeclineModel.EXPONENTIAL);
profile.setPeakRate(25000.0);         // boe/d
profile.setDeclineRate(0.15);         // 15% per year (Di)
profile.setPlateauDuration(3);        // years at peak
profile.setProjectLife(25);           // total years
double[] rates = profile.generateProfile();

// Method 2: Hyperbolic with b-factor
profile.setDeclineModel(ProductionProfile.DeclineModel.HYPERBOLIC);
profile.setHyperbolicB(0.5);

// Method 3: Resource-constrained
ProductionProfileGenerator gen = new ProductionProfileGenerator();
gen.setResourceVolume(100.0);         // MMboe recoverable
gen.setRecoveryFactor(0.55);
gen.setPeakRate(25000.0);
gen.setBuildUpYears(2);
gen.setPlateauYears(5);
gen.generate();

Multi-Well Drill Schedule

FieldProductionScheduler scheduler = new FieldProductionScheduler();
scheduler.setNumberOfWells(8);
scheduler.setDrillingInterval(6);      // months between wells
scheduler.setFirstOil(2027);
scheduler.setWellProductivity(4000.0); // initial boe/d/well
scheduler.setDeclineRate(0.12);        // 12%/year per well
scheduler.setFacilityCapacity(28000.0);// boe/d plateau constraint

double[][] schedule = scheduler.generateSchedule(25);
// schedule[year][0] = oil rate, [1] = gas rate, [2] = water rate

Decline Curve Fitting & History Matching (DeclineCurveAnalysis)

neqsim.pvtsimulation.util.DeclineCurveAnalysis is a static, unit-agnostic Arps + Duong decline toolkit. Besides the forward rate(...), cumulativeProduction(...), eur(...) and forecast(...) methods it now least-squares fits decline parameters to a measured rate-time history — the inverse (surveillance) direction used to estimate remaining reserves and EUR directly from production data. Times are in days; rates keep whatever consistent unit you supply.

import java.util.Map;
import neqsim.pvtsimulation.util.DeclineCurveAnalysis;

// t[] in days, q[] in bbl/d (or Sm3/d, MMscf/d — unit-agnostic)
Map<String, Double> fit = DeclineCurveAnalysis.fitArps(t, q);
double qi = fit.get("qi");        // initial rate
double di = fit.get("di");        // nominal decline (1/day)
double b = fit.get("b");          // Arps exponent (grid-searched 0..1)
double r2 = fit.get("rSquared");  // goodness of fit

// EUR to an economic-limit rate straight from the fit
double eur = DeclineCurveAnalysis.eurFromFit(fit, 50.0);   // rate-unit * days

// Windowed fit — exclude early transient / cleanup points (indices 0..2 here)
Map<String, Double> fitW = DeclineCurveAnalysis.fitArps(t, q, 3, t.length - 1);

The fitArps overloads grid-search the exponent b over [0, 1] (coarse then fine), analytically solving qi and di for each candidate by linearising in rate space (ln q vs t for b≈0; q^-b vs t otherwise). Use the windowed overload to fit only the established boundary-dominated decline.

Duong (2011) — tight / unconventional wells

For fracture-dominated tight-gas and shale wells the Arps model over-estimates reserves. The Duong (2011) model is included:

// Forward
double q = DeclineCurveAnalysis.rateDuong(q1, a, m, t);        // rate at time t
double gp = DeclineCurveAnalysis.cumulativeDuong(q1, a, m, t); // cumulative

// Fit q1, a, m to a rate history (log-log q/Gp vs t straight line)
Map<String, Double> duong = DeclineCurveAnalysis.fitDuong(t, q);
// keys: "q1", "a", "m", "rSquared"

Model selection: fit both fitArps and fitDuong, compare rSquared, and prefer Duong when the well is in transient linear (fracture-dominated) flow.


Reservoir Material Balance & Surveillance (inverse tank models)

neqsim.pvtsimulation.reservoirproperties.materialbalance regresses original hydrocarbon in place, drive mechanism and aquifer support directly from a measured pressure-vs-cumulative-production history. These "inverse" tank models complement the forward depletion model (SimpleReservoir) — use them for reserves surveillance and drive diagnosis. Pressures are in bara, temperatures in Kelvin; cumulative volumes keep any consistent surface unit and the returned in-place volume is in the same unit.

Gas — P/Z line, Cole plot, Havlena-Odeh (GasMaterialBalance)

import neqsim.pvtsimulation.reservoirproperties.materialbalance.GasMaterialBalance;

// P/Z straight line → OGIP (supply Z, or let it compute Z from Sutton + Hall-Yarborough)
GasMaterialBalance.Result r = GasMaterialBalance.fitVolumetric(pressure, z, gp);
double ogip = r.getOgip();          // x-intercept where p/Z = 0
double piZi = r.getPiOverZi();      // initial p/Z intercept (bara)
double r2 = r.getRSquared();

// Compute Z internally (Sutton pseudo-criticals + Hall-Yarborough)
GasMaterialBalance.Result r2fit = GasMaterialBalance.fitVolumetric(pressure, gp, tempK, gasGravity);

// Cole plot — aquifer diagnostic (flat = volumetric depletion, rising = water influx)
double[][] cole = GasMaterialBalance.colePlot(pressure, z, gp, tempK); // [0]=Gp, [1]=F/Eg

// Havlena-Odeh with a supplied cumulative water influx We
GasMaterialBalance.Result rHO = GasMaterialBalance.fitHavlenaOdeh(pressure, z, gp, we, tempK);

Oil — Havlena-Odeh, gas-cap ratio, drive indices (OilMaterialBalance)

import neqsim.pvtsimulation.reservoirproperties.materialbalance.OilMaterialBalance;

// Build the F / Eo / Eg / Efw terms from black-oil PVT, then regress:
OilMaterialBalance.Result dep = OilMaterialBalance.fitDepletionDrive(f, eo);        // OOIP (no gas cap / aquifer)
OilMaterialBalance.Result gc = OilMaterialBalance.fitGasCapDrive(f, eo, eg);        // OOIP + gas-cap ratio m
OilMaterialBalance.Result wd = OilMaterialBalance.fitWaterDrive(f, eo, we, bw);     // OOIP with known We

// Pirson fractional drive indices {DDI, SDI, WDI, EDI} (sum ≈ 1)
double[] di = OilMaterialBalance.driveIndices(n, m, eoTerm, egTerm, efwTerm, we, bw, fTerm);

Aquifer influx — Van Everdingen-Hurst / Carter-Tracy (VanEverdingenHurstAquifer)

import neqsim.pvtsimulation.reservoirproperties.materialbalance.VanEverdingenHurstAquifer;

double u = VanEverdingenHurstAquifer.aquiferConstant(porosity, ct, thickness, radius, angleDeg);
double[] we = VanEverdingenHurstAquifer.cumulativeInfluxCarterTracy(tD, deltaP, u, reD); // reservoir m3
String aqutab = VanEverdingenHurstAquifer.exportAqutab(tD, reD);  // ECLIPSE AQUTAB include table

The We array feeds the aquifer term of GasMaterialBalance.fitHavlenaOdeh / OilMaterialBalance.fitWaterDrive. Use reD = Double.POSITIVE_INFINITY for an infinite-acting aquifer or a finite reD for a bounded one.

Workflow: (1) diagnose drive with the Cole plot / drive indices, (2) if water drive, build We with Carter-Tracy, (3) regress OGIP/OOIP with the matching fit* method, (4) cross-check reserves against the DeclineCurveAnalysis EUR.


Facility Bottleneck Analysis

Identifying Constraints

BottleneckAnalyzer analyzer = new BottleneckAnalyzer(processSystem);
analyzer.setReservoirDecline(reservoirModel);
analyzer.setRateRange(10000, 60000, 5000);  // min, max, step (boe/d)

Map<String, Double> bottlenecks = analyzer.findBottlenecks();
// Returns: {"HP Separator": 35000, "Gas Compressor": 28000,
//           "Export Pump": 40000, "Water Treatment": 45000}
// Bottleneck = Gas Compressor at 28,000 boe/d

Facility Capacity Over Time

FacilityCapacity capacity = new FacilityCapacity();
capacity.setEquipment("HP Separator", 35000.0);    // boe/d
capacity.setEquipment("Gas Compressor", 28000.0);
capacity.setEquipment("Export Pump", 40000.0);
capacity.setEquipment("Water Treatment", 45000.0);

// Apply to production profile
double[] constrainedProfile = capacity.constrain(unconstrained);
String bottleneck = capacity.getActiveBottleneck(year);

Production Allocation

Multi-Field to Single Facility

ProductionAllocator allocator = new ProductionAllocator();
allocator.addField("Field A", fieldAProfile, 0.60);  // priority weight
allocator.addField("Field B", fieldBProfile, 0.30);
allocator.addField("Field C", fieldCProfile, 0.10);
allocator.setFacilityCapacity(50000.0);               // boe/d

Map<String, double[]> allocation = allocator.allocate();
// Returns constrained profiles per field

Network Optimization

Multi-Well Gathering System

NetworkSolver network = new NetworkSolver("Production Network");
network.addWell(well1, 3.0);    // well, flowline length (km)
network.addWell(well2, 5.5);
network.addWell(well3, 8.0);
network.addWell(well4, 4.2);

// Mode 1: Fixed manifold pressure → find well rates
network.setSolutionMode(SolutionMode.FIXED_MANIFOLD_PRESSURE);
network.setManifoldPressure(60.0);  // bara
NetworkResult result = network.solve();

for (String wellName : result.getWellNames()) {
    double rate = result.getWellRate(wellName);     // Sm3/d
    double whp = result.getWellheadPressure(wellName); // bara
}

// Mode 2: Fixed total rate → find required manifold pressure
network.setSolutionMode(SolutionMode.FIXED_TOTAL_RATE);
network.setTargetTotalRate(50000.0);  // Sm3/d
result = network.solve();
double requiredManifoldP = result.getManifoldPressure();

LoopedPipeNetwork (Advanced)

Full NR-GGA production network solver with IPR, chokes, tubing VLP, Beggs-Brill multiphase, compressors, artificial lift, water/sand/corrosion/emissions:

LoopedPipeNetwork net = new LoopedPipeNetwork("Gathering");
net.setFluidTemplate(gas);
net.setSolverType(LoopedPipeNetwork.SolverType.NEWTON_RAPHSON);
net.setMaxIterations(500);
net.setTolerance(500.0);

// Wells with IPR
net.addSourceNode("R1", 230.0, 0.0);
net.addJunctionNode("MF1");
net.addWellIPR("R1", "MF1", "W1", 5e-13, true);

// Artificial lift
net.setGasLift("W1", 500.0);             // kg/hr
net.setESP("W2", 80.0, 0.55);            // kW, efficiency

// Water, sand, corrosion tracking
net.setWaterCut("W1", 0.15);
net.setSandRate("W1", 3.0);              // kg/hr
net.setCorrosiveGas("trunk", 0.035, 0.002);  // CO2, H2S mol frac
net.setCorrosionModel("trunk", "NORSOK");     // NORSOK M-506

// GHG emissions
net.setCO2EmissionFactor(2.75);
net.setMethaneSlipFactor(0.02);

net.run();

// Post-run analysis
Map<String, double[]> sand = net.calculateSandTransport();
Map<String, double[]> corr = net.calculateCorrosion();
Map<String, double[]> em = net.calculateEmissions();
double annualCO2 = net.getAnnualCO2EmissionsTonnes();

See production_well_networks.md for full API documentation of all features.


Gas Lift Optimization

Single Well

GasLiftCalculator glCalc = new GasLiftCalculator();
glCalc.setWellDepth(3000.0);          // m
glCalc.setReservoirPressure(250.0);   // bara
glCalc.setProductionRate(5000.0);     // boe/d
glCalc.setGLR(500.0);                // Sm3/Sm3
glCalc.setInjectionPressure(150.0);   // bara

double optimalGLR = glCalc.calculateOptimalGLR();
double gasRate = glCalc.calculateInjectionRate();  // Sm3/d

Multi-Well Allocation

GasLiftOptimizer optimizer = new GasLiftOptimizer();
optimizer.addWell("P1", well1, glCalc1);
optimizer.addWell("P2", well2, glCalc2);
optimizer.addWell("P3", well3, glCalc3);
optimizer.setTotalGasAvailable(500000.0);  // Sm3/d field gas supply

Map<String, Double> allocation = optimizer.optimize();
// Returns optimal gas injection rate per well
double totalOilGain = optimizer.getTotalOilGain();

Choke + Lift-Gas Co-Optimization with Facility Constraints (strupe/øke lists)

When the decision is which wells to choke back or open up under several shared facility ceilings at once (gas handling, produced-water/PWRI, and the lift-gas budget) — the classic offshore "strupe/øke liste" — use the choke-and-gas-lift allocation stack in neqsim.process.fielddevelopment.integrated. It co-optimizes choke opening and lift-gas per well, honours discrete on/off locks (sand, lost comms, life extension) and per-well gas ceilings, and emits an operator-ranked action list.

// NIP-1: build a per-well GLPC anchored on a rigorous WellSystem nodal solve.
//        base oil rate comes from NeqSim IPR-VLP; the lift response is fitted to a
//        well-test peak (optimumLift, peakOil) or a fractional uplift.
GasLiftPerformanceCurve curve =
    GasLiftPerformanceCurve.fromWellSystem(wellSystem, 60000.0, peakOil, 150000.0);
// or: GasLiftPerformanceCurve.fromWellSystemUplift(wellSystem, 0.25, 50000.0, 150000.0);

// NIP-2: a chokeable, gas-lifted well with bounds and operational locks.
ChokeableGasLiftWell w = new ChokeableGasLiftWell("S-24", curve)
    .setMaxChokeFraction(0.60)          // "0-60%"
    .setCurrentChokeFraction(0.0)       // current strupe setting
    .setGor(750.0).setWaterCut(0.35)    // for facility roll-up
    .setGasHandlingLimit(750_000.0);    // per-well "mye gass" ceiling
// .setForcedShut(true, "sand production");  // hard lock

// NIP-3: co-optimize choke + lift under multiple facility constraints (never throws).
ChokeAndGasLiftAllocationOptimizer opt = new ChokeAndGasLiftAllocationOptimizer()
    .addWell(w) /* ...add all wells... */
    .setLiftGasBudget(totalLiftGasSm3d)
    .setGasHandlingLimit(maxGasSm3d)     // shared compressor limit
    .setWaterHandlingLimit(maxWaterSm3d) // shared produced-water/PWRI limit
    .setObjective(ChokeAndGasLiftAllocationOptimizer.Objective.OIL);
ChokeAndGasLiftAllocationOptimizer.AllocationResult r = opt.optimize();
String json = r.toJson();                // schema-versioned

// NIP-4: turn the optimum into the ranked strupe/øke recommendation list.
StrupeOkeReport report = StrupeOkeReport.build(Arrays.asList(w /* ... */), r);
System.out.println(report.toTable());    // per well: OPEN / CHOKE_BACK / SHUT / NO_CHANGE + uplift

Screening-grade: choke is a linear deliverability scale, the facility relief is a greedy "choke back the least valuable barrels first" search. Use LoopedPipeNetwork for a rigorous coupled network solve. Distinct from GasLiftOptimizer (lift gas + compression only) and ReservoirToMarketOptimizer (choke + one throughput cap only).


Scenario Analysis

Multi-Scenario Comparison

ScenarioAnalyzer scenarios = new ScenarioAnalyzer();

// Base case
scenarios.addScenario("Base", baseEngine);

// High oil price
CashFlowEngine highPrice = baseEngine.clone();
highPrice.setOilPrice(90.0);
scenarios.addScenario("High Price", highPrice);

// Low recovery
CashFlowEngine lowRecovery = baseEngine.clone();
lowRecovery.setRecoveryFactor(0.45);
scenarios.addScenario("Low Recovery", lowRecovery);

// Accelerated drilling
CashFlowEngine accelerated = baseEngine.clone();
accelerated.setDrillingInterval(3);  // 3 months vs 6
scenarios.addScenario("Accelerated", accelerated);

Map<String, CashFlowResult> results = scenarios.runAll();
scenarios.generateComparisonTable();

IOR/EOR Screening Considerations

Water Injection (Voidage Replacement)

InjectionStrategy waterInj = InjectionStrategy.waterInjection(1.0);  // VRR = 1.0
InjectionResult result = waterInj.calculateInjection(
    reservoir, oilRate, gasRate, waterRate
);
double requiredRate = result.waterInjectionRate;   // Sm3/d
double achievedVRR = result.achievedVRR;

Gas Injection

InjectionStrategy gasInj = InjectionStrategy.gasInjection(0.8);  // VRR = 0.8
// May also use produced gas reinjection

Key IOR/EOR Methods (Screening Criteria)

MethodViscosity LimitDepth LimitAPI GravityRecovery Boost
Water flood< 150 cPAny> 15°5-30% OOIP
WAG< 10 cP> 1500 m25-50°5-15% OOIP
Polymer10-150 cP< 3000 m> 15°5-15% OOIP
Steam (SAGD)> 200 cP< 1500 m7-20°20-50% OOIP
CO2 flooding< 12 cP> 600 m> 25°8-20% OOIP
Surfactant< 35 cP< 3000 m> 20°5-15% OOIP

Emissions Tracking

EmissionsTracker emissions = new EmissionsTracker();
emissions.setProcessSystem(processSystem);
emissions.setFuelType("natural_gas");
emissions.setProductionRate(25000.0);  // boe/d

double co2Tonnes = emissions.calculateAnnualCO2();
double intensity = emissions.getCO2Intensity();  // kgCO2/boe

Detailed Emissions

DetailedEmissionsCalculator detailedCalc = new DetailedEmissionsCalculator();
detailedCalc.setGasTurbinePower(25.0);    // MW
detailedCalc.setFlareRate(5000.0);        // Sm3/d
detailedCalc.setFugitiveRate(0.001);      // fraction of throughput

Map<String, Double> breakdown = detailedCalc.calculate();
// {"turbine_CO2": ..., "flare_CO2": ..., "fugitive_CH4": ..., "total_CO2e": ...}

Energy Efficiency

EnergyEfficiencyCalculator efficiency = new EnergyEfficiencyCalculator();
efficiency.setProcessSystem(processSystem);
efficiency.setExportRate(25000.0);  // boe/d

double specificPower = efficiency.getSpecificPower();  // kW/boe
double energyEfficiency = efficiency.getEfficiency();  // %
Map<String, Double> consumers = efficiency.getPowerBreakdown();
// {"Gas Compression": 15.2, "Water Injection": 8.5, "Utilities": 3.1}

Late Life & Decommissioning

Late Life Options

StrategyNeqSim SupportKey Considerations
Infill drillingNew WellSystem + network rebalanceMarginal well economics
Water shut-offAdjust WellSystem water cutIntervention cost vs benefit
Gas lift optimizationGasLiftOptimizerDeclining reservoir pressure
Choke + lift under gas/water/lift limits (strupe/øke list)ChokeAndGasLiftAllocationOptimizer + StrupeOkeReportMulti-constraint fleet, on/off locks
Tie-back satelliteTiebackAnalyzerHost capacity utilization
EOR (CO2, polymer)InjectionStrategy + EOSFluid compatibility
Cessation of productionDecommissioningEstimatorRegulatory requirements

Decommissioning

DecommissioningEstimator decom = new DecommissioningEstimator();
decom.setNumberOfWells(6);
decom.setWellAbandonment(true);       // P&A wells
decom.setSubseaRemoval(true);         // Remove subsea equipment
decom.setPlatformRemoval(false);      // Subsea tieback — no platform
decom.setPipelineDecommissioning(true);
decom.setWaterDepth(350.0);
decom.setRegion("Norway");

double abex = decom.estimate();       // MUSD
Map<String, Double> breakdown = decom.getBreakdown();

Common Optimization Pitfalls

PitfallImpactPrevention
Optimizing wells independentlySub-optimal network, back-pressure effectsAlways use NetworkSolver for coupled optimization
Ignoring facility constraintsUnrealistic production profileApply FacilityCapacity constraints to profile
Static gas lift allocationMissed oil as reservoir depletesRe-optimize gas lift periodically as BHP declines
Ignoring water cut increaseOverstated revenue, understated OPEXModel watercut trajectory, include water treatment costs
Over-producing from best wellsPremature water/gas coningBalanced withdrawal per reservoir zone
Ignoring backpressure couplingWrong wellhead pressuresNetwork solver captures well-to-well interactions
Encoding minimum limits as design/max constraintsSafe NPSH, minimum-flow, or residence-time margins appear overloadedUse setMinValue(...) without setDesignValue(...); use a HARD constraint type for trip/infeasibility limits
Recomputing every engineering margin as design - currentMinimum limits show infinite or incorrectly signed spare capacityUse the evaluator/throughput result's minimumConstraint direction; feasible margins are current - minimum for lower limits and maximum - current for upper limits
Dropping dataSource when exporting bottlenecksInstalled, calculated, and default limits become indistinguishable to Python or AI workflowsSet provenance on each CapacityConstraint and preserve the throughput row's dataSource in ranking, recommendations, and archives
Joining plant-wide bottlenecks by unit name aloneDuplicate names in separate process areas resolve to the wrong train or areaFor ProcessModel.getUtilizationSnapshotJson(), preserve the bottleneck area and use qualifiedName (area::unit) as the stable join key
Treating every constraint as equally credible and universally applicableAI or optimization recommendations can rely on a screening/default limit outside its evidence rangeSet confidence and a validity range on CapacityConstraint; consume the propagated ThroughputCaseRow presence flags, bounds, and in-range state in Java/JSON/CSV; require review when absent/out of range, and never interpret confidence as a safety probability
Showing only the leading constraintNear-active constraints and weak evidence remain hidden from debottleneck decisionsFor a simulated case, retain EvaluationResult.getRankedCapacityConstraints() or ThroughputCaseRow.getRankedCapacityConstraints() so later runs cannot overwrite the snapshot. Use rankCapacityConstraints(model) only for direct live-model inspection. Preserve getEvidenceApplicability() beside each item, and keep confidence/applicability out of utilization order and feasibility.
Dividing a finite difference by a step removed by parameter clampingLocal production and margin sensitivities are understated near operating boundsUse the bound-aware ProcessModelSimulationEvaluator gradient/Jacobian methods. Keep FORWARD for the historical one-run-per-parameter cost or select CENTRAL for smooth interior points, and always check step-size stability before interpreting a derivative as shadow-value evidence.
Ranking debottlenecking value from one unchecked finite-difference stepTruncation error, non-converged perturbations, or regime changes look like defensible sensitivityUse estimateSensitivitiesWithQuality(...) before ranking. Retain the applied stencil/steps and every perturbation's convergence, feasibility, and error; require a justified isNumericallyStable(tolerance) result, inspect feasibility separately, and validate nearby operating points.
Joining archived sensitivity arrays back to mutable evaluator listsObjective or constraint rows can be relabelled after definition changes or later runsArchive getParameterSnapshots(), getObjectiveSnapshot(), and getConstraintSnapshots() from the same SensitivityQualityResult. Preserve indices, units, bounds, direction/type, base values/margins, and capacity origin. Do not rank unlike raw margins or derivatives without explicit engineering scaling.
Treating one globally stable sensitivity matrix as evidence that every bottleneck action is usableA failed perturbation, infeasible sample, fixed control, one-sided stencil, or unstable row/column pair can be hidden by manual joins and ad hoc filteringCall assessConstraintSensitivities(SensitivityQualificationPolicy) and retain evidence flags, rejection reasons, and diagnostics for every constraint/parameter pair. Use getAcceptedConstraintSensitivities(...) only after selecting and recording the policy. Acceptance is local numerical evidence, not scaling, active-set proof, a KKT multiplier, or engineering approval.
Comparing raw margins or declaring an active set without explicit engineering scalesUnlike units become numerically rankable by accident, stale limits are reused, and a near-boundary heuristic is mistaken for KKT evidenceCreate one positive, provenance-bearing ConstraintScale from each immutable constraint snapshot and run ConstraintActivityAnalyzer.assess(...) with a recorded dimensionless tolerance and sensitivity policy. Missing, duplicate, unitless, or identity-stale scales must fail closed. Keep VIOLATED separate from CANDIDATE_ACTIVE, require each scaled derivative's isUsable(), and do not claim ranking, shadow price, or optimizer active-set proof.
Interpolating a discrete operating choice or mutating a candidate without a restoration tokenA solver can invent an invalid line-up, target the wrong area, hide conversion resolution behind a false rejection, or leave a rejected point in the modelDefine a provenance-bearing ProcessModelOperatingAction with an area-qualified address. Enumerate getAllowedValues() for discrete actions, capture the baseline before mutation, and restore the identity-matched state after candidate validation. Keep the strict default read-back comparison unless the exact automation conversion or control tag has a known resolution; then declare it with withReadBackTolerance(absolute, relative, provenance) and retain the numeric residual/tolerance diagnostics. Capability or read-back success is not process feasibility or operating approval.
Screening a well or gathering action from a live model without rerunning and restoring the baselineA rejected candidate can leak into the next evaluation, an exact hydraulic limit can be missing, or evidence can be used outside its validity rangeConfigure a zero-parameter ProcessModelSimulationEvaluator, wrap one action with ProcessModelOperatingActionEvaluator, and bind every required hydraulic constraint by exact area/equipment/constraint identity and provenance. Require candidate convergence, finite utilization/margin, no violation, in-range evidence when a range is declared, and successful baseline restoration and reconvergence. Use separate model instances for parallel candidates.
Applying coupled well-allocation actions independently or simulating a partial vectorA later rejected write can leave earlier wells changed, shared limits can be evaluated at an impossible mixed state, and rollback evidence is lostUse one provenance-bearing ProcessModelOperatingActionSetEvaluator with unique action IDs and addresses. Require exact per-well and shared constraints. Inspect every ActionCandidateEvidence, reject any partial application, and require reverse-order restoration plus baseline reconvergence before the next candidate. Validate total/component balance and nearby monotonic constraint response; the transaction does not choose or approve the allocation.
Reducing fixed-total allocation to a score-only callback or continuing after rollback failureConstraint provenance and rejected-point evidence disappear, a shared total can drift, or later trials can start from a corrupted process stateFor continuous common-unit actions, compose the atomic action set with ProcessModelAllocationOptimizer. Declare the fixed total, seed, objective row, budget, transfer tolerance and objective tolerance provenance. Require isModelRecovered(), retain the full candidate trace, and inspect utilization-ranked constraints at the best feasible and best sampled objective points. Treat the sampled opportunity gap and transfer convergence as local search diagnostics, not production loss, global optimality, a shadow price, or approval.
Labelling normalized installed-capacity utilization or margin with RPM, kW, or a flow unitExternal solvers and AI agents can mistake a fraction for physical headroom, resample a mutable supplier, or join relief to only a selected hydraulic subsetRegister capacities with addEquipmentCapacityConstraints() and retain EvaluationResult.getInstalledEquipmentCapacityEvidence(). Treat getNormalizedUnit() as "1"; use getPhysicalUnit() only for current, applicable limit, physical margin, and required relief. Preserve qualified identity, origin, evidence status, and validity applicability.
Joining an improving rejected allocation to mutable constraint definitions or calling one sampled gap causal debottleneck valueArchived rows can be relabelled, normalized capacity margins can be mistaken for engineering-unit relief, and coupled or weak evidence can look isolatedRetain CandidateSetEvaluationResult.getObjectiveEvidence() and getConstraintEvidence(), then call ProcessModelAllocationBottleneckAnalyzer.analyze(search). Require complete recovery, inspect every hard violation and its evidence class, and keep unlike relief units separate. Treat results as sampled non-causal associations, not capacity sizing, production loss, shadow price, economics, or approval.

Frequently asked questions

What to verify before installation and use

What does the neqsim-production-optimization source document cover?

Reference for production forecasting, optimization, bottleneck analysis, and improved recovery using NeqSim's field development and process simulation tools.

How do I install neqsim-production-optimization?

The source record exposes this install command: npx skills add https://github.com/equinor/neqsim --skill ".github/skills/neqsim-production-optimization". Inspect the command and pinned source before running it.

Alternatives

Compare before choosing

Computed 10045,960

coreyhaines31/marketingskills

ab-testing

When the user wants to plan, design, or implement an A/B test or experiment, or build a growth experimentation program. Also use when the user mentions "A/B test," "split test," "experiment," "test this change," "variant copy," "multivariate test," "hypothesis," "should I test this," "which version is better," "test two versions," "statistical significance," "how long should I run this test," "growth experiments," "experiment velocity," "experiment backlog," "ICE score," "experimentation program

Computed 10045,960

coreyhaines31/marketingskills

churn-prevention

When the user wants to reduce churn, build cancellation flows, set up save offers, recover failed payments, or implement retention strategies. Also use when the user mentions 'churn,' 'cancel flow,' 'offboarding,' 'save offer,' 'dunning,' 'failed payment recovery,' 'win-back,' 'retention,' 'exit survey,' 'pause subscription,' 'involuntary churn,' 'people keep canceling,' 'churn rate is too high,' 'how do I keep users,' or 'customers are leaving.' Use this whenever someone is losing subscribers o

Computed 10025,136

alirezarezvani/claude-skills

app-store-optimization

App Store Optimization (ASO) toolkit for researching keywords, analyzing competitor rankings, generating metadata suggestions, and improving app visibility on Apple App Store and Google Play Store. Use when the user asks about ASO, app store rankings, app metadata, app titles and descriptions, app store listings, app visibility, or mobile app marketing on iOS or Android. Supports keyword research and scoring, competitor keyword analysis, metadata optimization, A/B test planning, launch checklist

Computed 10015,385

wanshuiyin/Auto-claude-code-research-in-sleep

citation-audit

Use it for operations and research tasks; the detail page covers purpose, installation, and practical steps.