Skip to the content.

Enhanced Separator Entrainment Modeling

Physics-based, inlet-to-outlet separator performance calculation using open-literature correlations. This is an optional enhancement to the standard NeqSim separator that computes entrainment from first principles rather than user-specified fractions.

Package: neqsim.process.equipment.separator.entrainment

Table of Contents


Overview

Traditional NeqSim separators use user-specified entrainment fractions via setEntrainment(). The enhanced model instead derives entrainment from physical properties automatically:

Aspect Standard Model Enhanced Model
Entrainment source User-specified fractions Computed from DSD + vessel geometry
Flow regime Not considered Mandhane (horizontal), Taitel-Dukler (vertical)
Inlet device Not modeled 7 device types with momentum limits
Gravity section Not modeled Schiller-Naumann drag, cut diameter
Mist eliminator Not modeled Grade efficiency curve (wire mesh, vane, cyclone)
Liquid-liquid Not modeled Stokes settling with oil pad geometry
K-factor External Computed, with flooding detection

The enhanced model is enabled by a single flag and runs alongside the thermodynamic flash in the existing Separator and ThreePhaseSeparator classes.


Architecture

Inlet Pipe                    Separator Vessel
 ┌──────────┐    ┌─────────────────────────────────────────┐
 │ Flow     │    │  Inlet     Gravity     Mist             │
 │ Regime   │───>│  Device    Section     Eliminator        │──> Gas Out
 │ + DSD    │    │  (bulk     (settling)  (grade eff.)      │
 │ Predict  │    │   sep.)                                   │
 └──────────┘    │                                           │
                 │  Liquid-Liquid Section (3-phase only)     │
                 │  (oil/water settling, coalescence)        │──> Liquid Out(s)
                 └─────────────────────────────────────────┘

Key classes:

Class Purpose
SeparatorPerformanceCalculator Main orchestrator — routes through all stages
MultiphaseFlowRegime Predicts inlet flow regime, generates DSD
InletDeviceModel Models inlet device bulk separation + DSD transformation
SeparatorGeometryCalculator Vessel geometry for H/V vessels, K-factor
DropletSizeDistribution Rosin-Rammler and log-normal DSD models
DropletSettlingCalculator Schiller-Naumann terminal velocity
GradeEfficiencyCurve S-curve grade efficiency for mist eliminators
SeparatorInternalsDatabase CSV-backed database of internals specifications

Quick Start

Java — Two-Phase Separator with Enhanced Entrainment

import neqsim.process.equipment.separator.Separator;
import neqsim.process.equipment.separator.entrainment.*;
import neqsim.process.equipment.stream.Stream;
import neqsim.thermo.system.SystemSrkEos;

// Create fluid
SystemSrkEos fluid = new SystemSrkEos(273.15 + 30.0, 70.0);
fluid.addComponent("methane", 0.85);
fluid.addComponent("ethane", 0.10);
fluid.addComponent("n-heptane", 0.05);
fluid.setMixingRule("classic");

Stream feed = new Stream("Feed", fluid);
feed.setFlowRate(50000.0, "kg/hr");
feed.run();

// Create separator with enhanced entrainment
Separator separator = new Separator("HP Sep", feed);
separator.setInternalDiameter(2.0);
separator.setSeparatorLength(6.0);

// Enable enhanced mode
separator.setEnhancedEntrainmentCalculation(true);
separator.setInletDeviceType(InletDeviceModel.InletDeviceType.INLET_VANE);
separator.setInletPipeDiameter(0.254);  // 10-inch pipe

// Configure mist eliminator
separator.getPerformanceCalculator()
    .setMistEliminatorCurve(GradeEfficiencyCurve.wireMeshDefault());

separator.run();

// Results
System.out.println("Inlet flow regime: " + separator.getInletFlowRegime());
System.out.println("K-factor: " + separator.getKFactor());
System.out.println("K-factor utilization: " + separator.getKFactorUtilization());
System.out.println("Mist eliminator flooded: " + separator.isMistEliminatorFlooded());
System.out.println("Overall gas-liquid efficiency: "
    + separator.getPerformanceCalculator().getOverallGasLiquidEfficiency());

Python — Enhanced Separator

from neqsim import jneqsim
import jpype

# Classes
SystemSrkEos = jneqsim.thermo.system.SystemSrkEos
Stream = jneqsim.process.equipment.stream.Stream
Separator = jneqsim.process.equipment.separator.Separator
ProcessSystem = jneqsim.process.processmodel.ProcessSystem
InletDeviceModel = jneqsim.process.equipment.separator.entrainment.InletDeviceModel
GradeEfficiencyCurve = jneqsim.process.equipment.separator.entrainment.GradeEfficiencyCurve

# Fluid
fluid = SystemSrkEos(273.15 + 30.0, 70.0)
fluid.addComponent("methane", 0.85)
fluid.addComponent("ethane", 0.10)
fluid.addComponent("n-heptane", 0.05)
fluid.setMixingRule("classic")

feed = Stream("Feed", fluid)
feed.setFlowRate(50000.0, "kg/hr")

# Separator with enhanced mode
sep = Separator("HP Sep", feed)
sep.setInternalDiameter(2.0)
sep.setSeparatorLength(6.0)
sep.setEnhancedEntrainmentCalculation(True)
sep.setInletDeviceType(InletDeviceModel.InletDeviceType.INLET_VANE)
sep.setInletPipeDiameter(0.254)
sep.getPerformanceCalculator().setMistEliminatorCurve(
    GradeEfficiencyCurve.wireMeshDefault())

process = ProcessSystem()
process.add(feed)
process.add(sep)
process.run()

print(f"Inlet flow regime: {sep.getInletFlowRegime()}")
print(f"K-factor: {sep.getKFactor():.4f} m/s")
print(f"K-factor utilization: {sep.getKFactorUtilization():.1%}")
print(f"Overall efficiency: "
      f"{sep.getPerformanceCalculator().getOverallGasLiquidEfficiency():.2%}")

Calculation Chain (7 Stages)

When setEnhancedEntrainmentCalculation(true) is called, the SeparatorPerformanceCalculator executes a 7-stage pipeline. Each stage feeds the next.

Stage 1: Inlet Flow Regime Prediction

Class: MultiphaseFlowRegime

Predicts the multiphase flow regime in the inlet pipe using dimensionless superficial velocity maps:

Flow regimes (enum FlowRegime):

Regime Description Typical Gas Velocity
STRATIFIED_SMOOTH Separated layers, calm interface Low vsg, low vsl
STRATIFIED_WAVY Separated layers, wavy interface Moderate vsg, low vsl
SLUG Alternating liquid slugs and gas pockets Moderate vsg, moderate vsl
PLUG Elongated gas bubbles in liquid Low vsg, moderate vsl
ANNULAR Liquid film on wall, gas core High vsg
ANNULAR_MIST Annular with entrained droplets Very high vsg
DISPERSED_BUBBLE Small gas bubbles in liquid Low vsg, high vsl
CHURN Chaotic vertical oscillating flow Moderate-high vsg (vertical)
BUBBLE Discrete bubbles rising in liquid Low vsg (vertical)

