EN | JP

Chapter 4: Characterization and Analysis

BET, Spectroscopy, Microscopy, and ML-Assisted Interpretation

Reading time: 30-35 minutes Difficulty: Intermediate Code examples: 6

Learning Objectives

4.1 Surface Area Measurement: BET Method

The BET Equation

The Brunauer-Emmett-Teller (BET) method is the standard technique for measuring specific surface area. It extends the Langmuir monolayer model to multilayer adsorption:

$$\frac{P/P_0}{n(1-P/P_0)} = \frac{1}{n_m C} + \frac{C-1}{n_m C} \cdot \frac{P}{P_0}$$

Where:

BET Surface Area Calculation

$$S_{BET} = \frac{n_m \cdot N_A \cdot A_m}{m}$$

Where $N_A$ is Avogadro's number and $A_m$ is the cross-sectional area of the adsorbate molecule (0.162 nm² for N₂).

Code Example 1: BET Analysis

"""
BET surface area analysis from N2 adsorption data
Demonstrates linearization and surface area calculation
"""
import numpy as np
import matplotlib.pyplot as plt
from scipy import stats

# Simulated N2 adsorption data (P/P0, Volume adsorbed in cm³/g STP)
p_p0 = np.array([0.05, 0.10, 0.15, 0.20, 0.25, 0.30])
volume_ads = np.array([45.2, 52.1, 58.3, 64.8, 72.1, 80.5])

# BET linearization: y = (P/P0) / [V(1-P/P0)] vs x = P/P0
# Linear form: y = 1/(Vm*C) + [(C-1)/(Vm*C)] * x
y = p_p0 / (volume_ads * (1 - p_p0))
x = p_p0

# Linear regression
slope, intercept, r_value, p_value, std_err = stats.linregress(x, y)

# Calculate BET parameters
Vm = 1 / (slope + intercept)  # Monolayer volume (cm³/g STP)
C = 1 + slope / intercept      # BET constant

# Surface area calculation
# At STP: 1 mole of gas = 22,414 cm³
# N2 cross-sectional area: 0.162 nm² = 0.162e-18 m²
Na = 6.022e23
Am = 0.162e-18  # m²
V_molar = 22414  # cm³/mol at STP

S_BET = Vm * Na * Am / V_molar  # m²/g

# Create figure
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(14, 5))

# Left: Raw isotherm
ax1.scatter(p_p0, volume_ads, s=100, c='blue', edgecolors='black', zorder=5)
ax1.plot(p_p0, volume_ads, 'b-', linewidth=1.5, alpha=0.7)
ax1.set_xlabel('Relative Pressure P/P₀', fontsize=12)
ax1.set_ylabel('Volume Adsorbed (cm³/g STP)', fontsize=12)
ax1.set_title('N₂ Adsorption Isotherm', fontsize=13, fontweight='bold')
ax1.grid(alpha=0.3)
ax1.set_xlim(0, 0.35)

# Right: BET plot
ax2.scatter(x, y, s=100, c='red', edgecolors='black', zorder=5)
x_line = np.linspace(0, 0.35, 100)
y_line = slope * x_line + intercept
ax2.plot(x_line, y_line, 'r--', linewidth=2, label=f'y = {slope:.4f}x + {intercept:.5f}')
ax2.set_xlabel('P/P₀', fontsize=12)
ax2.set_ylabel('P/P₀ / [V(1-P/P₀)]', fontsize=12)
ax2.set_title('BET Plot (Linearized)', fontsize=13, fontweight='bold')
ax2.legend(fontsize=10)
ax2.grid(alpha=0.3)
ax2.set_xlim(0, 0.35)

# Add equation and results
textstr = f'$R^2$ = {r_value**2:.4f}\n$V_m$ = {Vm:.1f} cm³/g\nC = {C:.1f}\n$S_{{BET}}$ = {S_BET:.1f} m²/g'
ax2.text(0.05, 0.95, textstr, transform=ax2.transAxes, fontsize=11,
         verticalalignment='top', bbox=dict(boxstyle='round', facecolor='wheat'))

plt.tight_layout()
plt.show()

print("\nBET Analysis Results:")
print(f"• Monolayer volume (Vm): {Vm:.2f} cm³/g STP")
print(f"• BET constant (C): {C:.1f}")
print(f"• BET Surface Area: {S_BET:.1f} m²/g")
print(f"• R² of linear fit: {r_value**2:.4f}")

