Compressor Anti-Surge Recycle Setup
This skill explains how to protect a centrifugal compressor against surge in a
NeqSim ProcessSystem by adding a recycle (spill-back) loop. It covers the
preferred steady-state helper (AntiSurgeRecycleCalculator), the dynamic
reverse-acting PI controller (AntiSurgeController), and the application-level
supervisor (CompressorAntiSurgeApplication) that can bind directly to real
NeqSim topology objects such as a compressor, hot recycle valve, cold recycle
valve, cooler, mixer, recycle blocks, and ProcessSystem. It also explains how
to auto-generate a compressor chart with surge and stonewall curves when no
vendor chart is available, because every anti-surge option needs a surge limit
to act against.
The pure-Python helper (AntiSurgeRecycleModel) is an educational planning aid
that mirrors NeqSim's proportional anti-surge step so an agent can pre-estimate
the recycle flow and decide whether a chart must be generated first. Real
control design must use the validated NeqSim equipment classes below and a
qualified rotating-equipment review (API 617 / API 692).
When to Use
Use this skill when:
- A NeqSim compressor operating point can fall to the left of its surge line at low throughput (turndown, start-up, trips) and needs recycle protection.
- You must build the anti-surge recycle topology (surge curve, recycle stream,
discharge splitter or recycle branch, anti-surge valve,
Recycle, and optional cooler/mixer). - You need an executable dynamic application model where
CompressorAntiSurgeApplicationwrites hot/cold recycle valve openings and optional compressor speed runback to real NeqSim units. - No vendor compressor chart is provided and a chart with surge and stonewall curves must be generated from the compressor's design point.
- You want a screening estimate of the recycle flow required to keep the compressor off surge before running the full simulation.
Do not use this skill as a substitute for vendor performance maps, anti-surge controller tuning, dynamic surge/transient analysis, or rotating-equipment design review.
Inputs
- Compressor inlet (suction) volumetric flow at the operating point (m3/h).
- Surge-limit flow at the operating head and speed (m3/h). When no vendor chart is available, this comes from the generated surge curve.
- Whether a vendor compressor chart is provided (
chart_provided). - Existing recycle flow, if any (m3/h).
- For chart generation: a design speed, the number of speed lines, and optionally impeller diameter / number of stages for advanced corrections.
Outputs
needs_chart_generation— whether a chart must be generated before control.in_surge— whether the operating point is at or below the surge flow.surge_margin_fraction—(inlet_flow - surge_flow) / surge_flow.recommended_recycle_flow— screening recycle flow to add at suction (m3/h).total_suction_flow— inlet flow plus recommended recycle (m3/h).recycle_warning—ok,recycle, orsurge.- Assumptions and limitations.
Engineering Method
A centrifugal compressor surges when the inlet volumetric flow drops below the surge flow at the current head/speed. Anti-surge control opens a recycle line from discharge back to suction to keep the total suction flow above the surge limit plus a margin.
For steady-state recycle sizing and initialization, prefer
AntiSurgeRecycleCalculator for a charted compressor. It runs the compressor,
checks natural inlet flow against the surge-control line, and iterates a cooled
recycle stream until the target distance-to-surge margin is met. Use the older
splitter-based Calculator / AntiSurgeCalculator pattern only when you need
to reproduce an existing flowsheet that already uses a discharge splitter.
The legacy splitter-based topology is:
- A surge curve on the compressor chart provides the surge flow versus head.
- A low-flow recycle stream is added into the compressor suction.
- A splitter on the compressor discharge creates a forward branch
(
getSplitStream(0)) and a recycle branch (getSplitStream(1)). - An anti-surge
Calculator(legacy name-prefix API) or typedAntiSurgeCalculatorreads the compressor and writes the splitter recycle flow each iteration. Internally it compares the inlet flow to the surge flow: far from surge (inlet_flow > 1.2 * surge_flow) it drives recycle to a minimum; otherwise it adds a proportional, capped step0.5 * (surge_flow - inlet_flow)to the recycle branch. - An anti-surge valve on the recycle branch drops the discharge pressure back to suction pressure.
- A
Recycleunit closes the loop, feeding the valve outlet back into the placeholder suction recycle stream.
Generating a Compressor Chart When None Is Given
The anti-surge loop needs a surge limit, so if no vendor chart exists a chart must be generated first. NeqSim builds a chart from the compressor's design operating point and automatically populates both the surge curve and the stonewall curve:
Compressor.generateCompressorChart("normal curves", numberOfSpeeds)builds a multi-speed chart whose lowest-flow points form the surge curve and whose highest-flow points form the stonewall curve.CompressorChartGeneratorgives finer control (chart type, Reynolds/Mach corrections, multistage surge correction, impeller diameter) and also returns a chart with surge and stonewall curves attached.
After generation, the surge flow at the operating head is available through
Compressor.getSurgeFlowRate() and the distance to surge through
Compressor.getDistanceToSurge().
The AntiSurgeRecycleModel mirrors step 4 so you can estimate the recycle flow
and flag whether chart generation (needs_chart_generation) is required before
wiring the loop.
Python Usage Pattern
Screening estimate of the recycle flow (no NeqSim required):
from compressor_antisurge_recycle import AntiSurgeRecycleModel
model = AntiSurgeRecycleModel()
plan = model.plan(
inlet_flow=4200.0, # m3/h at suction
surge_flow=5000.0, # m3/h surge limit at operating head
chart_provided=True,
current_recycle=0.0,
)
print(plan.recommended_recycle_flow, plan.recycle_warning)
Generate a compressor chart (with surge and stonewall curves) when none is
given, using NeqSim through the neqsim package:
from neqsim import jneqsim
# `compressor` is an existing neqsim.process.equipment.compressor.Compressor
compressor.setSpeed(8000.0) # design speed (rpm)
compressor.run() # solve the design point first
compressor.generateCompressorChart("normal curves", 5) # 5 speed lines
# Surge and stonewall curves are now populated automatically.
chart = compressor.getCompressorChart()
surge_flow = compressor.getSurgeFlowRate()
distance_to_surge = compressor.getDistanceToSurge()
Finer control with the generator (optional corrections):
from neqsim import jneqsim
generator = jneqsim.process.equipment.compressor.CompressorChartGenerator(compressor)
generator.setChartType("interpolate and extrapolate")
generator.enableAdvancedCorrections(numberOfStages) # Reynolds + Mach + multistage
chart = generator.generateCompressorChart("normal curves", 5)
compressor.setCompressorChart(chart)
Wire the anti-surge recycle loop (generic data, after a chart exists):
from neqsim import jneqsim
splitter_pkg = jneqsim.process.equipment.splitter
valve_pkg = jneqsim.process.equipment.valve
util_pkg = jneqsim.process.equipment.util
suction_pressure = compressor.getInletStream().getPressure("bara")
# 2. Low-flow placeholder recycle stream into the compressor suction.
recycle_gas = compressor.getInletStream().clone()
recycle_gas.setName("anti surge recycle gas")
recycle_gas.setFlowRate(1.0, "kg/hr")
recycle_gas.run()
process.add(recycle_gas)
# 3. Splitter on the compressor discharge: branch 0 forward, branch 1 recycle.
gas_splitter = splitter_pkg.Splitter("anti surge splitter", compressor.getOutletStream(), 2)
gas_splitter.run()
process.add(gas_splitter)
# 4. Anti-surge Calculator (name MUST start with "anti surge calculator").
anti_surge_calc = util_pkg.Calculator("anti surge calculator 1")
anti_surge_calc.addInputVariable(compressor)
anti_surge_calc.setOutputVariable(gas_splitter)
process.add(anti_surge_calc)
# 5. Anti-surge valve on the recycle branch back to suction pressure.
anti_surge_valve = valve_pkg.ThrottlingValve("anti surge valve", gas_splitter.getSplitStream(1))
anti_surge_valve.setOutletPressure(suction_pressure, "bara")
anti_surge_valve.run()
process.add(anti_surge_valve)
# 6. Recycle unit closes the loop into the placeholder suction stream.
recycle = util_pkg.Recycle("recycle anti surge")
recycle.addStream(anti_surge_valve.getOutletStream())
recycle.setOutletStream(recycle_gas)
recycle.setTolerance(1e-2)
process.add(recycle)
process.run()
The forward process continues on gas_splitter.getSplitStream(0).
Preferred steady-state helper for a charted compressor:
AntiSurgeRecycleCalculator calc = new AntiSurgeRecycleCalculator(compressor, suctionStream);
calc.setSurgeControlMargin(0.10);
calc.setRecycleCoolerTemperature(35.0, "C");
AntiSurgeRecycleCalculator.Result result = calc.solve();
Dynamic Anti-Surge Control (AntiSurgeController)
The Calculator-driven loop above is a steady-state recycle solver. For a
dynamic (transient) anti-surge response, NeqSim provides a dedicated
reverse-acting PI controller, AntiSurgeController
(neqsim.process.controllerdevice.AntiSurgeController), that reads
Compressor.getDistanceToSurge() and drives a recycle ThrottlingValve open as
the margin falls below the set point, then closes it again on recovery.
from neqsim import jneqsim
controllerdevice = jneqsim.process.controllerdevice
# `recycle_valve` is the anti-surge ThrottlingValve on the recycle branch.
asc = controllerdevice.AntiSurgeController("anti-surge", compressor, recycle_valve)
asc.setSurgeMarginSetPoint(0.10) # protect a 10% distance-to-surge margin
asc.setProportionalGain(400.0) # percent opening per unit margin error
asc.setIntegralTime(20.0) # s
asc.setOpeningRange(0.0, 100.0) # valve opening clamp (%) with anti-windup
asc.setActive(True)
recycle_valve.addController("anti-surge", asc)
Control law each transient step: error = setPoint - distanceToSurge,
integral += Kp/Ti * error * dt, opening = clamp(Kp*error + integral) with
anti-windup. A reproducible benchmark,
neqsim.process.util.scenario.AntiSurgeDynamicBenchmark, drives the real
controller against a transparent first-order gas-path surrogate
(m_next = m - disturbance*dt + authority*(opening/100)*dt) and is the preferred
way to verify or tune the control law without solver fragility.
Critical gotchas when building a full dynamic recycle flowsheet:
- A fixed-factor
Splitter(setSplitFactors([0.97, 0.03])) pins the recycle fraction in dynamic mode, so the anti-surge valve has no authority over the actual recycle flow — it can reach 100% open with no effect. Let the recycle flow be set by the valve (Cv/resistance), or keep the steady-stateCalculatorpattern. - Once the operating point crosses left of the surge line,
getDistanceToSurge()clamps at -1.0 and the steady solver cannot recover; a flowsheet driven into deep surge will not self-heal even after the inlet is reopened. Apply gradual/ramped disturbances and keep the machine off deep surge. - Aggressive proportional gain can slam the recycle valve to minimum opening,
starve a stream, and trigger an SRK flash
NaN(PhaseSrkEos:molarVolume ... NaN). Keep gains moderate.
Dynamic controller tuning and transient surge analysis still require qualified rotating-equipment review (API 617 / API 692).
Application-Level Dynamic Topology Binding
For realistic dynamic studies with coordinated pressure, speed, hot recycle, and
cold recycle behavior, use CompressorAntiSurgeApplication. It is a
deterministic supervisory scan layer that can write directly to real NeqSim
objects and then advance the bound process one transient step.
CompressorAntiSurgeApplication application = new CompressorAntiSurgeApplication("export compression");
CompressorAntiSurgeApplication.StageApplication stage = application.addStage("K-101");
CompressorAntiSurgeApplication.TopologyBinding binding = stage.bindTopology(
process,
compressor,
hotRecycleValve,
coldRecycleValve,
recycleCooler,
suctionMixer,
hotRecycle,
coldRecycle);
binding.enableSpeedControl(95.0, 25.0, 8500.0, 12500.0, 150.0);
application.setRunningMode();
application.runDynamicStep(null, 0.25);
When the scan input is null, the stage reads the bound compressor margin and
inlet flow where available, falls back to the stage design basis where needed,
writes the hot and cold recycle valve openings, applies the optional compressor
speed command/runback, and advances the bound ProcessSystem with
runTransient(). Keep Recycle blocks algebraic unless the specific class has
transient inventory support; the valve, compressor, cooler, mixer, and any
volume-capable equipment carry the dynamic response.
CompressorAntiSurgeApplication is still a simulation and advisory layer. Its
certification status remains NOT_CERTIFIED_FOR_PROTECTION; use it for
engineering studies, training, digital twins, and commissioning evidence, not as
a certified machinery-protection package.
MCP runProcess Physical Topology Contract
Use two distinct JSON surfaces deliberately:
- Compressor property
antiSurgeconfigures the compressor's embedded screening control. It does not create or certify a physical recycle path. - Root-level
antiSurgeSystemsbindsCompressorAntiSurgeApplicationto named units that already exist in the submittedprocesstopology. It never synthesizes hidden valves, coolers, mixers, or recycle blocks.
A single-area cold-recycle declaration has this shape:
{
"autoSizing": {"enabled": true},
"antiSurgeSystems": [
{
"name": "Export anti-surge",
"stages": [
{
"name": "Stage 1",
"compressor": "Comp",
"suctionMixer": "Suction Mixer",
"aftercooler": "Aftercooler",
"coldRecycleValve": "Cold ASV",
"coldRecycle": "Cold Recycle",
"recycleDesign": {
"controlMargin": 0.10,
"valvePressureDrop": 10.0,
"pipingVolume": 1.0,
"requiredResponseTime": 5.0
},
"speedControl": {
"dischargePressureSetPoint": 40.0,
"minimumSpeed": 5000.0,
"maximumSpeed": 15000.0,
"speedGain": 40.0,
"recycleRunbackRate": 80.0
}
}
]
}
]
}
The referenced names must resolve to the expected concrete types:
Compressor, Mixer, optional Cooler, ThrottlingValve, and Recycle.
At least one complete hot or cold recycle path is required. For a multi-area
ProcessModel, every system also requires an area matching a submitted area;
unqualified and unknown-area definitions return bounded per-system failures.
Every stage needs an active surge curve. Supply properties.compressorChart,
enable autoSizing, or set generateScreeningMap: true on the stage. The
response reports truthful map provenance:
submitted: chart was present in the submitted canonical process JSON.auto_sized_screening:autoSizinggenerated the chart earlier in the run.stage_generated_screening: the anti-surge stage generated the chart.
The latter two set screeningGradeMap: true. They are estimates, not vendor
maps. generatedScreeningMapCount counts all configured stages using a
screening-grade map, regardless of which generation path created it.
The response antiSurgeSystems object contains configured/failed counts,
per-stage physical binding and map provenance, optional speed-control status,
and runCommissioningChecks() evidence. Its certification status is always
NOT_CERTIFIED_FOR_PROTECTION. The canonical processDefinition preserves the
declaration, and the generated Python replays that canonical post-design JSON.
When a canonical response is replayed, its exported compressor chart is now an
explicitly submitted chart for that new request. Therefore its provenance is
submitted; replay does not generate another map. This makes JSON round trips
stable while preserving the original run's generation evidence in that run's
response.
Validation Checklist
- The compressor has a chart with an active surge curve before the loop runs;
if not, generate one and confirm
getSurgeCurve().isActive()is true. - For steady-state recycle initialization, use
AntiSurgeRecycleCalculatorwhen practical; if using the legacy splitter path, the anti-surgeCalculatorname starts with"anti surge calculator"or the typedAntiSurgeCalculatoris used. - For the legacy splitter path, the
Calculatorinput is theCompressorand the output is the dischargeSplitter. - The anti-surge valve sits on
getSplitStream(1)and drops to suction pressure. - The
Recycleoutlet stream is the placeholder suction recycle stream. - After
process.run(), the total suction flow exceeds the surge flow plus the intended margin (getDistanceToSurge()is positive). - Recycle convergence tolerance is set (for example
setTolerance(1e-2)). - For
CompressorAntiSurgeApplicationtopology binding, hot/cold recycle valves are realThrottlingValveunits, speed-control limits are bounded, andrunDynamicStep(...)is used only after the process has a converged initial state. - For MCP
runProcess, use root-levelantiSurgeSystemsonly after all named physical units are present inprocess; requireareafor every multi-area system and inspectconfiguredCount,failedCount,mapProvenance,screeningGradeMap, commissioning checks, and certification status.
Common Mistakes
- Naming the legacy calculator anything that does not start with
"anti surge calculator"— the legacy anti-surge logic then never triggers. - Wiring the anti-surge valve to the forward branch
getSplitStream(0)instead of the recycle branchgetSplitStream(1). - Running the loop without a surge curve, so there is no surge flow to compare against (generate a chart first when no vendor chart is given).
- Using a zero or negative placeholder recycle flow that the
Recyclecannot converge from; start from a small positive flow (for example 1 kg/hr). - Reading the surge flow at the wrong head or speed — the surge flow must match the operating head and speed.
- Treating the generated chart as a vendor-validated map; generated charts are estimates for modelling, not design certification.
- For dynamic studies, leaving a fixed-factor
Splitteron the recycle branch so theAntiSurgeControllervalve has no authority over the recycle flow. - Driving a dynamic recycle flowsheet straight into deep surge, where
getDistanceToSurge()clamps at -1.0 and the steady solver cannot recover.
Limitations
- Screening logic only; it does not tune an anti-surge controller or set
recycle valve
Cv, response time, or surge control line offset. - The Python helper does not perform dynamic surge, ESD, or transient recycle
analysis; for dynamic response use NeqSim's
AntiSurgeController/AntiSurgeDynamicBenchmarkunder qualified review. - Generated compressor charts are model estimates, not vendor performance maps.
- It does not replace API 617 / API 692 rotating-equipment design and review.
- Results require qualified human review before any design or operating use.
Multi-Body Compressor Trains on One Shaft (common speed)
When several compressor bodies sit on one driver shaft (a single gas turbine
or motor, often through a gearbox) they must all turn at the same speed. A
2- or 3-body recompression string is the classic case. Model it with
neqsim.process.equipment.compressor.CompressorShaft, NOT by letting each body
solve its own speed.
Degrees of freedom. A shared shaft has exactly one mechanical degree of freedom — the common speed — and exactly one controlled target: the string's final discharge pressure. Every intermediate inter-body pressure is a result, not a spec, and must be allowed to float off the charts.
| Approach | DOF accounting | Verdict |
|---|---|---|
| Fix every stage outlet pressure and set a common speed | over-constrained | ❌ non-physical |
| Adjust ONE common speed → hit the final discharge; intermediates float | 1 variable, 1 target | ✅ correct |
Pattern. Put each body in fixed-speed, chart-forward mode and iterate the one common speed until the reference (last) body hits the target discharge:
CompressorShaft = jneqsim.process.equipment.compressor.CompressorShaft
shaft = CompressorShaft("recompression shaft (single GT)")
shaft.addCompressor(body1) # LP body (lowest suction)
shaft.addCompressor(body2)
shaft.addCompressor(body3) # HP body = reference
shaft.setSpeedBounds(8000.0, 16000.0)
# re-run the whole flowsheet between speed guesses so inter-body streams,
# scrubbers and mixers update:
run_proxy = jpype.JProxy("java.lang.Runnable", dict(run=lambda: process.run()))
shaft.solveSpeed(body3, 49.0, "bara", run_proxy) # one speed -> 49 bara at HP discharge
rpm = shaft.getSpeed()
mw = shaft.getTotalPower() / 1e6
Shared pressure nodes. Where another unit ties into an interstage (e.g. a
2nd-stage separator gas that joins the recompressor between bodies), model it as
a pressure equality, not a second spec: slave that unit's pressure to the
floating interstage discharge (a setter each iteration) or drop a small adapting
valve there. This removes a DOF rather than adding one. A Mixer at the join
already resolves to the lowest inlet pressure, so a small let-down is automatic.
Fixed-/single-speed drivers. If the driver is a constant-speed motor (no
variable-speed drive) speed is not a DOF — do not iterate it. Use
shaft.runAtFixedSpeed(rpm, run_proxy): the discharge floats off the chart at
the locked speed and any pressure spec is met by anti-surge recycle, suction
throttling, or inlet guide vanes — never by moving speed. Inlet guide vanes are a
first-class fixed-speed control on Compressor:
comp.setInletGuideVaneOpening(f) (f=1 fully open) or comp.setGuideVaneAngle(deg)
closes the vanes to reduce head and efficiency and lower the surge flow (via a
configurable InletGuideVaneModel), so getDistanceToSurge() reflects the shifted
surge line — distinct from moving speed. If you have vendor IGV-position maps
(a full chart per vane position), attach a CompressorChartIGV family with
comp.setInletGuideVaneChart(family); it interpolates the positions into the active
chart at each opening (and bypasses the parametric model). Use the parametric
InletGuideVaneModel for screening / fixed-speed discharge control, and
CompressorChartIGV to supply real per-position vendor maps.
Single body. A CompressorShaft with one compressor also works: solveSpeed
just finds that one machine's speed for its discharge target. So export /
re-injection / gas-lift machines (one body each on their own shaft) use the same
API — separate shafts keep separate speeds.
Anti-surge coexists. The per-body anti-surge loops (recycle splitter, valve,
Recycle, AntiSurgeCalculator) stay attached and keep protecting each body;
they adjust recycle flow, while the shaft sets speed. Apply the shaft solve
after the charts and anti-surge are active. solveSpeed uses a bracketed
false-position (Illinois) secant — the speed↔discharge map is smooth and
monotonic (higher speed → higher discharge), so it converges superlinearly. Each
iteration re-solves the whole flowsheet, so on a large multi-train plant make the
shaft solve opt-in and solve each train's shaft in turn.
Parallel machines and multi-stage strings. Real duties often use two parallel
bodies (A/B) rather than one machine: split the feed 50/50, give each body its own
anti-surge loop, and commingle with a Mixer. Splitting one large machine into two
halves the per-machine gas load (a suction scrubber that reads ~168 % of design on
one body drops to ~80 % on two). For a multi-stage duty (e.g. re-injection),
commingle the parallel 1st-stage discharges then feed a common 2nd stage at an
interstage pressure. Route a recompression train's HP discharge back to the gas
header, not straight into the export suction.
Process-integrated control (CompressorShaftCalculator). Instead of the
external solveSpeed callback, add a CompressorShaftCalculator to the
ProcessSystem; it converges the one common speed inside process.run()
(one damped secant step per pass, like AntiSurgeCalculator) so the shaft speed
converges together with the recycles in a single run — no separate full-field
solves. Add it after the compressor bodies / anti-surge.
CompressorShaftCalculator = jneqsim.process.equipment.util.CompressorShaftCalculator
shaft = CompressorShaft("recompression shaft (single GT)")
shaft.addCompressor(body1); shaft.addCompressor(body2); shaft.addCompressor(body3)
shaftCalc = CompressorShaftCalculator("shaft speed", shaft, body3, 49.0, "bara")
shaftCalc.setSpeedBounds(8000.0, 16000.0)
process.add(shaftCalc)
process.run() # shaft speed converges with the recycles
rpm = shaftCalc.getSpeed()
Feasibility result + pressure control (eCalc-style). A single-speed string
cannot make an arbitrary pressure — the max-speed curve is a ceiling and the
min-speed curve is a floor. Both solvers saturate and flag instead of
crashing, and expose a CompressorShaft.SolveResult (read with
getLastSolveResult(), or the shortcut isFeasible()). The two speed-bound
bracket evaluations give the min-/max-achievable discharge pressures for free.
shaft.solveSpeed(body3, 49.0, "bara", run_proxy)
r = shaft.getLastSolveResult()
if not r.isFeasible():
# r.getStatus(): PRESSURE_ABOVE_MAX_SPEED / PRESSURE_BELOW_MIN_SPEED / OVER_POWER / STONEWALL / SURGE
ceiling = r.getMaxAchievablePressure() # most the string can make
# too-low target -> shed the surplus head instead of flagging infeasible:
PressureControl = jneqsim.process.equipment.compressor.CompressorShaft.PressureControl
shaft.setPressureControl(PressureControl.DOWNSTREAM_CHOKE) # or UPSTREAM_CHOKE / ASV_RECYCLE
CompressorShaftCalculator carries the same getLastSolveResult() /
isFeasible() / setPressureControl(...), so an optimizer or evaluate() loop
can gate on shaftCalc.isFeasible() directly. Downstream, Mixer.isPressureMismatch()
flags where an unmet pressure collapses a commingling node to the lowest inlet —
the signal that an upstream machine missed spec. A worked end-to-end example
(three-stage separation + shared-shaft recompression + control) is in the NeqSim
repo notebook examples/notebooks/CompressorShaft_ThreeStageSeparation.ipynb.
Related NeqSim Functionality
neqsim.process.equipment.compressor.CompressorShaft— groups several compressor bodies on one shaft at a single common speed;addCompressor(...),solveSpeed(reference, targetP, unit, runnable)(iterate one speed to the final discharge, intermediates float),runAtFixedSpeed(rpm, runnable)(constant-speed drivers),setSpeed(...),setSpeedBounds(...),getSpeed(),getTotalPower().neqsim.process.equipment.compressor.Compressor—generateCompressorChart(...),getCompressorChart(),getSurgeFlowRate(),getDistanceToSurge(),setSpeed(...).neqsim.process.equipment.compressor.CompressorChart—getSurgeCurve(),getStoneWallCurve(),generateSurgeCurve(),generateStoneWallCurve(),checkStoneWall(...).neqsim.process.equipment.compressor.CompressorChartGenerator—setChartType(...),enableAdvancedCorrections(...),generateCompressorChart(...).neqsim.process.equipment.compressor.AntiSurgeRecycleCalculator— preferred steady-state recycle helper for charted compressors (setSurgeControlMargin,setRecycleCoolerTemperature,solve).neqsim.process.equipment.compressor.CompressorAntiSurgeApplication— application-level supervisor withStageApplication.bindTopology(...),TopologyBinding.enableSpeedControl(...),scan(...), andrunDynamicStep(...)for direct writeback to real hot/cold recycle valves and compressor speed.neqsim.process.equipment.splitter.Splitter— discharge split into forward and recycle branches.neqsim.process.equipment.util.Calculator— steady-state anti-surge engine (runAntiSurgeCalc) triggered by the"anti surge calculator"name prefix.neqsim.process.controllerdevice.AntiSurgeController— dynamic reverse-acting PI controller ongetDistanceToSurge()driving a recycle valve (setSurgeMarginSetPoint,setProportionalGain,setIntegralTime,setOpeningRange,setActive).neqsim.process.util.scenario.AntiSurgeDynamicBenchmark— reproducible surrogate benchmark for verifying/tuning the dynamic control law.neqsim.process.equipment.valve.ThrottlingValve— anti-surge recycle valve.neqsim.process.equipment.util.Recycle— closes the recycle loop.
The total_suction_flow (net forward flow + recycle) computed here is the
actual compressor throughput. When you go on to compute polytropic
head/efficiency or shaft power from measured conditions, use this actual
throughput — not the metered net/export flow. Using net flow while the recycle is
open understates suction volume and power and mis-locates the operating point on
the surge map (a common error when diagnosing compressor degradation at
turndown).
In Python these classes are reachable through the neqsim package (for example
from neqsim import jneqsim).
References
- NeqSim: https://github.com/equinor/neqsim
- NeqSim Community Skills: https://github.com/equinor/neqsim-community-skills
- API Standard 617 — Axial and Centrifugal Compressors.
- API Standard 692 — Surge Control for Centrifugal Compressors.