⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sem1d_impedance.m

📁 spectral element method
💻 M
字号:
% SEM1D	applies the Spectral Element Method% to solve the 1D SH wave equation, % with stress free boundary conditions,% zero initial conditions% and a time dependent force source.%% This script is intended for tutorial purposes.%% Jean-Paul Ampuero	jampuero@princeton.edu%% THIS VERSION: applied force on the bottom boundary%		absorbing condition on the top boundary% => analyze numerical impedance%------------------------------------------% STEP 1: MESH GENERATION% The interval [0,L] is divided into NEL non overlapping elements% The elements are defined by their "control nodes" XL=10;NEL = 10;X = [0:NEL]'*L/NEL;% add a viscous layer (one element) next to the boundary :NEL_VISC = 0;tvisc = 0.02; % viscous time /dt%------------------------------------------% STEP 2: INITIALIZATIONP = 8; % polynomial degreeNGLL = P+1; % number of GLL nodes per elementNT = 4096; % number of timestepsABSO_TOP = 1;ABSO_BOTTOM =0;% The Gauss-Lobatto-Legendre points and weights% and derivatives of the Lagrange polynomials H_ij = h'_i(xgll(j))% were pre-tabulated for the usual range of NGLL.% The xgll are in [-1,1][xgll,wgll,H] = GetGLL(NGLL,'gll');iglob = zeros(NGLL,NEL);	% local to global index mappingrho = zeros(NGLL,NEL);		% densitymu = zeros(NGLL,NEL);		% shear modulusnglob = NEL*(NGLL-1) + 1;	% number of global nodescoor = zeros(nglob,1);		% coordinates of GLL nodesM = zeros(nglob,1);		% global mass matrix, diagonalK = zeros(NGLL,NGLL,NEL);	% local stiffness matrixCFL = 0.5; 			% stability number 0.85dt = Inf;  			% timestep (set later)for e=1:NEL, % FOR EACH ELEMENT ... % The table I = iglob(i,e) maps the local numbering of the  % computational nodes (i,e) to their global numbering I. % 'iglob' is used to build global data  % from local data (contributions from each element)  iglob(:,e) = (e-1)*(NGLL-1)+(1:NGLL)'; % Coordinates of the computational (GLL) nodes  dxe = X(e+1)-X(e);  coor(iglob(:,e)) = 0.5*(X(e)+X(e+1)) + 0.5*dxe*xgll ; % Physical properties of the medium % can be heterogeneous inside the elements % and/or discontinuous across elements   rho(:,e) = 1;  mu(:,e) = 1; % For this simple mesh the jacobian of the global-local % coordinate map is a constant  dx_dxi = 0.5*dxe; % The diagonal mass matrix is stored in a global array.  % It is assembled here, from its local contributions % Nodes at the boundary between two elements get  % contributions from both.  M(iglob(:,e)) = M(iglob(:,e)) + wgll .*rho(:,e) *dx_dxi;% The stiffness matrix K is not assembled at this point% (it is sparse, block-diagonal)% We only store its local contributions  W = mu(:,e).*wgll/dx_dxi;%  K(:,:,e) = H * diag(W)* H';  K(:,:,e) = H * ( repmat(W,1,NGLL).* H');% The timestep dt is set by the stability condition%   dt = CFL*min(dx/vs)  vs = sqrt(mu(:,e)./rho(:,e));   vs = max( vs(1:NGLL-1), vs(2:NGLL) );  dx = abs(diff( coor(iglob(:,e)) ));  dt = min(dt, min(dx./vs));end %... of element loopdt = CFL*dt;half_dt = 0.5*dt;% absorbing boundaries% The mass matrix needs to be modified at the boundary% for the implicit treatment of the term C*v.if ABSO_TOP  BcTopC = sqrt(rho(NGLL,NEL)*mu(NGLL,NEL));  M(nglob) = M(nglob)+half_dt*BcTopC;endif ABSO_BOTTOM  BcBottomC = sqrt(rho(1,1)*mu(1,1));  M(1) = M(1)+half_dt*BcBottomC;end% treat implicitly the diagonal part of the damping matrix%if NEL_VISC%  Kdiag = zeros(NGLL,NEL_VISC);%  for e=1:NEL_VISC,%    ix = iglob(:,e);%    Kdiag(:,e) = diag(K(:,:,e));%    M(ix) = M(ix) + 0.1* 0.5*tvisc*Kdiag(:,e);%  end%end% Initialize kinematic fields, stored in global arraysd = zeros(nglob,1);v = zeros(nglob,1);a = zeros(nglob,1);f = zeros(nglob,1);% External force (SOURCE TERM), a Ricker wavelet% or velocity amplitude of an incoming waveF_IS_WAVE = 0;if ~F_IS_WAVE,  Fx = 0;  [Fdist,Fix] = min( abs(coor-Fx) );endFf0 = 3; % fundamental frequencyFt0 = 2/Ff0; % delay% source time function (at mid-steps)%Ft = ricker( (1:NT)'*dt-0.5*dt, Ff0,Ft0);%Ft = gabor( (1:NT)'*dt-0.5*dt, Ff0,Ft0, 80 );Ft = gaussian( (1:NT)'*dt-0.5*dt, Ff0,Ft0 );% output arraysOUTdt = 1;	% output every OUTdt timestepsOUTit = 0;	% a counterOUTnt = NT/OUTdt; % number of output timesteps% output receivers at these locationsOUTx  = [0:dxe/2:L]';OUTnx = length(OUTx);OUTix = zeros(OUTnx,1);% relocate to nearest GLL nodeOUTdist = zeros(OUTnx,1);for i=1:OUTnx,  [OUTdist(i),OUTix(i)] = min( abs(coor-OUTx(i)) );endOUTx = coor(OUTix);OUTd = zeros(OUTnx,OUTnt);OUTv = zeros(OUTnx,OUTnt);OUTa = zeros(OUTnx,OUTnt);%------------------------------------------% STEP 3: SOLVER  M*a = -K*d +F% Explicit Newmark-alpha scheme with% alpha=1/2, beta=1/2, gamma=1%for it=1:NT, % prediction of mid-step displacement: % d_mid = d_old + 0.5*dt*v_old  d = d + half_dt*v;   f(:) = 0; % internal forces at mid-step -K*d(t+1/2)   for e=1:NEL,    ix = iglob(:,e);    f(ix) = f(ix) - K(:,:,e)*d(ix) ;  end  % viscous layer:  for e=1:NEL_VISC    ix = iglob(:,e);    f(ix) = f(ix) - tvisc* K(:,:,e)*v(ix);   end % add external forces  if ~F_IS_WAVE, f(Fix) = f(Fix) + Ft(it); end % absorbing boundary  if ABSO_TOP, f(nglob) = f(nglob) -BcTopC*v(nglob); end  if ABSO_BOTTOM,     if F_IS_WAVE % incident wave, from bottom     %boundary term = -impedance*v_outgoing + impedance*v_incoming      f(1) = f(1) -BcBottomC*( v(1) -Ft(it) ) + BcBottomC*Ft(it);    else      f(1) = f(1) -BcBottomC*v(1);    end  end % acceleration: a = (-K*d +F)/M  a = f ./M ; % update % v_new = v_old + dt*a_new; % d_new = d_old + dt*v_old + 0.5*dt^2*a_new %       = d_mid + 0.5*dt*v_new  v = v + dt*a;  d = d + half_dt*v;%------------------------------------------% STEP 4: OUTPUT    if mod(it,OUTdt) == 0    OUTit = OUTit+1;    OUTd(:,OUTit) = d(OUTix);    OUTv(:,OUTit) = v(OUTix);    OUTa(:,OUTit) = a(OUTix);  endend % of time loopt = (1:OUTit) *OUTdt*dt;figure(1)PlotSeisTrace(OUTx,t,OUTv);figure(2)ista=1;subplot(311)[freq,fv]=plot_spec(OUTv(ista,:),dt);ylabel('velocity bottom boundary')subplot(312)[freq,fFt] = plot_spec(Ft,dt);ylabel('source time function')hold on; loglog( [freq(1) freq(end)], [1e-3 1e-3]*max(fFt),':');hold offsubplot(313)loglog(freq,fFt./fv)ylabel('impedance = f/v')

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -