%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Function Diffusion %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Change file name to Diffusion.m for the function to work. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Calculate diffusion driven dilution of processing liquid in inner HFC % For running, call e.g. Diffusion(1,1,1,5,4.5*1E2,20) % Parameters (with example values): % Qi1 = 1; Inner HFC: Injection flow rate [µl/min] % Qa1 = 1; Inner HFC: Aspiration flow rate [µl/min] % Qi2 = 1; Outer HFC: Injection flow rate [µl/min] % Qa2 = 5; Outer HFC: Aspiration flow rate [µl/min] % d = 20; Apex-to-surface distance [µm] % D = 4.5*1E2; Diffusion coefficient of analyte [µm^2*s^-1] % (Rhodamine B) % For running, type e.g. Dilution = Diffusion(1,1,1,5,4.5*1E2,20) % Diffusion will rate of dilution of analyte due to diffusive transport % from inner HFC to outer HFC. Diffusion also displays data at various % steps of the calculation routine for highlighting the key steps % within the model. % Diffusion calls the funciotn HFC for calculation of the flow field % between the apex of the MFP head and the surface under treatment % Diffusion returns the percentual dilution of analyte in the processing % liquid aspirated through the inner aspiration aperture. function Dilution = Diffusion(Qi1,Qa1,Qi2,Qa2,D,d) % clc close all FlowField = HFC(Qi1,Qi2,Qa1,Qa2,d); % Call HFC function to calculate maps % of vector components of velocity X1 = FlowField{1}; % X component Y1 = FlowField{2}; % Y component V = FlowField{3}; % Amplitude %% Grab Streamline X and Y data figure(5) Inner = streamline(X1); % Plot streamlines for inner set(gcf, 'Visible', 'off') L=findobj(Inner,'type','line'); % find the handles of the stream- % lines xlines = zeros(size(get(L(1),'Xdata'))); ylines = zeros(size(get(L(1),'Ydata'))); for i=1:length(L) % Get rid of nan's x = get(L(i),'Xdata'); x(isnan(x))=[]; xlines(i,1:length(x))=x; y = get(L(i),'Ydata'); y(isnan(y))=[]; ylines(i,1:length(y))=y; end %% Find longest streamline in inner HFC, calculate mean V along % this line, find its length and finally calculate the equivalent % residence time len = 0; for n=1:length(xlines(:,1)) % Lines which are expected to be longest A = [xlines(n,:); ylines(n,:)]; Line1X = A(1,:); Line1X(isnan(Line1X))=[]; Line1X(find(Line1X==0)) = []; Line1Y = A(2,:); Line1Y(isnan(Line1Y))= []; Line1Y(find(Line1Y==0)) = []; if Line1X(end)<75 % Really going to inner aspiration? len1=sum(sqrt(diff(Line1X).^2+diff(Line1Y).^2)); if len1 >= len len = len1; rem = n; end end end A = [xlines(rem,:);ylines(rem,:)]; % Longest streamline going from % Qi1 to Qa1 Line1X = A(1,:); Line1X(isnan(Line1X)) = []; Line1X(find(Line1X==0)) = []; Line1Y = A(2,:); Line1Y(isnan(Line1Y)) = []; Line1Y(find(Line1Y==0)) = []; % Now take the matrix of velocity amplitudes and interpolate for finding % approximation of velocities along streamline A [X,Y]=meshgrid(1:length(V(1,:)),1:length(V(:,1))); SV = interp2(X,Y,V,Line1X,Line1Y); SV = SV(1,isfinite(SV(1,:)))'; % Amplitude of flow velocity along the % interface dist = zeros(size(Line1X)-1); % Aquire non-uniform distances for n = 2:numel(Line1X) % of points composing the interface dist(n-1) = 10*sqrt((Line1X(n)-Line1X(n-1))^2+... (Line1Y(n)-Line1Y(n-1))^2); end pos = zeros(size(dist)); for n = 1:numel(dist) pos(n+1) = pos(n)+dist(n); % Create vector containing 1D position % of points composing the interface end pos = pos(1:numel(SV))'; len = pos(end); % Total interface length step = len/1000; posLin = (0:step:len)'; % Create vector of 1D position along interface% % with liner spacing between points VLin = interp1(pos,SV,posLin); % Find velocity at positions defined % in posLin TDif = zeros(size(VLin)); % Delta t between one position and another for n = 1:numel(VLin) TDif(n) = step/VLin(n); end TLin = zeros(size(TDif)); for n=2:numel(TDif) TLin(n) = TLin(n-1)+TDif(n); % Time spent up to corresponding % position in posLin end %% Diffusion u = @(D,t) sqrt(D/(4*pi*t)); u1 = @(D,X,t) (0.5+0.5*erf(X/sqrt(D*4*t))); X = -100:100; J = zeros(size(TLin)); Profile = zeros(numel(TLin), numel(X(1,:))); for n = 2:numel(TLin) J(n) = u(D, TLin(n)); Profile(n-1,:) = u1(D,X,TLin(n)); end Profile = Profile(2:20:numel(TLin), :); Jloss = trapz(posLin,J)*2*d; % sum up, weight with gap distance % and account for symmetry % see Equation (3) in main paper Qin = (Qi1/(6))*1E8; % Flow of species through % injection aperture Dilution = 100*Jloss/Qin; % ratio of dilution in % %% Visualize Monitor = get(0, 'MonitorPositions'); for n = 1:numel(Monitor(:,1)) if Monitor(n,1) == 1 Monitor = Monitor(n,:); end end p1 = [90 (Monitor(4)-200)/2+110 (Monitor(3)-200)/2,... (Monitor(4)-200)/2]; p2 = [(Monitor(3)-200)/2+110 (Monitor(4)-200)/2+110 (Monitor(3)-200)/2,... (Monitor(4)-200)/2]; p3 = [90 90 (Monitor(3)-200)/2,... (Monitor(4)-200)/2]; p4 = [(Monitor(3)-200)/2+110 90 (Monitor(3)-200)/2,... (Monitor(4)-200)/2]; figure(3) plot(posLin,TLin) set(gcf, 'Position', p3) xlim([0 posLin(end)]) title('Time spent up to a point along the interface') xlabel('Position along interface [10^{-6}m]','Fontsize',11) ylabel('Time [s]','Fontsize',11) figure(4) plot(X,Profile) set(gcf, 'Position', p4) title('Evolution of concentration profile perpendicular to interface') xlabel('Position perpendicular to interface [10^{-6}m]','Fontsize',11) ylabel('Normalized concentration [10^{-5}m]','Fontsize',11) figure(1) hold all set(gcf, 'Position', p1) title('HFC Streamlines, Interface highlighted') fill([53.5;48.5;48.5;53.5],[53.5;53.5;48.5;48.5],[0.7 1 0.7]); % Apertures fill([63.5;58.5;58.5;63.5],[53.5;53.5;48.5;48.5],[0.7 1 0.7]); fill([73.5;68.5;68.5;73.5],[53.5;53.5;48.5;48.5],[1 0.7 0.7]); fill([83.5;78.5;78.5;83.5],[53.5;53.5;48.5;48.5],[1 0.7 0.7]); streamline(X1); % Plot streamlines for inner Outer = streamline(Y1); % and outer HFC xlabel('X position [10^{-5}m]','Fontsize',11) ylabel('Y position [10^{-5}m]','Fontsize',11) Outerlines = findobj(Outer,'-property','LineStyle'); for n=1:length(Outerlines) set(Outerlines(n),'LineStyle', ':'); set(Outerlines(n), 'Color', [0 0 0]); end xlim([20 100]) ylim([20 80]) plot(Line1X,Line1Y,'m','LineWidth', 1) % mark interaface streamline figure(2) plot(posLin, VLin) set(gcf, 'Position', p2) xlim([0 posLin(end)]) title('Amplitude of velocity along interface') xlabel('Position along interface [10^{-6}m]','Fontsize',11) ylabel('Velocity [µm*s^{-1}]','Fontsize',11) end %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Function HFC %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Parameters (with example values): % Qi1 = 1; Inner HFC: Injection flow rate [µl/min] % Qa1 = 1; Inner HFC: Aspiration flow rate [µl/min] % Qi2 = 1; Outer HFC: Injection flow rate [µl/min] % Qa2 = 5; Outer HFC: Aspiration flow rate [µl/min] % d = 20; Apex-to-surface distance [µm] % HFC calculates the 2D velocity field between the apex of the MFP head and % the surface undwer treatment by superimposing single radial flow fields % generated by a set of apertures % HFC returnes the cell Res containing the streamline data for the inner % HFC XY!, the streamline data for the outer HFC XY" and the flied of % velocity amplitude V function Res = HFC(QI1, QI2, QA1, QA2, d) QI1 = (1/6)*1E8*QI1; QI2 = (1/6)*1E8*QI2; QA1 = (1/6)*1E8*QA1; QA2 = (1/6)*1E8*QA2; % Define function for calculation of radial flow field U = @(r, Q) (3*Q/(pi*d^3*r))*(1/6)*d^2; % Mean V of parabolic profile [X1,Y1] = meshgrid(1:101,1:101); % construct meshes [X111,Y111] = meshgrid(-60:-51,1:101); [X11,Y11] = meshgrid(51:70,1:101); X1 = X1-51*ones(101,101); Y1 = cat(2,Y111,Y1,Y11); X1 = cat(2,X111,X1,X11); Y1 = Y1-51*ones(101,131); [X2,Y2] = meshgrid(1:101,1:101); [X22,Y22] = meshgrid(51:80,1:101); X2 = X2-51*ones(101,101); X2 = cat(2,X2,X22); Y2 = cat(2,Y2,Y22); Y2 = Y2-51*ones(101,131); [X3,Y3] = meshgrid(1:101,1:101); [X333,Y333] = meshgrid(-70:-51,1:101); [X33,Y33] = meshgrid(51:60,1:101); X3 = X3-51*ones(101,101); Y3 = cat(2,Y333,Y3,Y33); X3 = cat(2,X333,X3,X33); Y3 = Y3-51*ones(101,131); [X4,Y4] = meshgrid(1:101,1:101); [X444,Y444] = meshgrid(-80:-51,1:101); X4 = X4-51*ones(101,101); X4 = cat(2,X444,X4); Y4 = cat(2,Y444,Y4); Y4 = Y4-51*ones(101,131); for n=1:length(X1(:,1)) for m=1:length(X1(1,:)) R1(n,m) = 10*sqrt(X1(n,m)^2+Y1(n,m)^2); R2(n,m) = 10*sqrt(X2(n,m)^2+Y2(n,m)^2); R3(n,m) = 10*sqrt(X3(n,m)^2+Y3(n,m)^2); R4(n,m) = 10*sqrt(X4(n,m)^2+Y4(n,m)^2); V1 = U(R1(n,m), -QI1); % Calculate flow field V2 = U(R2(n,m), -QI2); % for each single aperture V3 = U(R3(n,m), QA1); V4 = U(R4(n,m), QA2); norm1 = 1/sqrt(X1(n,m)^2+Y1(n,m)^2); norm2 = 1/sqrt(X2(n,m)^2+Y2(n,m)^2); norm3 = 1/sqrt(X3(n,m)^2+Y3(n,m)^2); norm4 = 1/sqrt(X4(n,m)^2+Y4(n,m)^2); % get the signs right V1X(n,m)=-X1(n,m)*norm1*V1; % and split amplitude of V2X(n,m)=-X2(n,m)*norm2*V2; % velocity in x and y... V3X(n,m)=-X3(n,m)*norm3*V3; V4X(n,m)=-X4(n,m)*norm4*V4; V1Y(n,m)=-Y1(n,m)*norm1*V1; V2Y(n,m)=-Y2(n,m)*norm2*V2; V3Y(n,m)=-Y3(n,m)*norm3*V3; V4Y(n,m)=-Y4(n,m)*norm4*V4; end end VX = V1X+V2X+V3X+V4X; % Overlap velocity matrices VY = V1Y+V2Y+V3Y+V4Y; [x1,y1] = meshgrid(59.9:0.25:62.25,49.5:0.25:52.5); % Seeding points [x2,y2] = meshgrid(49.9:0.25:52.25,49.5:0.25:52.5); % for streamlines XY1 = stream2(VX,VY,x1,y1); % Generate streamline data XY2 = stream2(VX,VY,x2,y2); V = sqrt(VX.^2+VY.^2); Res = {XY1 XY2 V}; end