API pattern (setter → predict → getter):

MultiphaseFlowRegime calc = new MultiphaseFlowRegime();
calc.setGasDensity(50.0);              // kg/m3
calc.setLiquidDensity(800.0);          // kg/m3
calc.setGasViscosity(1.0e-5);          // Pa.s
calc.setLiquidViscosity(1.0e-3);       // Pa.s
calc.setSurfaceTension(0.025);         // N/m
calc.setPipeDiameter(0.254);           // m
calc.setGasSuperficialVelocity(15.0);  // m/s
calc.setLiquidSuperficialVelocity(0.1); // m/s
calc.setPipeOrientation("horizontal"); // or "vertical"

calc.predict();

MultiphaseFlowRegime.FlowRegime regime = calc.getPredictedRegime();
DropletSizeDistribution dsd = calc.getGeneratedDSD();
double entrainedFraction = calc.calcEntrainedLiquidFraction();

The flow regime determines which DSD correlation is used in Stage 2.

Stage 2: Inlet Droplet Size Distribution

The DSD is generated automatically based on the predicted flow regime:

Flow Regime DSD Correlation Reference
Annular / Annular-Mist Azzopardi (1997) — Sauter mean diameter from Weber number and Reynolds number Azzopardi, B.J. (1997)
Stratified / Stratified-Wavy Ishii-Grolmes (1975) — entrainment onset and droplet generation from interfacial shear Ishii and Grolmes (1975)
Slug / Plug / Churn Hinze (1955) — maximum stable droplet from turbulent breakup Hinze (1955)
Bubble / Dispersed Bubble Hinze (1955) — applied for gas bubble breakup in liquid Hinze (1955)

The entrained liquid fraction is computed using the Oliemans, Pots, and Trompe (1986) correlation.

Alternatively, specify the DSD directly:

// Rosin-Rammler distribution
DropletSizeDistribution dsd = DropletSizeDistribution.rosinRammler(100e-6, 2.6);

// Log-normal distribution
DropletSizeDistribution dsd = DropletSizeDistribution.logNormal(80e-6, 0.8);

// Set on calculator
separator.getPerformanceCalculator().setGasLiquidDSD(dsd);

Stage 3: Inlet Device Modeling

Class: InletDeviceModel

Models the inlet device that distributes the feed into the vessel. The inlet device provides partial bulk separation of liquid from gas before the gravity section.

Device types (enum InletDeviceType):

Device Type Typical Bulk Efficiency Max Momentum [Pa] Pressure Drop Coeff. Typical Application
NONE 0% 0 Simple pipe entry
DEFLECTOR_PLATE 50-65% 1500-2000 0.5-0.6 Low-cost basic service
HALF_PIPE 65-75% 3000-3500 0.8-1.0 Moderate liquid load
INLET_VANE 75-85% 5000-7000 1.5-2.0 Standard gas-liquid separators
INLET_CYCLONE 85-95% 8000-10000 3.0-5.0 High-performance scrubbers
SCHOEPENTOETER 80-90% 7000-9000 2.0-3.0 Large diameter vessels
IMPINGEMENT_PLATE 55-70% 2000-3000 0.8-1.2 Slug catcher service

Key physics:

InletDeviceModel model = new InletDeviceModel(
    InletDeviceModel.InletDeviceType.INLET_VANE);
model.setInletNozzleDiameter(0.254);  // 10-inch

model.calculate(inletDSD, gasDensity, liquidDensity,
    gasVolumeFlow, liquidVolumeFlow, surfaceTension);

double bulkEff = model.getBulkSeparationEfficiency();
double momentum = model.getMomentumFlux();        // Pa
double pressureDrop = model.getPressureDrop();    // Pa
DropletSizeDistribution remainingDSD = model.getDownstreamDSD();

Stage 4: Vessel Geometry

Class: SeparatorGeometryCalculator

Computes exact vessel cross-sectional areas, gas/liquid heights, and residence times for both horizontal and vertical vessels.

Horizontal vessel geometry:

The gas and liquid cross-sectional areas are computed from the exact circular segment formula:

\[A_{liquid} = \frac{D^2}{4} \left[ \cos^{-1}\left(1 - \frac{2h}{D}\right) - \left(1 - \frac{2h}{D}\right)\sqrt{\frac{4h}{D} - \frac{4h^2}{D^2}} \right]\]

where $h$ is the liquid height and $D$ is the internal diameter.

Vertical vessel geometry:

\[A_{gas} = \frac{\pi D^2}{4}, \quad L_{gas} = L_{TT} \cdot (1 - f_{liquid})\]

The full cross-section is available for gas flow; the gas residence time depends on the effective gas height above the liquid level.

K-factor (Souders-Brown):

\[K = v_g \sqrt{\frac{\rho_g}{\rho_l - \rho_g}}\]

This static method is used to check flooding conditions:

double kFactor = SeparatorGeometryCalculator.calcKFactor(
    gasVelocity, gasDensity, liquidDensity);

API:

SeparatorGeometryCalculator geom = new SeparatorGeometryCalculator();
geom.setOrientation("horizontal");     // or "vertical"
geom.setInternalDiameter(2.0);         // m
geom.setTangentToTangentLength(6.0);   // m
geom.setNormalLiquidLevel(0.5);        // fraction of diameter

geom.calculate(gasVolumeFlow, liquidVolumeFlow);

double gasArea = geom.getGasArea();                   // m2
double liquidArea = geom.getLiquidArea();              // m2
double settlingHeight = geom.getEffectiveGasSettlingHeight();  // m
double gasResTime = geom.getGasResidenceTime();        // s
double liqResTime = geom.getLiquidResidenceTime();     // s

// Three-phase
geom.calculateThreePhase(gasVolumeFlow, oilVolumeFlow,
    waterVolumeFlow, oilLevelFraction);
double oilPad = geom.getOilPadThickness();             // m
double waterLayer = geom.getWaterLayerHeight();        // m

Stage 5: Gravity Settling Section

Class: DropletSettlingCalculator

Computes the terminal velocity of each droplet size class using the Schiller-Naumann drag correlation, which smoothly transitions from Stokes flow to Newton’s law:

\[C_D = \frac{24}{Re}\left(1 + 0.15 Re^{0.687}\right), \quad Re < 1000\] \[v_t = \sqrt{\frac{4 g d_p |\Delta\rho|}{3 C_D \rho_c}}\]

The gravity cut diameter is the smallest droplet that can settle across the effective settling height within the available residence time:

\[d_{cut} = d_p \text{ where } v_t(d_p) = \frac{H_{settle}}{t_{residence}}\]

Droplets smaller than $d_{cut}$ pass through the gravity section; larger droplets are captured.

// Single droplet terminal velocity
double vt = DropletSettlingCalculator.calcTerminalVelocity(
    dropletDiameter,   // m
    continuousDensity, // kg/m3 (gas for liquid droplets)
    dispersedDensity,  // kg/m3 (liquid for liquid droplets)
    continuousViscosity); // Pa.s

