% Example of differentiating experimental data % by fitting polynomial to groups of data and differentiating % the polynomial % % HIT SPACE BAR TO STEP THROUGH PROCESS ON PLOT clear fprintf('--------------------------\n') % run separator in command window % Differential method of analysis of batch reactor data in ReactorLab % copy data to Matlab file, comment the header lines, put all data into % array with arbitrary name d % D1L1 Batch, Data Set 2b % % k*_2b remained constant at 1.00E-4 (value at 300 K) % Ea_2b remained constant at 60.0 kJ/mol % n_2b remained constant at 2.00 (dimensionless) % T_2b remained constant at 325.0 K % Cin_2b remained constant at 100.0 mol/m3 % vol_2b remained constant at 1.00 m3 % time_2b has units of s % tau_2b has units of s % Cout_2b has units of mol/m3 % conv_2b has units of (dimensionless) % time_2b tau_2b Cout_2b conv_2b d = [0.00 0.00 100.0 0.00 1.00 1.00 95.8 4.21E-2 2.00 2.00 87.1 0.129 3.00 3.00 83.1 0.169 4.00 4.00 80.4 0.196 5.00 5.00 74.9 0.251 7.50 7.50 68.2 0.318 10.0 10.0 61.0 0.391 20.0 20.0 43.8 0.562 30.0 30.0 34.8 0.652 40.0 40.0 27.9 0.721 50.0 50.0 23.8 0.762 60.0 60.0 20.3 0.797 70.0 70.0 18.4 0.816 80.0 80.0 16.4 0.836 90.0 90.0 14.7 0.853]; % extract time and concentration vectors t = d(:,1); c = d(:,3); % plot plot(t,c,'.') title('HIT SPACE KEY TO STEP - differentiating data') ylabel('conc (mol/m3)') xlabel('time (s)') [rows cols] = size(c); % size is std matlab function npts = rows; %----- DIFFERENTIATE WITH GENERAL POLYNOMIAL FIT ---------- % We want to look at the rate of change of the concentration vs. t % by differentiating these data. % The simplest way is just to get the slope between each % pair of points using Matlab's diff function. % But this will show a very "noisy" derivative with these data. % We can also fit a polynomial to groups of points % to get some "smoothing" of the data. % The following will also work with pts that are % NOT equally spaced in time % Vary n and m and see how the derivative on the plot changes n = 2; % order of polynomial, reasonable numbers are 1-4 m = 5; % number of points in group to fit, m >= n+1 if m < n+1 fprintf('you must increase m in the derivative polynomial fit! \n\n') end fprintf('see plot - hit return key to step \n') % k = number of groups of m pts we can fit % with dropping one pt and adding one pt for each group % Note this grouping is different than for quadrature k = npts-m+1; for j = 1:k i = j; % use Matlab std function polyfit to fit n-th % order polynomial to this group of pts % with polynomial coefficients returned in array a % with highest-order term first, lowest last a = polyfit(t(i:i+m-1),c(i:i+m-1),n); % differentiate polynomial analytically over interval % and evaluate at approx. mid-point time t(i+floor(m/2)) sumd = 0; % mol/m3/s for jj = 1:n sumd = sumd + ... a(jj)*(n-jj+1)*t(i+floor(m/2))^(n-jj); end % save derivative, time, and concentration values in arrays diffValue(j) = sumd; % mol/m3/s diffTime(j) = t(i+floor(m/2)); % s diffConc(j) = polyval(a,t(i+floor(m/2))); % OPTIONAL - SHOW PROCESS ON PLOT if i < 10 % just do this for first few groups % add the polynomial and the slope to the plot % get intercept b of the tangent line of the polynomial at the mid-pt b = polyval(a,t(i+floor(m/2))) - sumd*t(i+floor(m/2)); % get start and end times tp(1) = t(i); tp(2) = t(i+m-1); % get y values of the tangent line at the start and end times yp = sumd*tp + b; % get conc values for the polynomial at each time cp = polyval(a,t(i:i+m-1)); plot(t,c,'.') axis([0 1.1*max(t) 0 1.1*max(c)]) title('HIT SPACE KEY TO STEP - differentiating data') ylabel('conc (mol/m3)') xlabel('time (s)') hold on plot(t(i:i+m-1),cp,'b',tp,yp,'r') hold off pause % YOU NEED TO HIT ANY KEY TO CONTINUE STEPPING % SEE THE POLYNOMIALS FIT ON THE PLOT end % END OF OPTIONAL - SHOW PROCESS ON PLOT end % generate pts for a line at zero zv = zeros(2); zt = [t(1) t(npts)]; % make final plot plot(t,c,'.',zt,zv,'g',diffTime,diffValue,'r') title('pts = data, red line = derivative') ylabel('conc, C (mol/m3) or dC/dt (mol/m3/s)') xlabel('time (s)') pause rate = -diffValue; figure(1) plot(log(diffConc), log(rate), 'bo') % fit straight line through points in log-log plot coef = polyfit(log(diffConc), log(rate),1); % the coefficients of 1st order polynomial are the order and ln(k) nfit = coef(1); % order k325fit = exp(coef(2)); % k at 325 hold on lnr = polyval(coef,log(diffConc)); % compute points for line through points plot(log(diffConc),lnr,'k') s = sprintf('ln(rate) vs. ln(conc), k = %4f, order = %4f',k325fit, nfit); title(s) hold off % now show the model rate vs. the experimental rate estimates figure(2) ratefit = k325fit * diffConc .^ nfit; plot(diffConc, rate, 'bo', diffConc, ratefit,'k') title('rate vs. conc, circles are from dC/dt estimates, line = model rate') axis([0 1.1*max(diffConc) 0 1.1*max(rate)]) E = 60e3; % J/mol R = 8.3145; % J/K/mol k300fit = k325fit * exp((E/R)*(1/325 - 1/300)) fprintf('DONE - see final plot \n') % note the random error or scatter in these data % which means we don't get the "true" values computed by the lab % % question for you: what does "true" mean in real world? % % order = 1.93 vs. "true" order = 2 in lab % % k325 = 8.84e-04 vs. "true" k325 = 6.36e-04 in lab % % k300fit = % % 1.3901e-04 % % vs. k300 = 1.0e-04 "true" rate coefficient in lab for Ea = 60 kJ/mol