4.2 Active Site Identification: Chemisorption

Probe Molecules for Different Metals

Probe Target Sites Stoichiometry Information
H₂ Pt, Pd, Ni H:M = 1:1 Metal dispersion
CO Pt, Pd, Rh, Cu CO:M = 1:1 to 1:2 Metal surface area
O₂ Ag, Cu O:M = 1:1 Reactive oxygen
NH₃ Acid sites - Total acidity (TPD)
Pyridine Lewis/Brønsted acids - Acid type (FTIR)

Metal Dispersion

Metal dispersion is the fraction of metal atoms exposed on the surface:

$$D = \frac{\text{Surface metal atoms}}{\text{Total metal atoms}} = \frac{n_{chem} \cdot S_f}{n_{total}}$$

Where $S_f$ is the stoichiometry factor (e.g., 1 for H:Pt = 1:1).

Code Example 2: Dispersion and Particle Size

"""
Calculate metal dispersion and particle size from chemisorption data
"""
import numpy as np
import matplotlib.pyplot as plt

def calculate_dispersion(V_chem_cm3_g, metal_loading_wt_pct, metal_mw,
                         stoichiometry=1, VM=22414):
    """
    Calculate metal dispersion from chemisorption volume

    Args:
        V_chem_cm3_g: Chemisorbed volume (cm³/g catalyst at STP)
        metal_loading_wt_pct: Metal loading (wt%)
        metal_mw: Metal molecular weight (g/mol)
        stoichiometry: Chemisorption stoichiometry (probe:metal)
        VM: Molar volume at STP (cm³/mol)
    """
    # Moles of probe chemisorbed per g catalyst
    n_probe = V_chem_cm3_g / VM

    # Moles of surface metal atoms
    n_surface_metal = n_probe / stoichiometry

    # Total moles of metal in catalyst
    n_total_metal = (metal_loading_wt_pct / 100) / metal_mw

    # Dispersion
    D = n_surface_metal / n_total_metal

    return min(D, 1.0)

def dispersion_to_particle_size(D, metal='Pt'):
    """
    Estimate particle size from dispersion (spherical particles)
    d = 6 * V_atomic / (a * D)
    """
    # Atomic parameters (approximate)
    params = {
        'Pt': {'V_atomic': 15.1e-24, 'a': 8.0e-20},  # cm³, cm²
        'Pd': {'V_atomic': 14.7e-24, 'a': 7.9e-20},
        'Rh': {'V_atomic': 13.8e-24, 'a': 7.6e-20},
    }
    p = params.get(metal, params['Pt'])

    if D > 0:
        d_cm = 6 * p['V_atomic'] / (p['a'] * D)
        return d_cm * 1e7  # Convert to nm
    return np.inf

# Example: Pt/Al2O3 catalyst with 1 wt% Pt
metal_loading = 1.0  # wt%
metal_mw = 195.08    # g/mol for Pt

# Different chemisorption volumes
V_chem_values = np.linspace(0.05, 0.5, 50)

dispersions = [calculate_dispersion(V, metal_loading, metal_mw) for V in V_chem_values]
particle_sizes = [dispersion_to_particle_size(D) for D in dispersions]

# Create figure
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(14, 5))

# Left: Dispersion vs chemisorption volume
ax1.plot(V_chem_values, np.array(dispersions) * 100, 'b-', linewidth=2)
ax1.set_xlabel('H₂ Chemisorption (cm³/g STP)', fontsize=12)
ax1.set_ylabel('Dispersion (%)', fontsize=12)
ax1.set_title('Pt Dispersion vs Chemisorption', fontsize=13, fontweight='bold')
ax1.grid(alpha=0.3)
ax1.axhline(y=50, color='green', linestyle='--', alpha=0.5, label='50% dispersion')
ax1.legend()

# Right: Particle size vs dispersion
D_range = np.linspace(0.05, 1.0, 100)
sizes = [dispersion_to_particle_size(D) for D in D_range]

ax2.plot(np.array(D_range) * 100, sizes, 'r-', linewidth=2)
ax2.set_xlabel('Dispersion (%)', fontsize=12)
ax2.set_ylabel('Particle Size (nm)', fontsize=12)
ax2.set_title('Particle Size vs Dispersion', fontsize=13, fontweight='bold')
ax2.grid(alpha=0.3)
ax2.set_ylim(0, 20)

