diff --git a/src/libecalc/application/energy_calculator.py b/src/libecalc/application/energy_calculator.py index c6f5431630..fbcd594dff 100644 --- a/src/libecalc/application/energy_calculator.py +++ b/src/libecalc/application/energy_calculator.py @@ -11,13 +11,16 @@ from libecalc.common.math.numbers import Numbers from libecalc.common.priorities import PriorityID from libecalc.common.priority_optimizer import PriorityOptimizer +from libecalc.common.temporal_model import TemporalModel from libecalc.common.units import Unit from libecalc.common.utils.rates import TimeSeriesInt, TimeSeriesString from libecalc.core.consumers.consumer_system import ConsumerSystem from libecalc.core.consumers.factory import create_consumer from libecalc.core.consumers.generator_set import Genset from libecalc.core.consumers.legacy_consumer.component import Consumer +from libecalc.core.consumers.legacy_consumer.consumer_function_mapper import EnergyModelMapper from libecalc.core.models.fuel import FuelModel +from libecalc.core.models.generator import GeneratorModelSampled from libecalc.core.result import ComponentResult, EcalcModelResult from libecalc.core.result.emission import EmissionResult from libecalc.dto.component_graph import ComponentGraph @@ -47,10 +50,36 @@ def evaluate_energy_usage(self, variables_map: dto.VariablesMap) -> Dict[str, Ec for component_dto in component_dtos: if isinstance(component_dto, (dto.ElectricityConsumer, dto.FuelConsumer)): - consumer = Consumer(consumer_dto=component_dto) + consumer = Consumer( + id=component_dto.id, + name=component_dto.name, + component_type=component_dto.component_type, + regularity=TemporalModel(component_dto.regularity), + consumes=component_dto.consumes, + energy_usage_model=TemporalModel( + { + start_time: EnergyModelMapper.from_dto_to_domain(model) + for start_time, model in component_dto.energy_usage_model.items() + } + ), + ) consumer_results[component_dto.id] = consumer.evaluate(variables_map=variables_map) elif isinstance(component_dto, dto.GeneratorSet): - fuel_consumer = Genset(component_dto) + fuel_consumer = Genset( + id=component_dto.id, + name=component_dto.name, + temporal_generator_set_model=TemporalModel( + { + start_time: GeneratorModelSampled( + fuel_values=model.fuel_values, + power_values=model.power_values, + energy_usage_adjustment_constant=model.energy_usage_adjustment_constant, + energy_usage_adjustment_factor=model.energy_usage_adjustment_factor, + ) + for start_time, model in component_dto.generator_set_model.items() + } + ), + ) power_requirement = elementwise_sum( *[ diff --git a/src/libecalc/core/consumers/generator_set.py b/src/libecalc/core/consumers/generator_set.py index da1e6a09ca..0c5b47d74d 100644 --- a/src/libecalc/core/consumers/generator_set.py +++ b/src/libecalc/core/consumers/generator_set.py @@ -1,7 +1,6 @@ import numpy as np from numpy.typing import NDArray -from libecalc import dto from libecalc.common.list.list_utils import array_to_list from libecalc.common.logger import logger from libecalc.common.temporal_model import TemporalModel @@ -20,16 +19,14 @@ class Genset: def __init__( self, - data_transfer_object: dto.GeneratorSet, + id: str, + name: str, + temporal_generator_set_model: TemporalModel[GeneratorModelSampled], ): - logger.debug(f"Creating Genset: {data_transfer_object.name}") - self.data_transfer_object = data_transfer_object - self.temporal_generator_set_model = TemporalModel( - { - start_time: GeneratorModelSampled(model) - for start_time, model in data_transfer_object.generator_set_model.items() - } - ) + logger.debug(f"Creating Genset: {name}") + self.id = id + self.name = name + self.temporal_generator_set_model = temporal_generator_set_model def evaluate( self, @@ -39,7 +36,7 @@ def evaluate( """Warning! We are converting energy usage to NaN when the energy usage models has invalid timesteps. this will probably be changed soon. """ - logger.debug(f"Evaluating Genset: {self.data_transfer_object.name}") + logger.debug(f"Evaluating Genset: {self.name}") if not len(power_requirement) == len(variables_map.time_vector): raise ValueError("length of power_requirement does not match the time vector.") @@ -62,7 +59,7 @@ def evaluate( fuel_rate = np.nan_to_num(fuel_rate) return GeneratorSetResult( - id=self.data_transfer_object.id, + id=self.id, timesteps=variables_map.time_vector, is_valid=TimeSeriesBoolean( timesteps=variables_map.time_vector, @@ -87,7 +84,7 @@ def evaluate( ) def evaluate_fuel_rate( - self, power_requirement: NDArray[np.float64], variables_map: dto.VariablesMap + self, power_requirement: NDArray[np.float64], variables_map: VariablesMap ) -> NDArray[np.float64]: result = np.full_like(power_requirement, fill_value=np.nan).astype(float) for period, model in self.temporal_generator_set_model.items(): @@ -97,7 +94,7 @@ def evaluate_fuel_rate( return result def evaluate_power_capacity_margin( - self, power_requirement: NDArray[np.float64], variables_map: dto.VariablesMap + self, power_requirement: NDArray[np.float64], variables_map: VariablesMap ) -> NDArray[np.float64]: result = np.zeros_like(power_requirement).astype(float) for period, model in self.temporal_generator_set_model.items(): diff --git a/src/libecalc/core/consumers/legacy_consumer/component.py b/src/libecalc/core/consumers/legacy_consumer/component.py index 9146e584ea..c0b9603205 100644 --- a/src/libecalc/core/consumers/legacy_consumer/component.py +++ b/src/libecalc/core/consumers/legacy_consumer/component.py @@ -6,8 +6,8 @@ import numpy as np from numpy.typing import NDArray +from typing_extensions import assert_never -from libecalc import dto from libecalc.common.list.list_utils import array_to_list from libecalc.common.logger import logger from libecalc.common.temporal_model import TemporalExpression, TemporalModel @@ -22,11 +22,9 @@ ) from libecalc.core.consumers.base import BaseConsumer from libecalc.core.consumers.legacy_consumer.consumer_function import ( + ConsumerFunction, ConsumerFunctionResult, ) -from libecalc.core.consumers.legacy_consumer.consumer_function_mapper import ( - EnergyModelMapper, -) from libecalc.core.consumers.legacy_consumer.result_mapper import ( get_consumer_system_models, get_operational_settings_results_from_consumer_result, @@ -43,9 +41,10 @@ GenericComponentResult, PumpResult, ) -from libecalc.dto import VariablesMap from libecalc.dto.base import ComponentType from libecalc.dto.types import ConsumptionType +from libecalc.dto.variables import VariablesMap +from libecalc.expression import Expression def get_operational_settings_used_from_consumer_result( @@ -65,31 +64,35 @@ def get_operational_settings_used_from_consumer_result( class Consumer(BaseConsumer): def __init__( self, - consumer_dto: dto.components.Consumer, - ): - logger.debug(f"Creating Consumer: {consumer_dto.name}") - self._consumer_dto = consumer_dto - self._consumer_time_function = TemporalModel( - { - start_time: EnergyModelMapper.from_dto_to_domain(model) - for start_time, model in consumer_dto.energy_usage_model.items() - } - ) + id: str, + name: str, + component_type: ComponentType, + consumes: ConsumptionType, + regularity: TemporalModel[Expression], + energy_usage_model: TemporalModel[ConsumerFunction], + ) -> None: + logger.debug(f"Creating Consumer: {name}") + self._id = id + self.name = name + self.component_type = component_type + self.consumes: ConsumptionType = consumes + self.regularity = regularity + self._consumer_time_function = energy_usage_model @property def id(self): - return self._consumer_dto.id + return self._id def map_model_result(self, model_result: Union[ConsumerOrSystemFunctionResult]) -> List[ConsumerModelResult]: - if self._consumer_dto.component_type in [ComponentType.PUMP_SYSTEM, ComponentType.COMPRESSOR_SYSTEM]: + if self.component_type in [ComponentType.PUMP_SYSTEM, ComponentType.COMPRESSOR_SYSTEM]: return get_consumer_system_models( model_result, - name=self._consumer_dto.name, + name=self.name, ) else: return get_single_consumer_models( result=model_result, - name=self._consumer_dto.name, + name=self.name, ) def get_consumer_result( @@ -100,7 +103,7 @@ def get_consumer_result( power_usage: TimeSeriesStreamDayRate, aggregated_result: Union[ConsumerOrSystemFunctionResult], ) -> ConsumerResult: - if self._consumer_dto.component_type in [ComponentType.PUMP_SYSTEM, ComponentType.COMPRESSOR_SYSTEM]: + if self.component_type in [ComponentType.PUMP_SYSTEM, ComponentType.COMPRESSOR_SYSTEM]: operational_settings_used = get_operational_settings_used_from_consumer_result(result=aggregated_result) operational_settings_used.values = self.reindex_time_vector( values=operational_settings_used.values, @@ -111,7 +114,7 @@ def get_consumer_result( operational_settings_used.timesteps = timesteps operational_settings_result = get_operational_settings_results_from_consumer_result( - aggregated_result, parent_id=self._consumer_dto.id + aggregated_result, parent_id=self.id ) # convert to 1-based index @@ -119,7 +122,7 @@ def get_consumer_result( operational_settings_used.values = [i + 1 for i in operational_settings_used.values] consumer_result = ConsumerSystemResult( - id=self._consumer_dto.id, + id=self.id, timesteps=timesteps, is_valid=is_valid, power=power_usage, @@ -128,7 +131,7 @@ def get_consumer_result( operational_settings_results=operational_settings_result, ) - elif self._consumer_dto.component_type == ComponentType.PUMP: + elif self.component_type == ComponentType.PUMP: # Using generic consumer result as pump has no specific results currently inlet_rate_time_series = TimeSeriesStreamDayRate( @@ -156,7 +159,7 @@ def get_consumer_result( ).reindex(new_time_vector=timesteps) consumer_result = PumpResult( - id=self._consumer_dto.id, + id=self.id, timesteps=timesteps, is_valid=is_valid, energy_usage=energy_usage, @@ -166,7 +169,7 @@ def get_consumer_result( outlet_pressure_bar=outlet_pressure_time_series, operational_head=operational_head_time_series, ) - elif self._consumer_dto.component_type == ComponentType.COMPRESSOR: + elif self.component_type == ComponentType.COMPRESSOR: # All energy_function_results should be CompressorTrainResult, # if not the consumer should not have COMPRESSOR type. if isinstance(aggregated_result.energy_function_result, CompressorTrainResult): @@ -205,7 +208,7 @@ def get_consumer_result( outlet_pressure_before_choking = [math.nan] * len(timesteps) consumer_result = CompressorResult( - id=self._consumer_dto.id, + id=self.id, timesteps=timesteps, is_valid=is_valid, energy_usage=energy_usage, @@ -225,7 +228,7 @@ def get_consumer_result( else: consumer_result = GenericComponentResult( - id=self._consumer_dto.id, + id=self.id, timesteps=timesteps, is_valid=is_valid, energy_usage=energy_usage, @@ -240,9 +243,9 @@ def evaluate( """Warning! We are converting energy usage to NaN when the energy usage models has invalid timesteps. this will probably be changed soon. """ - logger.debug(f"Evaluating consumer: {self._consumer_dto.name}") + logger.debug(f"Evaluating consumer: {self.name}") regularity = TemporalExpression.evaluate( - temporal_expression=TemporalModel(self._consumer_dto.regularity), + temporal_expression=self.regularity, variables_map=variables_map, ) @@ -276,7 +279,7 @@ def evaluate( # By convention, we change remaining NaN-values to 0 regardless of extrapolation energy_usage = np.nan_to_num(energy_usage) - if self._consumer_dto.consumes == ConsumptionType.FUEL: + if self.consumes == ConsumptionType.FUEL: power_time_series = None if aggregated_consumer_function_result.power is not None: power = self.reindex_time_vector( @@ -295,7 +298,7 @@ def evaluate( unit=Unit.STANDARD_CUBIC_METER_PER_DAY, ) - elif self._consumer_dto.consumes == ConsumptionType.ELECTRICITY: + elif self.consumes == ConsumptionType.ELECTRICITY: energy_usage_time_series = TimeSeriesStreamDayRate( timesteps=variables_map.time_vector, values=array_to_list(energy_usage), @@ -304,7 +307,7 @@ def evaluate( power_time_series = energy_usage_time_series.model_copy() else: - raise ValueError(f"Consuming '{self._consumer_dto.consumes}' is not implemented.") + assert_never(self.consumes) is_valid = TimeSeriesBoolean( timesteps=variables_map.time_vector, @@ -320,7 +323,7 @@ def evaluate( aggregated_result=aggregated_consumer_function_result, ) - if self._consumer_dto.component_type in [ComponentType.PUMP_SYSTEM, ComponentType.COMPRESSOR_SYSTEM]: + if self.component_type in [ComponentType.PUMP_SYSTEM, ComponentType.COMPRESSOR_SYSTEM]: model_results = self.map_model_result(aggregated_consumer_function_result) else: model_results = [self.map_model_result(model_result) for model_result in consumer_function_results] diff --git a/src/libecalc/core/models/generator.py b/src/libecalc/core/models/generator.py index 12a3daa58d..b0870808fe 100644 --- a/src/libecalc/core/models/generator.py +++ b/src/libecalc/core/models/generator.py @@ -1,24 +1,28 @@ +from typing import List + import numpy as np from numpy.typing import NDArray from scipy.interpolate import interp1d -from libecalc import dto from libecalc.common.list.adjustment import transform_linear class GeneratorModelSampled: def __init__( self, - data_transfer_object: dto.GeneratorSetSampled, + fuel_values: List[float], + power_values: List[float], + energy_usage_adjustment_constant: float, + energy_usage_adjustment_factor: float, ): fuel_values = transform_linear( - np.array(data_transfer_object.fuel_values), - constant=data_transfer_object.energy_usage_adjustment_constant, - factor=data_transfer_object.energy_usage_adjustment_factor, + np.array(fuel_values), + constant=energy_usage_adjustment_constant, + factor=energy_usage_adjustment_factor, ) self._func = interp1d( - data_transfer_object.power_values, + power_values, fuel_values.tolist(), fill_value=(min(fuel_values), max(fuel_values)), bounds_error=False, diff --git a/src/tests/libecalc/core/consumers/consumer_function/test_direct_expression_consumer_function.py b/src/tests/libecalc/core/consumers/consumer_function/test_direct_expression_consumer_function.py index b3c6617192..c67599dc37 100644 --- a/src/tests/libecalc/core/consumers/consumer_function/test_direct_expression_consumer_function.py +++ b/src/tests/libecalc/core/consumers/consumer_function/test_direct_expression_consumer_function.py @@ -5,12 +5,14 @@ import libecalc.common.utils.rates from libecalc import dto +from libecalc.common.temporal_model import TemporalModel from libecalc.core.consumers.legacy_consumer.component import Consumer from libecalc.core.consumers.legacy_consumer.consumer_function.direct_expression_consumer_function import ( DirectExpressionConsumerFunction, ) from libecalc.dto import VariablesMap -from libecalc.dto.base import ComponentType, ConsumerUserDefinedCategoryType +from libecalc.dto.base import ComponentType +from libecalc.dto.types import ConsumptionType from libecalc.expression import Expression @@ -22,7 +24,7 @@ def direct_variables_map(): def test_direct_expression_consumer_function(): time_series_name = "SIM1" - fuelratefunction = dto.DirectConsumerFunction( + fuel_rate_function_data = dto.DirectConsumerFunction( fuel_rate=Expression.setup_from_expression(time_series_name + ";Flare {+} " + time_series_name + ";Vent"), energy_usage_type=dto.types.EnergyUsageType.FUEL, ) @@ -32,7 +34,8 @@ def test_direct_expression_consumer_function(): time_vector=[datetime(2000, 1, 1, 0, 0), datetime(2001, 1, 1, 0, 0)], variables={"SIM1;Flare": [10.0, 3.0], "SIM1;Vent": [5.0, 2.0]}, ) - result = DirectExpressionConsumerFunction(fuelratefunction).evaluate( + + result = DirectExpressionConsumerFunction(fuel_rate_function_data).evaluate( variables_map=variables_map, regularity=[1.0] * len(variables_map.time_vector), ) @@ -41,14 +44,14 @@ def test_direct_expression_consumer_function(): # Test when used as consumer function for a fuel consumer fuel_consumer = Consumer( - dto.FuelConsumer( - name="Flare", - component_type=ComponentType.GENERIC, - energy_usage_model={datetime(1900, 1, 1): fuelratefunction}, - fuel={datetime(1900, 1, 1): dto.types.FuelType(name="standard_fuel", emissions=[])}, - user_defined_category={datetime(1900, 1, 1): ConsumerUserDefinedCategoryType.MISCELLANEOUS}, - regularity={datetime(1900, 1, 1): Expression.setup_from_expression(1)}, - ) + id="Flare", + name="Flare", + component_type=ComponentType.GENERIC, + energy_usage_model=TemporalModel( + {datetime(1900, 1, 1): DirectExpressionConsumerFunction(fuel_rate_function_data)} + ), + consumes=ConsumptionType.FUEL, + regularity=TemporalModel({datetime(1900, 1, 1): Expression.setup_from_expression(1)}), ) result = fuel_consumer.evaluate(variables_map=variables_map) consumer_result = result.component_result diff --git a/src/tests/libecalc/core/consumers/test_genset.py b/src/tests/libecalc/core/consumers/test_genset.py index 6357d23ee2..fd11f643ad 100644 --- a/src/tests/libecalc/core/consumers/test_genset.py +++ b/src/tests/libecalc/core/consumers/test_genset.py @@ -5,12 +5,14 @@ from libecalc import dto from libecalc.application.energy_calculator import EnergyCalculator +from libecalc.common.temporal_model import TemporalModel from libecalc.common.units import Unit from libecalc.common.utils.rates import ( TimeSeriesBoolean, TimeSeriesStreamDayRate, ) from libecalc.core.consumers.generator_set import Genset +from libecalc.core.models.generator import GeneratorModelSampled from libecalc.core.result.results import GenericComponentResult @@ -53,7 +55,21 @@ def test_genset_out_of_capacity(genset_2mw_dto, fuel_dto): def test_genset_with_elconsumer_nan_results(genset_2mw_dto, fuel_dto): """Testing what happens when the el-consumers has nan-values in power. -> Genset should not do anything.""" time_vector = pd.date_range(datetime(2020, 1, 1), datetime(2025, 1, 1), freq="YS").to_pydatetime().tolist() - genset = Genset(genset_2mw_dto) + genset = Genset( + id=genset_2mw_dto.id, + name=genset_2mw_dto.name, + temporal_generator_set_model=TemporalModel( + { + start_time: GeneratorModelSampled( + fuel_values=model.fuel_values, + power_values=model.power_values, + energy_usage_adjustment_constant=model.energy_usage_adjustment_constant, + energy_usage_adjustment_factor=model.energy_usage_adjustment_factor, + ) + for start_time, model in genset_2mw_dto.generator_set_model.items() + } + ), + ) results = genset.evaluate( variables_map=dto.VariablesMap(time_vector=time_vector), @@ -81,7 +97,21 @@ def test_genset_with_elconsumer_nan_results(genset_2mw_dto, fuel_dto): def test_genset_outside_capacity(genset_2mw_dto, fuel_dto): """Testing what happens when the power rate is outside of genset capacity. -> Genset will extrapolate (forward fill).""" time_vector = pd.date_range(datetime(2020, 1, 1), datetime(2025, 1, 1), freq="YS").to_pydatetime().tolist() - genset = Genset(genset_2mw_dto) + genset = Genset( + id=genset_2mw_dto.id, + name=genset_2mw_dto.name, + temporal_generator_set_model=TemporalModel( + { + start_time: GeneratorModelSampled( + fuel_values=model.fuel_values, + power_values=model.power_values, + energy_usage_adjustment_constant=model.energy_usage_adjustment_constant, + energy_usage_adjustment_factor=model.energy_usage_adjustment_factor, + ) + for start_time, model in genset_2mw_dto.generator_set_model.items() + } + ), + ) results = genset.evaluate( variables_map=dto.VariablesMap(time_vector=time_vector), diff --git a/src/tests/libecalc/core/consumers/test_legacy_consumer.py b/src/tests/libecalc/core/consumers/test_legacy_consumer.py index d09d125c03..2b8a11a863 100644 --- a/src/tests/libecalc/core/consumers/test_legacy_consumer.py +++ b/src/tests/libecalc/core/consumers/test_legacy_consumer.py @@ -5,6 +5,7 @@ import pandas as pd from libecalc import dto +from libecalc.common.temporal_model import TemporalModel from libecalc.common.units import Unit from libecalc.common.utils.rates import ( RateType, @@ -16,6 +17,7 @@ from libecalc.core.consumers.legacy_consumer.consumer_function import ( ConsumerFunctionResult, ) +from libecalc.core.consumers.legacy_consumer.consumer_function_mapper import EnergyModelMapper from libecalc.core.result import EcalcModelResult @@ -34,7 +36,19 @@ def test_compute_consumer_rate(): def test_evaluate_consumer_time_function(direct_el_consumer): """Testing using a direct el consumer for simplicity.""" - consumer = Consumer(direct_el_consumer) + consumer = Consumer( + id=direct_el_consumer.id, + name=direct_el_consumer.name, + component_type=direct_el_consumer.component_type, + regularity=TemporalModel(direct_el_consumer.regularity), + consumes=direct_el_consumer.consumes, + energy_usage_model=TemporalModel( + { + start_time: EnergyModelMapper.from_dto_to_domain(model) + for start_time, model in direct_el_consumer.energy_usage_model.items() + } + ), + ) time_vector = pd.date_range(datetime(2020, 1, 1), datetime(2025, 1, 1), freq="YS").to_pydatetime().tolist() results = consumer.evaluate_consumer_temporal_model( variables_map=dto.VariablesMap(time_vector=time_vector), regularity=np.ones_like(time_vector) @@ -48,7 +62,19 @@ def test_evaluate_consumer_time_function(direct_el_consumer): def test_fuel_consumer(tabulated_fuel_consumer): """Simple test to assert that the FuelConsumer actually runs as expected.""" time_vector = pd.date_range(datetime(2020, 1, 1), datetime(2025, 1, 1), freq="YS").to_pydatetime().tolist() - fuel_consumer = Consumer(tabulated_fuel_consumer) + fuel_consumer = Consumer( + id=tabulated_fuel_consumer.id, + name=tabulated_fuel_consumer.name, + component_type=tabulated_fuel_consumer.component_type, + regularity=TemporalModel(tabulated_fuel_consumer.regularity), + consumes=tabulated_fuel_consumer.consumes, + energy_usage_model=TemporalModel( + { + start_time: EnergyModelMapper.from_dto_to_domain(model) + for start_time, model in tabulated_fuel_consumer.energy_usage_model.items() + } + ), + ) result = fuel_consumer.evaluate( variables_map=dto.VariablesMap(time_vector=time_vector, variables={"RATE": [1, 1, 1, 1, 0, 0]}), @@ -73,7 +99,19 @@ def test_fuel_consumer(tabulated_fuel_consumer): def test_electricity_consumer(direct_el_consumer): """Simple test to assert that the FuelConsumer actually runs as expected.""" - electricity_consumer = Consumer(direct_el_consumer) + electricity_consumer = Consumer( + id=direct_el_consumer.id, + name=direct_el_consumer.name, + component_type=direct_el_consumer.component_type, + regularity=TemporalModel(direct_el_consumer.regularity), + consumes=direct_el_consumer.consumes, + energy_usage_model=TemporalModel( + { + start_time: EnergyModelMapper.from_dto_to_domain(model) + for start_time, model in direct_el_consumer.energy_usage_model.items() + } + ), + ) time_vector = pd.date_range(datetime(2020, 1, 1), datetime(2025, 1, 1), freq="YS").to_pydatetime().tolist() result = electricity_consumer.evaluate( variables_map=dto.VariablesMap(time_vector=time_vector), @@ -97,7 +135,19 @@ def test_electricity_consumer(direct_el_consumer): def test_electricity_consumer_mismatch_time_slots(direct_el_consumer): """The direct_el_consumer starts after the ElectricityConsumer is finished.""" time_vector = pd.date_range(datetime(2000, 1, 1), datetime(2005, 1, 1), freq="YS").to_pydatetime().tolist() - electricity_consumer = Consumer(direct_el_consumer) + electricity_consumer = Consumer( + id=direct_el_consumer.id, + name=direct_el_consumer.name, + component_type=direct_el_consumer.component_type, + regularity=TemporalModel(direct_el_consumer.regularity), + consumes=direct_el_consumer.consumes, + energy_usage_model=TemporalModel( + { + start_time: EnergyModelMapper.from_dto_to_domain(model) + for start_time, model in direct_el_consumer.energy_usage_model.items() + } + ), + ) result = electricity_consumer.evaluate( variables_map=dto.VariablesMap(time_vector=time_vector), @@ -130,7 +180,19 @@ def test_electricity_consumer_nan_values(direct_el_consumer): """ time_vector = pd.date_range(datetime(2020, 1, 1), datetime(2025, 1, 1), freq="YS").to_pydatetime().tolist() power = np.array([np.nan, np.nan, 1, np.nan, np.nan, np.nan]) - electricity_consumer = Consumer(direct_el_consumer) + electricity_consumer = Consumer( + id=direct_el_consumer.id, + name=direct_el_consumer.name, + component_type=direct_el_consumer.component_type, + regularity=TemporalModel(direct_el_consumer.regularity), + consumes=direct_el_consumer.consumes, + energy_usage_model=TemporalModel( + { + start_time: EnergyModelMapper.from_dto_to_domain(model) + for start_time, model in direct_el_consumer.energy_usage_model.items() + } + ), + ) consumer_function_result = ConsumerFunctionResult( power=power, energy_usage=power, diff --git a/src/tests/libecalc/core/models/test_generator_model.py b/src/tests/libecalc/core/models/test_generator_model.py index d8a35dbc02..6390312abe 100644 --- a/src/tests/libecalc/core/models/test_generator_model.py +++ b/src/tests/libecalc/core/models/test_generator_model.py @@ -1,7 +1,6 @@ import numpy as np import pandas as pd -from libecalc import dto from libecalc.core.models.generator import GeneratorModelSampled @@ -27,12 +26,10 @@ def test_evaluate(self): fuel_values = df["fuel"].tolist() el2fuel = GeneratorModelSampled( - data_transfer_object=dto.GeneratorSetSampled( - data=[power_values, fuel_values], - headers=["POWER", "FUEL"], - energy_usage_adjustment_factor=1, - energy_usage_adjustment_constant=0, - ) + fuel_values=fuel_values, + power_values=power_values, + energy_usage_adjustment_factor=1, + energy_usage_adjustment_constant=0, ) x_input = np.asarray([-1, 0, 5, 7, 10, 30, 31]) @@ -42,12 +39,10 @@ def test_evaluate(self): def test_capacity_margin(self): # Testing the capacity factor when using sampled genset. el2fuel_function = GeneratorModelSampled( - data_transfer_object=dto.GeneratorSetSampled( - data=[[1, 2, 3], [1, 2, 3]], - headers=["FUEL", "POWER"], - energy_usage_adjustment_factor=1, - energy_usage_adjustment_constant=0, - ) + fuel_values=[1, 2, 3], + power_values=[1, 2, 3], + energy_usage_adjustment_factor=1, + energy_usage_adjustment_constant=0, ) capacity_margin = el2fuel_function.evaluate_power_capacity_margin(np.array([0, 1, 2, 3, 4, 5])) np.testing.assert_allclose(capacity_margin, np.asarray([3, 2, 1, 0, -1, -2])) @@ -61,12 +56,10 @@ def test_energy_adjustment(self): adjustment_constant = 0.5 el2fuel = GeneratorModelSampled( - data_transfer_object=dto.GeneratorSetSampled( - data=[fuel_values, power_values], - headers=["FUEL", "POWER"], - energy_usage_adjustment_factor=adjustment_factor, - energy_usage_adjustment_constant=adjustment_constant, - ) + fuel_values=fuel_values, + power_values=power_values, + energy_usage_adjustment_factor=adjustment_factor, + energy_usage_adjustment_constant=adjustment_constant, ) expected_adjusted_fuel = list(np.array(fuel_values) * adjustment_factor + adjustment_constant) diff --git a/src/tests/libecalc/integration/test_all_consumer_with_time_slots_models.py b/src/tests/libecalc/integration/test_all_consumer_with_time_slots_models.py index 7bcc7d12b3..d7598b5f60 100644 --- a/src/tests/libecalc/integration/test_all_consumer_with_time_slots_models.py +++ b/src/tests/libecalc/integration/test_all_consumer_with_time_slots_models.py @@ -8,7 +8,9 @@ from libecalc import dto from libecalc.application.energy_calculator import EnergyCalculator from libecalc.application.graph_result import GraphResult +from libecalc.common.temporal_model import TemporalModel from libecalc.core.consumers.legacy_consumer.component import Consumer +from libecalc.core.consumers.legacy_consumer.consumer_function_mapper import EnergyModelMapper from libecalc.core.result import CompressorModelResult, GenericModelResult @@ -16,7 +18,19 @@ def test_mismatching_time_slots_within_a_consumer(time_slot_electricity_consumer """In case of mismatching time vector when ENERGY_USAGE_MODEL is outside of the vector of the CONSUMER. Then we still want a result. """ - el_consumer = Consumer(consumer_dto=time_slot_electricity_consumer_with_changing_model_type) + el_consumer = Consumer( + id=time_slot_electricity_consumer_with_changing_model_type.id, + name=time_slot_electricity_consumer_with_changing_model_type.name, + component_type=time_slot_electricity_consumer_with_changing_model_type.component_type, + regularity=TemporalModel(time_slot_electricity_consumer_with_changing_model_type.regularity), + consumes=time_slot_electricity_consumer_with_changing_model_type.consumes, + energy_usage_model=TemporalModel( + { + start_time: EnergyModelMapper.from_dto_to_domain(model) + for start_time, model in time_slot_electricity_consumer_with_changing_model_type.energy_usage_model.items() + } + ), + ) time_vector = [datetime(1900, 1, 1), datetime(1901, 1, 1)] result = el_consumer.evaluate(variables_map=dto.VariablesMap(time_vector=time_vector, variables={})) consumer_result = result.component_result @@ -28,7 +42,19 @@ def test_time_slots_with_changing_model(time_slot_electricity_consumer_with_chan """When using different ENERGY_USAGE_MODELs under a CONSUMER, the detailed energy_functions_results will be a list of results and not a merged object. """ - el_consumer = Consumer(consumer_dto=time_slot_electricity_consumer_with_changing_model_type) + el_consumer = Consumer( + id=time_slot_electricity_consumer_with_changing_model_type.id, + name=time_slot_electricity_consumer_with_changing_model_type.name, + component_type=time_slot_electricity_consumer_with_changing_model_type.component_type, + regularity=TemporalModel(time_slot_electricity_consumer_with_changing_model_type.regularity), + consumes=time_slot_electricity_consumer_with_changing_model_type.consumes, + energy_usage_model=TemporalModel( + { + start_time: EnergyModelMapper.from_dto_to_domain(model) + for start_time, model in time_slot_electricity_consumer_with_changing_model_type.energy_usage_model.items() + } + ), + ) input_variables_dict: Dict[str, List[float]] = {"RATE": np.linspace(start=2000000, stop=6000000, num=10).tolist()} result = el_consumer.evaluate( @@ -72,7 +98,19 @@ def test_time_slots_with_non_changing_model(time_slot_electricity_consumer_with_ """When using same ENERGY_USAGE_MODEL types under a CONSUMER, the detailed energy_functions_results will not be a merged result object. """ - el_consumer = Consumer(consumer_dto=time_slot_electricity_consumer_with_same_model_type) + el_consumer = Consumer( + id=time_slot_electricity_consumer_with_same_model_type.id, + name=time_slot_electricity_consumer_with_same_model_type.name, + component_type=time_slot_electricity_consumer_with_same_model_type.component_type, + regularity=TemporalModel(time_slot_electricity_consumer_with_same_model_type.regularity), + consumes=time_slot_electricity_consumer_with_same_model_type.consumes, + energy_usage_model=TemporalModel( + { + start_time: EnergyModelMapper.from_dto_to_domain(model) + for start_time, model in time_slot_electricity_consumer_with_same_model_type.energy_usage_model.items() + } + ), + ) input_variables_dict: Dict[str, List[float]] = {} result = el_consumer.evaluate( @@ -112,7 +150,19 @@ def test_time_slots_consumer_system_with_non_changing_model(time_slots_simplifie """When using compatible TYPEs within a CONSUMER SYSTEM then the result.""" start_year = 2015 time_steps = 10 - el_consumer = Consumer(consumer_dto=time_slots_simplified_compressor_system) + el_consumer = Consumer( + id=time_slots_simplified_compressor_system.id, + name=time_slots_simplified_compressor_system.name, + component_type=time_slots_simplified_compressor_system.component_type, + regularity=TemporalModel(time_slots_simplified_compressor_system.regularity), + consumes=time_slots_simplified_compressor_system.consumes, + energy_usage_model=TemporalModel( + { + start_time: EnergyModelMapper.from_dto_to_domain(model) + for start_time, model in time_slots_simplified_compressor_system.energy_usage_model.items() + } + ), + ) input_variables_dict: Dict[str, List[float]] = { "RATE": [1800000 - (x * 100000) for x in range(10)] # 1 000 000 -> 100 000 }