Skip to content

Commit

Permalink
polishing step
Browse files Browse the repository at this point in the history
  • Loading branch information
dallan-keylogic committed Apr 18, 2024
1 parent 4e6af02 commit ad4dddf
Show file tree
Hide file tree
Showing 7 changed files with 73 additions and 41 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@ CrossFlowHeatExchanger1D

.. module:: idaes.models_extra.power_generation.unit_models.cross_flow_heat_exchanger_1D

This model is for a cross flow heat exchanger between two gases. The gas in the shell has a straight path,
while the gas in the tubes snakes back and forth across the shell's path.
This model is for a cross flow heat exchanger between two gases. The gas in the shell has a straight path,
while the gas in the tubes snakes back and forth across the shell's path. Note that the ``finite_elements``
option in the shell and tube control volume configs should be set to an integer factor of ``number_passes``
in order for the discretization equations to make sense as a cross-flow heat exchanger.

Example
-------
Expand Down Expand Up @@ -145,14 +147,14 @@ Example
Heat Exchanger Geometry
-----------------------
=========================== =========== =================================================================================
=========================== =========== ===================================================================================================
Variable Index Sets Doc
=========================== =========== =================================================================================
=========================== =========== ===================================================================================================
``number_columns_per_pass`` None Number of columns of tube per pass
``number_rows_per_pass`` None Number of rows of tube per pass
``number_passes`` None Number of tube banks of ``nrow_tube * ncol_inlet`` tubes
``pitch_x`` None Distance between columns (TODO rows?) of tubes, measured from center-of-tube to center-of-tube
``pitch_y`` None Distance between rows (TODO columns?) of tubes, measured from center-of-tube to center-of-tube
``pitch_x`` None Distance between tubes parallel to shell flow, measured from center-of-tube to center-of-tube
``pitch_y`` None Distance between tubes perpendicular to shell flow, measured from center-of-tube to center-of-tube
``length_tube_seg`` None Length of tube segment perpendicular to flow in each pass
``area_flow_shell`` None Reference to flow area on shell control volume
``length_flow_shell`` None Reference to flow length on shell control volume
Expand All @@ -161,7 +163,7 @@ Variable Index Sets Doc
``thickness_tube`` None Thickness of tube wall.
``area_flow_tube`` None Reference to flow area on tube control volume
``length_flow_tube`` None Reference to flow length on tube control volume
=========================== =========== =================================================================================
=========================== =========== ===================================================================================================

============================ =========== ===========================================================================
Expression Index Sets Doc
Expand Down Expand Up @@ -222,7 +224,7 @@ Constraint Index Sets Doc
``conv_heat_transfer_coeff_shell_eqn`` time, length Calculates the shell-side convective heat transfer coefficient
``v_tube_eqn`` time, length Calculates gas velocity in tube
``N_Re_tube_eqn`` time, length Calculates the tube-side Reynolds number
``heat_transfer_coeff_tube_eqn`` time, length Calcualtes the tube-side heat transfer coefficient
``heat_transfer_coeff_tube_eqn`` time, length Calculates the tube-side heat transfer coefficient
``N_Nu_shell_eqn`` time, length Calculate the shell-side Nusselt number
``N_Nu_tube_eqn`` time, length Calculate the tube-side Nusselt number
``heat_tube_eqn`` time, length Calculates heat transfer per unit length
Expand Down Expand Up @@ -309,7 +311,7 @@ Initialization
First, the shell and tube control volumes are initialized without heat transfer. Next
the total possible heat transfer between streams is estimated based on heat capacity,
flow rate, and inlet/outlet temperatures. The actual temperature change is set to be
half the theoretical maximum, and the shell and tube are initalized with linear
half the theoretical maximum, and the shell and tube are initialized with linear
temperature profiles. Finally, temperatures besides the inlets are unfixed and
the performance equations are activated before a full solve of the system model.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ Heater1D
.. module:: idaes.models_extra.power_generation.unit_models.heater_1D

This model is for a gas trim heater modeled as gas being blown perpendicularly across banks of hollow tubes,
which are heated by resistive heating.
which are heated by resistive heating. Note that the ``finite_elements`` option in the control
volume config should be set to an integer factor of ``number_passes`` in order for the
discretization equations to make sense as a cross-flow heat exchanger.

Example
-------
Expand Down Expand Up @@ -116,21 +118,21 @@ Example
Heater Geometry
---------------
=========================== =========== =================================================================================
=========================== =========== =============================================================================================
Variable Index Sets Doc
=========================== =========== =================================================================================
=========================== =========== =============================================================================================
``number_columns_per_pass`` None Number of columns of tube per pass
``number_rows_per_pass`` None Number of rows of tube per pass
``number_passes`` None Number of tube banks of ``nrow_tube * ncol_inlet`` tubes
``pitch_x`` None Distance between columns (TODO rows?) of tubes, measured from center-of-tube to center-of-tube
``pitch_y`` None Distance between rows (TODO columns?) of tubes, measured from center-of-tube to center-of-tube
``pitch_x`` None Distance between tubes parallel to flow, measured from center-of-tube to center-of-tube
``pitch_y`` None Distance between tubes perpendicular to flow, measured from center-of-tube to center-of-tube
``length_tube_seg`` None Length of tube segment perpendicular to flow in each pass
``area_flow_shell`` None Reference to flow area on control volume
``length_flow_shell`` None Reference to flow length on control volume
``area_flow_shell_min`` None Minimum flow area on shell side
``di_tube`` None Inner diameter of tubes
``thickness_tube`` None Thickness of tube wall.
=========================== =========== =================================================================================
=========================== =========== =============================================================================================

