Skip to content

Commit

Permalink
Merge branch 'dev' into revision/custom_properties
Browse files Browse the repository at this point in the history
# Conflicts:
#	docs/whatsnew/v0-6-0.rst
  • Loading branch information
p-snft committed Dec 3, 2024
2 parents ce84bb3 + 07b7d97 commit fc0c66c
Show file tree
Hide file tree
Showing 89 changed files with 703 additions and 538 deletions.
74 changes: 37 additions & 37 deletions docs/usage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -268,13 +268,13 @@ Sink (basic)
A sink is normally used to define the demand within an energy model but it can also be used to detect excesses.

The example shows the electricity demand of the electricity_bus defined above.
The *'my_demand_series'* should be sequence of normalised valueswhile the *'nominal_value'* is the maximum demand the normalised sequence is multiplied with.
The *'my_demand_series'* should be sequence of normalised valueswhile the *'nominal_capacity'* is the maximum demand the normalised sequence is multiplied with.
Giving *'my_demand_series'* as parameter *'fix'* means that the demand cannot be changed by the solver.

.. code-block:: python
solph.components.Sink(label='electricity_demand', inputs={electricity_bus: solph.flows.Flow(
fix=my_demand_series, nominal_value=nominal_demand)})
fix=my_demand_series, nominal_capacity=nominal_demand)})
In contrast to the demand sink the excess sink has normally less restrictions but is open to take the whole excess.

Expand All @@ -292,21 +292,21 @@ Source (basic)

A source can represent a pv-system, a wind power plant, an import of natural gas or a slack variable to avoid creating an in-feasible model.

While a wind power plant will have as feed-in depending on the weather conditions the natural_gas import might be restricted by maximum value (*nominal_value*) and an annual limit (*full_load_time_max*).
While a wind power plant will have as feed-in depending on the weather conditions the natural_gas import might be restricted by maximum value (*nominal_capacity*) and an annual limit (*full_load_time_max*).
As we do have to pay for imported gas we should set variable costs.
Comparable to the demand series an *fix* is used to define a fixed the normalised output of a wind power plant.
Alternatively, you might use *max* to allow for easy curtailment.
The *nominal_value* sets the installed capacity.
The *nominal_capacity* sets the installed capacity.

.. code-block:: python
solph.components.Source(
label='import_natural_gas',
outputs={my_energysystem.groups['natural_gas']: solph.flows.Flow(
nominal_value=1000, full_load_time_max=1000000, variable_costs=50)})
nominal_capacity=1000, full_load_time_max=1000000, variable_costs=50)})
solph.components.Source(label='wind', outputs={electricity_bus: solph.flows.Flow(
fix=wind_power_feedin_series, nominal_value=1000000)})
fix=wind_power_feedin_series, nominal_capacity=1000000)})
.. note:: The Source class is only a plug and provides no additional constraints or variables.

