diff --git a/docs/MVS_parameters_list.csv b/docs/MVS_parameters_list.csv index e10a95641..0c7aa2dc9 100644 --- a/docs/MVS_parameters_list.csv +++ b/docs/MVS_parameters_list.csv @@ -48,3 +48,5 @@ 46, None, The type of the component., demand, *demand*, str, None,type_asset,typeasset-label 47, None," Input the type of OEMOF component. For example, a PV plant would be a source, a solar inverter would be a transformer, etc. The `type_oemof` will later on be determined through the EPA.", sink, *sink* or *source* or one of the other component classes of OEMOF., str, None,type_oemof,typeoemof-label 48, None, Unit associated with the capacity of the component.," Storage could have units like kW or kWh, transformer station could have kVA, and so on.", Appropriate scientific unit, str, NA,unit,unit-label +49, None, Thermal losses of storage independent of state of charge between two consecutive timesteps relative to nominal storage capacity., 0.0016, Between 0 and 1, Numeric, factor,fixed_thermal_losses_relative,fixed_thermal_losses_relative-label +50, None, Thermal losses of storage independent of state of charge and independent of nominal storage capacity between two consecutive timesteps., 0.0003, Between 0 and 1, Numeric, factor,fixed_thermal_losses_absolute,fixed_thermal_losses_absolute-label \ No newline at end of file diff --git a/docs/Model_Assumptions.rst b/docs/Model_Assumptions.rst index 089bbab7e..42cbe2e50 100644 --- a/docs/Model_Assumptions.rst +++ b/docs/Model_Assumptions.rst @@ -63,6 +63,61 @@ In case of excessive excess energy, a warning is given that it seems to be cheap High excess energy can for example result into an optimized inverter capacity that is smaller than the peak generation of installed PV. This becomes unrealistic when the excess is very high. +Stratified thermal storage +########################## + +In order to model a stratified thermal energy storage the two parameters `fixed_losses_relative` and `fixed_losses_absolute` are passed through `storage_xx.csv`. +They are used to take into account temperature dependent losses of a thermal storage. +Except for these two additional parameters the stratified thermal storage is implemented in the same way as other storage components. + +Precalculations of the `installedCap`, `efficiency`, `fixed_losses_relative` and `fixed_losses_absolute` can be done orientating on the stratified thermal storage component of `oemof.thermal `__. +Further parameters, which can be precalculated, are: U-value, volume and surface of the storage. + +The efficiency :math:`\eta` of the storage is calculated as follows: + +.. math:: + \eta = 1 - loss{\_}rate + +This example shows how to do precalculations using stratified thermal storage specific input data: + + +.. code-block:: python + + from oemof.thermal.stratified_thermal_storage import ( + calculate_storage_u_value, + calculate_storage_dimensions, + calculate_capacities, + calculate_losses, + ) + + # Precalculation + u_value = calculate_storage_u_value( + input_data['s_iso'], + input_data['lamb_iso'], + input_data['alpha_inside'], + input_data['alpha_outside']) + + volume, surface = calculate_storage_dimensions( + input_data['height'], + input_data['diameter'] + ) + + nominal_storage_capacity = calculate_capacities( + volume, + input_data['temp_h'], + input_data['temp_c']) + + loss_rate, fixed_losses_relative, fixed_losses_absolute = calculate_losses( + u_value, + input_data['diameter'], + input_data['temp_h'], + input_data['temp_c'], + input_data['temp_env']) + +Please see the `oemof.thermal` `examples `__ and the `documentation `__ for further information. + +For an investment optimization the height of the storage should be left open in the precalculations and `installedCap` should be set to 0 or NaN. + Energy providers (DSOs) ----------------------- diff --git a/src/multi_vector_simulator/D1_model_components.py b/src/multi_vector_simulator/D1_model_components.py index e31ad6543..97eca6140 100644 --- a/src/multi_vector_simulator/D1_model_components.py +++ b/src/multi_vector_simulator/D1_model_components.py @@ -31,6 +31,8 @@ SOC_INITIAL, SOC_MAX, SOC_MIN, + THERM_LOSSES_REL, + THERM_LOSSES_ABS, STORAGE_CAPACITY, TIMESERIES, TIMESERIES_NORMALIZED, @@ -578,6 +580,8 @@ def storage_fix(model, dict_asset, **kwargs): }, # maximum discharge possible in one timestep loss_rate=1 - dict_asset[STORAGE_CAPACITY][EFFICIENCY][VALUE], # from timestep to timestep + fixed_losses_absolute=dict_asset[STORAGE_CAPACITY][THERM_LOSSES_ABS][VALUE], + fixed_losses_relative=dict_asset[STORAGE_CAPACITY][THERM_LOSSES_REL][VALUE], min_storage_level=dict_asset[STORAGE_CAPACITY][SOC_MIN][VALUE], max_storage_level=dict_asset[STORAGE_CAPACITY][SOC_MAX][VALUE], initial_storage_level=dict_asset[STORAGE_CAPACITY][SOC_INITIAL][ @@ -641,6 +645,8 @@ def storage_optimize(model, dict_asset, **kwargs): }, # maximum discharge power loss_rate=1 - dict_asset[STORAGE_CAPACITY][EFFICIENCY][VALUE], # from timestep to timestep + fixed_losses_absolute=dict_asset[STORAGE_CAPACITY][THERM_LOSSES_ABS][VALUE], + fixed_losses_relative=dict_asset[STORAGE_CAPACITY][THERM_LOSSES_REL][VALUE], min_storage_level=dict_asset[STORAGE_CAPACITY][SOC_MIN][VALUE], max_storage_level=dict_asset[STORAGE_CAPACITY][SOC_MAX][VALUE], initial_storage_level=dict_asset[STORAGE_CAPACITY][SOC_INITIAL][ diff --git a/src/multi_vector_simulator/utils/constants.py b/src/multi_vector_simulator/utils/constants.py index 1fda6aa05..847d755a0 100644 --- a/src/multi_vector_simulator/utils/constants.py +++ b/src/multi_vector_simulator/utils/constants.py @@ -277,6 +277,18 @@ WARNING_TEXT: "allows setting a maximum amount of emissions of the optimized energy system (Values: None/Float). ", REQUIRED_IN_CSV_ELEMENTS: [CONSTRAINTS,], }, + THERM_LOSSES_REL: { + DEFAULT_VALUE: 0, + UNIT: TYPE_FLOAT, + WARNING_TEXT: "allows considering relative thermal energy losses (Values: Float). This is an advanced setting that most users can ignore.", + REQUIRED_IN_CSV_ELEMENTS: [ENERGY_STORAGE], + }, + THERM_LOSSES_ABS: { + DEFAULT_VALUE: 0, + UNIT: TYPE_FLOAT, + WARNING_TEXT: "allows considering relative thermal energy losses (Values: Float). This is an advanced setting that most users can ignore.", + REQUIRED_IN_CSV_ELEMENTS: [ENERGY_STORAGE], + }, } ENERGY_CARRIER_UNIT = "energy_carrier_unit" diff --git a/src/multi_vector_simulator/utils/constants_json_strings.py b/src/multi_vector_simulator/utils/constants_json_strings.py index 9b470b690..d55c9d413 100644 --- a/src/multi_vector_simulator/utils/constants_json_strings.py +++ b/src/multi_vector_simulator/utils/constants_json_strings.py @@ -110,6 +110,8 @@ SOC_INITIAL = "soc_initial" SOC_MAX = "soc_max" SOC_MIN = "soc_min" +THERM_LOSSES_REL = "fixed_thermal_losses_relative" +THERM_LOSSES_ABS = "fixed_thermal_losses_absolute" # Constraints CONSTRAINTS = "constraints" diff --git a/tests/benchmark_test_inputs/Economic_KPI_C2_E2/csv_elements/storage_1.csv b/tests/benchmark_test_inputs/Economic_KPI_C2_E2/csv_elements/storage_1.csv index 951a1cda3..accea4ffa 100644 --- a/tests/benchmark_test_inputs/Economic_KPI_C2_E2/csv_elements/storage_1.csv +++ b/tests/benchmark_test_inputs/Economic_KPI_C2_E2/csv_elements/storage_1.csv @@ -11,4 +11,6 @@ dispatch_price,currency/kWh,NA,0,0 soc_initial,None or factor,None,NA,NA soc_max,factor,1,NA,NA soc_min,factor,0.2,NA,NA +fixed_thermal_losses_relative,factor,0,, +fixed_thermal_losses_absolute,kWh,0,, unit,str,kWh,kW,kW diff --git a/tests/inputs/mvs_config.json b/tests/inputs/mvs_config.json index 197a2e0f1..6fd1caf42 100644 --- a/tests/inputs/mvs_config.json +++ b/tests/inputs/mvs_config.json @@ -637,6 +637,14 @@ "unit": "factor", "value": 0.2 }, + "fixed_thermal_losses_relative": { + "unit": "factor", + "value": 0.001 + }, + "fixed_thermal_losses_absolute": { + "unit": "factor", + "value": 0.0002 + }, "specific_costs": { "unit": "currency/kWh", "value": 4000 diff --git a/tests/test_D1_model_components.py b/tests/test_D1_model_components.py index 3fe627d1a..6c95d0c5d 100644 --- a/tests/test_D1_model_components.py +++ b/tests/test_D1_model_components.py @@ -25,6 +25,8 @@ INPUT_POWER, OUTPUT_POWER, C_RATE, + THERM_LOSSES_REL, + THERM_LOSSES_ABS, STORAGE_CAPACITY, TIMESERIES, TIMESERIES_NORMALIZED, @@ -621,6 +623,7 @@ def test_storage_optimize(self): dict_asset[STORAGE_CAPACITY][MAXIMUM_CAP] = {VALUE: None, UNIT: "kWh"} dict_asset[INPUT_POWER][MAXIMUM_CAP] = {VALUE: None, UNIT: "kWh"} dict_asset[OUTPUT_POWER][MAXIMUM_CAP] = {VALUE: None, UNIT: "kWh"} + dict_asset[STORAGE_CAPACITY][THERM_LOSSES_REL] = {VALUE: 0.001, UNIT: "no_unit"} D1.storage( model=self.model, dict_asset=dict_asset, @@ -675,6 +678,15 @@ def test_storage_optimize(self): == dict_asset[OUTPUT_POWER][C_RATE][VALUE] ) + assert ( + self.model.entities[-1].fixed_losses_relative.default + == dict_asset[STORAGE_CAPACITY][THERM_LOSSES_REL][VALUE] + ) + assert ( + self.model.entities[-1].fixed_losses_absolute.default + == dict_asset[STORAGE_CAPACITY][THERM_LOSSES_ABS][VALUE] + ) + def test_storage_fix(self): dict_asset = self.dict_values[ENERGY_STORAGE]["storage_fix"] D1.storage( @@ -718,6 +730,15 @@ def test_storage_fix(self): assert self.model.entities[-1].invest_relation_input_capacity is None assert self.model.entities[-1].invest_relation_output_capacity is None + assert ( + self.model.entities[-1].fixed_losses_relative.default + == dict_asset[STORAGE_CAPACITY][THERM_LOSSES_REL][VALUE] + ) + assert ( + self.model.entities[-1].fixed_losses_absolute.default + == dict_asset[STORAGE_CAPACITY][THERM_LOSSES_ABS][VALUE] + ) + ### other functionalities diff --git a/tests/test_data/inputs_for_D0/mvs_config.json b/tests/test_data/inputs_for_D0/mvs_config.json index 5106ca553..ce2844797 100644 --- a/tests/test_data/inputs_for_D0/mvs_config.json +++ b/tests/test_data/inputs_for_D0/mvs_config.json @@ -1912,6 +1912,14 @@ "unit": "factor", "value": 0.2 }, + "fixed_thermal_losses_relative": { + "unit": "factor", + "value": 0.001 + }, + "fixed_thermal_losses_absolute": { + "unit": "factor", + "value": 0.0002 + }, "unit": "kWh" }, "storage_filename": "storage_01.csv", diff --git a/tests/test_data/inputs_for_D1/mvs_config.json b/tests/test_data/inputs_for_D1/mvs_config.json index 5c91653c1..d21d09996 100644 --- a/tests/test_data/inputs_for_D1/mvs_config.json +++ b/tests/test_data/inputs_for_D1/mvs_config.json @@ -696,6 +696,14 @@ "unit": "factor", "value": 0.2 }, + "fixed_thermal_losses_relative": { + "unit": "factor", + "value": 0.001 + }, + "fixed_thermal_losses_absolute": { + "unit": "factor", + "value": 0.0002 + }, "simulation_annuity": { "value": 2.7, "unit": "currency/unit/simulation period" @@ -775,6 +783,14 @@ "soc_min": { "unit": "factor", "value": 0.2 + }, + "fixed_thermal_losses_relative": { + "unit": "factor", + "value": 0.001 + }, + "fixed_thermal_losses_absolute": { + "unit": "factor", + "value": 0.0002 } }, "input power": { diff --git a/tests/test_data/inputs_for_E1/csv_elements/storage_1.csv b/tests/test_data/inputs_for_E1/csv_elements/storage_1.csv index 2127dc040..86ec30027 100644 --- a/tests/test_data/inputs_for_E1/csv_elements/storage_1.csv +++ b/tests/test_data/inputs_for_E1/csv_elements/storage_1.csv @@ -11,4 +11,6 @@ dispatch_price,currency/kWh,NA,0,0 soc_initial,None or factor,None,NA,NA soc_max,factor,1,NA,NA soc_min,factor,0.2,NA,NA +fixed_thermal_losses_relative,factor,0,, +fixed_thermal_losses_absolute,kWh,0,, unit,str,kWh,kW,kW