============================ =========== ===========================================================================
Expression Index Sets Doc
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@

__author__ = "Jinliang Ma, Douglas Allan"


class CrossFlowHeatExchanger1DInitializer(SingleControlVolumeUnitInitializer):
"""
Initializer for Cross Flow Heat Exchanger 1D units.
Expand Down Expand Up @@ -100,7 +101,9 @@ def initialize_main_model(
)

hot_units = model.config.hot_side.property_package.get_metadata().derived_units
cold_units = model.config.cold_side.property_package.get_metadata().derived_units
cold_units = (
model.config.cold_side.property_package.get_metadata().derived_units
)

if model.config.shell_is_hot:
shell = model.hot_side
Expand Down Expand Up @@ -274,7 +277,9 @@ def initialize_main_model(
/ 2
)

model.temp_wall_shell[t, z].set_value(model.temp_wall_center[t, z].value)
model.temp_wall_shell[t, z].set_value(
model.temp_wall_center[t, z].value
)
model.temp_wall_tube[t, z].set_value(
pyunits.convert_value(
model.temp_wall_center[t, z].value,
Expand Down Expand Up @@ -354,6 +359,7 @@ def initialize_main_model(
init_log.info("Initialization Complete.")
return res


@declare_process_block_class("CrossFlowHeatExchanger1D")
class CrossFlowHeatExchanger1DData(HeatExchanger1DData):
"""Standard Cross Flow Heat Exchanger Unit Model Class."""
Expand Down Expand Up @@ -455,7 +461,9 @@ def _make_geometry(self):
add_object_reference(self, "length_flow_shell", shell.length)
add_object_reference(self, "length_flow_tube", tube.length)

heat_exchanger_common.make_geometry_common(self, shell=shell, shell_units=shell_units)
heat_exchanger_common.make_geometry_common(
self, shell=shell, shell_units=shell_units
)
heat_exchanger_common.make_geometry_tube(self, shell_units=shell_units)

def _make_performance(self):
Expand Down Expand Up @@ -764,10 +772,14 @@ def cst(con, sf):
ssf(self.temp_wall_shell[t, z], sf_T_shell)
cst(self.temp_wall_shell_eqn[t, z], sf_T_shell)

sf_conv_heat_transfer_coeff_shell = gsf(self.conv_heat_transfer_coeff_shell[t, z])
sf_conv_heat_transfer_coeff_shell = gsf(
self.conv_heat_transfer_coeff_shell[t, z]
)
s_Q_shell = sgsf(
shell.heat[t, z],
sf_conv_heat_transfer_coeff_shell * sf_area_per_length_shell * sf_T_shell,
sf_conv_heat_transfer_coeff_shell
* sf_area_per_length_shell
* sf_T_shell,
)
cst(
self.heat_shell_eqn[t, z], s_Q_shell * value(self.length_flow_shell)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,10 @@ def length_flow_shell_eqn(b):
def area_flow_shell_eqn(b):
return (
b.length_flow_shell * b.area_flow_shell
== b.length_tube_seg * b.length_flow_shell * b.pitch_y * b.number_columns_per_pass
== b.length_tube_seg
* b.length_flow_shell
* b.pitch_y
* b.number_columns_per_pass
- b.number_columns_per_pass
* b.nrow_tube
* 0.25
Expand Down Expand Up @@ -169,7 +172,11 @@ def length_flow_tube_eqn(b):
def area_flow_tube_eqn(b):
return (
b.area_flow_tube
== 0.25 * const.pi * b.di_tube**2.0 * b.number_columns_per_pass * b.number_rows_per_pass
== 0.25
* const.pi
* b.di_tube**2.0
* b.number_columns_per_pass
* b.number_rows_per_pass
)


Expand Down Expand Up @@ -702,9 +709,13 @@ def cst(con, sf):
cst(blk.N_Nu_shell_eqn[t, z], sf_N_Nu_shell)

sf_conv_heat_transfer_coeff_shell = sgsf(
blk.conv_heat_transfer_coeff_shell[t, z], sf_N_Nu_shell * sf_k_shell / sf_do_tube
blk.conv_heat_transfer_coeff_shell[t, z],
sf_N_Nu_shell * sf_k_shell / sf_do_tube,
)
cst(
blk.conv_heat_transfer_coeff_shell_eqn[t, z],
sf_conv_heat_transfer_coeff_shell * sf_do_tube,
)
cst(blk.conv_heat_transfer_coeff_shell_eqn[t, z], sf_conv_heat_transfer_coeff_shell * sf_do_tube)

# FIXME estimate from parameters
if blk.config.has_holdup:
Expand Down Expand Up @@ -751,6 +762,10 @@ def cst(con, sf):
cst(blk.N_Nu_tube_eqn[t, z], sf_N_Nu_tube)

sf_heat_transfer_coeff_tube = sgsf(
blk.heat_transfer_coeff_tube[t, z], sf_N_Nu_tube * sf_k_tube / sf_di_tube
blk.heat_transfer_coeff_tube[t, z],
sf_N_Nu_tube * sf_k_tube / sf_di_tube,
)
cst(
blk.heat_transfer_coeff_tube_eqn[t, z],
sf_heat_transfer_coeff_tube * sf_di_tube,
)
cst(blk.heat_transfer_coeff_tube_eqn[t, z], sf_heat_transfer_coeff_tube * sf_di_tube)
8 changes: 7 additions & 1 deletion idaes/models_extra/power_generation/unit_models/heater_1D.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,12 @@

__author__ = "Jinliang Ma, Douglas Allan"


class Heater1DInitializer(SingleControlVolumeUnitInitializer):
"""
Initializer for Heater 1D units.
"""

def initialize_main_model(
self,
model: Block,
Expand Down Expand Up @@ -144,6 +146,7 @@ def initialize_main_model(

return res


@declare_process_block_class("Heater1D")
class Heater1DData(UnitModelBlockData):
"""Standard Trim Heater Model Class Class."""
Expand Down Expand Up @@ -510,7 +513,10 @@ def cst(con, sf):
for t in self.flowsheet().time:
for z in self.control_volume.length_domain:
sf_hconv_conv = gsf(self.conv_heat_transfer_coeff_shell[t, z])
cst(self.conv_heat_transfer_coeff_shell_eqn[t, z], sf_hconv_conv * sf_d_tube)
cst(
self.conv_heat_transfer_coeff_shell_eqn[t, z],
sf_hconv_conv * sf_d_tube,
)

sf_T = gsf(self.control_volume.properties[t, z].temperature)
ssf(self.temp_wall_shell[t, z], sf_T)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
)
from idaes.models_extra.power_generation.unit_models import (
CrossFlowHeatExchanger1D,
CrossFlowHeatExchanger1DInitializer
CrossFlowHeatExchanger1DInitializer,
)
import idaes.core.util.model_statistics as mstat
from idaes.core.util.model_statistics import degrees_of_freedom
Expand Down Expand Up @@ -215,8 +215,7 @@ def test_initialization(model_no_dP):
_check_model_statistics(m, deltaP=False)

initializer = m.fs.heat_exchanger.default_initializer(
solver="ipopt",
solver_options=optarg
solver="ipopt", solver_options=optarg
)
assert isinstance(initializer, CrossFlowHeatExchanger1DInitializer)
initializer.initialize(model=m.fs.heat_exchanger)
Expand Down Expand Up @@ -250,8 +249,7 @@ def test_initialization_dP(model_dP):
_check_model_statistics(m, deltaP=True)

initializer = m.fs.heat_exchanger.default_initializer(
solver="ipopt",
solver_options=optarg
solver="ipopt", solver_options=optarg
)
assert isinstance(initializer, CrossFlowHeatExchanger1DInitializer)
initializer.initialize(m.fs.heat_exchanger)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,10 @@
get_prop,
EosType,
)
from idaes.models_extra.power_generation.unit_models import Heater1D, Heater1DInitializer
from idaes.models_extra.power_generation.unit_models import (
Heater1D,
Heater1DInitializer,
)
import idaes.core.util.model_statistics as mstat
from idaes.core.util.model_statistics import degrees_of_freedom
from idaes.core.solvers import get_solver
Expand Down Expand Up @@ -178,10 +181,7 @@ def test_initialization(model_no_dP):
assert degrees_of_freedom(m) == 0
_check_model_statistics(m, deltaP=False)

initializer = m.fs.heater.default_initializer(
solver="ipopt",
solver_options=optarg
)
initializer = m.fs.heater.default_initializer(solver="ipopt", solver_options=optarg)
assert isinstance(initializer, Heater1DInitializer)
initializer.initialize(model=m.fs.heater)

Expand Down Expand Up @@ -210,10 +210,7 @@ def test_initialization_dP(model_dP):
assert degrees_of_freedom(m) == 0
_check_model_statistics(m, deltaP=True)

initializer = m.fs.heater.default_initializer(
solver="ipopt",
solver_options=optarg
)
initializer = m.fs.heater.default_initializer(solver="ipopt", solver_options=optarg)
assert isinstance(initializer, Heater1DInitializer)
initializer.initialize(model=m.fs.heater)

Expand Down

0 comments on commit ad4dddf

Please sign in to comment.