Example #1
0
void lh_direct_LS( float **G	/* The Forward Operator */,
		   int Nr	/* Row Of G */,
		   int Nc	/* Column of G */,
		   float **Cd	/* The Covariance Matrix of Data Cd[Nr][Nr] */,
		   float **Cm 	/* The Covariance Matrix of model Cm[Nc][Nc] */,
		   float *d	/* Data */,
		   float *m_prior /* m prior */,
		   float *m_post  /* m posterior */ )
/*< Solve the Least Square Optimization Problem directly Using Matrix Inverse >*/
{
    float **Gt, **A, **B1, **B2, **B3, **B, *C1, *C, **AB;

    Gt = alloc2float( Nr , Nc );
    A  = alloc2float( Nr , Nc );
    B1 = alloc2float( Nc , Nr );
    B2 = alloc2float( Nr , Nr );
    B3 = alloc2float( Nr , Nr );
    B  = alloc2float( Nr , Nr );
    C1 = alloc1float( Nr );
    C  = alloc1float( Nr );
    AB = alloc2float( Nr , Nc );

    zero2float( Gt , Nr , Nc );
    zero2float( A  , Nr , Nc );
    zero2float( B1 , Nc , Nr );
    zero2float( B2 , Nr , Nr );
    zero2float( B3 , Nr , Nr );
    zero2float( B  , Nr , Nr );
    zero1float( C1 , Nr );
    zero1float( C  , Nr );
    zero2float( AB , Nr , Nc );

    lh_matrix_transpose( G , Gt , Nr , Nc );
    lh_matrix_mu_matrix( Cm , Gt , A , Nc , Nc , Nr );
    lh_matrix_mu_matrix( G , Cm , B1 , Nr , Nc , Nc );
    lh_matrix_mu_matrix( B1 , Gt , B2 , Nr , Nc , Nr );
    lh_matrix_add_matrix( B2 , Cd , B3 , Nr , Nr );
    lh_matrix_inverse( B3 , B , Nr );
    lh_matrix_mu_vector( G , m_prior , C1 , Nr , Nc );
    lh_vector_sub_vector( d , C1 , C , Nr );
    lh_matrix_mu_matrix( A , B , AB , Nc , Nr , Nr );
    lh_matrix_mu_vector( AB , C , m_post , Nc , Nr );
    lh_vector_add_vector( m_prior , m_post , m_post , Nc );

    free2float( Gt );
    free2float( A  );
    free2float( B1 );
    free2float( B2 );
    free2float( B3 );
    free2float( B  );
    free1float( C1 );
    free1float( C );
    free2float( AB );
}
Example #2
0
int main(int argc, char* argv[])
{
	int	ix, iz, jx, jz,ixx,izz,ixf,izf,i,j,im, jm,nx,nz,nxf,nzf,nxpad,nzpad,it,ii,jj;
	float   kxmax,kzmax;

        float   f0, t, t0, dx, dz, dxf, dzf,dt, dkx, dkz, dt2;
        int     mm, nvx, nvz, ns;
        int     hnkx, hnkz, nkx, nkz, nxz, nkxz;
        int     hnkx1, hnkz1, nkx1, nkz1;
        int     isx, isz, isxm, iszm; /*source location */

        int     itaper; /* tapering or not for spectrum of oprtator*/
        int     nstep;            /* every nstep in spatial grids to calculate filters sparsely*/

        float   *coeff_1dx, *coeff_1dz, *coeff_2dx, *coeff_2dz; /* finite-difference coefficient */

        float **apx, **apz, **apxx, **apzz;        /* polarization operator of P-wave for a location */
        float **apxs, **apzs, **apxxs, **apzzs;    /* polarization operator of SV-wave for a location */

        float ****ex, ****ez;                      /* operator for whole model for P-wave*/
        float ****exs, ****ezs;                    /* operator for whole model for SV-wave*/
        float **exx, **ezz;                        /* operator for constant model for P-wave*/
        float **exxs, **ezzs;                      /* operator for constant model for SV-wave*/

        float **vp0, **vs0, **epsi, **del, **theta;         /* velocity model */
        float **p1, **p2, **p3, **q1, **q2, **q3, **p3c, **q3c, **sum;  /* wavefield array */

        float *kx, *kz, *kkx, *kkz, *kx2, *kz2, **taper;

        clock_t t1, t2, t3, t4;
        float   timespent; 
        float   A, fx, fz;

        int     isep=1;
        int     ihomo=1;

        char    *tapertype;

	double  vp2, vs2, ep2, de2, the;

        sf_init(argc,argv);

        sf_file Fo1, Fo2, Fo3, Fo4, Fo5, Fo6, Fo7, Fo8, Fo9, Fo10, Fo11, Fo12;
       
        t1=clock();
 
        /*  wavelet parameter for source definition */
        f0=30.0;                  
        t0=0.04;                  
        A=1.0;                  

        /* time samping paramter */
        if (!sf_getint("ns",&ns)) ns=301;
        if (!sf_getfloat("dt",&dt)) dt=0.001;
        if (!sf_getint("isep",&isep)) isep=0;             /* if isep=1, separate wave-modes */ 
        if (!sf_getint("ihomo",&ihomo)) ihomo=0;          /* if ihomo=1, homogeneous medium */
        if (NULL== (tapertype=sf_getstring("tapertype"))) tapertype="D"; /* taper type*/
        if (!sf_getint("nstep",&nstep)) nstep=1; /* grid step to calculate operators: 1<=nstep<=5 */

        sf_warning("isep=%d",isep);
        sf_warning("ihomo=%d",ihomo);
        sf_warning("tapertype=%s",tapertype);
        sf_warning("nstep=%d",nstep);

        sf_warning("ns=%d dt=%f",ns,dt);
        sf_warning("read velocity model parameters");

        /* setup I/O files */
        sf_file Fvp0, Fvs0, Feps, Fdel, Fthe;

        Fvp0 = sf_input ("in");  /* vp0 using standard input */
        Fvs0 = sf_input ("vs0");  /* vs0 */
        Feps = sf_input ("epsi");  /* epsi */
        Fdel = sf_input ("del");  /* delta */
        Fthe = sf_input ("the");  /* theta */

        /* Read/Write axes */
        sf_axis az, ax;
        az = sf_iaxa(Fvp0,1); nvz = sf_n(az); dz = sf_d(az)*1000.0;
        ax = sf_iaxa(Fvp0,2); nvx = sf_n(ax); dx = sf_d(ax)*1000.0;
        fx=sf_o(ax)*1000.0;
        fz=sf_o(az)*1000.0;

        /* source definition */
        isx=nvx/2;
        isz=nvz/2;
        //isz=nvz*2/5;

        /* wave modeling space */
	nx=nvx;
	nz=nvz;
        nxpad=nx+2*m;
        nzpad=nz+2*m;

        sf_warning("fx=%f fz=%f dx=%f dz=%f",fx,fz,dx,dz);

        sf_warning("nx=%d nz=%d nxpad=%d nzpad=%d", nx,nz,nxpad,nzpad);

	vp0=sf_floatalloc2(nz,nx);	
	vs0=sf_floatalloc2(nz,nx);	
	epsi=sf_floatalloc2(nz,nx);	
	del=sf_floatalloc2(nz,nx);	
	theta=sf_floatalloc2(nz,nx);	

        nxz=nx*nz;
        mm=2*m+1;

        dt2=dt*dt;
        isxm=isx+m;  /* source's x location */
        iszm=isz+m;  /* source's z-location */

        /* read velocity model */
        sf_floatread(vp0[0],nxz,Fvp0);
        sf_floatread(vs0[0],nxz,Fvs0);
        sf_floatread(epsi[0],nxz,Feps);
        sf_floatread(del[0],nxz,Fdel);
        sf_floatread(theta[0],nxz,Fthe);

        for(i=0;i<nx;i++)
        for(j=0;j<nz;j++)
           theta[i][j] *= PI/180.0;

        t2=clock();

        Fo1 = sf_output("out"); /* Elastic-wave x-component */
        Fo2 = sf_output("Elasticz"); /* Elastic-wave z-component */
        /* setup I/O files */
        puthead3(Fo1, nz, nx, 1, dz/1000.0, dx/1000.0, dt, fz/1000.0, fx/1000.0, 0.0);
        puthead3(Fo2, nz, nx, 1, dz/1000.0, dx/1000.0, dt, fz/1000.0, fx/1000.0, 0.0);

        /*****************************************************************************
         *  Calculating polarization operator for wave-mode separation
         * ***************************************************************************/
        if(isep==1)
        {
           sf_warning("==================================================");
           sf_warning("==      Calculating Polarization Operator       ==");
           sf_warning("==================================================");
           /* calculate spatial steps for operater in sparsely sampling grid point */
           dxf=dx*nstep;
           dzf=dz*nstep;
           nxf=nx/nstep+1;
           nzf=nz/nstep+1;

           /* operators length for calculation */
           hnkx=400.0/dx;
           hnkz=400.0/dz;
           nkx=2*hnkx+1;   /* operator length in kx-direction */
           nkz=2*hnkz+1;   /* operator length in kz-direction */

           /* truncated spatial operators length for filtering*/
           hnkx1=200.0/dx;
           hnkz1=200.0/dz;
           nkx1=2*hnkx1+1;
           nkz1=2*hnkz1+1;

           sf_warning("nx=%d nz=%d nxf=%d nzf=%d", nx,nz,nxf,nzf);
           sf_warning("dx=%f dz=%f dxf=%f dzf=%f", dx,dz,dxf,dzf);

           sf_warning("hnkx=%d hnkz=%d nkx=%d nkz=%d", hnkx, hnkz, nkx, nkz);
           sf_warning("hnkx1=%d hnkz1=%d nkx1=%d nkz1=%d", hnkx1, hnkz1, nkx1, nkz1);

           dkx=2*PI/dx/nkx;
           dkz=2*PI/dz/nkz;
	   kxmax=PI/dx;
	   kzmax=PI/dz;

           kx=sf_floatalloc(nkx);
           kz=sf_floatalloc(nkx);
           kkx=sf_floatalloc(nkx);
           kkz=sf_floatalloc(nkx);
           kx2=sf_floatalloc(nkx);
           kz2=sf_floatalloc(nkx);

           taper=sf_floatalloc2(nkz, nkx);

           // define axis samples and taper in wavenumber domain 
           kxkztaper(kx, kz, kkx, kkz, kx2, kz2, taper, nkx, nkz, hnkx, hnkz, dkx, dkz, kxmax, kzmax, tapertype);

           nkxz=nkx*nkz;

           /* truncation of spatial filter */
           if(ihomo==1)
           {
              exx=sf_floatalloc2(nkz1, nkx1);
              ezz=sf_floatalloc2(nkz1, nkx1);
              exxs=sf_floatalloc2(nkz1, nkx1);
              ezzs=sf_floatalloc2(nkz1, nkx1);
           }else{
	      ex=sf_floatalloc4(nkz1, nkx1, nz, nx);
	      ez=sf_floatalloc4(nkz1, nkx1, nz, nx);
	      exs=sf_floatalloc4(nkz1, nkx1, nz, nx);
	      ezs=sf_floatalloc4(nkz1, nkx1, nz, nx);
           }
           /*****************************************************************************
           *  Calculating polarization operator for wave-mode separation
           * ***************************************************************************/
	    apx=sf_floatalloc2(nkz, nkx);
	    apz=sf_floatalloc2(nkz, nkx);

	    apxs=sf_floatalloc2(nkz, nkx);
	    apzs=sf_floatalloc2(nkz, nkx);

	    apxx=sf_floatalloc2(nkz, nkx);
	    apzz=sf_floatalloc2(nkz, nkx);

	    apxxs=sf_floatalloc2(nkz, nkx);
	    apzzs=sf_floatalloc2(nkz, nkx);

            /* setup I/O files for wavenumber-domain operators */
            Fo3 = sf_output("apx"); /*  P-wave's polarization x-comp */
            Fo4 = sf_output("apz"); /*  P-wave's polarization z-comp */
            Fo5 = sf_output("apxs"); /*  SV-wave's polarization x-comp */
            Fo6 = sf_output("apzs"); /*  SV-wave's polarization z-comp */

            puthead1(Fo3, nkz, nkx, dkz, -kzmax, dkx, -kxmax);
            puthead1(Fo4, nkz, nkx, dkz, -kzmax, dkx, -kxmax);
            puthead1(Fo5, nkz, nkx, dkz, -kzmax, dkx, -kxmax);
            puthead1(Fo6, nkz, nkx, dkz, -kzmax, dkx, -kxmax);
 
            /* setup I/O files for space-domain operators */
            Fo7 = sf_output("apxx");  /* P-wave's polarization x-comp in (x,z) domain */
            Fo8 = sf_output("apzz");  /* P-wave's polarization z-comp in (x,z) domain */
            Fo9 = sf_output("apxxs"); /* SV-wave's polarization x-comp in (x,z) domain */
            Fo10 = sf_output("apzzs"); /* SV-wave's polarization z-comp in (x,z) domain */

            puthead2(Fo7, nkz, nkx, dz/1000.0, 0.0, dx/1000.0, 0.0);
            puthead2(Fo8, nkz, nkx, dz/1000.0, 0.0, dx/1000.0, 0.0);
            puthead2(Fo9, nkz, nkx, dz/1000.0, 0.0, dx/1000.0, 0.0);
            puthead2(Fo10, nkz, nkx, dz/1000.0, 0.0, dx/1000.0, 0.0);

	    /*************calculate projection deviation grid-point by grid-point **********/
           for(ix=0,ixf=0;ix<nx;ix+=nstep,ixf++)
           {
              for(iz=0,izf=0;iz<nz;iz+=nstep,izf++)
              {
	        vp2=vp0[ix][iz]*vp0[ix][iz];
	        vs2=vs0[ix][iz]*vs0[ix][iz];
	        ep2=1.0+2*epsi[ix][iz];
	        de2=1.0+2*del[ix][iz];
                the=theta[ix][iz];

               if(ixf%10==0&&izf%100==0) sf_warning("Operator: nxf=%d ixf=%d izf=%d vp2=%f vs2=%f",nxf, ixf,izf,vp2,vs2);

   	        /*************calculate projection operrate with tapering **********/
                zero2float(apx, nkz, nkx);
                zero2float(apz, nkz, nkx);
                zero2float(apxs, nkz, nkx);
                zero2float(apzs, nkz, nkx);
               
                /* polvtipsv: P- and SV-wave polarization operators in VTI media  */
                itaper=1;
                polttipsv(apx,apz,apxs,apzs,kx,kz,kkx,kkz,taper,hnkx,hnkz,dkx,dkz,
                          vp2,vs2,ep2,de2,the,itaper);

                ikxkz2xz(apx, apxx, hnkx, hnkz, nkx, nkz);
                ikxkz2xz(apz, apzz, hnkx, hnkz, nkx, nkz);
                ikxkz2xz(apxs, apxxs, hnkx, hnkz, nkx, nkz);
                ikxkz2xz(apzs, apzzs, hnkx, hnkz, nkx, nkz);

                // truncation and saving of operator in space-domain
                if(ihomo==1)
                {
                   for(jx=-hnkx1,ixx=hnkx-hnkx1;jx<=hnkx1;jx++,ixx++) 
                   for(jz=-hnkz1,izz=hnkz-hnkz1;jz<=hnkz1;jz++,izz++) 
                   {
                     exx[jx+hnkx1][jz+hnkz1]=apxx[ixx][izz]; 
                     ezz[jx+hnkx1][jz+hnkz1]=apzz[ixx][izz]; 
                     exxs[jx+hnkx1][jz+hnkz1]=apxxs[ixx][izz]; 
                     ezzs[jx+hnkx1][jz+hnkz1]=apzzs[ixx][izz]; 
                   }
                }else{
                   for(jx=-hnkx1,ixx=hnkx-hnkx1;jx<=hnkx1;jx++,ixx++) 
                   for(jz=-hnkz1,izz=hnkz-hnkz1;jz<=hnkz1;jz++,izz++) 
                   {
                     ex[ixf][izf][jx+hnkx1][jz+hnkz1]=apxx[ixx][izz]; 
                     ez[ixf][izf][jx+hnkx1][jz+hnkz1]=apzz[ixx][izz]; 
                     exs[ixf][izf][jx+hnkx1][jz+hnkz1]=apxxs[ixx][izz]; 
                     ezs[ixf][izf][jx+hnkx1][jz+hnkz1]=apzzs[ixx][izz]; 
                   }
                }
                
                if((ixf==nxf/2&&izf==nzf/2&&ihomo==0)||ihomo==1)
                {
                   //write-disk operators in kx-kz domain
	           sf_floatwrite(apx[0], nkxz, Fo3);
	           sf_floatwrite(apz[0], nkxz, Fo4);
	           sf_floatwrite(apxs[0], nkxz, Fo5);
	           sf_floatwrite(apzs[0], nkxz, Fo6);

                   //write-disk operators in x-z domain
	           sf_floatwrite(apxx[0], nkxz, Fo7);
	           sf_floatwrite(apzz[0], nkxz, Fo8);
	           sf_floatwrite(apxxs[0], nkxz, Fo9);
	           sf_floatwrite(apzzs[0], nkxz, Fo10);
                }
                if(ihomo==1) goto loop;
             }// iz loop
           }//ix loop
           loop:;

           free(kx);
           free(kz);
           free(kx2);
           free(kz2);
           free(kkx);
           free(kkz);

           free(*taper);

           free(*apx);
           free(*apz);
           free(*apxs);
           free(*apzs);
           free(*apxx);
           free(*apzz);
           free(*apxxs);
           free(*apzzs);
        }// isep loop
	/****************End of Calculating Projection Deviation Operator****************/
        t3=clock();
        timespent=(float)(t3-t2)/CLOCKS_PER_SEC;
        sf_warning("Computation time (operators): %f (second)",timespent);
 
	/****************begin to calculate wavefield****************/
	/****************begin to calculate wavefield****************/
        sf_warning("==================================================");
        sf_warning("==      Propagation Using Elastic Wave Eq.      ==");
        sf_warning("==================================================");
       coeff_2dx=sf_floatalloc(mm);
       coeff_2dz=sf_floatalloc(mm);
       coeff_1dx=sf_floatalloc(mm);
       coeff_1dz=sf_floatalloc(mm);

        coeff2d(coeff_2dx,dx);
        coeff2d(coeff_2dz,dz);

	p1=sf_floatalloc2(nzpad, nxpad);
	p2=sf_floatalloc2(nzpad, nxpad);
	p3=sf_floatalloc2(nzpad, nxpad);

	q1=sf_floatalloc2(nzpad, nxpad);
	q2=sf_floatalloc2(nzpad, nxpad);
	q3=sf_floatalloc2(nzpad, nxpad);

        zero2float(p1, nzpad, nxpad);
        zero2float(p2, nzpad, nxpad);
        zero2float(p3, nzpad, nxpad);
      
        zero2float(q1, nzpad, nxpad);
        zero2float(q2, nzpad, nxpad);
        zero2float(q3, nzpad, nxpad);
        
        coeff1dmix(coeff_1dx,dx);
        coeff1dmix(coeff_1dz,dz);

        if(isep==1)
        {
            Fo11 = sf_output("ElasticSepP"); /*  scalar wavefield using P-wave's polarization projection oprtator*/
            Fo12 = sf_output("ElasticSepSV"); /*  scalar wavefield using SV-wave's polarization projection oprtator*/

            puthead3(Fo11, nz, nx, 1, dz/1000.0, dx/1000.0, dt, fz/1000.0, fx/1000.0, 0.0);
            puthead3(Fo12, nz, nx, 1, dz/1000.0, dx/1000.0, dt, fz/1000.0, fx/1000.0, 0.0);

	   p3c=sf_floatalloc2(nz,nx);
	   q3c=sf_floatalloc2(nz,nx);
           sum=sf_floatalloc2(nz,nx);

        }

	for(it=0;it<ns;it++)
	{
		t=it*dt;

                // 2D exploding force source (e.g., Wu's PhD
                for(i=-1;i<=1;i++)
                for(j=-1;j<=1;j++)
                {
                     if(fabs(i)+fabs(j)==2)
                     {
                          p2[isxm+i][iszm+j]+=i*Ricker(t, f0, t0, A);
                          q2[isxm+i][iszm+j]+=j*Ricker(t, f0, t0, A);
                     }
                }
        // 2D equil-energy force source (e.g., Wu's PhD)
        /*
        for(i=-1;i<=1;i++)
        for(j=-1;j<=1;j++)
        {
             if(fabs(i)+fabs(j)==2)
             {
                  if(i==-1&&j==1)  
                    q2[isxm+i][iszm+j]+=sqrt(2.0)*Ricker(t, f0, t0, A);
                  if(i==-1&&j==-1) 
                   p2[isxm+i][iszm+j]+=-sqrt(2.0)*Ricker(t, f0, t0, A);
                  if(i==1&&j==1)  
                   p2[isxm+i][iszm+j]+=sqrt(2.0)*Ricker(t, f0, t0, A);
                  if(i==1&&j==-1) 
                    q2[isxm+i][iszm+j]+=-sqrt(2.0)*Ricker(t, f0, t0, A);
             }
        }
        */
                /* fwpvtielastic: forward-propagating using original elastic equation of displacement in VTI media*/
		fwpttielastic(dt2, p1, p2, p3, q1, q2, q3, coeff_2dx, coeff_2dz, coeff_1dx, coeff_1dz,
                              dx, dz, nx, nz, nxpad, nzpad, vp0, vs0, epsi, del, theta);

               /******* output wavefields: component and divergence *******/
	       if(it==ns-1)
		{
		     for(i=0;i<nx;i++)
                     {
                        im=i+m;
		        for(j=0;j<nz;j++)
		        {
                            jm=j+m;
	                    sf_floatwrite(&p3[im][jm],1,Fo1);
	                    sf_floatwrite(&q3[im][jm],1,Fo2);
			}
                     }/* i loop*/

                       
                     if(isep==1)
                     {
                        //////////////////////////////////////////////////////////////////////////////////////////
                        /* applying P-wave polarization projection operator in spatial domain */
	                zero2float(p3c,nz,nx);
	                zero2float(q3c,nz,nx);
                        zero2float(sum, nz, nx);

                        if(ihomo==1)
                            filter2dsepglobal(p3, q3, p3c, q3c, exx, ezz, nx, nz, hnkx1, hnkz1);
                        else
                            filter2dsep(p3, q3, p3c, q3c, ex, ez, nx, nz, nstep, hnkx1, hnkz1);

			for(i=0;i<nx;i++)
			for(j=0;j<nz;j++)
			   sum[i][j]=p3c[i][j]+q3c[i][j];

			sf_floatwrite(sum[0],nx*nz, Fo11);
          
                        //////////////////////////////////////////////////////////////////////////////////////////
                        /* applying SV-wave polarization projection operator in spatial domain */
	                zero2float(p3c,nz,nx);
	                zero2float(q3c,nz,nx);
                        zero2float(sum, nz, nx);

                        if(ihomo==1)
                            filter2dsepglobal(p3, q3, p3c, q3c, exxs, ezzs, nx, nz, hnkx1, hnkz1);
                        else
                            filter2dsep(p3, q3, p3c, q3c, exs, ezs, nx, nz, nstep, hnkx1, hnkz1);

			for(i=0;i<nx;i++)
			for(j=0;j<nz;j++)
			   sum[i][j]=p3c[i][j]+q3c[i][j];

			sf_floatwrite(sum[0],nx*nz, Fo12);
                     }// isep==1

                }/* (it+1)%ntstep==0 */

                /**************************************/
 	        for(i=0,ii=m;i<nx;i++,ii++)
	        for(j=0,jj=m;j<nz;j++,jj++)
		{
				p1[ii][jj]=p2[ii][jj];	
				p2[ii][jj]=p3[ii][jj];	

				q1[ii][jj]=q2[ii][jj];	
				q2[ii][jj]=q3[ii][jj];	
		}

		if(it%100==0)
			sf_warning("Elastic: it= %d",it);
        }/* it loop */
        t4=clock();
        timespent=(float)(t4-t3)/CLOCKS_PER_SEC;
        sf_warning("Computation time (propagation + separation): %f (second)",timespent);

        if(isep==1)
        {
          free(*p3c);
          free(*q3c);
          free(*sum);

          if(ihomo==1)
          {
              free(*exx);
              free(*ezz);
              free(*exxs);
              free(*ezzs);
          }else{
              free(***ex);
              free(***ez);
              free(***exs);
              free(***ezs);
          }
        }

        free(*p1);
        free(*p2);
        free(*p3);
        free(*q1);
        free(*q2);
        free(*q3);

        free(*vp0);
        free(*vs0);
        free(*epsi);
        free(*del);
        free(*theta);

	exit(0);
}
Example #3
0
int main(int argc, char* argv[])
{
     	int	i,j,im,jm,nx,nz,nxpad,nzpad,it,ii,jj;

        float   f0, t, t0, dx, dz,dt, dt2;
        int     mm, nvx, nvz, ns;
        int     isx, isz, isxm, iszm; /*source location */

        float   *coeff_1dx, *coeff_1dz, *coeff_2dx, *coeff_2dz; /* finite-difference coefficient */

        float **vp0, **vs0, **epsi, **del, **theta;         /* velocity model */
        float **p1, **p2, **p3, **q1, **q2, **q3;  /* wavefield array */

        float   A, fx, fz;
		clock_t t1, t2, t3;

        sf_init(argc,argv);

        sf_file Fo1, Fo2;
		float timespent;
       
		t1 = clock();

        /*  wavelet parameter for source definition */
        f0=30.0;                  
        t0=0.04;                  
        A=1.0;                  

        /* time samping paramter */
        if (!sf_getint("ns",&ns)) ns=301;
        if (!sf_getfloat("dt",&dt)) dt=0.001;

        sf_warning("ns=%d dt=%f",ns,dt);
        sf_warning("read velocity model parameters");

        /* setup I/O files */
        sf_file Fvp0, Fvs0, Feps, Fdel, Fthe;

        Fvp0 = sf_input ("in");  /* vp0 using standard input */
        Fvs0 = sf_input ("vs0");  /* vs0 */
        Feps = sf_input ("epsi");  /* epsi */
        Fdel = sf_input ("del");  /* delta */
        Fthe = sf_input ("the");  /* theta */

        /* Read/Write axes */
        sf_axis az, ax;
        az = sf_iaxa(Fvp0,1); nvz = sf_n(az); dz = sf_d(az)*1000.0;
        ax = sf_iaxa(Fvp0,2); nvx = sf_n(ax); dx = sf_d(ax)*1000.0;
        fx=sf_o(ax)*1000.0;
        fz=sf_o(az)*1000.0;

        /* source definition */
        isx=nvx/2;
        isz=nvz/2;
        //isz=nvz*2/5;

        /* wave modeling space */
	nx=nvx;
	nz=nvz;
        nxpad=nx+2*_m;
        nzpad=nz+2*_m;

        sf_warning("fx=%f fz=%f dx=%f dz=%f",fx,fz,dx,dz);

        sf_warning("nx=%d nz=%d nxpad=%d nzpad=%d", nx,nz,nxpad,nzpad);

	vp0=sf_floatalloc2(nz,nx);	
	vs0=sf_floatalloc2(nz,nx);	
	epsi=sf_floatalloc2(nz,nx);	
	del=sf_floatalloc2(nz,nx);	
	theta=sf_floatalloc2(nz,nx);	

        int nxz=nx*nz;
        mm=2*_m+1;

        dt2=dt*dt;
        isxm=isx+_m;  /* source's x location */
        iszm=isz+_m;  /* source's z-location */

        /* read velocity model */
        sf_floatread(vp0[0],nxz,Fvp0);
        sf_floatread(vs0[0],nxz,Fvs0);
        sf_floatread(epsi[0],nxz,Feps);
        sf_floatread(del[0],nxz,Fdel);
        sf_floatread(theta[0],nxz,Fthe);

        for(i=0;i<nx;i++)
        for(j=0;j<nz;j++)
           theta[i][j] *= SF_PI/180.0;

        Fo1 = sf_output("out"); /* Elastic-wave x-component */
        Fo2 = sf_output("Elasticz"); /* Elastic-wave z-component */
        /* setup I/O files */
        puthead3(Fo1, nz, nx, 1, dz/1000.0, dx/1000.0, dt, fz/1000.0, fx/1000.0, 0.0);
        puthead3(Fo2, nz, nx, 1, dz/1000.0, dx/1000.0, dt, fz/1000.0, fx/1000.0, 0.0);

	/****************begin to calculate wavefield****************/
	/****************begin to calculate wavefield****************/
        sf_warning("==================================================");
        sf_warning("==      Porpagation Using Elastic Wave Eq.      ==");
        sf_warning("==================================================");
       coeff_2dx=sf_floatalloc(mm);
       coeff_2dz=sf_floatalloc(mm);
       coeff_1dx=sf_floatalloc(mm);
       coeff_1dz=sf_floatalloc(mm);

        coeff2d(coeff_2dx,dx);
        coeff2d(coeff_2dz,dz);

	p1=sf_floatalloc2(nzpad, nxpad);
	p2=sf_floatalloc2(nzpad, nxpad);
	p3=sf_floatalloc2(nzpad, nxpad);

	q1=sf_floatalloc2(nzpad, nxpad);
	q2=sf_floatalloc2(nzpad, nxpad);
	q3=sf_floatalloc2(nzpad, nxpad);

        zero2float(p1, nzpad, nxpad);
        zero2float(p2, nzpad, nxpad);
        zero2float(p3, nzpad, nxpad);
      
        zero2float(q1, nzpad, nxpad);
        zero2float(q2, nzpad, nxpad);
        zero2float(q3, nzpad, nxpad);
        
        coeff1dmix(coeff_1dx,dx);
        coeff1dmix(coeff_1dz,dz);

		t2 = clock();
	for(it=0;it<ns;it++)
	{
		t=it*dt;

                // 2D exploding force source (e.g., Wu's PhD
                for(i=-1;i<=1;i++)
                for(j=-1;j<=1;j++)
                {
                     if(fabs(i)+fabs(j)==2)
                     {
                          p2[isxm+i][iszm+j]+=sqrt(2.0)*i*Ricker(t, f0, t0, A);
                          q2[isxm+i][iszm+j]+=sqrt(2.0)*j*Ricker(t, f0, t0, A);
                     }
                }
        // 2D equil-energy force source (e.g., Wu's PhD)
        /*
        for(i=-1;i<=1;i++)
        for(j=-1;j<=1;j++)
        {
             if(fabs(i)+fabs(j)==2)
             {
                  if(i==-1&&j==1)  
                    q2[isxm+i][iszm+j]+=sqrt(2.0)*Ricker(t, f0, t0, A);
                  if(i==-1&&j==-1) 
                   p2[isxm+i][iszm+j]+=-sqrt(2.0)*Ricker(t, f0, t0, A);
                  if(i==1&&j==1)  
                   p2[isxm+i][iszm+j]+=sqrt(2.0)*Ricker(t, f0, t0, A);
                  if(i==1&&j==-1) 
                    q2[isxm+i][iszm+j]+=-sqrt(2.0)*Ricker(t, f0, t0, A);
             }
        }
        */
                /* fwpvtielastic: forward-propagating using original elastic equation of displacement in VTI media*/
		fwpttielastic(dt2, p1, p2, p3, q1, q2, q3, coeff_2dx, coeff_2dz, coeff_1dx, coeff_1dz,
                              dx, dz, nx, nz, nxpad, nzpad, vp0, vs0, epsi, del, theta);

               /******* output wavefields: component and divergence *******/
	       if(it==ns-1)
		{
		     for(i=0;i<nx;i++)
                     {
                        im=i+_m;
		        for(j=0;j<nz;j++)
		        {
                            jm=j+_m;
	                    sf_floatwrite(&p3[im][jm],1,Fo1);
	                    sf_floatwrite(&q3[im][jm],1,Fo2);
			}
                     }/* i loop*/
                       
                }/* (it+1)%ntstep==0 */

                /**************************************/
 	        for(i=0,ii=_m;i<nx;i++,ii++)
	        for(j=0,jj=_m;j<nz;j++,jj++)
		{
				p1[ii][jj]=p2[ii][jj];	
				p2[ii][jj]=p3[ii][jj];	

				q1[ii][jj]=q2[ii][jj];	
				q2[ii][jj]=q3[ii][jj];	
		}

		if(it%100==0)
			sf_warning("Elastic: it= %d",it);
        }/* it loop */
   t3=clock();
   timespent=(float)(t3-t2)/CLOCKS_PER_SEC;
   sf_warning("CPU time for wavefield extrapolation.: %f(second)",timespent);

   timespent=(float)(t3-t1)/(ns*CLOCKS_PER_SEC);
   sf_warning("All CPU time: %f(second)",timespent);

        free(*p1);
        free(*p2);
        free(*p3);
        free(*q1);
        free(*q2);
        free(*q3);

        free(*vp0);
        free(*vs0);
        free(*epsi);
        free(*del);
        free(*theta);

	exit(0);
}
Example #4
0
void fwpttielastic(float dt2, float** p1,float** p2,float** p3, float** q1,float** q2,float** q3,
                   float* coeff_2dx,float* coeff_2dz, float* coeff_1dx,float* coeff_1dz,
                   float dx, float dz, int nx, int nz, int nxpad, int nzpad, 
                   float **vp0,float **vs0, float **epsilon,float **delta, float **theta)
