HeatExchanger (0D)¶
The HeatExchanger model can be imported from idaes.models.unit_models
,
while additional rules and utility functions can be imported from
idaes.models.unit_models.heat_exchanger
.
Example¶
The example below demonstrates how to initialize the HeatExchanger model, and override the default temperature difference calculation. This example also demonstrates how to assign custom names to the hot and cold sides of the heat exchanger.
import pyomo.environ as pe # Pyomo environment
from idaes.core import FlowsheetBlock, StateBlock
from idaes.models.unit_models import HeatExchanger
from idaes.models.unit_models.heat_exchanger import HX0DInitializer
from idaes.models.unit_models.heat_exchanger import delta_temperature_amtd_callback
from idaes.models.properties import iapws95
# Create an empty flowsheet and steam property parameter block.
model = pe.ConcreteModel()
model.fs = FlowsheetBlock(dynamic=False)
model.fs.properties = iapws95.Iapws95ParameterBlock()
# Add a Heater model to the flowsheet.
model.fs.heat_exchanger = HeatExchanger(
delta_temperature_callback=delta_temperature_amtd_callback,
hot_side_name="shell",
cold_side_name="tube",
shell={"property_package": model.fs.properties},
tube={"property_package": model.fs.properties}
)
model.fs.heat_exchanger.area.fix(1000)
model.fs.heat_exchanger.overall_heat_transfer_coefficient[0].fix(100)
model.fs.heat_exchanger.shell_inlet.flow_mol.fix(100)
model.fs.heat_exchanger.shell_inlet.pressure.fix(101325)
model.fs.heat_exchanger.shell_inlet.enth_mol.fix(4000)
model.fs.heat_exchanger.tube_inlet.flow_mol.fix(100)
model.fs.heat_exchanger.tube_inlet.pressure.fix(101325)
model.fs.heat_exchanger.tube_inlet.enth_mol.fix(3000)
# Initialize the model
initializer = HX0DInitializer()
initializer.initialize(model.fs.heat_exchanger)
Degrees of Freedom¶
Aside from the inlet conditions, a heat exchanger model usually has two degrees of freedom, which can be fixed for it to be fully specified. Things that are frequently fixed are two of:
heat transfer area,
heat transfer coefficient, or
temperature approach.
The user may also provide constraints to calculate the heat transfer coefficient.
Note
For model initialization, the in-built routine currently only supports defining two of area, heat transfer coefficient and heat duty as fixed variables. Fixing of temperature differences or driving forces is not currently supported. Also note that it is assumed that if a time-indexed variable (i.e. heat duty) is fixed that it will be fixed at all points in time during initialization. Users wishing to solve models with alternative specifications should first initialize the model using one of the supported options, or write a custom initialization routine for their specification.
Model Structure¶
The HeatExchanger
model contains two ControlVolume0DBlock
blocks which are named hot_side
and cold_side
.
These names are configurable using the hot_side_name
and cold_side_name
configuration arguments, in which case
aliases are assigned to the control volumes and associated Ports using the names provided (note that hot_side
and
cold_side
will always work). The sign convention is that duty is positive for heat flowing from the hot side to the cold
side. Aside from the sign convention there is no requirement that the hot side be hotter than the cold side, however
some formulations for the average temperature driving force may require that the hot side be hotter than the cold side.
The control volumes are configured the same as the ControlVolume0DBlock
in the
Heater model. The HeatExchanger
model contains additional
constraints that calculate the amount of heat transferred from the hot side to the cold side.
The HeatExchanger
has two inlet ports and two outlet ports. By default these are
hot_side_inlet
, cold_side_inlet
, hot_side_outlet
, and cold_side_outlet
. If the user
supplies different hot and cold side names the inlet and outlets are named accordingly.
Variables¶
Variable |
Symbol |
Index Sets |
Doc |
---|---|---|---|
heat_duty |
\(Q\) |
t |
Heat transferred from hot side to the cold side |
area |
\(A\) |
None |
Heat transfer area |
heat_transfer_coefficient |
\(U\) |
t |
Heat transfer coefficient |
delta_temperature |
\(\Delta T\) |
t |
Temperature difference, defaults to LMTD |
Note: delta_temperature
may be either a variable or expression depending on the callback used. If the specified cold side is hotter
than the specified hot side this value will be negative.
Constraints¶
The default constants can be overridden by providing alternative rules for the heat transfer equation, temperature difference, and heat transfer coefficient. The section describes the default constraints.
Heat transfer from shell to tube:
Temperature difference is an expression:
The heat transfer coefficient is a variable with no associated constraints by default.
Initialization¶
- class idaes.models.unit_models.heat_exchanger.HX0DInitializer(**kwargs)[source]¶
Initializer for 0D Heat Exchanger units.
- constraint_tolerance
Tolerance for checking constraint convergence
- output_level
Set output level for logging messages
- solver
Solver to use for initialization
- solver_options
Dict of options to pass to solver
- default_submodel_initializer
Default Initializer object to use for sub-models. Only used if no Initializer defined in submodel_initializers.
- always_estimate_states
Whether initialization routine should estimate values for state variables that already have values. Note that if set to True, this will overwrite any initial guesses provided.
- initialization_routine(model, plugin_initializer_args=None, copy_inlet_state=False, duty=<pyomo.core.expr.numeric_expr.NPV_ProductExpression object>)[source]¶
Common initialization routine for 0D Heat Exchangers.
This routine starts by initializing the hot and cold side properties. Next, the heat transfer between the two sides is fixed to an initial guess for the heat duty (provided by the duty argument), the associated constraint is deactivated, and the model is then solved. Finally, the heat duty is unfixed and the heat transfer constraint reactivated followed by a final solve of the model.
- Parameters
model (Block) – Pyomo Block to be initialized
plugin_initializer_args (dict) – dict-of-dicts containing arguments to be passed to plug-in Initializers. Keys should be submodel components.
copy_inlet_state (bool) – bool (default=False). Whether to copy inlet state to other states or not (0-D control volumes only). Copying will generally be faster, but inlet states may not contain all properties required elsewhere.
duty – initial guess for heat duty to assist with initialization. Can be a Pyomo expression with units.
- Returns
Pyomo solver results object
Class Documentation¶
Note
The hot_side
and cold_side
can also be supplied using the name of
the hot and cold sides as in the example.
- class idaes.models.unit_models.heat_exchanger.HeatExchanger(*args, **kwds)¶
Simple 0D heat exchanger model.
- Parameters
rule (function) – A rule function or None. Default rule calls build().
concrete (bool) – If True, make this a toplevel model. Default - False.
ctype (class) –
Pyomo ctype of the block. Default - pyomo.environ.Block
Config args
- dynamic
Indicates whether this model will be dynamic or not, default = useDefault. Valid values: { useDefault - get flag from parent (default = False), True - set as a dynamic model, False - set as a steady-state model.}
- has_holdup
Indicates whether holdup terms should be constructed or not. Must be True if dynamic = True, default - False. Valid values: { useDefault - get flag from parent (default = False), True - construct holdup terms, False - do not construct holdup terms}
- hot_side_name
Hot side name, sets control volume and inlet and outlet names
- cold_side_name
Cold side name, sets control volume and inlet and outlet names
- hot_side
A config block used to construct the hot side control volume. This config can be given by the hot side name instead of hot_side.
- hot_side
- material_balance_type
Indicates what type of mass balance should be constructed, default - MaterialBalanceType.useDefault. Valid values: { MaterialBalanceType.useDefault - refer to property package for default balance type **MaterialBalanceType.none - exclude material balances, MaterialBalanceType.componentPhase - use phase component balances, MaterialBalanceType.componentTotal - use total component balances, MaterialBalanceType.elementTotal - use total element balances, MaterialBalanceType.total - use total material balance.}
- energy_balance_type
Indicates what type of energy balance should be constructed, default - EnergyBalanceType.useDefault. Valid values: { EnergyBalanceType.useDefault - refer to property package for default balance type **EnergyBalanceType.none - exclude energy balances, EnergyBalanceType.enthalpyTotal - single enthalpy balance for material, EnergyBalanceType.enthalpyPhase - enthalpy balances for each phase, EnergyBalanceType.energyTotal - single energy balance for material, EnergyBalanceType.energyPhase - energy balances for each phase.}
- momentum_balance_type
Indicates what type of momentum balance should be constructed, default - MomentumBalanceType.pressureTotal. Valid values: { MomentumBalanceType.none - exclude momentum balances, MomentumBalanceType.pressureTotal - single pressure balance for material, MomentumBalanceType.pressurePhase - pressure balances for each phase, MomentumBalanceType.momentumTotal - single momentum balance for material, MomentumBalanceType.momentumPhase - momentum balances for each phase.}
- has_phase_equilibrium
Indicates whether terms for phase equilibrium should be constructed, default = False. Valid values: { True - include phase equilibrium terms False - exclude phase equilibrium terms.}
- has_pressure_change
Indicates whether terms for pressure change should be constructed, default - False. Valid values: { True - include pressure change terms, False - exclude pressure change terms.}
- property_package
Property parameter object used to define property calculations, default - useDefault. Valid values: { useDefault - use default package from parent model or flowsheet, PropertyParameterObject - a PropertyParameterBlock object.}
- property_package_args
A ConfigBlock with arguments to be passed to a property block(s) and used when constructing these, default - None. Valid values: { see property package for documentation.}
- cold_side
A config block used to construct the cold side control volume. This config can be given by the cold side name instead of cold_side.
- cold_side
- material_balance_type
Indicates what type of mass balance should be constructed, default - MaterialBalanceType.useDefault. Valid values: { MaterialBalanceType.useDefault - refer to property package for default balance type **MaterialBalanceType.none - exclude material balances, MaterialBalanceType.componentPhase - use phase component balances, MaterialBalanceType.componentTotal - use total component balances, MaterialBalanceType.elementTotal - use total element balances, MaterialBalanceType.total - use total material balance.}
- energy_balance_type
Indicates what type of energy balance should be constructed, default - EnergyBalanceType.useDefault. Valid values: { EnergyBalanceType.useDefault - refer to property package for default balance type **EnergyBalanceType.none - exclude energy balances, EnergyBalanceType.enthalpyTotal - single enthalpy balance for material, EnergyBalanceType.enthalpyPhase - enthalpy balances for each phase, EnergyBalanceType.energyTotal - single energy balance for material, EnergyBalanceType.energyPhase - energy balances for each phase.}
- momentum_balance_type
Indicates what type of momentum balance should be constructed, default - MomentumBalanceType.pressureTotal. Valid values: { MomentumBalanceType.none - exclude momentum balances, MomentumBalanceType.pressureTotal - single pressure balance for material, MomentumBalanceType.pressurePhase - pressure balances for each phase, MomentumBalanceType.momentumTotal - single momentum balance for material, MomentumBalanceType.momentumPhase - momentum balances for each phase.}
- has_phase_equilibrium
Indicates whether terms for phase equilibrium should be constructed, default = False. Valid values: { True - include phase equilibrium terms False - exclude phase equilibrium terms.}
- has_pressure_change
Indicates whether terms for pressure change should be constructed, default - False. Valid values: { True - include pressure change terms, False - exclude pressure change terms.}
- property_package
Property parameter object used to define property calculations, default - useDefault. Valid values: { useDefault - use default package from parent model or flowsheet, PropertyParameterObject - a PropertyParameterBlock object.}
- property_package_args
A ConfigBlock with arguments to be passed to a property block(s) and used when constructing these, default - None. Valid values: { see property package for documentation.}
- delta_temperature_callback
Callback for for temperature difference calculations
- flow_pattern
Heat exchanger flow pattern, default - HeatExchangerFlowPattern.countercurrent. Valid values: { HeatExchangerFlowPattern.countercurrent - countercurrent flow, HeatExchangerFlowPattern.cocurrent - cocurrent flow, HeatExchangerFlowPattern.crossflow - cross flow, factor times countercurrent temperature difference.}
initialize (dict) – ProcessBlockData config for individual elements. Keys are BlockData indexes and values are dictionaries with config arguments as keys.
idx_map (function) – Function to take the index of a BlockData element and return the index in the initialize dict from which to read arguments. This can be provided to override the default behavior of matching the BlockData index exactly to the index in initialize.
- Returns
(HeatExchanger) New instance
- class idaes.models.unit_models.heat_exchanger.HeatExchangerData(component)[source]¶
Simple 0D heat exchange unit. Unit model to transfer heat from one material to another.
- default_initializer¶
alias of
HX0DInitializer
- initialize_build(state_args_1=None, state_args_2=None, outlvl=0, solver=None, optarg=None, duty=None)[source]¶
Heat exchanger initialization method.
- Parameters
state_args_1 – a dict of arguments to be passed to the property initialization for the hot side (see documentation of the specific property package) (default = {}).
state_args_2 – a dict of arguments to be passed to the property initialization for the cold side (see documentation of the specific property package) (default = {}).
outlvl – sets output level of initialization routine
optarg – solver options dictionary object (default=None, use default solver options)
solver – str indicating which solver to use during initialization (default = None, use default solver)
duty – an initial guess for the amount of heat transferred. This should be a tuple in the form (value, units), (default = (1000 J/s))
- Returns
None
Callbacks¶
A selection of functions for constructing the delta_temperature
variable or
expression are provided in the idaes.models.unit_models.heat_exchanger
module.
The user may also provide their own function. These callbacks should all take
one argument (the HeatExchanger block). With the block argument, the function
can add any additional variables, constraints, and expressions needed. The only
requirement is that either a variable or expression called delta_temperature
must be added to the block.
Defined Callbacks for the delta_temperature_callback
Option¶
These callbacks provide expressions for the temperature difference used in the heat transfer equations. There is a choice of three forms for the LMTD calculation. Depending on the expected approach temperatures, one form may be more favorable. The first two forms do not require one side or the other to be the hot side, while the third form requires the hot side to be the hot side to avoid an evaluation error in the log function.
- idaes.models.unit_models.heat_exchanger.delta_temperature_lmtd_callback(b)[source]¶
This is a callback for a temperature difference expression to calculate \(\Delta T\) in the heat exchanger model using log-mean temperature difference (LMTD). It can be supplied to “delta_temperature_callback” HeatExchanger configuration option. This form is
\[\Delta T = \frac{\Delta T_1 - \Delta T_2}{ \log_e\left(\frac{\Delta T_1}{\Delta T_2}\right)}\]where \(\Delta T_1\) is the temperature difference at the hot inlet end and \(\Delta T_2\) is the temperature difference at the hot outlet end.
- idaes.models.unit_models.heat_exchanger.delta_temperature_lmtd2_callback(b)[source]¶
This is a callback for a temperature difference expression to calculate \(\Delta T\) in the heat exchanger model using log-mean temperature difference (LMTD). It can be supplied to “delta_temperature_callback” HeatExchanger configuration option. This form is
\[\Delta T = \frac{\Delta T_2 - \Delta T_1}{ \log_e\left(\frac{\Delta T_2}{\Delta T_1}\right)}\]where \(\Delta T_1\) is the temperature difference at the hot inlet end and \(\Delta T_2\) is the temperature difference at the hot outlet end.
- idaes.models.unit_models.heat_exchanger.delta_temperature_lmtd3_callback(b)[source]¶
This is a callback for a temperature difference expression to calculate \(\Delta T\) in the heat exchanger model using log-mean temperature difference (LMTD). It can be supplied to “delta_temperature_callback” HeatExchanger configuration option. This form is
\[\Delta T = \frac{\Delta T_1 - \Delta T_2}{ \log_e\left(\Delta T_2\right) - \log_e\left(\Delta T_1\right)}\]where \(\Delta T_1\) is the temperature difference at the hot inlet end and \(\Delta T_2\) is the temperature difference at the hot outlet end.
- idaes.models.unit_models.heat_exchanger.delta_temperature_amtd_callback(b)[source]¶
This is a callback for a temperature difference expression to calculate \(\Delta T\) in the heat exchanger model using arithmetic-mean temperature difference (AMTD). It can be supplied to “delta_temperature_callback” HeatExchanger configuration option. This form is
\[\Delta T = \frac{\Delta T_1 + \Delta T_2}{2}\]where \(\Delta T_1\) is the temperature difference at the hot inlet end and \(\Delta T_2\) is the temperature difference at the hot outlet end.
- idaes.models.unit_models.heat_exchanger.delta_temperature_underwood_callback(b)[source]¶
This is a callback for a temperature difference expression to calculate \(\Delta T\) in the heat exchanger model using log-mean temperature difference (LMTD) approximation given by Underwood (1970). It can be supplied to “delta_temperature_callback” HeatExchanger configuration option. This uses a cube root function that works with negative numbers returning the real negative root. This should always evaluate successfully. This form is
\[\Delta T = \left(\frac{ \Delta T_1^\frac{1}{3} + \Delta T_2^\frac{1}{3}}{2}\right)^3\]where \(\Delta T_1\) is the temperature difference at the hot inlet end and \(\Delta T_2\) is the temperature difference at the hot outlet end.
- idaes.models.unit_models.heat_exchanger.delta_temperature_lmtd_smooth_callback(b)[source]¶
This is a callback for a temperature difference expression to calculate \(\Delta T\) in the heat exchanger model using log-mean temperature difference (LMTD) approximation from Kazi, S., M. Short, A.J. Isafiade, L.T. Biegler. “Heat exchanger network synthesus with detailed exchanger designs - 2. Hybrid optimization strategy for synthesis of heat exchanger networks”. AIChE Journal, 2020.
\[\alpha = \frac{\Delta T_2}{\Delta T_1}\]\[\Delta T = \frac{\Delta T_1 \sqrt{(\alpha - 1)^2 + \varepsilon}}{\sqrt{(\log_e{\alpha})^2 + \varepsilon}}\]where \(\Delta T_1\) is the temperature difference at the hot inlet end, \(\Delta T_2\) is the temperature difference at the hot outlet end, and \(\varepsilon\) is the smoothing parameter.
The smoothing parameter (
eps_lmtd_smoothing
) is mutable and the default is 1e-10.