Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Ok-landscape
GitHub Repository: Ok-landscape/computational-pipeline
Path: blob/main/latex-templates/templates/chemical-engineering/mass_transfer.tex
51 views
unlisted
1
\documentclass[11pt,a4paper]{article}
2
\usepackage[utf8]{inputenc}
3
\usepackage[T1]{fontenc}
4
\usepackage{amsmath,amssymb}
5
\usepackage{graphicx}
6
\usepackage{booktabs}
7
\usepackage{siunitx}
8
\usepackage{geometry}
9
\geometry{margin=1in}
10
\usepackage{pythontex}
11
\usepackage{hyperref}
12
\usepackage{float}
13
14
\title{Mass Transfer\\Diffusion and Convective Transport}
15
\author{Chemical Engineering Research Group}
16
\date{\today}
17
18
\begin{document}
19
\maketitle
20
21
\begin{abstract}
22
Mass transfer describes the movement of chemical species due to concentration gradients (diffusion) and bulk fluid motion (convection). This computational analysis examines Fick's laws of diffusion, film theory mass transfer coefficients, and packed column design for gas-liquid absorption. Applications include chemical reactors, separation processes, and biological systems. We present transient diffusion solutions, dimensionless correlations for mass transfer coefficients, and design calculations for industrial absorption columns.
23
\end{abstract}
24
25
\section{Introduction}
26
27
Mass transfer is fundamental to chemical engineering unit operations including distillation, absorption, extraction, adsorption, and membrane separation. The driving force for mass transfer is the chemical potential gradient, which for ideal systems reduces to a concentration gradient. Transport occurs by molecular diffusion (random thermal motion) and convective diffusion (bulk fluid motion enhancing contact). This analysis presents:
28
29
\begin{itemize}
30
\item Fick's first and second laws for steady and transient diffusion
31
\item Film theory and two-resistance model for interfacial mass transfer
32
\item Dimensionless correlations for liquid and gas-phase coefficients
33
\item Packed column design using transfer unit concepts (NTU-HTU method)
34
\item Transient diffusion solutions using error function and similarity variables
35
\end{itemize}
36
37
These computational tools enable design of separation equipment, prediction of mass transfer rates, and optimization of process conditions for enhanced transport.
38
39
\begin{pycode}
40
41
import numpy as np
42
import matplotlib.pyplot as plt
43
from scipy.integrate import odeint
44
from scipy.optimize import fsolve
45
from scipy.special import erfc
46
import scipy.stats as stats
47
plt.rcParams['text.usetex'] = True
48
plt.rcParams['font.family'] = 'serif'
49
50
\end{pycode}
51
52
\section{Fick's Law of Diffusion}
53
54
Fick's first law relates molar flux $J_A$ to the concentration gradient:
55
\begin{equation}
56
J_A = -D_{AB} \frac{dC_A}{dx}
57
\end{equation}
58
where $D_{AB}$ is the binary diffusivity (\si{m^2/s}). For steady-state diffusion through a stagnant film:
59
60
\begin{pycode}
61
# Fick's law: steady-state diffusion through film
62
L = 0.01 # film thickness (m)
63
x = np.linspace(0, L, 100) # distance coordinate
64
D_AB = 1.5e-9 # diffusivity of solute in water (m²/s)
65
C_0 = 1000 # concentration at x=0 (mol/m³)
66
C_L = 100 # concentration at x=L (mol/m³)
67
68
# Linear concentration profile (steady-state)
69
C = C_0 - (C_0 - C_L) * (x / L)
70
71
# Molar flux (constant in steady state)
72
J_A = -D_AB * (C_L - C_0) / L # mol/(m²·s)
73
74
# Store for inline reporting
75
avg_C = np.mean(C)
76
J_A_value = abs(J_A)
77
78
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5))
79
80
# Concentration profile
81
ax1.plot(x * 1e3, C, 'b-', linewidth=2.5, label='Steady-state profile')
82
ax1.axhline(C_0, color='r', linestyle='--', alpha=0.5, label='$C_0$')
83
ax1.axhline(C_L, color='g', linestyle='--', alpha=0.5, label='$C_L$')
84
ax1.set_xlabel('Distance (mm)', fontsize=12)
85
ax1.set_ylabel('Concentration (mol/m$^3$)', fontsize=12)
86
ax1.set_title("Fick's First Law: Steady Diffusion", fontsize=13, weight='bold')
87
ax1.legend()
88
ax1.grid(True, alpha=0.3)
89
90
# Flux visualization (constant)
91
ax2.axhline(J_A_value * 1e6, color='purple', linewidth=3, label=f'$J_A$ = {J_A_value*1e6:.3f} µmol/(m²·s)')
92
ax2.fill_between(x * 1e3, 0, J_A_value * 1e6, alpha=0.3, color='purple')
93
ax2.set_xlabel('Distance (mm)', fontsize=12)
94
ax2.set_ylabel('Molar Flux (µmol/(m²·s))', fontsize=12)
95
ax2.set_title('Constant Flux in Steady State', fontsize=13, weight='bold')
96
ax2.legend()
97
ax2.grid(True, alpha=0.3)
98
99
plt.tight_layout()
100
plt.savefig('mass_transfer_plot1.pdf', dpi=150, bbox_inches='tight')
101
plt.close()
102
\end{pycode}
103
104
\begin{figure}[H]
105
\centering
106
\includegraphics[width=0.95\textwidth]{mass_transfer_plot1.pdf}
107
\caption{Fick's first law for steady-state diffusion through a stagnant liquid film. Left: linear concentration profile from \py{f'{C_0:.0f}'} to \py{f'{C_L:.0f}'} mol/m³ over \py{f'{L*1e3:.1f}'} mm. Right: constant molar flux of \py{f'{J_A_value*1e6:.3f}'} µmol/(m²·s). The gradient $dC/dx$ is constant, resulting in uniform flux throughout the film. This model applies to absorption of sparingly soluble gases into liquids.}
108
\end{figure}
109
110
\section{Transient Diffusion: Fick's Second Law}
111
112
Fick's second law describes unsteady diffusion:
113
\begin{equation}
114
\frac{\partial C_A}{\partial t} = D_{AB} \frac{\partial^2 C_A}{\partial x^2}
115
\end{equation}
116
117
For semi-infinite medium with constant surface concentration, the solution involves the error function:
118
\begin{equation}
119
\frac{C_A - C_0}{C_s - C_0} = \text{erfc}\left(\frac{x}{2\sqrt{D_{AB}t}}\right)
120
\end{equation}
121
122
\begin{pycode}
123
# Transient diffusion into semi-infinite medium
124
x_trans = np.linspace(0, 0.05, 200) # distance (m)
125
D_AB = 1.5e-9 # diffusivity (m²/s)
126
C_0 = 0 # initial concentration (mol/m³)
127
C_s = 1000 # surface concentration (mol/m³)
128
129
# Time snapshots
130
times = [60, 300, 900, 3600, 14400] # seconds
131
colors = ['blue', 'green', 'orange', 'red', 'purple']
132
133
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5))
134
135
# Concentration profiles at different times
136
for t, color in zip(times, colors):
137
eta = x_trans / (2 * np.sqrt(D_AB * t)) # similarity variable
138
C = C_0 + (C_s - C_0) * erfc(eta)
139
ax1.plot(x_trans * 1e3, C, color=color, linewidth=2.5,
140
label=f't = {t/60:.1f} min' if t < 3600 else f't = {t/3600:.1f} hr')
141
142
ax1.set_xlabel('Distance from surface (mm)', fontsize=12)
143
ax1.set_ylabel('Concentration (mol/m$^3$)', fontsize=12)
144
ax1.set_title("Transient Diffusion Profiles", fontsize=13, weight='bold')
145
ax1.legend()
146
ax1.grid(True, alpha=0.3)
147
ax1.set_xlim([0, 50])
148
149
# Penetration depth (distance to 1% of surface concentration)
150
penetration = []
151
for t in times:
152
# erfc(eta) = 0.01 when eta 1.82
153
depth = 1.82 * 2 * np.sqrt(D_AB * t)
154
penetration.append(depth * 1e3) # convert to mm
155
156
ax2.plot(np.array(times)/60, penetration, 'o-', color='darkblue',
157
linewidth=2.5, markersize=8, label='Penetration depth')
158
ax2.set_xlabel('Time (min)', fontsize=12)
159
ax2.set_ylabel('Penetration depth (mm)', fontsize=12)
160
ax2.set_title('Diffusion Penetration (99\% criterion)', fontsize=13, weight='bold')
161
ax2.grid(True, alpha=0.3)
162
ax2.legend()
163
164
# Store for reporting
165
max_penetration = penetration[-1]
166
max_time = times[-1] / 3600
167
168
plt.tight_layout()
169
plt.savefig('mass_transfer_plot2.pdf', dpi=150, bbox_inches='tight')
170
plt.close()
171
\end{pycode}
172
173
\begin{figure}[H]
174
\centering
175
\includegraphics[width=0.95\textwidth]{mass_transfer_plot2.pdf}
176
\caption{Transient diffusion governed by Fick's second law with error function solution. Left: concentration profiles evolving from uniform initial state ($C_0$ = \py{f'{C_0:.0f}'} mol/m³) toward surface concentration ($C_s$ = \py{f'{C_s:.0f}'} mol/m³). Right: penetration depth grows as $\sqrt{t}$, reaching \py{f'{max_penetration:.2f}'} mm after \py{f'{max_time:.1f}'} hours. This analysis applies to drug diffusion in tissue, gas absorption in polymers, and contaminant transport in soil.}
177
\end{figure}
178
179
\section{Film Theory and Mass Transfer Coefficients}
180
181
The two-film theory models interfacial mass transfer as diffusion through stagnant films on each side of the interface. Mass transfer coefficients are defined as:
182
\begin{equation}
183
k_L = \frac{D_{AB}}{\delta_L} \quad \text{(liquid)}, \quad k_G = \frac{D_{AB}}{\delta_G} \quad \text{(gas)}
184
\end{equation}
185
186
For gas-liquid systems with Henry's law equilibrium ($y^* = m x$), the overall coefficient is:
187
\begin{equation}
188
\frac{1}{K_{OG}} = \frac{1}{k_G} + \frac{m}{k_L}
189
\end{equation}
190
191
\begin{pycode}
192
# Film theory: mass transfer coefficients
193
# Physical properties for CO2 absorption in water at 25°C
194
D_L = 1.92e-9 # CO2 diffusivity in water (m²/s)
195
D_G = 1.64e-5 # CO2 diffusivity in air (m²/s)
196
m = 0.83 # Henry's law constant (dimensionless)
197
198
# Film thicknesses (varied)
199
delta_L_range = np.linspace(10e-6, 500e-6, 100) # 10-500 microns
200
delta_G = 100e-6 # fixed gas film (100 microns)
201
202
# Mass transfer coefficients
203
k_L = D_L / delta_L_range # liquid-phase coefficient (m/s)
204
k_G = D_G / delta_G * np.ones_like(delta_L_range) # gas-phase (constant)
205
206
# Overall coefficient (gas-phase basis)
207
K_OG = 1 / (1/k_G + m/k_L)
208
209
# Resistance fractions
210
R_gas = (1/k_G) / (1/k_G + m/k_L) # gas-side resistance fraction
211
R_liq = (m/k_L) / (1/k_G + m/k_L) # liquid-side resistance fraction
212
213
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5))
214
215
# Mass transfer coefficients
216
ax1.plot(delta_L_range * 1e6, k_L * 1e5, 'b-', linewidth=2.5, label='$k_L$ (liquid)')
217
ax1.plot(delta_L_range * 1e6, k_G * 1e5, 'r--', linewidth=2.5, label='$k_G$ (gas)')
218
ax1.plot(delta_L_range * 1e6, K_OG * 1e5, 'g-', linewidth=3, label='$K_{OG}$ (overall)')
219
ax1.set_xlabel('Liquid film thickness (µm)', fontsize=12)
220
ax1.set_ylabel('Mass transfer coefficient (cm/s)', fontsize=12)
221
ax1.set_title('Film Theory Coefficients', fontsize=13, weight='bold')
222
ax1.legend()
223
ax1.grid(True, alpha=0.3)
224
ax1.set_yscale('log')
225
226
# Resistance distribution
227
ax2.plot(delta_L_range * 1e6, R_gas * 100, 'r-', linewidth=2.5, label='Gas-side')
228
ax2.plot(delta_L_range * 1e6, R_liq * 100, 'b-', linewidth=2.5, label='Liquid-side')
229
ax2.axhline(50, color='gray', linestyle='--', alpha=0.5)
230
ax2.set_xlabel('Liquid film thickness (µm)', fontsize=12)
231
ax2.set_ylabel('Resistance fraction (\%)', fontsize=12)
232
ax2.set_title('Controlling Resistance Analysis', fontsize=13, weight='bold')
233
ax2.legend()
234
ax2.grid(True, alpha=0.3)
235
ax2.set_ylim([0, 100])
236
237
# Store for reporting
238
k_L_ref = D_L / (100e-6) # at 100 micron film
239
K_OG_ref = 1 / (1/k_G[0] + m/k_L_ref)
240
241
plt.tight_layout()
242
plt.savefig('mass_transfer_plot3.pdf', dpi=150, bbox_inches='tight')
243
plt.close()
244
\end{pycode}
245
246
\begin{figure}[H]
247
\centering
248
\includegraphics[width=0.95\textwidth]{mass_transfer_plot3.pdf}
249
\caption{Film theory analysis for CO$_2$ absorption in water at 25°C. Left: mass transfer coefficients versus liquid film thickness. Gas-phase coefficient $k_G$ = \py{f'{k_G[0]*1e5:.3f}'} cm/s is constant, while liquid-phase $k_L$ varies inversely with $\delta_L$. Overall coefficient $K_{OG}$ = \py{f'{K_OG_ref*1e5:.3f}'} cm/s at 100 µm film. Right: resistance distribution shows transition from liquid-controlled (thick films) to gas-controlled (thin films). For sparingly soluble gases like CO$_2$, liquid-side resistance dominates.}
250
\end{figure}
251
252
\section{Packed Column Design: NTU-HTU Method}
253
254
Absorption column design uses the transfer unit concept. Number of transfer units (NTU):
255
\begin{equation}
256
N_{OG} = \int_{y_2}^{y_1} \frac{dy}{y - y^*} = \frac{1}{1 - m/A} \ln\left[\frac{y_1 - mx_2}{y_2 - mx_2}\left(1 - \frac{m}{A}\right) + \frac{m}{A}\right]
257
\end{equation}
258
259
Height of transfer unit (HTU):
260
\begin{equation}
261
H_{OG} = \frac{G}{K_{OG} a P}
262
\end{equation}
263
264
Column height: $Z = N_{OG} \times H_{OG}$
265
266
\begin{pycode}
267
# Packed column design for CO2 absorption
268
# Design conditions
269
y1 = 0.10 # inlet gas mole fraction CO2
270
y2 = 0.01 # outlet gas mole fraction CO2
271
x2 = 0.0 # inlet liquid mole fraction (pure water)
272
m = 0.83 # Henry's law slope
273
A = 1.5 # absorption factor L/(mG)
274
275
# Number of transfer units (Kremser equation)
276
if abs(A - m) > 0.01:
277
N_OG = (1/(1 - m/A)) * np.log((y1 - m*x2)/(y2 - m*x2) * (1 - m/A) + m/A)
278
else:
279
N_OG = (y1 - y2) / (y2 - m*x2) # simplified for A m
280
281
# Operating conditions
282
G = 1.5 # gas velocity (kmol/(m²·s))
283
P = 101325 # total pressure (Pa)
284
K_OG_design = 0.05 # overall coefficient (kmol/(m²·s))
285
a = 200 # specific area (m²/m³)
286
287
# Height of transfer unit
288
H_OG = G / (K_OG_design * a * P) * 1e3 # convert to m
289
290
# Column height
291
Z = N_OG * H_OG
292
293
# Operating line and equilibrium
294
x_op = np.linspace(x2, x2 + (y1 - y2)/(A*m), 100)
295
y_op = y2 + A * m * (x_op - x2)
296
y_eq = m * x_op
297
298
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5))
299
300
# McCabe-Thiele diagram
301
ax1.plot(x_op, y_op, 'b-', linewidth=2.5, label=f'Operating line (A={A:.1f})')
302
ax1.plot(x_op, y_eq, 'r--', linewidth=2.5, label=f'Equilibrium ($y^* = {m:.2f}x$)')
303
ax1.plot([x2, x2], [y2, y1], 'go', markersize=10, label='Terminal points')
304
ax1.fill_between(x_op, y_op, y_eq, where=(y_op >= y_eq), alpha=0.2, color='green', label='Driving force')
305
ax1.set_xlabel('Liquid mole fraction (x)', fontsize=12)
306
ax1.set_ylabel('Gas mole fraction (y)', fontsize=12)
307
ax1.set_title('McCabe-Thiele Diagram', fontsize=13, weight='bold')
308
ax1.legend()
309
ax1.grid(True, alpha=0.3)
310
ax1.set_xlim([0, max(x_op)*1.1])
311
ax1.set_ylim([0, y1*1.1])
312
313
# Column profile (gas composition vs height)
314
z_profile = np.linspace(0, Z, 50)
315
# Approximate exponential profile
316
y_profile = y2 + (y1 - y2) * np.exp(-z_profile / (Z/N_OG))
317
318
ax2.plot(y_profile * 100, z_profile, 'b-', linewidth=2.5)
319
ax2.axhline(Z, color='r', linestyle='--', linewidth=2, label=f'Total height = {Z:.2f} m')
320
ax2.axhline(H_OG, color='g', linestyle='--', linewidth=2, label=f'$H_{{OG}}$ = {H_OG:.2f} m')
321
ax2.set_xlabel('CO$_2$ concentration (\%)', fontsize=12)
322
ax2.set_ylabel('Height (m)', fontsize=12)
323
ax2.set_title('Axial Concentration Profile', fontsize=13, weight='bold')
324
ax2.legend()
325
ax2.grid(True, alpha=0.3)
326
ax2.invert_yaxis()
327
328
plt.tight_layout()
329
plt.savefig('mass_transfer_plot4.pdf', dpi=150, bbox_inches='tight')
330
plt.close()
331
\end{pycode}
332
333
\begin{figure}[H]
334
\centering
335
\includegraphics[width=0.95\textwidth]{mass_transfer_plot4.pdf}
336
\caption{Packed column design for CO$_2$ absorption using NTU-HTU method. Left: McCabe-Thiele diagram showing operating line (absorption factor $A$ = \py{f'{A:.1f}'}) and equilibrium curve. Green shaded area represents driving force $(y - y^*)$. Right: axial concentration profile showing CO$_2$ removal from \py{f'{y1*100:.1f}'}\% to \py{f'{y2*100:.1f}'}\%. Column requires $N_{OG}$ = \py{f'{N_OG:.2f}'} transfer units with $H_{OG}$ = \py{f'{H_OG:.2f}'} m, yielding total height $Z$ = \py{f'{Z:.2f}'} m.}
337
\end{figure}
338
339
\section{Dimensionless Correlations for Mass Transfer}
340
341
Empirical correlations predict mass transfer coefficients from dimensionless groups. Sherwood number:
342
\begin{equation}
343
Sh = \frac{k_L d}{D_{AB}} = a \cdot Re^b \cdot Sc^c
344
\end{equation}
345
where $Re = \rho u d / \mu$ (Reynolds), $Sc = \mu / (\rho D_{AB})$ (Schmidt).
346
347
For flow past spheres (Frossling correlation):
348
\begin{equation}
349
Sh = 2 + 0.6 Re^{1/2} Sc^{1/3}
350
\end{equation}
351
352
\begin{pycode}
353
# Dimensionless correlations: flow past spheres
354
# Physical properties (water at 25°C)
355
rho = 997 # density (kg/m³)
356
mu = 8.9e-4 # viscosity (Pa·s)
357
D_AB_corr = 1.5e-9 # diffusivity (m²/s)
358
359
Sc = mu / (rho * D_AB_corr) # Schmidt number
360
361
# Particle diameter and velocity ranges
362
d_particle = 1e-3 # particle diameter (1 mm)
363
u_range = np.logspace(-3, 0, 50) # velocity 0.001 to 1 m/s
364
365
# Reynolds and Sherwood numbers
366
Re = rho * u_range * d_particle / mu
367
Sh = 2 + 0.6 * Re**0.5 * Sc**(1/3) # Frossling correlation
368
369
# Mass transfer coefficient
370
k_L_corr = Sh * D_AB_corr / d_particle
371
372
# Compare to stagnant case
373
k_L_stagnant = 2 * D_AB_corr / d_particle # Sh = 2
374
375
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5))
376
377
# Sherwood vs Reynolds
378
ax1.loglog(Re, Sh, 'b-', linewidth=2.5, label='Frossling correlation')
379
ax1.axhline(2, color='r', linestyle='--', linewidth=2, label='Stagnant limit (Sh=2)')
380
ax1.set_xlabel('Reynolds number (Re)', fontsize=12)
381
ax1.set_ylabel('Sherwood number (Sh)', fontsize=12)
382
ax1.set_title('Dimensionless Mass Transfer Correlation', fontsize=13, weight='bold')
383
ax1.legend()
384
ax1.grid(True, alpha=0.3, which='both')
385
ax1.text(0.05, 0.95, f'Sc = {Sc:.0f}', transform=ax1.transAxes,
386
fontsize=11, verticalalignment='top',
387
bbox=dict(boxstyle='round', facecolor='wheat', alpha=0.5))
388
389
# Enhancement factor vs velocity
390
enhancement = k_L_corr / k_L_stagnant
391
ax2.semilogx(u_range, enhancement, 'g-', linewidth=2.5)
392
ax2.set_xlabel('Velocity (m/s)', fontsize=12)
393
ax2.set_ylabel('Enhancement factor ($k_L / k_{L,stagnant}$)', fontsize=12)
394
ax2.set_title('Convection Enhancement over Diffusion', fontsize=13, weight='bold')
395
ax2.grid(True, alpha=0.3)
396
ax2.axhline(1, color='r', linestyle='--', alpha=0.5)
397
398
# Store for reporting
399
Re_ref = rho * 0.1 * d_particle / mu
400
Sh_ref = 2 + 0.6 * Re_ref**0.5 * Sc**(1/3)
401
enhancement_ref = Sh_ref / 2
402
403
plt.tight_layout()
404
plt.savefig('mass_transfer_plot5.pdf', dpi=150, bbox_inches='tight')
405
plt.close()
406
\end{pycode}
407
408
\begin{figure}[H]
409
\centering
410
\includegraphics[width=0.95\textwidth]{mass_transfer_plot5.pdf}
411
\caption{Frossling correlation for mass transfer to spherical particles in water (Schmidt number $Sc$ = \py{f'{Sc:.0f}'}). Left: Sherwood number versus Reynolds number showing deviation from stagnant limit ($Sh = 2$) as convection intensifies. Right: enhancement factor quantifies improvement over pure diffusion. At $u$ = 0.1 m/s ($Re$ = \py{f'{Re_ref:.1f}'}), convection enhances mass transfer by \py{f'{enhancement_ref:.1f}'}× relative to stagnant conditions. This analysis applies to dissolution, crystallization, and heterogeneous catalysis.}
412
\end{figure}
413
414
\section{Batch Absorption: Time-Dependent Uptake}
415
416
For gas absorption into a well-mixed liquid batch with first-order reaction:
417
\begin{equation}
418
\frac{dC_L}{dt} = k_L a (C^* - C_L) - k_1 C_L
419
\end{equation}
420
where $k_L a$ is volumetric mass transfer coefficient and $k_1$ is reaction rate constant.
421
422
\begin{pycode}
423
# Batch absorption with chemical reaction
424
def batch_absorption(C, t, k_L_a, C_star, k_rxn):
425
"""ODE for batch gas absorption with first-order reaction"""
426
dCdt = k_L_a * (C_star - C) - k_rxn * C
427
return dCdt
428
429
# Parameters
430
k_L_a = 0.01 # volumetric coefficient (1/s)
431
C_star = 50 # saturation concentration (mol/m³)
432
k_rxn_values = [0, 0.005, 0.01, 0.02] # reaction rates (1/s)
433
C_0 = 0 # initial concentration
434
435
# Time span
436
t_batch = np.linspace(0, 600, 500) # 0-600 seconds
437
438
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5))
439
440
colors_rxn = ['blue', 'green', 'orange', 'red']
441
for k_rxn, color in zip(k_rxn_values, colors_rxn):
442
C_batch = odeint(batch_absorption, C_0, t_batch, args=(k_L_a, C_star, k_rxn))
443
444
label = 'Physical absorption' if k_rxn == 0 else f'$k_1$ = {k_rxn} s$^{{-1}}$'
445
ax1.plot(t_batch/60, C_batch, color=color, linewidth=2.5, label=label)
446
447
ax1.axhline(C_star, color='gray', linestyle='--', linewidth=2, alpha=0.5, label='$C^*$ (saturation)')
448
ax1.set_xlabel('Time (min)', fontsize=12)
449
ax1.set_ylabel('Liquid concentration (mol/m$^3$)', fontsize=12)
450
ax1.set_title('Batch Absorption with Reaction', fontsize=13, weight='bold')
451
ax1.legend()
452
ax1.grid(True, alpha=0.3)
453
454
# Enhancement factor vs reaction rate
455
k_rxn_range = np.logspace(-3, -1, 50)
456
# Hatta number: sqrt(k_rxn * D_AB) / k_L
457
D_AB_batch = 1.5e-9
458
delta_L_batch = 100e-6
459
k_L_batch = D_AB_batch / delta_L_batch
460
Ha = np.sqrt(k_rxn_range * D_AB_batch) / k_L_batch
461
462
# Enhancement factor (simplified for fast reaction)
463
E = np.where(Ha < 0.3, 1 + Ha**2/2, Ha) # asymptotic limits
464
465
ax2.loglog(Ha, E, 'b-', linewidth=2.5)
466
ax2.axhline(1, color='r', linestyle='--', linewidth=2, label='No enhancement')
467
ax2.set_xlabel('Hatta number (Ha)', fontsize=12)
468
ax2.set_ylabel('Enhancement factor (E)', fontsize=12)
469
ax2.set_title('Chemical Reaction Enhancement', fontsize=13, weight='bold')
470
ax2.legend()
471
ax2.grid(True, alpha=0.3, which='both')
472
ax2.text(0.05, 0.95, 'Slow rxn: $E \\approx 1$\nFast rxn: $E \\approx Ha$',
473
transform=ax2.transAxes, fontsize=10, verticalalignment='top',
474
bbox=dict(boxstyle='round', facecolor='wheat', alpha=0.5))
475
476
# Store for reporting
477
steady_state_physical = C_star
478
steady_state_reactive = C_star * k_L_a / (k_L_a + k_rxn_values[-1])
479
480
plt.tight_layout()
481
plt.savefig('mass_transfer_plot6.pdf', dpi=150, bbox_inches='tight')
482
plt.close()
483
\end{pycode}
484
485
\begin{figure}[H]
486
\centering
487
\includegraphics[width=0.95\textwidth]{mass_transfer_plot6.pdf}
488
\caption{Batch gas absorption with simultaneous chemical reaction. Left: liquid concentration evolution for different reaction rates. Physical absorption approaches saturation ($C^*$ = \py{f'{C_star:.0f}'} mol/m³), while reactive absorption reaches lower steady state due to consumption. At $k_1$ = \py{f'{k_rxn_values[-1]}'} s$^{-1}$, equilibrium drops to \py{f'{steady_state_reactive:.1f}'} mol/m³. Right: Hatta number analysis shows transition from diffusion-limited (Ha $<$ 0.3) to reaction-limited (Ha $>$ 3) regimes. Chemical reaction enhances effective mass transfer.}
489
\end{figure}
490
491
\section{Results Summary}
492
493
\begin{pycode}
494
results = [
495
['Fick diffusivity $D_{AB}$', f'{D_AB*1e9:.2f}', 'nm$^2$/s'],
496
['Film thickness $\\delta_L$', f'{L*1e3:.1f}', 'mm'],
497
['Molar flux $J_A$', f'{J_A_value*1e6:.3f}', r'$\mu$mol/(m$^2$$\cdot$s)'],
498
['Liquid coefficient $k_L$', f'{k_L_ref*1e5:.3f}', 'cm/s'],
499
['Gas coefficient $k_G$', f'{k_G[0]*1e5:.3f}', 'cm/s'],
500
['Overall coefficient $K_{OG}$', f'{K_OG_ref*1e5:.3f}', 'cm/s'],
501
['Schmidt number $Sc$', f'{Sc:.0f}', '--'],
502
['Transfer units $N_{OG}$', f'{N_OG:.2f}', '--'],
503
['HTU $H_{OG}$', f'{H_OG:.2f}', 'm'],
504
['Column height $Z$', f'{Z:.2f}', 'm'],
505
]
506
507
print(r'\begin{table}[H]')
508
print(r'\centering')
509
print(r'\caption{Summary of Mass Transfer Calculations}')
510
print(r'\begin{tabular}{@{}lcc@{}}')
511
print(r'\toprule')
512
print(r'Parameter & Value & Unit \\')
513
print(r'\midrule')
514
for row in results:
515
print(f"{row[0]} & {row[1]} & {row[2]} \\\\")
516
print(r'\bottomrule')
517
print(r'\end{tabular}')
518
print(r'\end{table}')
519
\end{pycode}
520
521
\section{Conclusions}
522
523
This computational analysis demonstrates fundamental mass transfer phenomena relevant to chemical process design:
524
525
\begin{itemize}
526
\item \textbf{Fick's laws:} Steady-state diffusion through a \py{f'{L*1e3:.1f}'} mm film yields constant flux of \py{f'{J_A_value*1e6:.3f}'} µmol/(m²·s). Transient diffusion exhibits characteristic $\sqrt{Dt}$ penetration depth, critical for design of batch processes and unsteady operations.
527
528
\item \textbf{Film theory:} Two-resistance model identifies controlling regime. For CO$_2$-water system, liquid-side resistance dominates ($k_L$ = \py{f'{k_L_ref*1e5:.3f}'} cm/s $<$ $k_G$ = \py{f'{k_G[0]*1e5:.3f}'} cm/s), motivating liquid-phase intensification strategies.
529
530
\item \textbf{Dimensionless correlations:} Frossling correlation predicts enhancement from convection. At Reynolds number \py{f'{Re_ref:.1f}'}, Sherwood number reaches \py{f'{Sh_ref:.2f}'}, representing \py{f'{enhancement_ref:.1f}'}× improvement over stagnant diffusion.
531
532
\item \textbf{Packed column design:} NTU-HTU method yields \py{f'{Z:.2f}'} m column height for 90\% CO$_2$ removal (\py{f'{N_OG:.2f}'} transfer units, $H_{OG}$ = \py{f'{H_OG:.2f}'} m). McCabe-Thiele analysis reveals driving force distribution along column height.
533
534
\item \textbf{Reactive absorption:} Chemical reaction enhances mass transfer via Hatta number mechanism. Fast reactions shift regime from diffusion-limited to reaction-limited, enabling process intensification through chemistry rather than hydrodynamics.
535
\end{itemize}
536
537
These computational methods enable rapid screening of operating conditions, equipment sizing, and process optimization without extensive pilot-plant trials. The Python-based framework integrates transport theory, thermodynamic equilibrium, and chemical kinetics for comprehensive mass transfer analysis.
538
539
\begin{thebibliography}{99}
540
541
\bibitem{bird2007}
542
R.B. Bird, W.E. Stewart, E.N. Lightfoot, \textit{Transport Phenomena}, 2nd ed., Wiley (2007).
543
544
\bibitem{treybal1980}
545
R.E. Treybal, \textit{Mass Transfer Operations}, 3rd ed., McGraw-Hill (1980).
546
547
\bibitem{cussler2009}
548
E.L. Cussler, \textit{Diffusion: Mass Transfer in Fluid Systems}, 3rd ed., Cambridge University Press (2009).
549
550
\bibitem{sherwood1975}
551
T.K. Sherwood, R.L. Pigford, C.R. Wilke, \textit{Mass Transfer}, McGraw-Hill (1975).
552
553
\bibitem{geankoplis2003}
554
C.J. Geankoplis, \textit{Transport Processes and Separation Process Principles}, 4th ed., Prentice Hall (2003).
555
556
\bibitem{seader2016}
557
J.D. Seader, E.J. Henley, D.K. Roper, \textit{Separation Process Principles}, 4th ed., Wiley (2016).
558
559
\bibitem{incropera2007}
560
F.P. Incropera, D.P. DeWitt, T.L. Bergman, A.S. Lavine, \textit{Fundamentals of Heat and Mass Transfer}, 6th ed., Wiley (2007).
561
562
\bibitem{deen2012}
563
W.M. Deen, \textit{Analysis of Transport Phenomena}, 2nd ed., Oxford University Press (2012).
564
565
\bibitem{welty2008}
566
J.R. Welty, C.E. Wicks, R.E. Wilson, G.L. Rorrer, \textit{Fundamentals of Momentum, Heat, and Mass Transfer}, 5th ed., Wiley (2008).
567
568
\bibitem{benitez2009}
569
J. Benitez, \textit{Principles and Modern Applications of Mass Transfer Operations}, 2nd ed., Wiley (2009).
570
571
\bibitem{higbie1935}
572
R. Higbie, ``The rate of absorption of a pure gas into a still liquid during short periods of exposure,'' Trans. AIChE \textbf{31}, 365-389 (1935).
573
574
\bibitem{danckwerts1951}
575
P.V. Danckwerts, ``Significance of liquid-film coefficients in gas absorption,'' Ind. Eng. Chem. \textbf{43}, 1460-1467 (1951).
576
577
\bibitem{astarita1967}
578
G. Astarita, \textit{Mass Transfer with Chemical Reaction}, Elsevier (1967).
579
580
\bibitem{taylor1993}
581
R. Taylor, R. Krishna, \textit{Multicomponent Mass Transfer}, Wiley (1993).
582
583
\bibitem{poling2001}
584
B.E. Poling, J.M. Prausnitz, J.P. O'Connell, \textit{The Properties of Gases and Liquids}, 5th ed., McGraw-Hill (2001).
585
586
\bibitem{wilke1955}
587
C.R. Wilke, C.Y. Lee, ``Estimation of diffusion coefficients for gases and vapors,'' Ind. Eng. Chem. \textbf{47}, 1253-1257 (1955).
588
589
\bibitem{onda1968}
590
K. Onda, H. Takeuchi, Y. Okumoto, ``Mass transfer coefficients between gas and liquid phases in packed columns,'' J. Chem. Eng. Japan \textbf{1}, 56-62 (1968).
591
592
\bibitem{frossling1938}
593
N. Frossling, ``Uber die Verdunstung fallender Tropfen,'' Gerlands Beitr. Geophys. \textbf{52}, 170-216 (1938).
594
595
\bibitem{vankrevelen1948}
596
D.W. van Krevelen, P.J. Hoftijzer, ``Kinetics of gas-liquid reactions,'' Rec. Trav. Chim. Pays-Bas \textbf{67}, 563-586 (1948).
597
598
\bibitem{westerterp1984}
599
K.R. Westerterp, W.P.M. van Swaaij, A.A.C.M. Beenackers, \textit{Chemical Reactor Design and Operation}, Wiley (1984).
600
601
\end{thebibliography}
602
603
\end{document}
604
605