Stage 6: Mist Eliminator

Class: GradeEfficiencyCurve

Models separation internals using an S-shaped grade efficiency curve defined by $d_{50}$ (50% collection efficiency diameter) and maximum achievable efficiency:

\[\eta(d_p) = \eta_{max} \cdot \left[1 - \exp\left(-0.693 \left(\frac{d_p}{d_{50}}\right)^n\right)\right]\]

where $n$ is the sharpness parameter (typically 2-4).

Pre-configured internals types:

Factory Method $d_{50}$ Max $\eta$ Application
wireMeshDefault() 5 $\mu$m 99.8% Standard demisting pad
vanePackDefault() 15 $\mu$m 99.0% Higher capacity, coarser cut
axialCycloneDefault() 3 $\mu$m 99.8% Highest efficiency
platePack(d50, maxEff) Custom Custom Liquid-liquid coalescence

Overall efficiency integrates the grade efficiency over the DSD:

\[\eta_{overall} = \int_0^{\infty} \eta(d_p) \cdot f(d_p) \, dd_p\]
GradeEfficiencyCurve curve = GradeEfficiencyCurve.wireMeshDefault();

// Single-size efficiency
double eta100um = curve.getEfficiency(100e-6);  // ~99.8% for wire mesh

// Overall efficiency against a DSD
double etaOverall = curve.calcOverallEfficiency(dsd);

Flooding detection: If the K-factor exceeds the internals’ maximum K-factor (from the database), the mist eliminator is flagged as flooded and its efficiency is degraded.

Stage 7: Liquid-Liquid Separation (Three-Phase)

For ThreePhaseSeparator, the enhanced model also computes:

  1. Oil-in-water settling — water droplets rising through the oil pad
  2. Water-in-oil settling — oil droplets settling through the water layer
  3. Gas bubble carry-under — gas rising through the liquid phase

The liquid-liquid residence time uses the actual vessel geometry to determine the available settling time. Stokes settling velocity is used with the interfacial tension between oil and water phases.


Separator Internals Database

Class: SeparatorInternalsDatabase

A CSV-backed database of separator internals specifications, loaded as a singleton from src/main/resources/designdata/:

Internals Records

Each record in SeparatorInternals.csv contains:

Field Description Example
internalsType Category WIRE_MESH, VANE_PACK, AXIAL_CYCLONE, PLATE_PACK, GRAVITY
subType Variant Standard Knitted, Double Pocket, High Efficiency Tube
manufacturer Manufacturer Generic (extensible to vendor-specific)
d50_um 50% collection diameter [$\mu$m] 3.0 to 500.0
sharpness Grade efficiency curve sharpness 1.5 to 4.0
maxEfficiency Maximum achievable efficiency 0.90 to 0.999
maxKFactor Maximum K-factor before flooding [m/s] 0.04 to 0.30
minKFactor Minimum recommended K-factor [m/s] 0.01 to 0.05
pressureDrop_mbar Typical pressure drop [mbar] 0.1 to 10.0
designStandard Applicable standard API 12J, NORSOK P-100
material Construction material SS316L, Monel, Hastelloy C-276, PTFE, Titanium Gr2, Duplex 2205
maxTemperature_C Maximum operating temperature [C] 150 to 800
minThickness_mm Minimum pad/element thickness [mm] 50 to 300
weight_kg_m2 Installed weight per unit area [kg/m²] 10 to 120
reference Published reference Brunazzi and Paglianti (1998), El-Dessouky et al. (2000), York (2003)

Inlet Device Records

Each record in SeparatorInletDevices.csv contains:

Field Description Example
deviceType Category DEFLECTOR_PLATE, INLET_VANE, INLET_CYCLONE, etc.
subType Variant Flat Baffle, Multi-Tube, Standard
minMomentum_Pa Minimum recommended momentum [Pa] 0 to 1000
maxMomentum_Pa Maximum recommended momentum [Pa] 500 to 10000
typicalBulkEfficiency Typical bulk liquid separation efficiency 0.0 to 0.95
dsdMultiplier DSD transformation factor (downstream/upstream d50) 0.45 to 1.0
pressureDropCoeff Pressure loss coefficient 0.0 to 5.0
reference Published reference Bothamley (2013)

Querying the Database

SeparatorInternalsDatabase db = SeparatorInternalsDatabase.getInstance();

// Find all wire mesh types
List<SeparatorInternalsDatabase.InternalsRecord> meshes = db.findByType("WIRE_MESH");
for (SeparatorInternalsDatabase.InternalsRecord rec : meshes) {
    System.out.printf("%-30s  d50=%5.1f um  maxK=%.3f m/s  maxEff=%.3f%n",
        rec.subType, rec.d50_um, rec.maxKFactor, rec.maxEfficiency);
}

// Find specific variant
SeparatorInternalsDatabase.InternalsRecord hiEff =
    db.findByTypeAndSubType("WIRE_MESH", "High Efficiency");

// Convert to grade efficiency curve for calculations
GradeEfficiencyCurve curve = hiEff.toGradeEfficiencyCurve();

// Find inlet devices
List<SeparatorInternalsDatabase.InletDeviceRecord> vanes =
    db.findInletDeviceByType("INLET_VANE");

// Export full catalog as JSON
String json = db.toCatalogJson();

Extending the Database

Add rows to the CSV files to include vendor-specific or custom internals. The database reloads automatically on next getInstance() call after JVM restart. Fields are public for direct access — no getters needed.


Vendor-Certified Efficiency Curves

The database includes 25 vendor-certified grade efficiency curves from factory acceptance tests (FAT), stored in SeparatorVendorCurves.csv. Each curve contains 12 measured (droplet diameter, efficiency) points obtained from standardized testing (EN 13544, ISO 29042, or vendor in-house methods).

Vendor Curve Records

Field Description Example
curveId Unique identifier VC001, VC015
internalsType WIRE_MESH, VANE_PACK, AXIAL_CYCLONE, PLATE_PACK WIRE_MESH
vendorName Vendor name VendorA, VendorB
productFamily Product model designation WM-StdKnit-150, VP-DP-Standard
testStandard Test method EN 13544 / ISO 29042
testFluid Gas-liquid pair used Air-Water, N2-Exxsol
testPressure_bar Test pressure [bar] 1.0, 50.0
testTemperature_C Test temperature [°C] 20, 25
diameterPoints_um Measured droplet diameters [µm] 1;2;3;5;8;10;15;20;30;50;80;100
efficiencyPoints Measured collection efficiencies [0-1] 0.05;0.12;0.25;0.50;…
maxKFactor Maximum K-factor at test conditions [m/s] 0.107
testDate Factory acceptance test date 2022-03-15
certificateRef Certificate or report reference FAT-2022-001

Coverage

Internals Type Number of Curves Includes HP (50 bar)
WIRE_MESH 8 Yes (2 curves)
VANE_PACK 6 Yes (1 curve)
AXIAL_CYCLONE 6 Yes (1 curve)
PLATE_PACK 3 No
Total 25  

