-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
chore: implement venting emitter dto
- Loading branch information
Showing
7 changed files
with
229 additions
and
205 deletions.
There are no files selected for viewing
Empty file.
167 changes: 167 additions & 0 deletions
167
src/libecalc/domain/infrastructure/emitters/venting_emitter.py
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,167 @@ | ||
from typing import Optional | ||
|
||
import numpy as np | ||
|
||
from libecalc.application.energy.component_energy_context import ComponentEnergyContext | ||
from libecalc.application.energy.emitter import Emitter | ||
from libecalc.application.energy.energy_component import EnergyComponent | ||
from libecalc.application.energy.energy_model import EnergyModel | ||
from libecalc.common.component_type import ComponentType | ||
from libecalc.common.string.string_utils import generate_id | ||
from libecalc.common.temporal_model import TemporalModel | ||
from libecalc.common.time_utils import Period | ||
from libecalc.common.units import Unit | ||
from libecalc.common.utils.rates import Rates, RateType, TimeSeriesFloat, TimeSeriesStreamDayRate | ||
from libecalc.common.variables import ExpressionEvaluator | ||
from libecalc.core.result.emission import EmissionResult | ||
from libecalc.dto.types import ConsumerUserDefinedCategoryType | ||
from libecalc.dto.utils.validators import convert_expression | ||
from libecalc.expression import Expression | ||
from libecalc.presentation.yaml.yaml_types.emitters.yaml_venting_emitter import ( | ||
YamlVentingEmission, | ||
YamlVentingType, | ||
YamlVentingVolume, | ||
) | ||
|
||
|
||
class VentingEmitter(Emitter, EnergyComponent): | ||
def __init__( | ||
self, | ||
name: str, | ||
expression_evaluator: ExpressionEvaluator, | ||
component_type: ComponentType, | ||
user_defined_category: dict[Period, ConsumerUserDefinedCategoryType], | ||
emitter_type: YamlVentingType, | ||
): | ||
self.name = name | ||
self.expression_evaluator = expression_evaluator | ||
self.component_type = component_type | ||
self.user_defined_category = user_defined_category | ||
self.emitter_type = emitter_type | ||
self._regularity_evaluated = None | ||
|
||
@property | ||
def id(self) -> str: | ||
return generate_id(self.name) | ||
|
||
@property | ||
def regularity_evaluated(self): | ||
return self.expression_evaluator.evaluate(expression=TemporalModel(self._regularity)).tolist() | ||
|
||
def evaluate_emissions( | ||
self, | ||
energy_context: ComponentEnergyContext, | ||
energy_model: EnergyModel, | ||
) -> Optional[dict[str, EmissionResult]]: | ||
self._regularity = energy_model.get_regularity(self.id) | ||
venting_emitter_results = {} | ||
emission_rates = self.get_emissions() | ||
|
||
for emission_name, emission_rate in emission_rates.items(): | ||
emission_result = EmissionResult( | ||
name=emission_name, | ||
periods=self.expression_evaluator.get_periods(), | ||
rate=emission_rate, | ||
) | ||
venting_emitter_results[emission_name] = emission_result | ||
return venting_emitter_results | ||
|
||
def get_emissions(self) -> dict[str, TimeSeriesStreamDayRate]: | ||
raise NotImplementedError("Subclasses should implement this method") | ||
|
||
def _evaluate_emission_rate(self, emission): | ||
emission_rate = self.expression_evaluator.evaluate(Expression.setup_from_expression(value=emission.rate.value)) | ||
if emission.rate.type == RateType.CALENDAR_DAY: | ||
emission_rate = Rates.to_stream_day( | ||
calendar_day_rates=np.asarray(emission_rate), regularity=self.regularity_evaluated | ||
).tolist() | ||
unit = emission.rate.unit.to_unit() | ||
emission_rate = unit.to(Unit.TONS_PER_DAY)(emission_rate) | ||
return emission_rate | ||
|
||
def _create_time_series(self, emission_rate): | ||
return TimeSeriesStreamDayRate( | ||
periods=self.expression_evaluator.get_periods(), | ||
values=emission_rate, | ||
unit=Unit.TONS_PER_DAY, | ||
) | ||
|
||
def is_fuel_consumer(self) -> bool: | ||
return False | ||
|
||
def is_electricity_consumer(self) -> bool: | ||
return False | ||
|
||
def get_component_process_type(self) -> ComponentType: | ||
return self.component_type | ||
|
||
def get_name(self) -> str: | ||
return self.name | ||
|
||
def is_provider(self) -> bool: | ||
return False | ||
|
||
def is_container(self) -> bool: | ||
return False | ||
|
||
|
||
class DirectVentingEmitter(VentingEmitter): | ||
def __init__(self, emissions: list[YamlVentingEmission], **kwargs): | ||
super().__init__(**kwargs) | ||
self.emissions = emissions | ||
self.emitter_type = YamlVentingType.DIRECT_EMISSION | ||
|
||
def get_emissions(self) -> dict[str, TimeSeriesStreamDayRate]: | ||
emissions = {} | ||
for emission in self.emissions: | ||
emission_rate = self._evaluate_emission_rate(emission) | ||
emissions[emission.name] = self._create_time_series(emission_rate) | ||
return emissions | ||
|
||
|
||
class OilVentingEmitter(VentingEmitter): | ||
def __init__(self, volume: YamlVentingVolume, **kwargs): | ||
super().__init__(**kwargs) | ||
self.volume = volume | ||
self.emitter_type = YamlVentingType.OIL_VOLUME | ||
|
||
def get_emissions(self) -> dict[str, TimeSeriesStreamDayRate]: | ||
oil_rates = self.expression_evaluator.evaluate( | ||
expression=Expression.setup_from_expression(value=self.volume.rate.value) | ||
) | ||
if self.volume.rate.type == RateType.CALENDAR_DAY: | ||
oil_rates = Rates.to_stream_day( | ||
calendar_day_rates=np.asarray(oil_rates), regularity=self.regularity_evaluated | ||
).tolist() | ||
emissions = {} | ||
for emission in self.volume.emissions: | ||
factors = self.expression_evaluator.evaluate( | ||
Expression.setup_from_expression(value=emission.emission_factor) | ||
) | ||
unit = self.volume.rate.unit.to_unit() | ||
oil_rates = unit.to(Unit.STANDARD_CUBIC_METER_PER_DAY)(oil_rates) | ||
emission_rate = [oil_rate * factor for oil_rate, factor in zip(oil_rates, factors)] | ||
emission_rate = Unit.KILO_PER_DAY.to(Unit.TONS_PER_DAY)(emission_rate) | ||
emissions[emission.name] = self._create_time_series(emission_rate) | ||
return emissions | ||
|
||
def get_oil_rates( | ||
self, | ||
regularity: TimeSeriesFloat, | ||
) -> TimeSeriesStreamDayRate: | ||
oil_rates = self.expression_evaluator.evaluate(expression=convert_expression(self.volume.rate.value)) | ||
|
||
if self.volume.rate.type == RateType.CALENDAR_DAY: | ||
oil_rates = Rates.to_stream_day( | ||
calendar_day_rates=np.asarray(oil_rates), | ||
regularity=regularity.values, | ||
).tolist() | ||
|
||
unit = self.volume.rate.unit.to_unit() | ||
oil_rates = unit.to(Unit.STANDARD_CUBIC_METER_PER_DAY)(oil_rates) | ||
|
||
return TimeSeriesStreamDayRate( | ||
periods=self.expression_evaluator.get_periods(), | ||
values=oil_rates, | ||
unit=Unit.STANDARD_CUBIC_METER_PER_DAY, | ||
) |
This file contains 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
This file contains 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
This file contains 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
Oops, something went wrong.