Gas expanders recover shaft work while reducing pressure. Each example below
defines its fluid, flow, and equipment. Place its imports at file level and its
statements inside a Java method. MathAndExpanderDocumentationTest compiles and
runs the marked examples directly from this page.
Table of Contents
Overview
| Class | Purpose |
|---|---|
neqsim.process.equipment.expander.Expander |
Expansion at a specified outlet pressure and efficiency |
neqsim.process.equipment.expander.TurboExpanderCompressor |
Integrated expander/compressor with design data and speed matching |
neqsim.process.equipment.expander.MapTurboExpanderCompressor |
Integrated machine using performance maps |
neqsim.process.equipment.stream.MechanicalShaft |
Shared shaft power balance and rotational dynamics |
There are no TurboExpander or ExpanderCompressorModule classes.
Use Expander for a simple thermodynamic expansion and the integrated
classes when machine matching is required.
Expander Class
Basic Usage
new Expander(name, inlet) takes a solved inlet stream.
setOutletPressure(value, "bara") specifies absolute discharge pressure and
setIsentropicEfficiency(value) takes a fraction between zero and one.
Read temperature and pressure through getOutletStream().
Outlet Specification
The examples use outlet pressure and efficiency as independent specifications. Do not assume every inherited compressor setting is implemented by the expander’s solver. For an integrated machine with an outlet-temperature specification, see the turboexpander/compressor model.
Turboexpander
A simple turboexpansion is modeled by Expander, including expansion into
a two-phase outlet. Use a downstream Separator when the resulting phases
need separate material streams.
Shaft Coupling
For TurboExpanderCompressor, the compressor feed is supplied through
setCompressorFeedStream and the expander pressure through
setExpanderOutPressure (bara). Its design speed, efficiencies, geometry,
and maps must represent the actual machine. The
integrated-machine guide
documents that workflow.
Power Recovery
Isentropic Power
For specific enthalpies in J/kg and mass flow in kg/s, the positive magnitude of ideal recovered power is
\[P_{s}=\dot m(h_{in}-h_{out,s})\]Actual Power
\[P_{recovered}=\eta_s P_s\]Expander.getPower("kW") uses a negative value for work extracted from
the gas. Therefore, display -expander.getPower("kW") as positive recovered
power. A compressor’s consumed power is positive. Do not subtract an already
negative expander value from compressor demand and call that recovered power.
Temperature Drop
An expander and a throttling valve follow different thermodynamic paths. The comparison example below evaluates both at identical inlet and outlet pressures. Cooling depends on the fluid and conditions; the displayed trend is a result of that case, not a guarantee for every fluid.
Capacity Utilization
setRatedRecoveredPower takes kW and creates a recoveredPower constraint
based on the magnitude of expander power. Without an installed rating there
is no recovered-power rating check. Read the specific constraint for that
utilization; other constraints may still limit the machine. See the
capacity framework.
Compander Systems
For already solved equipment, MechanicalShaft.setGeneratedPower and
setConsumedPower take watts. getNetPower("kW") is positive for a surplus
and negative for a deficit. The third example performs this accounting only:
it does not change a compressor pressure or solve a speed match. Use the
integrated machine when that coupling is needed.
Examples
Example 1: Simple Expander
SRK gas at 320 K and 80 bara expands to 20 bara with 85% isentropic efficiency. The output should cool, recover work, and conserve mass.
import neqsim.thermo.system.SystemSrkEos;
import neqsim.process.equipment.stream.Stream;
import neqsim.process.equipment.expander.Expander;
SystemSrkEos gas = new SystemSrkEos(320.0, 80.0);
gas.addComponent("methane", 0.90);
gas.addComponent("ethane", 0.07);
gas.addComponent("propane", 0.03);
gas.setMixingRule("classic");
Stream feed = new Stream("HP Gas", gas);
feed.setFlowRate(50000.0, "kg/hr");
feed.run();
Expander expander = new Expander("EX-100", feed);
expander.setOutletPressure(20.0, "bara");
expander.setIsentropicEfficiency(0.85);
expander.run();
double outletTemperatureC = expander.getOutletStream().getTemperature("C");
double recoveredPowerKW = -expander.getPower("kW");
double outletMassFlow = expander.getOutletStream().getFlowRate("kg/hr");
expander.setRatedRecoveredPower(5000.0);
double powerUtilization = expander.getCapacityConstraints()
.get("recoveredPower").getUtilization();
Example 2: NGL Recovery with Turboexpander
The cooler can create liquid before expansion. This simplified equilibrium example does not qualify inlet liquid tolerance or separation internals for a real turboexpander. Include upstream separation and a machine operating envelope for an equipment study.
import neqsim.thermo.system.SystemSrkEos;
import neqsim.process.equipment.stream.Stream;
import neqsim.process.equipment.heatexchanger.Cooler;
import neqsim.process.equipment.expander.Expander;
import neqsim.process.equipment.separator.Separator;
SystemSrkEos richGas = new SystemSrkEos(300.0, 70.0);
richGas.addComponent("nitrogen", 0.02);
richGas.addComponent("methane", 0.75);
richGas.addComponent("ethane", 0.10);
richGas.addComponent("propane", 0.08);
richGas.addComponent("n-butane", 0.05);
richGas.setMixingRule("classic");
Stream feed = new Stream("Rich Gas", richGas);
feed.setFlowRate(100000.0, "Sm3/day");
feed.run();
Cooler precooler = new Cooler("Pre-cooler", feed);
precooler.setOutTemperature(280.0);
precooler.run();
Separator inletSeparator = new Separator("Expander inlet separator", precooler.getOutletStream());
inletSeparator.run();
Expander expander = new Expander("TEX-100", inletSeparator.getGasOutStream());
expander.setOutletPressure(25.0, "bara");
expander.setIsentropicEfficiency(0.82);
expander.run();
Separator coldSeparator = new Separator("Cold Separator", expander.getOutletStream());
coldSeparator.run();
double nglKgPerHour = coldSeparator.getLiquidOutStream().getFlowRate("kg/hr");
double totalOutletKgPerHour = inletSeparator.getLiquidOutStream().getFlowRate("kg/hr")
+ coldSeparator.getGasOutStream().getFlowRate("kg/hr") + nglKgPerHour;
The mass balance includes liquid recovered in both separators. Report an
actual liquid volume with "m3/hr" only with its operating conditions;
standard gas-equivalent volume is a different quantity.
Example 3: Expander vs JT Valve Comparison
Two independent feeds prevent shared fluid state between alternative paths. The additional compressor represents a separately specified shaft load.
import neqsim.thermo.system.SystemSrkEos;
import neqsim.process.equipment.stream.Stream;
import neqsim.process.equipment.stream.MechanicalShaft;
import neqsim.process.equipment.valve.ThrottlingValve;
import neqsim.process.equipment.expander.Expander;
import neqsim.process.equipment.compressor.Compressor;
SystemSrkEos gas = new SystemSrkEos(300.0, 60.0);
gas.addComponent("methane", 0.85);
gas.addComponent("ethane", 0.10);
gas.addComponent("propane", 0.05);
gas.setMixingRule("classic");
Stream valveFeed = new Stream("Valve feed", gas);
valveFeed.setFlowRate(10000.0, "kg/hr");
valveFeed.run();
Stream expanderFeed = new Stream("Expander feed", gas.clone());
expanderFeed.setFlowRate(10000.0, "kg/hr");
expanderFeed.run();
ThrottlingValve valve = new ThrottlingValve("JT Valve", valveFeed);
valve.setOutletPressure(15.0, "bara");
valve.run();
Expander expander = new Expander("Expander", expanderFeed);
expander.setOutletPressure(15.0, "bara");
expander.setIsentropicEfficiency(0.85);
expander.run();
Compressor compressor = new Compressor("Independent shaft load", valveFeed);
compressor.setOutletPressure(80.0, "bara");
compressor.setIsentropicEfficiency(0.75);
compressor.run();
MechanicalShaft shaft = new MechanicalShaft("Power accounting");
shaft.setGeneratedPower(expander.getName(), -expander.getPower());
shaft.setConsumedPower(compressor.getName(), compressor.getPower());
double shaftSurplusKW = shaft.getNetPower("kW");
double extraCoolingK = valve.getOutletStream().getTemperature("K")
- expander.getOutletStream().getTemperature("K");