% 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 % The experiment here involved injection of a pulse of % 1e-3 mol of tracer into fluid flowing at 1e-5 m3/s % through a packed bed. % This is a Residence Time Distribution (RTD) experiment % that is used to investigate flow patterns in process units. % These data are time and tracer concentration measurements % at the outlet of the bed. % Data pasted in from experiment in SimzLab > ReactorLab > % Division 4 Lab 2 (www.SimzLab.com) % paste header data from experiment and comment out: % D4L2, Data Set 1 % % input_1 remained constant at pulse % dp_1 remained constant at 2.00E-3 m % wt_1 remained constant at 0.250 kg % flow_1 remained constant at 1.00E-5 m3/s % dBed_1 remained constant at 0.200 m % len_1 remained constant at 1.14E-2 m % t_1 has units of s % Cout_1 has units of mol/m3 % % t_1 Cout_1 % paste data from experiment into array d % alternatively, could also read data from a text file % but do this here to keep everything in one file d = [ -2.14 5.61E-2 -1.60 -0.157 -1.07 0.298 -0.535 6.79E-2 0 0.366 0.535 -0.139 1.07 0.242 1.60 0.352 2.14 1.65 2.67 2.10 3.21 3.19 3.75 4.02 4.28 5.17 4.82 5.82 5.35 6.54 5.88 7.05 6.42 7.78 6.96 8.15 7.49 8.05 8.03 8.42 8.56 8.31 9.10 7.83 9.63 7.74 10.2 7.37 10.7 7.41 11.2 7.03 11.8 6.54 12.3 6.26 12.8 5.54 13.4 5.24 13.9 4.94 14.4 4.67 15.0 4.33 15.5 3.49 16.1 3.49 16.6 3.09 17.1 3.01 17.6 2.42 18.2 2.28 18.7 1.73 19.3 1.82 19.8 1.29 20.3 1.41 20.9 0.915 21.4 0.812 21.9 1.11 22.5 0.860 23.0 0.779 23.5 0.826 24.1 0.606 24.6 0.396 25.1 0.268 25.7 0.601 26.2 0.356 26.8 0.200 27.3 0.174 27.8 0.341 28.4 -9.55E-2 28.9 -0.244 29.4 9.45E-2 30.0 0.136 30.5 6.72E-2 31.0 -4.32E-2 31.6 0.211 32.1 -8.75E-2 ]; % extract time and concentration columns into separate arrays t = d(:,1); % s, time c = d(:,2); % mol/m3, tracer concentration % plot plot(t,c,'.') title('HIT SPACE KEY TO STEP - differentiating data') ylabel('tracer 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 % >>> FREEMAT <<< SEEMS TO HAVE PROBLEMS WITH THIS % SECTION SO BEST TO COMMENT OUT THIS SECTION % IN FREEMAT UNDER TOOLS MENU if i < 10 % just do this for first 10 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,'.') title('HIT SPACE KEY TO STEP - differentiating data') ylabel('tracer 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,'.',diffTime,diffValue,'r',zt,zv,'g') title('RTD experiment: pts = data, red line = derivative') ylabel('tracer conc, C (mol/m3) or dC/dt (mol/m3/s)') xlabel('time (s)') % FOR SOME APPLICATIONS such as the differential method % of reaction kinetic analysis, you may need to find and delete % (or find and keep) derivative values that are positive (or negative) % before you take the logarithm of the values. This can be done using % Matlab's find command, e.g., % y = find(diffValue < 0); % y is array of indexes of diffValue where values are < 0 % diffVx = diffValue(y); % diffVx is array with only the selected values of diffValue fprintf('DONE - see final plot \n')