├── Acoustic FWI in the frequency domain.pdf ├── FWI2.m ├── FWI_solver.m ├── README.md ├── generate_true_recordings.m ├── log.txt ├── rickerWave.m ├── solver.m ├── taperGradient_not_used.m ├── test.m ├── trueModel.mat └── true_rect.mat /Acoustic FWI in the frequency domain.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/deconvolution/FWI/6298b5f32ebbe7fccff1cac0f4d6f9e1767db934/Acoustic FWI in the frequency domain.pdf -------------------------------------------------------------------------------- /FWI2.m: -------------------------------------------------------------------------------- 1 | %% input parameters 2 | clear all; 3 | close all; 4 | load('true_rect.mat'); 5 | dims.dh=10; 6 | lp=30; 7 | % initial velocity model 8 | v0=ones([51,101])*2500; 9 | % estimation to first layer thickness 10 | l1=15; 11 | % estimation to first layer velocity 12 | %v0(l1:end,:)=2300; 13 | dims.dt=10^-3; % [s] 14 | dims.nz0=size(v0,1); % Cells in z-direction 15 | dims.nx0=size(v0,2); % Cells in x-direction 16 | dims.nt=1000; % Amount of time steps 17 | dims.ns=dims.nt; 18 | %% extend the velocity model region to employ PML 19 | v=v0; 20 | temp=v0(1,:); 21 | temp2=v0(end,:); 22 | v=[temp(ones(lp,1),:); 23 | v; 24 | temp2(ones(lp,1),:)]; 25 | temp3=v(:,1); 26 | temp4=v(:,end); 27 | v=[temp3(:,ones(1,lp)),v,temp4(:,ones(1,lp))]; 28 | figure; 29 | imagesc(v); 30 | colorbar; 31 | xlabel({['x*' num2str(dims.dh) '[m]']}); 32 | ylabel({['z*' num2str(dims.dh) '[m]']}); 33 | hold on; 34 | plot([lp+1,dims.nx0+lp],[lp+1,lp+1],'color','red'); 35 | hold on; 36 | plot([lp+1,dims.nx0+lp],[lp+dims.nz0,lp+dims.nz0],'color','red'); 37 | hold on; 38 | plot([lp+1,lp+1],[lp+1,lp+dims.nz0],'color','red'); 39 | hold on; 40 | plot([dims.nx0+lp,dims.nx0+lp],[lp+1,lp+dims.nz0],'color','red'); 41 | axis on; 42 | shg; 43 | Rc=.1; 44 | %% Model dimensions 45 | dims.nz=size(v,1); 46 | dims.nx=size(v,2); 47 | % mz=31:81 48 | dims.mz=lp+1:dims.nz0+lp; 49 | % mx=31:131 50 | dims.mx=lp+1:dims.nx0+lp; 51 | %% source 52 | singles=rickerWave(10,dims); 53 | dims.sx=min(dims.mx); 54 | dims.sz=min(dims.mz); 55 | %% Receiver locations 56 | dims.rx=min(dims.mx):max(dims.mx); 57 | dims.rz=min(dims.mz)*ones(1,length(dims.rx)); 58 | %% source 59 | fs=1/dims.dt; 60 | L=dims.nt; 61 | n=2000; 62 | f=fs*(0:(n/2))/n; 63 | s=zeros([dims.nz*dims.nx,1]); 64 | source_freq=fft(singles,n)/(n/2); 65 | source_freq2=source_freq(1:n/2+1); 66 | % check source 67 | source_time=ifft(source_freq2,n,1)*n; 68 | figure('name','source signals'); 69 | subplot(3,1,1) 70 | plot(dims.dt:dims.dt:dims.dt*L,real(singles)); 71 | xlabel(['t [s]']); 72 | title('original'); 73 | subplot(3,1,2) 74 | plot(dims.dt:dims.dt:dims.dt*L,real(source_time(1:dims.nt))); 75 | xlabel(['t' [s]']); 76 | title('transformed from frequency'); 77 | subplot(3,1,3) 78 | plot(abs(source_freq2)); 79 | %aa=reshape(aa,[300,1]); 80 | %plot(real(aa)) 81 | title('frequency domain'); 82 | shg; 83 | %% find effective frequency of source 84 | s_diff=diff(abs(source_freq2)); 85 | s_diff=[s_diff(1);s_diff]; 86 | s_lim=find(abs(source_freq2)<.1*max(abs(source_freq2)) & s_diff<0); 87 | s_lim2=s_lim(1); 88 | f_range=1:s_lim2; 89 | f2=f(f_range); 90 | ome=2*pi*f2; 91 | % source term 92 | sf=source_freq2(1:s_lim2); 93 | %% source location in FWI 94 | shot_interval=10; 95 | sx0=dims.sx(1):shot_interval:dims.sx(end); 96 | sz0=dims.sz(1)*ones(size(sx0)); 97 | % extend source term 98 | sf2=sf*ones(1,length(sx0)); 99 | % sf2=sf(:,ones(3,1)); 100 | %% find effective frequency for true_rect 101 | n_true_recf=n; 102 | fs2=fs; 103 | f2=fs2*(0:(n_true_recf/2))/n_true_recf; 104 | true_recf=fft(true_rect,n_true_recf,1)/(n_true_recf/2); 105 | true_recf=true_recf(1:s_lim2,:,:); 106 | %% solver parameters 107 | nz=dims.nz; 108 | nx=dims.nx; 109 | 110 | dh=dims.dh; 111 | nt=dims.nt; 112 | % ome 113 | % sf 114 | rz=dims.rz; 115 | rx=dims.rx; 116 | 117 | n_iteration=20; 118 | alp_progress=zeros([length(n_iteration)+1,1]); 119 | of_progress=zeros([length(n_iteration)+1,1]); 120 | 121 | d0=log(1/Rc)/log(10)*3*v/2/lp; 122 | gmax1=150; 123 | C=zeros(length(n_iteration),1); 124 | FID=fopen('log.txt','w'); 125 | tic; 126 | for l=1:n_iteration 127 | fprintf('\n current iteration=%d/%d \t time=%f s',l,n_iteration,toc); 128 | fprintf(FID,'\n current iteration=%d/%d \t time=%f s',l,n_iteration,toc); 129 | %% 130 | vg=zeros(size(v)); 131 | %% gradient 132 | for i=1:length(sx0) 133 | loc=(i-1)*shot_interval+1; 134 | fprintf('\n \t current shot number=%d/%d',i,length(sx0)); 135 | fprintf(FID,'\n \t current shot number=%d/%d',i,length(sx0)); 136 | true_recfs=true_recf(:,:,loc); 137 | [pf,recf,Ct,vgt]=FWI_solver(nz,nx,dh,sz0(i),sx0(i),ome,sf2(:,i),rz,rx,v,lp,d0,true_recfs); 138 | vg=vgt+vg; 139 | end 140 | vg=vg/length(sx0); 141 | %vg=taperGradient(vg,lp,l1); 142 | C(l)=Ct/length(sx0); 143 | fprintf('\n \t\t\t Cost=%f',C(l)); 144 | fprintf(FID,'\n \t Cost=%f',C(l)); 145 | fprintf(FID,'\n \t max gradient=%f',max(abs(vg(:)))); 146 | %% optimization 147 | % max gradient for the first iteration 148 | if l==1 149 | alp=gmax1/max(abs(vg(:))); 150 | end 151 | v=v-alp*vg; 152 | figure(99) 153 | subplot(2,1,1) 154 | imagesc(vg); 155 | hold on; 156 | plot([lp+1,nx-lp],[lp+1,lp+1],'color','red'); 157 | hold on; 158 | plot([lp+1,nx-lp],[nz-lp,nz-lp],'color','red'); 159 | hold on; 160 | plot([lp+1,lp+1],[lp+1,nz-lp],'color','red'); 161 | hold on; 162 | plot([nx-lp,nx-lp],[lp+1,nz-lp],'color','red'); 163 | title({['G [m/s]'],[ 'max gradient= ' num2str(max(abs(vg(:))))]}); 164 | colorbar; 165 | subplot(2,1,2) 166 | imagesc(v); 167 | hold on; 168 | plot([lp+1,nx-lp],[lp+1,lp+1],'color','red'); 169 | hold on; 170 | plot([lp+1,nx-lp],[nz-lp,nz-lp],'color','red'); 171 | hold on; 172 | plot([lp+1,lp+1],[lp+1,nz-lp],'color','red'); 173 | hold on; 174 | plot([nx-lp,nx-lp],[lp+1,nz-lp],'color','red'); 175 | colorbar; 176 | title('v [m/s]'); 177 | shg; 178 | end 179 | fclose(FID); 180 | %% 181 | figure('name','final result'); 182 | subplot(2,2,1) 183 | load('trueModel.mat'); 184 | imagesc(trueModel); 185 | colorbar; 186 | title('true model'); 187 | subplot(2,2,2) 188 | imagesc(v(dims.mz,dims.mx)); 189 | colorbar; 190 | title('inversion result'); 191 | subplot(2,2,3) 192 | imagesc(v(dims.mz,dims.mx)-trueModel); 193 | title('error'); 194 | %% 195 | -------------------------------------------------------------------------------- /FWI_solver.m: -------------------------------------------------------------------------------- 1 | function [pf,recf,C2,vg]=FWI_solver(nz,nx,dh,sz,sx,ome,sf,rz,rx,v,lp,d0,true_recfs) 2 | % linearized wave equation 3 | % dims frequency sample number 4 | % Source: source signals in frequency domain 5 | % lp: layers of PML 6 | % d0: for PML, could be related to R (reflection coefficient) 7 | %% 8 | AA=sparse(nz*nx,nz*nx); 9 | s=zeros(nz*nx,length(ome)); 10 | pf=zeros(nz*nx,length(ome)); 11 | recf=zeros(length(rx),length(ome)); 12 | % sampling operator 13 | R=zeros(length(rx),nz*nx); 14 | C=zeros(length(ome),1); 15 | true_recfs2=true_recfs.'; 16 | vg=zeros(nz,nx); 17 | %% 18 | for i=1:size(R,1) 19 | R(i,(rx(i)-1)*nz+rz(i))=1; 20 | end 21 | %% 22 | for i=1:length(sx) 23 | s(sz(i)+(sx(i)-1)*nz,:)=sf(:,i); 24 | end 25 | %% 26 | for l=2:length(ome) 27 | %% assign d 28 | dx=zeros(nz,nx); 29 | dz=zeros(nz,nx); 30 | % top 31 | for i=2:lp+1 32 | for j=lp+2:nx-lp-1 33 | dx(i,j)=0; 34 | dz(i,j)=d0(i,j)*((lp+2-i)/lp)^2; 35 | end 36 | end 37 | % bottom 38 | for i=nz-lp:nz-1 39 | for j=lp+2:nx-lp-1 40 | dx(i,j)=0; 41 | dz(i,j)=d0(i,j)*((i+1-(nz-lp))/lp)^2; 42 | end 43 | end 44 | % left 45 | for i=lp+2:nz-lp-1 46 | for j=2:lp+1 47 | dz(i,j)=0; 48 | dx(i,j)=d0(i,j)*((lp+2-j)/lp)^2; 49 | end 50 | end 51 | % right 52 | for i=lp+1:nz-lp-1 53 | for j=nx-lp:nx-1 54 | dz(i,j)=0; 55 | dx(i,j)=d0(i,j)*((j+1-(nx-lp))/lp)^2; 56 | end 57 | end 58 | % upper left 59 | for i=2:lp+1 60 | for j=2:lp+1 61 | dz(i,j)=d0(i,j)*((lp+2-i)/lp)^2; 62 | dx(i,j)=d0(i,j)*((lp+2-j)/lp)^2; 63 | end 64 | end 65 | % upper right 66 | for i=2:lp+1 67 | for j=nx-lp:nx-1 68 | dz(i,j)=d0(i,j)*((lp+2-i)/lp)^2; 69 | dx(i,j)=d0(i,j)*((j+1-(nx-lp))/lp)^2; 70 | end 71 | end 72 | % lower left 73 | for i=nz-lp:nz-1 74 | for j=2:lp+1 75 | dz(i,j)=d0(i,j)*((i+1-(nz-lp))/lp)^2; 76 | dx(i,j)=d0(i,j)*((lp+2-j)/lp)^2; 77 | end 78 | end 79 | % lower right 80 | for i=nz-lp:nz-1 81 | for j=nx-lp:nx-1 82 | dz(i,j)=d0(i,j)*((i+1-(nz-lp))/lp)^2; 83 | dx(i,j)=d0(i,j)*((j+1-(nx-lp))/lp)^2; 84 | end 85 | end 86 | gx=1+dx/1i./ome(l); 87 | gz=1+dz/1i./ome(l); 88 | gx_x=diff(gx,1,2)/dh; 89 | gz_z=diff(gz,1,1)/dh; 90 | gx_x=[-gx_x(:,1:end-31),zeros([size(gx_x,1),1]),gx_x(:,end-30:end)]; 91 | gx_x(:,1)=0; 92 | gx_x(:,end)=0; 93 | gz_z=[-gz_z(1:end-31,:);zeros([1,size(gz_z,2)]);gz_z(end-30:end,:)]; 94 | gz_z(1,:)=0; 95 | gz_z(end,:)=0; 96 | %% domain interior 97 | for i=lp+2:nz-1 98 | for j=lp+2:nx-1 99 | % i,j 100 | AA((j-1)*nz+i,(j-1)*nz+i)=(ome(l)^2-2*v(i,j)^2/gx(i,j)^2/dh^2-2*v(i,j)^2/gz(i,j)^2/dh^2)/v(i,j)^2; 101 | 102 | % i,j+1 103 | AA((j-1)*nz+i,(j)*nz+i)=(-v(i,j)^2/2/gx(i,j)^3/dh*gx_x(i,j)+v(i,j)^2/gx(i,j)^2/dh^2)/v(i,j)^2; 104 | % i,j-1 105 | AA((j-1)*nz+i,(j-2)*nz+i)=(v(i,j)^2/2/gx(i,j)^3/dh*gx_x(i,j)+v(i,j)^2/gx(i,j)^2/dh^2)/v(i,j)^2; 106 | 107 | % i+1,j 108 | AA((j-1)*nz+i,(j-1)*nz+i+1)=(-v(i,j)^2/2/gz(i,j)^3/dh*gz_z(i,j)+v(i,j)^2/gz(i,j)^2/dh^2)/v(i,j)^2; 109 | % i-1,j 110 | AA((j-1)*nz+i,(j-1)*nz+i-1)=(v(i,j)^2/2/gz(i,j)^3/dh*gz_z(i,j)+v(i,j)^2/gz(i,j)^2/dh^2)/v(i,j)^2; 111 | end 112 | end 113 | %% top local 114 | for i=2:lp+1 115 | for j=lp+2:nx-lp-1 116 | % i,j 117 | AA((j-1)*nz+i,(j-1)*nz+i)=(ome(l)^2-2*v(i,j)^2/gx(i,j)^2/dh^2-2*v(i,j)^2/gz(i,j)^2/dh^2)/v(i,j)^2; 118 | 119 | % i,j+1 120 | AA((j-1)*nz+i,(j)*nz+i)=(-v(i,j)^2/2/gx(i,j)^3/dh*gx_x(i,j)+v(i,j)^2/gx(i,j)^2/dh^2)/v(i,j)^2; 121 | % i,j-1 122 | AA((j-1)*nz+i,(j-2)*nz+i)=(v(i,j)^2/2/gx(i,j)^3/dh*gx_x(i,j)+v(i,j)^2/gx(i,j)^2/dh^2)/v(i,j)^2; 123 | 124 | % i+1,j 125 | AA((j-1)*nz+i,(j-1)*nz+i+1)=(v(i,j)^2/2/gz(i,j)^3/dh*gz_z(i,j)+v(i,j)^2/gz(i,j)^2/dh^2)/v(i,j)^2; 126 | % i-1,j 127 | AA((j-1)*nz+i,(j-1)*nz+i-1)=(-v(i,j)^2/2/gz(i,j)^3/dh*gz_z(i,j)+v(i,j)^2/gz(i,j)^2/dh^2)/v(i,j)^2; 128 | end 129 | end 130 | %% left local 131 | for i=lp+2:nz-lp-1 132 | for j=2:lp+1 133 | % i,j 134 | AA((j-1)*nz+i,(j-1)*nz+i)=(ome(l)^2-2*v(i,j)^2/gx(i,j)^2/dh^2-2*v(i,j)^2/gz(i,j)^2/dh^2)/v(i,j)^2; 135 | 136 | % i,j+1 137 | AA((j-1)*nz+i,(j)*nz+i)=(v(i,j)^2/2/gx(i,j)^3/dh*gx_x(i,j)+v(i,j)^2/gx(i,j)^2/dh^2)/v(i,j)^2; 138 | % i,j-1 139 | AA((j-1)*nz+i,(j-2)*nz+i)=(-v(i,j)^2/2/gx(i,j)^3/dh*gx_x(i,j)+v(i,j)^2/gx(i,j)^2/dh^2)/v(i,j)^2; 140 | 141 | % i+1,j 142 | AA((j-1)*nz+i,(j-1)*nz+i+1)=(-v(i,j)^2/2/gz(i,j)^3/dh*gz_z(i,j)+v(i,j)^2/gz(i,j)^2/dh^2)/v(i,j)^2; 143 | % i-1,j 144 | AA((j-1)*nz+i,(j-1)*nz+i-1)=(v(i,j)^2/2/gz(i,j)^3/dh*gz_z(i,j)+v(i,j)^2/gz(i,j)^2/dh^2)/v(i,j)^2; 145 | end 146 | end 147 | %% upper left 148 | for i=2:lp+1 149 | for j=2:lp+1 150 | % i,j 151 | AA((j-1)*nz+i,(j-1)*nz+i)=(ome(l)^2-2*v(i,j)^2/gx(i,j)^2/dh^2-2*v(i,j)^2/gz(i,j)^2/dh^2)/v(i,j)^2; 152 | 153 | % i,j+1 154 | AA((j-1)*nz+i,(j)*nz+i)=(v(i,j)^2/2/gx(i,j)^3/dh*gx_x(i,j)+v(i,j)^2/gx(i,j)^2/dh^2)/v(i,j)^2; 155 | % i,j-1 156 | AA((j-1)*nz+i,(j-2)*nz+i)=(-v(i,j)^2/2/gx(i,j)^3/dh*gx_x(i,j)+v(i,j)^2/gx(i,j)^2/dh^2)/v(i,j)^2; 157 | 158 | % i+1, 159 | AA((j-1)*nz+i,(j-1)*nz+i+1)=(v(i,j)^2/2/gz(i,j)^3/dh*gz_z(i,j)+v(i,j)^2/gz(i,j)^2/dh^2)/v(i,j)^2; 160 | % i-1,j 161 | AA((j-1)*nz+i,(j-1)*nz+i-1)=(-v(i,j)^2/2/gz(i,j)^3/dh*gz_z(i,j)+v(i,j)^2/gz(i,j)^2/dh^2)/v(i,j)^2; 162 | end 163 | end 164 | %% upper right 165 | for i=2:lp+1 166 | for j=nx-lp:nx-1 167 | % i,j 168 | AA((j-1)*nz+i,(j-1)*nz+i)=(ome(l)^2-2*v(i,j)^2/gx(i,j)^2/dh^2-2*v(i,j)^2/gz(i,j)^2/dh^2)/v(i,j)^2; 169 | 170 | % i,j+1 171 | AA((j-1)*nz+i,(j)*nz+i)=(-v(i,j)^2/2/gx(i,j)^3/dh*gx_x(i,j)+v(i,j)^2/gx(i,j)^2/dh^2)/v(i,j)^2; 172 | % i,j-1 173 | AA((j-1)*nz+i,(j-2)*nz+i)=(v(i,j)^2/2/gx(i,j)^3/dh*gx_x(i,j)+v(i,j)^2/gx(i,j)^2/dh^2)/v(i,j)^2; 174 | 175 | % i+1,j 176 | AA((j-1)*nz+i,(j-1)*nz+i+1)=(v(i,j)^2/2/gz(i,j)^3/dh*gz_z(i,j)+v(i,j)^2/gz(i,j)^2/dh^2)/v(i,j)^2; 177 | % i-1,j 178 | AA((j-1)*nz+i,(j-1)*nz+i-1)=(-v(i,j)^2/2/gz(i,j)^3/dh*gz_z(i,j)+v(i,j)^2/gz(i,j)^2/dh^2)/v(i,j)^2; 179 | end 180 | end 181 | %% lower left 182 | for i=nz-lp:nz-1 183 | for j=2:lp+1 184 | % i,j 185 | AA((j-1)*nz+i,(j-1)*nz+i)=(ome(l)^2-2*v(i,j)^2/gx(i,j)^2/dh^2-2*v(i,j)^2/gz(i,j)^2/dh^2)/v(i,j)^2; 186 | 187 | % i,j+1 188 | AA((j-1)*nz+i,(j)*nz+i)=(v(i,j)^2/2/gx(i,j)^3/dh*gx_x(i,j)+v(i,j)^2/gx(i,j)^2/dh^2)/v(i,j)^2; 189 | % i,j-1 190 | AA((j-1)*nz+i,(j-2)*nz+i)=(-v(i,j)^2/2/gx(i,j)^3/dh*gx_x(i,j)+v(i,j)^2/gx(i,j)^2/dh^2)/v(i,j)^2; 191 | 192 | % i+1,j 193 | AA((j-1)*nz+i,(j-1)*nz+i+1)=(-v(i,j)^2/2/gz(i,j)^3/dh*gz_z(i,j)+v(i,j)^2/gz(i,j)^2/dh^2)/v(i,j)^2; 194 | % i-1,j 195 | AA((j-1)*nz+i,(j-1)*nz+i-1)=(v(i,j)^2/2/gz(i,j)^3/dh*gz_z(i,j)+v(i,j)^2/gz(i,j)^2/dh^2)/v(i,j)^2; 196 | end 197 | end 198 | %% boundary line 199 | %% B2 200 | i=1; 201 | for j=2:nx-1 202 | AA((j-1)*nz+i,(j-1)*nz+i)=-1/dh-1i*ome(l)/(v(i,j)); 203 | %AA((j-1)*nz+i,(j)*nz+i)=1/dh^2; 204 | %AA((j-1)*nz+i,(j-2)*nz+i)=1/dh^2; 205 | %AA((j-1)*nz+i,(j-1)*nz+i-1)=1/dh^2; 206 | AA((j-1)*nz+i,(j-1)*nz+i+1)=1/dh; 207 | end 208 | %% B3 209 | i=nz; 210 | for j=2:nx-1 211 | AA((j-1)*nz+i,(j-1)*nz+i)=-1/dh-1i*ome(l)/(v(i,j)); 212 | %AA((j-1)*nz+i,(j)*nz+i)=1/dh; 213 | %AA((j-1)*nz+i,(j-2)*nz+i)=1/dh; 214 | AA((j-1)*nz+i,(j-1)*nz+i-1)=1/dh; 215 | %AA((j-1)*nz+i,(j-1)*nz+i+1)=1/dh; 216 | end 217 | %% B4 218 | j=nx; 219 | for i=2:nz-1 220 | AA((j-1)*nz+i,(j-1)*nz+i)=-1/dh-1i*ome(l)/(v(i,j)); 221 | %AA((j-1)*nz+i,(j)*nz+i)=1/dh; 222 | AA((j-1)*nz+i,(j-2)*nz+i)=1/dh; 223 | %AA((j-1)*nz+i,(j-1)*nz+i-1)=1/dh; 224 | %AA((j-1)*nz+i,(j-1)*nz+i+1)=1/dh; 225 | end 226 | %% B5 227 | j=1; 228 | for i=2:nz-1 229 | AA((j-1)*nz+i,(j-1)*nz+i)=-1/dh-1i*ome(l)/(v(i,j)); 230 | AA((j-1)*nz+i,(j)*nz+i)=1/dh; 231 | %AA((j-1)*nz+i,(j-2)*nz+i)=1/dh; 232 | %AA((j-1)*nz+i,(j-1)*nz+i-1)=1/dh; 233 | %AA((j-1)*nz+i,(j-1)*nz+i+1)=1/dh; 234 | end 235 | %% B6 236 | j=nx; 237 | i=1; 238 | AA((j-1)*nz+i,(j-1)*nz+i)=-2/dh-2i*ome(l)/(v(i,j)); 239 | %AA((j-1)*nz+i,(j)*nz+i)=1/dh; 240 | AA((j-1)*nz+i,(j-2)*nz+i)=1/dh; 241 | %AA((j-1)*nz+i,(j-1)*nz+i-1)=1/dh; 242 | AA((j-1)*nz+i,(j-1)*nz+i+1)=1/dh; 243 | %% B7 244 | j=1; 245 | i=1; 246 | AA((j-1)*nz+i,(j-1)*nz+i)=-2/dh-2i*ome(l)/(v(i,j)); 247 | AA((j-1)*nz+i,(j)*nz+i)=1/dh; 248 | %AA((j-1)*nz+i,(j-2)*nz+i)=1/dh; 249 | %AA((j-1)*nz+i,(j-1)*nz+i-1)=1/dh; 250 | AA((j-1)*nz+i,(j-1)*nz+i+1)=1/dh; 251 | %% B8 252 | i=nz; 253 | j=nx; 254 | AA((j-1)*nz+i,(j-1)*nz+i)=-2/dh-2i*ome(l)/(v(i,j)); 255 | %AA((j-1)*nz+i,(j)*nz+i)=1/dh; 256 | AA((j-1)*nz+i,(j-2)*nz+i)=1/dh; 257 | AA((j-1)*nz+i,(j-1)*nz+i-1)=1/dh; 258 | %AA((j-1)*nz+i,(j-1)*nz+i+1)=1/dh; 259 | %% B9 260 | j=1; 261 | i=nz; 262 | AA((j-1)*nz+i,(j-1)*nz+i)=-2/dh-2i*ome(l)/(v(i,j)); 263 | AA((j-1)*nz+i,(j)*nz+i)=1/dh; 264 | %AA((j-1)*nz+i,(j-2)*nz+i)=1/dh; 265 | AA((j-1)*nz+i,(j-1)*nz+i-1)=1/dh; 266 | %AA((j-1)*nz+i,(j-1)*nz+i+1)=1/dh; 267 | %% solve Ax=b 268 | p0=AA\(-s(:,l)); 269 | pf(:,l)=p0; 270 | %% sampling 271 | recf(:,l)=R*p0; 272 | %% cost 273 | e=recf(:,l)-true_recfs2(:,l); 274 | C(l)=norm(e); 275 | %% 276 | paf=AA'\(R'*e); 277 | %% adjoint field 278 | t2=ome(l)^2*(diag(pf(:,l)))'*paf; 279 | %% gradient 280 | vg=vg+reshape(t2,[size(vg,1),size(vg,2)]); 281 | %% 282 | fprintf('\n \t\t\t frequency number=%d/%d',l,length(ome)); 283 | end 284 | vg(nz-lp+1:end,:)=0; 285 | vg(1:lp,:)=0; 286 | vg(:,1:lp)=0; 287 | vg(:,nx-lp+1:end)=0; 288 | vg=real(vg); 289 | 290 | C2=mean(C); 291 | end -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # FWI 2 | Acoustic Full-waveform inversion (FWI) for isotropic media, where the wave equation is solved in the frequency domain with perfectly mathced layers (PML) and absorbing boundary condition (ABC) by finite difference method. 3 | For more details, please read 'Acoustic FWI in the frequency domain.pdf'.\ 4 | The toy velocity model is stolen from the course TPG4155 at NTNU. 5 | -------------------------------------------------------------------------------- /generate_true_recordings.m: -------------------------------------------------------------------------------- 1 | %% input parameters 2 | clear all; 3 | close all; 4 | dims.dh=10; 5 | lp=30; 6 | load('trueModel.mat'); 7 | v0=ones(size(trueModel))*2500; 8 | v0(25:35,30:40)=1700; 9 | dims.dt=10^-3; % [s] 10 | dims.nz0=size(v0,1); % Cells in z-direction 11 | dims.nx0=size(v0,2); % Cells in x-direction 12 | dims.nt=1000; % Amount of time steps 13 | dims.ns=dims.nt; 14 | %% extend the velocity model region to employ PML 15 | v=v0; 16 | temp=v0(1,:); 17 | temp2=v0(end,:); 18 | v=[temp(ones(lp,1),:); 19 | v; 20 | temp2(ones(lp,1),:)]; 21 | temp3=v(:,1); 22 | temp4=v(:,end); 23 | v=[temp3(:,ones(1,lp)),v,temp4(:,ones(1,lp))]; 24 | figure('name','true velocity'); 25 | imagesc(v); 26 | colorbar; 27 | xlabel({['x*' num2str(dims.dh) '[m]']}); 28 | ylabel({['z*' num2str(dims.dh) '[m]']}); 29 | hold on; 30 | plot([lp+1,dims.nx0+lp],[lp+1,lp+1],'color','red'); 31 | hold on; 32 | plot([lp+1,dims.nx0+lp],[lp+dims.nz0,lp+dims.nz0],'color','red'); 33 | hold on; 34 | plot([lp+1,lp+1],[lp+1,lp+dims.nz0],'color','red'); 35 | hold on; 36 | plot([dims.nx0+lp,dims.nx0+lp],[lp+1,lp+dims.nz0],'color','red'); 37 | axis on; 38 | shg; 39 | Rc=.1; 40 | d0=log(1/Rc)/log(10)*3*v/2/lp; 41 | %% Model dimensions 42 | dims.nz=size(v,1); 43 | dims.nx=size(v,2); 44 | % mz=31:81 45 | dims.mz=lp+1:dims.nz0+lp; 46 | % mx=31:131 47 | dims.mx=lp+1:dims.nx0+lp; 48 | %% source signals 49 | singles=rickerWave(10,dims); 50 | %% Receiver locations 51 | dims.rx=min(dims.mx):max(dims.mx); 52 | dims.rz=min(dims.mz)*ones(1,length(dims.rx)); 53 | %% source 54 | fs=1/dims.dt; 55 | L=dims.nt; 56 | n=2000; 57 | f=fs*(0:(n/2))/n; 58 | s=zeros([dims.nz*dims.nx,1]); 59 | source_freq=fft(singles,n)/(n/2); 60 | source_freq2=source_freq(1:n/2+1); 61 | % check source 62 | source_time=ifft(source_freq2,n,1)*n; 63 | figure('name','source signals'); 64 | subplot(3,1,1) 65 | plot(dims.dt:dims.dt:dims.dt*L,real(singles)); 66 | xlabel(['t [s]']); 67 | title('original'); 68 | subplot(3,1,2) 69 | plot(dims.dt:dims.dt:dims.dt*L,real(source_time(1:dims.nt))); 70 | xlabel(['t' [s]']); 71 | title('transformed from frequency'); 72 | subplot(3,1,3) 73 | plot(abs(source_freq2)); 74 | %aa=reshape(aa,[300,1]); 75 | %plot(real(aa)) 76 | title('frequencu domain'); 77 | shg; 78 | %% find effective frequency of source 79 | s_diff=diff(abs(source_freq2)); 80 | s_diff=[s_diff(1);s_diff]; 81 | s_lim=find(abs(source_freq2)<.01*max(abs(source_freq2)) & s_diff<0); 82 | s_lim2=s_lim(1); 83 | f_range=1:s_lim2; 84 | f2=f(f_range); 85 | ome=2*pi*f2; 86 | 87 | % source term 88 | sf=source_freq2(1:s_lim2); 89 | 90 | source_time2=ifft(source_freq2(f_range),n,1)*n; 91 | figure('name','check source') 92 | plot(dims.dt:dims.dt:dims.dt*L,real(source_time2(1:dims.nt))); 93 | %% run solver 94 | nz=dims.nz; 95 | nx=dims.nx; 96 | 97 | dh=dims.dh; 98 | nt=dims.nt; 99 | % ome 100 | % sf 101 | rz=dims.rz; 102 | rx=dims.rx; 103 | 104 | % boundary condition 105 | pini=zeros(nz,nx,length(ome)); 106 | 107 | % v 108 | %% source location 109 | sx0=dims.mx(1); 110 | sz0=dims.mz(1); 111 | 112 | % true_rec: (time_samples,receivers,source), common shot gather 113 | true_rect=zeros(dims.nt,length(rx),length(sx0)); 114 | %% 115 | tic; 116 | for i=1:length(sx0) 117 | sz=sz0(i); 118 | sx=sx0(i); 119 | [~,pt,~,rect]=solver(nz,nx,dh,nt,sz,sx,ome,n,sf,rz,rx,v,lp,d0); 120 | true_rect(:,:,i)=rect; 121 | fprintf('\ncommon shot gather generator \t source=%d/%d \t',i,length(sx0)); 122 | fprintf('t=%f s', toc); 123 | end 124 | %% 125 | save('true_rect.mat','true_rect'); 126 | %% 127 | load('true_rect.mat'); 128 | for i=1:size(true_rect,3) 129 | figure(5) 130 | imagesc(true_rect(:,:,i),1*[min(true_rect(:)),max(true_rect(:))]); 131 | shg; 132 | pause(.5); 133 | end -------------------------------------------------------------------------------- /log.txt: -------------------------------------------------------------------------------- 1 | 2 | current iteration=1/20 time=0.000314 s 3 | current shot number=1/1 4 | Cost=0.009354 5 | max gradient=1011.634584 6 | current iteration=2/20 time=180.682484 s 7 | current shot number=1/1 -------------------------------------------------------------------------------- /rickerWave.m: -------------------------------------------------------------------------------- 1 | function [ricker] = rickerWave(freq,dims) 2 | %RICKERWAVE Generates the time derivative of a Ricker wavelet 3 | % to be used as a source signature 4 | t = 0:dims.dt:dims.dt*(dims.ns); 5 | tau = (t-1/freq)*freq*pi; 6 | ricker = (1-tau.*tau).*exp(-tau.*tau); 7 | ricker = (ricker(2:end) - ricker(1:end-1))'; 8 | end -------------------------------------------------------------------------------- /solver.m: -------------------------------------------------------------------------------- 1 | function [p,pt,rec,rect]=solver(nz,nx,dh,nt,sz,sx,ome,n,sf,rz,rx,v,lp,d0) 2 | % dims frequency sample number 3 | % Source: source signals in frequency domain 4 | % lp: layers of PML 5 | % d0: for PML, could be related to R (reflection coefficient) 6 | %% 7 | AA=sparse(nz*nx,nz*nx); 8 | s=zeros(nz*nx,length(ome)); 9 | p=zeros(nz,nx,length(ome)); 10 | %% 11 | for i=1:length(sx) 12 | s(sz(i)+(sx(i)-1)*nz,:)=sf(:,i); 13 | end 14 | %% 15 | % tic; 16 | %% 17 | for l=2:length(ome) 18 | %% assign d 19 | dx=zeros(nz,nx); 20 | dz=zeros(nz,nx); 21 | % top 22 | for i=2:lp+1 23 | for j=lp+2:nx-lp-1 24 | dx(i,j)=0; 25 | dz(i,j)=d0(i,j)*((lp+2-i)/lp)^2; 26 | end 27 | end 28 | % bottom 29 | for i=nz-lp:nz-1 30 | for j=lp+2:nx-lp-1 31 | dx(i,j)=0; 32 | dz(i,j)=d0(i,j)*((i+1-(nz-lp))/lp)^2; 33 | end 34 | end 35 | % left 36 | for i=lp+2:nz-lp-1 37 | for j=2:lp+1 38 | dz(i,j)=0; 39 | dx(i,j)=d0(i,j)*((lp+2-j)/lp)^2; 40 | end 41 | end 42 | % right 43 | for i=lp+1:nz-lp-1 44 | for j=nx-lp:nx-1 45 | dz(i,j)=0; 46 | dx(i,j)=d0(i,j)*((j+1-(nx-lp))/lp)^2; 47 | end 48 | end 49 | % upper left 50 | for i=2:lp+1 51 | for j=2:lp+1 52 | dz(i,j)=d0(i,j)*((lp+2-i)/lp)^2; 53 | dx(i,j)=d0(i,j)*((lp+2-j)/lp)^2; 54 | end 55 | end 56 | % upper right 57 | for i=2:lp+1 58 | for j=nx-lp:nx-1 59 | dz(i,j)=d0(i,j)*((lp+2-i)/lp)^2; 60 | dx(i,j)=d0(i,j)*((j+1-(nx-lp))/lp)^2; 61 | end 62 | end 63 | % lower left 64 | for i=nz-lp:nz-1 65 | for j=2:lp+1 66 | dz(i,j)=d0(i,j)*((i+1-(nz-lp))/lp)^2; 67 | dx(i,j)=d0(i,j)*((lp+2-j)/lp)^2; 68 | end 69 | end 70 | % lower right 71 | for i=nz-lp:nz-1 72 | for j=nx-lp:nx-1 73 | dz(i,j)=d0(i,j)*((i+1-(nz-lp))/lp)^2; 74 | dx(i,j)=d0(i,j)*((j+1-(nx-lp))/lp)^2; 75 | end 76 | end 77 | gx=1+dx/1i./ome(l); 78 | gz=1+dz/1i./ome(l); 79 | gx_x=diff(gx,1,2)/dh; 80 | gz_z=diff(gz,1,1)/dh; 81 | gx_x=[-gx_x(:,1:end-31),zeros([size(gx_x,1),1]),gx_x(:,end-30:end)]; 82 | gx_x(:,1)=0; 83 | gx_x(:,end)=0; 84 | gz_z=[-gz_z(1:end-31,:);zeros([1,size(gz_z,2)]);gz_z(end-30:end,:)]; 85 | gz_z(1,:)=0; 86 | gz_z(end,:)=0; 87 | %% domain interior 88 | for i=lp+2:nz-1 89 | for j=lp+2:nx-1 90 | % i,j 91 | AA((j-1)*nz+i,(j-1)*nz+i)=(ome(l)^2-2*v(i,j)^2/gx(i,j)^2/dh^2-2*v(i,j)^2/gz(i,j)^2/dh^2)/v(i,j)^2; 92 | 93 | % i,j+1 94 | AA((j-1)*nz+i,(j)*nz+i)=(-v(i,j)^2/2/gx(i,j)^3/dh*gx_x(i,j)+v(i,j)^2/gx(i,j)^2/dh^2)/v(i,j)^2; 95 | % i,j-1 96 | AA((j-1)*nz+i,(j-2)*nz+i)=(v(i,j)^2/2/gx(i,j)^3/dh*gx_x(i,j)+v(i,j)^2/gx(i,j)^2/dh^2)/v(i,j)^2; 97 | 98 | % i+1,j 99 | AA((j-1)*nz+i,(j-1)*nz+i+1)=(-v(i,j)^2/2/gz(i,j)^3/dh*gz_z(i,j)+v(i,j)^2/gz(i,j)^2/dh^2)/v(i,j)^2; 100 | % i-1,j 101 | AA((j-1)*nz+i,(j-1)*nz+i-1)=(v(i,j)^2/2/gz(i,j)^3/dh*gz_z(i,j)+v(i,j)^2/gz(i,j)^2/dh^2)/v(i,j)^2; 102 | end 103 | end 104 | %% top local 105 | for i=2:lp+1 106 | for j=lp+2:nx-lp-1 107 | % i,j 108 | AA((j-1)*nz+i,(j-1)*nz+i)=(ome(l)^2-2*v(i,j)^2/gx(i,j)^2/dh^2-2*v(i,j)^2/gz(i,j)^2/dh^2)/v(i,j)^2; 109 | 110 | % i,j+1 111 | AA((j-1)*nz+i,(j)*nz+i)=(-v(i,j)^2/2/gx(i,j)^3/dh*gx_x(i,j)+v(i,j)^2/gx(i,j)^2/dh^2)/v(i,j)^2; 112 | % i,j-1 113 | AA((j-1)*nz+i,(j-2)*nz+i)=(v(i,j)^2/2/gx(i,j)^3/dh*gx_x(i,j)+v(i,j)^2/gx(i,j)^2/dh^2)/v(i,j)^2; 114 | 115 | % i+1,j 116 | AA((j-1)*nz+i,(j-1)*nz+i+1)=(v(i,j)^2/2/gz(i,j)^3/dh*gz_z(i,j)+v(i,j)^2/gz(i,j)^2/dh^2)/v(i,j)^2; 117 | % i-1,j 118 | AA((j-1)*nz+i,(j-1)*nz+i-1)=(-v(i,j)^2/2/gz(i,j)^3/dh*gz_z(i,j)+v(i,j)^2/gz(i,j)^2/dh^2)/v(i,j)^2; 119 | end 120 | end 121 | %% left local 122 | for i=lp+2:nz-lp-1 123 | for j=2:lp+1 124 | % i,j 125 | AA((j-1)*nz+i,(j-1)*nz+i)=(ome(l)^2-2*v(i,j)^2/gx(i,j)^2/dh^2-2*v(i,j)^2/gz(i,j)^2/dh^2)/v(i,j)^2; 126 | 127 | % i,j+1 128 | AA((j-1)*nz+i,(j)*nz+i)=(v(i,j)^2/2/gx(i,j)^3/dh*gx_x(i,j)+v(i,j)^2/gx(i,j)^2/dh^2)/v(i,j)^2; 129 | % i,j-1 130 | AA((j-1)*nz+i,(j-2)*nz+i)=(-v(i,j)^2/2/gx(i,j)^3/dh*gx_x(i,j)+v(i,j)^2/gx(i,j)^2/dh^2)/v(i,j)^2; 131 | 132 | % i+1,j 133 | AA((j-1)*nz+i,(j-1)*nz+i+1)=(-v(i,j)^2/2/gz(i,j)^3/dh*gz_z(i,j)+v(i,j)^2/gz(i,j)^2/dh^2)/v(i,j)^2; 134 | % i-1,j 135 | AA((j-1)*nz+i,(j-1)*nz+i-1)=(v(i,j)^2/2/gz(i,j)^3/dh*gz_z(i,j)+v(i,j)^2/gz(i,j)^2/dh^2)/v(i,j)^2; 136 | end 137 | end 138 | %% upper left 139 | for i=2:lp+1 140 | for j=2:lp+1 141 | % i,j 142 | AA((j-1)*nz+i,(j-1)*nz+i)=(ome(l)^2-2*v(i,j)^2/gx(i,j)^2/dh^2-2*v(i,j)^2/gz(i,j)^2/dh^2)/v(i,j)^2; 143 | 144 | % i,j+1 145 | AA((j-1)*nz+i,(j)*nz+i)=(v(i,j)^2/2/gx(i,j)^3/dh*gx_x(i,j)+v(i,j)^2/gx(i,j)^2/dh^2)/v(i,j)^2; 146 | % i,j-1 147 | AA((j-1)*nz+i,(j-2)*nz+i)=(-v(i,j)^2/2/gx(i,j)^3/dh*gx_x(i,j)+v(i,j)^2/gx(i,j)^2/dh^2)/v(i,j)^2; 148 | 149 | % i+1, 150 | AA((j-1)*nz+i,(j-1)*nz+i+1)=(v(i,j)^2/2/gz(i,j)^3/dh*gz_z(i,j)+v(i,j)^2/gz(i,j)^2/dh^2)/v(i,j)^2; 151 | % i-1,j 152 | AA((j-1)*nz+i,(j-1)*nz+i-1)=(-v(i,j)^2/2/gz(i,j)^3/dh*gz_z(i,j)+v(i,j)^2/gz(i,j)^2/dh^2)/v(i,j)^2; 153 | end 154 | end 155 | %% upper right 156 | for i=2:lp+1 157 | for j=nx-lp:nx-1 158 | % i,j 159 | AA((j-1)*nz+i,(j-1)*nz+i)=(ome(l)^2-2*v(i,j)^2/gx(i,j)^2/dh^2-2*v(i,j)^2/gz(i,j)^2/dh^2)/v(i,j)^2; 160 | 161 | % i,j+1 162 | AA((j-1)*nz+i,(j)*nz+i)=(-v(i,j)^2/2/gx(i,j)^3/dh*gx_x(i,j)+v(i,j)^2/gx(i,j)^2/dh^2)/v(i,j)^2; 163 | % i,j-1 164 | AA((j-1)*nz+i,(j-2)*nz+i)=(v(i,j)^2/2/gx(i,j)^3/dh*gx_x(i,j)+v(i,j)^2/gx(i,j)^2/dh^2)/v(i,j)^2; 165 | 166 | % i+1,j 167 | AA((j-1)*nz+i,(j-1)*nz+i+1)=(v(i,j)^2/2/gz(i,j)^3/dh*gz_z(i,j)+v(i,j)^2/gz(i,j)^2/dh^2)/v(i,j)^2; 168 | % i-1,j 169 | AA((j-1)*nz+i,(j-1)*nz+i-1)=(-v(i,j)^2/2/gz(i,j)^3/dh*gz_z(i,j)+v(i,j)^2/gz(i,j)^2/dh^2)/v(i,j)^2; 170 | end 171 | end 172 | %% lower left 173 | for i=nz-lp:nz-1 174 | for j=2:lp+1 175 | % i,j 176 | AA((j-1)*nz+i,(j-1)*nz+i)=(ome(l)^2-2*v(i,j)^2/gx(i,j)^2/dh^2-2*v(i,j)^2/gz(i,j)^2/dh^2)/v(i,j)^2; 177 | 178 | % i,j+1 179 | AA((j-1)*nz+i,(j)*nz+i)=(v(i,j)^2/2/gx(i,j)^3/dh*gx_x(i,j)+v(i,j)^2/gx(i,j)^2/dh^2)/v(i,j)^2; 180 | % i,j-1 181 | AA((j-1)*nz+i,(j-2)*nz+i)=(-v(i,j)^2/2/gx(i,j)^3/dh*gx_x(i,j)+v(i,j)^2/gx(i,j)^2/dh^2)/v(i,j)^2; 182 | 183 | % i+1,j 184 | AA((j-1)*nz+i,(j-1)*nz+i+1)=(-v(i,j)^2/2/gz(i,j)^3/dh*gz_z(i,j)+v(i,j)^2/gz(i,j)^2/dh^2)/v(i,j)^2; 185 | % i-1,j 186 | AA((j-1)*nz+i,(j-1)*nz+i-1)=(v(i,j)^2/2/gz(i,j)^3/dh*gz_z(i,j)+v(i,j)^2/gz(i,j)^2/dh^2)/v(i,j)^2; 187 | end 188 | end 189 | %% boundary line 190 | %% B2 191 | i=1; 192 | for j=2:nx-1 193 | AA((j-1)*nz+i,(j-1)*nz+i)=-1/dh-1i*ome(l)/(v(i,j)); 194 | %AA((j-1)*nz+i,(j)*nz+i)=1/dh^2; 195 | %AA((j-1)*nz+i,(j-2)*nz+i)=1/dh^2; 196 | %AA((j-1)*nz+i,(j-1)*nz+i-1)=1/dh^2; 197 | AA((j-1)*nz+i,(j-1)*nz+i+1)=1/dh; 198 | end 199 | %% B3 200 | i=nz; 201 | for j=2:nx-1 202 | AA((j-1)*nz+i,(j-1)*nz+i)=-1/dh-1i*ome(l)/(v(i,j)); 203 | %AA((j-1)*nz+i,(j)*nz+i)=1/dh; 204 | %AA((j-1)*nz+i,(j-2)*nz+i)=1/dh; 205 | AA((j-1)*nz+i,(j-1)*nz+i-1)=1/dh; 206 | %AA((j-1)*nz+i,(j-1)*nz+i+1)=1/dh; 207 | end 208 | %% B4 209 | j=nx; 210 | for i=2:nz-1 211 | AA((j-1)*nz+i,(j-1)*nz+i)=-1/dh-1i*ome(l)/(v(i,j)); 212 | %AA((j-1)*nz+i,(j)*nz+i)=1/dh; 213 | AA((j-1)*nz+i,(j-2)*nz+i)=1/dh; 214 | %AA((j-1)*nz+i,(j-1)*nz+i-1)=1/dh; 215 | %AA((j-1)*nz+i,(j-1)*nz+i+1)=1/dh; 216 | end 217 | %% B5 218 | j=1; 219 | for i=2:nz-1 220 | AA((j-1)*nz+i,(j-1)*nz+i)=-1/dh-1i*ome(l)/(v(i,j)); 221 | AA((j-1)*nz+i,(j)*nz+i)=1/dh; 222 | %AA((j-1)*nz+i,(j-2)*nz+i)=1/dh; 223 | %AA((j-1)*nz+i,(j-1)*nz+i-1)=1/dh; 224 | %AA((j-1)*nz+i,(j-1)*nz+i+1)=1/dh; 225 | end 226 | %% B6 227 | j=nx; 228 | i=1; 229 | AA((j-1)*nz+i,(j-1)*nz+i)=-2/dh-2i*ome(l)/(v(i,j)); 230 | %AA((j-1)*nz+i,(j)*nz+i)=1/dh; 231 | AA((j-1)*nz+i,(j-2)*nz+i)=1/dh; 232 | %AA((j-1)*nz+i,(j-1)*nz+i-1)=1/dh; 233 | AA((j-1)*nz+i,(j-1)*nz+i+1)=1/dh; 234 | %% B7 235 | j=1; 236 | i=1; 237 | AA((j-1)*nz+i,(j-1)*nz+i)=-2/dh-2i*ome(l)/(v(i,j)); 238 | AA((j-1)*nz+i,(j)*nz+i)=1/dh; 239 | %AA((j-1)*nz+i,(j-2)*nz+i)=1/dh; 240 | %AA((j-1)*nz+i,(j-1)*nz+i-1)=1/dh; 241 | AA((j-1)*nz+i,(j-1)*nz+i+1)=1/dh; 242 | %% B8 243 | i=nz; 244 | j=nx; 245 | AA((j-1)*nz+i,(j-1)*nz+i)=-2/dh-2i*ome(l)/(v(i,j)); 246 | %AA((j-1)*nz+i,(j)*nz+i)=1/dh; 247 | AA((j-1)*nz+i,(j-2)*nz+i)=1/dh; 248 | AA((j-1)*nz+i,(j-1)*nz+i-1)=1/dh; 249 | %AA((j-1)*nz+i,(j-1)*nz+i+1)=1/dh; 250 | %% B9 251 | j=1; 252 | i=nz; 253 | AA((j-1)*nz+i,(j-1)*nz+i)=-2/dh-2i*ome(l)/(v(i,j)); 254 | AA((j-1)*nz+i,(j)*nz+i)=1/dh; 255 | %AA((j-1)*nz+i,(j-2)*nz+i)=1/dh; 256 | AA((j-1)*nz+i,(j-1)*nz+i-1)=1/dh; 257 | %AA((j-1)*nz+i,(j-1)*nz+i+1)=1/dh; 258 | %% solve Ax=b 259 | p0=AA\(-s(:,l)); 260 | p(:,:,l)=reshape(p0,[nz,nx]); 261 | 262 | %fprintf('frequency step=%f/%f \t',l,length(ome)); 263 | %fprintf('t=%f s\n',toc); 264 | end 265 | %% 266 | rec=reshape(p(rz(1),rx,:),[length(rx),length(ome)]).'; 267 | pt0=ifft(p,n,3)*n; 268 | pt=real(pt0(:,:,1:nt)); 269 | rect=reshape(pt(rz(1),rx,:),[length(rx),nt]).'; 270 | end -------------------------------------------------------------------------------- /taperGradient_not_used.m: -------------------------------------------------------------------------------- 1 | function G = taperGradient(G,lp,l1) 2 | %% Taper gradient near sources to avoid interference 3 | [~,n] = size(G); 4 | taper = sin(linspace(0,pi/2,l1)); 5 | taper = repmat(taper,n,1).'; 6 | G(lp+1:lp+l1,:)=taper.*G(lp+1:lp+l1,:); 7 | %% Normalise gradient 8 | %{ 9 | scale = 1.0/max(abs(G(:))); 10 | G = scale*G; 11 | %} 12 | end -------------------------------------------------------------------------------- /test.m: -------------------------------------------------------------------------------- 1 | %% input parameters 2 | clear all; 3 | close all; 4 | dims.dh=10; 5 | lp=30; 6 | load('trueModel.mat'); 7 | v0=trueModel; 8 | dims.dt=10^-3; % [s] 9 | dims.nz0=size(v0,1); % Cells in z-direction 10 | dims.nx0=size(v0,2); % Cells in x-direction 11 | dims.nt=800; % Amount of time steps 12 | dims.ns=dims.nt; 13 | %% extend the velocity model region to employ PML 14 | v=v0; 15 | temp=v0(1,:); 16 | temp2=v0(end,:); 17 | v=[temp(ones(lp,1),:); 18 | v; 19 | temp2(ones(lp,1),:)]; 20 | temp3=v(:,1); 21 | temp4=v(:,end); 22 | v=[temp3(:,ones(1,lp)),v,temp4(:,ones(1,lp))]; 23 | figure('name','velocity'); 24 | imagesc(v); 25 | colorbar; 26 | xlabel({['x*' num2str(dims.dh) '[m]']}); 27 | ylabel({['z*' num2str(dims.dh) '[m]']}); 28 | hold on; 29 | plot([lp+1,dims.nx0+lp],[lp+1,lp+1],'color','red'); 30 | hold on; 31 | plot([lp+1,dims.nx0+lp],[lp+dims.nz0,lp+dims.nz0],'color','red'); 32 | hold on; 33 | plot([lp+1,lp+1],[lp+1,lp+dims.nz0],'color','red'); 34 | hold on; 35 | plot([dims.nx0+lp,dims.nx0+lp],[lp+1,lp+dims.nz0],'color','red'); 36 | axis on; 37 | shg; 38 | Rc=.1; 39 | d0=log(1/Rc)/log(10)*3*v/2/lp; 40 | %% Model dimensions 41 | dims.nz=size(v,1); 42 | dims.nx=size(v,2); 43 | % mz=31:81 44 | dims.mz=lp+1:dims.nz0+lp; 45 | % mx=31:131 46 | dims.mx=lp+1:dims.nx0+lp; 47 | %% Source and source signals 48 | dims.sz=[31]; 49 | dims.sx=[31]; 50 | sn=length(dims.sx); 51 | singles=rickerWave(10,dims); 52 | %% Receiver locations 53 | dims.rx=min(dims.mx):max(dims.mx); 54 | dims.rz=min(dims.mz)*ones(1,length(dims.rx)); 55 | %% source 56 | fs=1/dims.dt; 57 | L=dims.nt; 58 | n=dims.nt; 59 | f=fs*(0:(n/2))/n; 60 | s=zeros([dims.nz*dims.nx,1]); 61 | source_freq=fft(singles,n)/(n/2); 62 | source_freq2=source_freq(1:n/2+1); 63 | % check source 64 | source_time=ifft(source_freq2,n,1)*n; 65 | figure('name','source signals') 66 | subplot(3,1,1) 67 | plot(dims.dt:dims.dt:dims.dt*L,real(singles)); 68 | xlabel(['t [s]']); 69 | title('original'); 70 | subplot(3,1,2) 71 | plot(dims.dt:dims.dt:dims.dt*L,real(source_time(1:dims.nt))); 72 | xlabel(['t' ' [s]']); 73 | title('transformed from frequency'); 74 | subplot(3,1,3) 75 | plot(abs(source_freq2)); 76 | %aa=reshape(aa,[300,1]); 77 | %plot(real(aa)) 78 | title('frequencu domain'); 79 | shg; 80 | %% find effective frequency of source 81 | s_diff=diff(abs(source_freq2)); 82 | s_diff=[s_diff(1);s_diff]; 83 | s_lim=find(abs(source_freq2)<.01*max(abs(source_freq2)) & s_diff<0); 84 | s_lim2=s_lim(1); 85 | f_range=1:s_lim2; 86 | f2=f(f_range); 87 | ome=2*pi*f2; 88 | 89 | % source term 90 | temp=source_freq2(1:s_lim2); 91 | sf=temp(:,ones([2,1])); 92 | %% some parameters 93 | nz=dims.nz; 94 | nx=dims.nx; 95 | sz=dims.sz; 96 | sx=dims.sx; 97 | dh=dims.dh; 98 | nt=dims.nt; 99 | % ome 100 | % sf 101 | rz=dims.rz; 102 | rx=dims.rx; 103 | % v 104 | %% 105 | [p,pt,~,rect]=solver(nz,nx,dh,nt,sz,sx,ome,n,sf,rz,rx,v,lp,d0); 106 | %{ 107 | %% 108 | figure; 109 | aa=pt(sz,sx,:); 110 | aa=reshape(aa,[size(aa,3),1]); 111 | subplot(3,1,1) 112 | plot(real(aa)); 113 | subplot(3,1,2) 114 | plot(real(singles)); 115 | subplot(3,1,3) 116 | plot(real(aa-source_time)); 117 | %% 118 | figure; 119 | aa=p(sz,sx,:); 120 | aa=reshape(aa,[size(aa,3),1]); 121 | subplot(3,1,1) 122 | plot(real(aa)); 123 | subplot(3,1,2) 124 | plot(real(sf2)); 125 | subplot(3,1,3); 126 | plot(real(aa-sf2)); 127 | %} 128 | %% plot pt 129 | figure('name','animation of wavefield') 130 | for i=1:fix(size(pt,3))/20:size(pt,3) 131 | %C=imfuse(real(pt(:,:,i)),v,'falsecolor','Scaling','independent','ColorChannels','red-cyan'); 132 | subplot(2,1,1) 133 | imshow(real(pt(:,:,i)),.1*[min(real(pt(:))),max(real(pt(:)))]); 134 | colorbar; 135 | xlabel({['x*' num2str(dims.dh) '[m]']}); 136 | ylabel({['z*' num2str(dims.dh) '[m]']}); 137 | title({['t=' num2str(i*dims.dt) 's'],['p']}); 138 | hold on; 139 | plot([lp+1,dims.nx0+lp],[lp+1,lp+1],'color','red'); 140 | hold on; 141 | plot([lp+1,dims.nx0+lp],[lp+dims.nz0,lp+dims.nz0],'color','red'); 142 | hold on; 143 | plot([lp+1,lp+1],[lp+1,lp+dims.nz0],'color','red'); 144 | hold on; 145 | plot([dims.nx0+lp,dims.nx0+lp],[lp+1,lp+dims.nz0],'color','red'); 146 | axis on; 147 | 148 | subplot(2,1,2) 149 | imshow(v,[min(v(:)),max(v(:))]); 150 | colorbar; 151 | xlabel({['x*' num2str(dims.dh) '[m]']}); 152 | ylabel({['z*' num2str(dims.dh) '[m]']}); 153 | %title({['t=' num2str(i*dims.dt) 's'],['p']}); 154 | hold on; 155 | plot([lp+1,dims.nx0+lp],[lp+1,lp+1],'color','red'); 156 | hold on; 157 | plot([lp+1,dims.nx0+lp],[lp+dims.nz0,lp+dims.nz0],'color','red'); 158 | hold on; 159 | plot([lp+1,lp+1],[lp+1,lp+dims.nz0],'color','red'); 160 | hold on; 161 | plot([dims.nx0+lp,dims.nx0+lp],[lp+1,lp+dims.nz0],'color','red'); 162 | axis on; 163 | shg; 164 | end 165 | %% 166 | figure(3) 167 | imagesc(real(rect),.1*[min(real(rect(:))),max(real(rect(:)))]); 168 | grid on; 169 | hold off; 170 | %% test attenuation of PML 171 | 172 | t1=real(pt(sz(1),:,:)); 173 | t2=reshape(t1,[size(t1,2),size(t1,3)]); 174 | 175 | for i=1:size(t2,2) 176 | figure(4) 177 | subplot(2,1,1) 178 | plot(t2(:,i)); 179 | ylim([min(t2(:)),max(t2(:))]); 180 | title(num2str(i)); 181 | shg; 182 | pause(.01); 183 | end -------------------------------------------------------------------------------- /trueModel.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/deconvolution/FWI/6298b5f32ebbe7fccff1cac0f4d6f9e1767db934/trueModel.mat -------------------------------------------------------------------------------- /true_rect.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/deconvolution/FWI/6298b5f32ebbe7fccff1cac0f4d6f9e1767db934/true_rect.mat --------------------------------------------------------------------------------