Skip to content

Commit 5c321e4

Browse files
committed
refactor: separate process definitions from instance references
1 parent 0733f54 commit 5c321e4

11 files changed

Lines changed: 151 additions & 48 deletions

File tree

src/libecalc/presentation/yaml/mappers/process/build_sections.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
MappedSection,
44
ProcessPartitioner,
55
)
6-
from libecalc.presentation.yaml.yaml_types.process.yaml_process_references import ProcessUnitReference
6+
from libecalc.presentation.yaml.yaml_types.process.yaml_process_references import ProcessUnitInstanceName
77
from libecalc.presentation.yaml.yaml_types.process.yaml_process_simulation import YamlProcessConstraint
88
from libecalc.process.fluid_stream.fluid_service import FluidService
99
from libecalc.process.process_pipeline.process_unit import ProcessUnit, ProcessUnitId
@@ -25,7 +25,7 @@ def __init__(self):
2525
def partition_and_validate(
2626
self,
2727
process_unit_map: dict[ProcessUnitId, ProcessUnit],
28-
unit_name_to_id: dict[ProcessUnitReference, ProcessUnitId],
28+
unit_name_to_id: dict[ProcessUnitInstanceName, ProcessUnitId],
2929
pipeline_constraints: list[YamlProcessConstraint],
3030
) -> list[MappedSection]:
3131
sections = self._partitioner.partition(

src/libecalc/presentation/yaml/mappers/process/process_partitioner.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from libecalc.common.ddd import value_object
22
from libecalc.common.errors.ecalc_validation_error import EcalcValidationException
3-
from libecalc.presentation.yaml.yaml_types.process.yaml_process_references import ProcessUnitReference
3+
from libecalc.presentation.yaml.yaml_types.process.yaml_process_references import ProcessUnitInstanceName
44
from libecalc.presentation.yaml.yaml_types.process.yaml_process_simulation import YamlProcessConstraint
55
from libecalc.process.process_pipeline.process_unit import ProcessUnit, ProcessUnitId
66
from libecalc.process.process_units.compressor import Compressor
@@ -27,7 +27,7 @@ class ProcessPartitioner:
2727
@staticmethod
2828
def partition(
2929
process_unit_map: dict[ProcessUnitId, ProcessUnit],
30-
unit_name_to_id: dict[ProcessUnitReference, ProcessUnitId],
30+
unit_name_to_id: dict[ProcessUnitInstanceName, ProcessUnitId],
3131
pipeline_constraints: list[YamlProcessConstraint],
3232
) -> list[MappedSection]:
3333
process_units = list(process_unit_map.values())
@@ -40,7 +40,7 @@ def partition(
4040
raise EcalcValidationException("Only one constraint can target the process pipeline outlet.")
4141
terminal_constraint = constraint
4242
continue
43-
unit_id = unit_name_to_id.get(constraint.process_unit)
43+
unit_id = unit_name_to_id.get(ProcessUnitInstanceName(constraint.process_unit))
4444
if unit_id is None:
4545
raise EcalcValidationException(f"Constraint references unknown unit '{constraint.process_unit}'.")
4646

src/libecalc/presentation/yaml/mappers/process_simulation_mapper.py

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,16 @@
3939
)
4040
from libecalc.presentation.yaml.mappers.model import InvalidChartResourceException
4141
from libecalc.presentation.yaml.mappers.process.build_sections import ProcessSectionBuilder
42+
from libecalc.presentation.yaml.resolvers.process_unit_resolver import ProcessUnitResolver
4243
from libecalc.presentation.yaml.yaml_types.components.yaml_expression_type import YamlExpressionType
4344
from libecalc.presentation.yaml.yaml_types.models import YamlFluidModel
4445
from libecalc.presentation.yaml.yaml_types.models.yaml_compressor_stages import YamlControlMarginUnits
4546
from libecalc.presentation.yaml.yaml_types.models.yaml_fluid import YamlCompositionFluidModel, YamlPredefinedFluidModel
4647
from libecalc.presentation.yaml.yaml_types.process.yaml_process_pipeline import YamlProcessPipeline
4748
from libecalc.presentation.yaml.yaml_types.process.yaml_process_references import (
48-
ProcessUnitReference,
49+
ProcessPipelineInstanceName,
50+
ProcessPipelineInstanceReference,
51+
ProcessUnitInstanceName,
4952
)
5053
from libecalc.presentation.yaml.yaml_types.process.yaml_process_simulation import (
5154
YamlProcessSimulation,
@@ -131,6 +134,7 @@ def __init__(
131134
self._reference_service = reference_service
132135
self._resources = resources
133136
self._ecalc_event_service = ecalc_event_service
137+
self._process_unit_resolver = ProcessUnitResolver(reference_service)
134138

135139
def _resolve_train_reference(self, ref: str | YamlProcessPipeline) -> YamlProcessPipeline:
136140
if isinstance(ref, str):
@@ -247,7 +251,7 @@ def _map_fluid_model(self, yaml_fluid_model: YamlFluidModel) -> FluidModel:
247251
def _validate_and_map_pipeline_events(
248252
self,
249253
yaml_pipeline: YamlProcessPipeline,
250-
unit_name_to_id: dict[ProcessUnitReference, ProcessUnitId],
254+
unit_name_to_id: dict[ProcessUnitInstanceName, ProcessUnitId],
251255
) -> list[PipelineEvent]:
252256
"""Validate pipeline event references and map to domain objects."""
253257
events: list[PipelineEvent] = []
@@ -275,7 +279,7 @@ def _validate_and_map_pipeline_events(
275279
events.append(
276280
PipelineEvent(
277281
action=PipelineEventAction(yaml_event.type.value),
278-
change_target=unit_name_to_id[yaml_event.change_target],
282+
change_target=unit_name_to_id[ProcessUnitInstanceName(yaml_event.change_target)],
279283
change_to=change_to_unit,
280284
change_type=PipelineEventChangeType(yaml_event.change_type.value),
281285
change_time=ecalc_event.start,
@@ -308,9 +312,10 @@ def map_process_simulation(
308312
problem_configuration_handlers = []
309313
shaft = VariableSpeedShaft()
310314
item = self._resolve_train_reference(yaml_compressor_train_item.target)
315+
pipeline_instance_name = yaml_compressor_train_item.name or ProcessPipelineInstanceName(item.name)
311316
process_unit_map: dict[ProcessUnitId, ProcessUnit] = {}
312317
compressor_ids: list[ProcessUnitId] = []
313-
unit_name_to_id: dict[ProcessUnitReference, ProcessUnitId] = {}
318+
unit_name_to_id: dict[ProcessUnitInstanceName, ProcessUnitId] = {}
314319
problem_time_series_configurations: dict[
315320
ProcessUnitId,
316321
TimeSeriesTemperatureSetterConfiguration
@@ -320,10 +325,9 @@ def map_process_simulation(
320325
] = {}
321326

322327
for yaml_pipeline_item in item.items:
323-
yaml_process_unit = yaml_pipeline_item.target
324-
process_unit_name = yaml_pipeline_item.name
325-
if isinstance(yaml_process_unit, str):
326-
yaml_process_unit = self._reference_service.get_process_unit(yaml_process_unit)
328+
resolved_process_unit = self._process_unit_resolver.resolve(yaml_pipeline_item)
329+
process_unit_name = resolved_process_unit.name
330+
yaml_process_unit = resolved_process_unit.specification
327331

328332
match yaml_process_unit:
329333
case YamlCompressor():
@@ -394,10 +398,11 @@ def map_process_simulation(
394398
# from section, and keep track of them at pipeline level
395399
process_pipeline_sections: list[ProcessPipelineSection] = []
396400
process_problem_sections: list[ProcessProblemSection] = []
397-
pipeline_constraints = yaml_process_simulation.constraints.get(item.name)
398-
401+
pipeline_constraints = yaml_process_simulation.constraints.get(
402+
ProcessPipelineInstanceReference(pipeline_instance_name)
403+
)
399404
if not pipeline_constraints:
400-
raise EcalcValidationException(f"Missing constraint for process system '{item.name}'")
405+
raise EcalcValidationException(f"Missing constraint for process system '{pipeline_instance_name}'")
401406

402407
mapped_sections = section_builder.partition_and_validate(
403408
process_unit_map=process_unit_map,
@@ -426,7 +431,7 @@ def map_process_simulation(
426431
# TODO: We should move this class to this module/layer
427432
# in particular because it creates necessary connections, which means that they will get new IDs
428433
process_pipeline = ProcessPipeline(
429-
name=item.name,
434+
name=pipeline_instance_name,
430435
process_pipeline_sections=process_pipeline_sections,
431436
events=pipeline_events,
432437
process_periods=process_periods,
@@ -476,7 +481,7 @@ def map_process_simulation(
476481

477482
predefined_configurations[process_pipeline.get_id()] = problem_time_series_configurations
478483

479-
process_pipeline_reference_to_id_map[item.name] = process_pipeline.get_id()
484+
process_pipeline_reference_to_id_map[pipeline_instance_name] = process_pipeline.get_id()
480485
process_pipelines.append(process_pipeline)
481486
process_problems.append(
482487
ProcessProblem(

src/libecalc/presentation/yaml/resolvers/__init__.py

Whitespace-only changes.
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
from dataclasses import dataclass
2+
3+
from libecalc.presentation.yaml.domain.reference_service import ReferenceService
4+
from libecalc.presentation.yaml.yaml_types.process.yaml_process_pipeline import YamlProcessUnitItem
5+
from libecalc.presentation.yaml.yaml_types.process.yaml_process_references import ProcessUnitInstanceName
6+
from libecalc.presentation.yaml.yaml_types.process.yaml_process_units import YamlProcessUnit
7+
8+
9+
@dataclass(frozen=True)
10+
class ResolvedProcessUnitItem:
11+
name: ProcessUnitInstanceName | None
12+
specification: YamlProcessUnit
13+
14+
15+
class ProcessUnitResolver:
16+
def __init__(self, references: ReferenceService):
17+
self._references = references
18+
19+
def resolve(self, item: YamlProcessUnitItem) -> ResolvedProcessUnitItem:
20+
specification = self._references.get_process_unit(item.target) if isinstance(item.target, str) else item.target
21+
return ResolvedProcessUnitItem(
22+
name=item.name,
23+
specification=specification,
24+
)

src/libecalc/presentation/yaml/yaml_types/process/yaml_process_pipeline.py

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66
from libecalc.presentation.yaml.yaml_types import YamlBase
77
from libecalc.presentation.yaml.yaml_types.process.yaml_process_references import (
88
ProcessEventReference,
9+
ProcessUnitDefinitionReference,
10+
ProcessUnitInstanceName,
11+
ProcessUnitInstanceReference,
912
ProcessUnitReference,
1013
)
1114
from libecalc.presentation.yaml.yaml_types.process.yaml_process_units import (
@@ -20,6 +23,11 @@ class YamlItem[TTarget](YamlBase):
2023
name: str | None = None
2124

2225

26+
class YamlProcessUnitItem(YamlBase):
27+
name: ProcessUnitInstanceName | None = None
28+
target: YamlProcessUnit | ProcessUnitDefinitionReference
29+
30+
2331
class PipelineEventAction(StrEnum):
2432
CHANGE = "CHANGE"
2533
ADD = "ADD"
@@ -39,21 +47,21 @@ class YamlPipelineEvent(YamlBase):
3947
),
4048
]
4149
change_target: Annotated[
42-
ProcessUnitReference,
50+
ProcessUnitInstanceReference,
4351
Field(
4452
title="CHANGE_TARGET",
4553
description="Name of the process unit in the pipeline to change.",
4654
),
4755
]
4856
change_from: Annotated[
49-
ProcessUnitReference,
57+
ProcessUnitDefinitionReference,
5058
Field(
5159
title="CHANGE_FROM",
5260
description="Reference to the existing process unit template being replaced.",
5361
),
5462
]
5563
change_to: Annotated[
56-
ProcessUnitReference,
64+
ProcessUnitDefinitionReference,
5765
Field(
5866
title="CHANGE_TO",
5967
description="Reference to the new process unit template to use.",
@@ -78,7 +86,7 @@ class YamlPipelineEvent(YamlBase):
7886
class YamlProcessPipeline(YamlBase):
7987
type: Literal["SERIAL"]
8088
name: str
81-
items: list[YamlItem[YamlProcessUnit]]
89+
items: list[YamlProcessUnitItem]
8290
events: Annotated[
8391
list[YamlPipelineEvent],
8492
Field(

src/libecalc/presentation/yaml/yaml_types/process/yaml_process_references.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,19 @@
22
Shared reference type aliases for YAML process types.
33
"""
44

5+
from typing import NewType
6+
57
type StreamRef = str
68
type ProcessPipelineReference = str # TODO: validate correct reference
79
type ProcessUnitReference = str
810
type EcalcEventReference = str
911
type ProcessEventReference = str
1012
type PumpChartReference = str
13+
14+
ProcessUnitInstanceName = NewType("ProcessUnitInstanceName", str)
15+
ProcessUnitInstanceReference = NewType("ProcessUnitInstanceReference", str)
16+
ProcessUnitDefinitionReference = NewType("ProcessUnitDefinitionReference", str)
17+
18+
ProcessPipelineInstanceName = NewType("ProcessPipelineInstanceName", str)
19+
ProcessPipelineInstanceReference = NewType("ProcessPipelineInstanceReference", str)
20+
ProcessPipelineDefinitionReference = NewType("ProcessPipelineDefinitionReference", str)

src/libecalc/presentation/yaml/yaml_types/process/yaml_process_simulation.py

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,13 @@
55
from libecalc.ecalc_model.ecalc_event import EcalcEventType, ProcessEventType
66
from libecalc.presentation.yaml.yaml_types import YamlBase
77
from libecalc.presentation.yaml.yaml_types.components.yaml_expression_type import YamlExpressionType
8-
from libecalc.presentation.yaml.yaml_types.process.yaml_process_pipeline import (
9-
YamlItem,
10-
YamlProcessPipeline,
11-
)
8+
from libecalc.presentation.yaml.yaml_types.process.yaml_process_pipeline import YamlProcessPipeline
129
from libecalc.presentation.yaml.yaml_types.process.yaml_process_references import (
1310
EcalcEventReference,
14-
ProcessPipelineReference,
15-
ProcessUnitReference,
11+
ProcessPipelineDefinitionReference,
12+
ProcessPipelineInstanceName,
13+
ProcessPipelineInstanceReference,
14+
ProcessUnitInstanceReference,
1615
PumpChartReference,
1716
)
1817
from libecalc.presentation.yaml.yaml_types.process.yaml_stream_distribution import YamlStreamDistribution
@@ -83,9 +82,14 @@ class YamlProcessEvent(YamlBase):
8382
]
8483

8584

85+
class YamlProcessPipelineTarget(YamlBase):
86+
name: ProcessPipelineInstanceName | None = None
87+
target: YamlProcessPipeline | ProcessPipelineDefinitionReference
88+
89+
8690
class YamlProcessConstraint(YamlBase):
8791
process_unit: Annotated[
88-
ProcessUnitReference | None,
92+
ProcessUnitInstanceReference | None,
8993
Field(
9094
title="PROCESS_UNIT",
9195
description="Reference to a named unit within the pipeline. If omitted, the constraint applies to the last process unit in the pipeline section.",
@@ -117,12 +121,12 @@ class YamlProcessConstraint(YamlBase):
117121
class YamlProcessSimulation(YamlBase):
118122
name: str
119123
targets: Annotated[
120-
list[YamlItem[YamlProcessPipeline]],
124+
list[YamlProcessPipelineTarget],
121125
Field(title="TARGETS"),
122126
]
123127
stream_distribution: YamlStreamDistribution
124128
constraints: Annotated[
125-
dict[ProcessPipelineReference, list[YamlProcessConstraint]],
129+
dict[ProcessPipelineInstanceReference, list[YamlProcessConstraint]],
126130
Field(
127131
title="CONSTRAINTS",
128132
description="Constraints per target. Key is pipeline name, value is list of constraints.",

src/libecalc/presentation/yaml/yaml_types/process/yaml_stream_distribution.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,14 @@
33

44
from libecalc.presentation.yaml.yaml_types import YamlBase
55
from libecalc.presentation.yaml.yaml_types.components.yaml_expression_type import YamlExpressionType
6-
from libecalc.presentation.yaml.yaml_types.process.yaml_process_references import ProcessPipelineReference
6+
from libecalc.presentation.yaml.yaml_types.process.yaml_process_references import ProcessPipelineInstanceReference
77
from libecalc.presentation.yaml.yaml_types.streams.yaml_inlet_stream import YamlInletStream
88
from libecalc.presentation.yaml.yaml_types.process.yaml_process_references import StreamRef
99

1010

1111
class YamlOverflow(YamlBase):
12-
from_reference: ProcessPipelineReference
13-
to_reference: ProcessPipelineReference
12+
from_reference: ProcessPipelineInstanceReference
13+
to_reference: ProcessPipelineInstanceReference
1414

1515

1616
class YamlCommonStreamSetting(YamlBase):

0 commit comments

Comments
 (0)