Skip to content

WIP: feat(yaml): introduce multiple streams and pressures functionality in process_systems and process_simulations#1453

Draft
olelod wants to merge 1 commit intomainfrom
feat/yaml-interstage-types
Draft

WIP: feat(yaml): introduce multiple streams and pressures functionality in process_systems and process_simulations#1453
olelod wants to merge 1 commit intomainfrom
feat/yaml-interstage-types

Conversation

@olelod
Copy link
Copy Markdown
Contributor

@olelod olelod commented Mar 23, 2026

Summary

Refactors the process system and simulation YAML types to support interstage topology — enabling expression of legacy multi-stream and multi-pressure compressor trains in the new YAML format.

All types live in yaml_process_system.py.

Process system topology (PROCESS_SYSTEMS)

Type Description
COMPRESSOR_STAGE Single compressor stage with inlet temperature
PRESSURE_DROP Interstage pressure drop element
MIXER Stream injection point (one per injected stream)
SPLITTER Stream extraction point (one per extracted stream)
SERIAL Ordered list of item references; carries ANTI_SURGE (default: INDIVIDUAL_ASV)

PRESSURE_DROP, MIXER, and SPLITTER are new interstage topology types.

Process simulation (PROCESS_SIMULATIONS)

Each simulation has a list of TARGETS (one = serial, many = parallel — implicit from count) and a required STREAM_DISTRIBUTION (COMMON_STREAM or INDIVIDUAL_STREAMS, both accept stream refs or inline stream definitions).

Each target carries:

  • TARGET: reference to a SERIAL process system
  • CONSTRAINTS: map of item name / train name → OUTLET_PRESSURE + PRESSURE_CONTROL
  • MIXER_STREAMS: map of mixer name → inlet stream
  • SPLITTER_RATES: map of splitter name → extraction rate

Parse-time validation

  • Simulation targets must reference a known SERIAL process system
  • Every train must have an outlet constraint keyed by the train name
  • Every MIXER in a train must have a MIXER_STREAMS entry per target
  • Every SPLITTER in a train must have a SPLITTER_RATES entry per target
  • Constraint keys must be valid item names or the train name
  • Constraints must appear in topological order (matching SERIAL.items)
  • UPSTREAM_CHOKE only valid on the first constraint in topological order
  • DOWNSTREAM_CHOKE only valid on the last constraint in topological order
  • INDIVIDUAL_STREAMS: inlet stream count must match target count
  • COMMON_STREAM: each RATE_FRACTIONS list must have one entry per target
  • SERIAL.items must not reference another SERIAL (no nested serial trains)
  • MIXER_STREAMS keys must reference MIXER items in the train
  • SPLITTER_RATES keys must reference SPLITTER items in the train
  • COMMON_STREAM overflow FROM/TO references must be valid target names

Mapper

process_simulation_mapper.py updated to resolve string item references via reference_service, read pressure control from per-target outlet constraints, and read anti-surge from train.anti_surge. Multi-segment trains (more than one constraint) raise NotImplementedError pending MultiPressureSolver support.

Example YAML

INLET_STREAMS:
  feed_stream:
    FLUID_MODEL: dry_gas
    RATE:
      VALUE: SIM1;FEED_RATE
      UNIT: SM3_PER_DAY
  injection_stream:
    FLUID_MODEL: wet_gas
    RATE:
      VALUE: SIM1;INJECTION_RATE
      UNIT: SM3_PER_DAY
  train_a_stream:
    FLUID_MODEL: dry_gas
    RATE:
      VALUE: SIM1;TRAIN_A_RATE
      UNIT: SM3_PER_DAY
  train_b_stream:
    FLUID_MODEL: dry_gas
    RATE:
      VALUE: SIM1;TRAIN_B_RATE
      UNIT: SM3_PER_DAY

PROCESS_SYSTEMS:
  - TYPE: COMPRESSOR_STAGE
    NAME: stage_1
    INLET_TEMPERATURE: 30
    COMPRESSOR: my_compressor

  - TYPE: PRESSURE_DROP
    NAME: interstage_choke
    PRESSURE_DROP: 3

  - TYPE: MIXER
    NAME: injection_point

  - TYPE: COMPRESSOR_STAGE
    NAME: stage_2
    INLET_TEMPERATURE: 40
    COMPRESSOR: my_compressor

  - TYPE: SERIAL
    NAME: main_train
    ANTI_SURGE: INDIVIDUAL_ASV
    ITEMS:
      - stage_1
      - interstage_choke
      - injection_point
      - stage_2

  - TYPE: COMPRESSOR_STAGE
    NAME: train_a_stage
    INLET_TEMPERATURE: 30
    COMPRESSOR: my_compressor

  - TYPE: SERIAL
    NAME: train_a
    ANTI_SURGE: COMMON_ASV
    ITEMS:
      - train_a_stage

  - TYPE: COMPRESSOR_STAGE
    NAME: train_b_stage
    INLET_TEMPERATURE: 30
    COMPRESSOR: my_compressor

  - TYPE: SERIAL
    NAME: train_b
    ANTI_SURGE: INDIVIDUAL_ASV
    ITEMS:
      - train_b_stage