Querying Vendor Curves

SeparatorInternalsDatabase db = SeparatorInternalsDatabase.getInstance();

// All vendor curves
List<SeparatorInternalsDatabase.VendorCurveRecord> all = db.getAllVendorCurves();

// Find by internals type
List<SeparatorInternalsDatabase.VendorCurveRecord> meshCurves =
    db.findVendorCurvesByType("WIRE_MESH");

// Find by vendor
List<SeparatorInternalsDatabase.VendorCurveRecord> vendorACurves =
    db.findVendorCurvesByVendor("VendorA");

// Find specific curve by ID
SeparatorInternalsDatabase.VendorCurveRecord curve = db.findVendorCurveById("VC001");
System.out.println("Product: " + curve.productFamily);
System.out.println("Test pressure: " + curve.testPressure_bar + " bar");
System.out.println("Points: " + curve.diameterPoints_um.length);

// Convert to GradeEfficiencyCurve for calculations
GradeEfficiencyCurve gec = curve.toGradeEfficiencyCurve();
double eta10 = gec.getEfficiency(10e-6);  // Efficiency at 10 µm

// Find by type AND vendor
List<SeparatorInternalsDatabase.VendorCurveRecord> vendorBMesh =
    db.findVendorCurvesByTypeAndVendor("WIRE_MESH", "VendorB");

Using Vendor Curves in Simulation

// Use a specific vendor curve instead of the generic defaults
SeparatorInternalsDatabase db = SeparatorInternalsDatabase.getInstance();
SeparatorInternalsDatabase.VendorCurveRecord vc =
    db.findVendorCurveById("VC001");

separator.getPerformanceCalculator()
    .setMistEliminatorCurve(vc.toGradeEfficiencyCurve());

Python API

db = SeparatorInternalsDatabase.getInstance()

# Browse vendor curves
for vc in db.getAllVendorCurves():
    print(f"{vc.curveId:6s}  {vc.internalsType:15s}  {vc.vendorName:10s}  "
          f"{vc.productFamily:25s}  P={vc.testPressure_bar:.0f} bar")

# Get a specific curve and use it
curve = db.findVendorCurveById("VC001")
gec = curve.toGradeEfficiencyCurve()
print(f"Efficiency at 10 um: {gec.getEfficiency(10e-6):.3f}")

Droplet Size Distributions

Class: DropletSizeDistribution

Two statistical models are supported:

Rosin-Rammler Distribution

\[F(d) = 1 - \exp\left[-\left(\frac{d}{d_0}\right)^n\right]\]

where $d_0$ is the characteristic diameter (63.2% cumulative) and $n$ is the spread parameter (typically 2.0-4.0 for separator applications).

// d0 = 100 um, spread = 2.6
DropletSizeDistribution dsd = DropletSizeDistribution.rosinRammler(100e-6, 2.6);

Log-Normal Distribution

\[f(d) = \frac{1}{d \sigma \sqrt{2\pi}} \exp\left[-\frac{(\ln d - \ln d_{50})^2}{2\sigma^2}\right]\]
// d50 = 80 um, geometric standard deviation = 0.8
DropletSizeDistribution dsd = DropletSizeDistribution.logNormal(80e-6, 0.8);

Key Properties

double d50 = dsd.getD50();               // Median diameter [m]
double d32 = dsd.getSauterMeanDiameter(); // Volume-to-surface mean [m]

// Discrete classes for numerical integration (20 bins)
double[][] classes = dsd.getDiscreteClasses();
// Each row: [d_lower, d_mid, volume_fraction]

Grade Efficiency Curves

Class: GradeEfficiencyCurve

The S-shaped collection efficiency function characterizes any separation device (mist eliminator, coalescer, gravity section):

// Pre-configured types
GradeEfficiencyCurve wireMesh = GradeEfficiencyCurve.wireMeshDefault();
GradeEfficiencyCurve vanePack = GradeEfficiencyCurve.vanePackDefault();
GradeEfficiencyCurve cyclone  = GradeEfficiencyCurve.axialCycloneDefault();

// Custom curve
GradeEfficiencyCurve custom = GradeEfficiencyCurve.platePack(20e-6, 0.98);

// From database record
SeparatorInternalsDatabase db = SeparatorInternalsDatabase.getInstance();
GradeEfficiencyCurve fromDB = db.findByTypeAndSubType("VANE_PACK", "Double Pocket")
    .toGradeEfficiencyCurve();

// Query efficiency
double eta = wireMesh.getEfficiency(10e-6);  // Efficiency at 10 um
double overall = wireMesh.calcOverallEfficiency(dsd);  // Integrated over DSD

Calibration Framework

The enhanced model includes a structured calibration system for matching model predictions to plant or laboratory measurements. Three independent calibration multipliers adjust three categories of entrainment:

Multiplier Affects Default
liquidInGasCalibrationFactor Oil-in-gas, water-in-gas 1.0
gasCarryUnderCalibrationFactor Gas-in-oil, gas-in-water 1.0
liquidLiquidCalibrationFactor Oil-in-water, water-in-oil 1.0

Manual Calibration

Set factors directly:

SeparatorPerformanceCalculator perf = separator.getPerformanceCalculator();
perf.setLiquidInGasCalibrationFactor(1.5);     // 50% more carryover than model
perf.setGasCarryUnderCalibrationFactor(0.8);   // 20% less gas carry-under
perf.setLiquidLiquidCalibrationFactor(2.0);    // double liq-liq cross-contamination

Auto-Calibration from a Single Measurement

Fit factors to one set of measured fractions:

SeparatorPerformanceCalculator.CalibrationSummary summary =
    perf.calibrateFromMeasuredFractions(
        1.5e-3,   // measured oil-in-gas fraction
        0.0,      // measured water-in-gas (0 if not measured)
        8.0e-3,   // measured gas-in-oil
        0.0,      // measured gas-in-water
        2.0e-2,   // measured oil-in-water
        0.0,      // measured water-in-oil
        1e-12);   // model floor (avoid divide-by-zero)

System.out.println("New liquid-in-gas factor: " + summary.newLiquidInGasFactor);
System.out.println("New gas carry-under factor: " + summary.newGasCarryUnderFactor);
System.out.println("New liquid-liquid factor: " + summary.newLiquidLiquidFactor);

Grouped-Measurement Convenience

When plant data is reported as grouped categories (not individual fractions):

SeparatorPerformanceCalculator.CalibrationSummary summary =
    perf.calibrateFromGroupedMeasurements(
        1.5e-3,   // measured grouped liquid-in-gas
        8.0e-3,   // measured grouped gas carry-under
        2.0e-2,   // measured grouped liquid-liquid
        1e-12);   // model floor

Batch Calibration from CSV Case Library

Fit calibration factors across multiple operating points from a CSV file:

// Load calibration cases from CSV
List<SeparatorPerformanceCalculator.CalibrationCase> cases =
    SeparatorPerformanceCalculator.loadCalibrationCasesFromCsv(
        "src/main/resources/designdata/SeparatorCalibrationCasesTemplate.csv");

