Skip to the content.

Source-term uncertainty ensembles and validation evidence

ReleaseFlowEnsemble propagates complete, caller-defined uncertainty cases through a selected release model. It retains every request and result, including failures. It exports cases through the existing v1 source-frame contract, with no new downstream software dependency or change to live-session behavior.

Joint inputs and probability meaning

Each ReleaseFlowEnsemble.Case supplies a unique ID, a ReleaseFlowRequest, a finite positive relative weight, and sampling provenance. A request includes the full upstream fluid, opening diameter [m], discharge coefficient [1] and absolute back pressure [Pa]. Pressure, temperature, composition and geometry may vary together. This preserves caller-supplied correlations; the API does not assume independent distributions, generate samples, infer probability weights from operating scenarios, or decide which uncertainty ranges are physically credible.

For equally probable Monte Carlo samples use equal weights and retain the sampling method, seed, distribution parameters and source process calculation identity in the case metadata. For a discrete distribution assign its declared relative probabilities. A low/base/high scenario set is probabilistic only when its weights have a justified probability meaning. Convergence of sample count and tail quantiles remains the caller’s responsibility.

For weights $w_i$, normalized probabilities are $p_i=w_i/\sum_j w_j$. The unconditional mean is $\overline{\dot m}=\sum_i p_i\dot m_i$ [kg/s]. The quantile is the inverse weighted empirical CDF, without interpolation: the smallest rate with cumulative probability at least the requested value. Endpoints return the minimum and maximum. P90 means 90% non-exceedance, not petroleum-reserve exceedance notation or a confidence bound. These are statistics over supplied inputs, not confidence intervals on physical model accuracy.

Executable example

The code is exercised by ReleaseFlowEnsembleTest.documentationExampleHasAnalyticallyKnownWeightedStatistics. fluid is a configured methane SRK system at 300 K and 5 bara. Coefficients and weights below are synthetic examples, not recommended distributions.

List<ReleaseFlowEnsemble.Case> cases = new ArrayList<ReleaseFlowEnsemble.Case>();
cases.add(new ReleaseFlowEnsemble.Case("low",
    new ReleaseFlowRequest(fluid, 0.01, 0.50, 1e5), 1.0,
    Collections.singletonMap("method", "discrete joint scenarios")));
cases.add(new ReleaseFlowEnsemble.Case("base",
    new ReleaseFlowRequest(fluid, 0.01, 0.75, 1e5), 2.0,
    Collections.singletonMap("method", "discrete joint scenarios")));
cases.add(new ReleaseFlowEnsemble.Case("high",
    new ReleaseFlowRequest(fluid, 0.01, 1.00, 1e5), 1.0,
    Collections.singletonMap("method", "discrete joint scenarios")));
ReleaseFlowEnsemble ensemble = ReleaseFlowEnsemble.evaluate("opening-study",
    new HomogeneousEquilibriumReleaseModel(), cases);
// Check isComplete(), getStatusCounts() and every result's diagnostics first.
double meanKgS = ensemble.getMeanMassFlowRateKgS();
double p90KgS = ensemble.getMassFlowRateQuantileKgS(0.90);
List<SourceTermFrame> frames = ensemble.toFrames("scenario-1", "feed-opening",
    UUID.fromString("00000000-0000-0000-0000-000000000386"), 0.0,
    Instant.parse("2026-09-21T00:00:00Z"));

Import release types from neqsim.process.safety.release, collections and UUID from java.util, and Instant from java.time. Requests defensively clone their fluids. Evaluation is sequential in supplied order; it does not run or mutate a connected process. Obtain each uncertain upstream state from a successfully solved process first when uncertainty changes that process’s operating point. getCases() retains complete immutable requests for inspection; exported failure frames intentionally omit numeric source payloads.

Failed cases cannot disappear into the statistics

Condition Result
Every case is usable Mean and quantiles are available.
Any case is INVALID or UNSUPPORTED isComplete() is false; rate-statistic getters throw.
Some cases have warnings Statistics remain available; warning counts and diagnostics remain visible.
Valid no-forward-flow case Its genuine zero rate participates in statistics.
Model throws, returns null, or returns another model’s identity/version A per-case INVALID result records the reason; later cases still run.
Duplicate ID, missing case or unrepresentable probability Input is rejected before any model is called.

getUsableProbability() reports the sum of the original probabilities for usable cases. The evaluator never renormalizes probabilities after a failure and never substitutes zero. An ensemble with 75% unsupported probability has 25% usable probability and no unconditional rate statistics, even if remaining cases appear well behaved. This avoids silently excluding regimes that may dominate the high-rate tail. Resolve failures before reporting an unconditional distribution.

Reproducible exchange

toFrames preserves order, status, stations, model identity and the UNQUALIFIED evidence label. Metadata records ensemble ID, case ID, original weight, normalized probability, and caller provenance under sampling.*. Fixed identities/timestamp and deterministic calculations give deterministic JSON and fingerprints. The schema is unchanged.

All cases share the supplied simulation time. sequenceMeaning=ENSEMBLE_CASE_INDEX states that the sequence indexes alternative cases, not a transient trajectory. Do not interleave them into a live sequence or integrate them as successive time samples. Retain complete input cases separately for replay, particularly failed cases whose frames contain no numeric source payload. Provenance should identify the EOS, composition, sampling method and correlated process inputs sufficiently for reproducibility.

Validation matrix and evidence limits

The focused CI workflow runs this matrix and retains test reports, schema-validated frames and CSV output. Existing flashing and mixture tests remain in the same mandatory command.

Regime or behavior Executable evidence What it establishes
Dilute methane, 300 K, 0.1 bara, back-pressure ratios 0.05/0.30/0.70/0.90/0.98 ReleaseFlowBenchmarkTest.diluteGasBackpressureSweepMatchesIndependentPerfectGasEquation Choked/subcritical decision and rate within 1.5% of the constant-gamma equation.
Methane, 300 K, 50 bara ReleaseFlowModelTest.documentationExampleAndEnergyClosure Entropy, stagnation-energy and phase-mass closure.
Flashing propane, 300 K, 20 to 3 bara ReleaseFlowModelTest.liquidFlashingUsesMassFractionsAndPreservesInventory Two-phase expansion, mass fractions and conserved composition.
Methane/ethane gas ReleaseFlowModelTest.mixtureGasAndUnresolvedFlashingBoundaryAreDistinguished Multicomponent gas support; explicit rejection of an unresolved flashing-mixture root.
Dense CO2, 310 K, 120 to 110 bara ReleaseFlowBenchmarkTest.denseFluidHighBackpressureAndCo2SolidRiskAreExplicit A resolved dense-fluid case and conservation; not independent dense-fluid rate accuracy.
CO2 at 210 K Same dense-fluid test Solid-risk rejection without a fabricated rate.
Weighted cases and failures ReleaseFlowEnsembleTest Exact scaling statistics, retained failure probability, deterministic frames, serialization and defensive inputs.
Real separator transients in both containers SourceTermSessionTest Actual vessel dynamics reach source frames; no release-inventory feedback is implied.

For the gas benchmark, with $R_s=R/M$, $r=\max(p_b/p_0,r_c)$ and $r_c=(2/(\gamma+1))^{\gamma/(\gamma-1)}$, the reference is

\[\dot m=C_d A p_0\sqrt{\frac{2\gamma}{R_s T_0(\gamma-1)}\left(r^{2/\gamma}-r^{(\gamma+1)/\gamma}\right)}.\]

Here $R_s$ is the specific gas constant [J/(kg K)], $\gamma$ the upstream heat-capacity ratio [1], $p_0$ absolute stagnation pressure [Pa], $T_0$ stagnation temperature [K], and $A$ opening area [m2]. The reference follows constant-gamma ideal-gas isentropic relations and the steady energy balance. It shares upstream NeqSim heat-capacity ratio and molar mass: this is an independent discharge equation, not independent property data. The tolerance allows EOS and heat-capacity differences.

Run the six release test classes in .github/workflows/safety-source-term-contract.yml, then devtools/validate_source_term_contract.py. CSVs under target/source-term-benchmarks/ are generated from calculations, not pre-filled. Conservation and software checks do not establish experimental accuracy or facility qualification. See the completion status for remaining work in #3860.