feat(libecalc): add closed-form liquid pump process simulation - #1681
Merged
Conversation
kjbrak
force-pushed
the
feat/liquid-pump-process-simulation
branch
2 times, most recently
from
July 21, 2026 14:23
166f490 to
2a52ea5
Compare
tj098895
reviewed
Jul 22, 2026
tj098895
reviewed
Jul 22, 2026
kjbrak
force-pushed
the
feat/liquid-pump-process-simulation
branch
from
July 22, 2026 07:48
2a52ea5 to
c65f2cf
Compare
tj098895
reviewed
Jul 22, 2026
tj098895
reviewed
Jul 22, 2026
tj098895
reviewed
Jul 22, 2026
tj098895
reviewed
Jul 22, 2026
tj098895
reviewed
Jul 22, 2026
tj098895
reviewed
Jul 22, 2026
tj098895
reviewed
Jul 22, 2026
tj098895
reviewed
Jul 22, 2026
tj098895
reviewed
Jul 22, 2026
tj098895
reviewed
Jul 22, 2026
| simple_yaml.main_file.read() | ||
| + """ | ||
|
|
||
| PROCESS_SIMULATIONS: |
Contributor
There was a problem hiding this comment.
nice. can you add an example yaml in web in order for the rest of the team to have access to and use?
tj098895
approved these changes
Jul 22, 2026
tj098895
left a comment
Contributor
There was a problem hiding this comment.
nice, please see my comments.
There are many simplifictions I want to make, both here and in existing code, but worth to fix soon instead.
Also, I see that it is hard to know what is the boundary of what is going on in core vs backend, and I want to clarify. We can talk later again :)
kjbrak
force-pushed
the
feat/liquid-pump-process-simulation
branch
4 times, most recently
from
July 23, 2026 09:55
e8c551c to
1e1aa7c
Compare
Introduce a liquid pump process graph under a dedicated PUMP_PROCESS_SIMULATIONS YAML keyword, kept separate from the gas FluidStream pipeline. - Extend the closed-form Pump result with efficiency, specific shaft work, shaft power and speed at the operating point (PumpEvaluationResult). - Add PumpProcessSimulation: a fixed liquid graph of inlet, recirculation mixer, pump, recirculation splitter, choke and outlet with typed LiquidProcessUnit entities, connections and a recirculation loop. The domain is time-agnostic: evaluate() maps a sequence of PumpOperatingInput to a liquid stream on every connection plus the pump result, in order. - Add the PUMP_PROCESS_SIMULATIONS "TYPE: PUMP" YAML root, its mapper and YamlModel.get_pump_process_simulations(). Refs: equinor/ecalc-internal#2059
kjbrak
force-pushed
the
feat/liquid-pump-process-simulation
branch
from
July 23, 2026 11:07
1e1aa7c to
414f957
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What is this PR all about?
Adds a closed-form liquid pump as its own process graph in the new (experimental) process domain, under a dedicated
PUMP_PROCESS_SIMULATIONSYAML keyword, kept separate from the gas pipeline.What is added
Pump(libecalc/process/pump/) is fully closed-form. Its resultPumpEvaluationResultcarries efficiency, specific shaft work, shaft power, speed, feasibility, the operating rate/head and the recirculation rate. Minimum-flow recirculation and minimum-head choking are computed directly - no solver.PumpProcessSimulationbuilds a fixed liquid process graph and evaluates a sequence of data-defined inputs (the domain is time-agnostic - it carries noPeriod):It exposes typed
LiquidProcessUnitnodes (entities with ids), serialProcessUnitConnectionedges (reusing the shared process primitive), and aLiquidRecirculationLoop(its own id, splitter id + mixer id).evaluate(...)returns, for each input in order, the flat pump result plus aLiquidStreamon every connection, keyed by connection id.New YAML
PUMP_PROCESS_SIMULATIONS: - TYPE: PUMP(withPUMP_MODEL,INLET,REQUIRED_DISCHARGE_PRESSURE), its mapper, andYamlModel.get_pump_process_simulations().How a consumer uses it
The graph structure (stable for persistence and visualisation) is read separately:
Capabilities and patterns supported
LiquidStreamon every connection, keyed by connection id.Intended integration in a consuming application
A consuming application (for example a persistence-and-worker backend that renders process diagrams) can treat the pump like any other process graph, because libecalc owns the graph and its ids. The application only maps and schedules; it never re-implements pump physics or topology:
Note: unit and connection ids are generated when the simulation is built. A consumer that needs ids to be stable across runs persists them once and reuses them, exactly as the compressor process graph is handled.
Why it is shaped this way, and how it differs from the compressor
The pump deliberately reuses the compressor process graph contract (typed units, connections, per-connection streams, a recirculation loop, all with ids) so a consumer can persist and visualise pumps and compressors with one pattern. It deliberately does not reuse the compressor runtime:
FluidStreamwith composition, EoS and temperature. A liquid is modelled as an incompressibleLiquidStream(pressure, density, mass rate). It cannot flow through the gas pipeline types, and the persisted gas stream shape carries gas-only fields. Liquid is therefore kept as a separate track rather than forced through the gas hierarchy or changing working compressor code.There is no planned support for generic, user-composable liquid process systems - only this pump process and, soon, a pump-system process (
TYPE: PUMP_SYSTEM) with pumps in parallel. If a composable liquid system is ever needed, the internal stream projection can be replaced by a real per-unit liquid runner behind the same publicevaluate(...)contract, without callers changing. TheLiquidStreamandLiquidStreamPropagatorabstractions already exist to support that.What else did you consider?
FluidStreampipeline. Rejected: the pipeline is gas-typed and solver-driven; this would change working compressor infrastructure for no pump benefit.LiquidStreamPropagatorinterface keeps that door open.Between the lines?
PUMP_PROCESS_SIMULATIONSYAML keyword) is experimental and not yet wired to energy output or a consumer; this PR is a contract-first building block validated by tests (unit propagation, graph structure, streams-per-connection, order-preserving evaluation, and end-to-end YAML mapping).HEAD_MARGINis not supported in the new pump process domain - a point above the chart's maximum head is flagged as infeasible (ABOVE_MAXIMUM_HEAD_AT_RATE) rather than snapped to the maximum, so a facility pump chart that sets a non-zeroHEAD_MARGINis rejected.ENERGY_USAGE_MODEL: TYPE: PUMP) is untouched.Refs.:
Refs: equinor/ecalc-internal#2059