// Fit (finds median ratio across all cases)
SeparatorPerformanceCalculator.BatchCalibrationSummary fit =
    perf.calibrateFromCaseLibrary(cases, 1e-12);

System.out.println("Cases: " + fit.nCases);
System.out.println("Before MAPE: " + fit.beforeMAPE);
System.out.println("After MAPE: " + fit.afterMAPE);

JSON Calibration Report

Generate a comprehensive report with per-case residuals:

String report = perf.buildBatchCalibrationReportJson(cases, fit);
System.out.println(report);  // JSON with calibrationFactors, caseResults, summary

// Or save to file
perf.saveBatchCalibrationReportJson("calibration_report.json", cases, fit);

Using the Enhanced Mode

Java API

The enhanced mode is activated on a Separator or ThreePhaseSeparator via convenience methods that delegate to the internal SeparatorPerformanceCalculator:

Separator sep = new Separator("V-100", feed);
sep.setInternalDiameter(2.0);
sep.setSeparatorLength(6.0);

// ── Enable enhanced mode ──
sep.setEnhancedEntrainmentCalculation(true);

// ── Configure inlet device ──
sep.setInletDeviceType(InletDeviceModel.InletDeviceType.INLET_VANE);
sep.setInletPipeDiameter(0.254);          // 10-inch feed pipe
sep.setGasLiquidSurfaceTension(0.025);    // N/m (optional override)

// ── Configure mist eliminator ──
sep.getPerformanceCalculator()
    .setMistEliminatorCurve(GradeEfficiencyCurve.wireMeshDefault());

// ── Run ──
sep.run();

// ── Results ──
// Flow regime at inlet
MultiphaseFlowRegime.FlowRegime regime = sep.getInletFlowRegime();

// Souders-Brown K-factor and utilization (% of max K before flooding)
double kFactor = sep.getKFactor();
double kUtil = sep.getKFactorUtilization();

// Flooding check
boolean flooded = sep.isMistEliminatorFlooded();

// Detailed performance from calculator
SeparatorPerformanceCalculator perf = sep.getPerformanceCalculator();
double gravityEff = perf.getGravitySectionEfficiency();
double meEff = perf.getMistEliminatorEfficiency();
double overallEff = perf.getOverallGasLiquidEfficiency();
double dCut = perf.getGravityCutDiameter();

// Entrainment fractions (fed back into Separator outlet compositions)
double oilInGas = perf.getOilInGasFraction();
double waterInGas = perf.getWaterInGasFraction();
double gasInOil = perf.getGasInOilFraction();

// Full JSON report
String json = perf.toJson();

// Optional: one-point grouped calibration from measured field data
// (liquid-in-gas, gas carry-under, liquid-liquid)
perf.calibrateFromGroupedMeasurements(
    1.5e-3, // measured grouped liquid-in-gas
    8.0e-3, // measured grouped gas carry-under
    2.0e-2, // measured grouped liquid-liquid cross-contamination
    1e-12); // model floor

// Optional: batch calibration from a field-case library CSV
List<SeparatorPerformanceCalculator.CalibrationCase> cases =
    SeparatorPerformanceCalculator.loadCalibrationCasesFromCsv(
        "src/main/resources/designdata/SeparatorCalibrationCasesTemplate.csv");
SeparatorPerformanceCalculator.BatchCalibrationSummary fit =
    perf.calibrateFromCaseLibrary(cases, 1e-12);

Advanced: Direct Calculator Usage

For standalone calculations without a Separator equipment object:

SeparatorPerformanceCalculator calc = new SeparatorPerformanceCalculator();

// Set inlet DSD (manual or from flow regime prediction)
calc.setGasLiquidDSD(DropletSizeDistribution.rosinRammler(100e-6, 2.6));

// Set mist eliminator
calc.setMistEliminatorCurve(GradeEfficiencyCurve.vanePackDefault());

// Enable enhanced mode
calc.setUseEnhancedCalculation(true);
calc.setInletPipeDiameter(0.254);
calc.setSurfaceTension(0.025);
calc.setInletDeviceModel(
    new InletDeviceModel(InletDeviceModel.InletDeviceType.INLET_VANE));

// Run: gas density, oil density, water density,
//      gas viscosity, oil viscosity, water viscosity,
//      gas velocity, separator diameter, separator length,
//      orientation, liquid level fraction
calc.calculate(
    50.0, 800.0, 0.0,          // densities (0 = no water)
    1.5e-5, 3.0e-3, 0.0,       // viscosities
    3.0, 2.0, 6.0,             // velocity, diameter, length
    "horizontal", 0.5);         // orientation, liquid level

// Get results
double overallEff = calc.getOverallGasLiquidEfficiency();
double kFactor = calc.getKFactor();

Python API

from neqsim import jneqsim

# Import entrainment classes
InletDeviceModel = jneqsim.process.equipment.separator.entrainment.InletDeviceModel
GradeEfficiencyCurve = jneqsim.process.equipment.separator.entrainment.GradeEfficiencyCurve
DropletSizeDistribution = jneqsim.process.equipment.separator.entrainment.DropletSizeDistribution
SeparatorInternalsDatabase = jneqsim.process.equipment.separator.entrainment.SeparatorInternalsDatabase
MultiphaseFlowRegime = jneqsim.process.equipment.separator.entrainment.MultiphaseFlowRegime

# Query internals database
db = SeparatorInternalsDatabase.getInstance()
all_internals = list(db.getAllInternals())
for rec in all_internals:
    print(f"{rec.internalsType:15s} {rec.subType:25s} "
          f"d50={rec.d50_um:6.1f} um  maxK={rec.maxKFactor:.3f} m/s")

# Create custom DSD
dsd = DropletSizeDistribution.rosinRammler(100e-6, 2.6)
print(f"D50 = {dsd.getD50() * 1e6:.1f} um")
print(f"D32 = {dsd.getSauterMeanDiameter() * 1e6:.1f} um")

# Predict flow regime
regime_calc = MultiphaseFlowRegime()
regime_calc.setGasDensity(50.0)
regime_calc.setLiquidDensity(800.0)
regime_calc.setGasViscosity(1.0e-5)
regime_calc.setLiquidViscosity(1.0e-3)
regime_calc.setSurfaceTension(0.025)
regime_calc.setPipeDiameter(0.254)
regime_calc.setGasSuperficialVelocity(15.0)
regime_calc.setLiquidSuperficialVelocity(0.1)
regime_calc.setPipeOrientation("horizontal")
regime_calc.predict()
print(f"Flow regime: {regime_calc.getPredictedRegime()}")

JSON Output

The toJson() method on SeparatorPerformanceCalculator produces a comprehensive JSON report. When enhanced mode is active, it includes additional sections:

