Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 13 additions & 2 deletions src/libecalc/process/process_pipeline/process_unit.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import abc
from abc import abstractmethod
from typing import NewType, Self
from uuid import UUID

Expand All @@ -9,10 +10,20 @@
ProcessUnitId = NewType("ProcessUnitId", UUID)


class ProcessUnit(Entity[ProcessUnitId], StreamPropagator, abc.ABC):
@abc.abstractmethod
class ProcessUnit[TSnapshot](Entity[ProcessUnitId], StreamPropagator, abc.ABC):
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.

TSnapshot, or TInput and TOutput? for a snapshot?

@abstractmethod
def get_id(self) -> ProcessUnitId: ...

@classmethod
def _create_id(cls: type[Self]) -> ProcessUnitId:
return ProcessUnitId(ecalc_id_generator())

@abstractmethod
def _record_snapshot(self, key: object, snapshot: TSnapshot) -> None: ...

@abstractmethod
def snapshot_for(self, key: object) -> TSnapshot | None: ...

@abstractmethod
@property
def history(self) -> list[TSnapshot]: ...
54 changes: 52 additions & 2 deletions src/libecalc/process/process_units/compressor.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from typing import Final

from libecalc.common.ddd import value_object
from libecalc.domain.process.compressor.core.train.utils.common import (
RECIRCULATION_BOUNDARY_TOLERANCE,
calculate_outlet_pressure_and_stream,
Expand All @@ -13,7 +14,20 @@
from libecalc.process.process_solver.boundary import Boundary


class Compressor(ProcessUnit):
@value_object
class OperatingPoint:
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.

correct "input params"?

inlet_stream: FluidStream
speed: float


@value_object
class CompressorSnapshot:
outlet_stream: FluidStream
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.

relevant "minimum" output params?

polytropic_head_joule_per_kg: float
polytropic_efficiency: float


class Compressor(ProcessUnit[CompressorSnapshot]):
def __init__(
self,
compressor_chart: ChartData,
Expand All @@ -25,10 +39,34 @@ def __init__(
self._fluid_service = fluid_service
self._speed: float | None = None

# Both, for different purposes?
self._snapshots: dict[OperatingPoint, CompressorSnapshot] = {}
self._history: list[CompressorSnapshot] = []

def get_id(self) -> ProcessUnitId:
return self._id

def _record_snapshot(self, key: object, snapshot: CompressorSnapshot) -> None:
if not isinstance(key, OperatingPoint):
raise ValueError("Key must be of type OperatingPoint")
self._snapshots[key] = snapshot
self._history.append(snapshot)

def snapshot_for(self, key: object) -> CompressorSnapshot | None:
if not isinstance(key, OperatingPoint):
raise ValueError("Key must be of type OperatingPoint")
return self._snapshots.get(key, None)

@property
def history(self) -> list[CompressorSnapshot]:
return self._history

def propagate_stream(self, inlet_stream: FluidStream) -> FluidStream:
if (
cached_snapshot := self.snapshot_for(OperatingPoint(inlet_stream=inlet_stream, speed=self.speed))
) is not None:
return cached_snapshot.outlet_stream

actual_rate = inlet_stream.volumetric_rate_m3_per_hour
if actual_rate < self.minimum_flow_rate:
raise RateTooLowError(
Expand Down Expand Up @@ -56,13 +94,25 @@ def propagate_stream(self, inlet_stream: FluidStream) -> FluidStream:
rate=actual_rate,
)

return calculate_outlet_pressure_and_stream(
outlet_stream = calculate_outlet_pressure_and_stream(
polytropic_efficiency=polytropic_efficiency,
polytropic_head_joule_per_kg=polytropic_head,
inlet_stream=inlet_stream,
fluid_service=self._fluid_service,
)

# Ok that it is explicit, or decorator?
self._record_snapshot(
key=OperatingPoint(inlet_stream=inlet_stream, speed=self.speed),
snapshot=CompressorSnapshot(
outlet_stream=outlet_stream,
polytropic_head_joule_per_kg=polytropic_head,
polytropic_efficiency=polytropic_efficiency,
),
)

return outlet_stream

@property
def compressor_chart(self) -> CompressorChart:
return self._compressor_chart
Expand Down
Loading