Expand All @@ -329,7 +329,7 @@ A condensing power plant can be defined by a converter with one input (fuel) and
solph.components.Converter(
label="pp_gas",
inputs={bgas: solph.flows.Flow()},
outputs={b_el: solph.flows.Flow(nominal_value=10e10)},
outputs={b_el: solph.flows.Flow(nominal_capacity=10e10)},
conversion_factors={electricity_bus: 0.58})
A CHP power plant would be defined in the same manner but with two outputs:
Expand All @@ -343,8 +343,8 @@ A CHP power plant would be defined in the same manner but with two outputs:
solph.components.Converter(
label='pp_chp',
inputs={b_gas: Flow()},
outputs={b_el: Flow(nominal_value=30),
b_th: Flow(nominal_value=40)},
outputs={b_el: Flow(nominal_capacity=30),
b_th: Flow(nominal_capacity=40)},
conversion_factors={b_el: 0.3, b_th: 0.4})
A CHP power plant with 70% coal and 30% natural gas can be defined with two inputs and two outputs:
Expand All @@ -359,8 +359,8 @@ A CHP power plant with 70% coal and 30% natural gas can be defined with two inpu
solph.components.Converter(
label='pp_chp',
inputs={b_gas: Flow(), b_coal: Flow()},
outputs={b_el: Flow(nominal_value=30),
b_th: Flow(nominal_value=40)},
outputs={b_el: Flow(nominal_capacity=30),
b_th: Flow(nominal_capacity=40)},
conversion_factors={b_el: 0.3, b_th: 0.4,
b_coal: 0.7, b_gas: 0.3})
Expand Down Expand Up @@ -430,7 +430,7 @@ applies when the second flow is zero (*`conversion_factor_full_condensation`*).
solph.components._extractionTurbineCHP(
label='variable_chp_gas',
inputs={b_gas: solph.flows.Flow(nominal_value=10e10)},
inputs={b_gas: solph.flows.Flow(nominal_capacity=10e10)},
outputs={b_el: solph.flows.Flow(), b_th: solph.flows.Flow()},
conversion_factors={b_el: 0.3, b_th: 0.5},
conversion_factor_full_condensation={b_el: 0.5})
Expand Down Expand Up @@ -561,16 +561,16 @@ GenericStorage (component)
A component to model a storage with its basic characteristics. The
GenericStorage is designed for one input and one output.
The ``nominal_storage_capacity`` of the storage signifies the storage capacity. You can either set it to the net capacity or to the gross capacity and limit it using the min/max attribute.
To limit the input and output flows, you can define the ``nominal_value`` in the Flow objects.
To limit the input and output flows, you can define the ``nominal_capacity`` in the Flow objects.
Furthermore, an efficiency for loading, unloading and a loss rate can be defined.

.. code-block:: python
solph.components.GenericStorage(
label='storage',
inputs={b_el: solph.flows.Flow(nominal_value=9, variable_costs=10)},
outputs={b_el: solph.flows.Flow(nominal_value=25, variable_costs=10)},
loss_rate=0.001, nominal_storage_capacity=50,
inputs={b_el: solph.flows.Flow(nominal_capacity=9, variable_costs=10)},
outputs={b_el: solph.flows.Flow(nominal_capacity=25, variable_costs=10)},
loss_rate=0.001, nominal_capacity=50,
inflow_conversion_factor=0.98, outflow_conversion_factor=0.8)
For initialising the state of charge before the first time step (time step zero) the parameter ``initial_storage_level`` (default value: ``None``) can be set by a numeric value as fraction of the storage capacity.
Expand All @@ -590,9 +590,9 @@ The following code block shows an example of the storage parametrization for the
solph.components.GenericStorage(
label='storage',
inputs={b_el: solph.flows.Flow(nominal_value=9, variable_costs=10)},
outputs={b_el: solph.flows.Flow(nominal_value=25, variable_costs=10)},
loss_rate=0.001, nominal_storage_capacity=50,
inputs={b_el: solph.flows.Flow(nominal_capacity=9, variable_costs=10)},
outputs={b_el: solph.flows.Flow(nominal_capacity=25, variable_costs=10)},
loss_rate=0.001, nominal_capacity=50,
initial_storage_level=0.5, balanced=True,
inflow_conversion_factor=0.98, outflow_conversion_factor=0.8)
Expand Down Expand Up @@ -627,7 +627,7 @@ Based on the `GenericStorage` object the `GenericInvestmentStorageBlock` adds tw
* Invest into the flow parameters e.g. a turbine or a pump
* Invest into capacity of the storage e.g. a basin or a battery cell

Investment in this context refers to the value of the variable for the 'nominal_value' (installed capacity) in the investment mode.
Investment in this context refers to the value of the variable for the 'nominal_capacity' (installed capacity) in the investment mode.

