Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/stratified therm storage #711

Closed
wants to merge 12 commits into from
Closed
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
2 changes: 2 additions & 0 deletions docs/MVS_parameters_list.csv
Original file line number Diff line number Diff line change
Expand Up @@ -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
55 changes: 55 additions & 0 deletions docs/Model_Assumptions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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`.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
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`.
In order to model a stratified thermal energy storage the two parameters `fixed_losses_relative` and `fixed_losses_absolute` are passed to `storage_xx.csv`.

You do not have to have linebreaks for each sentence, but you can.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add something that explicitly states that the parameters are not required for storage_*.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 <https://github.com/oemof/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 <https://github.com/oemof/oemof-thermal/tree/dev/examples/stratified_thermal_storage>`__ and the `documentation <https://oemof-thermal.readthedocs.io/en/latest/stratified_thermal_storage.html>`__ 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.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
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.
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`.

Can installedCap be NaN? It should always be a number, as far as I know. Please test this.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can installedCap be NaN? It should always be a number, as far as I know. Please test this.

Actually I have. I was also wondering how this works, but it does. The background is, that I implemented precalculations in pvcompare, which calculate the oemof.thermal parameter nominal_storage_capacity (= mvs parameter installedCap = oemof.solph parameter Investment(existing)). If you want to do an investment optimization you leave the height open which leads to nominal_storage_capacity= NaN in the precalculations. If you pass the height as a limiting parameter (no investment optimization) nominal_storage_capacity is a fix number in the precalculations. In the precalculations the mvs parameter installedCap is overwritten with the corresponding value.

And this is why I documented it in this way. Does it make sense?


Energy providers (DSOs)
-----------------------

Expand Down
6 changes: 6 additions & 0 deletions src/multi_vector_simulator/D1_model_components.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@
SOC_INITIAL,
SOC_MAX,
SOC_MIN,
THERM_LOSSES_REL,
THERM_LOSSES_ABS,
STORAGE_CAPACITY,
TIMESERIES,
TIMESERIES_NORMALIZED,
Expand Down Expand Up @@ -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][
Expand Down Expand Up @@ -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][
Expand Down
12 changes: 12 additions & 0 deletions src/multi_vector_simulator/utils/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
2 changes: 2 additions & 0 deletions src/multi_vector_simulator/utils/constants_json_strings.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,,
Comment on lines +14 to +15
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I hope that we can keep fixed_thermal_losses_relative and fixed_thermal_losses_absolute optional parameters. If so, please remove the parameters from all other input files, and only leave one benchmark tests for your own feature.

unit,str,kWh,kW,kW
8 changes: 8 additions & 0 deletions tests/inputs/mvs_config.json
Original file line number Diff line number Diff line change
Expand Up @@ -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
},
mahendrark marked this conversation as resolved.
Show resolved Hide resolved
"specific_costs": {
"unit": "currency/kWh",
"value": 4000
Expand Down
21 changes: 21 additions & 0 deletions tests/test_D1_model_components.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
INPUT_POWER,
OUTPUT_POWER,
C_RATE,
THERM_LOSSES_REL,
THERM_LOSSES_ABS,
STORAGE_CAPACITY,
TIMESERIES,
TIMESERIES_NORMALIZED,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -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

Expand Down
8 changes: 8 additions & 0 deletions tests/test_data/inputs_for_D0/mvs_config.json
Original file line number Diff line number Diff line change
Expand Up @@ -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
},
mahendrark marked this conversation as resolved.
Show resolved Hide resolved
"unit": "kWh"
},
"storage_filename": "storage_01.csv",
Expand Down
16 changes: 16 additions & 0 deletions tests/test_data/inputs_for_D1/mvs_config.json
Original file line number Diff line number Diff line change
Expand Up @@ -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
},
mahendrark marked this conversation as resolved.
Show resolved Hide resolved
"simulation_annuity": {
"value": 2.7,
"unit": "currency/unit/simulation period"
Expand Down Expand Up @@ -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
mahendrark marked this conversation as resolved.
Show resolved Hide resolved
}
},
"input power": {
Expand Down
2 changes: 2 additions & 0 deletions tests/test_data/inputs_for_E1/csv_elements/storage_1.csv
Original file line number Diff line number Diff line change
Expand Up @@ -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,,
mahendrark marked this conversation as resolved.
Show resolved Hide resolved
unit,str,kWh,kW,kW