# Add size regions
ax2.axhspan(0, 2, alpha=0.2, color='green', label='Clusters (<2 nm)')
ax2.axhspan(2, 5, alpha=0.2, color='yellow', label='Small NPs (2-5 nm)')
ax2.axhspan(5, 20, alpha=0.2, color='orange', label='Large NPs (>5 nm)')
ax2.legend(loc='upper right', fontsize=9)

plt.tight_layout()
plt.show()

# Example calculation
V_example = 0.25
D_example = calculate_dispersion(V_example, metal_loading, metal_mw)
size_example = dispersion_to_particle_size(D_example)

print(f"\nExample: 1 wt% Pt/Al₂O₃ with V_chem = {V_example} cm³/g")
print(f"• Dispersion: {D_example*100:.1f}%")
print(f"• Estimated particle size: {size_example:.1f} nm")

4.3 Spectroscopic Techniques

X-ray Photoelectron Spectroscopy (XPS)

XPS provides information about surface composition and oxidation states:

Code Example 3: XPS Peak Analysis

"""
Simulate and analyze XPS spectrum for Pt catalyst
Demonstrates peak fitting and oxidation state identification
"""
import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit

def gaussian(x, amp, cen, wid):
    """Gaussian peak function"""
    return amp * np.exp(-(x - cen)**2 / (2 * wid**2))

def multi_gaussian(x, *params):
    """Multiple Gaussian peaks"""
    n_peaks = len(params) // 3
    y = np.zeros_like(x)
    for i in range(n_peaks):
        amp = params[3*i]
        cen = params[3*i + 1]
        wid = params[3*i + 2]
        y += gaussian(x, amp, cen, wid)
    return y

# Binding energy range for Pt 4f
BE = np.linspace(68, 82, 200)

# Simulate Pt 4f spectrum with Pt(0) and Pt(II) components
# Pt(0) 4f7/2: 71.0 eV, 4f5/2: 74.5 eV (spin-orbit splitting ~3.5 eV)
# Pt(II) 4f7/2: 72.5 eV, 4f5/2: 76.0 eV (shifted +1.5 eV)

# True parameters (what we're trying to recover)
true_params = [
    100, 71.0, 0.8,   # Pt(0) 4f7/2
    67, 74.5, 0.8,    # Pt(0) 4f5/2 (ratio 0.67 from degeneracy)
    40, 72.5, 1.0,    # Pt(II) 4f7/2
    27, 76.0, 1.0,    # Pt(II) 4f5/2
]

# Generate synthetic spectrum with noise
np.random.seed(42)
spectrum = multi_gaussian(BE, *true_params)
noise = np.random.normal(0, 3, len(BE))
spectrum_noisy = spectrum + noise
background = 5 + 0.5 * (BE - 68)  # Shirley-like background
spectrum_noisy += background

# Fit the spectrum (simplified - in practice, more sophisticated fitting is used)
initial_guess = [90, 71.2, 0.9, 60, 74.6, 0.9, 35, 72.8, 1.1, 23, 76.3, 1.1]
popt, pcov = curve_fit(lambda x, *p: multi_gaussian(x, *p) + 5 + 0.5*(x-68),
                       BE, spectrum_noisy, p0=initial_guess, maxfev=5000)

# Create figure
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(14, 5))

# Left: Raw spectrum with fit
ax1.plot(BE, spectrum_noisy, 'k-', linewidth=1.5, label='Experimental')
ax1.plot(BE, multi_gaussian(BE, *popt) + 5 + 0.5*(BE-68), 'r-',
         linewidth=2, label='Fitted')

# Individual components
colors = ['blue', 'blue', 'green', 'green']
labels = ['Pt(0) 4f₇/₂', 'Pt(0) 4f₅/₂', 'Pt(II) 4f₇/₂', 'Pt(II) 4f₅/₂']
for i in range(4):
    peak = gaussian(BE, popt[3*i], popt[3*i+1], popt[3*i+2])
    ax1.fill_between(BE, background, peak + background, alpha=0.3,
                     color=colors[i], label=labels[i])

