tespy.components.reactors package

tespy.components.reactors.fuel_cell module

Module of class FuelCell.

This file is part of project TESPy (github.com/oemof/tespy). It’s copyrighted by the contributors recorded in the version control history of the file, available from its original location tespy/components/reactors/fuel_cell.py

SPDX-License-Identifier: MIT

class tespy.components.reactors.fuel_cell.FuelCell(label, **kwargs)[source]

Bases: Component

The fuel cell produces power by oxidation of hydrogen.

Mandatory Equations

Optional Equations

Inlets/Outlets

  • in1 (cooling inlet), in2 (oxygen inlet), in3 (hydrogen inlet)

  • out1 (cooling outlet), out2 (water outlet)

Image

alternative text
Parameters:
  • label (str) – The label of the component.

  • design (list) – List containing design parameters (stated as String).

  • offdesign (list) – List containing offdesign parameters (stated as String).

  • design_path (str) – Path to the components design case.

  • local_offdesign (boolean) – Treat this component in offdesign mode in a design calculation.

  • local_design (boolean) – Treat this component in design mode in an offdesign calculation.

  • char_warnings (boolean) – Ignore warnings on default characteristics usage for this component.

  • printout (boolean) – Include this component in the network’s results printout.

  • P (float, dict, "var") – Power input, \(P/\text{W}\).

  • Q (float, dict) – Heat output of cooling, \(Q/\text{W}\)

  • e (float, dict, "var") – Electrolysis specific energy consumption, \(e/(\text{J}/\text{m}^3)\).

  • eta (float, dict) – Electrolysis efficiency, \(\eta/1\).

  • pr (float, dict) – Cooling loop pressure ratio, \(pr/1\).

  • dp (float, dict) – Inlet to outlet pressure difference of cooling loop, \(dp/\text{p}_\text{unit}\) Is specified in the Network’s pressure unit

  • zeta (float, dict, "var") – Geometry independent friction coefficient for cooling loop pressure drop, \(\frac{\zeta}{D^4}/\frac{1}{\text{m}^4}\).

Note

Other than usual components, the fuel cell has the fluid composition built into its equations for the feed hydrogen and oxygen inlets as well as the water outlet. Thus, the user must not specify the fluid composition at these connections!

Example

The example shows a simple adaptation of the fuel cell. It works with water as cooling fluid.

>>> from tespy.components import (Sink, Source, FuelCell)
>>> from tespy.connections import Connection
>>> from tespy.networks import Network
>>> from tespy.tools import ComponentCharacteristics as dc_cc
>>> nw = Network(iterinfo=False)
>>> nw.units.set_defaults(**{
...     "pressure": "bar", "temperature": "degC", "volumetric_flow": "l/s"
... })
>>> fc = FuelCell('fuel cell')
>>> oxygen_source = Source('oxygen_source')
>>> hydrogen_source = Source('hydrogen_source')
>>> cw_source = Source('cw_source')
>>> cw_sink = Sink('cw_sink')
>>> water_sink = Sink('water_sink')
>>> cw_in = Connection(cw_source, 'out1', fc, 'in1')
>>> cw_out = Connection(fc, 'out1', cw_sink, 'in1')
>>> oxygen_in = Connection(oxygen_source, 'out1', fc, 'in2')
>>> hydrogen_in = Connection(hydrogen_source, 'out1', fc, 'in3')
>>> water_out = Connection(fc, 'out2', water_sink, 'in1')
>>> nw.add_conns(cw_in, cw_out, oxygen_in, hydrogen_in, water_out)

The fuel cell produces 200kW of electrical power with an efficiency of 0.45. The thermodynamic parameters of the input oxygen and hydrogen are given, the mass flow rates are calculated out of the given power output. The temperature of the water at the outlet should be 50 °C. The cooling fluid is pure water and is heated up from 25 °C to 40 °C.

>>> fc.set_attr(eta=0.45, P=-200e03, pr=0.9)
>>> cw_in.set_attr(T=25, p=1, fluid={'H2O': 1})
>>> cw_out.set_attr(T=40)
>>> oxygen_in.set_attr(T=25, p=1)
>>> hydrogen_in.set_attr(T=25)
>>> water_out.set_attr(T=50)
>>> nw.solve('design')
>>> round(cw_in.m.val, 1)
10.2
>>> Q = fc.Q.val / 1e3
>>> round(Q, 0)
-642.0
>>> round(fc.eta.val, 2)
0.45
calc_P()[source]

Calculate fuel cell power output.

Returns:

P (float) – Value of power output.

\[\begin{split}\begin{split} P = & +\dot{m}_{in,2} \cdot \left( h_{in,2} - h_{in,2,ref} \right)\\ & + \dot{m}_{in,3} \cdot \left( h_{in,3} - h_{in,3,ref} - e_0 \right)\\ & - \dot{m}_{in,1} \cdot \left( h_{out,1} - h_{in,1} \right)\\ & - \dot{m}_{out,2} \cdot \left( h_{out,2} - h_{out,2,ref} \right)\\ \end{split}\end{split}\]

Note

The temperature for the reference state is set to 25 °C, thus the produced water must be liquid as proposed in the calculation of the minimum specific energy for oxidation: tespy.components.reactors.fuel_cell.FuelCell.calc_e0(). The part of the equation regarding the cooling water is implemented with negative sign as the energy for cooling is extracted from the reactor. - Reference temperature: 298.15 K. - Reference pressure: 1 bar.

calc_e0()[source]

Calculate the specific energy output of the fuel cell.

Returns:

float – Specific energy.

\[\begin{split}e0 = \frac{\sum_i {\Delta H_f^0}_i - \sum_j {\Delta H_f^0}_j } {M_{H_2}}\\ \forall i \in \text{reation products},\\ \forall j \in \text{reation educts},\\ \Delta H_f^0: \text{molar formation enthalpy}\end{split}\]

calc_parameters()[source]

Postprocessing parameter calculation.

cooling_fluid_structure_matrix(k)[source]
cooling_mass_flow_structure_matrix(k)[source]
energy_balance_dependents()[source]
energy_balance_deriv(increment_filter, k, dependents=None)[source]

Partial derivatives for reactor energy balance.

Parameters:
  • increment_filter (ndarray) – Matrix for filtering non-changing variables.

  • k (int) – Position of derivatives in Jacobian matrix (k-th equation).

energy_balance_func()[source]

Calculate the residual in energy balance.

Returns:

residual (float) – Residual value of energy balance equation.

\[\begin{split}\begin{split} 0=&P + \dot{m}_\mathrm{out,2}\cdot\left(h_\mathrm{out,2}- h_\mathrm{out,2,ref}\right)\\ &+\dot{m}_\mathrm{in,1}\cdot\left( h_\mathrm{out,1} - h_\mathrm{in,1} \right)\\ & -\dot{m}_\mathrm{in,2} \cdot \left( h_\mathrm{in,2} - h_\mathrm{in,2,ref} \right)\\ & -\dot{m}_\mathrm{in,3} \cdot \left( h_\mathrm{in,3} - h_\mathrm{in,3,ref} - e_0\right)\\ \end{split}\end{split}\]
  • Reference temperature: 298.15 K.

  • Reference pressure: 1 bar.

eta_dependents()[source]
eta_func()[source]

Equation for efficiency.

Returns:

residual (float) – Residual value of equation.

\[0 = P - \eta \cdot \dot{m}_{H_2,in} \cdot e_0\]

static get_bypass_constraints()[source]
get_mandatory_constraints()[source]
get_parameters()[source]
get_variables()[source]
heat_dependents()[source]
heat_func()[source]

Equation for heat output.

Returns:

residual (float) – Residual value of equation.

\[0 = \dot{Q}-\dot{m}_{in,1}\cdot \left(h_{out,1}-h_{in,1}\right)\]

initialise_source(c, key)[source]

Return a starting value for pressure and enthalpy at inlet.

Parameters:
  • c (tespy.connections.connection.Connection) – Connection to perform initialisation on.

  • key (str) – Fluid property to retrieve.

Returns:

val (float) – Starting value for pressure/enthalpy in SI units.

initialise_target(c, key)[source]

Return a starting value for pressure and enthalpy at outlet.

Parameters:
  • c (tespy.connections.connection.Connection) – Connection to perform initialisation on.

  • key (str) – Fluid property to retrieve.

Returns:

val (float) – Starting value for pressure/enthalpy in SI units.

static inlets()[source]
static outlets()[source]
propagate_wrapper_to_target(branch)[source]
reactor_mass_flow_dependents()[source]
reactor_mass_flow_deriv(increment_filter, k, dependents=None)[source]

Calculate the partial derivatives for all mass flow balance equations.

Returns:

deriv (ndarray) – Matrix with partial derivatives for the mass flow equations.

reactor_mass_flow_func()[source]

Equations for mass conservation.

Returns:

residual (list) – Residual values of equation.

\[\begin{split}O_2 = \frac{M_{O_2}}{M_{O_2} + 2 \cdot M_{H_2}}\\ 0=O_2\cdot\dot{m}_\mathrm{H_{2}O,out,1}- \dot{m}_\mathrm{O_2,in,2}\\ 0 = \left(1 - O_2\right) \cdot \dot{m}_\mathrm{H_{2}O,out,1} - \dot{m}_\mathrm{H_2,in,1}\end{split}\]

reactor_pressure_structure_matrix(k)[source]

Structure matrix representing the equations for reactor pressure balance.

\[\begin{split}0 = p_\mathrm{in,2} - p_\mathrm{out,2}\\ 0 = p_\mathrm{in,3} - p_\mathrm{out,2}\end{split}\]
specific_energy_dependents()[source]
specific_energy_func()[source]

Equation for specific energy output.

Returns:

residual (float) – Residual value of equation.

\[0 = P - \dot{m}_{H_2,in} \cdot e\]

start_fluid_wrapper_branch()[source]

tespy.components.reactors.water_electrolyzer module

Module of class WaterElectrolyzer.

This file is part of project TESPy (github.com/oemof/tespy). It’s copyrighted by the contributors recorded in the version control history of the file, available from its original location tespy/components/reactors/water_electrolyzer.py

SPDX-License-Identifier: MIT

class tespy.components.reactors.water_electrolyzer.WaterElectrolyzer(label, **kwargs)[source]

Bases: Component

The water electrolyzer produces hydrogen and oxygen from water and power.

Mandatory Equations

Optional Equations

Inlets/Outlets

  • in1 (cooling inlet), in2 (feed water inlet)

  • out1 (cooling outlet), out2 (oxygen outlet), out3 (hydrogen outlet)

Image

flowsheet of the water electrolyzer flowsheet of the water electrolyzer
Parameters:
  • label (str) – The label of the component.

  • design (list) – List containing design parameters (stated as String).

  • offdesign (list) – List containing offdesign parameters (stated as String).

  • design_path (str) – Path to the components design case.

  • local_offdesign (boolean) – Treat this component in offdesign mode in a design calculation.

  • local_design (boolean) – Treat this component in design mode in an offdesign calculation.

  • char_warnings (boolean) – Ignore warnings on default characteristics usage for this component.

  • printout (boolean) – Include this component in the network’s results printout.

  • P (float, dict, "var") – Power input, \(P/\text{W}\).

  • Q (float, dict) – Heat output of cooling, \(Q/\text{W}\)

  • e (float, dict, "var") – Electrolysis specific energy consumption, \(e/(\text{J}/\text{m}^3)\).

  • eta (float, dict) – Electrolysis efficiency (referring to H2 higher heating value), \(\eta/1\).

  • eta_char (tespy.tools.characteristics.CharLine, dict) – Electrolysis efficiency characteristic line.

  • pr (float, dict) – Cooling loop pressure ratio, \(pr/1\).

  • dp (float, dict) – Inlet to outlet pressure difference of cooling loop, \(dp/\text{p}_\text{unit}\) Is specified in the Network’s pressure unit

  • zeta (float, dict) – Geometry independent friction coefficient for cooling loop pressure drop, \(\frac{\zeta}{D^4}/\frac{1}{\text{m}^4}\).

Note

Other than usual components, the water electrolyzer has the fluid composition built into its equations for the feed water inlet and the hydrogen and oxygen outlet. Thus, the user must not specify the fluid composition at these connections!

Example

Create a water electrolyzer and compress the hydrogen, e.g. for a hydrogen storage.

>>> from tespy.components import (Sink, Source, Compressor,
... WaterElectrolyzer)
>>> from tespy.connections import Connection
>>> from tespy.networks import Network
>>> import os
>>> nw = Network(iterinfo=False)
>>> nw.units.set_defaults(**{
...     "pressure": "bar", "temperature": "degC", "volumetric_flow": "l/s"
... })
>>> fw = Source('feed water')
>>> oxy = Sink('oxygen sink')
>>> hydro = Sink('hydrogen sink')
>>> cw_cold = Source('cooling water source')
>>> cw_hot = Sink('cooling water sink')
>>> comp = Compressor('compressor', eta_s=0.9)
>>> el = WaterElectrolyzer('electrolyzer')

The electrolyzer should produce 100 l/s of hydrogen at an operating pressure of 10 bars and an outlet temperature of 50 °C. The fluid composition needs to be specified for the cooling liquid only. The storage pressure is 25 bars. The electrolysis efficiency is at 80 % and the compressor isentropic efficiency at 85 %. After designing the plant the offdesign electrolysis efficiency is predicted by the characteristic line. The default characteristic line can be found here: tespy.data.

>>> fw_el = Connection(fw, 'out1', el, 'in2')
>>> el_o = Connection(el, 'out2', oxy, 'in1')
>>> el_cmp = Connection(el, 'out3', comp, 'in1')
>>> cmp_h = Connection(comp, 'out1', hydro, 'in1')
>>> cw_el = Connection(cw_cold, 'out1', el, 'in1')
>>> el_cw = Connection(el, 'out1', cw_hot, 'in1')
>>> nw.add_conns(fw_el, el_o, el_cmp, cmp_h, cw_el, el_cw)
>>> fw_el.set_attr(p=10, T=15)
>>> cw_el.set_attr(p=5, T=15, fluid={'H2O': 1})
>>> el_cw.set_attr(T=45)
>>> cmp_h.set_attr(p=25)
>>> el_cmp.set_attr(v=100, T=50)
>>> el.set_attr(eta=0.8, pr=0.99, design=['eta', 'pr'],
... offdesign=['eta_char', 'zeta'])
>>> comp.set_attr(eta_s=0.85)
>>> nw.solve('design')
>>> nw.save('tmp.json')
>>> round(el.e0 / el.P.val * el_cmp.m.val_SI, 1)
0.8
>>> P_design = el.P.val
>>> round(P_design / 1e6, 1)
13.2
>>> nw.solve('offdesign', design_path='tmp.json')
>>> round(el.eta.val, 1)
0.8
>>> el_cmp.set_attr(v=None)
>>> el.set_attr(P=P_design * 0.2)
>>> nw.solve('offdesign', design_path='tmp.json')
>>> round(el.eta.val, 2)
0.84
>>> os.remove('tmp.json')
bus_deriv(bus)[source]

Calculate partial derivatives of the bus function.

Parameters:

bus (tespy.connections.bus.Bus) – TESPy bus object.

Returns:

deriv (ndarray) – Matrix of partial derivatives.

bus_func(bus)[source]

Calculate the value of the bus function.

Parameters:

bus (tespy.connections.bus.Bus) – TESPy bus object.

Returns:

val (float) – Value of energy transfer \(\dot{E}\). This value is passed to tespy.components.component.Component.calc_bus_value() for value manipulation according to the specified characteristic line of the bus.

\[\begin{split}\dot{E} = \begin{cases} P & \text{key = 'P'}\\ - \dot{m}_{in,1} \cdot \left(h_{out,1} - h_{in,1} \right) & \text{key = 'Q'}\\ \end{cases}\end{split}\]

calc_P()[source]

Calculate water electrolyzer power input.

Returns:

P (float) – Value of power input.

\[\begin{split}\begin{split} P = & -\dot{m}_{in,2} \cdot \left( h_{in,2} - h_{in,2,ref} \right)\\ & + \dot{m}_{in,1} \cdot \left( h_{out,1} - h_{in,1} \right)\\ & + \dot{m}_{out,2} \cdot \left( h_{out,2} - h_{out,2,ref} \right)\\ & - \dot{m}_{out,3} \cdot \left( h_{out,3} - h_{out,3,ref} + e_0\right)\\ \end{split}\end{split}\]

Note

The temperature for the reference state is set to 25 °C, thus the feed water must be liquid as proposed in the calculation of the minimum specific energy consumption for electrolysis: tespy.components.reactors.water_electrolyzer.WaterElectrolyzer.calc_e0(). The part of the equation regarding the cooling water is implemented with negative sign as the energy for cooling is extracted from the reactor.

  • Reference temperature: 298.15 K.

  • Reference pressure: 1 bar.

calc_e0()[source]

Calculate the minimum specific energy required for electrolysis.

Returns:

float – Minimum specific energy.

\[\begin{split}e0 = -\frac{\sum_i {\Delta H_f^0}_i - \sum_j {\Delta H_f^0}_j } {M_{H_2}}\\ \forall i \in \text{reation products},\\ \forall j \in \text{reation educts},\\ \Delta H_f^0: \text{molar formation enthalpy}\end{split}\]

calc_parameters()[source]

Postprocessing parameter calculation.

cooling_fluid_structure_matrix(k)[source]
cooling_mass_flow_structure_matrix(k)[source]
energy_balance_dependents()[source]
energy_balance_deriv(increment_filter, k, dependents=None)[source]

Partial derivatives for reactor energy balance.

Parameters:
  • increment_filter (ndarray) – Matrix for filtering non-changing variables.

  • k (int) – Position of derivatives in Jacobian matrix (k-th equation).

energy_balance_func()[source]

Calculate the residual in energy balance.

Returns:

residual (float) – Residual value of energy balance equation.

\[\begin{split}\begin{split} 0=&P + \dot{m}_\mathrm{in,2}\cdot\left(h_\mathrm{in,2}- h_\mathrm{in,2,ref}\right)\\ &-\dot{m}_\mathrm{in,1}\cdot\left( h_\mathrm{out,1} - h_\mathrm{in,1} \right)\\ & -\dot{m}_\mathrm{out,2} \cdot \left( h_\mathrm{out,2} - h_\mathrm{out,2,ref} \right)\\ & +\dot{m}_\mathrm{out,3} \cdot \left( h_\mathrm{out,3} - h_\mathrm{out,3,ref} + e_0\right)\\ \end{split}\end{split}\]
  • Reference temperature: 298.15 K.

  • Reference pressure: 1 bar.

eta_char_dependents()[source]
eta_char_deriv(increment_filter, k, dependents=None)[source]

Partial derivatives electrolysis efficiency characteristic.

Parameters:
  • increment_filter (ndarray) – Matrix for filtering non-changing variables.

  • k (int) – Position of derivatives in Jacobian matrix (k-th equation).

eta_char_func()[source]

Equation for given efficiency characteristic of a water electrolyzer.

Returns:

residual (float) – Residual value of equation.

\[0 = P - \dot{m}_{H_2,out,3} \cdot \frac{e_0}{\eta_{design}\cdot f\left(expr \right)}\]

eta_dependents()[source]
eta_func()[source]

Equation for electrolysis efficiency.

Returns:

residual (float) – Residual value of equation.

\[0 = P \cdot \eta - \dot{m}_{H_2,out,3} \cdot e_0\]

exergy_balance(T0)[source]

Exergy balance calculation method.

Parameters:

T0 (float) – Ambient temperature T0 / K.

gas_temperature_dependents()[source]
gas_temperature_func()[source]

Equation for temperature equality of product gases.

Returns:

residual (float) – Residual value of equation.

\[0 = T_\mathrm{out,2} - T_\mathrm{out,3}\]

static get_bypass_constraints()[source]
get_mandatory_constraints()[source]
get_parameters()[source]
get_variables()[source]
heat_dependents()[source]
heat_func()[source]

Equation for heat output.

Returns:

residual (float) – Residual value of equation.

\[0 = \dot{Q}-\dot{m}_{in,1}\cdot \left(h_{in,1}-h_{out,1}\right)\]

initialise_source(c, key)[source]

Return a starting value for pressure and enthalpy at outlet.

Parameters:
  • c (tespy.connections.connection.Connection) – Connection to perform initialisation on.

  • key (str) – Fluid property to retrieve.

Returns:

val (float) – Starting value for pressure/enthalpy in SI units.

initialise_target(c, key)[source]

Return a starting value for pressure and enthalpy at inlet.

Parameters:
  • c (tespy.connections.connection.Connection) – Connection to perform initialisation on.

  • key (str) – Fluid property to retrieve.

Returns:

val (float) – Starting value for pressure/enthalpy in SI units.

static inlets()[source]
static outlets()[source]
propagate_wrapper_to_target(branch)[source]
reactor_mass_flow_dependents()[source]
reactor_mass_flow_deriv(increment_filter, k, dependents=None)[source]

Calculate the partial derivatives for all mass flow balance equations.

Returns:

deriv (ndarray) – Matrix with partial derivatives for the mass flow equations.

reactor_mass_flow_func()[source]

Equations for mass conservation.

Returns:

residual (list) – Residual values of equation.

\[\begin{split}O_2 = \frac{M_{O_2}}{M_{O_2} + 2 \cdot M_{H_2}}\\ 0 =\dot{m}_\mathrm{in,1}-\dot{m}_\mathrm{out,1}\\ 0=O_2\cdot\dot{m}_\mathrm{H_{2}O,in,2}- \dot{m}_\mathrm{O_2,out,2}\\ 0 = \left(1 - O_2\right) \cdot \dot{m}_\mathrm{H_{2}O,in,2} - \dot{m}_\mathrm{H_2,out,3}\end{split}\]

reactor_pressure_structure_matrix(k)[source]

Structure matrix representing the equations for reactor pressure balance.

\[\begin{split}0 = p_\mathrm{in,2} - p_\mathrm{out,2}\\ 0 = p_\mathrm{in,3} - p_\mathrm{out,2}\end{split}\]
specific_energy_dependents()[source]
specific_energy_func()[source]

Equation for specific energy consumption.

Returns:

residual (float) – Residual value of equation.

\[0 = P - \dot{m}_{H_2,out3} \cdot e\]

start_fluid_wrapper_branch()[source]