% Examples of integrating area under experimental data (quadrature) % using a variety of methods. % % SEE OUTPUT IN COMMAND WINDOW TO SEE AREA FROM EACH METHOD % 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 BAR TO STEP - fitting polynomial to integrate under data') ylabel('tracer conc (mol/m3)') xlabel('time (s)') [rows cols] = size(c); % size is std matlab function npts = rows; % dt = constant time interval between pts in this data set % see time data above for first pt after t = 0 % other times are rounded dt = 0.535; % s, time interval %--------- RECTANGLES -------------- % just do rectangles... sumq = 0; % mol-s/m3 for i = 1:npts-1 sumq = sumq + dt*c(i); end % to get amt tracer injected (mol) % need to multiply sumq (mol-s/m3) by % flow rate (m3/s) amt = 1e-5*sumq; % mol = mol/s * mol-s/m3 fprintf('integrated moles by RECTANGLES = %8.6f \n',amt) %--------- TRAPEZOIDS -------------- % now do trapezoids... sumq = 0; for i = 1:npts-1 sumq = sumq + dt*(c(i) + c(i+1))/2; end amt = 1e-5*sumq; % mol = mol/s * mol-s/m3 fprintf('integrated moles by TRAPEZOIDS = %8.6f \n',amt) %----- SIMPSON'S 1/3 RULE ---------- % NOTE Simpson's rules fit a polynomial to minimum number % of points to get a unique fit: number pts = polynomial order + 1 % Since the fit is unique, Simpson determined the polynomial % coefficients and integrated the polynomial for you already! % now use Simpson's 1/3 rule % (fit quadratic polynomial uniquely to groups of 3 equally spaced pts) % integral approx = sumq over i to npts-1 of % interval*(1/3)*(c(i) + 4*c(i+1) + c(i+2)) % where interval between pairs of pts here is 0.5 s n = 2; % order of polynomial m = n+1; % number of points in group to fit, m = n+1 for Simpson's sumq = 0; % mol-s/m3 % k = number of groups of m pts we can fit % floor is std matlab function that rounds down to nearest integer k = floor((npts-1)/(m-1)); for j = 1:k i = 1 + (j-1)*(m-1); sumq = sumq + dt*(1/3)*(c(i) + 4*c(i+1) + c(i+2)); end % we may have not fit some pts p = mod(npts-1,k); % number of pts not fit if p ~= 0 fprintf('Simp 1/3 left off last %4i pts, catch with trapezoid \n',p) % last pt # of groups above was 1+k*(m-1) % very last pt # of all data is npts % catch these with trapezoid method for i = 1+k*(m-1):npts-1 sumq = sumq + dt*(c(i) + c(i+1))/2; end end amt = 1e-5*sumq; % mol = mol/s * mol-s/m3 fprintf('integrated moles by SIMPSONS 1/3 = %8.6f \n',amt) %----- SIMPSON'S 3/8 RULE ---------- % now use Simpson's 3/8 rule % (fit cubic polynomial uniquely to groups of 4 equally spaced pts) % integral approx = sumq over i to npts-1 of % interval*(3/8)*(c(i) + 3*c(i+1) + 3*c(i+2) + c(i+3)) n = 3; % order of polynomial m = n+1; % number of points in group to fit, m = n+1 for Simpson's sumq = 0; % mol-s/m3 % k = number of groups of m pts we can fit % floor is std matlab function that rounds down to nearest integer k = floor((npts-1)/(m-1)); for j = 1:k i = 1 + (j-1)*(m-1); sumq = sumq + ... dt*(3/8)*(c(i) + 3*c(i+1) + 3*c(i+2) + c(i+3)); end % we may have not fit some pts p = mod(npts-1,k); % number of pts not fit if p ~= 0 fprintf('Simp 3/8 left off last %4i pts, catch with trapezoid \n',p) % last pt # of groups above was 1+k*(m-1) % very last pt # of all data is npts % catch these with trapezoid method for i = 1+k*(m-1):npts-1 sumq = sumq + dt*(c(i) + c(i+1))/2; end end amt = 1e-5*sumq; % mol = mol/s * mol-s/m3 fprintf('integrated moles by SIMPSONS 3/8 = %8.6f \n',amt) % NOTE can get more efficient computation if pull % dt*(3/8) outside of for-end repeat and multiple sumq % by that amount after the for-end repeat but % this is short and fast so there will be no noticeable % speed difference here - similar for other repeats above %----- GENERAL POLYNOMIAL FIT ---------- % We can also fit a polynomial to a greater number of % points in each group to get some "smoothing" of the data % Use a larger number of points (m) with more scatter in data % % ALSO, the following will also work with pts that are % NOT equally spaced in time (Simpson's required equally spaced data) n = 2; % order of polynomial, reasonable values are 1-3 m = 5; % number points in each group, m >= n+1 if m < n+1 fprintf('you must increase m in the general polynomial fit! \n\n') end fprintf('see plot - hit return key to step \n') sumq = 0; % mol-s/m3 % k = number of groups of m pts we can fit % floor is std matlab function that rounds down to nearest integer k = floor((npts-1)/(m-1)); for j = 1:k i = 1 + (j-1)*(m-1); % 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); % 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 cp = polyval(a,t(i:i+m-1)); hold on plot(t(i:i+m-1),cp,'r') hold off pause % YOU NEED TO HIT ANY KEY TO CONTINUE STEPPING % SEE THE POLYNOMIALS FIT ON THE PLOT % END OF OPTIONAL - SHOW PROCESS ON PLOT % integrate polynomial analytically over interval for jj = 1:n+1 sumq = sumq + ... (a(jj)/(n+2-jj))*(t(i+m-1)^(n+2-jj) - t(i)^(n+2-jj)); end end % we may have not fit some pts p = mod(npts-1,k); if p ~= 0 fprintf('Poly left off last %4i pts, catch with trapezoid \n',p) % last pt # of groups above was 1+k*(m-1) % very last pt # of all data is npts % catch these with trapezoid method for i = 1+k*(m-1):npts-1 sumq = sumq + dt*(c(i) + c(i+1))/2; end end amt = 1e-5*sumq; % mol = mol/s * mol-s/m3 fprintf('integrated moles by POLYNOMIAL = %8.6f \n',amt) fprintf('DONE - see final plot \n')