% Danalysis: perform a dimensional analysis. % Find non-dimensional variables via the basis set of the % null space of the dimension matrix, D. Several examples, % starting with finding the drag on a sphere moving at a known % speed through a viscous fluid, are shown below. The lines % having comments denoted by the symbol %%% are the % lines that you will need to change to define a new problem. % Enter the variables by calling Din; enter one dependent % variable first, and then as many independent variables % as appear in the problem. The dimensions are entered as a % row vector of the exponents on the dimensions Mass, Length, % time and Temperature, i.e, velocity is [0 1 -1 0]. The % order of these dimensions is arbitrary, as is the choice % of the fundamental dimensions themselves. You must be % consistent within any one problem but otherwise the choice % is yours. % % The raw output is a set of exponents, nsb, that are to be % associated with each of the input variables. The specific % order of the exponents, and thus the specific form of the % non-dimensional variables, is determined by the arbitrary order % in which you entered the independent variables. Only by % accident would the form be optimal. Your part of this job is to % manipulate the non-d variables into a useful form. For example, % in the first problem of drag on a moving sphere, you might % guess that inertial drag is the zero order solution, and hence % you may want to divide Pi(1) by Pi(2) to show this. Note that % Pi is a symbolic variable, and to do this you could % enter >>Pi(1) = Pi(1)/Pi(2), and then >>pretty(simplify(Pi)) % (assuming that you have the symbolic toolbox). If you do not % have the symbolic toolbox (you should get it!), you will still % get the exponents on each variable returned through nsb. % % By Jim Price, July, 2001. jprice@whoi.edu, 508-289-2526. % Please also let me know if you find a problem on which this % method fails or if you have suggestions or comments that % would help improve the script. % % Public domain for all personal, educational purposes. % function Danalysis % this has been set up as a function so that all the necessary % subroutines can be included within one file, Din, Dclear, % Dnullspace global D Ds jp nsb Pi % if you enter 'global Pi nsb' in the command window before % running Danalysis, the exponent array nsb and the symbolic % variable array Pi will be available in the command window % for further use (or at least the last computed values will % be available) format compact format rational disp(' ') disp(' *** drag on a sphere moving at a known speed ***') %%% Dclear % always start with this Din('Force', [1 1 -2] ) %%% drag (force) = [m*l/t*t]; the dependent variable Din('rho', [1 -3 0] ) %%% density of the fluid = [m/l*l*l] Din('radius', [0 1 0] ) %%% radius of the sphere = [l] Din('mu', [1 -1 -1] ) %%% viscosity = [m/l*t] Din('speed', [0 1 -1] ) %%% the known speed of the sphere = [l/t] D; % print out D (or not) [nsb Pi] = Dnullspace(Ds, D); % now perform the analysis on D % % You may prefer other forms of these Pis, as noted above. % disp(' hit any key to continue'), disp(' '), disp(' '), pause % now try with viscosity omitted disp(' *** drag on a sphere with viscosity omitted ***') %%% Dclear % always start with this Din('Force', [1 1 -2] ) %%% drag (force) = [m*l/t*t]; the dependent variable Din('rho', [1 -3 0] ) %%% density of the fluid = [m/l*l*l] Din('radius', [0 1 0] ) %%% radius of the sphere = [l] % Din('mu', [1 -1 -1] ) %%% viscosity = [m/l*t] Din('speed', [0 1 -1] ) %%% the known speed of the sphere = [l/t] D; % print out D (or not) [nsb Pi] = Dnullspace(Ds, D); % now perform the analysis on D disp(' hit any key to continue'), disp(' '), disp(' '), pause % now try with density of the fluid omitted disp(' *** drag on a sphere with density omitted ***') %%% Dclear % always start with this Din('Force', [1 1 -2] ) %%% drag (force) = [m*l/t*t]; the dependent variable % Din('rho', [1 -3 0] ) %%% density of the fluid = [m/l*l*l] Din('radius', [0 1 0] ) %%% radius of the sphere = [l] Din('mu', [1 -1 -1] ) %%% viscosity = [m/l*t] Din('speed', [0 1 -1] ) %%% the known speed of the sphere = [l/t] D; % print out D (or not) [nsb Pi] = Dnullspace(Ds, D); % now perform the analysis on D disp(' hit any key to continue'), disp(' '), disp(' '), pause % now add g, as if near the sea surface, but w/ viscosity omitted disp(' *** drag on a sphere, with g but not viscosity ***') %%% Dclear % always start with this Din('Force', [1 1 -2] ) %%% drag (force) = [m*l/t*t]; the dependent variable Din('rho', [1 -3 0] ) %%% density of the fluid = [m/l*l*l] Din('radius', [0 1 0] ) %%% radius of the sphere = [l] Din('depth', [0 1 0] ) %%% depth = [l] Din('g', [0 1 -2]) %%% accel of gravity % Din('mu', [1 -1 -1] ) %%% viscosity = [m/l*t] Din('speed', [0 1 -1] ) %%% the known speed of the sphere = [l/t] D; % print out D (or not) [nsb Pi] = Dnullspace(Ds, D); % now perform the analysis on D disp(' hit any key to continue'), disp(' '), disp(' '), pause % now add everything back in disp(' *** drag on a moving sphere with all variables ***') %%% Dclear % always start with this Din('Force', [1 1 -2] ) %%% drag (force) = [m*l/t*t]; the dependent variable Din('rho', [1 -3 0] ) %%% density of the fluid = [m/l*l*l] Din('radius', [0 1 0] ) %%% radius of the sphere = [l] Din('g', [0 1 -2]) %%% accel of gravity Din('depth', [0 1 0] ) %%% depth = [l] Din('mu', [1 -1 -1] ) %%% viscosity = [m/l*t] Din('speed', [0 1 -1] ) %%% the known speed of the sphere = [l/t] D; % print out D (or not) [nsb Pi] = Dnullspace(Ds, D); % now perform the analysis on D disp(' hit any key to continue'), disp(' '), disp(' '), pause disp(' *** GI Taylor`s famous analysis of the first A bomb *** ') % grim, but physically very interesting and historical Dclear % reinitialize a counter and memory Din('Energy', [1 2 -2]) %%% energy released (the unknown) Din('radius', [0 1 0]) %%% observed radius of the blast wave Din('time', [0 0 1]) %%% time elasped since the blast Din('rho', [1 -3 0]) %%% density of the ambient fluid % D; % print out D (or not) [nsb Pi] = Dnullspace(Ds, D); % perform the analysis on D % % some data read off photos in Sedov (1959), Fig 59-61 % R is accurate to no better than about 10-20% t = 1.e-3*[0.1 0.24 0.38 0.80 1.36 1.93 15.0 127.0]; % time, sec R = 0.5*[24 36 50 68 80 90 220 340]; % radius of blast wave E = 8.0e13; % (kinetic) energy released, Joules, found by % an eyeball fit of the observed and non-d curves. This % fitting would be plausible if the form (slope) of the % non-d function were consistent with the data (it seems % to be in this case). The best fit E corresponds roughly % to 12 kilotons of TNT (perhaps more than you wanted to know?) rho = 1.25; % air density tmod = 1.e-4*[1:10:1000]; Rmod = (E/rho)^0.2*(tmod.^0.4); % some graphics settings set(0,'DefaultLineLineWidth',1.0) set(0,'DefaultTextFontSize',14) set(0,'DefaultAxesLineWidth',1.1) set(0,'DefaultAxesFontSize',12) figure(9) clf reset loglog(t, R, '*', tmod, Rmod) legend('observed radius', 'fit of r(t), E = 8x10^{13} J') xlabel('elapsed time, sec') ylabel('radius of the blast wave, m') title('radius(t) of a very intense blast wave') disp(' hit any key to continue'), disp(' '), disp(' '), pause disp (' ') disp(' *** period of planetary orbits a la Kepler *** ') %%% title Dclear % reinitialize a counter and memory Din('T', [0 0 1]) %%% Period, the unknown Din('R', [0 1 0]) %%% radius of the orbit Din('m', [1 0 0]) %%% mass of the planet Din('M', [1 0 0]) %%% mass of the sun Din('G', [-1 3 -2]) %%% universal gravitational constant % D; % print out D (or not) [nsb Pi] = Dnullspace(Ds, D); % perform the nondimensional analysis of D % % Kepler's data % planets are: Mercury, Venus, Earth, Mars, Jupiter, Saturn Rp = [0.389 0.724 1.0 1.524 5.200 9.510]; % AU Tp = [87.8 224.7 365.25 687.0 4332.6 10759.2]; % days mp = [0.054 0.815 1.0 0.108 317.8 95.2]; % mass in units of Earth Ms = 3.33e5*5.97e24; % mass of the sun % Rp = Rp*1.49e11; % convert AU to meters Tp = Tp*8.64e4; % days to sec mp = mp*5.97e24; % earth masses to kg Gp = Rp.^3./(Ms*Tp.^2); format short; Gavg = mean(Gp); G = 6.67e-11; % the universal gravitational constant figure(33); clf reset loglog(Rp, Tp, Rp, Tp, 'r*') xlabel('radius, m'); ylabel('period, sec') Tmod = 2*3.14159*(Rp.^1.5)/sqrt(G*Ms); hold on loglog(Rp, Tmod, 'b') title('orbital period of the inner planets and Jupiter`s moons') figure(34); clf reset Tnd = Tp./((Rp.^1.5)/sqrt(Gavg*Ms)); loglog(mp/5.97e24, Tnd); axis([0.01 1000 0.1 10.]) xlabel('mass planet/mass Earth'); ylabel('period, non-d') % the moons of Jupiter; Io, Europa, Ganymede, Callisto % Rm = [5.57 8.87 14.15 24.90]*69.9e6; % m Tm = [1.53 3.07 6.19 14.5]*1.e5; % sec Mj = 317.8*5.97e24; % mass of Jupiter in kg G = 6.67e-11; figure(33); hold on loglog(Rm, Tm, 'g*') Tmod = 2*3.14159*(Rm.^1.5)/sqrt(G*Mj); hold on loglog(Rm, Tmod, 'b') hold on % loglog(Rm, Tm/sqrt(3.33e5/317.8), 'm') axis([1.e8 1.e14 1.e3 1.e9]) axis('square') legend('fit of p(r); G = 6.67 x10^{-11}',4) function [nsb, Pi] = Dnullspace(Ds, D) % % Dnullspace: non-dimensional analysis of a dimension % matrix D. Ds is a cell array of variable names. The % output is a matrix nsb of exponents on the dimensional % variables that will give a basis set of the null space % of D. If symbolic toolbox is available, then the symbolic % variable Pi is a printable version of the non-d % variables. The resulting basis set is not unique, and is % unlikely to conform to your preferred set of non-d % variables. Jim Price, August, 2001. disp(' ') nrank = rank(D); fprintf(' the rank of the dimension matrix is %g', nrank) disp(' ') [nv nd] = size(D); numndv = nv - nrank; fprintf(' the number of non-d variables is N = %g', numndv) disp(' ') % The next two lines are the key steps. First compute the null space % basis of the dimensional matrix D by use of null, then put the % result into reduced row echelon form by rref. The latter insures % that the first dimensional variable (the dependent variable) will % appear in one non-d variable only (the first one), and that % it will have an exponent of 1. Beyond that, it is hard to say % how nsb (the exponents of the basis set) will be arranged. nsb = null(D.','r').'; % find a basis set of non-d variables. % null seems to want the transpose of our D. nsb = rref(nsb); % sort nsb so that pi(1) has an exponent % =1 on the dependent variable. % all that follows is an attempt to make a useful display of % the result computed just above [nr nc] = size(nsb); % list the exponents on the input variables disp(' ') disp(' the dimensional variables and the exponents required to make') disp(' one possible basis set of non-d variables are:') disp(' ') for j = 1:nc fprintf(' %4s ', char(Ds(j))) end disp(' '), disp(' ') for jr=1:nr exponents = [sprintf('%9.4g ', nsb(jr,:))] end disp(' ') % if the symbolic toolbox is available, then we can % make a more easily interpreted display of the results % (if not, you should still get the exponents) Pi = 0; % just in case you can't do the following: % check to see if the symbolic toolbox is (really) available if exist('maplemex', 'file') == 3 clear Q QQ Pi eval('syms Q QQ Pi') % store the nc variable names for m=1:nc QQ(m) = char(Ds(1,m)); end % assemble the nr non-d variables for j1=1:nr Pi(j1) = prod(QQ.^nsb(j1,:)); end disp(' one possible set of non-d variables (Pi(1) ... Pi(N)) is:') pretty(Pi) end % if on symbolic toolbox disp(' ') function Dclear % Dclear: call this once at the start of a non-d % analysis problem to reset some variables. global D Ds jp nsb D = []; Ds = []; nsb = []; jp = 0; function Din(x, y) % Din: accept and store input to D and Ds. x is % a string with the variable name, y is a row matrix % of the exponents on each of the fundamental dimensions % that appear in x. The length of y must be the same for % each call to Din (within a given problem). global D Ds jp nsb jp = jp + 1; if jp == 1 Ds = {x}; % store x in a cell array else Ds = [Ds {x}]; % add on to Ds with each call end ny = length(y); % the number of fundamental dimensions D(jp, 1:ny) = y(1:ny); % store the exponents