As an addition to other flow-investments, the storage class implements the possibility to couple or decouple the flows
with the capacity of the storage.
Expand All @@ -645,8 +645,8 @@ The following example pictures a Pumped Hydroelectric Energy Storage (PHES). Bot
solph.components.GenericStorage(
label='PHES',
inputs={b_el: solph.flows.Flow(nominal_value=solph.Investment(ep_costs=500))},
outputs={b_el: solph.flows.Flow(nominal_value=solph.Investment(ep_costs=500)},
inputs={b_el: solph.flows.Flow(nominal_capacity=solph.Investment(ep_costs=500))},
outputs={b_el: solph.flows.Flow(nominal_capacity=solph.Investment(ep_costs=500)},
loss_rate=0.001,
inflow_conversion_factor=0.98, outflow_conversion_factor=0.8),
investment = solph.Investment(ep_costs=40))
Expand Down Expand Up @@ -757,7 +757,7 @@ Then we can create our component with the buses attached to it.
... label='boiler',
... inputs={
... bfuel: solph.flows.Flow(
... nominal_value=P_out_max,
... nominal_capacity=P_out_max,
... max=l_max,
... min=l_min,
... nonconvex=solph.NonConvex()
Expand All @@ -777,7 +777,7 @@ Then we can create our component with the buses attached to it.
will serve as the reference for the `conversion_factors` and the
`normed_offsets`. The `NonConvex` flow also holds
- the `nominal_value` (or `Investment` in case of investment optimization),
- the `nominal_capacity` (can be `Investment` in case of investment optimization),
- the `min` and
- the `max` attributes.
Expand Down Expand Up @@ -899,7 +899,7 @@ This small example of PV, grid and SinkDSM shows how to use the component
grid = solph.components.Source(label='Grid',
outputs={
b_elec: solph.flows.Flow(
nominal_value=10000,
nominal_capacity=10000,
variable_costs=50)}
)
es.add(grid)
Expand All @@ -909,7 +909,7 @@ This small example of PV, grid and SinkDSM shows how to use the component
outputs={
b_elec: solph.flows.Flow(
fix=data['pv'],
nominal_value=3.5)}
nominal_capacity=3.5)}
)
es.add(s_wind)
Expand Down Expand Up @@ -958,7 +958,7 @@ The annual savings by building up new capacity must therefore compensate the ann
See the API of the :py:class:`~oemof.solph.options.Investment` class to see all possible parameters.
Basically, an instance of the Investment class can be added to a Flow, a
Storage or a DSM Sink. All parameters that usually refer to the *nominal_value/capacity* will
Storage or a DSM Sink. All parameters that usually refer to the *nominal_capacity* will
now refer to the investment variables and existing capacity. It is also
possible to set a maximum limit for the capacity that can be build.
If existing capacity is considered for a component with investment mode enabled,
Expand All @@ -983,7 +983,7 @@ turbines.
solph.components.Source(label='new_wind_pp', outputs={electricity: solph.flows.Flow(
fix=wind_power_time_series,
nominal_value=solph.Investment(ep_costs=epc, maximum=50000))})
nominal_capacity=solph.Investment(ep_costs=epc, maximum=50000))})
Let's slightly alter the case and consider for already existing wind power
capacity of 20,000 kW. We're still expecting the total wind power capacity, thus we
Expand All @@ -993,7 +993,7 @@ allow for 30,000 kW of new installations and formulate as follows.
solph.components.Source(label='new_wind_pp', outputs={electricity: solph.flows.Flow(
fix=wind_power_time_series,
nominal_value=solph.Investment(ep_costs=epc,
nominal_capacity=solph.Investment(ep_costs=epc,
maximum=30000,
existing=20000))})
Expand Down Expand Up @@ -1028,7 +1028,7 @@ example of a converter:
label='converter_nonconvex',
inputs={bus_0: solph.flows.Flow()},
outputs={bus_1: solph.flows.Flow(
nominal_value=solph.Investment(
nominal_capacity=solph.Investment(
ep_costs=4,
maximum=100,
minimum=20,
Expand Down Expand Up @@ -1185,7 +1185,7 @@ Then you add all the *components* and *buses* to your energy system, just as you
label="electricity_demand",
inputs={
electricity_bus: solph.flows.Flow(
nominal_value=1000, fix=[0.8] * len(my_index)
nominal_capacity=1000, fix=[0.8] * len(my_index)
)
},
)
Expand Down Expand Up @@ -1214,7 +1214,7 @@ Here is an example
inputs={hydrogen_bus: solph.flows.Flow()},
outputs={
electricity_bus: solph.flows.Flow(
nominal_value=solph.Investment(
nominal_capacity=solph.Investment(
maximum=1000,
ep_costs=1e6,
lifetime=30,
Expand Down Expand Up @@ -1248,7 +1248,7 @@ This would mean that for investments in the particular period, these values woul
inputs={hydrogen_bus: solph.flows.Flow()},
outputs={
electricity_bus: solph.flows.Flow(
nominal_value=solph.Investment(
nominal_capacity=solph.Investment(
maximum=1000,
ep_costs=[1e6, 1.1e6],
lifetime=30,
Expand All @@ -1275,7 +1275,7 @@ For components that is not invested into, you also can specify some additional a
inputs={coal_bus: solph.flows.Flow()},
outputs={
electricity_bus: solph.flows.Flow(
nominal_value=600,
nominal_capacity=600,
max=1,
min=0.4,
lifetime=50,
Expand Down Expand Up @@ -1379,9 +1379,9 @@ class, and only the optimal dispatch strategy of an existing asset with a given
inputs={b_gas: solph.flows.Flow()},
outputs={b_el: solph.flows.Flow(
nonconvex=solph.NonConvex(),
nominal_value=30,
nominal_capacity=30,
min=0.5),
b_th: solph.flows.Flow(nominal_value=40)},
b_th: solph.flows.Flow(nominal_capacity=40)},
conversion_factors={b_el: 0.3, b_th: 0.4})
The class :py:class:`~oemof.solph.options.NonConvex` for the electrical output of the created Converter (i.e., CHP)
Expand Down Expand Up @@ -1423,7 +1423,7 @@ This nonlinearity is linearised in the
min=0.2,
max=1,
nonconvex=solph.NonConvex(),
nominal_value=solph.Investment(
nominal_capacity=solph.Investment(
ep_costs=90,
maximum=150, # required for the linearization
),
Expand Down
2 changes: 1 addition & 1 deletion docs/whatsnew/v0-2-2.rst
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ New features
`invest_relation_output_capacity` replace the existing attributes
`nominal_input_capacity_ratio` and `nominal_input_capacity_ratio` for the
investment mode. In case of the dispatch mode one should use the
`nominal_value` of the Flow classes. The attributes
`nominal_capacity` of the Flow classes. The attributes
`nominal_input_capacity_ratio` and `nominal_input_capacity_ratio` will be
removed in v0.3.0. Please adapt your application to avoid problems in the
future (`Issue #480 <https://github.com/oemof/oemof-solph/pull/480>`_).
Expand Down
2 changes: 1 addition & 1 deletion docs/whatsnew/v0-5-1.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ API changes
(Note that we always had the argument "conversion_factor".)
* Unify API for constant sized objects and sizing of investment. For both, `Flow` and
`GenericStorage`, the argument `investment` is now deprecated. Instead,
`nominal_value` and `nominal_storage_capacity` accept an `Investment` object.
`nominal_capacity` and `nominal_storage_capacity` accept an `Investment` object.
* Change investment for experimental :class:`oemof.solph.components.experimental._sink_dsm.SinkDSM`: Remove
obsolete parameters `flex_share_down` and `flex_share_up`.
* Mainline link component :class:`oemof.solph.components._link.Link` from experimental.
Expand Down
2 changes: 1 addition & 1 deletion docs/whatsnew/v0-5-3.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ API changes
to the `NonConvex` flow, and `normed_offsets` with the normed offsets
relative to the `NonConvex` flow.
* The `NonConvex` attribute must be specified for one of `Flow` at the inlets
or outlets of the `OffsetConverter`. `min`, `max` and `nominal_value` have to
or outlets of the `OffsetConverter`. `min`, `max` and `nominal_capacity` have to
be specified for the same `Flow`.

New features
Expand Down
3 changes: 3 additions & 0 deletions docs/whatsnew/v0-6-0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ API changes
using an argument called "custom_attributes" was rather confusing.
Additionally, the class Bus already called the argument
"custom_properties".
* The parameters `GenericStorage.nominal_storage_capacity` and
`Flow.nominal_value` are now both called `nominal_capacity`.

New features
############
Expand All @@ -39,3 +41,4 @@ Contributors
############

* Patrik Schönfeldt
* Johannes Kochems
6 changes: 3 additions & 3 deletions examples/activity_costs/activity_costs.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,14 +69,14 @@ def main():

sink_heat = solph.components.Sink(
label="demand",
inputs={b_heat: solph.Flow(fix=demand_heat, nominal_value=1)},
inputs={b_heat: solph.Flow(fix=demand_heat, nominal_capacity=1)},
)

fireplace = solph.components.Source(
label="fireplace",
outputs={
b_heat: solph.Flow(
nominal_value=3,
nominal_capacity=3,
variable_costs=0,
nonconvex=solph.NonConvex(activity_costs=activity_costs),
)
Expand All @@ -85,7 +85,7 @@ def main():

boiler = solph.components.Source(
label="boiler",
outputs={b_heat: solph.Flow(nominal_value=10, variable_costs=1)},
outputs={b_heat: solph.Flow(nominal_capacity=10, variable_costs=1)},
)

es.add(sink_heat, fireplace, boiler)
Expand Down
20 changes: 11 additions & 9 deletions examples/basic_example/basic_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ def main(dump_and_restore=False):
label="wind",
outputs={
bus_electricity: flows.Flow(
fix=data["wind"], nominal_value=1000000
fix=data["wind"], nominal_capacity=1000000
)
},
)
Expand All @@ -185,20 +185,20 @@ def main(dump_and_restore=False):
label="pv",
outputs={
bus_electricity: flows.Flow(
fix=data["pv"], nominal_value=582000
fix=data["pv"], nominal_capacity=582000
)
},
)
)

# create simple sink object representing the electrical demand
# nominal_value is set to 1 because demand_el is not a normalised series
# nominal_capacity is set to 1 because demand_el is not a normalised series
energysystem.add(
components.Sink(
label="demand",
inputs={
bus_electricity: flows.Flow(
fix=data["demand_el"], nominal_value=1
fix=data["demand_el"], nominal_capacity=1
)
},
)
Expand All @@ -211,7 +211,7 @@ def main(dump_and_restore=False):
inputs={bus_gas: flows.Flow()},
outputs={
bus_electricity: flows.Flow(
nominal_value=10e10, variable_costs=50
nominal_capacity=10e10, variable_costs=50
)
},
conversion_factors={bus_electricity: 0.58},
Expand All @@ -220,15 +220,17 @@ def main(dump_and_restore=False):

# create storage object representing a battery
nominal_capacity = 10077997
nominal_value = nominal_capacity / 6
nominal_capacity = nominal_capacity / 6

battery_storage = components.GenericStorage(
nominal_storage_capacity=nominal_capacity,
nominal_capacity=nominal_capacity,
label=STORAGE_LABEL,
inputs={bus_electricity: flows.Flow(nominal_value=nominal_value)},
inputs={
bus_electricity: flows.Flow(nominal_capacity=nominal_capacity)
},
outputs={
bus_electricity: flows.Flow(
nominal_value=nominal_value, variable_costs=0.001
nominal_capacity=nominal_capacity, variable_costs=0.001
)
},
loss_rate=0.00,
Expand Down
Loading

0 comments on commit fc0c66c

Please sign in to comment.