This tutorial builds a three-stage gas-oil separation screening model. It is intended for process-model development and teaching: the calculation predicts equilibrium phase splits at the selected pressures, but it does not qualify separator internals, produced-water treatment, compression, export specifications, or mechanical design.
Engineering Question
For a synthetic water-bearing well fluid, calculate the gas, oil, and aqueous product rates after separation at 50, 10, and 2 bara. Check the overall mass balance and calculate a model-based VPCR4 value for the final oil at 37.8 degrees Celsius.
The example uses SRK-CPA because water is present. The supplied TBP molar masses are in kg/mol and
the densities are specific gravities, matching the current addTBPfraction API.
Process Configuration
well stream
|
v
HP three-phase separator (50 bara) ----> HP gas
|
+----> HP water
|
v
MP valve -> MP separator (10 bara) ----> MP gas + MP water
|
v
LP valve -> LP separator (2 bara) -----> LP gas + LP water
|
v
export-oil screening stream
The three gas streams are separate battery-limit products. A real facility would normally route the MP and LP gas through scrubbers, compression, cooling, and recycle before export. Those units are deliberately excluded so the phase-split and material-balance contract remains clear.
Complete Java 8 Example
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import neqsim.process.equipment.separator.ThreePhaseSeparator;
import neqsim.process.equipment.stream.Stream;
import neqsim.process.equipment.stream.StreamInterface;
import neqsim.process.equipment.valve.ThrottlingValve;
import neqsim.process.processmodel.ProcessSystem;
import neqsim.thermo.system.SystemInterface;
import neqsim.thermo.system.SystemSrkCPAstatoil;
public final class GospScreeningExample {
private static final Logger logger = LogManager.getLogger(GospScreeningExample.class);
private GospScreeningExample() {}
public static void main(String[] args) {
SystemInterface wellFluid = new SystemSrkCPAstatoil(353.15, 50.0);
wellFluid.addComponent("nitrogen", 0.005);
wellFluid.addComponent("CO2", 0.020);
wellFluid.addComponent("methane", 0.350);
wellFluid.addComponent("ethane", 0.080);
wellFluid.addComponent("propane", 0.060);
wellFluid.addComponent("i-butane", 0.020);
wellFluid.addComponent("n-butane", 0.030);
wellFluid.addComponent("i-pentane", 0.015);
wellFluid.addComponent("n-pentane", 0.020);
wellFluid.addComponent("n-hexane", 0.025);
wellFluid.addComponent("n-heptane", 0.040);
wellFluid.addComponent("n-octane", 0.050);
wellFluid.addComponent("n-nonane", 0.040);
wellFluid.addComponent("nC10", 0.030);
wellFluid.addTBPfraction("C11", 0.050, 0.150, 0.78);
wellFluid.addTBPfraction("C15", 0.040, 0.210, 0.82);
wellFluid.addTBPfraction("C20", 0.060, 0.350, 0.88);
wellFluid.addComponent("water", 0.050);
wellFluid.setMixingRule(10);
wellFluid.setMultiPhaseCheck(true);
Stream feed = new Stream("well stream", wellFluid);
feed.setFlowRate(50000.0, "kg/hr");
feed.setTemperature(80.0, "C");
feed.setPressure(50.0, "bara");
ThreePhaseSeparator hpSeparator = new ThreePhaseSeparator("HP separator", feed);
StreamInterface hpOil = hpSeparator.getOilOutStream();
ThrottlingValve mpValve = new ThrottlingValve("MP valve", hpOil);
mpValve.setOutletPressure(10.0, "bara");
ThreePhaseSeparator mpSeparator =
new ThreePhaseSeparator("MP separator", mpValve.getOutletStream());
StreamInterface mpOil = mpSeparator.getOilOutStream();
ThrottlingValve lpValve = new ThrottlingValve("LP valve", mpOil);
lpValve.setOutletPressure(2.0, "bara");
ThreePhaseSeparator lpSeparator =
new ThreePhaseSeparator("LP separator", lpValve.getOutletStream());
ProcessSystem process = new ProcessSystem();
process.add(feed);
process.add(hpSeparator);
process.add(mpValve);
process.add(mpSeparator);
process.add(lpValve);
process.add(lpSeparator);
process.run();
double gasMassFlow = hpSeparator.getGasOutStream().getFlowRate("kg/hr")
+ mpSeparator.getGasOutStream().getFlowRate("kg/hr")
+ lpSeparator.getGasOutStream().getFlowRate("kg/hr");
double waterMassFlow = hpSeparator.getWaterOutStream().getFlowRate("kg/hr")
+ mpSeparator.getWaterOutStream().getFlowRate("kg/hr")
+ lpSeparator.getWaterOutStream().getFlowRate("kg/hr");
StreamInterface exportOil = lpSeparator.getOilOutStream();
double oilMassFlow = exportOil.getFlowRate("kg/hr");
double feedMassFlow = feed.getFlowRate("kg/hr");
double recoveredMassFlow = gasMassFlow + waterMassFlow + oilMassFlow;
double relativeMassBalanceError =
Math.abs(recoveredMassFlow - feedMassFlow) / feedMassFlow;
double vpcr4Bara = exportOil.getRVP(37.8, "C", "bara");
assert Double.isFinite(gasMassFlow) && gasMassFlow > 0.0;
assert Double.isFinite(waterMassFlow) && waterMassFlow > 0.0;
assert Double.isFinite(oilMassFlow) && oilMassFlow > 0.0;
assert Double.isFinite(vpcr4Bara) && vpcr4Bara > 0.0;
assert relativeMassBalanceError <= 1.0e-3;
logger.info("Gas products: {} kg/hr", gasMassFlow);
logger.info("Water products: {} kg/hr", waterMassFlow);
logger.info("Export-oil screening stream: {} kg/hr", oilMassFlow);
logger.info("Relative material-balance error: {}", relativeMassBalanceError);
logger.info("Model VPCR4 at 37.8 C: {} bara", vpcr4Bara);
}
}
Run with assertions enabled (-ea). The repository documentation contract extracts this exact
fence, compiles it with the Java 8 language target, and executes it.
Interpret the Results
The recovered product mass should match the feed within the stated numerical tolerance. Each gas, oil, and water rate is an equilibrium phase-split result for this synthetic fluid and selected model; it is not a separator-efficiency guarantee.
getRVP(37.8, "C", "bara") returns NeqSim’s VPCR4 model result on a cloned fluid. It is not the
LP separator pressure and does not replace a qualified laboratory result. See the
ASTM D6377 vapor-pressure screening guide for method semantics,
state ownership, and compliance boundaries.
Pressure Selection
Stage pressure changes affect liquid recovery, flash-gas production, vapor pressure, compression power, and downstream water handling. Compare candidate pressure sets with freshly constructed process cases and record, at minimum:
- export-oil and gas mass rates;
- VPCR4 or the contract-selected vapor-pressure quantity;
- MP/LP gas compression duties and discharge temperatures;
- hydrocarbon losses to produced water;
- material and energy closure; and
- equipment operating envelopes.
Maximizing oil mass alone is not a complete optimization objective. Pressure limits, compressor maps, heating/cooling duties, product specifications, emissions, and operability must also be represented.
Model Boundaries
| Topic | What this tutorial proves | Additional evidence required |
|---|---|---|
| Phase separation | Equilibrium gas/oil/aqueous splits | Internals, residence time, entrainment, foaming, and vessel sizing |
| Vapor pressure | NeqSim VPCR4 screening at 37.8 degrees Celsius | Qualified laboratory method and applicable product contract |
| Produced water | Aqueous phase rate leaving each stage | Hydrocyclone/deoiling model, oil-in-water measurement, chemistry, and discharge basis |
| Gas export | Gas available at three pressure levels | Compression, cooling, scrubbers, recycle, dew-point treatment, and metering |
| Oil export | Final equilibrium oil stream | BS&W/salt/H2S analysis, export pumping, custody-transfer basis, and specification checks |
| Floating facility | Thermodynamic screening remains usable | Motion-specific separation performance and accountable mechanical design |
Do not apply generic RVP, BS&W, salt, H2S, dew-point, heating-value, or discharge limits. These limits depend on the product, jurisdiction, receiving system, measurement method, and controlled contract or regulation.