/*< fwpttielastic: forward-propagating using original elastic equation of displacement in 2D TTI media>*/
{
    int   i,j,l;

    float vp2,vs2,ep,de,vpx2,vpn2, the;
    float sinthe,costhe,cos2,sin2,sin2a,cos_sin;
    float px,pxz,qxz,qx,px1, qxz1, qx1, pxz1,hpx,hqx,hpz,hqz;
    
    float **px_tmp;
    float **qx_tmp;

    int im, jm;

    px_tmp=sf_floatalloc2(nzpad,nxpad);
    qx_tmp=sf_floatalloc2(nzpad,nxpad);

    zero2float(px_tmp,nzpad,nxpad);	
    zero2float(qx_tmp,nzpad,nxpad);	

#ifdef _OPENMP
#pragma omp parallel for private(i,j,l)		\
    schedule(dynamic)				\
    shared(p2,q2,px_tmp,qx_tmp,coeff_1dx,dx)
#endif
    for(i=_m;i<nx+_m;i++)
	for(j=_m;j<nz+_m;j++)
	{
	    for(l=-_mix;l<=_mix;l++)
	    {
		int lm=l+_mix;
		px_tmp[i][j]+=coeff_1dx[lm]*p2[i+l][j]/2.0/dx;
		qx_tmp[i][j]+=coeff_1dx[lm]*q2[i+l][j]/2.0/dx;
	    }
	}

#ifdef _OPENMP
#pragma omp parallel for private(i,j,l,im,jm,vp2,vs2,ep,de,vpx2,vpn2, the, sinthe,costhe,cos2,sin2,sin2a,cos_sin, px,pxz,qxz,qx,px1, qxz1, qx1, pxz1,hpx,hqx,hpz,hqz) \
    schedule(dynamic)					\
    shared(p1,p2,p3,q1,q2,q3,				\
	   px_tmp,qx_tmp,				\
	   coeff_1dx,coeff_1dz,coeff_2dx,coeff_2dz,	\
	   vp0,vs0,epsilon,delta,theta,dt2)
#endif
    for(i=_m;i<nx+_m;i++)
    {
	im=i-_m;
	for(j=_m;j<nz+_m;j++)
	{
	    jm=j-_m;


	    vp2=vp0[im][jm]*vp0[im][jm];
	    vs2=vs0[im][jm]*vs0[im][jm];
	    ep=1+2*epsilon[im][jm];
	    de=1+2*delta[im][jm];
	    the=theta[im][jm];

	    costhe=cos(the);
	    sinthe=sin(the);
	    cos2=costhe*costhe;
	    sin2=sinthe*sinthe;
	    cos_sin=costhe*sinthe;
	    sin2a=2*cos_sin;

	    vpx2=vp2*ep;
	    vpn2=vp2*de;
/*	    coef=sqrt((vp2-vs2)*(vpn2-vs2)); */

	    pxz=0;
	    qxz=0;
	    for(l=-_mix;l<=_mix;l++)
	    {
		int lm=l+_mix;
		pxz+=coeff_1dz[lm]*px_tmp[i][j+l]/2.0/dz;
		qxz+=coeff_1dz[lm]*qx_tmp[i][j+l]/2.0/dz;
	    }

	    hpx=0;
	    hpz=0;
	    hqx=0;
	    hqz=0;
	    for(l=-_m;l<=_m;l++)
	    {
		int lm=l+_m;
		hpx+=coeff_2dx[lm]*p2[i+l][j];
		hqx+=coeff_2dx[lm]*q2[i+l][j];
		hpz+=coeff_2dz[lm]*p2[i][j+l];
		hqz+=coeff_2dz[lm]*q2[i][j+l];
	    }

	    px  = cos2*hpx + sin2*hpz + sin2a*pxz;
	    px1 = sin2*hpx + cos2*hpz - sin2a*pxz;
	    qxz1 = -cos_sin*hqx + cos_sin*hqz + (cos2-sin2)*qxz;

	    p3[i][j]=2*p2[i][j] - p1[i][j] + dt2*( vpx2*px +  vs2*px1 + sqrt((vp2-vs2)*(vpn2-vs2))*qxz1);

	    qx  = cos2*hqx + sin2*hqz + sin2a*qxz;
	    qx1 = sin2*hqx + cos2*hqz - sin2a*qxz;
	    pxz1 = -cos_sin*hpx + cos_sin*hpz + (cos2-sin2)*pxz;

	    q3[i][j]=2*q2[i][j] - q1[i][j] + dt2*( vs2*qx +  vp2*qx1 + sqrt((vp2-vs2)*(vpn2-vs2))*pxz1);
	}
    }

    free(*px_tmp);	
    free(*qx_tmp);	
}
int main( int argc , char* argv[] )
{
    sf_init( argc , argv );

    sf_file FI1, FI2, FI3, FO1;

    sf_axis aa;

    int dim, num_dim[SF_MAX_DIM], NTRACE, NT, nw, nwave, wsft, itrace, idim;

    float dt, **ref, **Q, *wave, **gather, **TVM;

    if(!sf_getint( "wsft" , &wsft ))  sf_error( "MISSING wave_shift PARAMETER!!\n" );
    /* The wave shift should be set up! */

    FI1 = sf_input( "ref" );
    FI2 = sf_input( "Q" );
    FI3 = sf_input( "wave" );
    FO1 = sf_output( "gather" );

    NTRACE = sf_leftsize( FI1 , 1 );
    dim = sf_filedims( FI1 , num_dim );

    /* define the LEFTSIZE bigger than the first 
     * dimension, so we can treat the data as two
     * dimensional-data, 
     */

    NT = sf_n( sf_iaxa( FI1 , 1 ) );
    dt = sf_d( sf_iaxa( FI1 , 1 ) );
    nw = sf_n( sf_iaxa( FI3 , 1 ) );

    /* extract the information about the first
     * dimension, which is needed by the function
     * of calculating the attenuated wavelet
     */

    nwave = lh_powerof2( nw );

    /* compute the suitable length for the FFT
     */

    ref     = alloc2float( NT , NTRACE );
    Q       = alloc2float( NT , NTRACE );
    gather  = alloc2float( NT , NTRACE );
    wave    = alloc1float( nwave );
    TVM     = alloc2float( NT , NT );

    zero2float( ref   , NT , NTRACE );
    zero2float( Q     , NT , NTRACE );
    zero2float( gather, NT , NTRACE );
    zero1float( wave  , nwave );

    /* alloc and setup */

    sf_floatread( &ref[0][0] , NT*NTRACE , FI1 );
    sf_floatread( &Q[0][0]   , NT*NTRACE , FI2 );
    sf_floatread( &wave[0]   , nw        , FI3 );

    for( itrace=0 ; itrace<NTRACE ; itrace++ )
    {
        zero2float( TVM , NT , NT );
        lh_time_variant_matrix( wave , wsft , nwave , dt , &Q[itrace][0], NT , TVM );
        lh_matrix_mu_vector( TVM , &ref[itrace][0] , &gather[itrace][0], NT , NT );
    }
/*
float **spec_real, **spec_imag, **spec_amp;
int nwave1 = lh_powerof2( NT );

spec_real = alloc2float( nwave1 , NT );
spec_imag = alloc2float( nwave1 , NT );
spec_amp  = alloc2float( 200 , NT );

zero2float( spec_real , nwave1 , NT );
zero2float( spec_imag , nwave1 , NT );
zero2float( spec_amp  , 200   , NT );

int i,j;
for( i=0 ; i<NT ; i++ )
{
    for( j=0 ; j<NT ; j++ )
    spec_real[i][j] = TVM[j][i];

    lh_fft( &spec_real[i][0] , &spec_imag[i][0], nwave1 , 1 );

    for( j=0 ; j<200 ; j++ )
    spec_amp[i][j] = sqrt( spec_real[i][j]*spec_real[i][j]+spec_imag[i][j]*spec_imag[i][j] );
}
lh_write_2d_float_bin_row( spec_amp , NT , 200 , "spec_amp_qwave.bin" );
*/

    for( idim=1 ; idim<=dim ; idim++ )
    {
        aa = sf_iaxa( FI1 , idim );
        sf_oaxa( FO1 , aa , idim );
    }
    sf_floatwrite( &gather[0][0] , NT*NTRACE , FO1 );

    exit( 0 );
}
Example #6
0
int main(int argc, char* argv[])
{
    int	ix, iz, jx, jz, ixf, izf, ixx, izz, i,j,im, jm,nx,nz,nxf,nzf,nxpad,nzpad,it,ii,jj;
    float   kxmax,kzmax;

    float   A, f0, t, t0, dx, dz, dxf, dzf, dt, dkx, dkz, dt2, div;
    int     mm, nvx, nvz, ns;
    int     hnkx, hnkz, nkx, nkz, nxz, nkxz;
    int     hnkx1=1, hnkz1=1, nkx1, nkz1;
    int     isx, isz, isxm, iszm; /*source location */
    int     itaper; /* tapering or not for spectrum of oprtator*/

    int     nstep;            /* every nstep in spatial grids to calculate filters sparsely*/

    float   *coeff_1dx, *coeff_1dz, *coeff_2dx, *coeff_2dz; /* finite-difference coefficient */

    float **apvx, **apvz, **apvxx, **apvzz;    /* projection deviation operator of P-wave for a location */

    float ****ex=NULL, ****ez=NULL;                      /* operator for whole model for P-wave*/
    float **exx=NULL, **ezz=NULL;                        /* operator for constant model for P-wave*/

    float **vp0, **vs0, **epsi, **del, **theta;         /* velocity model */
    float **p1, **p2, **p3, **q1, **q2, **q3, **p3c=NULL, **q3c=NULL, **sum=NULL;  /* wavefield array */
    float *kx, *kz, *kkx, *kkz, *kx2, *kz2, **taper;

    clock_t t2, t3, t4, t5;
    float   timespent, fx,fz; 
    char    *tapertype;

    int     isep=1;
    int     ihomo=1;

    double  vp2, vs2, ep2, de2, the;

    sf_file Fo1, Fo2, Fo3, Fo4, Fo5, Fo6, Fo7, Fo8;
    sf_file Fvp0, Fvs0, Feps, Fdel, Fthe;

    sf_axis az, ax;
       
    sf_init(argc,argv);

    /* t1=clock(); */
 
    /*  wavelet parameter for source definition */
    f0=30.0;                  
    t0=0.04;                  
    A=1.0;                  

    /* time samping paramter */
    if (!sf_getint("ns",&ns)) ns=301;
    if (!sf_getfloat("dt",&dt)) dt=0.001;
    if (!sf_getint("isep",&isep)) isep=0;             /* if isep=1, separate wave-modes */
    if (!sf_getint("ihomo",&ihomo)) ihomo=0;          /* if ihomo=1, homogeneous medium */
    if (NULL== (tapertype=sf_getstring("tapertype"))) tapertype="D"; /* taper type*/
    if (!sf_getint("nstep",&nstep)) nstep=1; /* grid step to calculate operators: 1<=nstep<=5 */

    sf_warning("isep=%d",isep);
    sf_warning("ihomo=%d",ihomo);
    sf_warning("tapertype=%s",tapertype);
    sf_warning("nstep=%d",nstep);

    sf_warning("ns=%d dt=%f",ns,dt);
    sf_warning("read velocity model parameters");

    /* setup I/O files */
    Fvp0 = sf_input ("in");  /* vp0 using standard input */
    Fvs0 = sf_input ("vs0");  /* vs0 */
    Feps = sf_input ("epsi");  /* epsi */
    Fdel = sf_input ("del");  /* delta */
    Fthe = sf_input ("the");  /* theta */

    /* Read/Write axes */
    az = sf_iaxa(Fvp0,1); nvz = sf_n(az); dz = sf_d(az)*1000.0;
    ax = sf_iaxa(Fvp0,2); nvx = sf_n(ax); dx = sf_d(ax)*1000.0;
    fx=sf_o(ax);
    fz=sf_o(az);

    /* source definition */
    isx=nvx/2;
    isz=nvz/2;
    /* isz=nvz*2/5; */

    /* wave modeling space */
    nx=nvx;
    nz=nvz;
    nxpad=nx+2*_m;
    nzpad=nz+2*_m;

    sf_warning("dx=%f dz=%f",dx,dz);

    sf_warning("nx=%d nz=%d nxpad=%d nzpad=%d", nx,nz,nxpad,nzpad);

    vp0=sf_floatalloc2(nz,nx);	
    vs0=sf_floatalloc2(nz,nx);	
    epsi=sf_floatalloc2(nz,nx);	
    del=sf_floatalloc2(nz,nx);	
    theta=sf_floatalloc2(nz,nx);	

    nxz=nx*nz;
    mm=2*_m+1;

    dt2=dt*dt;
    isxm=isx+_m;  /* source's x location */
    iszm=isz+_m;  /* source's z-location */

    /* read velocity model */
    sf_floatread(vp0[0],nxz,Fvp0);
    sf_floatread(vs0[0],nxz,Fvs0);
    sf_floatread(epsi[0],nxz,Feps);
    sf_floatread(del[0],nxz,Fdel);
    sf_floatread(theta[0],nxz,Fthe);

    for(i=0;i<nx;i++)
        for(j=0;j<nz;j++)
	    theta[i][j] *= SF_PI/180.0;

    t2=clock();

    /* setup I/O files */
    Fo1 = sf_output("out"); /* pseudo-pure P-wave x-component */
    Fo2 = sf_output("PseudoPurePz"); /* pseudo-pure P-wave z-component */
    Fo3 = sf_output("PseudoPureP"); /* scalar P-wave field using divergence operator */
    puthead3(Fo1, nz, nx, 1, dz/1000.0, dx/1000.0, dt, fz, fx, 0.0);
    puthead3(Fo2, nz, nx, 1, dz/1000.0, dx/1000.0, dt, fz, fx, 0.0);
    puthead3(Fo3, nz, nx, 1, dz/1000.0, dx/1000.0, dt, fz, fx, 0.0);

    /*****************************************************************************
     *  Calculating polarization deviation operator for wave-mode separation
     * ***************************************************************************/
    if(isep==1)
    {
	/* calculate spatial steps for operater in sparsely sampling grid point */
	dxf=dx*nstep;
	dzf=dz*nstep;
	nxf=nx/nstep+1;
	nzf=nz/nstep+1;

	/* operators length for calculation */
	hnkx=400.0/dx;
	hnkz=400.0/dz;
	nkx=2*hnkx+1;   /* operator length in kx-direction */
	nkz=2*hnkz+1;   /* operator length in kz-direction */

	/* truncated spatial operators length for filtering*/
	hnkx1=200.0/dx;
	hnkz1=200.0/dz;
	nkx1=2*hnkx1+1;
	nkz1=2*hnkz1+1;

	sf_warning("nx=%d nz=%d nxf=%d nzf=%d", nx,nz,nxf,nzf);
	sf_warning("dx=%f dz=%f dxf=%f dzf=%f", dx,dz,dxf,dzf);

	sf_warning("hnkx=%d hnkz=%d nkx=%d nkz=%d", hnkx, hnkz, nkx, nkz);
	sf_warning("hnkx1=%d hnkz1=%d nkx1=%d nkz1=%d", hnkx1, hnkz1, nkx1, nkz1);

	dkx=2*SF_PI/dx/nkx;
	dkz=2*SF_PI/dz/nkz;
	kxmax=SF_PI/dx;
	kzmax=SF_PI/dz;

	kx=sf_floatalloc(nkx);
	kz=sf_floatalloc(nkx);
	kkx=sf_floatalloc(nkx);
	kkz=sf_floatalloc(nkx);
	kx2=sf_floatalloc(nkx);
	kz2=sf_floatalloc(nkx);

	taper=sf_floatalloc2(nkz, nkx);

	/* define axis samples and taper in wavenumber domain */
	kxkztaper(kx, kz, kkx, kkz, kx2, kz2, taper, nkx, nkz, hnkx, hnkz, dkx, dkz, kxmax, kzmax, tapertype);
           
	/* truncation of spatial filter */
	p3c=sf_floatalloc2(nz,nx);
	q3c=sf_floatalloc2(nz,nx);
	sum=sf_floatalloc2(nz,nx);

	if(ihomo==1)
	{
	    exx=sf_floatalloc2(nkz1, nkx1);
	    ezz=sf_floatalloc2(nkz1, nkx1);
	}
	else{ /* to store spatail varaied operators */
	    ex=sf_floatalloc4(nkz1, nkx1, nzf, nxf);
	    ez=sf_floatalloc4(nkz1, nkx1, nzf, nxf);
	}
	nkxz=nkx*nkz;

	apvx=sf_floatalloc2(nkz, nkx);
	apvz=sf_floatalloc2(nkz, nkx);
	apvxx=sf_floatalloc2(nkz, nkx);
	apvzz=sf_floatalloc2(nkz, nkx);

	/* setup I/O files */
	Fo4 = sf_output("apvx"); /* P-wave projection deviation x-comp */
	Fo5 = sf_output("apvz"); /* P-wave projection deviation z-comp */
	Fo6 = sf_output("apvxx"); /* P-wave projection deviation x-comp in (x,z) domain */
	Fo7 = sf_output("apvzz"); /* P-wave projection deviation z-comp in (x,z) domain */

	puthead1(Fo4, nkz, nkx, dkz, -kzmax, dkx, -kxmax);
	puthead1(Fo5, nkz, nkx, dkz, -kzmax, dkx, -kxmax);

	puthead2(Fo6, nkz, nkx, dz/1000.0, 0.0, dx/1000.0, 0.0);
	puthead2(Fo7, nkz, nkx, dz/1000.0, 0.0, dx/1000.0, 0.0);

	/*************calculate projection deviation grid-point by grid-point **********/
	for(ix=0,ixf=0;ix<nx;ix+=nstep,ixf++)
	{
	    for(iz=0,izf=0;iz<nz;iz+=nstep,izf++)
	    {
	        vp2=vp0[ix][iz]*vp0[ix][iz];
	        vs2=vs0[ix][iz]*vs0[ix][iz];
	        ep2=1.0+2*epsi[ix][iz];
	        de2=1.0+2*del[ix][iz];
	        the=theta[ix][iz];

                if(ixf%10==0&&izf%100==0) sf_warning("Operator: nxf=%d ixf=%d izf=%d vp2=%f vs2=%f",nxf, ixf,izf,vp2,vs2);

   	        /*************calculate projection deviation without tapering **********/
                itaper=0;
                /* devvtip: projection deviation operators for P-wave in TTI media */
                devttip(apvx,apvz,kx,kz,kkx,kkz,taper,hnkx,hnkz,dkx,dkz,vp2,vs2,ep2,de2,the,itaper);

                /* inverse Fourier transform */
                kxkz2xz(apvx, apvxx, hnkx, hnkz, nkx, nkz);
                kxkz2xz(apvz, apvzz, hnkx, hnkz, nkx, nkz);

                /* truncation and saving of operator in space-domain */
                if(ihomo==1)
                {
		    for(jx=-hnkx1,ixx=hnkx-hnkx1;jx<=hnkx1;jx++,ixx++)
			for(jz=-hnkz1,izz=hnkz-hnkz1;jz<=hnkz1;jz++,izz++)
			{
			    exx[jx+hnkx1][jz+hnkz1]=apvxx[ixx][izz];
			    ezz[jx+hnkx1][jz+hnkz1]=apvzz[ixx][izz];
			}
                }else{
		    for(jx=-hnkx1,ixx=hnkx-hnkx1;jx<=hnkx1;jx++,ixx++)
			for(jz=-hnkz1,izz=hnkz-hnkz1;jz<=hnkz1;jz++,izz++)
			{
			    ex[ixf][izf][jx+hnkx1][jz+hnkz1]=apvxx[ixx][izz];
			    ez[ixf][izf][jx+hnkx1][jz+hnkz1]=apvzz[ixx][izz];
			}
                }
                if((ix==nx/2&&iz==nz/2&&ihomo==0)||ihomo==1)
                {
		    sf_floatwrite(apvx[0], nkxz, Fo4);
		    sf_floatwrite(apvz[0], nkxz, Fo5);

		    sf_floatwrite(apvxx[0], nkxz, Fo6);
		    sf_floatwrite(apvzz[0], nkxz, Fo7);
                }
                if(ihomo==1) goto loop;

	    }/* iz loop */
	}/* ix loop */
    loop:;

	free(kx);
	free(kz);
	free(kx2);
	free(kz2);
	free(kkx);
	free(kkz);

	free(*taper);

	free(*apvx);
	free(*apvz);
	free(*apvxx);
	free(*apvzz);
    }/* isep */
    /****************End of Calculating Projection Deviation Operator****************/
    t3=clock();
    timespent=(float)(t3-t2)/CLOCKS_PER_SEC;
    sf_warning("Computation time (operators): %f (second)",timespent);

    /****************begin to calculate wavefield****************/
    coeff_2dx=sf_floatalloc(mm);
    coeff_2dz=sf_floatalloc(mm);
    coeff_1dx=sf_floatalloc(mm);
    coeff_1dz=sf_floatalloc(mm);

    coeff2d(coeff_2dx,dx);
    coeff2d(coeff_2dz,dz);
    coeff1d(coeff_1dx,dx);
    coeff1d(coeff_1dz,dz);

    p1=sf_floatalloc2(nzpad, nxpad);
    p2=sf_floatalloc2(nzpad, nxpad);
    p3=sf_floatalloc2(nzpad, nxpad);

    q1=sf_floatalloc2(nzpad, nxpad);
    q2=sf_floatalloc2(nzpad, nxpad);
    q3=sf_floatalloc2(nzpad, nxpad);

    zero2float(p1, nzpad, nxpad);
    zero2float(p2, nzpad, nxpad);
    zero2float(p3, nzpad, nxpad);
        
    zero2float(q1, nzpad, nxpad);
    zero2float(q2, nzpad, nxpad);
    zero2float(q3, nzpad, nxpad);
        
    if(isep==1)
    {
        /* setup I/O files */
        Fo8 = sf_output("PseudoPureSepP"); /* scalar P-wave field using polarization projection oprtator*/

        puthead3(Fo8, nz, nx, 1, dz/1000.0, dx/1000.0, dt, fz, fx, 0.0);
    } else {
	Fo8 = NULL;
    }

    sf_warning("==================================================");
    sf_warning("==  Propagation Using Pseudo-Pure P-Wave Eq.    ==");
    sf_warning("==================================================");
    t4=clock();
    for(it=0;it<ns;it++)
    {
	t=it*dt;

	p2[isxm][iszm]+=Ricker(t, f0, t0, A);
	q2[isxm][iszm]+=Ricker(t, f0, t0, A);

	/* fwpttipseudop: forward-propagating in TTI media with pseudo-pure P-wave equation */
	fwpttipseudop(dt2, p1, p2, p3, q1, q2, q3, coeff_2dx, coeff_2dz,
		      dx, dz, nx, nz, nxpad, nzpad, vp0, vs0, epsi, del, theta);

	/******* output wavefields: component and divergence *******/
	if(it==ns-1)
	{
	    for(i=0;i<nx;i++)
	    {
		im=i+_m;
		for(j=0;j<nz;j++)
		{
		    jm=j+_m;
		    sf_floatwrite(&p3[im][jm],1,Fo1);
		    sf_floatwrite(&q3[im][jm],1,Fo2);

		    div=p3[im][jm]+q3[im][jm];

		    sf_floatwrite(&div,1,Fo3);
		}
	    }/* i loop*/

	    /* correct projection error for accurate separate qP wave in spatial domain */
	    if(isep==1)
	    {
		zero2float(p3c,nz,nx);
		zero2float(q3c,nz,nx);
		zero2float(sum, nz, nx);

		if(ihomo==1)
		    filter2dsepglobal(p3, q3, p3c, q3c, exx, ezz, nx, nz, hnkx1, hnkz1);
		else
		    filter2dsep(p3, q3, p3c, q3c, ex, ez, nx, nz, nstep, hnkx1, hnkz1);

		for(i=0;i<nx;i++)
		    for(j=0;j<nz;j++)
			sum[i][j]=p3c[i][j]+q3c[i][j];

		sf_floatwrite(sum[0],nx*nz, Fo8);
	    }
	}/* (it+1)%ntstep==0 */

	/**************************************/
	for(i=0,ii=_m;i<nx;i++,ii++)
	    for(j=0,jj=_m;j<nz;j++,jj++)
	    {
		p1[ii][jj]=p2[ii][jj];	
		p2[ii][jj]=p3[ii][jj];	

		q1[ii][jj]=q2[ii][jj];	
		q2[ii][jj]=q3[ii][jj];	
	    }

	if(it%50==0)
	    sf_warning("Pseudo: it= %d",it);
    }/* it loop */
    t5=clock();
    timespent=(float)(t5-t4)/CLOCKS_PER_SEC;
    sf_warning("Computation time (propagation + separation): %f (second)",timespent);

    if(isep==1)
    {
	free(*p3c);
	free(*q3c);
	free(*sum);

	if(ihomo==1)
	{
	    free(*exx);
	    free(*ezz);
	}else{
	    free(***ex);
	    free(***ez);
	}
    }

    free(*p1);
    free(*p2);
    free(*p3);
    free(*q1);
    free(*q2);
    free(*q3);

    free(*vp0);
    free(*vs0);
    free(*epsi);
    free(*del);
    free(*theta);

    exit(0);
}