ax1.set_xlabel('Binding Energy (eV)', fontsize=12)
ax1.set_ylabel('Intensity (a.u.)', fontsize=12)
ax1.set_title('Pt 4f XPS Spectrum', fontsize=13, fontweight='bold')
ax1.legend(fontsize=9, loc='upper left')
ax1.invert_xaxis()  # XPS convention: higher BE on left
ax1.grid(alpha=0.3)

# Right: Oxidation state quantification
pt0_area = popt[0] * popt[2] + popt[3] * popt[5]  # Pt(0) 4f7/2 + 4f5/2
pt2_area = popt[6] * popt[8] + popt[9] * popt[11]  # Pt(II)
total_area = pt0_area + pt2_area

pt0_pct = pt0_area / total_area * 100
pt2_pct = pt2_area / total_area * 100

categories = ['Pt(0)\nMetallic', 'Pt(II)\nOxidized']
values = [pt0_pct, pt2_pct]
colors_bar = ['#2196f3', '#4caf50']

bars = ax2.bar(categories, values, color=colors_bar, edgecolor='black', width=0.5)
ax2.set_ylabel('Relative Amount (%)', fontsize=12)
ax2.set_title('Pt Oxidation State Distribution', fontsize=13, fontweight='bold')
ax2.set_ylim(0, 100)

for bar, val in zip(bars, values):
    ax2.text(bar.get_x() + bar.get_width()/2, bar.get_height() + 2,
             f'{val:.1f}%', ha='center', fontsize=12, fontweight='bold')

plt.tight_layout()
plt.show()

print("\nXPS Analysis Results:")
print(f"• Pt(0) metallic: {pt0_pct:.1f}%")
print(f"• Pt(II) oxidized: {pt2_pct:.1f}%")
print(f"• Pt(0) 4f₇/₂ binding energy: {popt[1]:.2f} eV")
print(f"• Pt(II) 4f₇/₂ binding energy: {popt[7]:.2f} eV")

4.4 Microscopy Techniques

TEM and SEM

Technique Resolution Information Sample Prep
TEM ~0.1 nm Particle size, crystallinity, lattice fringes Thin samples (~100 nm)
STEM-HAADF ~0.1 nm Z-contrast imaging, single atoms Thin samples
SEM ~1-10 nm Surface morphology, porosity Conductive coating
EDX ~100 nm Elemental mapping Combined with TEM/SEM

Code Example 4: Particle Size Distribution Analysis

"""
Analyze particle size distribution from TEM data
Demonstrates histogram fitting and statistics
"""
import numpy as np
import matplotlib.pyplot as plt
from scipy import stats

# Simulated TEM particle size measurements (nm)
np.random.seed(123)
# Lognormal distribution (common for nanoparticles)
particle_sizes = np.random.lognormal(mean=1.0, sigma=0.4, size=200)
particle_sizes = particle_sizes[particle_sizes < 10]  # Remove outliers

# Calculate statistics
mean_size = np.mean(particle_sizes)
std_size = np.std(particle_sizes)
median_size = np.median(particle_sizes)
d10 = np.percentile(particle_sizes, 10)
d50 = np.percentile(particle_sizes, 50)
d90 = np.percentile(particle_sizes, 90)

# Create figure
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(14, 5))

# Left: Histogram with fitted distribution
n, bins, patches = ax1.hist(particle_sizes, bins=25, density=True,
                             alpha=0.7, color='steelblue', edgecolor='black')

# Fit lognormal distribution
shape, loc, scale = stats.lognorm.fit(particle_sizes, floc=0)
x_fit = np.linspace(0, 10, 200)
pdf_fit = stats.lognorm.pdf(x_fit, shape, loc, scale)
ax1.plot(x_fit, pdf_fit, 'r-', linewidth=2, label='Lognormal fit')

ax1.axvline(x=mean_size, color='green', linestyle='--', linewidth=2,
            label=f'Mean = {mean_size:.2f} nm')
ax1.axvline(x=median_size, color='orange', linestyle=':', linewidth=2,
            label=f'Median = {median_size:.2f} nm')

ax1.set_xlabel('Particle Size (nm)', fontsize=12)
ax1.set_ylabel('Probability Density', fontsize=12)
ax1.set_title('TEM Particle Size Distribution', fontsize=13, fontweight='bold')
ax1.legend(fontsize=9)
ax1.set_xlim(0, 8)
ax1.grid(alpha=0.3)

