-
Jan Willem Thorbecke authoredJan Willem Thorbecke authored
PlaneWaveDecomposition.c 11.83 KiB
#include<stdlib.h>
#include<stdarg.h>
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<complex.h>
#include<fftw3.h>
#include"fdacrtmc.h"
#include"par.h"
/*
NOTE: If signals are even in length we mute the highest
frequency/wavenumber component.
*/
// TODO Get rid of deubg in wisdom files
int PlaneWaveDecompositionUpDownRTMImagingCondition(migPar *mig, fftPlansPar *fftPlans,int verbose){
fftw_complex *Forw, *Back, *Mute;
bool evenT=false, evenZ=false; //Booleans if nt & nz are even (true) or not (false)
double *forw, *back;
float *tap;
size_t it, it1, ix, iz, iz1, ntz, nw, nwp, nwn, nkz, nkzp, nwkz, perc;
//float *im1, *im2, *im3, *im4;
va_list args; //Needed to initialize progress
/* Compute Constants */
ntz=mig->nt*mig->nz;
nwp=mig->nt/2; //Number of positive frequencies
nw=nwp+1;
nwn=mig->nt-nw; //Number of negative frequencies
nkzp=mig->nz/2; //Number of positive wavenumbers
nkz=nkzp+1;
nwkz=nkz*mig->nt;
if(!mig->nt%2) evenT=true; // Note we mute the highest frequency component
if(!mig->nz%2) evenZ=true; // Note we mute the highest wavenumber component
//im1=(float*)fftw_malloc(mig->sizem*sizeof(float));
//im2=(float*)fftw_malloc(mig->sizem*sizeof(float));
//im3=(float*)fftw_malloc(mig->sizem*sizeof(float));
//im4=(float*)fftw_malloc(mig->sizem*sizeof(float));
/* Allocate Arrays */
forw=(double*)fftw_malloc(ntz*sizeof(double)); //Forward Propagated Wavefield
Forw=(fftw_complex*)fftw_malloc(nwkz*sizeof(fftw_complex)); // " in the Wavenumber Frequency Domain
Mute=(fftw_complex*)fftw_malloc(nwkz*sizeof(fftw_complex)); //Muted Wavefields
back=(double*)fftw_malloc(ntz*sizeof(double)); //Backward Propagated Wavefield
Back=(fftw_complex*)fftw_malloc(nwkz*sizeof(fftw_complex)); // " in the Wavenumber Frequency Domain
/**************************/
/* Construct Sine^2 Taper */
/**************************/
// Format of tap:
// |--------------| Note: C memory alignment !
// | |
// | Corner Taper |
// | Matrix |
// | |
// |--------------|
// | Taper |
// |--------------|
//
// tap=[ 0 0 ... 0 ]
// [ 0 sin^2(PI*ix/(nx+1))*sin^2(PI*iz/(ntap+1)) ... sin^2(PI*nx/(nx+1))*sin^2(PI*iz/(ntap+1)) ]
// [ ... ... ... ... ]
// [ 0 sin^2(PI*ix/(nx+1))*sin^2(PI*nz/(ntap+1)) ... sin^2(PI*nx/(nx+1))*sin^2(PI*nz/(ntap+1)) ]
// [ 0 sin^2(PI*ix/(nx+1)) ... sin^2(PI*nx/(nx+1)) ]
// Note: Zeros are not included in the taper
mig->tap=50;
if(mig->tap){
/* Construct Taper */
tap=malloc((float)(mig->tap-1)*mig->tap*sizeof(float));
// Compute Simple Taper
for(ix=0;ix<mig->tap-1;ix++){
tap[(mig->tap-1)*(mig->tap-1)+ix]=sin(1.5707963267948966192313216916398*(((float)(ix+1))/((float)(mig->tap+1)))); //Value outside boundary is 1
tap[(mig->tap-1)*(mig->tap-1)+ix]*=tap[(mig->tap-1)*(mig->tap-1)+ix];
}
// Compute Corners
for(ix=0;ix<mig->tap-1;ix++) for(iz=0;iz<mig->tap-1;iz++) tap[ix*(mig->tap-1)+iz]=tap[(mig->tap-1)*(mig->tap-1)+ix]*tap[(mig->tap-1)*(mig->tap-1)+iz];
}
/************************************/
/* Loop Over Horizontal Coordinates */
/************************************/
if(verbose){perc=mig->nx/100;if(!perc)perc=1;fprintf(stderr," %s: Progress: 0%%",xargv[0]);}
for(ix=0;ix<mig->nx;ix++){
/***************************************/
/* Forward Propagated Source Wavefield */
/***************************************/
/* Copy Array to Double */
if(mig->tap){ //Additionaly Taper Wavefield
// Source Wavefield
memset(forw,0,mig->nz*sizeof(double)); //Zero Boundary
for(it=1;it<mig->tap;it++){ // Boundary 1
forw[it*mig->nz]=0; //Zero Boundary
for(iz=1;iz<mig->tap;iz++) forw[it*mig->nz+iz]=(double)(mig->wav[it].tzz[ix*mig->nz+iz]*tap[(it-1)*(mig->tap-1)+iz-1]); //Corner 1
for(iz=mig->tap;iz<mig->nz-mig->tap;iz++) forw[it*mig->nz+iz]=(double)(mig->wav[it].tzz[ix*mig->nz+iz]*tap[(mig->tap-1)*(mig->tap-1)+it-1]); //Boundary 1
for(iz=mig->nz-mig->tap,iz1=mig->tap-2;iz<mig->nz-1;iz++,iz1--) forw[it*mig->nz+iz]=(double)(mig->wav[it].tzz[ix*mig->nz+iz]*tap[(it-1)*(mig->tap-1)+iz1]); //Corner 2
forw[(it+1)*mig->nz-1]=0; //Zero Boundary
}
for(it=mig->tap;it<mig->nt-mig->tap;it++){
forw[it*mig->nz]=0; //Zero Boundary
for(iz=1;iz<mig->tap;iz++) forw[it*mig->nz+iz]=(double)(mig->wav[it].tzz[ix*mig->nz+iz]*tap[(mig->tap-1)*(mig->tap-1)+iz-1]); //Boundary 2
for(iz=mig->tap;iz<mig->nz-mig->tap;iz++) forw[it*mig->nz+iz]=(double)mig->wav[it].tzz[ix*mig->nz+iz];
for(iz=mig->nz-mig->tap,iz1=mig->tap-2;iz<mig->nz-1;iz++,iz1--) forw[it*mig->nz+iz]=(double)(mig->wav[it].tzz[ix*mig->nz+iz]*tap[(mig->tap-1)*(mig->tap-1)+iz1]); //Boundary 3
forw[(it+1)*mig->nz-1]=0; //Zero Boundary
}
for(it=mig->nt-mig->tap,it1=mig->tap-2;it<mig->nt-1;it++,it1--){ //Boundary 4
forw[it*mig->nz]=0; //Zero Boundary
for(iz=1;iz<mig->tap;iz++) forw[it*mig->nz+iz]=(double)(mig->wav[it].tzz[ix*mig->nz+iz]*tap[it1*(mig->tap-1)+iz-1]); //Corner 3
for(iz=mig->tap;iz<mig->nz-mig->tap;iz++) forw[it*mig->nz+iz]=(double)(mig->wav[it].tzz[ix*mig->nz+iz]*tap[(mig->tap-1)*(mig->tap-1)+it1]); //Boundary 4
for(iz=mig->nz-mig->tap,iz1=mig->tap-2;iz<mig->nz-1;iz++,iz1--) forw[it*mig->nz+iz]=(double)(mig->wav[it].tzz[ix*mig->nz+iz]*tap[it1*(mig->tap-1)+iz1]); //Corner 4
forw[(it+1)*mig->nz-1]=0; //Zero Boundary
}
memset(&forw[(mig->nt-1)*mig->nz],0,mig->nz*sizeof(double)); //Zero Boundary
}else for(it=0;it<mig->nt;it++) for(iz=0;iz<mig->nz;iz++) forw[it*mig->nz+iz]=(double)mig->wav[it].tzz[ix*mig->nz+iz];
/* Compute Forward Fourier Transform */
fftw_execute_dft_r2c(fftPlans->fft_2d_r2c_TZ,forw,Forw);
for(iz=0;iz<nkz;iz++)Forw[iz]/=2.; //Zero-Frequency Component 1
for(it=1;it<mig->nt;it++)Forw[it*nkz]/=2.; //Zero-Frequency Component 2
if(evenZ) for(it=0;it<mig->nt;it++) Forw[it*nkz-1]=0;
/*********************************/
/* Backward Propagated Wavefield */
/*********************************/
/* Copy Array to Double */
if(mig->tap){ //Additionaly Taper Wavefield
// Source Wavefield
memset(back,0,mig->nz*sizeof(double)); //Zero Boundary
for(it=1;it<mig->tap;it++){ // Boundary 1
back[it*mig->nz]=0; //Zero Boundary
for(iz=1;iz<mig->tap;iz++) back[it*mig->nz+iz]=(double)(mig->wav[2*mig->nt-1-it].tzz[ix*mig->nz+iz]*tap[(it-1)*(mig->tap-1)+iz-1]); //Corner 1
for(iz=mig->tap;iz<mig->nz-mig->tap;iz++) back[it*mig->nz+iz]=(double)(mig->wav[2*mig->nt-1-it].tzz[ix*mig->nz+iz]*tap[(mig->tap-1)*(mig->tap-1)+it-1]); //Boundary 1
for(iz=mig->nz-mig->tap,iz1=mig->tap-2;iz<mig->nz-1;iz++,iz1--) back[it*mig->nz+iz]=(double)(mig->wav[2*mig->nt-1-it].tzz[ix*mig->nz+iz]*tap[(it-1)*(mig->tap-1)+iz1]); //Corner 2
back[(it+1)*mig->nz-1]=0; //Zero Boundary
}
for(it=mig->tap;it<mig->nt-mig->tap;it++){
back[it*mig->nz]=0; //Zero Boundary
for(iz=1;iz<mig->tap;iz++) back[it*mig->nz+iz]=(double)(mig->wav[2*mig->nt-1-it].tzz[ix*mig->nz+iz]*tap[(mig->tap-1)*(mig->tap-1)+iz-1]); //Boundary 2
for(iz=mig->tap;iz<mig->nz-mig->tap;iz++) back[it*mig->nz+iz]=(double)mig->wav[2*mig->nt-1-it].tzz[ix*mig->nz+iz];
for(iz=mig->nz-mig->tap,iz1=mig->tap-2;iz<mig->nz-1;iz++,iz1--) back[it*mig->nz+iz]=(double)(mig->wav[2*mig->nt-1-it].tzz[ix*mig->nz+iz]*tap[(mig->tap-1)*(mig->tap-1)+iz1]); //Boundary 3
back[(it+1)*mig->nz-1]=0; //Zero Boundary
}
for(it=mig->nt-mig->tap,it1=mig->tap-2;it<mig->nt-1;it++,it1--){ //Boundary 4
back[it*mig->nz]=0; //Zero Boundary
for(iz=1;iz<mig->tap;iz++) back[it*mig->nz+iz]=(double)(mig->wav[2*mig->nt-1-it].tzz[ix*mig->nz+iz]*tap[it1*(mig->tap-1)+iz-1]); //Corner 3
for(iz=mig->tap;iz<mig->nz-mig->tap;iz++) back[it*mig->nz+iz]=(double)(mig->wav[2*mig->nt-1-it].tzz[ix*mig->nz+iz]*tap[(mig->tap-1)*(mig->tap-1)+it1]); //Boundary 4
for(iz=mig->nz-mig->tap,iz1=mig->tap-2;iz<mig->nz-1;iz++,iz1--) back[it*mig->nz+iz]=(double)(mig->wav[2*mig->nt-1-it].tzz[ix*mig->nz+iz]*tap[it1*(mig->tap-1)+iz1]); //Corner 4
back[(it+1)*mig->nz-1]=0; //Zero Boundary
}
memset(&back[(mig->nt-1)*mig->nz],0,mig->nz*sizeof(double)); //Zero Boundary
}else for(it=0,iz1=2*mig->nt-1;it<mig->nt;it++,iz1--) for(iz=0;iz<mig->nz;iz++) back[it*mig->nz+iz]=(double)mig->wav[iz1].tzz[ix*mig->nz+iz];
/* Compute Forward Fourier Transform */
fftw_execute_dft_r2c(fftPlans->fft_2d_r2c_TZ,back,Back);
for(iz=0;iz<nkz;iz++)Back[iz]/=2.; //Zero-Frequency Component 1
for(it=1;it<mig->nt;it++)Back[it*nkz]/=2.; //Zero-Frequency Component 2
if(evenZ) for(it=0;it<mig->nt;it++) Back[it*nkz-1]=0;
/***************************/
/* Apply Imaging Condition */
/***************************/
/* 1.)Down-Up Imaging */
// Mute Up-Going Source Wavefield
memcpy(Mute,Forw,nkz*sizeof(fftw_complex)); //Zero-Wavenumber Component
memset(&Mute[nkz],0,nkz*nwp*sizeof(fftw_complex)); //Mute + Quadrant
for(it=1;it<mig->nt;it++)Mute[it*nkz]=Forw[it*nkz]; //Zero-Frequency Component
memcpy(&Mute[nkz*nw],&Forw[nkz*nw],nkz*nwn*sizeof(fftw_complex)); //Copy - Quadrant
fftw_execute_dft_c2r(fftPlans->ifft_2d_c2r_WKz,Mute,forw); //Transform Back
//for(iz=0;iz<mig->nz;iz++) im1[ix*mig->nz+iz]=(float)(forw[200*mig->nz+iz]/((double)ntz));
//for(iz=0;iz<mig->nz;iz++) im2[ix*mig->nz+iz]=(float)(forw[400*mig->nz+iz]/((double)ntz));
//for(iz=0;iz<mig->nz;iz++) im3[ix*mig->nz+iz]=(float)(forw[600*mig->nz+iz]/((double)ntz));
//for(iz=0;iz<mig->nz;iz++) im4[ix*mig->nz+iz]=(float)(forw[800*mig->nz+iz]/((double)ntz));
// Mute Up-Going Receiver Wavefield - for Up-Down Imaging
memcpy(Mute,Back,nkz*sizeof(fftw_complex)); //Zero-Frequency Component
memset(&Mute[nkz],0,nkz*nwp*sizeof(fftw_complex)); //Mute + Quadrant
for(it=1;it<mig->nt;it++)Mute[it*nkz]=Back[it*nkz]; //Zero-Frequency Component
memcpy(&Mute[nkz*nw],&Back[nkz*nw],nkz*nwn*sizeof(fftw_complex)); //Copy - Quadrant
// Mute Down-Going Receiver Wavefield
if(evenT) memset(&Back[nkzp*nwp],0,nkz*nw*sizeof(fftw_complex)); //Mute - Quadrant
else memset(&Back[nkz*nw],0,nkz*nwp*sizeof(fftw_complex));
fftw_execute_dft_c2r(fftPlans->ifft_2d_c2r_WKz,Back,back); //Transform Back
// Apply Zero-Lag Imaging Condition
for(iz=0;iz<mig->nz;iz++) mig->image[ix*mig->nz+iz]=mig->dt*((float)(forw[iz]/(double)ntz)*(back[iz]/(double)ntz));
for(it=1;it<mig->nt;it++) for(iz=0;iz<mig->nz;iz++) mig->image[ix*mig->nz+iz]+=mig->dt*((float)(forw[it*mig->nz+iz]/(double)ntz)*(back[it*mig->nz+iz]/(double)ntz));
/* 2.) Up-Down Imaging */
// Mute Down-Going Source Wavefield
if(evenT) memset(&Forw[nkz*nwp],0,nkz*nw*sizeof(fftw_complex)); //Mute - Quadrant
else memset(&Forw[nkz*nw],0,nkz*nwp*sizeof(fftw_complex));
fftw_execute_dft_c2r(fftPlans->ifft_2d_c2r_WKz,Forw,forw); //Transform Back
// Mute Up-Going Receiver Wavefield
fftw_execute_dft_c2r(fftPlans->ifft_2d_c2r_WKz,Mute,back); //Transform Back
// Apply Zero-Lag Imaging Condition
for(it=0;it<mig->nt;it++)for(iz=0;iz<mig->nz;iz++)mig->image[ix*mig->nz+iz]+=mig->dt*(float)((forw[it*mig->nz+iz]/(double)ntz)*(back[it*mig->nz+iz]/(double)ntz));
// Update Progress
if(verbose&&!(ix%perc)) fprintf(stderr,"\b\b\b\b%3zu%%",(ix+1)*100/mig->nx);
} //Loop over Horiztonal Locations
if(verbose) fprintf(stderr,"\b\b\b\b100%%\n");
//writesufile("pw1.su",im1,mig->nz,mig->nx,0.0,0.0,1,1);free(im1);
//writesufile("pw2.su",im2,mig->nz,mig->nx,0.0,0.0,1,1);free(im2);
//writesufile("pw3.su",im3,mig->nz,mig->nx,0.0,0.0,1,1);free(im3);
//writesufile("pw4.su",im4,mig->nz,mig->nx,0.0,0.0,1,1);free(im4);
/* Deallocate Snapshot Memory */
for(it=0;it<2*mig->nt;it++) fftw_free(mig->wav[it].tzz);
fftw_free(forw);fftw_free(Forw);
fftw_free(Mute);
fftw_free(back);fftw_free(Back);
return(0);
}