clc; clear;
fprintf('--- Heterogeneous Reaction Analysis using Langmuir-Hinshelwood Model ---\
n');
%% === General User Inputs ===
reaction_name = input('Enter the reaction name (e.g., Hydrogenation of Ethene): ',
's');
W = input('Catalyst weight (g): ');
num_exp = input('Enter number of experiments/runs: ');
%% === Initialize Storage for Experimental Data ===
PA_exp = zeros(1, num_exp);
PB_exp = zeros(1, num_exp);
rate_exp = zeros(1, num_exp);
T_K_all = zeros(1, num_exp);
P_total_all = zeros(1, num_exp);
%% === Constants ===
R = 0.0821; % L·atm/mol·K
%% === Loop for Experimental Runs ===
for i = 1:num_exp
fprintf('\n--- Run %d ---\n', i);
Q_A = input('Flow rate of Reactant A (L/min): ');
Q_B = input('Flow rate of Reactant B (L/min): ');
T_K = input('Temperature (K): ');
P_total = input('Total Pressure (atm): ');
PA = input('Partial pressure of A (atm): ');
PB = input('Partial pressure of B (atm): ');
X = input('Conversion of A (0 to 1): ');
FA0 = (Q_A / 60) / (R * T_K); % mol/s
rate_exp(i) = (FA0 * X) / W; % mol/g·s
PA_exp(i) = PA;
PB_exp(i) = PB;
T_K_all(i) = T_K;
P_total_all(i) = P_total;
end
%% === Langmuir-Hinshelwood Parameter Estimation ===
rate_model_func = @(params, PA, PB) ...
(params(1) .* PA .* PB) ./ (1 + params(2)*PA + params(3)*PB).^2;
params0 = [0.01, 1, 1]; % Initial guess: [k, K_A, K_B]
obj_fun = @(params) sum((rate_exp - rate_model_func(params, PA_exp, PB_exp)).^2);
[params_opt, ~] = fminsearch(obj_fun, params0);
k = params_opt(1); % Rate constant
K_A = params_opt(2); % Adsorption constant for A
K_B = params_opt(3); % Adsorption constant for B
%% === Display Results for Each Run ===
fprintf('\n--- Experimental Data and Model Prediction ---\n');
rate_fitted = zeros(1, num_exp);
for i = 1:num_exp
rate_fitted(i) = rate_model_func(params_opt, PA_exp(i), PB_exp(i));
fprintf('Run %d: PA = %.3f atm, PB = %.3f atm | Rate_exp = %.5f mol/g·s |
Rate_model = %.5f mol/g·s\n', ...
i, PA_exp(i), PB_exp(i), rate_exp(i), rate_fitted(i));
end
%% === Rate-limiting Step Analysis ===
fprintf('\n--- Rate-Limiting Step Analysis ---\n');
if K_A > K_B
disp('The rate-limiting step is likely adsorption of Reactant A.');
elseif K_B > K_A
disp('The rate-limiting step is likely adsorption of Reactant B.');
else
disp('Both reactants contribute similarly to the rate-limiting step.');
end
%% === Reactor Recommendation ===
avg_T = mean(T_K_all);
avg_P = mean(P_total_all);
avg_conversion = mean((rate_exp .* W) ./ ((PA_exp ./ avg_P) * R * avg_T * 60)); %
Rough estimate
fprintf('\n--- Reactor Recommendation ---\n');
if avg_conversion < 0.3
reactor_type = 'Recommended: Plug Flow Reactor (PFR)';
elseif avg_conversion > 0.7
reactor_type = 'Recommended: Packed Bed Reactor with Recycle or Staged PFR';
else
reactor_type = 'Recommended: Either PFR or CSTR depending on heat/mass
transfer';
end
fprintf('%s\n', reactor_type);
%% === Plots ===
figure;
% Plot for partial pressure of A (P_A) vs Reaction Rate
subplot(2,2,1);
plot(PA_exp, rate_exp, 'ro', 'MarkerFaceColor','r');
hold on;
plot(PA_exp, rate_fitted, 'b-', 'LineWidth', 2);
xlabel('P_A (Partial Pressure of A)');
ylabel('Reaction Rate (mol/g·s)');
title('Reaction Rate vs P_A');
legend('Experimental Data', 'Fitted Rate Law');
grid on;
% Plot for partial pressure of B (P_B) vs Reaction Rate
subplot(2,2,2);
plot(PB_exp, rate_exp, 'ro', 'MarkerFaceColor','r');
hold on;
plot(PB_exp, rate_fitted, 'b-', 'LineWidth', 2);
xlabel('P_B (Partial Pressure of B)');
ylabel('Reaction Rate (mol/g·s)');
title('Reaction Rate vs P_B');
legend('Experimental Data', 'Fitted Rate Law');
grid on;
% Parity plot: Experimental vs Model Rates
subplot(2,2,3);
plot(rate_exp, rate_fitted, 'ko');
hold on;
plot([min(rate_exp), max(rate_exp)], [min(rate_exp), max(rate_exp)], 'r--');
xlabel('Experimental Rate (mol/g·s)');
ylabel('Fitted Rate (mol/g·s)');
title('Parity Plot: Experimental vs Fitted Rates');
grid on;
% Residuals plot: Difference between experimental and model rates
subplot(2,2,4);
bar(rate_exp - rate_fitted);
xlabel('Experiment No.');
ylabel('Residual (Exp - Model)');
title('Residuals: Experimental - Fitted');
grid on;