No BSD License  

Highlights from
Dynamics of Some Classical System Models

from Dynamics of Some Classical System Models by Howard Wilson
Animated response of some classical systems.

[w,xm,ym,modes,bderr,modcofs]=elipmodes(...
function [w,xm,ym,modes,bderr,modcofs]=elipmodes(...
                 a,b,typ,nfrqs,step,nser,nbp,noplot)      
% [w,xm,ym,modes,bderr,modcofs]=elipmodes(...
%                a,b,typ,nfrqs,step,nser,nbp,noplot)
% See Article 10.7 (using a different method)
%
% This function computes natural frequencies and mode
% shapes of an elliptic membrane using the method
% presented by Dr. Cleve Moler in function membranetx.
%                    ---input--- 
% a,b     - ellipse major and minor semi-diameters
% typ     - 1 for modes symmetric about the x-axis
%           and zero on the boundary
%           2 for antisymmetric modes which are
%           zero on the boundary
%           3 for symmetric modes with zero normal
%           derivative on the boundary
%           4 for antisymmetric modes with zero
%           normal derivative on the boundary
% nfrqs   - number of frequencies to be computed
% step    - stepsize used in the frequency search.
%           A typical value is 0.01
% nser    - number of Bessel series terms used to 
%           approximate the modal functions. Values
%           of nser would typically be chosen
%           between 15 and 20.
% nbp     - number of boundary points used to
%           impose the boundary conditions. Taking
%           nbp equal to 101 is usually adequate.
% noplot  - an arbitrary value is input for this
%           variable to skip plotting 
%                    ---output---
% w       - vector of natural frequencies
% xm,ym   - coordinate matrices for plotting the
%           modal surfaces
% modes   - array in which modes(:,:,j) describes
%           the j'th modal surface
% modcofs - matrix in which modcofs(:,j) contains
%           the series coefficients for mode j.
%           These coefficients are scaled to make
%           the largest surface value of each 
%           mode equal unity.

%           by Howard Wilson, November,2004

if nargin<8, doplot=1; else, doplot=2; end
if nargin==0   % Interactive input
  disp(' ')
  disp('ELLIPTIC MEMBRANE FREQUENCIES')
  disp(' COMPUTED BY MOLER''S METHOD')
  disp(' ')
  [a,b]=readstr(...
            'Input semi-diameters a and b : ');
  disp(' ')      
  disp('Input function type, number of series')       
  disp(['terms, and number of ',...
             'boundary points.']); 
  [typ,nser,nbp]=readstr(...
         '(typical values are 1,15,101)  ? : ');
  disp(' ')   
  disp('Input number of frequencies sought')
  disp('and search increment size.')  
  [nfrqs,step]=readstr(...
            '(typical values are 20,.01)  ? : ');
  disp(' '), disp('Do you want modal plots ?')
  doplot=input('( 1 for yes or 2 for no)  ? : ');
end

% Generate points for boundary conditions
[x,y]=elipnts(a,b,nbp); x=x(:); y=y(:);
r=sqrt(x.*x+y.*y); th=atan2(y,x);

% Specify even or odd modes
if typ==1 | typ==3, 
    n=0:nser-1; thmat=cos(th*n); mult=1;
else
  n=1:nser; thmat=sin(th*n); mult=2;
end

% Search for frequencies
was=asymtroe(typ,a,b,0:nfrqs,1:nfrqs);
was=sort(was(:)); wmin=was(1)/2;
wmax=2*was(nfrqs); tic;
if typ==1 | typ==2    
  w=manym(@fzerobv,nfrqs,wmin,step,wmax,...
             n,r,thmat);
  w=w(:); nw=length(w);
  modcofs=zeros(nser,nw); cmat=[]; dmat=[];      
  % Evaluate series coefficients for the
  % Dirichlet boundary condition
  for j=1:nw
    [dumy,vj]=fzerobv(w(j),n,r,thmat);
    modcofs(:,j)=vj;
  end    
else
  [cmat,dmat]=elpbdrc(a,b,r,th,typ,nser);
  w=manym(@fzrobgrd,nfrqs,wmin,step,wmax,...
              nser,r,typ,cmat,dmat);
  w=w(:); nw=length(w);
  modcofs=zeros(nser,nw);        
  % Evaluate series coefficients for the
  % Neumann boundary condition
  for j=1:length(w)
    [dumy,vj]=fzrobgrd(w(j),nser,r,typ,...
        cmat,dmat); modcofs(:,j)=vj;
  end   
end

% Evaluate modal functions on a curvilinear
% coordinate grid
neta=181; nxi=16; %neta=81; nxi=10;
%neta=145; nxi=13;
[xm,ym,modes,bderr,modcofs]=modeshap(a,b,w,typ,...
                   modcofs,neta,nxi,r,cmat,dmat);
tim=toc; if doplot~=1, return; end

while 0
sa=num2str(a); sb=num2str(b);
sw=num2str(nw); st=num2str(tim);
disp(['Using a = ',sa,' and b = ',sb,...
      ', ',sw,' frequencies'])
disp(['and modes were found in ',...
       num2str(tim),' secs.'])
end  

t=linspace(0,2*pi,201); xb=a*cos(t); yb=b*sin(t);

% Show animated modal plots  
showmo(a,b,typ,w,xm,ym,modes,2);

%==========================================

function varargout=readstr(strng)
% varargout=readstr(strng) reads several
% data items on one line
if nargin==0, strng='>> ?  : '; end
f=input(strng,'s'); f=eval(['[',f,']']);
for j=1:length(f), varargout{j}=f(j); end

%==========================================

function [x,y,modes,bderr,modcofs]=modeshap(a,b,...
              w,typ,modcofs,neta,nxi,rb,cmat,dmat)
% [x,y,modes,bderr,modcofs]=modeshap(a,b,w,typ,...
%                   modcofs,neta,nxi,rb,cmat,dmat)

% function modeshap evaluates the modes for known
% frequencies and series coefficients. Normalized
% coefficients for the series expansions, and the 
% maximum error in satisfaction of the boundary
% conditions are also obtained.

% Get an elliptical coordinate grid
[x,y]=elipmap(a,b,neta,nxi); s=size(x);
x=x(:); y=y(:); nw=length(w);
nfun=size(modcofs,1);

% Use polar coordinates to evaluate the modal
% function series
r=sqrt(x.*x+y.*y); th=atan2(y,x);
if typ==1 | typ==3 % even valued modes
  N=0:nfun-1; thmat=cos(th*N);
else             % odd valued modes
  N=1:nfun; thmat=sin(th*N);
end

% Place successive modes as layers in a 3D      
% array
modes=zeros([s,nw]); bderr=zeros(nw,1);
for j=1:nw
    
  % Normalize maximum mode height to unity  
  mj=(besselj(N,w(j)*r).*thmat)*modcofs(:,j);
  [dumy,k]=max(abs(mj)); mbj=mj(k);
  mj=mj/mbj; modcofs(:,j)=modcofs(:,j)/mbj;
  modes(:,:,j)=reshape(mj,s);
end
x=reshape(x,s); y=reshape(y,s);

if typ<3
  % max error for Dirichlet boundary condition  
  bderr=max(abs(squeeze(modes(:,end,:))))';
else
  % max error for Neumann boundary condition  
  for k=1:nw
    wk=w(k);  
    if typ==3, J=besselj(-1:nfun,wk*rb);
    else, J=besselj(0:nfun+1,wk*rb); end
    A=wk/2*(J(:,1:end-2)-J(:,3:end)).*cmat+...
    J(:,2:end-1).*dmat; 
    bderr(k)=max(abs(A*modcofs(:,k)));
  end
end    

%==========================================

function [sigma,c]=fzerobv(w,n,r,thmat)
% [sigma,c]=fzerobv(w,n,r,thmat)
% This is the primary function used to
% compute frequencies for the case of zero
% boundary deflection. The natural fre-
% quencies are located where the smallest
% singular value of matix A has a relative
% minimum.
A=besselj(n,w*r).*thmat; N=length(n);
scale=diag(sparse(1./sqrt(sum(A.*A))));
A=A*scale; [u,s,v]= svd(A,0);
sigma=s(N,N); c=scale*v(:,N);

%==========================================

function [C,D]=elpbdrc(a,b,r,th,typ,nf)
% [C,D]=elpbdrc(a,b,r,th,typ,nf)
% This function computes matrices used to
% formulate a Neumann type boundary
% condition for an elliptic membrane
% The boundary condition has the form 
%   w*J'(nu,w*r)*C+J(nu,w*r)*D=0
% where either
% nu=0:nf-1 for even modes or
% nu=1:nf for odd modes
%
% a,b  - ellipse semi-diameters
% r,th - polar coordinates of points
%        on the top half of the ellipse
% typ  - 3 for even valued functions or
%        4 for odd valued functions
% nf   - the number of terms in the
%        modal function series
% C,D  - matrices used to form the grad-
%        ient type boundary condition.

r=r(:); th=th(:); c=cos(th); s=sin(th);
phi=c/a^2; psi=s/b^2; len=abs(phi+i*psi);
phi=phi./len; psi=psi./len;
if rem(typ,2)==1  % even valued function
  n=0:nf-1; C=c.*phi+s.*psi;
  C=C(:,ones(1,nf)).*cos(th*n); 
  D=s.*phi-c.*psi; D=D(:,ones(1,nf));
  D=(1./r)*n.*D.*sin(th*n);
else              % odd valued function
  n=1:nf; C=c.*phi+s.*psi;
  C=C(:,ones(1,nf)).*sin(th*n);
  D=s.*phi-c.*psi; D=D(:,ones(1,nf));
  D=(-1./r)*n.*D.*cos(th*n);
end

%==========================================

function [sig,c]=fzrobgrd(w,nf,r,typ,cmat,dmat)
% [sig,c]=fzrobgrd(w,nf,r,typ,cmat,dmat)
% This function formulates the boundary
% condition for a membrane with zero normal
% derivative on the edge.
if typ==3, J=besselj(-1:nf,w*r);
else, J=besselj(0:nf+1,w*r); end
A=w/2*(J(:,1:end-2)-J(:,3:end)).*cmat+...
                   J(:,2:end-1).*dmat;  
scale=diag(sparse(1./sqrt(sum(A.*A))));
A=A*scale; [u,s,v]= svd(A,0);
sig=s(nf,nf); c=scale*v(:,nf);

%==========================================

function [J,Jp]=Jeval(n,z)
% [J,Jp]=Jeval(n,z)
% This function evaluates J=besselj(n,z)
% and Jp=Besselj'(n,z)=...
% (besselj(n-1,z)-besselj(n+1,z))/2;
J=besselj([n(1)-1,n(:)',n(end)+1],z(:));
Jp=(J(:,1:end-2)-J(:,3:end))/2;
J=J(:,2:end-1);

%==========================================

function [x,y]=elipnts(a,b,n,nu)
% [x,y]=elipnts(a,b,n,nu)
% elipnts generates points equally spaced
% with respect to arc length on the top 
% half of an ellipse
if nargin<4, nu=500; end
tu=pi/(nu-1)*(0:nu-1)';
xu=a*cos(tu); yu=b*sin(tu);
su=[0;cumsum(abs(diff(xu+i*yu)))];
s=su(end)/(n-1)*(0:n-1)';
x=interp1q(su,xu,s); y=interp1q(su,yu,s);

%==========================================

function [x,y]=elipmap(a,b,neta,nxi,doplot)
% [x,y]=elipmap(a,b,neta,nxi,doplot)
% This function uses elliptical coordinates
% to compute a curvilinear coordinate grid
% on the interior of an ellipse
if nargin == 0
  doplot=1; nxi=8; neta=81; a=1; b=.5;
end
h=sqrt(a^2-b^2); r=atanh(b/a);
%[xi,eta]=meshgrid(linspace(0,r,nxi),...
%                  linspace(-pi,pi,neta));
rr=asinh(linspace(0,b/sqrt(a^2-b^2),nxi));
[xi,eta]=meshgrid(rr,linspace(-pi,pi,neta));              
z=h*cosh(xi+i*eta); x=real(z); y=imag(z);
if nargin > 4 | exist('doplot')
  plot(x,y,'k',x',y','k');
  title('ELLIPTICAL COORDINATE SYSTEM')
  xlabel('x axis'), ylabel('y axis')
  axis equal, shg
end

%==========================================

function [x,fmin]=manym(func,nrts,a,step,b,varargin)
% [x,fmin]=manym(func,nrts,a,step,b,varargin)
% This function searches for several minima of 
% a general function in a given interval.
% func     - handle for the function analyzed
% nrts     - number of roots sought
% a        - lower search limit 
% step     - the interval s searched in successive
%            increments of length step.
% b        - upper search limit
% varargin - auxiliary parameters needed by func
% x, fmin  - vector of minima and function values

f=[0 0 0]; x=[]; fmin=[]; nmin=0;
t=[a,a+step,a+2*step];
f(1)=feval(func,t(1),varargin{:});
f(2)=feval(func,t(2),varargin{:});
opts=optimset('tolx',1e-12);
while nmin<nrts & t(3)<= b  
  f(3)=feval(func,t(3),varargin{:});
  if f(1) > f(2) & f(2) < f(3)
    [xk,fk]=fminbnd(func,t(1),t(3),opts,...
                    varargin{:});
    x=[x,xk]; fmin=[fmin,fk]; nmin=nmin+1; 
  end
  t(1:2)=t(2:3); f(1:2)=f(2:3); t(3)=t(3)+step;
end

%==========================================

function showmo(a,b,typ,frqs,x,y,modes,tpause)
% showmo(a,b,typ,frqs,x,y,modes,tpause)
% ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
% This function makes surface or contour
% plots of the modal surfaces of a general 
% membrane for various frequencies. The 
% interactive part of the data input asks for
% a vector of modal indices (such as 1:5). If
% negative values are input (such as -(1:5)),
% then contour plots are made. Otherwise, 
% animated surface plots are presented.
%
% a,b    - ellipse semi diameters
% typ    - type of boundary condition.
%          1, 2, 3 or 4
% frqs   - vector of sorted frequencies
% x,y    - arrays of points defining the
%          curvilinear coordinate grid
% modes  - array of modal surfaces for 
%          the corresponding frequencies

if nargin<8, tpause=0; end
xmin=min(x(:)); xmax=max(x(:));
ymin=min(y(:)); ymax=max(y(:));
zmax=max(abs(modes(:)));
a=(xmax-xmin)/2; b=(ymax-ymin)/2;
th=linspace(0,2*pi,201)';
xx=a*cos(th); yy=b*sin(th);
nf=25; ft=cos(linspace(0,4*pi,nf));
nfrqs=length(frqs); ne=num2str(nfrqs);
%scalz=0.5/zmax*max(xmax-xmin,ymax-ymin);
scalz=1.0/zmax*max(xmax-xmin,ymax-ymin);
range=[xmin,xmax,ymin,ymax,-scalz,scalz];

while 0
disp(' ')
disp('   MODAL PLOTS FOR AN ELLIPTIC MEMBRANE')
%disp(' ')
disp(['The highest allowable frequency ',...,
      'index is ',ne])
end  

str1=['A = ',num2str(a),',  B = ',...
      num2str(b),',  TYPE = ',num2str(typ)];  
%%while 1
    
   while 0 
   jlim=[];
   while isempty(jlim), disp(' ')
     disp(['Give a vector of mode ',...
           'indices (such as 1:2:10 or']);
     jlim=input('input 0 to stop) > ? ');
   end
   if any(jlim<0), jlim=abs(jlim); pltype=1;
   else, pltype=2; end
   jj=find(jlim>nfrqs);
   if length(jj)>0
     disp(['The largest allowable ',...
           'modal index is ',ne])
     pause(2), jlim(jj)=[];
   end
   if any(jlim==0)
     disp(' '), disp('All done'), return
   end
   end
   
   jlim=1:10; pltype=2;
   for j=jlim
       
      %u=scalz*modes(:,:,j); 
      h=.25*a; u=modes(:,:,j);
      [dumy,k]=max(abs(u(:)));
      u=h/u(k)*u;
      
      if pltype==1
        % Draw contours  
        %u=modes(:,:,j);
        contour(x,y,u,60);
        axis equal, colormap([127/255 1 212/255])
        % colormap('default')
        str2=['FOR MODE ',num2str(j),...
           ',  OMEGA = ',num2str(frqs(j),6)];
        title({str2;str1})
        hold on; plot(xx,yy,'k');
        axis off, hold off, shg
      else
        % Draw animated surface 
        for kk=1:nf
           %surf(x,y,ft(kk)*u), axis equal
           surf(x,y,ft(kk)*1.5*u), axis equal
           %axis([xmin,xmax,ymin,ymax,-h,h]);
           axis([xmin,xmax,ymin,ymax,-1.5*h,1.5*h]);
           xlabel('x axis'), ylabel('y axis')
           zlabel('u(x,y)'), axis on
           str2=['FOR MODE ',num2str(j),...
           ',  OMEGA = ',num2str(frqs(j),6)];
           title({str2;str1})
           %colormap([1 1 0]), drawnow, shg
           %colormap('default'), drawnow, shg
           colormap([127/255 1 212/255])
           drawnow, shg, pause(.05)
        end
      
      end      
      if tpause==0, pause; else, pause(tpause); end
   end
%%end

%==========================================

function w=asymtroe(type,a,b,m,k)
% w=asymtroe(type,a,b,m,k) computes asymptotic
% approximations for zeros of Mc1 or Ms1
r=b/a; M=length(m); K=length(k);
m=m(:)*ones(1,K); k=ones(M,1)*k(:)';
if type==1
  w=((k-1/2)*pi+(m+1/2)*r+...
     (m.^2+m+1)./(4*k-2)*(r^2/pi))/b;
else
  w=(k*pi+(m-1/2)*r+...
    ((m-1).^2+m)./(4*k)*(r^2/pi))/b; 
end    

Contact us at files@mathworks.com