BoilerHeatExchanger2D¶
The BoilerHeatExchanger2D model can be used to represent boiler heat exchangers in sub-critical and super critical power plant flowsheets (i.e. econmizer, primary superheater, secondary superheater, finishing superheater, reheater, etc.). The model consists of a shell and tube crossflow heat exchanger, in which the shell is used as the gas side and the tube is used as the water or steam side. Due to the fluid temperature changes along the flow paths inside and outside of the tubes, the velocities of the fluids also change from the inlet to the outlet, causing the changes of heat transfer coefficients and friction factors on both sides along the flow paths. If the flows on both sides can be discretized along the flow paths, local temperature difference between the hot and cold streams (the driving force for heat transfer), local heat transfer coefficients and local friction factors can be used and a more accurate model can be constructed. Figure 1 shows a schematic of the shell and tube cross-flow heat exchanger. In this figure, the hot fluid on the shell side flows from left to right while the cold fluid flows through the tubes up and down. Notice that the cold fluid may enter the tube bundle in multiple rows (2 rows shown in the figure) and flow in parallel. The dash lines show the discretization along the flow path of the hot shell-side flow. The dash lines also cut the tube side flow to multiple segments with the direction of the flow inside the tube switching in two neighboring segments. The flow properties such as heat transfer coefficients and friction factors are calculated in individual discretized elements. Meanwhile the overall flow configuration is either a co-current or counter-current. Counter-current configuration are shown in Figure 1. Since the tube-side flow switches direction from one discretized section to another, pressure drop due the U-turn is also modeled based on the loss coefficient of the U-turn. If the elevation changes between the tube inlet and outlet, the pressure change due to gravity for the tube side fluid is also modeled in each element. Rigorous heat transfer calculations (convective heat transfer for shell side, and convective heat transfer for tube side) and shell and tube pressure drop calculations have been included.
In a transient heat transfer process such as in a load ramping operating condition, tube metal wall contains internal energy and its change with time represents the accumulation term (source or sink) in the energy conservation equation. Due to the high density and high heat capacity of the tube metal, its energy holdup should not be ignored. In other words, the transient tube wall temperatures and its distribution along the wall thickness and along the flow path need to be solved. In addition to the discretization along the flow path direction, the discretization along the tube wall thickness at each discretized flow path section is required, which make the heat exchanger model a 2-D model. Besides, the temperature gradient along the tube thickness is also required to calculate the thermal stress and other equipment health related properties. Figure 2 shows the discretization of tube wall temperature along the tube radius direction. The transient tube wall temperature T_(w,r) at each discretized radius r is calculated based on transient heat conduction equation(Eqn. 1), and in the cylindrical coordinate system the heat conduction equation is shown in equation 2.
where, T_(w,r) is the tube metal temperature, t is time, alfa is termal diffusivity of the tube metal, typically steel, and r is the radius. This partial differential equation can be discretized by Pyomo-DAE in the radius direction. The heat accumulation in the tube metal is represented by the solution of the transient temperatures along the radius direction.
The HeatExchangerCrossFlow2D_Header model can be imported from idaes.power_generation.unit_models
,
while additional rules and utility functions can be imported from
idaes.power_generation.unit_models.boiler_heat_exchanger2D
.
Degrees of Freedom¶
The configuration variables for the 2-D heat exchanger model include the inside diameter of the tube and thickness of the tube. They are used as parameters of the model and have to be declared for discretization in the radius direction. Once declared as configuration arguments, they are not allowed to change (immutable). Other configuration variables include “finite_elements” (the number of elements) in the flow path direction, “radial_elements” (the number of elements in radius direction, “tube_arrangement” for either staggered or in-line arrangement, “has_radiation” if shell-side radiation heat transfer is considered, and “flow_type” for either co-current or counter-current configuration. Additionally, has_header has been added as a configuration argument, when it is True, the health of the water/steam headers is calculated (see header section). The main input variables for the 2-D cross-flow heat exchanger model include design variables such as number of tube segments, number of tube columns, number of tube inlet rows, length of the tube in each segment (each pass), pitches in directions parallel and perpendicular to the shell fluid flow, and elevation change from tube inlet to tube outlet. The thermal and transport properties are also required as well as the mechanical properties if the equipment health model is used. Other required operating variables include fouling resistances on both tube and shell sides, tube wall emissivity if radiation model is turned on, and correction factors for heat transfer and pressure drops on both sides. Given the inlet conditions such as pressures, temperatures and flow rates on both sides, the outlet conditions will be predicted by the model. Meanwhile the temperature and pressure distributions along the flow path direction will be solved on both sides. The 2-D tube wall temperature distribution will also be solved.
In order to capture off design conditions and heat transfer coefficients at ramp up/down or load following conditions, the BoilerHeatExchanger2D model includes rigorous heat transfer calculations. Therefore, additional degrees of freedom are required to calculate Nusselt, Prandtl, Reynolds numbers, such as:
tube_di (inner diameter)
tube length
tube number of rows (tube_nrow), columns (tube_ncol), and inlet flow (nrow_inlet)
pitch in x and y axis (pitch_x and pitch_y, respectively)
If pressure drop calculation is enabled, additional degrees of freedom are required:
elevation with respect to ground level (delta_elevation)
tube fouling resistance (tube_r_fouling)
shell fouling resistance (shell_r_fouling)
Model Structure¶
The HeatExchangerCrossFlow2D_Header
model contains two ControlVolume1DBlock
blocks. By default the
gas side is named shell
and the water/steam side is named tube
. These names are configurable.
The sign convention is that duty is positive for heat flowing from the hot side to the cold
side.
The control volumes are configured the same as the ControlVolume1DBlock
in the
Heater model.
The HeatExchangerCrossFlow2D_Header
model contains additional constraints that calculate the amount
of heat transferred from the hot side to the cold side.
The HeatExchangerCrossFlow2D_Header
has two inlet ports and two outlet ports. By default these are
shell_inlet
, tube_inlet
, shell_outlet
, and tube_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\) |
time |
Heat transferred from hot side to the cold side |
area |
\(A\) |
None |
Heat transfer area |
U |
\(U\) |
time |
Heat transfer coefficient |
delta_temperature |
\(\Delta T\) |
time |
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 constraints can be overridden by providing alternative rules for the heat transfer equation, temperature difference, heat transfer coefficient, shell and tube pressure drop. This section describes the default constraints.
Heat transfer from shell to tube:
Temperature difference is:
The overall heat transfer coefficient is calculated as a function of convective heat transfer shell and tube, and wall conduction heat transfer resistance.
Convective heat transfer equations:
Tube convective heat transfer (for all elements in tube discretization approach):
Shell convective heat transfer:
Wall heat conduction resistance equation:
where:
hconv_tube : convective heat transfer resistance tube side (fluid water/steam) (W / m2 / K)
hconv_shell : convective heat transfer resistance shell side (fluid Flue Gas) (W / m2 / K )
Nu : Nusselt number
Pr : Prandtl number
Re : Reynolds number
V: velocity (m/s)
tube_di : inner diameter of the tube (m)
tube_do : outer diameter of the tube (m) (expression calculated by the model)
tube_thickness : tube thickness (m)
r = wall heat conduction resistance (K m^2 / W)
k : thermal conductivity of the tube wall (W / m / K)
\(\rho\) : density (kg/m^3)
\(\mu\) : viscocity (kg/m/s)
tube_r_fouling : tube side fouling resistance (K m^2 / W)
shell_r_fouling : shell side fouling resistance (K m^2 / W)
fcorrection_htc: correction factor for overall heat trasnfer
f_arrangement: tube arrangement factor
Note: by default fcorrection_htc is set to 1, however, this variable can be used to match unit performance (i.e. as a parameter estimation problem using real plant data).
Tube arrangement factor is a config argument with two different type of arrangements supported at the moment: 1.- In-line tube arrangement factor (f_arrangement = 0.788), and 2.- Staggered tube arrangement factor (f_arrangement = 1). f_arrangement is a parameter that can be adjusted by the user.
The HeatExchangerCrossFlow2D_Header
model includes an argument to compute heat tranfer due to radiation of the flue gases. If has_radiation = True the model builds additional heat transfer calculations that will be added to the hconv_shell resistances.
Radiation effects are calculated based on the gas gray fraction and gas-surface radiation (between gas and shell).
Note: Gas emissivity is calculated with surrogate models (see more details in boiler_heat_exchanger.py). Radiation = True when flue gas temperatures are higher than 700 K (for example, when the model is used for units like Primary superheater, Reheater, or Finishing Superheater; while Radiation = False when the model is used to represent the economizer in a power plant flowsheet).
If pressure change is set to True, \(deltaP_{uturn} and friction_{factor}\) are calculated
Tube side:
where:
\(k_{loss uturn}\) : pressure loss coeficient of a tube u-turn
g : is the acceleration of gravity 9.807 (m/s^2)
Shell side:
\(\Delta P_{shell friction}\) is calculated based on the tube arrangement type:
In-line: \(\Delta P_{shell friction} = \frac{ 0.044 + \frac{0.08 ( \frac{P_x}{tube_{do}} ) } {(\frac{P_y}{tube_{do}}-1)^{0.43+\frac{1.13}{(\frac{P_x}{tube_{do}})}}}}{Re^{0.15}}\)
Staggered: \(\Delta P_{shell friction} = \frac{ 0.25 + \frac{0.118}{(\frac{P_y}{tube_{do}} -1)^{1.08}} }{Re^{0.16}}\)
Figure. Tube Arrangement
Header Health Model¶
The heat exchanger 2D model allows the user to calculate the thermal and mechanical stresses of the water/steam headers connected to the outlet of the tube side. Additionally, the rupture time and fatigue calculation of allowable cycles are computed by the model. A simplified 1D PDE problem is developed to represent the heat conduction transient through the radius of the superheater/reheater headers. Regarding to the flow path configuration (counter-current or co-current) of the 2D heat exchanger, the first or the last discretization point will be used to define the boundary of the headers. For this example, the last discretization point will be used for the outlet superheater header due to the counter-current flow configuration. Under the assumptions of constant conductivity and no heat generation, the Fourier’s equation is converted to the Eq. (h1) for the cylindrical header. The Pyomo.DAE framework is applied to solve the PDE problem. The thermal and mechanical stresses are calculated based on the pressure and temperature difference between both sides of the header which can be used to evaluate the allowable number of cycles of the main body and the critical point of the edge of the hole.
where T is wall temperature (K), r is radius (m), and a is the material thermal difussivity (m2/s). The material thermal difussivity is a function of (material thermal conductivity, specific heat, and density)
Detailed description of the mechanical stress calculations and thermal stress calculations can be found in S. Bracco, 2012 and Taler & Duda, 2006, respectively.
Rupture time calculation: The creep phenomenon is an important design consideration in the analysis of structures. At the high temperature operation, the creep is coupled with fatigue due to cycling, the damage will be much higher than that occurring if the same fatigue or creep is working alone. For example, a long-time creep rupture strength values can be derived by using the Manson-Haferd model. However, depending on the investigated material, users can find another correlation to calculate the rupture strength in the open literature.
Fatigue calculation of allowable cycles: For general ferritic and austenitic materials, the calculation of the allowable number of cycles are expressed in the following equation. However, the users can be recommended to find a specific fatigue equation for their own material to obtain a better result. Using the calculated stresses above, the number of allowable cycles of the component can be evaluated based on fatigue assessment standard, such as EN 13445. The detail of the developed approach can be found in Bracco’s report (S. Bracco, 2012). This model can be applied for both drum and thick-walled components such as header. According to the EN 13445 standard, for a single cycle, the allowable number of fatigue cycles N can be computed as:
where Rm is the material tensile strength at room temperature while the reference stress range \(\Delta\SigmaR_i\) depends on the stress range \(\Delta\Sigma_i\)
Bracco, S. (2012). Dynamic simulation of combined cycles operating in transient conditions: An innovative approach to determine the steam drums life consumption. In Proceedings of the 25th International Conference on Efficiency, Cost, Optimization and Simulation of Energy Conversion Systems and Processes, ECOS 2012. Taler, J., & Duda, P. (2006). Solving direct and inverse heat conduction problems. Solving Direct and Inverse Heat Conduction Problems. Springer Berlin Heidelberg. https://doi.org/10.1007/978-3-540-33471-2
Class Documentation¶
- class idaes.power_generation.unit_models.boiler_heat_exchanger_2D.HeatExchangerCrossFlow2D_Header(*args, **kwds)¶
- 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
default (dict) –
Default ProcessBlockData config
- Keys
- 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}
- shell_side
shell side config arguments
- material_balance_type
Indicates what type of mass balance should be constructed, default - MaterialBalanceType.componentTotal. Valid values: { 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.enthalpyTotal. Valid values: { EnergyBalanceType.none - exclude energy balances, EnergyBalanceType.enthalpyTotal - single ethalpy balance for material, EnergyBalanceType.enthalpyPhase - ethalpy 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_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 = ‘use_parent_value’) - ‘use_parent_value’ - get package from parent (default = None) - a ParameterBlock object
- property_package_args
A dict of arguments to be passed to the PropertyBlockData and used when constructing these (default = ‘use_parent_value’) - ‘use_parent_value’ - get package from parent (default = None) - a dict (see property package for documentation)
- tube_side
tube side config arguments
- material_balance_type
Indicates what type of mass balance should be constructed, default - MaterialBalanceType.componentTotal. Valid values: { 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.enthalpyTotal. Valid values: { EnergyBalanceType.none - exclude energy balances, EnergyBalanceType.enthalpyTotal - single ethalpy balance for material, EnergyBalanceType.enthalpyPhase - ethalpy 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_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 = ‘use_parent_value’) - ‘use_parent_value’ - get package from parent (default = None) - a ParameterBlock object
- property_package_args
A dict of arguments to be passed to the PropertyBlockData and used when constructing these (default = ‘use_parent_value’) - ‘use_parent_value’ - get package from parent (default = None) - a dict (see property package for documentation)
- transformation_method
Discretization method to use for DAE transformation. See Pyomo documentation for supported transformations.
- transformation_scheme
Discretization scheme to use when transformating domain. See Pyomo documentation for supported schemes.
- finite_elements
Number of finite elements to use when discretizing length domain (default=5). Should set to the number of tube rows
- collocation_points
Number of collocation points to use per finite element when discretizing length domain (default=3)
- flow_type
Flow configuration of heat exchanger co_current: shell and tube flows from 0 to 1 counter_current: shell side flows from 0 to 1 tube side flows from 1 to 0
- tube_arrangement
Tube arrangement could be in-line or staggered
- tube_side_water_phase
Define water phase for property calls
- has_radiation
Define if shell side gas radiation is to be considered
- tube_inner_diameter
User must define inner diameter of tube
- tube_thickness
User must define tube wall thickness
- radial_elements
Number of finite elements to use when discretizing radius domain (default=5).
- header_inner_diameter
User must define inner diameter of header
- header_wall_thickness
User must define header wall thickness
- header_radial_elements
Number of finite elements to use when discretizing radius domain (default=5).
- has_header
If has_header is True, user must provide header thickness and inner diameter.
initialize (dict) – ProcessBlockData config for individual elements. Keys are BlockData indexes and values are dictionaries described under the “default” argument above.
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 overide the default behavior of matching the BlockData index exactly to the index in initialize.
- Returns
(HeatExchangerCrossFlow2D_Header) New instance
- class idaes.power_generation.unit_models.boiler_heat_exchanger_2D.HeatExchangerCrossFlow2D_HeaderData(component)[source]¶
Standard Heat Exchanger Cross Flow Unit Model Class.
- initialize(shell_state_args=None, tube_state_args=None, outlvl=0, solver=None, optarg=None)[source]¶
HeatExchangerCrossFlow1D initialisation routine
- Keyword Arguments
state_args – a dict of arguments to be passed to the property package(s) to provide an initial state for initialization (see documentation of the specific property package) (default = None).
outlvl –
sets output level of initialisation routine
0 = no output (default)
1 = return solver state for each step in routine
2 = return solver state for each step in subroutines
3 = include solver output infomation (tee=True)
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)
- Returns
None