{
  "gasLiquidDSD": {
    "type": "ROSIN_RAMMLER",
    "characteristicDiameter_m": 1.0e-4,
    "spreadParameter": 2.6,
    "d50_m": 8.3e-5,
    "sauterMeanDiameter_m": 7.1e-5
  },
  "gravitySectionEfficiency": 0.72,
  "gravityCutDiameter_m": 4.5e-5,
  "mistEliminatorEfficiency": 0.998,
  "overallGasLiquidEfficiency": 0.9994,
  "oilInGasFraction": 6.0e-4,
  "waterInGasFraction": 0.0,
  "gasInOilFraction": 0.002,
  "enhancedResults": {
    "inletFlowRegime": "ANNULAR",
    "kFactor_m_s": 0.068,
    "kFactorUtilization": 0.63,
    "mistEliminatorFlooded": false,
    "inletDeviceBulkEfficiency": 0.82,
    "inletDeviceMomentumFlux_Pa": 3200,
    "inletDevicePressureDrop_Pa": 450,
    "gasResidenceTime_s": 8.5,
    "liquidResidenceTime_s": 120.0,
    "gasSettlingHeight_m": 0.95,
    "postInletDeviceDSD": {
      "type": "ROSIN_RAMMLER",
      "characteristicDiameter_m": 5.5e-5,
      "spreadParameter": 2.6
    }
  }
}

Mechanical Design Integration

When detailed entrainment calculation is enabled, the SeparatorMechanicalDesign class automatically pulls performance results from the SeparatorPerformanceCalculator into the mechanical design output. This means calcDesign() and toJson() include entrainment fractions, efficiency metrics, calibration factors, and the full performance calculator JSON — all in a single design report.

How It Works

  1. Enable detailed entrainment on the separator: separator.setDetailedEntrainmentCalculation(true)
  2. Run the separator: separator.run() — this executes the performance calculator
  3. Call calcDesign() on the mechanical design — at the end, it calls populateEntrainmentResults() which copies all performance data from the calculator into the design object
  4. Call toJson() — the response includes both vessel sizing data AND entrainment performance

Fields Added to Mechanical Design JSON

Field Type Description
detailedEntrainmentUsed boolean Whether detailed entrainment was active
oilInGasFraction double Oil-in-gas carryover (volume basis, 0-1)
waterInGasFraction double Water-in-gas carryover (volume basis, 0-1)
gasInOilFraction double Gas carry-under into oil (volume basis, 0-1)
gasInWaterFraction double Gas carry-under into water (volume basis, 0-1)
oilInWaterFraction double Oil-in-water (volume basis, 0-1)
waterInOilFraction double Water-in-oil (volume basis, 0-1)
overallGasLiquidEfficiency double Combined gravity + ME efficiency (0-1)
mistEliminatorEfficiency double Mist eliminator efficiency alone (0-1)
kFactorUtilization double Actual K / design K (0-1)
mistEliminatorFlooded boolean True if K-factor exceeds ME capacity
liquidInGasCalibrationFactor double Calibration multiplier (1.0 = uncalibrated)
gasCarryUnderCalibrationFactor double Calibration multiplier (1.0 = uncalibrated)
liquidLiquidCalibrationFactor double Calibration multiplier (1.0 = uncalibrated)
entrainmentDetailJson String Full SeparatorPerformanceCalculator.toJson() output

Java Example

Separator separator = new Separator("HP Sep", feedStream);
separator.setDetailedEntrainmentCalculation(true);
separator.run();

SeparatorMechanicalDesign design =
    (SeparatorMechanicalDesign) separator.getMechanicalDesign();
design.calcDesign();

// Entrainment data is now part of the mechanical design
double efficiency = design.getOverallGasLiquidEfficiency();
double oilCarryover = design.getOilInGasFraction();
boolean flooded = design.isMistEliminatorFlooded();

// Full JSON includes vessel sizing + entrainment performance
String json = design.toJson();

Python Example

from neqsim import jneqsim
import json

Separator = jneqsim.process.equipment.separator.Separator

sep = Separator("HP Sep", feed_stream)
sep.setDetailedEntrainmentCalculation(True)
sep.run()

design = sep.getMechanicalDesign()
design.calcDesign()

print(f"Efficiency: {design.getOverallGasLiquidEfficiency():.2%}")
print(f"Oil in gas: {design.getOilInGasFraction():.4f}")
print(f"ME flooded: {design.isMistEliminatorFlooded()}")

# Full JSON report
report = json.loads(str(design.toJson()))

Calibration Factors in Design Reports

When the performance calculator has been calibrated (via calibrateFromMeasuredFractions() or batch CSV calibration), the calibration factors are carried through to the mechanical design JSON. This provides full traceability from measured plant data to the design report.

// Calibrate, then generate design
SeparatorPerformanceCalculator perf = separator.getPerformanceCalculator();
perf.calibrateFromMeasuredFractions(measuredOilInGas, measuredGasInOil, measuredOilInWater);

// Re-run separator with calibrated calculator
separator.run();

// Design now includes calibration factors
design.calcDesign();
assert design.getLiquidInGasCalibrationFactor() != 1.0; // calibrated

Dynamic Simulation Integration

The enhanced entrainment model is fully integrated with NeqSim’s transient (dynamic) simulation via runTransient(). When enabled, the separator recalculates entrainment fractions at every timestep using live vessel conditions, then applies those fractions to outlet stream compositions—without disturbing the vessel mass/energy balance.

How It Works

During each runTransient(dt, id) call the following sequence executes:

  1. VU flash — The standard volume-energy (VU) flash solves for the new vessel state given inlet/outlet mass flows and energy balance.
  2. Performance calculator update — If enhanced entrainment is enabled, the calculator reads physical properties directly from the post-flash vessel state (thermoSystem), estimates gas velocity from the previous-timestep outlet stream, and runs the full 7-stage calculation chain.
  3. Clone and redistribute — The vessel inventory is cloned (never modified), and addPhaseFractionToPhase() is applied to the clone to model imperfect separation. Outlet stream compositions are set from the modified clone.
  4. Vessel inventory preserved — The original thermoSystem (mass balance state) is untouched. Entrainment only affects what leaves the vessel, not what is stored in it.

This design ensures that the dynamic mass balance remains conserved while outlet quality responds to changing conditions in real time.

Enabling Entrainment in Dynamic Mode

Java API

// Create separator
Separator separator = new Separator("V-100", feed);
separator.setOrientation("horizontal");
separator.setSeparatorLength(5.0);
separator.setInternalDiameter(1.5);
separator.setLiquidLevel(0.5);

// Enable enhanced entrainment (auto-generates DSD from flow regime)
separator.setEnhancedEntrainmentCalculation(true);

// Switch to transient mode
separator.setCalculateSteadyState(false);

// Initial steady-state run
separator.run();

// Transient loop
UUID id = UUID.randomUUID();
double dt = 1.0; // seconds
for (int step = 0; step < 3600; step++) {
    separator.runTransient(dt, id);

    // Read current entrainment fractions (updated each timestep)
    SeparatorPerformanceCalculator perf = separator.getPerformanceCalculator();
    double oilInGas = perf.getOilInGasFraction();
    double gasInOil = perf.getGasInOilFraction();
}

