Learning Objectives
By completing this chapter, you will be able to:
- Define what a catalyst is and explain its role in chemical reactions
- Understand activation energy and how catalysts lower it
- Distinguish between homogeneous and heterogeneous catalysis
- Explain enzyme (biological) catalysis basics
- Apply key performance metrics: TOF, TON, selectivity, and stability
- Trace the historical development of catalysis from Berzelius to modern times
1.1 What is a Catalyst?
Definition
A catalyst is a substance that increases the rate of a chemical reaction without being consumed in the process. The catalyst participates in the reaction mechanism but is regenerated at the end, allowing it to catalyze multiple reaction cycles.
Berzelius (1835): "A catalyst is a substance that, by its mere presence, evokes chemical reactions that would not otherwise take place."
Key characteristics of catalysts:
- Not consumed: Regenerated after each catalytic cycle
- Lowers activation energy: Provides an alternative reaction pathway
- Does not change thermodynamics: Cannot make non-spontaneous reactions spontaneous
- Affects kinetics only: Changes reaction rate, not equilibrium position
Catalyst vs. Reactant
A catalyst participates in the reaction but is regenerated. A reactant is consumed and appears in the stoichiometric equation. The distinction is crucial: a reaction requires stoichiometric amounts of reactants but only catalytic amounts of catalyst.
The Catalytic Cycle
Every catalytic reaction follows a cycle where the catalyst:
- Binds to reactant(s) - adsorption or coordination
- Activates the reactant(s) - lowering activation energy
- Facilitates bond breaking/forming
- Releases product(s) - desorption
- Returns to original state - ready for next cycle
1.2 Activation Energy and Reaction Kinetics
The Arrhenius Equation
The reaction rate constant $k$ depends on temperature according to the Arrhenius equation:
$$k = A \cdot e^{-E_a / RT}$$Where:
- $k$ = rate constant
- $A$ = pre-exponential factor (frequency factor)
- $E_a$ = activation energy (J/mol)
- $R$ = gas constant (8.314 J/mol·K)
- $T$ = temperature (K)
How Catalysts Lower Activation Energy
Catalysts provide an alternative reaction pathway with a lower activation energy barrier. The overall thermodynamics ($\Delta G$) remains unchanged, but the kinetic barrier is reduced.
Code Example 1: Visualizing Activation Energy
"""
Visualize the effect of catalyst on activation energy
Shows reaction coordinate diagrams with and without catalyst
"""
import numpy as np
import matplotlib.pyplot as plt
# Reaction coordinate (arbitrary units)
x = np.linspace(0, 10, 200)
# Energy profiles
def energy_profile(x, Ea, delta_H):
"""Generate Gaussian-like energy profile"""
peak_pos = 5
width = 1.5
return Ea * np.exp(-(x - peak_pos)**2 / (2 * width**2)) + \
delta_H * (1 / (1 + np.exp(-2*(x - peak_pos))))
# Parameters
delta_H = -20 # Exothermic reaction (kJ/mol)
Ea_uncatalyzed = 80 # kJ/mol
Ea_catalyzed = 40 # kJ/mol
# Calculate profiles
E_uncatalyzed = energy_profile(x, Ea_uncatalyzed, delta_H)
E_catalyzed = energy_profile(x, Ea_catalyzed, delta_H)
# Normalize so reactants start at 0
E_uncatalyzed = E_uncatalyzed - E_uncatalyzed[0]
E_catalyzed = E_catalyzed - E_catalyzed[0]
# Plot
fig, ax = plt.subplots(figsize=(10, 6))
ax.plot(x, E_uncatalyzed, 'b-', linewidth=2, label='Uncatalyzed')
ax.plot(x, E_catalyzed, 'r-', linewidth=2, label='Catalyzed')
# Mark activation energies
ax.annotate('', xy=(5, max(E_uncatalyzed)), xytext=(5, 0),
arrowprops=dict(arrowstyle='<->', color='blue'))
ax.text(5.3, max(E_uncatalyzed)/2, f'Ea = {Ea_uncatalyzed} kJ/mol',
color='blue', fontsize=10)
ax.annotate('', xy=(5, max(E_catalyzed)), xytext=(5, 0),
arrowprops=dict(arrowstyle='<->', color='red'))
ax.text(5.3, max(E_catalyzed)/2 - 5, f'Ea = {Ea_catalyzed} kJ/mol',
color='red', fontsize=10)
# Labels and formatting
ax.axhline(y=0, color='gray', linestyle='--', alpha=0.5)
ax.axhline(y=delta_H, color='gray', linestyle='--', alpha=0.5)
ax.text(0.5, 2, 'Reactants', fontsize=11)
ax.text(8.5, delta_H + 2, 'Products', fontsize=11)
ax.text(9, delta_H/2, f'ΔH = {delta_H} kJ/mol', fontsize=10, color='green')
ax.set_xlabel('Reaction Coordinate', fontsize=12)
ax.set_ylabel('Energy (kJ/mol)', fontsize=12)
ax.set_title('Effect of Catalyst on Activation Energy', fontsize=14, fontweight='bold')
ax.legend(fontsize=11)
ax.set_xlim(0, 10)
ax.set_ylim(-30, 90)
ax.grid(alpha=0.3)
plt.tight_layout()
plt.show()
# Calculate rate enhancement
R = 8.314 # J/mol·K
T = 300 # K
k_ratio = np.exp((Ea_uncatalyzed - Ea_catalyzed) * 1000 / (R * T))
print(f"\nAt T = {T} K:")
print(f"Rate enhancement (k_cat / k_uncat) = {k_ratio:.2e}")
print(f"The catalyst speeds up the reaction by a factor of {k_ratio:.0f}!")
Output
At T = 300 K: Rate enhancement (k_cat / k_uncat) = 1.07e+07 The catalyst speeds up the reaction by a factor of 10,700,000!
A reduction of just 40 kJ/mol in activation energy results in a 10 million-fold increase in reaction rate at room temperature!
1.3 Homogeneous vs Heterogeneous Catalysis
Classification Overview
| Property | Homogeneous | Heterogeneous |
|---|---|---|
| Phase | Same phase as reactants (usually liquid) | Different phase (usually solid catalyst, gas/liquid reactants) |
| Active Sites | All atoms potentially active | Surface atoms only |
| Selectivity | Often higher | Can be lower |
| Separation | Difficult | Easy (filtration) |
| Regeneration | Often complex | Often possible |
| Examples | Wilkinson's catalyst, enzymes | Pt/Pd on alumina, zeolites |
Heterogeneous Catalysis: The Langmuir-Hinshelwood Mechanism
In heterogeneous catalysis, reactions occur on the catalyst surface following these steps:
- Adsorption: Reactants bind to surface active sites
- Surface Reaction: Adsorbed species react
- Desorption: Products leave the surface
The Langmuir adsorption isotherm describes surface coverage:
$$\theta = \frac{K \cdot P}{1 + K \cdot P}$$Where $\theta$ is the fractional surface coverage, $K$ is the adsorption equilibrium constant, and $P$ is the partial pressure of the adsorbate.
Code Example 2: Langmuir Adsorption Isotherm
"""
Visualize Langmuir adsorption isotherms for different adsorption strengths
Demonstrates how binding affinity affects surface coverage
"""
import numpy as np
import matplotlib.pyplot as plt
# Pressure range
P = np.linspace(0, 10, 200)
# Langmuir isotherm
def langmuir(P, K):
"""Calculate fractional surface coverage"""
return K * P / (1 + K * P)
# Different adsorption equilibrium constants
K_values = [0.1, 0.5, 1.0, 2.0, 5.0]
colors = plt.cm.viridis(np.linspace(0, 1, len(K_values)))
# Plot
fig, ax = plt.subplots(figsize=(10, 6))
for K, color in zip(K_values, colors):
theta = langmuir(P, K)
ax.plot(P, theta, color=color, linewidth=2, label=f'K = {K}')
ax.axhline(y=1, color='gray', linestyle='--', alpha=0.5, label='Monolayer')
ax.set_xlabel('Pressure (arbitrary units)', fontsize=12)
ax.set_ylabel('Surface Coverage θ', fontsize=12)
ax.set_title('Langmuir Adsorption Isotherm', fontsize=14, fontweight='bold')
ax.legend(title='Adsorption Constant', fontsize=10)
ax.set_xlim(0, 10)
ax.set_ylim(0, 1.1)
ax.grid(alpha=0.3)
# Add annotation
ax.annotate('Strong adsorption\n(high K)', xy=(2, 0.9), fontsize=10, color='purple')
ax.annotate('Weak adsorption\n(low K)', xy=(6, 0.4), fontsize=10, color='green')
plt.tight_layout()
plt.show()
# Calculate coverage at P = 1 for each K
print("\nSurface coverage at P = 1:")
for K in K_values:
theta = langmuir(1, K)
print(f" K = {K}: θ = {theta:.3f} ({theta*100:.1f}%)")
1.4 Enzyme Catalysis
Biological Catalysts
Enzymes are biological catalysts - proteins that catalyze specific biochemical reactions with remarkable efficiency and selectivity. Key features:
- High specificity: Each enzyme catalyzes a specific reaction
- Enormous rate enhancement: 106 to 1017 fold
- Mild conditions: Room temperature, neutral pH, aqueous solution
- Regulation: Activity can be controlled by inhibitors, activators
Michaelis-Menten Kinetics
Enzyme kinetics are described by the Michaelis-Menten equation:
$$v = \frac{V_{max} \cdot [S]}{K_M + [S]}$$Where:
- $v$ = reaction rate
- $V_{max}$ = maximum rate (at substrate saturation)
- $[S]$ = substrate concentration
- $K_M$ = Michaelis constant (substrate concentration at $v = V_{max}/2$)
Code Example 3: Michaelis-Menten Enzyme Kinetics
"""
Visualize Michaelis-Menten enzyme kinetics
Shows saturation behavior and Km determination
"""
import numpy as np
import matplotlib.pyplot as plt
# Substrate concentration
S = np.linspace(0, 100, 200)
# Michaelis-Menten equation
def michaelis_menten(S, Vmax, Km):
"""Calculate reaction velocity"""
return Vmax * S / (Km + S)
# Parameters for different enzymes
enzymes = {
'Carbonic Anhydrase': {'Vmax': 100, 'Km': 8},
'Chymotrypsin': {'Vmax': 80, 'Km': 25},
'Lysozyme': {'Vmax': 60, 'Km': 50}
}
# Plot
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(14, 5))
# Left: Michaelis-Menten plot
for name, params in enzymes.items():
v = michaelis_menten(S, params['Vmax'], params['Km'])
ax1.plot(S, v, linewidth=2, label=f"{name} (Km={params['Km']})")
# Mark Km and Vmax/2
ax1.axhline(y=params['Vmax']/2, color='gray', linestyle=':', alpha=0.3)
ax1.axvline(x=params['Km'], color='gray', linestyle=':', alpha=0.3)
ax1.set_xlabel('[Substrate] (μM)', fontsize=12)
ax1.set_ylabel('Reaction Rate v (μM/s)', fontsize=12)
ax1.set_title('Michaelis-Menten Kinetics', fontsize=14, fontweight='bold')
ax1.legend(fontsize=10)
ax1.set_xlim(0, 100)
ax1.grid(alpha=0.3)
# Right: Lineweaver-Burk plot (double reciprocal)
S_nonzero = S[1:] # Avoid division by zero
for name, params in enzymes.items():
v = michaelis_menten(S_nonzero, params['Vmax'], params['Km'])
ax2.plot(1/S_nonzero, 1/v, linewidth=2, label=name)
ax2.set_xlabel('1/[S] (1/μM)', fontsize=12)
ax2.set_ylabel('1/v (s/μM)', fontsize=12)
ax2.set_title('Lineweaver-Burk Plot', fontsize=14, fontweight='bold')
ax2.legend(fontsize=10)
ax2.set_xlim(-0.05, 0.3)
ax2.set_ylim(0, 0.05)
ax2.axhline(y=0, color='gray', linestyle='-', alpha=0.3)
ax2.axvline(x=0, color='gray', linestyle='-', alpha=0.3)
ax2.grid(alpha=0.3)
plt.tight_layout()
plt.show()
# Display enzyme comparison
print("\nEnzyme Kinetic Parameters:")
print("-" * 50)
for name, params in enzymes.items():
kcat = params['Vmax'] / 0.001 # Assuming [E] = 1 nM
efficiency = kcat / params['Km']
print(f"{name}:")
print(f" Km = {params['Km']} μM")
print(f" Vmax = {params['Vmax']} μM/s")
print(f" Catalytic efficiency (kcat/Km) ∝ {1/params['Km']:.3f}")
1.5 Catalyst Performance Metrics
Key Performance Indicators
| Metric | Definition | Formula | Units |
|---|---|---|---|
| Turnover Number (TON) | Total moles of product per mole of catalyst | $\text{TON} = \frac{n_{product}}{n_{catalyst}}$ | dimensionless |
| Turnover Frequency (TOF) | Moles of product per mole of catalyst per unit time | $\text{TOF} = \frac{\text{TON}}{t}$ | s-1 or h-1 |
| Selectivity | Fraction of desired product among all products | $S = \frac{n_{desired}}{n_{total}}$ | % or fraction |
| Conversion | Fraction of reactant converted | $X = \frac{n_0 - n}{n_0}$ | % or fraction |
| Yield | Fraction of desired product formed | $Y = X \times S$ | % or fraction |
Code Example 4: Calculating Catalyst Performance
"""
Calculate and compare catalyst performance metrics
Demonstrates TON, TOF, selectivity, and yield calculations
"""
import numpy as np
import matplotlib.pyplot as plt
class CatalystPerformance:
"""Calculate catalyst performance metrics"""
def __init__(self, name):
self.name = name
self.reactions = []
def add_reaction(self, time_h, n_catalyst_mol, n_reactant_initial,
n_reactant_final, n_desired_product, n_total_products):
"""Add reaction data"""
self.reactions.append({
'time': time_h,
'n_cat': n_catalyst_mol,
'n_react_0': n_reactant_initial,
'n_react': n_reactant_final,
'n_desired': n_desired_product,
'n_total': n_total_products
})
def calculate_metrics(self):
"""Calculate all performance metrics"""
results = []
for rxn in self.reactions:
ton = rxn['n_desired'] / rxn['n_cat']
tof = ton / rxn['time']
conversion = (rxn['n_react_0'] - rxn['n_react']) / rxn['n_react_0']
selectivity = rxn['n_desired'] / rxn['n_total'] if rxn['n_total'] > 0 else 0
yield_val = conversion * selectivity
results.append({
'time': rxn['time'],
'TON': ton,
'TOF': tof,
'Conversion': conversion,
'Selectivity': selectivity,
'Yield': yield_val
})
return results
# Example: Compare three catalysts for CO2 hydrogenation
catalysts = []
# Catalyst A: Ru/TiO2
cat_a = CatalystPerformance("Ru/TiO2")
cat_a.add_reaction(time_h=2, n_catalyst_mol=1e-5, n_reactant_initial=0.1,
n_reactant_final=0.03, n_desired_product=0.06, n_total_products=0.07)
catalysts.append(cat_a)
# Catalyst B: Pd/C
cat_b = CatalystPerformance("Pd/C")
cat_b.add_reaction(time_h=2, n_catalyst_mol=1e-5, n_reactant_initial=0.1,
n_reactant_final=0.05, n_desired_product=0.04, n_total_products=0.05)
catalysts.append(cat_b)
# Catalyst C: Cu/ZnO
cat_c = CatalystPerformance("Cu/ZnO")
cat_c.add_reaction(time_h=2, n_catalyst_mol=1e-5, n_reactant_initial=0.1,
n_reactant_final=0.02, n_desired_product=0.075, n_total_products=0.08)
catalysts.append(cat_c)
# Calculate and display metrics
print("Catalyst Performance Comparison (CO2 Hydrogenation)")
print("=" * 70)
print(f"{'Catalyst':<15} {'TON':>10} {'TOF (h⁻¹)':>12} {'Conv. (%)':>10} {'Sel. (%)':>10} {'Yield (%)':>10}")
print("-" * 70)
metrics_data = {}
for cat in catalysts:
metrics = cat.calculate_metrics()[0]
metrics_data[cat.name] = metrics
print(f"{cat.name:<15} {metrics['TON']:>10.0f} {metrics['TOF']:>12.0f} "
f"{metrics['Conversion']*100:>10.1f} {metrics['Selectivity']*100:>10.1f} "
f"{metrics['Yield']*100:>10.1f}")
# Visualization
fig, axes = plt.subplots(1, 3, figsize=(14, 4))
names = list(metrics_data.keys())
colors = ['#f093fb', '#7c3aed', '#ec4899']
# TOF comparison
tof_values = [metrics_data[name]['TOF'] for name in names]
axes[0].bar(names, tof_values, color=colors)
axes[0].set_ylabel('TOF (h⁻¹)', fontsize=11)
axes[0].set_title('Turnover Frequency', fontsize=12, fontweight='bold')
# Selectivity comparison
sel_values = [metrics_data[name]['Selectivity'] * 100 for name in names]
axes[1].bar(names, sel_values, color=colors)
axes[1].set_ylabel('Selectivity (%)', fontsize=11)
axes[1].set_title('Selectivity', fontsize=12, fontweight='bold')
axes[1].set_ylim(0, 100)
# Yield comparison
yield_values = [metrics_data[name]['Yield'] * 100 for name in names]
axes[2].bar(names, yield_values, color=colors)
axes[2].set_ylabel('Yield (%)', fontsize=11)
axes[2].set_title('Overall Yield', fontsize=12, fontweight='bold')
axes[2].set_ylim(0, 100)
for ax in axes:
ax.grid(axis='y', alpha=0.3)
plt.tight_layout()
plt.show()
print("\nConclusion: Cu/ZnO shows the best overall performance with")
print("highest TOF, selectivity, and yield for this reaction.")
1.6 Historical Development of Catalysis
Timeline of Key Discoveries
| Year | Discovery | Scientist(s) | Impact |
|---|---|---|---|
| 1835 | Coined "catalysis" | Berzelius | Established the field |
| 1909 | Haber-Bosch process | Haber, Bosch | Nitrogen fixation, feeds billions |
| 1913 | Michaelis-Menten kinetics | Michaelis, Menten | Enzyme kinetics foundation |
| 1925 | Fischer-Tropsch synthesis | Fischer, Tropsch | Syngas to fuels |
| 1953 | Ziegler-Natta polymerization | Ziegler, Natta | Modern plastics industry |
| 1975 | Three-way catalytic converter | Multiple | Automotive emissions control |
| 2001 | Asymmetric catalysis Nobel Prize | Knowles, Noyori, Sharpless | Chiral synthesis |
| 2010 | Cross-coupling Nobel Prize | Heck, Negishi, Suzuki | Organic synthesis revolution |
| 2025 | MOFs Nobel Prize | Yaghi, Kitagawa, Ferey | Designed porous materials |
The Haber-Bosch Impact
The Haber-Bosch process for ammonia synthesis is often called the most important invention of the 20th century. It enables production of nitrogen fertilizers that feed approximately half of the world's population. Without catalysis, this reaction would be economically impossible - it requires breaking the extremely strong N≡N triple bond (945 kJ/mol).
Code Example 5: Catalyst Development Timeline
"""
Visualize the historical development of catalysis
Timeline showing major discoveries and their impact
"""
import matplotlib.pyplot as plt
import numpy as np
# Historical data
events = [
(1835, "Catalysis coined", "Berzelius", "Foundation"),
(1909, "Haber-Bosch", "Haber & Bosch", "Ammonia"),
(1925, "Fischer-Tropsch", "Fischer & Tropsch", "Fuels"),
(1953, "Ziegler-Natta", "Ziegler & Natta", "Polymers"),
(1975, "Three-way catalyst", "Industry", "Emissions"),
(2001, "Asymmetric catalysis", "Nobel Prize", "Pharma"),
(2010, "Cross-coupling", "Nobel Prize", "Synthesis"),
(2025, "MOFs", "Nobel Prize", "Materials"),
]
# Create figure
fig, ax = plt.subplots(figsize=(14, 6))
# Plot timeline
years = [e[0] for e in events]
y_positions = [1 if i % 2 == 0 else -1 for i in range(len(events))]
# Draw timeline
ax.axhline(y=0, color='gray', linewidth=2)
# Plot events
for i, (year, name, scientist, impact) in enumerate(events):
color = plt.cm.viridis(i / len(events))
ax.scatter(year, 0, s=150, c=[color], zorder=5, edgecolors='black')
y_offset = y_positions[i] * 0.3
ax.annotate(f"{year}\n{name}", xy=(year, 0), xytext=(year, y_offset),
fontsize=9, ha='center', va='bottom' if y_offset > 0 else 'top',
bbox=dict(boxstyle='round,pad=0.3', facecolor='white', edgecolor=color, alpha=0.9),
arrowprops=dict(arrowstyle='-', color=color))
ax.set_xlim(1820, 2035)
ax.set_ylim(-0.8, 0.8)
ax.set_xlabel('Year', fontsize=12)
ax.set_title('Historical Development of Catalysis', fontsize=14, fontweight='bold')
ax.set_yticks([])
# Add era labels
ax.axvspan(1830, 1910, alpha=0.1, color='blue', label='Classical Era')
ax.axvspan(1910, 1970, alpha=0.1, color='green', label='Industrial Era')
ax.axvspan(1970, 2030, alpha=0.1, color='red', label='Modern Era')
ax.legend(loc='upper left', fontsize=10)
plt.tight_layout()
plt.show()
# Print impact statistics
print("\nCatalysis Impact by the Numbers:")
print("-" * 50)
print("• 90% of chemical products involve catalysts")
print("• Haber-Bosch: Feeds 4+ billion people annually")
print("• Three-way catalyst: Reduces CO emissions by 95%")
print("• Ziegler-Natta: 150+ million tons polymers/year")
print("• Enzyme catalysis: 10^17 rate enhancement possible")
1.7 Chapter Summary
Key Takeaways
- Catalysts accelerate reactions by lowering activation energy without being consumed
- Homogeneous catalysts are in the same phase as reactants; heterogeneous catalysts are in a different phase
- Enzymes are biological catalysts with extraordinary specificity and efficiency
- TON, TOF, selectivity, and yield are key metrics for evaluating catalyst performance
- Catalysis has transformed industry, agriculture, and environmental protection
- The activation energy reduction leads to exponential rate enhancements (millions of times faster)
Exercises
Exercise 1: Activation Energy Calculation
A reaction has an activation energy of 75 kJ/mol without a catalyst and 50 kJ/mol with a catalyst. Calculate the ratio of rate constants at 25°C and 100°C.
Solution
import numpy as np
R = 8.314 # J/mol·K
Ea_uncat = 75000 # J/mol
Ea_cat = 50000 # J/mol
for T in [298, 373]: # 25°C and 100°C
k_ratio = np.exp((Ea_uncat - Ea_cat) / (R * T))
print(f"At T = {T-273}°C: k_cat/k_uncat = {k_ratio:.2e}")
Exercise 2: Michaelis-Menten Analysis
An enzyme has Km = 15 μM and Vmax = 100 μM/s. Calculate the reaction rate at [S] = 5, 15, 45, and 150 μM.
Exercise 3: Catalyst Comparison
Catalyst A has TON = 50,000 and TOF = 2,500 h⁻¹. Catalyst B has TON = 100,000 and TOF = 1,000 h⁻¹. Which catalyst would you choose for (a) continuous industrial process, (b) batch reaction with limited catalyst?
Next Chapter
In Chapter 2: Types of Catalysts, we will explore the major catalyst classes including metal catalysts, metal oxides, zeolites, MOFs (2025 Nobel Prize winners!), organometallic catalysts, and the revolutionary single-atom catalysts that achieve 100% atomic efficiency.