PROCESS_SIMULATIONS:
  # Serial train with interstage mixer and pressure drop
  - NAME: sim_serial
    TARGETS:
      - TARGET: main_train
        MIXER_STREAMS:
          injection_point: injection_stream
        CONSTRAINTS:
          injection_point:
            OUTLET_PRESSURE: 50
            PRESSURE_CONTROL: DOWNSTREAM_CHOKE
          main_train:
            OUTLET_PRESSURE: 120
            PRESSURE_CONTROL: DOWNSTREAM_CHOKE
    STREAM_DISTRIBUTION:
      METHOD: INDIVIDUAL_STREAMS
      INLET_STREAMS:
        - feed_stream

  # Parallel trains with individual streams
  - NAME: sim_parallel_individual
    TARGETS:
      - TARGET: train_a
        CONSTRAINTS:
          train_a:
            OUTLET_PRESSURE: 120
            PRESSURE_CONTROL: COMMON_ASV
      - TARGET: train_b
        CONSTRAINTS:
          train_b:
            OUTLET_PRESSURE: 120
            PRESSURE_CONTROL: DOWNSTREAM_CHOKE
    STREAM_DISTRIBUTION:
      METHOD: INDIVIDUAL_STREAMS
      INLET_STREAMS:
        - train_a_stream
        - train_b_stream

  # Parallel trains with common stream distribution
  - NAME: sim_parallel_common
    TARGETS:
      - TARGET: train_a
        CONSTRAINTS:
          train_a:
            OUTLET_PRESSURE: 120
            PRESSURE_CONTROL: COMMON_ASV
      - TARGET: train_b
        CONSTRAINTS:
          train_b:
            OUTLET_PRESSURE: 120
            PRESSURE_CONTROL: DOWNSTREAM_CHOKE
    STREAM_DISTRIBUTION:
      METHOD: COMMON_STREAM
      INLET_STREAM: feed_stream
      SETTINGS:
        - RATE_FRACTIONS: [0.6, 0.4]
          OVERFLOW:
            - FROM_REFERENCE: train_a
              TO_REFERENCE: train_b
        - RATE_FRACTIONS: [0.5, 0.5]

@olelod olelod force-pushed the feat/yaml-interstage-types branch from 2f01beb to 507f040 Compare March 23, 2026 12:18
Comment on lines +115 to +122
class YamlInterstageProcessSystem(YamlBase):
type: Literal["INTERSTAGE"]
name: ProcessSystemReference
items: list[YamlInterstageItem] = Field(
default_factory=list,
title="ITEMS",
description="Ordered list of choke, mixer, and splitter units at this interstage location.",
)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we actually need this? Can we instead just have a list of units in addition to CompressorStages when setting up the train?

type: Literal["SERIAL"]
name: ProcessSystemReference
items: list[YamlItem[YamlCompressorStageProcessSystem]]
items: list[YamlItem[YamlCompressorStageProcessSystem | YamlInterstageProcessSystem]]
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
items: list[YamlItem[YamlCompressorStageProcessSystem | YamlInterstageProcessSystem]]
items: list[YamlItem[YamlCompressorStageProcessSystem | YamlInterstageChoke | YamlInterstageSplitter | YamlInterstageMixer]]


class YamlProcessConstraints(YamlBase):
outlet_pressure: YamlExpressionType | None = Field(
discharge_pressure: YamlExpressionType | None = Field(
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we use discharge instead of inlet? inlet/outlet seems to work for streams, is it different for pressure?

title="DISCHARGE_PRESSURE",
description="Target discharge pressure [bara].",
)
pressure_control: YamlPressureControl | None = Field(
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will constraint, anti-surge and pressure control always go hand-in-hand?

I think we also should consider introducing a type for constraint, maybe switch to a list. That gives us more flexibility in case we need to introduce different constraints.

If combining constraint and 'how to solve' like this we should also consider a different name than constraint

@olelod olelod force-pushed the feat/yaml-interstage-types branch 4 times, most recently from 08d553e to 88e14e6 Compare April 8, 2026 11:20
@olelod olelod changed the title WIP: feat(yaml): introduce INTERSTAGE process system type and PRESSURE_CON… WIP: feat(yaml): introduce multiple streams and pressures functionality in process_systems and process_simulations Apr 8, 2026
@olelod olelod force-pushed the feat/yaml-interstage-types branch 5 times, most recently from 8e95998 to fbae582 Compare April 8, 2026 12:09
@@ -231,12 +231,12 @@ def _get_compressor(self, yaml_compressor_stage: YamlCompressorStageProcessSyste
)

def _get_compressors(self, target: YamlSerialProcessSystem, shaft: Shaft) -> list[Compressor]:
Copy link
Copy Markdown
Contributor

@frodehk frodehk Apr 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion - replace _get_compressors() and _get_compressor() with:

  • _map_stage_to_process_units() -> list[ProcessUnit] (Compressor and TemperatureSetter)
  • _map_pressure_drop_to_process_units() -> list[ProcessUnit] (Choke)
  • _get_process_units() -> list[ProcessUnit] (Choke, TemperatureSetter, Compressor)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will be added in a follow up PR involving yaml-to-domain mapping

Consolidate all process system types in yaml_process_system.py.

- Add interstage topology types: PRESSURE_DROP, MIXER, SPLITTER
- Add SERIAL anti-surge config (INDIVIDUAL_ASV / COMMON_ASV)
- Restructure simulation targets with per-item constraints carrying
  OUTLET_PRESSURE and PRESSURE_CONTROL
- Add MIXER_STREAMS and SPLITTER_RATES to simulation targets
- Add parse-time validators in YamlAsset (topological ordering,
  choke placement, reference consistency)
@olelod olelod force-pushed the feat/yaml-interstage-types branch from fbae582 to 4289e42 Compare April 14, 2026 17:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants