Python API¶
Public API¶
HeatMixin¶
- class rtctools_heat_network.heat_mixin.HeatMixin(*args, **kwargs)[source]¶
Bases:
_HeadLossMixin
,BaseComponentTypeMixin
,CollocatedIntegratedOptimizationProblem
- heat_network_options()[source]¶
Returns a dictionary of heat network specific options.
Option
Type
Default value
minimum_pressure_far_point
float
1.0
barmaximum_temperature_der
float
2.0
°C/hourmaximum_flow_der
float
np.inf
m3/s/hourneglect_pipe_heat_losses
bool
False
heat_loss_disconnected_pipe
bool
True
minimum_velocity
float
0.005
m/shead_loss_option
(inherited)enum
HeadLossOption.LINEAR
minimize_head_losses
(inherited)bool
False
include_demand_insulation_options
bool
False
The
maximum_temperature_der
gives the maximum temperature change per hour. Similarly, themaximum_flow_der
parameter gives the maximum flow change per hour. These options together are used to constrain the maximum heat change per hour allowed in the entire network. Note the unit for flow is m3/s, but the change is expressed on an hourly basis leading to them3/s/hour
unit.The
heat_loss_disconnected_pipe
option decides whether a disconnectable pipe has heat loss or not when it is disconnected on that particular time step. By default, a pipe has heat loss even if it is disconnected, as it would still contain relatively hot water in reality. We also do not want minimization of heat production to lead to overly disconnecting pipes. In some scenarios it is hydraulically impossible to supply heat to these disconnected pipes (Q is forced to zero), in which case this option can be set toFalse
.The
neglect_pipe_heat_losses
option sets the heat loss in pipes to zero. This can be useful when the insulation properties are unknown. Note that other components can still have heat loss, e.g. a buffer.The
minimum_velocity
is the minimum absolute value of the velocity in every pipe. It is mostly an option to improve the stability of the solver in a possibly subsequent QTH problem: the default value of 0.005 m/s helps the solver by avoiding the difficult case where discharges get close to zero.Note that the inherited options
head_loss_option
andminimize_head_losses
are changed from their default values toHeadLossOption.LINEAR
andFalse
respectively.The
include_demand_insulation_options
options is used, when insulations options per demand is specificied, to include heat demand and supply matching via constraints for all possible insulation options.
QTHMixin¶
- class rtctools_heat_network.qth_mixin.QTHMixin(*args, flow_directions=None, **kwargs)[source]¶
Bases:
_HeadLossMixin
,BaseComponentTypeMixin
,CollocatedIntegratedOptimizationProblem
Adds handling of QTH heat network objects in your model to your optimization problem.
Relevant parameters and variables are read from the model, and from this data a set of constraints and objectives are automatically generated, e.g. for the head loss and temperature losses in pipes.
- __init__(*args, flow_directions=None, **kwargs)[source]¶
- Parameters:
flow_directions –
A dictionary mapping a pipe name to a Timeseries of the flow directions of type:
PipeFlowDirection
ControlValveDirection
CheckValveStatus
- property heat_network_flow_directions: Dict[str, str]¶
Maps a pipe name to its corresponding constant_inputs Timeseries name for the direction.
- heat_network_options()[source]¶
Returns a dictionary of heat network specific options.
Option
Type
Default value
maximum_temperature_der
float
2.0
°C/hourmax_t_der_bidirect_pipe
bool
True
minimum_velocity
float
0.005
m/ssources_equal_output_temp
bool
False
demand_temperature_option
bool
DemandTemperatureOption.FIXED_DT
The
maximum_temperature_der
is the maximum temperature change allowed in the network. It is expressed in °C per hour. Note that this is a proxy constraint as it does not imply that temperature in the entire network is within the wanted limits.When the flag
max_t_der_bidirect_pipe
is False, the maximum temperature change set withmaximum_temperature_der
is _not_ imposed on pipes when the flow direction changes. When it is True (the default), it is imposed in cases of flow reversal.The
minimum_velocity
is the minimum absolute value of the velocity in every pipe. It is mostly an option to improve the stability of the solver: the default value of 0.005 m/s helps the solver by avoiding the difficult case where discharges get close to zero.When the flag
sources_equal_output_temp
is set to True, all the sources in the network are forced to have the same output temperature. When it is False, the default, each source can operate its temperature independently from each other.The
demand_temperature_option
option controls what the temperature drop and/or the return temperature of each demand is.When
DemandTemperatureOption.FIXED_DT
is used (default), the temperature drop over each demand is fixed to its <demand>.dT parameter value. In other words, if the supply temperature drops, so does the return temperature.When
DemandTemperatureOption.MIN_RETURN_MAX_DT
is used, the return temperature is required to be at least its <demand.T_return> parameter value. The temperature drop can be at most <demand>.dT, but is allowed to be lower.When
DemandTemperatureOption.FREE
is used, no relationship is enforced. It is then up to the user to enforce a relationship on a demand’s temperature drop, return and/or supply temperature.
HeadLossMixin¶
- class rtctools_heat_network.head_loss_mixin.HeadLossOption(value)[source]¶
Bases:
IntEnum
Enumeration for the possible options to take head loss in pipes into account. Also see
_HeadLossMixin.heat_network_options()
for related options.Note
Not all options are supported by
HeatMixin
, due to the focus on MILP formulations.- NO_HEADLOSS
The NO_HEADLOSS option assumes that there is no headloss in the pipelines. There are no constraints added relating the discharge to the head.
- CQ2_INEQUALITY
As the name implies, this adds a quadratic inquality constraint between the head and the discharge in a pipe:
\[dH \ge C \cdot Q^2\]This expression of the headloss requires a system-specific estimation of the constant C.
As dH is always positive, a boolean is needed when flow directions are not fixed in a mixed-integer formulation to determine if
\[dH = H_{up} - H_{down}\]or (when the \(Q < 0\))
\[dH = H_{down} - H_{up}\]- LINEARIZED_DW
Just like
CQ2_INEQUALITY
, this option adds inequality constraints:\[\Delta H \ge \vec{a} \cdot Q + \vec{b}\]with \(\vec{a}\) and \(\vec{b}\) the linearization coefficients.
This approach can more easily be explain with a plot, showing the Darcy-Weisbach head loss, and the linear lines approximating it. Note that the number of supporting lines is an option that can be set by the user by overriding
_HeadLossMixin.heat_network_options()
. Also note that, just likeCQ2_INEQUALITY
, a boolean is needed when flow directions are not fixed.- LINEAR
This option uses a linear head loss formulation. A single constraint of the type
\[H_{up} - H_{down} = dH = C \cdot Q\]is added. Note that no boolean are required to support the case where flow directions are not fixed yet, at the cost of reduced fidelity in the head-loss relationship.
The exact velocity to use to linearize can be set by overriding
_HeadLossMixin.heat_network_options()
.- CQ2_EQUALITY
This option adds equality constraints of the type:
\[dH = C \cdot Q^2\]This equation is non-convex, and can therefore lead to convergence issues.
Internal API¶
HeadLossMixin¶
- class rtctools_heat_network.head_loss_mixin._HeadLossMixin(*args, **kwargs)[source]¶
Bases:
BaseComponentTypeMixin
,_GoalProgrammingMixinBase
,OptimizationProblem
Adds handling of discharge - head (loss) relationship to the model.
- abstract _hn_get_pipe_head_loss_option(pipe, heat_network_options, parameters, **kwargs) HeadLossOption [source]¶
The global user head loss option is not necessarily the same as the head loss option for a specific pipe. For example, when a control valve is present, a .LINEAR global head loss option could mean a .CQ2_INEQUALITY formulation should be used instead.
See also the explanation of head_loss_option (and its values) in
heat_network_options()
.
- _hn_pipe_head_loss(pipe: str, heat_network_options, parameters, discharge: Union[MX, float, ndarray], head_loss: Optional[MX] = None, dh: Optional[MX] = None, is_disconnected: Union[MX, int] = 0, big_m: Optional[float] = None, pipe_class: Optional[PipeClass] = None) Union[List[Tuple[MX, Union[float, ndarray, Timeseries], Union[float, ndarray, Timeseries]]], float, ndarray] [source]¶
This function has two purposes: - return the head loss constraint expression(s) or - compute the head loss numerically (always positive).
Note that there are different head loss formulations (see
HeadLossOption
). Some formulations require the passing of head_loss (a symbol that is always positive by definition), and others require the passing of dh (which is negative when the flow is positive).When head_loss or dh is its corresponding MX symbol/expression, the appropriate constraint expression is returned. When head_loss and dh are both None, the discharge is assumed numerical, and the numerical computation of the appropriate head loss formulation is returned. Note that this returned numerical value is always positive, regardless of the sign of the discharge.
is_disconnected can be used to specify whether a pipe is disconnected or not. This is most useful if a (boolean) ca.MX symbol is passed, which can then be used with a big-M formulation. The big-M itself then also needs to be passed via the big_m keyword argument.
- abstract _hn_pipe_head_loss_constraints(ensemble_member) List[Tuple[MX, float, float]] [source]¶
This method should be implemented to relate the three variables:
discharge: e.g. pipe.Q
head difference: e.g. pipe.dH
head loss of the pipe (note: proxy symbol that is >= abs(actual head loss))
The internal variable name/symbol for the head loss can be retried via self._hn_pipe_to_head_loss_map[pipe]. The method that should/can be called to relate these three variables is
_hn_pipe_head_loss()
.
- heat_network_options()[source]¶
Returns a dictionary of heat network specific options.
Option
Type
Default value
minimum_pressure_far_point
float
1.0
barwall_roughness
float
0.0002
mhead_loss_option
enum
HeadLossOption.CQ2_INEQUALITY
estimated_velocity
float
1.0
m/s (CQ2_* & LINEAR)maximum_velocity
float
2.5
m/s (LINEARIZED_DW)n_linearization_lines
int
5
(LINEARIZED_DW)minimize_head_losses
bool
True
pipe_minimum_pressure
float
-np.inf
pipe_maximum_pressure
float
np.inf
The
minimum_pressure_far_point
gives the minimum pressure requirement at any demand node, which means that the pressure at the furthest point is also satisfied without inspecting the topology.The
wall_roughness
of the pipes plays a role in determining the resistance of the pipes.To model the head loss in pipes, the
head_loss_option
refers to one of the ways this can be done. SeeHeadLossOption
for more explanation on what each option entails. Note that some options model the head loss as an inequality, i.e. \(\Delta H \ge f(Q)\), whereas others model it as an equality.When
HeadLossOption.CQ2_INEQUALITY
is used, the wall roughness atestimated_velocity
determines the C in \(\Delta H \ge C \cdot Q^2\).When
HeadLossOption.LINEARIZED_DW
is used, themaximum_velocity
needs to be set. The Darcy-Weisbach head loss relationship from \(v = 0\) until \(v = \text{maximum_velocity}\) will then be linearized usingn_linearization
lines.When
HeadLossOption.LINEAR
is used, the wall roughness atestimated_velocity
determines the C in \(\Delta H = C \cdot Q\). For pipes that contain a control valve, the formulation ofHeadLossOption.CQ2_INEQUALITY
is used.When
HeadLossOption.CQ2_EQUALITY
is used, the wall roughness atestimated_velocity
determines the C in \(\Delta H = C \cdot Q^2\). Note that this formulation is non-convex. At theta < 1 we therefore use the formulationHeadLossOption.LINEAR
. For pipes that contain a control valve, the formulation ofHeadLossOption.CQ2_INEQUALITY
is used.When
minimize_head_losses
is set to True (default), a last priority is inserted where the head losses and hydraulic power in the system are minimized if thehead_loss_option
is not NO_HEADLOSS. This is related to the assumption that control valves are present in the system to steer water in the right direction the case of multiple routes. If such control valves are not present, enabling this option will give warnings in case the found solution is not feasible. In case the option is False, both the minimization and checks are skipped.The
pipe_minimum_pressure
is the global minimum pressured allowed in the network. Similarly,pipe_maximum_pressure
is the maximum one.
- class rtctools_heat_network.head_loss_mixin._MinimizeHeadLosses(optimization_problem: _HeadLossMixin, *args, **kwargs)[source]¶
Bases:
Goal
- function(optimization_problem: _HeadLossMixin, ensemble_member)[source]¶
This method returns a CasADi
MX
object describing the goal function.- Returns:
A CasADi
MX
object.
- order = 1¶
The goal violation value is taken to the order’th power in the objective function.
- priority = 2147483647¶
Lower priority goals take precedence over higher priority goals.