# Right: Cumulative distribution
sorted_sizes = np.sort(particle_sizes)
cumulative = np.arange(1, len(sorted_sizes) + 1) / len(sorted_sizes) * 100

ax2.plot(sorted_sizes, cumulative, 'b-', linewidth=2)
ax2.axhline(y=10, color='gray', linestyle='--', alpha=0.5)
ax2.axhline(y=50, color='gray', linestyle='--', alpha=0.5)
ax2.axhline(y=90, color='gray', linestyle='--', alpha=0.5)

ax2.scatter([d10, d50, d90], [10, 50, 90], s=100, c='red', zorder=5)
ax2.text(d10, 15, f'd₁₀={d10:.2f}', fontsize=10)
ax2.text(d50, 55, f'd₅₀={d50:.2f}', fontsize=10)
ax2.text(d90, 85, f'd₉₀={d90:.2f}', fontsize=10)

ax2.set_xlabel('Particle Size (nm)', fontsize=12)
ax2.set_ylabel('Cumulative %', fontsize=12)
ax2.set_title('Cumulative Size Distribution', fontsize=13, fontweight='bold')
ax2.grid(alpha=0.3)
ax2.set_xlim(0, 8)

plt.tight_layout()
plt.show()

print("\nTEM Particle Size Analysis:")
print(f"• Number of particles measured: {len(particle_sizes)}")
print(f"• Mean diameter: {mean_size:.2f} ± {std_size:.2f} nm")
print(f"• d₁₀/d₅₀/d₉₀: {d10:.2f}/{d50:.2f}/{d90:.2f} nm")
print(f"• Polydispersity index (PDI): {(d90-d10)/d50:.2f}")

4.5 Operando Spectroscopy

In Situ vs Operando

In situ: Measurements under controlled atmosphere/temperature without actual reaction. Operando: Measurements during actual catalytic reaction with simultaneous activity measurement. Operando provides direct structure-activity correlations.

Common Operando Techniques

Technique Information Time Resolution
Operando DRIFTS Surface adsorbates, intermediates Seconds
Operando XAS Oxidation state, coordination Seconds-minutes
Operando Raman Catalyst structure, adsorbates Seconds
Environmental TEM Morphology changes, sintering Sub-second

4.6 ML-Assisted Spectral Analysis

2025-2026: AI Revolution in Catalyst Characterization

Machine learning is transforming catalyst analysis by enabling automated spectral interpretation, reducing analysis time by 30-50%, and discovering hidden patterns in complex data.

Code Example 5: ML-Based Spectral Classification

"""
Machine learning classification of catalyst states from spectra
Demonstrates training and prediction for catalyst health monitoring
"""
import numpy as np
import matplotlib.pyplot as plt
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report, confusion_matrix
import seaborn as sns

# Generate synthetic spectral data for different catalyst states
np.random.seed(42)
n_samples = 200
n_features = 100  # Spectral points

def generate_spectrum(state, noise_level=0.1):
    """Generate synthetic IR spectrum for different catalyst states"""
    x = np.linspace(1000, 2000, n_features)

    if state == 'fresh':
        # Strong metal carbonyl peak at 2050, weak hydroxyl
        spectrum = 0.8 * np.exp(-(x - 2050)**2 / 100) + \
                   0.2 * np.exp(-(x - 1600)**2 / 200)
    elif state == 'active':
        # Medium carbonyl, reaction intermediates
        spectrum = 0.5 * np.exp(-(x - 2050)**2 / 100) + \
                   0.4 * np.exp(-(x - 1800)**2 / 150) + \
                   0.3 * np.exp(-(x - 1500)**2 / 100)
    elif state == 'deactivated':
        # Weak carbonyl, strong coke peaks
        spectrum = 0.2 * np.exp(-(x - 2050)**2 / 100) + \
                   0.6 * np.exp(-(x - 1400)**2 / 200) + \
                   0.5 * np.exp(-(x - 1300)**2 / 150)

    spectrum += np.random.normal(0, noise_level, n_features)
    return spectrum

# Generate dataset
states = ['fresh', 'active', 'deactivated']
X = []
y = []

for state in states:
    for _ in range(n_samples // len(states)):
        X.append(generate_spectrum(state))
        y.append(state)

X = np.array(X)
y = np.array(y)

# Split data
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3,
                                                      random_state=42)

# Train classifier
clf = RandomForestClassifier(n_estimators=100, random_state=42)
clf.fit(X_train, y_train)

