Skip to the content.

TwoFluidPipe Reporting and Validation

This page describes how to extract engineering results from neqsim.process.equipment.pipeline.TwoFluidPipe for long multiphase flowlines and how to compare those results with external simulator or field data.

Current reporting status

TwoFluidPipe exposes detailed profile and summary APIs. The convenience class neqsim.process.equipment.pipeline.twophasepipe.reporting.TwoFluidPipeReport builds standard CSV, text, JSON, event, and benchmark comparison outputs from those APIs.

The recommended production workflow is:

  1. Build and run the TwoFluidPipe model.
  2. Extract spatial profiles from the pipe, or call TwoFluidPipeReport helper methods.
  3. Add summary metrics and flow-assurance indicators.
  4. Export to CSV/JSON for plotting, review, or comparison.
  5. If available, compare against OLGA, LedaFlow, or field data using the benchmark harness.

Steady-state profile reporting

After pipe.run(), the following methods provide one value per pipe section:

API Unit Description
getPositionProfile() m Section midpoint positions
getPressureProfile() Pa Pressure profile
getTemperatureProfile() K Fluid temperature profile
getTemperatureProfile("C") degC Fluid temperature profile in Celsius
getLiquidHoldupProfile() fraction Total liquid holdup
getWaterCutProfile() fraction Water fraction of liquid
getOilHoldupProfile() fraction Oil holdup
getWaterHoldupProfile() fraction Water holdup
getGasVelocityProfile() m/s Gas velocity
getLiquidVelocityProfile() m/s Liquid velocity
getOilVelocityProfile() m/s Oil velocity when oil-water slip is active
getWaterVelocityProfile() m/s Water velocity when oil-water slip is active
getOilWaterSlipProfile() m/s Oil velocity minus water velocity
getFlowRegimeProfile() enum Gas-liquid flow regime by section
getHeatTransferProfile() W/(m2 K) Heat-transfer coefficient profile, when configured
getSurfaceTemperatureProfile() K Ambient/surface temperature profile, when configured

Example Java extraction:

pipe.run();

double[] x = pipe.getPositionProfile();
double[] pressureBara = pipe.getPressureProfile();
double[] temperatureC = pipe.getTemperatureProfile("C");
double[] liquidHoldup = pipe.getLiquidHoldupProfile();
double[] waterCut = pipe.getWaterCutProfile();
double[] gasVelocity = pipe.getGasVelocityProfile();
double[] liquidVelocity = pipe.getLiquidVelocityProfile();
PipeSection.FlowRegime[] regimes = pipe.getFlowRegimeProfile();

for (int i = 0; i < x.length; i++) {
  double pBara = pressureBara[i] * 1.0e-5;
  System.out.printf("%8.1f,%10.4f,%8.3f,%8.5f,%8.5f,%8.3f,%8.3f,%s%n",
      x[i], pBara, temperatureC[i], liquidHoldup[i], waterCut[i],
      gasVelocity[i], liquidVelocity[i], regimes[i]);
}

The same steady-state results can be exported directly:

String profileCsv = TwoFluidPipeReport.toSteadyStateProfileCsv(pipe);
String summaryText = TwoFluidPipeReport.toSummaryText(pipe);
String summaryJson = TwoFluidPipeReport.toSummaryJson(pipe);
String eventsCsv = TwoFluidPipeReport.toSlugAndFlowAssuranceCsv(pipe);

Transient reporting

For transient cases, call runTransient(dt, id) repeatedly and store a snapshot at the reporting interval required by the study. Do not store every internal sub-step for long pipelines unless high-frequency pressure waves or slug arrivals are being investigated.

UUID id = UUID.randomUUID();
double dt = 1.0;
int reportEvery = 10;

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

  if (step % reportEvery == 0) {
    double time = pipe.getSimulationTime();
    double[] x = pipe.getPositionProfile();
    double[] p = pipe.getPressureProfile();
    double[] hL = pipe.getLiquidHoldupProfile();
    // Write one row per position with this time stamp.
  }
}

Recommended transient CSV columns:

time_s,position_m,pressure_bara,temperature_C,liquid_holdup,water_cut,
gas_velocity_m_s,liquid_velocity_m_s,oil_velocity_m_s,water_velocity_m_s,
flow_regime

Summary metrics

Use these methods for an executive summary or design report:

API Description
getInletPressure() Inlet pressure in bara
getOutletPressure() Outlet pressure in bara
getAverageLiquidHoldup() Volume-weighted average liquid holdup
getDominantFlowRegime() Most frequent flow regime
getAverageSuperficialGasVelocity() Average superficial gas velocity
getAverageSuperficialLiquidVelocity() Average superficial liquid velocity
getAverageMixtureDensity() Volume-weighted mixture density
getMaxMixtureVelocity() Maximum mixture velocity
getErosionalVelocity() API 14E erosional velocity
getErosionalVelocityMargin(double) Maximum velocity divided by erosional velocity
getFlowAnalysisSummary() Mid-pipe dimensionless flow summary
getThermalSummary() Thermal model summary
getSlugStatisticsSummary() Slug-tracking summary
getHydrateRiskSections() Sections below configured hydrate temperature
getWaxRiskSections() Sections below configured wax appearance temperature

Closure diagnostics

The two-fluid closure pass updates additional section-level diagnostics that are useful for model review and validation:

Section API Description
getOilWaterFlowRegime() Oil-water flow configuration
isWaterWetting() Water-wetting indicator for corrosion screening
isWaterDropoutRisk() Water dropout / accumulation risk
getEntrainmentFraction() Estimated liquid entrainment fraction in annular/mist flow
getEntrainedDropletDiameter() Characteristic entrained droplet diameter
getSevereSluggingNumber() Riser-base stability indicator
isSevereSlugPotential() Severe slugging risk flag

These values are stored on TwoFluidSection objects. They are not yet exposed as top-level TwoFluidPipe profile arrays, so a future report exporter should add profile accessors for them.

Benchmark comparison format

The validation harness reads external simulator or field data in this CSV format:

case,time_s,position_m,variable,value,abs_tolerance,rel_tolerance,source

Supported captured variables include:

pressure_pa
pressure_bara
temperature_k
liquid_holdup
water_cut
oil_holdup
water_holdup
gas_velocity_m_s
liquid_velocity_m_s
oil_velocity_m_s
water_velocity_m_s

Example use:

Path reference = Path.of("olga_export.csv");
List<TwoFluidBenchmarkHarness.BenchmarkPoint> points =
    TwoFluidBenchmarkHarness.readCsv(reference);

TwoFluidBenchmarkHarness.Snapshot snapshot = TwoFluidBenchmarkHarness.capture(pipe);
TwoFluidBenchmarkHarness.Comparison comparison =
    TwoFluidBenchmarkHarness.compare(snapshot, points);

if (!comparison.isPassed()) {
  throw new AssertionError(comparison.failureSummary());
}

For transient comparisons, capture and pass a list of snapshots. The harness interpolates in both time and position. Comparison results can be exported as CSV:

String comparisonCsv = TwoFluidPipeReport.toComparisonCsv(comparison);

Reporting recommendations for long flowlines

For long oil and gas flowlines, report at least:

Gaps and planned improvements

The current API is adequate for engineering studies and benchmark development. A polished industrial report workflow should still add: