Skip to the content.

Cached K-Value Fast Process Simulation

The cached K-value fast simulator is a proxy method for running many process-flow scenarios after one rigorous base-case ProcessSystem solve. It is intended for screening, production allocation studies, digital-twin sensitivity sweeps, and agentic optimization loops where source rates change frequently but the thermodynamic operating envelope stays close to a calibrated reference case.

The method lives in neqsim.process.fastsimulation and is exposed from ProcessSystem through:

When To Use It

Use this method when:

Do not use it as the final design calculation when pressures, temperatures, fluid compositions, phase behaviour, or three-phase separation materially change. Re-run the rigorous process and rebuild the proxy when the thermodynamic envelope moves.

Method

The workflow is:

  1. Build and run a normal rigorous process model.
  2. Extract a KValueProcessSimulator from the solved process.
  3. Run fast source-rate scenarios with runWithSourceFlowMultipliers(...) or runWithSourceFlowRates(...).
  4. Query component and total flows from the KValueProcessResult.

During extraction, the simulator scans the process topology using each unit’s inlet and outlet streams. It creates a component slate, stores source stream component flows, and builds one KValueUnitProfile per unit operation that has outlet streams.

For separator-like two-outlet units, the base-case gas and liquid outlet compositions are converted to component K-values:

\[K_i = \frac{y_i}{x_i}\]

For a later inlet composition $z_i$, the vapour fraction beta is solved from the Rachford-Rice equation:

\[\sum_i \frac{z_i (K_i - 1)}{1 + \beta (K_i - 1)} = 0\]

The component flows are then routed without an EOS flash:

\[x_i = \frac{z_i}{1 + \beta (K_i - 1)}\] \[y_i = K_i x_i\]

For gas/oil/water separators, the oil outlet is used as the reference phase. The method stores gas/oil ratios and water/oil distribution ratios:

\[K^g_i = \frac{y_i}{x_i}\] \[K^w_i = \frac{w_i}{x_i}\]

The fast rerun solves two coupled Rachford-Rice-style equations for gas and water phase fractions. With oil fraction $\beta_o = 1 - \beta_g - \beta_w$:

\[\sum_i \frac{z_i (K^g_i - 1)}{1 + \beta_g (K^g_i - 1) + \beta_w (K^w_i - 1)} = 0\] \[\sum_i \frac{z_i (K^w_i - 1)}{1 + \beta_g (K^g_i - 1) + \beta_w (K^w_i - 1)} = 0\]

Single-outlet units pass component flows through. Unsupported multi-outlet units fall back to frozen base-case component split factors. Recycle loops are handled by fixed-point iteration over stream component flow vectors.

Supported Scope

Model element Fast-simulation behaviour
Source streams Base component composition is preserved; total source rate can be scaled or replaced.
Mixers and single-outlet units Component molar flows are passed through conservatively.
Two-outlet gas/liquid separators Cached gas/liquid K-values are used with Rachford-Rice routing for the current inlet composition.
Three-outlet gas/oil/water separators Cached gas/oil and water/oil ratios are used with a two-variable phase-fraction solve for the current inlet composition.
Wrapper product streams Product aliases such as ExportGas are mapped back to their internal separator outlet flow.
Recycles Stream flows are iterated to a fixed-point tolerance.
Unsupported multi-outlet units Frozen base-case component split factors are used as a fallback.

API Example

The example assumes process is a solved ProcessSystem containing source streams named Well-A and Well-B, and a product stream alias named ExportGas. The same API calls are covered by KValueProcessSimulatorTest.

process.run();

KValueProcessSimulator simulator = process.createKValueProcessSimulator();
simulator.setMaxIterations(50);
simulator.setTolerance(1.0e-9);

Map<String, Double> multipliers = new LinkedHashMap<String, Double>();
multipliers.put("Well-B", 1.25);

KValueProcessResult result = simulator.runWithSourceFlowMultipliers(multipliers);
double exportGasKgPerHr = result.getStreamTotalFlow("ExportGas", "kg/hr");
double methaneKgPerHr = result.getStreamComponentFlow("ExportGas", "methane", "kg/hr");
double totalProductKgPerHr = result.getTerminalTotalFlow("kg/hr");
String resultJson = result.toJson();

You can also replace total source flow rates while keeping the base-case source compositions:

Map<String, Double> sourceRates = new LinkedHashMap<String, Double>();
sourceRates.put("Well-A", 1200.0);
KValueProcessResult rateCase = simulator.runWithSourceFlowRates(sourceRates, "kg/hr");

Benchmarking

KValueProcessSimulator includes a convenience benchmark that compares repeated proxy cases against repeated rigorous ProcessSystem.run() cases for source-flow multipliers:

KValueProcessBenchmarkResult benchmark = simulator.benchmarkSourceFlowMultipliers("Well-B",
    new double[] { 0.80, 1.00, 1.20 });
double speedup = benchmark.getSpeedup();
String benchmarkJson = benchmark.toJson();

The focused unit test uses a multistage PR-EOS HP/MP/LP separation process based on the same reference process family as the recovery-factor production-allocation benchmark. The proxy is expected to be faster because it avoids repeated EOS flashes while retaining component-resolved separator routing around the calibrated base case.

Result Naming

Internal unit outlets use keys of the form unitName.outletStreamName, for example:

If the process also contains wrapper streams such as ExportGas or StabOil, the result exposes those aliases as stream names too. Use result.getStreamNames() or result.toJson() to inspect the available keys for a model.

Limitations