# Predict
y_pred = clf.predict(X_test)

# Create figure
fig, axes = plt.subplots(2, 2, figsize=(14, 10))

# Top-left: Example spectra
ax1 = axes[0, 0]
x = np.linspace(1000, 2000, n_features)
for state, color in zip(states, ['blue', 'green', 'red']):
    spectrum = generate_spectrum(state, noise_level=0.02)
    ax1.plot(x, spectrum, color=color, linewidth=2, label=state.capitalize())

ax1.set_xlabel('Wavenumber (cm⁻¹)', fontsize=11)
ax1.set_ylabel('Absorbance (a.u.)', fontsize=11)
ax1.set_title('Example FTIR Spectra', fontsize=12, fontweight='bold')
ax1.legend()
ax1.invert_xaxis()
ax1.grid(alpha=0.3)

# Top-right: Feature importance
ax2 = axes[0, 1]
importance = clf.feature_importances_
ax2.plot(x, importance, 'purple', linewidth=1.5)
ax2.fill_between(x, importance, alpha=0.3, color='purple')
ax2.set_xlabel('Wavenumber (cm⁻¹)', fontsize=11)
ax2.set_ylabel('Feature Importance', fontsize=11)
ax2.set_title('ML Feature Importance', fontsize=12, fontweight='bold')
ax2.invert_xaxis()
ax2.grid(alpha=0.3)

# Bottom-left: Confusion matrix
ax3 = axes[1, 0]
cm = confusion_matrix(y_test, y_pred, labels=states)
sns.heatmap(cm, annot=True, fmt='d', cmap='Blues', xticklabels=states,
            yticklabels=states, ax=ax3)
ax3.set_xlabel('Predicted', fontsize=11)
ax3.set_ylabel('True', fontsize=11)
ax3.set_title('Confusion Matrix', fontsize=12, fontweight='bold')

# Bottom-right: Accuracy by class
ax4 = axes[1, 1]
accuracy = cm.diagonal() / cm.sum(axis=1) * 100
bars = ax4.bar(states, accuracy, color=['blue', 'green', 'red'], edgecolor='black')
ax4.set_ylabel('Classification Accuracy (%)', fontsize=11)
ax4.set_title('Accuracy by Catalyst State', fontsize=12, fontweight='bold')
ax4.set_ylim(0, 105)
for bar, acc in zip(bars, accuracy):
    ax4.text(bar.get_x() + bar.get_width()/2, bar.get_height() + 2,
             f'{acc:.1f}%', ha='center', fontsize=11)

plt.tight_layout()
plt.show()

# Classification report
print("\nML Classification Results:")
print(classification_report(y_test, y_pred, target_names=states))

4.7 Catalyst Deactivation

Deactivation Mechanisms

Mechanism Cause Detection Regeneration
Sintering High temperature, particle migration TEM, chemisorption loss Often irreversible
Coking Carbon deposition TPO, TGA, Raman Oxidative regeneration
Poisoning Strong adsorbate binding Chemisorption, XPS Depends on poison
Fouling Physical blocking BET, pore analysis Washing, calcination

4.8 Chapter Summary

Key Takeaways

  1. BET provides total surface area from N₂ adsorption
  2. Chemisorption quantifies active sites and metal dispersion
  3. XPS reveals surface composition and oxidation states
  4. TEM provides atomic-resolution imaging of nanoparticles
  5. Operando techniques enable real-time structure-activity correlations
  6. ML accelerates spectral analysis and enables automated catalyst monitoring
  7. Deactivation characterization guides regeneration strategies

Exercises

Exercise 1: BET Calculation

From BET data with slope = 0.015 and intercept = 0.001, calculate Vm, C, and surface area.

Exercise 2: Dispersion Analysis

A 2 wt% Pt/SiO₂ catalyst shows H₂ chemisorption of 0.35 cm³/g. Calculate the dispersion and estimate particle size.

Exercise 3: XPS Interpretation

An XPS spectrum shows Pt 4f₇/₂ peaks at 71.2 eV and 73.5 eV. What oxidation states are present? What might cause the higher BE component?

Exercise 4: Deactivation Diagnosis

A hydrogenation catalyst loses 50% activity after 100 hours. BET area is unchanged, but CO chemisorption dropped 60%. What is the likely deactivation mechanism?

Disclaimer