Python API

from neqsim import jneqsim
import java.util.UUID as UUID

Separator = jneqsim.process.equipment.separator.Separator

separator = Separator("V-100", feed)
separator.setOrientation("horizontal")
separator.setSeparatorLength(5.0)
separator.setInternalDiameter(1.5)
separator.setLiquidLevel(0.5)
separator.setEnhancedEntrainmentCalculation(True)
separator.setCalculateSteadyState(False)
separator.run()

sim_id = UUID.randomUUID()
dt = 1.0

for step in range(3600):
    separator.runTransient(dt, sim_id)
    level = separator.getLiquidLevel()
    perf = separator.getPerformanceCalculator()
    oil_in_gas = perf.getOilInGasFraction()

Three-Phase Separator

ThreePhaseSeparator follows the same pattern but tracks all six entrainment paths:

Path From Phase To Phase
Oil-in-gas Oil Gas
Water-in-gas Aqueous Gas
Gas-in-oil Gas Oil
Gas-in-water Gas Aqueous
Oil-in-water Oil Aqueous
Water-in-oil Aqueous Oil
ThreePhaseSeparator sep3 = new ThreePhaseSeparator("V-200", feed);
sep3.setEnhancedEntrainmentCalculation(true);
sep3.setCalculateSteadyState(false);
sep3.run();

UUID id = UUID.randomUUID();
for (int step = 0; step < 3600; step++) {
    sep3.runTransient(1.0, id);
    // Gas, oil, and water outlets all have entrainment-corrected compositions
}

Key Design Notes

Aspect Detail
Gas velocity source Estimated from gas outlet stream flow rate (previous timestep), not from vessel inventory
Liquid level Read from liquidLevel field, which is updated each timestep by the VU flash
Oil volume fraction Computed from vessel phase volumes (moles × molar volume)
Vessel inventory Never modified by entrainment—only outlet compositions change
Backward compatible Entrainment only activates when setEnhancedEntrainmentCalculation(true) is called; default behavior unchanged
Standard vs enhanced The enhanced path auto-generates DSD from flow regime prediction; the standard path requires explicit DSD setup
Manual fractions setEntrainment() fractions are also applied during runTransient() (no calculator needed)

Monitoring Entrainment Over Time

Track entrainment fractions across timesteps to observe how they respond to feed disturbances, pressure changes, or liquid level swings:

List<Double> oilInGasHistory = new ArrayList<>();
List<Double> gasVelocityHistory = new ArrayList<>();

for (int step = 0; step < totalSteps; step++) {
    separator.runTransient(dt, id);

    SeparatorPerformanceCalculator perf = separator.getPerformanceCalculator();
    oilInGasHistory.add(perf.getOilInGasFraction());

    // Also track gas velocity to correlate with entrainment
    // gasVelocityHistory.add(perf.getGasVelocity()); // if exposed
}

In Python with matplotlib:

import matplotlib.pyplot as plt

times, oil_in_gas_vals, levels = [], [], []
for step in range(total_steps):
    separator.runTransient(dt, sim_id)
    times.append(step * dt)
    oil_in_gas_vals.append(separator.getPerformanceCalculator().getOilInGasFraction())
    levels.append(separator.getLiquidLevel())

fig, (ax1, ax2) = plt.subplots(2, 1, sharex=True)
ax1.plot(times, oil_in_gas_vals)
ax1.set_ylabel("Oil-in-Gas Fraction")
ax2.plot(times, levels)
ax2.set_ylabel("Liquid Level (m)")
ax2.set_xlabel("Time (s)")
plt.tight_layout()
plt.show()

Correlations and References

Correlation Application Reference
Mandhane-Gregory-Aziz flow map Horizontal flow regime prediction Mandhane, J.M., Gregory, G.A., Aziz, K. (1974). A flow pattern map for gas-liquid flow in horizontal pipes. Int. J. Multiphase Flow, 1(4), 537-553.
Taitel-Dukler-Barnea Vertical flow regime transitions Taitel, Y., Dukler, A.E. (1976); Barnea, D. (1987). A unified model for predicting flow-pattern transitions. Int. J. Multiphase Flow, 13(1), 1-12.
Azzopardi d32 Annular flow Sauter mean diameter Azzopardi, B.J. (1997). Drops in annular two-phase flow. Int. J. Multiphase Flow, 23, 1-53.
Ishii-Grolmes Stratified flow entrainment onset Ishii, M., Grolmes, M.A. (1975). Inception criteria for droplet entrainment in two-phase concurrent film flow. AIChE J., 21(2), 308-318.
Hinze Turbulent droplet breakup Hinze, J.O. (1955). Fundamentals of the hydrodynamic mechanism of splitting in dispersion processes. AIChE J., 1(3), 289-295.
Oliemans et al. Entrained liquid fraction Oliemans, R.V.A., Pots, B.F.M., Trompe, N. (1986). Modelling of annular dispersed two-phase flow in vertical pipes. Int. J. Multiphase Flow, 12(5), 711-732.
Schiller-Naumann Drag coefficient correlation Schiller, L., Naumann, A. (1933). Uber die grundlegenden Berechnungen bei der Schwerkraftaufbereitung. Z. Ver. Dtsch. Ing., 77, 318-320.
Souders-Brown K-factor for mist eliminator flooding Souders, M., Brown, G.G. (1934). Design of fractionating columns. Ind. Eng. Chem., 26(1), 98-103.
Bothamley Inlet device momentum limits Bothamley, M. (2013). Gas/Liquid Separators: Quantifying Separation Performance. Oil Gas Facilities, 2(4), 21-29.
Brunazzi-Paglianti Wire mesh demister performance Brunazzi, E., Paglianti, A. (1998). Design of wire mesh mist eliminators. AIChE J., 44(3), 505-512.
Csanady Turbulent diffusion cut-diameter correction Csanady, G.T. (1963). Turbulent diffusion of heavy particles in the atmosphere. J. Atmos. Sci., 20(3), 201-208.
Koenders et al. Turbulence intensity from K-factor load Koenders, M.A. et al. (2015). Gas-liquid separation: prediction of liquid carryover from gravity settlers. SPE J., 20(4), 810-822.
API 12J Compliance thresholds (K, cut diameter, HRT) API Specification 12J (2014). Specification for Oil and Gas Separators. American Petroleum Institute.
Fabian et al. / GPSA Partial flooding efficiency degradation Fabian, P. et al. (1993). Demisting applications. Chem. Eng. Progress, 89(10), 58-63; GPSA Engineering Data Book (14th ed.), Ch. 7.
Hinze Liquid-liquid droplet breakup (oil-water DSD) Hinze, J.O. (1955). Fundamentals of the hydrodynamic mechanism of splitting in dispersion processes. AIChE J., 1(3), 289-295.

Class Reference

SeparatorPerformanceCalculator

Main orchestrator. Call calculate() with fluid properties and vessel geometry.

