Stratified thermal storage¶
Scope¶
This module was developed to implement a simplified model of a large-scale sensible heat storage with ideal stratification for energy system optimization with oemof.solph.
Concept¶
A simplified 2-zone-model of a stratified thermal energy storage.
- We assume a cylindrical storage of (inner) diameter d and height h, with two temperature regions that are perfectly separated.
- The temperatures are assumed to be constant and correspond to the feed-in/return temperature of the heating system.
- Heat conductivity of the storage has to be passed as well as a timeseries of outside temperatures for the calculation of heat losses.
- There is no distinction between outside temperature and ground temperature.
- A single value for the thermal transmittance is assumed, neglecting the fact that the storage’s lateral surface is bent and thus has a higher thermal transmittance than a flat surface. The relative error introduced here gets smaller with larger storage diameters.
- Material properties are constant.
The equation describing the storage content at timestep t is the following:
which is of the form
with
The three terms represent:
- , constant heat losses through the top and bottom surfaces,
- , losses through the total lateral surface assuming the storage to be empty (storage is at , and is the driving temperature difference), depending on the height of the storage,
- , additional losses through lateral surface that belong to the hot part of the water body, depending on the state of charge.
In the case of investment, the diameter is given and the height can be adapted to adapt the nominal capacity of the storage. With this assumption, all relations stay linear.
Because of the space that diffuser plates for charging/discharging take up, it is assumed that the storage can neither be fully charged nor discharged, which is parametrised as a minimal/maximal storage level (indicated by the dotted lines in Fig. 1).
These parameters are part of the stratified thermal storage module:
symbol attribute type explanation height
Height [m] (if not investment) diameter
Diameter [m] surface
Storage surface [m2] volume
Storage volume [m3] density
Density of storage medium [kg/m3] heat_capacity
Heat capacity of storage medium [J/(kg*K)] temp_h
Hot temperature level [deg C] temp_c
Cold temperature level [deg C] temp_env
Environment temperature timeseries [deg C] attribute of oemof-solph component Stored thermal energy at time t [MWh] attribute of oemof-solph component Energy flowing in at time t nominal_storage_capacity
Maximum amount of stored thermal energy [MWh] u_value
Thermal transmittance [W/(m2*K)] s_iso
Thickness of isolation layer [mm] lamb_iso
Heat conductivity of isolation material [W/(m*K)] alpha_inside
Heat transfer coefficient inside [W/(m2*K)] alpha_outside
Heat transfer coefficient outside [W/(m2*K)] loss_rate
Relative loss of storage content within one timestep [-] fixed_losses_relative
Fixed losses as share of nominal storage capacity [-] fixed_losses_absolute
Fixed absolute losses independent of storage content or nominal storage capacity [MWh] inflow_conversion_factor
Charging efficiency [-] outflow_conversion_factor
Discharging efficiency [-]
Usage¶
StratifiedThermalStorage facade¶
Using the StratifiedThermalStorage facade, you can instantiate a storage like this:
from oemof.solph import Bus
from oemof.thermal.facades import StratifiedThermalStorage
bus_heat = Bus('heat')
thermal_storage = StratifiedThermalStorage(
label='thermal_storage',
bus=bus_heat,
diameter=2,
height=5,
temp_h=95,
temp_c=60,
temp_env=10,
u_value=u_value,
min_storage_level=0.05,
max_storage_level=0.95,
capacity=1,
efficiency=0.9,
marginal_cost=0.0001
)
The non-usable storage volume is represented by the parameters
min_storage_level
and max_storage_level
.
To learn about all parameters that can be passed to the facades, have a look at the API documentation of the StratifiedThermalStorage
class of the facade module.
For the storage investment mode, you still need to provide diameter
, but
leave height
and capacity
open and set expandable=True
.
There are two options to choose from:
- Invest into
nominal_storage_capacity
andcapacity
(charging/discharging power) with a fixed ratio. Passinvest_relation_input_capacity
and eitherstorage_capacity_cost
orcapacity_cost
. - Invest into
nominal_storage_capacity
andcapacity
independently with no fixed ratio. Passstorage_capacity_cost
andcapacity_cost
.
In many practical cases, thermal storages are dimensioned using a rule of thumb: The storage should be able to provide its peak thermal power for 6-7 hours. To apply this in a model, use option 1.
thermal_storage = StratifiedThermalStorage(
label='thermal_storage',
bus=bus_heat,
diameter=2,
temp_h=95,
temp_c=60,
temp_env=10,
u_value=u_value,
expandable=True,
capacity_cost=0,
storage_capacity_cost=400,
minimum_storage_capacity=1,
invest_relation_input_capacity=1 / 6,
min_storage_level=0.05,
max_storage_level=0.95,
efficiency=0.9,
marginal_cost=0.0001
)
If you do not want to use a rule of thumb and rather let the model decide, go with option 2. Do so
by leaving out invest_relation_input_capacity
and setting capacity_cost
to
a finite value. Also have a look at the examples, where both options are shown.
A 3rd and 4th option, investing into nominal_storage_capacity
but leaving
capacity
fixed or vice versa, can not be modelled with this facade (at the moment).
It seems to be a case that is not as relevant for thermal storages as the others. If you want to
model it, you can do so by performing the necessary pre-calculations and using oemof.solph’s
GenericStorage
directly.
Warning
For this example to work as intended, please use oemof-solph v0.4.0 or higher
to ensure that the GenericStorage has the attributes fixed_losses_absolute
and
fixed_losses_relative
.
The following figure shows a comparison of results of a common storage implementation using only a loss rate vs. the stratified thermal storage implementation (source code).
Implicit calculations¶
In the background, the StratifiedThermalStorage class uses the following functions. They can be used independent of the facade class as well.
The thermal transmittance is pre-calculated using calculate_u_value.
The dimensions of the storage are calculated with calculate_storage_dimensions
volume, surface = calculate_storage_dimensions(height, diameter)
The nominal storage capacity is pre-calculated using calculate_capacities.
nominal_storage_capacity = calculate_capacities(
volume, temp_h, temp_c, heat_capacity, density
)
Loss terms are precalculated by the following function.
loss_rate, fixed_losses_relative, fixed_losses_absolute = calculate_losses(
u_value, diameter, temp_h, temp_c, temp_env,
time_increment, heat_capacity, density)
To calculate the thermal transmittance of the storage hull from material properties, you can use the following function.
u_value = calculate_storage_u_value(s_iso, lamb_iso, alpha_inside, alpha_outside)