A heat exchanger exampleΒΆ
within carbatpy
import numpy as np
import matplotlib.pyplot as plt
import carbatpy as cb
Trend not found! Check the environmentvariable TREND_DLL, TREND_PATH
Refprop is not installed!
Select two fluid (mixtures) and further conditions. H_DOT is the wanted heatflow rate ($\dot Q = $1 kW) here.
FLUID = "Propane * Pentane" # working fluid
FLS = "Methanol" # "Water" # secondary fluid
comp = [.50, 0.5]
flm = cb.fprop.FluidModel(FLUID)
myFluid = cb.fprop.Fluid(flm, comp)
secFlm = cb.fprop.FluidModel(FLS)
secFluid = cb.fprop.Fluid(secFlm, [1.])
D_TEMP_MIN = 5.0
# Condenser, working fluid fixes all, secondary output enthalpy can be varied:
SEC_TEMP_IN = 300.0 # K
SEC_TEMP_OUT_MAX = 370.0
SEC_PRES_IN = 5e5 # Pa
H_DOT = 1e3 # W
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
Cell In[2], line 4
2 FLS = "Methanol" # "Water" # secondary fluid
3 comp = [.50, 0.5]
----> 4 flm = cb.fprop.FluidModel(FLUID)
5 myFluid = cb.fprop.Fluid(flm, comp)
7 secFlm = cb.fprop.FluidModel(FLS)
File ~/checkouts/readthedocs.org/user_builds/carbatpy-010/checkouts/stable/src/carbatpy/models/fluids/fluid_props.py:111, in FluidModel.__init__(self, fluid, units, props, rp_inst, args)
109 if props == "REFPROP":
110 self.rp_instance = rp_inst
--> 111 self.set_rp_fluid()
112 elif props == "TREND":
113 self.set_tr_fluid()
File ~/checkouts/readthedocs.org/user_builds/carbatpy-010/checkouts/stable/src/carbatpy/models/fluids/fluid_props.py:132, in FluidModel.set_rp_fluid(self, modwf, name)
115 def set_rp_fluid(self, modwf=REFPROPFunctionLibrary, name='RPPREFIX'):
116 """
117 A new instance of Refpropdll for the given fluid. It can then be called
118 using fluid =""
(...)
129
130 """
--> 132 self.rp_instance = modwf(os.environ[name])
133 self.rp_instance.SETPATHdll(os.environ[name])
134 ierr = self.rp_instance.SETFLUIDSdll(self.fluid)
File ~/checkouts/readthedocs.org/user_builds/carbatpy-010/envs/stable/lib/python3.10/site-packages/ctREFPROP/ctREFPROP.py:161, in REFPROPFunctionLibrary(name, shared_extension)
159 raise ValueError('Too many loadable shared libraries were found in the folder "{name:s}"; obtained libraries were: {libs:s}. You must provide an absolute path to the shared library you would like to load'.format(name=name, libs=str(list(good_so))))
160 else:
--> 161 raise ValueError('"{name:s}" is neither a directory nor a file'.format(name=name))
163 # Now load the library
164 dll = loader_fcn(full_path)
ValueError: "C:/Program Files (x86)/REFPROP" is neither a directory nor a file
Now set the wanted states, determine the enthalpies (alwas the value state[2] below), needed as input
state_sec_out = secFluid.set_state([SEC_TEMP_OUT_MAX, SEC_PRES_IN], "TP")
state_sec_in = secFluid.set_state(
[SEC_TEMP_IN, SEC_PRES_IN], "TP") # this is the entering state
# working fluid
TEMP_SAT_VAP = SEC_TEMP_OUT_MAX + D_TEMP_MIN
state_in = myFluid.set_state(
[TEMP_SAT_VAP, 1.], "TQ") # find minimum pressure
WF_TEMP_IN = TEMP_SAT_VAP + D_TEMP_MIN
WF_TEMP_OUT = SEC_TEMP_IN + D_TEMP_MIN
state_out = myFluid.set_state([WF_TEMP_OUT, state_in[1]], "TP")
state_in = myFluid.set_state([myFluid.properties.pressure,
WF_TEMP_IN],
"PT")
Now we create an instance of the heat exchanger here: hex0. The input are the two Fluid-instances with the correct input states. The enthalpies of the wanted output states (one will be varied later to meet the minimum approach temperature). The pressures will be deduced from the actual values.
hex0 = cb.hex_th.StaticHeatExchanger([myFluid, secFluid], H_DOT, state_out[2],
state_sec_out[2],
d_temp_separation_min=D_TEMP_MIN)
It is called find_pinch, but it actually just varies the fluid mass flow rate ratio, until the minimum approach temperature(d_temp_separation_min) is reached, if it is possible for the given inlet, wanted outlet values. If not a warning is given.
hex0.find_pinch()
if hex0.warning > 0:
print(hex0.warning_message)
# now plotting can directly be done in pinch_calc 2024-05-24
fig_act, ax_act = plt.subplots(1)
PLOT_INFO = {"fig": fig_act, "ax": ax_act, "what": [2, 0], "col": ["r:", "ko"],
"label": ["work,c", "sec,c"], "x-shift": [0, 0]}
hex0.plot_info=PLOT_INFO
hex0.pinch_calc(verbose=True)
ax_act.legend()
Min T-distance 4.999, Mean T-distance 13.816
Min T-distance 4.9990002898326225, Mean T-distance 13.816388378792048
cond 4.999999996768054 7.880529723560983 4.9990002898326225 22.9172499170362
<matplotlib.legend.Legend at 0x1e7a76ec550>
print(hex0.warning, hex0.warning_message)
0 All o.k.
You can plot a second heat exchanger into the same plot by passing the figure information. But first we need a new instance of an heat exchanger, now an evaporator called hex1:
# Evaporator: ----------------------------
SEC_TEMP_IN = 300.0 # K
SEC_TEMP_OUT = 285
SEC_PRES_IN = 15e5
H_DOT = 1e3 # heat flow rate
extra = 2 # some additional temperature difference between both fluids at the entrance of the working fluid
# D_TEMP_SUPER = 5.
D_TEMP_MIN = 6.0 # Minimum approach temperature, allowed
state_sec_out = secFluid.set_state([SEC_TEMP_OUT, SEC_PRES_IN], "TP")
state_out = myFluid.set_state([SEC_TEMP_IN-D_TEMP_MIN - extra, 1.0], "TQ")
# the inlet states must be the last set_state before the hex is constructed, because it is further used by the heat exchanger:
state_sec_in = secFluid.set_state([SEC_TEMP_IN, SEC_PRES_IN], "TP")
state_in = myFluid.set_state(
[SEC_TEMP_OUT-D_TEMP_MIN - extra, state_out[1]], "TP")
print("state in (T,p,h,v,s,q,u):", state_in)
state in (T,p,h,v,s,q,u): [2.77000000e+02 1.04510486e+05 2.37193722e+05 2.21710771e-01
1.11102909e+03 5.28596305e-01 2.14022622e+05]
The new states are set, now we can do the calculations again.
hex1 = cb.hex_th.StaticHeatExchanger([myFluid, secFluid], H_DOT, state_out[2],
state_sec_out[2],
d_temp_separation_min=D_TEMP_MIN)
# ms1, d_tempall1, w1, s1 = hex1.pinch_calc()
factor_out = hex1.find_pinch()
if hex1.warning > 2:
print("Second heat exchanger:", hex1.warning_message, hex1.dt_min)
else:
# plotting in the same figure
PLOT_INFO = {"fig": fig_act, "ax": ax_act, "what": [2, 0], "col": ["k:", "bo"],
"label": ["work,e", "sec,e"], "x-shift": [0, 0]}
hex1.plot_info=PLOT_INFO
hex1.pinch_calc(verbose=True)
ax_act.legend()
Min T-distance 5.999, Mean T-distance -6.650
Min T-distance 5.9990002875455275, Mean T-distance -6.65042055546035
evap -8.000000001512547 -7.619450263333988 -5.9990002875455275 -8.000000001512547
By the way, the mean temperature difference between both curves is evaluated. If you have an idea of the mean heat transfer coefficient U, you can calculate the needed heat exchanger area:
u_heat_transfer = 500 # W/ (m2 K)
area_needed = H_DOT/ np.abs(hex1.dt_mean) /u_heat_transfer
print(f"Estimated HEX area: {area_needed:.3f} m^2")
Estimated HEX area: 0.301 m^2
fig_act