Method Description
calculate(...) Run standard or enhanced calculation
setUseEnhancedCalculation(boolean) Switch between standard and enhanced
setGasLiquidDSD(DropletSizeDistribution) Set inlet DSD (overrides flow regime prediction)
setMistEliminatorCurve(GradeEfficiencyCurve) Set mist eliminator grade efficiency
setInletDeviceModel(InletDeviceModel) Set inlet device
setFlowRegimeCalculator(MultiphaseFlowRegime) Set flow regime predictor
setGeometryCalculator(SeparatorGeometryCalculator) Set vessel geometry
setInletPipeDiameter(double) Feed pipe diameter [m]
setSurfaceTension(double) Gas-liquid interfacial tension [N/m]
setOilWaterInterfacialTension(double) Oil-water interfacial tension [N/m]
setLiquidInGasCalibrationFactor(double) Calibration multiplier for liquid-in-gas fractions
setGasCarryUnderCalibrationFactor(double) Calibration multiplier for gas carry-under fractions
setLiquidLiquidCalibrationFactor(double) Calibration multiplier for liquid-liquid fractions
calibrateFromMeasuredFractions(...) Auto-calibrate from measured entrainment fractions
calibrateFromGroupedMeasurements(...) Auto-calibrate from grouped measurement categories
static loadCalibrationCasesFromCsv(String) Load calibration cases from CSV file
calibrateFromCaseLibrary(List, double) Batch fit factors across multiple cases
buildBatchCalibrationReportJson(List, BatchCalibrationSummary) JSON calibration report
saveBatchCalibrationReportJson(String, List, BatchCalibrationSummary) Save report to file
setOilVolumeFraction(double) Oil fraction in liquid for 3-phase geometry [0-1] — auto-set from EOS when running via Separator
setApplyTurbulenceCorrection(boolean) Enable/disable Csanady turbulence correction (default: true)
getApiComplianceResult() API 12J compliance result after calculate()
static generateLiquidLiquidDSD(sigma, rhoCont, vNozzle, dNozzle) Hinze-based oil-water DSD from inlet conditions
getOverallGasLiquidEfficiency() Combined gravity + mist eliminator efficiency
getGravitySectionEfficiency() Gravity section efficiency alone
getMistEliminatorEfficiency() Mist eliminator efficiency alone
getGravityCutDiameter() Smallest droplet removed by gravity [m]
getKFactor() Souders-Brown K-factor [m/s]
getKFactorUtilization() K-factor as fraction of max allowed
isMistEliminatorFlooded() True if K exceeds internals max K
getInletFlowRegime() Predicted flow regime
getPostInletDeviceDSD() DSD after inlet device separation
toJson() Full results as JSON string

MultiphaseFlowRegime

Method Description
setGasDensity(double) Gas density [kg/m3]
setLiquidDensity(double) Liquid density [kg/m3]
setGasViscosity(double) Gas dynamic viscosity [Pa.s]
setLiquidViscosity(double) Liquid dynamic viscosity [Pa.s]
setSurfaceTension(double) Gas-liquid surface tension [N/m]
setPipeDiameter(double) Pipe inner diameter [m]
setGasSuperficialVelocity(double) Gas superficial velocity [m/s]
setLiquidSuperficialVelocity(double) Liquid superficial velocity [m/s]
setPipeOrientation(String) “horizontal” or “vertical”
predict() Run prediction (no arguments)
getPredictedRegime() Get result FlowRegime enum
getGeneratedDSD() Get auto-generated DSD
calcEntrainedLiquidFraction() Oliemans et al. correlation

InletDeviceModel

Method Description
InletDeviceModel(InletDeviceType) Constructor with device type
setInletNozzleDiameter(double) Nozzle diameter [m]
calculate(DSD, gasDens, liqDens, gasFlow, liqFlow, sigma) Run calculation
getBulkSeparationEfficiency() Fraction of liquid removed at inlet
getDownstreamDSD() DSD after inlet device
getNozzleVelocity() Mixture velocity at nozzle [m/s]
getMomentumFlux() Inlet momentum $\rho v^2$ [Pa]
getPressureDrop() Device pressure drop [Pa]

SeparatorGeometryCalculator

Method Description
setOrientation(String) “horizontal” or “vertical”
setInternalDiameter(double) Vessel ID [m]
setTangentToTangentLength(double) Vessel length [m]
setNormalLiquidLevel(double) Liquid level as fraction of diameter
calculate(gasFlow, liqFlow) Two-phase geometry
calculateThreePhase(gasFlow, oilFlow, waterFlow, oilFrac) Three-phase
getGasArea() / getLiquidArea() Cross-sectional areas [m2]
getEffectiveGasSettlingHeight() Gas settling height [m]
getEffectiveLiquidSettlingHeight() Liquid settling height [m]
getGasResidenceTime() / getLiquidResidenceTime() Residence times [s]
getOilPadThickness() / getWaterLayerHeight() Three-phase heights [m]
static calcKFactor(vGas, rhoGas, rhoLiq) Souders-Brown K [m/s]

DropletSizeDistribution

Method Description
static rosinRammler(d0, n) Create Rosin-Rammler DSD
static logNormal(d50, sigma) Create log-normal DSD
getD50() Median diameter [m]
getSauterMeanDiameter() Volume-surface mean d32 [m]
getDiscreteClasses() 20-bin discretization
getCumulativeFraction(d) CDF at diameter d

DropletSettlingCalculator

Method Description
static calcTerminalVelocity(d, rhoCont, rhoDisp, muCont) Terminal velocity [m/s]
static calcDragCoefficient(Re) Schiller-Naumann drag
static calcTurbulenceCorrectedCutDiameter(dCut, vGas, H, kFactor, kDesign, rhoGas, rhoLiq, muGas) Csanady (1963) turbulence-corrected effective cut diameter [m]
static checkApi12JCompliance(dCut, kFactor, hasME, liquidHRT, orientation, isThreePhase) API 12J compliance check returning ApiComplianceResult

GradeEfficiencyCurve

Method Description
static wireMeshDefault() Standard wire mesh pad
static vanePackDefault() Standard vane pack
static axialCycloneDefault() Standard axial cyclone
static platePack(d50, maxEff) Custom plate pack
getEfficiency(d) Grade efficiency at diameter d
calcOverallEfficiency(DSD) Integrated efficiency over DSD

SeparatorInternalsDatabase

Method Description
static getInstance() Singleton accessor
findByType(String) Find internals by type
findByTypeAndSubType(String, String) Find specific variant
findInletDeviceByType(String) Find inlet devices by type
getAllInternals() All internals records (70+)
getAllInletDevices() All inlet device records (31)
getAllVendorCurves() All vendor curve records (25)
findVendorCurvesByType(String) Find vendor curves by internals type
findVendorCurvesByVendor(String) Find vendor curves by vendor name
findVendorCurveById(String) Find a specific vendor curve by ID
findVendorCurvesByTypeAndVendor(String, String) Find curves by type and vendor
toCatalogJson() Full catalog as JSON (internals + inlet devices + vendor curves)