% 10.34 - Fall 2006 % Hw Set #7 - Problem #2 % Rob Ashcraft - Oct. 20, 2006 % This function solve the reactor optimization problem in Beers' text 5.B.4. % This implementation uses all unscaled variables, and requires very high % tolerances in order to force V_rxtr to vary. function p2_main clear; clc; % rate constant data at 298K and 310K for k1 --> k5 T_data = [298, 310]; % kelvin k_T = [0.01, 0.02; 0.01, 0.02; 0.001, 0.005; 0.001, 0.005; 0.001, 0.005]; % L/mol-s T_plot = linspace(273,335,20); for i=1:length(k_T) EaR(i,1) = -log(k_T(i,1)/k_T(i,2)) / (1/T_data(1) - 1/T_data(2)); % solve for Ea/R for each reaction Af(i,1) = k_T(i,1)*exp(EaR(i)/T_data(1)); % solve for the A-factor using k(298K) k_plot(:,i) = Af(i).*exp(-EaR(i)./T_plot); % make a vector k(T) to plot end % plot the rate constants to make sure they fit the data figure; semilogy(T_data,k_T(1,:),'ok',T_plot,k_plot(:,1),'-',T_data,k_T(3,:),'*k',T_plot,k_plot(:,3),'--'); xlabel('Temperature (K)'); ylabel('Rate Constant (L/mole-s)'); legend('k_1 and k_2 data','k_1 and k_2 fit','k_3, k_4, k_5 data','k_3, k_4, k_5 fit','location','SouthEast'); % now deal with the reactor problem V_flow = 1; % L/s % initial guesses for the optimization: C_Ao_guess = 1; % molar C_Bo_guess = 1; % molar T_guess = 315; % Kelvin V_rxtr_guess = 5000; % liters var0 = [C_Ao_guess; C_Bo_guess; T_guess; V_rxtr_guess]; options = optimset('Display','iter','TolFun',1e-15,'TolX',1e-10,... 'TolCon',1e-10,'MaxFunEval',10000); % Define the constraint that Ca + Cb < 2 M A = [1, 1, 0, 0]; b = 2; % Include the given upper and lower bounds on the system varaible lb = [0; 0; 298; 10]; ub = [2; 2; 335; 10000]; [var, fval] = fmincon(@obj_fun,var0,A,b,[],[],lb,ub,[],options,V_flow,Af,EaR); disp(['Inlet [A] = ',num2str(var(1)),' M']); disp(['Inlet [B] = ',num2str(var(2)),' M']); disp(['Reactor Temperature = ',num2str(var(3)),' K']); disp(['Reactor Volume = ',num2str(var(4)),' L']); disp(['Outlet [C] = ',num2str(-fval),' M']); C_Ao = var(1); C_Bo = var(2); T = var(3); V_rxtr = var(4); % Since we found out early that the V_rxtr term was causing problems, it is % also useful to look at the cost function as a function of V_rxtr, and % make sure our fmincon solution appears to be at the minimum. test = logspace(1,4,50); for i=1:length(test) cost_i(i) = obj_fun([var(1:3);(test(i))],V_flow,Af,EaR); end figure; semilogx(test,cost_i,'-',V_rxtr,fval,'o') xlabel('Reactor Volume (L)'); ylabel('Cost Function (-[C]_o_u_t M)'); legend('Cost Function','fmincon Solution'); return; % other functions %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Define the function called by fmincon with the cost function % we use fsolve in this case function cost = obj_fun(var,V_flow,Af,EaR) C_Ao = var(1); C_Bo = var(2); T = var(3); V_rxtr = var(4); C_guess = [1; 1; 0; 0; 0; 0; 0; 0]; options = optimset('Display','off','TolX',1e-14,'TolFun',1e-16); % we need to find the steady state values of outlet concentrations C_all = fsolve(@rxtr_dCdt_fsolve,C_guess,options,C_Ao,C_Bo,T,V_rxtr,V_flow,Af,EaR); cost = -C_all(3); return; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function dAlldt = rxtr_dCdt_fsolve(C_all,C_Ao,C_Bo,T,V_rxtr,V_flow,Af,EaR) % all of the C variable are concentrations in moles/L tau = V_flow/V_rxtr; A = C_all(1); B = C_all(2); C = C_all(3); D = C_all(4); S1 = C_all(5); S2 = C_all(6); S3 = C_all(7); S4 = C_all(8); k = Af.*exp(-EaR./T); dAdt = -k(1)*A*B - k(3)*A*D - k(4)*A*B + tau*(C_Ao - A); dBdt = -k(1)*A*B - k(2)*B*C - k(4)*A*B - k(5)*B*C + tau*(C_Bo - B); dCdt = k(1)*A*B - k(2)*B*C - k(5)*B*C - tau*C; dDdt = k(1)*A*B + k(2)*B*C - k(3)*A*D - tau*D; dS1dt = k(2)*B*C - tau*S1; dS2dt = k(3)*A*D - tau*S2; dS3dt = k(4)*A*B - tau*S3; dS4dt = k(5)*B*C - tau*S4; dAlldt = [dAdt; dBdt; dCdt; dDdt; dS1dt; dS2dt; dS3dt; dS4dt]; return;