Documentation for power generation equipment in NeqSim, including gas turbines, steam turbines, HRSG, combined-cycle systems, fuel cells, wind turbines, and solar panels.
Table of Contents
- Overview
- Gas Turbine
- Steam Turbine
- HRSG
- Combined Cycle System
- Fuel Cell
- Wind Turbine
- Solar Panel
- Battery Storage
- Right-Sizing, Dispatch & Retrofit (gasturbine sub-package)
- Driver Performance Curves (driver sub-package)
- Usage Examples
- Capacity Constraints and Optimization
- Related Documentation
Overview
Location: neqsim.process.equipment.powergeneration
The power generation package provides equipment models for converting chemical and renewable energy sources into electrical power:
| Equipment | Energy Source | Output |
|---|---|---|
GasTurbine |
Fuel gas combustion | Electricity + heat |
SteamTurbine |
High-pressure steam | Electricity |
HRSG |
Gas turbine exhaust | Steam |
CombinedCycleSystem |
Fuel gas (GT + HRSG + ST) | Electricity (high efficiency) |
FuelCell |
Hydrogen + oxygen | Electricity + water |
WindTurbine |
Wind | Electricity |
SolarPanel |
Solar radiation | Electricity |
BatteryStorage |
Stored electricity | Electricity |
Gas Turbine
The GasTurbine class models a simple cycle gas turbine with integrated air compression, combustion, and expansion.
Class Hierarchy
TwoPortEquipment
└── GasTurbine
Constructor
import neqsim.process.equipment.powergeneration.GasTurbine;
import neqsim.process.equipment.stream.Stream;
// Basic constructor
GasTurbine turbine = new GasTurbine("GT-101");
// Constructor with fuel stream
GasTurbine turbine = new GasTurbine("GT-101", fuelGasStream);
Key Properties
| Property | Description | Unit |
|---|---|---|
combustionPressure |
Combustor pressure | bara |
airGasRatio |
Air to fuel ratio | - |
excessAirFactor |
Combustion-air excess over stoichiometric O₂ (setExcessAirFactor) |
- |
power |
Net electrical power output | W |
heat |
Heat output | W |
compressorPower |
Air compressor power | W |
expanderPower |
Expander power | W |
Example Usage
import neqsim.process.equipment.powergeneration.GasTurbine;
import neqsim.process.equipment.stream.Stream;
import neqsim.thermo.system.SystemSrkEos;
// Create fuel gas
SystemInterface fuelGas = new SystemSrkEos(288.15, 25.0);
fuelGas.addComponent("methane", 0.90);
fuelGas.addComponent("ethane", 0.05);
fuelGas.addComponent("propane", 0.03);
fuelGas.addComponent("nitrogen", 0.02);
fuelGas.setMixingRule("classic");
Stream fuelStream = new Stream("Fuel Gas", fuelGas);
fuelStream.setFlowRate(1000.0, "kg/hr");
// Create gas turbine
GasTurbine turbine = new GasTurbine("Power Turbine", fuelStream);
turbine.combustionpressure = 2.5; // bara (public field) - simplified low-pressure cycle
turbine.setExcessAirFactor(2.5); // sizes combustion air so O2 is not depleted
// Run simulation
turbine.run();
// Results
System.out.println("Net power: " + turbine.getPower() / 1e6 + " MW");
System.out.println("Heat output: " + turbine.getHeat() / 1e6 + " MW");
System.out.println("Ideal air/fuel ratio: " + turbine.calcIdealAirFuelRatio());
The detailed cycle sizes combustion air using the stoichiometric oxygen demand and
excessAirFactor(default 2.5). It obtains the fuel lower heating value from ISO 6976 on a molar basis (kJ/mol), using the 0 C combustion reference to match the EOS sensible-enthalpy reference, then multiplies by mol/s and 1000 to obtain W. This avoids mixing volumetric calorific values with molar flows or inconsistent standard-volume references. Combustion changes the product composition before solving its enthalpy; a heat-capacity temperature estimate initializes that solve, and an unconverged combustion energy balance raises an exception.
getPower()is positive net shaft output: recovered expander work minus air compressor work.getHeat()estimates positive heat recoverable by cooling the exhaust to 288.15 K.getOutletStream()contains the hot combustion exhaust leaving the expander so a downstream HRSG can recover that energy. The detailed cycle balances inlet sensible enthalpy plus fuel heat against shaft output and hot exhaust enthalpy; do not add recoverable heat again to that balance. It is a simplified complete-combustion model without dissociation, combustor pressure loss or blade cooling. The optional specified-efficiency and power-demand modes retain their separate fuel-sizing convention and are not detailed-cycle performance predictions.
Steam Turbine
The SteamTurbine class models isentropic expansion of high-pressure steam to produce power. Outlet conditions are computed via PS-flash (isentropic) followed by PH-flash (actual) using the specified isentropic efficiency.
Class Hierarchy
TwoPortEquipment
└── SteamTurbine
Constructor
import neqsim.process.equipment.powergeneration.SteamTurbine;
// Basic constructor
SteamTurbine st = new SteamTurbine("ST-100");
// Constructor with inlet steam stream
SteamTurbine st = new SteamTurbine("ST-100", steamStream);
Key Properties
| Property | Setter | Default | Unit |
|---|---|---|---|
outletPressure |
setOutletPressure(p) / setOutletPressure(p, "bara") |
1.01325 | bara |
isentropicEfficiency |
setIsentropicEfficiency(e) |
0.85 | 0-1 |
numberOfStages |
setNumberOfStages(n) |
1 | - |
power |
(result) | - | W |
Example Usage
import neqsim.process.equipment.powergeneration.SteamTurbine;
import neqsim.process.equipment.stream.Stream;
import neqsim.thermo.system.SystemSrkEos;
// Create superheated steam
SystemInterface steam = new SystemSrkEos(273.15 + 450.0, 40.0);
steam.addComponent("water", 1.0);
steam.setMixingRule("classic");
Stream steamFeed = new Stream("HP Steam", steam);
steamFeed.setFlowRate(50000.0, "kg/hr");
// Create steam turbine
SteamTurbine turbine = new SteamTurbine("ST-100", steamFeed);
turbine.setOutletPressure(0.05, "bara");
turbine.setIsentropicEfficiency(0.88);
turbine.run();
System.out.println("Power output: " + turbine.getPower("MW") + " MW");
HRSG
The HRSG (Heat Recovery Steam Generator) class models counter-current heat exchange between hot gas turbine exhaust and a water/steam loop. It calculates the heat transferred and the steam production rate for given steam conditions.
Class Hierarchy
TwoPortEquipment
└── HRSG
Constructor
import neqsim.process.equipment.powergeneration.HRSG;
// Basic constructor
HRSG hrsg = new HRSG("HRSG-1");
// Constructor with hot gas inlet (gas turbine exhaust)
HRSG hrsg = new HRSG("HRSG-1", gasTurbineExhaust);
Key Properties
| Property | Setter | Default | Unit |
|---|---|---|---|
steamPressure |
setSteamPressure(p) |
40.0 | bara |
steamTemperature |
setSteamTemperature(t) / setSteamTemperature(t, "C") |
400 C | K |
feedWaterTemperature |
setFeedWaterTemperature(t) / setFeedWaterTemperature(t, "C") |
60 C | K |
approachTemperature |
setApproachTemperature(dT) |
15.0 | K |
effectiveness |
setEffectiveness(e) |
0.85 | 0-1 |
Results
| Method | Returns | Unit |
|---|---|---|
getHeatTransferred() / getHeatTransferred("MW") |
Heat to steam | W / MW |
getSteamFlowRate() / getSteamFlowRate("kg/hr") |
Steam production | kg/s / kg/hr |
getGasOutletTemperature() |
Gas stack temperature | K |
Example Usage
HRSG hrsg = new HRSG("HRSG-1", turbine.getOutletStream());
hrsg.setSteamPressure(40.0);
hrsg.setSteamTemperature(400.0, "C");
hrsg.setApproachTemperature(15.0);
hrsg.run();
System.out.println("Heat recovered: " + hrsg.getHeatTransferred("MW") + " MW");
System.out.println("Steam production: " + hrsg.getSteamFlowRate("kg/hr") + " kg/hr");
Combined Cycle System
The CombinedCycleSystem class integrates a GasTurbine, HRSG, and SteamTurbine into a single equipment unit. It models the full gas turbine combined cycle (GTCC) workflow:
- Fuel gas combustion in the gas turbine
- Exhaust heat recovery in the HRSG to produce steam
- Steam expansion through the steam turbine
Class Hierarchy
TwoPortEquipment
└── CombinedCycleSystem (composes GasTurbine + HRSG + SteamTurbine)
Constructor
import neqsim.process.equipment.powergeneration.CombinedCycleSystem;
CombinedCycleSystem cc = new CombinedCycleSystem("CC-Plant");
CombinedCycleSystem cc = new CombinedCycleSystem("CC-Plant", fuelGasStream);
Key Properties
| Property | Setter | Default | Unit |
|---|---|---|---|
combustionPressure |
combustionpressure (public field) |
2.5 | bara |
steamPressure |
setSteamPressure(p) |
40.0 | bara |
steamTemperature |
setSteamTemperature(t, "C") |
400.0 | C |
steamTurbineEfficiency |
setSteamTurbineEfficiency(e) |
0.85 | 0-1 |
steamCondensorPressure |
setSteamCondensorPressure(p) |
0.05 | bara |
hrsgApproachTemperature |
setHrsgApproachTemperature(dT) |
15.0 | K |
hrsgEffectiveness |
setHrsgEffectiveness(e) |
0.85 | 0-1 |
Results
| Method | Returns | Unit |
|---|---|---|
getTotalPower() / getTotalPower("MW") |
Combined GT + ST power | W / MW |
getGasTurbinePower() |
GT contribution | W |
getSteamTurbinePower() |
ST contribution | W |
getOverallEfficiency() |
LHV thermal efficiency | 0-1 |
getFuelEnergyInput() |
Fuel energy (LHV) | W |
toJson() |
Full results JSON | String |
Example Usage
CombinedCycleSystem cc = new CombinedCycleSystem("CC-1", fuelStream);
cc.setCombustionPressure(15.0);
cc.setSteamPressure(40.0);
cc.setSteamTemperature(400.0, "C");
cc.setSteamTurbineEfficiency(0.85);
cc.run();
System.out.println("Total power: " + cc.getTotalPower("MW") + " MW");
System.out.println("GT power: " + cc.getGasTurbinePower() / 1e6 + " MW");
System.out.println("ST power: " + cc.getSteamTurbinePower() / 1e6 + " MW");
System.out.println("Efficiency: " + cc.getOverallEfficiency() * 100 + "%");
System.out.println(cc.toJson());
Fuel Cell
Class Hierarchy
TwoPortEquipment
└── FuelCell
Constructor
import neqsim.process.equipment.powergeneration.FuelCell;
// Basic constructor
FuelCell cell = new FuelCell("FC-101");
// Constructor with fuel and oxidant streams
FuelCell cell = new FuelCell("FC-101", hydrogenStream, airStream);
Key Properties
| Property | Description | Unit |
|---|---|---|
efficiency |
Electrical efficiency | 0-1 |
power |
Electrical power output | W |
heatLoss |
Heat loss to environment | W |
Example Usage
import neqsim.process.equipment.powergeneration.FuelCell;
import neqsim.process.equipment.stream.Stream;
import neqsim.thermo.system.SystemSrkEos;
// Create hydrogen fuel stream
SystemInterface h2Fluid = new SystemSrkEos(298.15, 5.0);
h2Fluid.addComponent("hydrogen", 1.0);
h2Fluid.setMixingRule("classic");
Stream hydrogenFeed = new Stream("Hydrogen", h2Fluid);
hydrogenFeed.setFlowRate(10.0, "kg/hr");
// Create air stream
SystemInterface airFluid = new SystemSrkEos(298.15, 1.01325);
airFluid.addComponent("nitrogen", 0.79);
airFluid.addComponent("oxygen", 0.21);
airFluid.setMixingRule("classic");
Stream airFeed = new Stream("Air", airFluid);
airFeed.setFlowRate(100.0, "kg/hr");
// Create fuel cell
FuelCell fuelCell = new FuelCell("SOFC", hydrogenFeed, airFeed);
fuelCell.setEfficiency(0.55);
// Run simulation
fuelCell.run();
// Results
System.out.println("Electrical power: " + fuelCell.getPower() / 1000 + " kW");
System.out.println("Heat loss: " + fuelCell.getHeatLoss() / 1000 + " kW");
Wind Turbine
The WindTurbine class models wind power generation based on wind speed and turbine characteristics.
Constructor
import neqsim.process.equipment.powergeneration.WindTurbine;
WindTurbine turbine = new WindTurbine("WT-01");
turbine.setWindSpeed(12.0); // m/s
turbine.setRotorArea(11310.0); // m² (e.g. pi * 60² for 120m diameter)
turbine.setPowerCoefficient(0.45); // Betz limit max ~0.593
Key Properties
| Property | Description | Unit |
|---|---|---|
windSpeed |
Wind velocity | m/s |
rotorArea |
Rotor swept area | m² |
powerCoefficient |
Aerodynamic efficiency (Cp) | 0-0.593 (Betz limit) |
airDensity |
Air density | kg/m³ |
power |
Electrical power output | W |
Solar Panel
The SolarPanel class models photovoltaic power generation.
Constructor
import neqsim.process.equipment.powergeneration.SolarPanel;
SolarPanel panel = new SolarPanel("PV-Array");
panel.setPanelArea(1000.0); // m²
panel.setIrradiance(800.0); // W/m²
panel.setEfficiency(0.20);
Key Properties
| Property | Description | Unit |
|---|---|---|
panelArea |
Total panel area | m² |
irradiance |
Solar radiation | W/m² |
efficiency |
Panel efficiency | 0-1 |
power |
Electrical power output | W |
Battery Storage
Location: neqsim.process.equipment.battery
The BatteryStorage class models electrical energy storage systems.
Constructor
import neqsim.process.equipment.battery.BatteryStorage;
BatteryStorage battery = new BatteryStorage("BESS-01");
battery.setCapacity(3.6e11); // Joules (= 100 MWh)
// Note: charge/discharge efficiencies are internal (default 0.95 each)
Key Properties
| Property | Description | Unit |
|---|---|---|
capacity |
Total energy capacity | J |
stateOfCharge |
Current energy level | J |
stateOfChargeFraction |
SOC as fraction | 0-1 |
Operations
battery.charge(25e6, 2.0); // charge at 25 MW for 2 hours
double delivered = battery.discharge(25e6, 1.0); // discharge at 25 MW for 1 hour
double soc = battery.getStateOfChargeFraction(); // 0-1
Right-Sizing, Dispatch & Retrofit (gasturbine sub-package)
For late-life turndown, fleet right-sizing, dispatch with N+1 reserve, and
retrofit NPV / CO₂-avoided studies, use the catalog-driven classes under
neqsim.process.equipment.powergeneration.gasturbine. These complement the
legacy GasTurbine class above: use the legacy class when you need full
thermodynamic GT + HRSG integration; use this sub-package when the question
is “which turbines, how many, and at what load over 20 years?”
| Class | Purpose |
|---|---|
GasTurbineCatalog |
Bundled gas_turbine_catalog.csv (14 aero + industrial models: LM2500, LM2500PLUS_G4, LM6000PF/PG, RB211_6562, Trent 60, SGT-700/750, Centaur 50, Taurus 60/70, Mars 100, Titan 130/250) |
GasTurbineSpec |
Immutable rating point (rated MW, ISO heat rate, exhaust flow/T, NOx, mass) |
GasTurbinePerformanceMap |
Part-load + ambient correction (aero vs industrial polynomials, min-load fraction) |
GasTurbineDegradation |
Recoverable + non-recoverable fouling vs fired hours, water-wash and overhaul reset |
GasTurbineEmissions |
Full-carbon-balance CO₂, NOx, methane slip from fuel composition |
CO2TaxSchedule |
Loads co2_tax_norway.csv (2020–2040 NOK/tonne, CO₂ tax + EU ETS), linear interpolation |
GasTurbineUnit |
TwoPortEquipment — runs inside a ProcessSystem, accepts fuel Stream, aggregates Compressor shaft load via addPowerConsumer |
TurbineDispatchOptimizer |
Picks the cheapest feasible on/off combination (brute-force ≤8 units, merit-order above) with N+1 reserve |
LateLifeRetrofitStudy |
Year-by-year NPV / CO₂-avoided / payback for baseline vs retrofit fleet over a declining demand profile |
Catalog & site-corrected available power
import neqsim.process.equipment.powergeneration.gasturbine.GasTurbineCatalog;
import neqsim.process.equipment.powergeneration.gasturbine.GasTurbineSpec;
import neqsim.process.equipment.powergeneration.gasturbine.GasTurbineUnit;
GasTurbineSpec spec = GasTurbineCatalog.get("LM2500");
GasTurbineUnit gt = new GasTurbineUnit("GT-A", fuelStream, spec);
gt.setAmbientTemperatureK(273.15 + 30.0); // hot-day derate
gt.setDemandedPower(15.0e6); // 15 MW shaft
gt.run(UUID.randomUUID());
double availMW = gt.getAvailablePowerW() / 1.0e6;
double load = gt.getLoadFraction();
double co2Tph = gt.getCO2EmissionKgPerS() * 3.6;
Linking turbine shaft to compressor demand
Each GasTurbineUnit sums the live shaft demand from any number of
Compressor objects in the same flowsheet — the dispatcher reads it on
every run():
ProcessSystem plant = new ProcessSystem();
plant.add(exportCompressor); // existing Compressor
plant.add(injectionCompressor);
GasTurbineUnit gt = new GasTurbineUnit("GT-A", fuelStream,
GasTurbineCatalog.get("LM2500"));
gt.addPowerConsumer(exportCompressor);
gt.addPowerConsumer(injectionCompressor);
plant.add(gt);
plant.run(); // gt aggregates Compressor.getPower() automatically
Closing the loop: feeding the available-power limit back to compressors
By default the link above is one-way — the turbine reads compressor shaft
power but does not constrain it. Enable setEnforcePowerLimit(true) to close
the loop: on every run() the unit distributes its site-corrected
getAvailablePowerW() across the attached compressors (in proportion to their
current demand) and installs each share as a
GasTurbineDriver performance
curve on the compressor via Compressor.setDriverCurve(...). Because the
per-compressor caps sum to the turbine available power, the capacity /
bottleneck framework then enforces Σ compressor power ≤ turbine available
power automatically.
GasTurbineUnit gt = new GasTurbineUnit("GT-A", fuelStream,
GasTurbineCatalog.get("LM2500"));
gt.addPowerConsumer(exportCompressor);
gt.addPowerConsumer(injectionCompressor);
gt.setAmbientTemperatureK(273.15 + 30.0); // hot-day derate shrinks the budget
gt.setEnforcePowerLimit(true); // opt-in: cap the compressors
plant.add(gt);
plant.run();
if (gt.isOverloaded()) {
System.out.println("Shortfall: " + gt.getPowerShortfallW() / 1e6 + " MW");
}
// Per-machine power budget actually installed on each compressor:
gt.getPowerAllocationW().forEach((name, watts) ->
System.out.println(name + " allocated " + watts / 1e6 + " MW"));
// Each compressor now reports a finite capacity limit from its driver curve:
double capMW = exportCompressor.getCapacityMax() / 1e6;
The default (
enforcePowerLimit = false) preserves the historical snapshot-only behaviour, so existing dispatch and right-sizing studies are unaffected. Turn it on when you want the turbine’s installed/derated power to act as a hard ceiling for the compression train in capacity and debottlenecking analysis.
Fleet dispatch with N+1 redundancy
import neqsim.process.equipment.powergeneration.gasturbine.TurbineDispatchOptimizer;
List<GasTurbineUnit> fleet = Arrays.asList(gt1, gt2, gt3);
TurbineDispatchOptimizer disp = new TurbineDispatchOptimizer(
/*fuelPriceNOKPerKg*/ 4.5,
/*co2CostNOKPerTonne*/ 1500.0);
disp.setRequireNplusOne(true);
TurbineDispatchOptimizer.DispatchResult r = disp.dispatch(fleet, 18.0e6);
if (r.feasible) {
System.out.println(r.summary()); // running units, load, NOK/hr
}
Retrofit NPV vs baseline
import neqsim.process.equipment.powergeneration.gasturbine.CO2TaxSchedule;
import neqsim.process.equipment.powergeneration.gasturbine.LateLifeRetrofitStudy;
double[] demandMW = new double[20];
for (int i = 0; i < 20; i++) demandMW[i] = Math.max(8.0, 56.0 - i * 2.0);
LateLifeRetrofitStudy study = new LateLifeRetrofitStudy(
baselineFleet, // e.g. 2x LM6000PF
retrofitFleet, // e.g. 3x SGT-700
demandMW,
/*startYear*/ 2026,
CO2TaxSchedule.loadDefault(),
/*fuelPriceNOKPerKg*/ 4.5);
study.setRetrofitCapexMNOK(800.0);
study.setDiscountRate(0.08);
study.setAnnualOperatingHours(8000);
LateLifeRetrofitStudy.RetrofitResult res = study.run();
System.out.println("NPV (MNOK): " + res.npvMNOK);
System.out.println("CO2 avoided (t): " + res.totalCO2AvoidedTonne);
System.out.println("Payback (yr): " + res.simplePaybackYear);
End-to-end notebooks
The Gas Turbine & Compressor Driver Coupling
notebook is a focused, runnable introduction to the three abstractions on this
page: the GasTurbine Brayton-cycle thermo model (Part A), the catalog-driven
GasTurbineUnit accounting wrapper that caps a compressor train (Part B), and
a standalone GasTurbineDriver capacity ceiling with ambient derating (Part C).
The Gas Turbine 20-Year Right-Sizing and Retrofit notebook walks through a complete late-life study:
- Build a 50 MMSCFD export-compression train and link it to a
GasTurbineUnit. - Sweep ambient temperature × load to map site-corrected available power.
- Apply
GasTurbineDegradationover fired hours and overhauls. - Dispatch a 3-unit fleet with
TurbineDispatchOptimizeragainst an annual load-duration curve. - Run
LateLifeRetrofitStudywithCO2TaxSchedule.loadDefault()to compare baseline (2 × LM6000PF) vs retrofit (3 × SGT-700) on NPV, payback, and CO₂ avoided. - Layer an HRSG + steam-turbine bottoming cycle on the retrofit fleet to evaluate a combined-cycle alternative.
- Replace the synthetic decline with a reservoir + Beggs-Brills riser + flowline model so the compressor suction — and therefore the shaft demand — is driven by reservoir physics.
The full skill reference lives at .github/skills/neqsim-power-generation/SKILL.md.
Driver Performance Curves (driver sub-package)
A Compressor can be given a richer driver performance curve from
neqsim.process.equipment.compressor.driver. Unlike the simpler enum-based
CompressorDriver, the DriverCurve family models speed-dependent available
power with ambient-temperature and altitude derating, and feeds that
derated limit into Compressor.getCapacityMax() for capacity and bottleneck
analysis.
| Class | Models |
|---|---|
DriverCurve |
Interface (extends Serializable) — available power, torque, efficiency vs speed |
DriverCurveBase |
Shared base: rated power/speed, ISO ambient, overspeed limit |
GasTurbineDriver |
Ambient + altitude derating, part-load efficiency, fuel consumption |
ElectricMotorDriver |
Constant-torque (VFD) or fixed-speed characteristics |
SteamTurbineDriver |
Power vs steam conditions / extraction |
Attaching a driver curve to a compressor
import neqsim.process.equipment.compressor.Compressor;
import neqsim.process.equipment.compressor.driver.GasTurbineDriver;
Compressor exportCompressor = new Compressor("Export", suctionStream);
exportCompressor.setOutletPressure(120.0);
// 20 MW gas-turbine driver, 35% design efficiency
GasTurbineDriver driver = new GasTurbineDriver(20000.0, 0.35); // kW, fraction
driver.setAmbientTemperature(30.0); // hot-day derate
exportCompressor.setDriverCurve(driver);
exportCompressor.run();
// getCapacityMax() now uses the derated driver curve (highest priority)
double capMW = exportCompressor.getCapacityMax() / 1e6;
double availMW = driver.getAvailablePower(driver.getRatedSpeed()) / 1000.0; // kW->MW
boolean ok = driver.canSupplyPower(exportCompressor.getPower("kW"),
driver.getRatedSpeed());
getCapacityMax() resolves the limit in priority order:
DriverCurve(getDriverCurve()) — derated available power at the current/rated speed, if set.CompressorDriverspeed-dependent max-power curve (if speed is set).- Mechanical design maximum power.
CompressorDriverrated power with a 10% overload margin.
This is the same curve type that GasTurbineUnit.setEnforcePowerLimit(true)
installs automatically on each driven compressor (see
Closing the loop),
so a gas turbine’s installed/derated power becomes a hard ceiling for its
compression train.
Usage Examples
Combined Heat and Power (CHP) System
import neqsim.process.processmodel.ProcessSystem;
import neqsim.process.equipment.powergeneration.GasTurbine;
import neqsim.process.equipment.powergeneration.HRSG;
ProcessSystem chpSystem = new ProcessSystem("CHP Plant");
// Create fuel gas stream
Stream fuelGas = new Stream("Fuel", fuelFluid);
fuelGas.setFlowRate(500.0, "kg/hr");
chpSystem.add(fuelGas);
// Gas turbine
GasTurbine turbine = new GasTurbine("GT", fuelGas);
turbine.combustionpressure = 12.0;
chpSystem.add(turbine);
// Heat recovery steam generator
HRSG hrsg = new HRSG("HRSG", turbine.getOutletStream());
hrsg.setSteamPressure(20.0);
hrsg.setSteamTemperature(250.0, "C");
hrsg.setApproachTemperature(15.0);
chpSystem.add(hrsg);
// Run
chpSystem.run();
// Calculate efficiency
double electricalPower = turbine.getPower();
double thermalPower = hrsg.getHeatTransferred();
double fuelInput = fuelGas.getFlowRate("kg/hr") * 50e6 / 3600; // LHV ~ 50 MJ/kg
double electricalEff = electricalPower / fuelInput;
double totalEff = (electricalPower + thermalPower) / fuelInput;
System.out.println("Electrical efficiency: " + electricalEff * 100 + "%");
System.out.println("Total CHP efficiency: " + totalEff * 100 + "%");
System.out.println("Steam production: " + hrsg.getSteamFlowRate("kg/hr") + " kg/hr");
Combined Cycle Power Plant
import neqsim.process.equipment.powergeneration.CombinedCycleSystem;
// One-call combined cycle with internal GT + HRSG + ST
CombinedCycleSystem ccPlant = new CombinedCycleSystem("GTCC", fuelGasStream);
ccPlant.setCombustionPressure(15.0);
ccPlant.setSteamPressure(40.0);
ccPlant.setSteamTemperature(400.0, "C");
ccPlant.setSteamTurbineEfficiency(0.85);
ccPlant.run();
System.out.println("Total power: " + ccPlant.getTotalPower("MW") + " MW");
System.out.println("GT power: " + ccPlant.getGasTurbinePower() / 1e6 + " MW");
System.out.println("ST power: " + ccPlant.getSteamTurbinePower() / 1e6 + " MW");
System.out.println("Overall efficiency: " + ccPlant.getOverallEfficiency() * 100 + "%");
Hybrid Renewable System
// Solar + Wind + Battery system
SolarPanel solar = new SolarPanel("PV");
solar.setPanelArea(5000.0);
solar.setIrradiance(600.0);
solar.setEfficiency(0.18);
WindTurbine wind = new WindTurbine("Wind");
wind.setWindSpeed(8.0);
wind.setRotorArea(5027.0); // ~80m diameter
BatteryStorage battery = new BatteryStorage("Battery");
battery.setCapacity(3.6e10); // 10 MWh in Joules
// Calculate total renewable generation
solar.run();
wind.run();
double totalGeneration = solar.getPower() + wind.getPower();
System.out.println("Total renewable power: " + totalGeneration / 1e6 + " MW");
Capacity Constraints and Optimization
All four core power generation equipment types (GasTurbine, SteamTurbine, HRSG, CombinedCycleSystem) implement the CapacityConstrainedEquipment and AutoSizeable interfaces. This enables rated-capacity tracking, bottleneck detection, and integration with the plant-wide ProcessOptimizationEngine.
Interfaces
| Interface | Purpose |
|---|---|
CapacityConstrainedEquipment |
Tracks operating point vs rated capacity, detects violations |
AutoSizeable |
Sets rated capacity from current operating point with a safety factor |
Setting Rated Capacity
Each equipment type has a rated capacity field that defines its design limit:
// Gas turbine — rated power
GasTurbine gt = new GasTurbine("GT-1", fuelStream);
gt.setRatedPower(30.0, "MW"); // 30 MW design rating
// Steam turbine — rated power
SteamTurbine st = new SteamTurbine("ST-1", steamStream);
st.setRatedPower(15.0, "MW");
// HRSG — design heat duty
HRSG hrsg = new HRSG("HRSG-1", gt.getOutletStream());
hrsg.setDesignHeatDuty(50.0, "MW");
// Combined cycle — rated total power
CombinedCycleSystem cc = new CombinedCycleSystem("CC-1", fuelStream);
cc.setRatedTotalPower(45.0, "MW");
Auto-Sizing
When design ratings are not known, auto-size from the current operating point:
// Run the process first to establish operating conditions
process.run();
// Auto-size with a 20% safety margin (factor = 1.2)
gt.autoSize(1.2);
st.autoSize(1.2);
hrsg.autoSize(1.2);
cc.autoSize(1.2);
// Check sizing results
System.out.println(gt.getSizingReport());
System.out.println(gt.isAutoSized()); // true
Querying Capacity
After running and setting rated capacity (manually or via auto-size), query the operating margin:
The registry’s PowerGenerationCapacityStrategy reports power and heat-duty capacities in
kW. Its constraint design values and evaluateMaxCapacity(equipment) use the same equipment
rating: getRatedPower("kW") for either turbine, getDesignHeatDuty("kW") for an HRSG, and
getRatedTotalPower("kW") for a combined cycle. A positive equipment rating takes precedence
over the strategy’s configured fallback (50,000 kW by default). Changing the equipment rating
is reflected by subsequent calls to both strategy APIs. evaluateMaxCapacity reports the
design rating; overload margins remain separate constraint limits. For example, a 25 MW turbine
reports 25,000 kW through this strategy, while the equipment’s getCapacityMax() returns watts.
// Current operating duty vs maximum
double duty = gt.getCapacityDuty(); // current power output (W)
double max = gt.getCapacityMax(); // rated power (W)
// Utilization fraction (0-1, where 1.0 = at capacity)
double utilization = gt.getMaxUtilization();
// Check if any constraint is violated
boolean exceeded = gt.isCapacityExceeded(); // soft or hard limit
boolean hardTrip = gt.isHardLimitExceeded(); // hard limit only
// Get the most-loaded constraint
CapacityConstraint bottleneck = gt.getBottleneckConstraint();
if (bottleneck != null) {
System.out.println(bottleneck.getName() + ": " + bottleneck.getUtilization());
}
// Iterate all constraints
for (Map.Entry<String, CapacityConstraint> entry :
gt.getCapacityConstraints().entrySet()) {
System.out.println(entry.getKey() + " -> " + entry.getValue().getUtilization());
}
Adding Custom Constraints
The built-in constraint (power or heat duty) covers the primary capacity limit. Add additional constraints for operational envelopes:
import neqsim.process.equipment.capacity.CapacityConstraint;
// Add an exhaust temperature limit to the gas turbine
gt.addCapacityConstraint(
new CapacityConstraint("exhaustTemp", "C", CapacityConstraint.ConstraintType.HARD)
.setDesignValue(550.0)
.setMaxValue(600.0)
.setWarningThreshold(0.90)
.setDescription("Exhaust gas temperature limit")
.setValueSupplier(() -> gt.getOutletStream().getTemperature("C")));
// Remove a constraint by name
gt.removeCapacityConstraint("exhaustTemp");
// Clear all constraints
gt.clearCapacityConstraints();
Integration with ProcessOptimizationEngine
The ProcessOptimizationEngine reads capacity constraints from all equipment in a ProcessSystem to find the plant-wide maximum throughput and identify bottlenecks.
Bottleneck Detection
import neqsim.process.util.optimizer.ProcessOptimizationEngine;
// Build a combined heat and power system
ProcessSystem chp = new ProcessSystem();
chp.add(fuelStream);
chp.add(gt);
chp.add(hrsg);
chp.run();
// Set rated capacities
gt.setRatedPower(30.0, "MW");
hrsg.setDesignHeatDuty(50.0, "MW");
// Evaluate constraints across the entire process
ProcessOptimizationEngine engine = new ProcessOptimizationEngine(chp);
ProcessOptimizationEngine.ConstraintReport report = engine.evaluateAllConstraints();
for (ProcessOptimizationEngine.EquipmentConstraintStatus status :
report.getEquipmentStatuses()) {
System.out.printf("%s %s: %.1f%% utilization%n",
status.isWithinLimits() ? "OK" : "!!",
status.getEquipmentName(),
status.getMaxUtilization() * 100);
}
Maximum Throughput Optimization
Find how much fuel gas the system can handle before hitting a capacity limit:
ProcessOptimizationEngine.OptimizationResult result =
engine.findMaximumThroughput(
25.0, // inlet pressure (bara)
25.0, // outlet pressure (bara — no compression)
100.0, // min fuel flow (kg/hr)
10000.0 // max fuel flow (kg/hr)
);
System.out.println("Max fuel rate: " + result.getOptimalFlowRate() + " kg/hr");
System.out.println("Bottleneck: " + result.getBottleneckEquipment());
System.out.println("Total power at max: " + result.getTotalPower() + " kW");
Capacity Utilization Summary
For a quick overview of all equipment headroom in the process:
Map<String, Double> utilization = chp.getCapacityUtilizationSummary();
for (Map.Entry<String, Double> entry : utilization.entrySet()) {
System.out.printf("%-25s %.1f%%%n", entry.getKey(), entry.getValue() * 100);
}
// Example output:
// GT-1 72.3%
// HRSG-1 65.8%
Python (Jupyter) Example
from neqsim import jneqsim
# Create fuel gas
gas = jneqsim.thermo.system.SystemSrkEos(288.15, 25.0)
gas.addComponent("methane", 0.90)
gas.addComponent("ethane", 0.05)
gas.addComponent("propane", 0.03)
gas.addComponent("nitrogen", 0.02)
gas.setMixingRule("classic")
Stream = jneqsim.process.equipment.stream.Stream
GasTurbine = jneqsim.process.equipment.powergeneration.GasTurbine
HRSG = jneqsim.process.equipment.powergeneration.HRSG
ProcessSystem = jneqsim.process.processmodel.ProcessSystem
fuel = Stream("Fuel Gas", gas)
fuel.setFlowRate(1000.0, "kg/hr")
gt = GasTurbine("GT-1", fuel)
hrsg = HRSG("HRSG-1", gt.getOutletStream())
hrsg.setSteamPressure(40.0)
process = ProcessSystem()
process.add(fuel)
process.add(gt)
process.add(hrsg)
process.run()
# Auto-size with 20% margin
gt.autoSize(1.2)
hrsg.autoSize(1.2)
# Check utilization
print(f"GT utilization: {gt.getMaxUtilization() * 100:.1f}%")
print(f"HRSG utilization: {hrsg.getMaxUtilization() * 100:.1f}%")
print(f"GT capacity exceeded: {gt.isCapacityExceeded()}")
# Sizing report
print(gt.getSizingReport())
Related Documentation
- Capacity Constraint Framework - Equipment capacity limits and bottleneck detection
- Optimization Overview - When to use which optimizer
- Optimization Practical Examples - Java and Python optimization code samples
- Heat Integration (Pinch Analysis) - Minimum utility targeting
- Electrolyzers - Hydrogen production
- Compressors - Gas compression
- Heat Exchangers - Heat recovery
- Sustainability - Emissions tracking
- Gas Turbine 20-Year Right-Sizing and Retrofit Notebook - End-to-end late-life study using
GasTurbineUnit,TurbineDispatchOptimizer,LateLifeRetrofitStudy, and reservoir-driven demand - Gas Turbine & Compressor Driver Coupling Notebook - Focused intro to
GasTurbine,GasTurbineUnit, andGasTurbineDriverwith ambient derating