% MATLABScript for obtaning the analytical solution for 2D wave propagation % in a viscoelastic medium, based on the Appendix B of paper of Carcione et % al. (1988)(1), corrected in (2). % % The source used is a Ricker wavelet in the y velocity component. % % A figure of the source temporal function and its inverse Fourier % transform are provided to verify the good working of the method. Also % works for elastic variables by substituting the values of vp and vs by % real constant ones (vp_0 & vs_0). % % Attenuation is implemented by GMB-EK rheology presented in (4) and % thoroughfully explained in (3). % % In order to make a proper comparison with numerical data it is % recommended to either use the same rheology in both the numerical and the % analytical. It is also possible to get an almost constant Q value by % increasing a lot the number of mechanisms used in both the numerical and % the analytical solutions, thus minimizing the effects of the Q fitting in % the comparison. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% By Josep de la Puente, LMU Geophysics, 2005 %%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% home clear all; close all; disp('======================================') disp('COMPUTATION OF VISCOELASTIC ANALYTICAL') disp(' SOLUTION ') disp('======================================') disp(' ((c) Josep de la Puente Alvarez ') disp(' LMU Geophysics 2005)') disp('======================================') %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%% PARAMETERS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %Source parameters (Ricker wavelet): f0=10; % cutoff frequency t0=0.1; % time shift nu=0.5; % weight of exponential (for Carcione's source) epsilon=1.0; % weight of cosinus (for Carcione's source) %Frequency domain: w_max=1001; % Maximum frequency (minimum freq = -w_max). Is better to keep an odd number w_inc=0.1; % Increment in frequency %Position of receiver: x=0.5; y=0.5; %Force of the source: F=1.0; % Constant magnitude. Only alters amplitude of the seismograms %Material parameters: rho=1.0; % Density vp_0=sqrt(3); % P-wave velocity (elastic) vs_0=1; % S_wave velocity (elastic) %Attenuation Q-Solver parameters n=3; % Number of mechanisms we want to have QPval=20; % Desired QP constant value QSval=10; % Desired QS constant value freq=f0; % Central frequency of the absorption band (in Hertz). Good to center it % at the source's central frequency f_ratio=100; % The ratio between the maximum and minimum frequencies of our bandwidth % (Usually between 10^2 and 10^4) %Outputting variables toutmax=1.0; % Maximum value of t desired as output disp('--------------------------------------') disp(' GEOMETRY AND MATERIAL SETTINGS:'); disp('--------------------------------------') disp(strcat('Density= ',num2str(rho))); disp(strcat('VP= ',num2str(vp_0))); disp(strcat('VS= ',num2str(vs_0))); disp('Source at coordinates: (0,0)'); disp(strcat('Receiver at coordinates: (',num2str(x),',',num2str(y),')')); disp(' '); disp('--------------------------------------') disp(' ATTENUATION SETTINGS:'); disp('--------------------------------------') disp(strcat('Number of mechanisms= ',num2str(n))); disp(strcat('Q for P-wave= ',num2str(QPval))); disp(strcat('Q for S-wave= ',num2str(QSval))); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%% PROBLEM SETUP %%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %Derived quantities initialization r=sqrt(x^2+y^2); % Distance to the receiver w0=f0/(2*pi); % Conversion to angular velocity w=[0:w_inc:w_max]; w=2*w-w_max; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%% GMB-EK COMPLEX M SOLUTION %%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Equation system initialization %% kmax=2*n-1; %Number of equations to solve (the system is overdetermined) AP=zeros(kmax,n); %Initialization of system matrix (P wave) AS=zeros(kmax,n); %Initialization of system matrix (S wave) QP=ones(kmax,1)/QPval; %Desired values of Q for each mechanism inverted (P wave) QS=ones(kmax,1)/QSval; % " " (S wave) YP=zeros(n,1); YS=zeros(n,1); %% Selection of the logarithmically equispaced frequencies wmean=2*pi*freq; wmin_disc=wmean/sqrt(f_ratio); for j=1:kmax w_disc(j)=exp(log(wmin_disc)+(j-1)/(kmax-1)*log(f_ratio)); end %% Filling of the linear system matrix %% for m=1:kmax for j=1:n AP(m,j)=(w_disc(2*j-1).*w_disc(m)+w_disc(2*j-1).^2/QPval)./(w_disc(2*j-1).^2+w_disc(m).^2); end end for m=1:kmax for j=1:n AS(m,j)=(w_disc(2*j-1).*w_disc(m)+w_disc(2*j-1).^2/QSval)./(w_disc(2*j-1).^2+w_disc(m).^2); end end %% Solving of the system %% YP=AP\QP; YS=AS\QS; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%% VISUALIZATION OF Q IN FREQUENCY %%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Getting values for the continuous representation of Q %% wmin=wmean/sqrt(f_ratio); wmax=wmean*sqrt(f_ratio); xfrq=[wmin:(wmax-wmin)/(10000-1):wmax]; %% P-wave Q continuous values numP=0; denP=1; for j=1:n numP=numP+(YP(j)*w_disc(2*j-1)*xfrq(:))./(w_disc(2*j-1)^2+xfrq(:).^2); denP=denP-(YP(j)*w_disc(2*j-1).^2)./(w_disc(2*j-1)^2+xfrq(:).^2); end Q_contP=denP./numP; %% S-wave Q continuous values numS=0; denS=1; for j=1:n numS=numS+(YS(j)*w_disc(2*j-1)*xfrq(:))./(w_disc(2*j-1)^2+xfrq(:).^2); denS=denS-(YS(j)*w_disc(2*j-1).^2)./(w_disc(2*j-1)^2+xfrq(:).^2); end Q_contS=denS./numS; %% Computing fitting quality (RMS and maximum difference) maxPdif=0; maxSdif=0; for j=1:length(Q_contP) tempP=abs(Q_contP(j)-QPval); if tempP >= maxPdif maxPdif=tempP; end tempS=abs(Q_contS(j)-QSval); if tempS >= maxSdif maxSdif=tempS; end end subplot(1,2,1), semilogx(xfrq/(2*pi),Q_contP,xfrq/(2*pi),QPval*ones(length(xfrq),1)), title('Q for the P-wave'),legend('computed','desired') xlabel('frequency (Hz)'),ylabel('Q'),axis([wmin/(2*pi) wmax/(2*pi) 0 QPval*1.25]) subplot(1,2,2), semilogx(xfrq/(2*pi),Q_contS,xfrq/(2*pi),QSval*ones(length(xfrq),1)), title('Q for the S-wave'),legend('computed','desired'), xlabel('frequency (Hz)'),ylabel('Q'),axis([wmin/(2*pi) wmax/(2*pi) 0 QSval*1.25]) disp(strcat('Attenuation bandwidth= [',num2str(wmin/(2*pi)),',',num2str(wmax/(2*pi)),'] Hz')); disp(''); disp(strcat('Maximum QP fitting error= ',num2str(maxPdif/QPval*100),' %')); disp(''); disp(strcat('Maximum QS fitting error= ',num2str(maxSdif/QSval*100),' %')); disp(' '); disp('--------------------------------------') %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%% VELOCITIES COMPUTATION %%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Translating into Y_kappa and Y_mu %% YK=YP*0; YM=YP*0; YK(:)=(vp_0^2*YP(:)-4/3*vs_0^2*YS(:))/(vp_0^2-4/3*vs_0^2); YM(:)=YS(:); % Complex modulus mu_0=vs_0^2*rho; lam_0=vp_0^2*rho-2*mu_0; MUK=(lam_0+2/3*mu_0); % Elastic bulk modulus MUM=2*mu_0; % Elastic shear modulus MK=MUK*ones(length(w),1); MM=MUM*ones(length(w),1); lambda=zeros(length(w),1); mu=zeros(length(w),1); vp=zeros(length(w),1); vs=zeros(length(w),1); for j=1:n MK(:)=MK(:)-MUK*(YK(j)*(w_disc(2*j-1)./(w_disc(2*j-1)+i*w(:)))); MM(:)=MM(:)-MUM*(YM(j)*(w_disc(2*j-1)./(w_disc(2*j-1)+i*w(:)))); end lambda(:)=MK(:)-1/3*MM(:); mu(:)=MM(:)/2; % Complex wave velocities (NOTE: Substitute by vp_0 and vs_0 to get the % elastic solution) vp(:)=sqrt((lambda(:)+2*mu(:))/rho); vs(:)=sqrt(mu(:)/rho); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%% PROBLEM FUNCTIONS INITIALIZATION %%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Green's functions (CORRECTED, as appear in Carcione (2002)) for j=1:length(w) if w(j)>0 G1=-i*pi/2*(1/vp(j)^2*besselh(0,2,(w(j)*r/(vp(j))))+ ... 1./(w(j)*r*vs(j))*besselh(1,2,(w(j)*r/(vs(j))))- ... 1./(w(j)*r*vp(j))*besselh(1,2,(w(j)*r/(vp(j))))); G2=i*pi/2*(1/vs(j)^2*besselh(0,2,(w(j)*r/(vs(j))))- ... 1./(w(j)*r*vs(j))*besselh(1,2,(w(j)*r/(vs(j))))+ ... 1./(w(j)*r*vp(j))*besselh(1,2,(w(j)*r/(vp(j))))); u1(j)=F/(2*pi*rho)*(x*y/r^2)*(G1+G2); u2(j)=F/(2*pi*rho)*(1/r^2)*(y^2*G1-x^2*G2); end end %% Geting the symmetric conjugate of the u1 and u2 functions for j=1:length(w) u1(j)=conj(u1(length(w)+1-j)); u2(j)=conj(u2(length(w)+1-j)); end %Ricker type source S=sqrt(pi)*w.^2/(4*(pi*f0)^3).*exp(-i*w*t0).*exp(-w.^2/(4*(pi*f0)^2)); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%% PROBLEM SOLUTION %%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Construction of the w-space displacements PHI_DX=u1.*S; PHI_DY=u2.*S; %% Construction of the w-space velocities PHI_VX=PHI_DX.*i.*w; PHI_VY=PHI_DY.*i.*w; %% Time axis scaling by the Nyquist frequency dt=1/(2*w_max)*2*pi; %% FFT of the PHI functions to obtain solution Sol_x=(ifft(fftshift(PHI_DX)))/dt; Sol_y=(ifft(fftshift(PHI_DY)))/dt; %% Same for the velocities Vel_x=(ifft(fftshift(PHI_VX)))/dt; Vel_y=(ifft(fftshift(PHI_VY)))/dt; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%% VARIABLES' SCALING %%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% t=(1:length(w))*dt-dt ; %The substraction is to have a t=0 value %% Rescaling of the time variable to adjust to the t-space sampling rate for j=1:length(w)/2 t_res(j)=t(2*j-1); end %% Rescaling of the sampling of our function to compare with a t-domain %% function for j=1:length(w)/2 SX_res(j)=Sol_x(2*j-1); SY_res(j)=Sol_y(2*j-1); VX_res(j)=Vel_x(2*j-1); VY_res(j)=Vel_y(2*j-1); end %% MATLAB's "ifft" routines don't give us a purely real function for the %% inverse transform of a conjugate symmetric function. Therefore we have %% to correct the amplitudes with the small complex residues obtained. SX_res=abs(SX_res).*sign(real(SX_res)); SY_res=abs(SY_res).*sign(real(SY_res));; VX_res=abs(VX_res).*sign(real(VX_res)); VY_res=abs(VY_res).*sign(real(VY_res));; %% Looking for the t value closest to our desired tmax found=0; for j=1:length(t_res) if found==0 if t_res(j)>=toutmax countt=j; found=1; end end end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%% PLOTTING %%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Displacements displayed in desired time window minx=(min(real(SX_res(1:countt)))-eps)*1.2; maxx=(max(real(SX_res(1:countt)))+eps)*1.2; miny=(min(real(SY_res(1:countt)))-eps)*1.2; maxy=(max(real(SY_res(1:countt)))+eps)*1.2; figure, subplot(121),plot(t_res(1:countt),SX_res(1:countt),'-r'),xlabel('Time (sec)'), legend('x component'), axis([t_res(1) t_res(countt) minx maxx]),ylabel('x-displacement') title(strcat('Receiver at x= ',num2str(x),',y= ',num2str(y))) subplot(122),plot(t_res(1:countt),SY_res(1:countt),'-r'),xlabel('Time (sec)'), legend('y component'), axis([t_res(1) t_res(countt) miny maxy]),ylabel('y-dispplacement') title(strcat('Source frequency= ',num2str(f0),' Hz; Source delay= ',num2str(t0),'s')) % Velocities displayed in desired time window minx=(min(real(VX_res(1:countt)))-eps)*1.2; maxx=(max(real(VX_res(1:countt)))+eps)*1.2; miny=(min(real(VY_res(1:countt)))-eps)*1.2; maxy=(max(real(VY_res(1:countt)))+eps)*1.2; figure, subplot(121),plot(t_res(1:countt),VX_res(1:countt),'-k'),xlabel('Time (sec)'), legend('x component'), axis([t_res(1) t_res(countt) minx maxx]),ylabel('u velocity') title(strcat('Receiver at x= ',num2str(x),',y= ',num2str(y))) subplot(122),plot(t_res(1:countt),VY_res(1:countt),'-k'),xlabel('Time (sec)'), legend('y component'), axis([t_res(1) t_res(countt) miny maxy]),ylabel('v velocity'), title(strcat('Source frequency= ',num2str(f0),' Hz; Source delay= ',num2str(t0),'s')) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%% SOURCE COMPARISON %%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% As a check for the scalings chosen, we can compare the ifft of the %% Ricker source to the analytical expression of the inverse Fourier %% transform: B=pi*pi*f0*f0; %% Real time-domain expression of the Ricker wavelet source SOrig=t*0; SOrig=(0.5-B*(t-t0).*(t-t0)).*exp(-B*(t-t0).*(t-t0)); SS=ifft(fftshift(S))/dt; for j=1:length(w)/2 SS_res(j)=SS(2*j-1); end SS_res=abs(SS_res).*sign(real(SS_res)); minS=(min(real(SS_res(1:countt)))-eps)*1.2; maxS=(max(real(SS_res(1:countt)))+eps)*1.2; figure, plot(t(1:countt),SOrig(1:countt),'-b',t_res(1:countt),SS_res(1:countt),'.k'), title('MATLAB Check: ifft of the source') xlabel('time (s)'),axis([t_res(1) t_res(countt) minS maxS]), legend('Analytical source','ifft of the Analytical FT of the source') %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%% END OF THE PROGRAM !!! %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%% %% REFERENCES %% %%%%%%%%%%%%%%%% % (1) "WAVE PROPAGATION SIMULATION IN A LINEAR VISCOELASTIC MEDIUM", Carcione et al. (1988) % % (2) "WAVE FIELDS IN REAL MEDIA: WAVE PROPAGSTION IN ANISOTROPIC, ANELASTIC % AND POROUS MEDIA", Carcione (2002) % % (3) "THE FINITE DIFFERENCE METHOD FOR SEISMOLOGISTS: AN INTRODUCTION", % Moczo et al. (2005) % % (4) "INCORPORATION OF ATTENUATION INTO TIME-DOMAIN COMPUTATIONS OF % SEISMIC WAVE FIELDS", Emmerich & Korn (1987)