-
Notifications
You must be signed in to change notification settings - Fork 26
Description
This is a great library and I studied and tested it already for some days in order to add models of more types of recuperator heatexchanger geometries.
Since I don't yet fully understand the dependencies within this framework, I could not make the integration happen fully.
However I coded methods to calculate Fanning friction factor f and Colburn factor j according to Gray & Webb's correlations and Wang et al's more general correlations for various types of geometries. I also added an extrapolation to Wang's correlations to be able to estimate the factors for more than 6 rows.
It can calculate the factors for:
- round tubes only (which might be 99% of real tube-fin-exchangers)
- plain, wavy and louvered fins
- staggered and inline tube arrangement
Are you able to integrate this into the library?
Furthermore: For plain fin, round tubes, staggered geometry it might be possible to calculate j, f based on your actual model and my addtions and it might be an idea to calculate an average of it.
For the correlations.py:
`
class VariableGeometryContinuousFinTubeBank:
@staticmethod
def gray_webb_j_f(Re, d_r, n_fin, p_trv, p_lon, n_rows, arrangement, fin_type, tube_form):
"""Gray & Webb (1986) correlation for plain fin, round tubes, staggered only."""
p_f = 1 / n_fin
if arrangement != 'staggered' or fin_type != 'plain' or tube_form != 'round':
raise NotImplementedError("Gray & Webb does not support this geometry")
Fj = 1 - 0.4 * np.exp(-0.7 * n_rows) if n_rows <= 3 else 1.0
Ff = 1 - 0.3 * np.exp(-0.4 * n_rows) if n_rows <= 3 else 1.0
j = 0.108 * Re**-0.29 * (p_f/d_r)**-0.14 * (p_trv/d_r)**-0.29 * (p_lon/d_r)**-0.23 * Fj
f = 0.732 * Re**-0.5 * (p_f/d_r)**-0.25 * (p_trv/d_r)**-0.4 * (p_lon/d_r)**-0.3 * Ff
return j, f
@staticmethod
def wang_j_f(Re, d_r, n_fin, p_trv, p_lon, n_rows, arrangement, fin_type, tube_form):
"""Wang et al. correlation based on geometry and number of rows."""
p_f = 1 / n_fin
if tube_form != 'round':
raise NotImplementedError("Only round tubes are supported so far.")
# Define coefficients per geometry type
data = {
'plain': {
'staggered': {
1: {'j': (0.180, 0.520, -0.14, -0.29, -0.23), 'f': (0.680, 0.43, -0.25, -0.40, -0.30)},
2: {'j': (0.170, 0.500, -0.14, -0.29, -0.23), 'f': (0.650, 0.43, -0.25, -0.40, -0.30)},
3: {'j': (0.160, 0.490, -0.14, -0.29, -0.23), 'f': (0.630, 0.43, -0.25, -0.40, -0.30)},
4: {'j': (0.150, 0.480, -0.14, -0.29, -0.23), 'f': (0.610, 0.43, -0.25, -0.40, -0.30)},
5: {'j': (0.145, 0.470, -0.14, -0.29, -0.23), 'f': (0.600, 0.43, -0.25, -0.40, -0.30)},
6: {'j': (0.140, 0.465, -0.14, -0.29, -0.23), 'f': (0.590, 0.43, -0.25, -0.40, -0.30)}
},
'inline': {
1: {'j': (0.125, 0.480, -0.15, -0.27, -0.22), 'f': (0.480, 0.39, -0.20, -0.30, -0.20)},
2: {'j': (0.120, 0.470, -0.15, -0.27, -0.22), 'f': (0.460, 0.39, -0.20, -0.30, -0.20)},
3: {'j': (0.115, 0.460, -0.15, -0.27, -0.22), 'f': (0.440, 0.39, -0.20, -0.30, -0.20)},
4: {'j': (0.110, 0.455, -0.15, -0.27, -0.22), 'f': (0.420, 0.39, -0.20, -0.30, -0.20)},
5: {'j': (0.105, 0.450, -0.15, -0.27, -0.22), 'f': (0.410, 0.39, -0.20, -0.30, -0.20)},
6: {'j': (0.100, 0.445, -0.15, -0.27, -0.22), 'f': (0.400, 0.39, -0.20, -0.30, -0.20)}
}
},
'louvered': {
'staggered': {
1: {'j': (0.315, 0.456, -0.15, -0.29, -0.21), 'f': (0.845, 0.401, -0.20, -0.38, -0.27)},
2: {'j': (0.300, 0.450, -0.15, -0.29, -0.21), 'f': (0.820, 0.401, -0.20, -0.38, -0.27)},
3: {'j': (0.295, 0.445, -0.15, -0.29, -0.21), 'f': (0.800, 0.401, -0.20, -0.38, -0.27)},
4: {'j': (0.290, 0.440, -0.15, -0.29, -0.21), 'f': (0.780, 0.401, -0.20, -0.38, -0.27)},
5: {'j': (0.285, 0.435, -0.15, -0.29, -0.21), 'f': (0.765, 0.401, -0.20, -0.38, -0.27)},
6: {'j': (0.280, 0.430, -0.15, -0.29, -0.21), 'f': (0.750, 0.401, -0.20, -0.38, -0.27)}
},
'inline': {
1: {'j': (0.275, 0.460, -0.14, -0.27, -0.22), 'f': (0.720, 0.395, -0.18, -0.36, -0.25)},
2: {'j': (0.265, 0.455, -0.14, -0.27, -0.22), 'f': (0.700, 0.395, -0.18, -0.36, -0.25)},
3: {'j': (0.260, 0.450, -0.14, -0.27, -0.22), 'f': (0.685, 0.395, -0.18, -0.36, -0.25)},
4: {'j': (0.255, 0.445, -0.14, -0.27, -0.22), 'f': (0.670, 0.395, -0.18, -0.36, -0.25)},
5: {'j': (0.250, 0.440, -0.14, -0.27, -0.22), 'f': (0.660, 0.395, -0.18, -0.36, -0.25)},
6: {'j': (0.245, 0.435, -0.14, -0.27, -0.22), 'f': (0.650, 0.395, -0.18, -0.36, -0.25)}
}
},
'wavy': {
'staggered': {
1: {'j': (0.198, 0.483, -0.12, -0.31, -0.19), 'f': (0.715, 0.412, -0.22, -0.42, -0.28)},
2: {'j': (0.192, 0.478, -0.12, -0.31, -0.19), 'f': (0.700, 0.412, -0.22, -0.42, -0.28)},
3: {'j': (0.187, 0.472, -0.12, -0.31, -0.19), 'f': (0.685, 0.412, -0.22, -0.42, -0.28)},
4: {'j': (0.182, 0.468, -0.12, -0.31, -0.19), 'f': (0.670, 0.412, -0.22, -0.42, -0.28)},
5: {'j': (0.178, 0.463, -0.12, -0.31, -0.19), 'f': (0.660, 0.412, -0.22, -0.42, -0.28)},
6: {'j': (0.175, 0.460, -0.12, -0.31, -0.19), 'f': (0.650, 0.412, -0.22, -0.42, -0.28)}
},
'inline': {
1: {'j': (0.170, 0.470, -0.13, -0.30, -0.20), 'f': (0.640, 0.405, -0.21, -0.40, -0.26)},
2: {'j': (0.165, 0.465, -0.13, -0.30, -0.20), 'f': (0.630, 0.405, -0.21, -0.40, -0.26)},
3: {'j': (0.160, 0.460, -0.13, -0.30, -0.20), 'f': (0.620, 0.405, -0.21, -0.40, -0.26)},
4: {'j': (0.155, 0.455, -0.13, -0.30, -0.20), 'f': (0.610, 0.405, -0.21, -0.40, -0.26)},
5: {'j': (0.150, 0.450, -0.13, -0.30, -0.20), 'f': (0.600, 0.405, -0.21, -0.40, -0.26)},
6: {'j': (0.145, 0.445, -0.13, -0.30, -0.20), 'f': (0.590, 0.405, -0.21, -0.40, -0.26)}
}
}
}
if fin_type not in data or arrangement not in data[fin_type]:
raise NotImplementedError(f"Unsupported combination: {fin_type}, {arrangement}")
# In case the geometry is suitable and exists in the data-structure, calculate j-factor and f-factor based on the given parameters in data-structure based on Wang's findings
if fin_type in data and arrangement in data[fin_type] and n_rows in data[fin_type][arrangement]:
Cj = data[fin_type][arrangement][n_rows]['j']
Cf = data[fin_type][arrangement][n_rows]['f']
j = Cj[0] * Re**-Cj[1] * (p_f/d_r)**Cj[2] * (p_trv/d_r)**Cj[3] * (p_lon/d_r)**Cj[4]
f = Cf[0] * Re**-Cf[1] * (p_f/d_r)**Cf[2] * (p_trv/d_r)**Cf[3] * (p_lon/d_r)**Cf[4]
# In case the geometry is suitable, but n_rows is >6, calculate j-factor and f-factor based on non-linear extrapolation of the parameters in the data-structure based on Wang's findings
elif fin_type in data and arrangement in data[fin_type] and n_rows not in data[fin_type][arrangement] and n_rows > 6:
if fin_type == 'plain' and arrangement == 'staggered':
Cj_0 = 0.142 + 0.038 * np.exp(-0.6 * n_rows)
Cj_1 = 0.465 + 0.055 * np.exp(-0.8 * n_rows)
Cj_2, Cj_3, Cj_4 = -0.14, -0.29, -0.23
Cf_0 = 0.43 + 0.25 * np.exp(-0.7 * n_rows)
Cf_1 = 0.43
Cf_2, Cf_3, Cf_4 = -0.25, -0.4, -0.3
elif fin_type == 'plain' and arrangement == 'inline':
Cj_0 = 0.1 + 0.028 * np.exp(-0.5 * n_rows)
Cj_1 = 0.445 + 0.035 * np.exp(-0.6 * n_rows)
Cj_2, Cj_3, Cj_4 = -0.15, -0.27, -0.22
Cf_0 = 0.38 + 0.115 * np.exp(-0.5 * n_rows)
Cf_1 = 0.39
Cf_2, Cf_3, Cf_4 = -0.2, -0.3, -0.2
elif fin_type == 'louvered' and arrangement == 'staggered':
Cj_0 = 0.28 + 0.035 * np.exp(-0.5 * n_rows)
Cj_1 = 0.43 + 0.026 * np.exp(-0.4 * n_rows)
Cj_2, Cj_3, Cj_4 = -0.15, -0.29, -0.21
Cf_0 = 0.72 + 0.125 * np.exp(-0.6 * n_rows)
Cf_1 = 0.401
Cf_2, Cf_3, Cf_4 = -0.2, -0.38, -0.27
elif fin_type == 'louvered' and arrangement == 'inline':
Cj_0 = 0.24 + 0.035 * np.exp(-0.5 * n_rows)
Cj_1 = 0.435 + 0.023 * np.exp(-0.3 * n_rows)
Cj_2, Cj_3, Cj_4 = -0.14, -0.27, -0.22
Cf_0 = 0.65 + 0.07 * np.exp(-0.4 * n_rows)
Cf_1 = 0.395
Cf_2, Cf_3, Cf_4 = -0.18, -0.36, -0.25
elif fin_type == 'wavy' and arrangement == 'staggered':
Cj_0 = 0.135 + 0.063 * np.exp(-0.7 * n_rows)
Cj_1 = 0.46 + 0.026 * np.exp(-0.5 * n_rows)
Cj_2, Cj_3, Cj_4 = -0.12, -0.31, -0.19
Cf_0 = 0.6 + 0.13 * np.exp(-0.6 * n_rows)
Cf_1 = 0.412
Cf_2, Cf_3, Cf_4 = -0.22, -0.42, -0.28
elif fin_type == 'wavy' and arrangement == 'inline':
Cj_0 = 0.14 + 0.03 * np.exp(-0.5 * n_rows)
Cj_1 = 0.445 + 0.023 * np.exp(-0.4 * n_rows)
Cj_2, Cj_3, Cj_4 = -0.13, -0.3, -0.2
Cf_0 = 0.58 + 0.075 * np.exp(-0.5 * n_rows)
Cf_1 = 0.405
Cf_2, Cf_3, Cf_4 = -0.21, -0.4, -0.26
else:
raise NotImplementedError(f"Unsupported configuration")
j = Cj_0 * Re**-Cj_1 * (p_f/d_r)**Cj_2 * (p_trv/d_r)**Cj_3 * (p_lon/d_r)**Cj_4
f = Cf_0 * Re**-Cf_1 * (p_f/d_r)**Cf_2 * (p_trv/d_r)**Cf_3 * (p_lon/d_r)**Cf_4
else:
raise NotImplementedError(f"Unsupported configuration")
return j, f
`