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

📄 rayt2d.c

📁 su 的源代码库
💻 C
📖 第 1 页 / 共 3 页
字号:
*****************************************************************************Author: Zhenyue Liu, CSM 1995.****************************************************************************/ {	int na=raytr.na,nt=raytr.nt,nxo=geo2dt.nx,nzo=geo2dt.nz,		nx=geo2dv.nx,nz=geo2dv.nz;	float fxo=geo2dt.fx,fzo=geo2dt.fz,dxo=geo2dt.dx,dzo=geo2dt.dz,		odxo=geo2dt.odx,odzo=geo2dt.odz;	float fac=raytr.fac,dt=raytr.dt,fa=raytr.fa,da=raytr.da,xs=raytr.xs;	float *vxx,*vxz,*vzz,*s,zs=raytr.zs;	int nrs;	Ray *ray;  	int i,ia,ixo,izo;	float a,xo,zo,exo,ezo;/*	variables used for extrapolation	*/	int it,jt,nxf,nxe,nzf,nze;	float tc,xoc,zoc,xc,zc,r1,v0=0.0,norm2,terr,vd1,cuv,      		sd,sind,cosd,vd,pxd,pzd,r2,t1,t2,r1x,r2x,t1x,t2x,t2xz,      		p2d,q2d,gradv[2],d2t[3],dtvd,odt=1.0/dt,xcosd=0.0,*tvd;	vxx = alloc1float(nx*nz);	vxz = alloc1float(nx*nz);	vzz = alloc1float(nx*nz);	tvd = alloc1float(nt);	s = alloc1float(nxo*nzo);	ray = (Ray*)alloc1(nt,sizeof(Ray)); 	/* compute second derivatives of velocity	*/ 	dv2(geo2dv,v,vxx,vxz,vzz); /*	maximum range of output points	*/	exo = fxo+(nxo-1)*dxo;	ezo = fzo+(nzo-1)*dzo;/*	initialize traveltime and raypath length	*/	for(ixo=0; ixo<nxo; ++ixo) 		for(izo=0; izo<nzo; ++izo){			i = izo+ixo*nzo;			t[i] = INITIAL_T;			s[i] = INITIAL_T;		     if(npv) tv[i] = cs[i] = 0.0;	}/* 	loop over shooting angles at source point 	*/	for(ia=0,a=fa; ia<na; ++ia,a+=da){  	/*		trace rays	*/		makeRay(geo2dv,v,vxx,vxz,vzz,raytr,a,&nrs,ray,npv,pv);/*		extropolate to grids near central rays	*/		    v0 = ray[0].v;		    r2 = 0.0;		    xc = raytr.xs;		    zc = raytr.zs;		    sd = 0;		    vd1 = v0;		    if(npv) {		      dtvd = 0.0;		      for(it=1; it<nrs; ++it) {			dtvd += 0.5*dt*(ray[it].dtv+ray[it-1].dtv);			tvd[it] = ray[it].v*dtvd;		      }		    }		    for (it=1; it<nrs; ++it) {			xo = ray[it].x;			zo = ray[it].z;			vd = ray[it].v;			sd = sd+0.5*dt*(vd+vd1);			vd1 = vd;/*		    	if the point is within the previous circle	*/			if(r2 > (xc-xo)*(xc-xo)+(zc-zo)*(zc-zo)      			  && it != nrs-1) continue;/*		    	if the point is out of output range	*/			if(xo<fxo || xo>exo || zo<fzo || zo>ezo) continue;											xc = xo;			zc = zo;			q2d = ray[it].q2; /*			if caustics	*/			if(q2d == 0.0) {				r2 = 0.0;				continue;			}			vd = ray[it].v;			pxd = ray[it].px;			pzd = ray[it].pz;			p2d = ray[it].p2;			sind = vd*pxd;			cosd = vd*pzd;			gradv[0] = ray[it].dvdx;			gradv[1] = ray[it].dvdz;/*			calculate second derivatives of traveltime*/			ddt(p2d,q2d,cosd,sind,gradv,vd,d2t,&cuv);/*			determine radius for extrapolation	*/			tc = it*dt;			terr = tc*fac;			norm2 = sqrt(d2t[0]*d2t[0]+d2t[2]*d2t[2]+      				2.0*d2t[1]*d2t[1]);			r2 = terr/norm2;			r1 = sqrt(r2);/*			keep ray-centered coordinate system regular */			if(r1*cuv > 0.1) r1 = 0.1/cuv;/*			radius cannot be too large	*/			if(r1 > 0.1*sd) r1 = 0.1*sd;			r2 = r1*r1;			nxf = (xc-r1-fxo)*odxo+0.9;			if(nxf < 0) nxf = 0;			nxe = (xc+r1-fxo)*odxo+0.1;			if(nxe >= nxo) nxe = nxo-1;/*       	fprintf(stderr,"x,z,t,r=%g %g %g %g\n",			xc,zc,tc,r1);*/	 			for(ixo=nxf; ixo<=nxe; ++ixo){				xoc = fxo-xc+ixo*dxo;				r2x = r2-xoc*xoc;				if(r2x < 0) continue;				r1x = sqrt(r2x);				t1x = tc+xoc*pxd;				t2x = tc*xoc*xoc*d2t[0];				t2xz = 2.0*xoc*d2t[1];				if(npv) xcosd = pzd+xoc*d2t[1];				nzf = (zc-r1x-fzo)*odzo+0.9;				if(nzf < 0) nzf = 0;				nze = (zc+r1x-fzo)*odzo+0.1;				if(nze>=nzo) nze = nzo-1;				i = ixo*nzo;				for(izo=nzf; izo<=nze; ++izo){ /*				    if ray path is shorter	*/				    if(sd < s[i+izo] ) {					zoc = fzo-zc+izo*dzo;					t1 = t1x+zoc*pzd;					t2 = t2x+zoc*(zoc*d2t[2]+t2xz);					s[i+izo] = sd;					t[i+izo] = t1*t1+tc*t2;				      if(npv) {					jt = (t1+0.5*t2)*odt+0.5;					if(jt<0) jt = 0;					if(jt>nrs-1) jt = nrs-1;					tv[i+izo] = tvd[jt];					cs[i+izo] = xcosd+d2t[2]*zoc;				      }				    } 				} 			} 		}	}/*	square root of traveltimes */	for (ixo=0; ixo<nxo; ++ixo){ 		i = ixo*nzo;		for (izo=0; izo<nzo; ++izo){  			t[i+izo] = MAX(0.0,t[i+izo]);			if(t[i+izo] < 999) t[i+izo] = sqrt(t[i+izo]);  			if(npv) cs[i+izo] *= vo[i+izo];		}	}/*	compute traveltime near source	*/	nxf = (xs-fxo)/dxo-1.5;	if(nxf<0) nxf = 0;	nxe = (xs-fxo)/dxo+2.5;	if(nxe>nxo-1) nxe = nxo-1;	nzf = (zs-fzo)/dzo-0.5;	if(nzf<0) nzf = 0;	nze = (zs-fzo)/dzo+1.5;	if(nze>=nzo) nze = nzo-1;	for (ixo=nxf; ixo<=nxe; ++ixo){		xo = fxo+ixo*dxo;		i = ixo*nzo;		for (izo=nzf; izo<=nze; ++izo){			zo = fzo+izo*dzo;			if(t[i+izo] > 999) 			  t[i+izo] = sqrt((xo-xs)*(xo-xs)+(zo-zs)*(zo-zs))/v0; 		}	}	free1float(vxx);	free1float(vxz);	free1float(vzz);	free1float(s);	free1((void*)ray);}void ddt(float p,float q,float c,float s, float *dv,float v,float *d2t,	float *cuv)/************************************************************************ddt - calculate second derivatives of traveltime with respect to x,y************************************************************************/{ 	float ov2,m11,m12,m22;	ov2 = 1.0/(v*v);	m11 = p/q;/*	calculate 2nd column of m	*/	m12 = -(dv[0]*c-dv[1]*s)*ov2;	m22 = -(dv[0]*s+dv[1]*c)*ov2;/*	compute h*m*h^T	*/	d2t[0] = m11*c*c+2.0*m12*c*s+m22*s*s;	d2t[1] = (m22-m11)*c*s+m12*(c*c-s*s);	d2t[2] = m11*s*s-2.0*m12*c*s+m22*c*c;/*	compute the curvature of raypath	*/	*cuv = fabs(m12)*v;}void trans(int nx,int nz,int nxt,int nx0,float *v,float *vt) {	int ix,iz,i,i0;	for(ix=0*nx; ix<nxt; ++ix){		i = ix*nz;		i0 = (ix+nx0)*nz;		for(iz=0; iz<nz; ++iz)			vt[i+iz] = v[i0+iz];	}}void voint(Geo2d geo2dv,float *v,Geo2d geo2dt,float *ov2,int npv,float *vo){	int nx=geo2dv.nx,nz=geo2dv.nz,nxo=geo2dt.nx,nzo=geo2dt.nz;	int i,io,jx,jz,ixo,izo;	float fx=geo2dv.fx,fz=geo2dv.fz,odx=geo2dv.odx,odz=geo2dv.odz;	float fxo=geo2dt.fx,fzo=geo2dt.fz,dxo=geo2dt.dx,dzo=geo2dt.dz;	float x,z,ax,az,sx,sz,temp;	for(ixo=0,x=fxo; ixo<nxo; ++ixo,x+=dxo){		ax = (x-fx)*odx;		jx = ax;		sx = ax-jx;		if(jx < 0) jx = 0;		if(jx > nx-2) jx = nx-2;		for(izo=0,z=fzo; izo<nzo; ++izo,z+=dzo){			az = (z-fz)*odz;			jz = az;			sz = az-jz;			if(jz < 0) jz = 0;			if(jz > nz-2) jz = nz-2;			io = ixo*nzo+izo;			i = jx*nz+jz;		    	temp = (1.0-sx)*((1.0-sz)*v[i]+sz*v[i+1])      			    	+sx*((1.0-sz)*v[i+nz]+sz*v[i+nz+1]);			if(npv) vo[io] = temp;			ov2[io] = 1.0/(temp*temp);		}	}} void dv2(Geo2d geo2dv,float *v,float *vxx,float *vxz,float *vzz) /*calculate second DeriVatives from a 2D VELocity grid by finite difference*//*  	input: 	velocity v   	output: vxx,vxz and vzz  */	 {   	int  nx=geo2dv.nx, nz=geo2dv.nz, ix, iz, i; 	  	float   odx=geo2dv.odx,odz=geo2dv.odz,odxx,odzz,odxz;    		odxx = odx*odx; 	odzz = odz*odz; 	odxz = 0.25*odx*odz; /*	initialize	*/	for(ix=0; ix<nx; ++ix)     	    for(iz=0; iz<nz; ++iz){ 		i = ix*nz+iz;		vxx[i] = 0.; 		vxz[i] = 0.; 		vzz[i] = 0.; 	}	/*	finite difference 	*/	for(ix=1; ix<nx-1; ++ix)     	    for(iz=1; iz<nz-1; ++iz){ 		i = ix*nz+iz; 		vxx[i] = odxx*(v[i+nz]-2.0*v[i]+v[i-nz]);  		vxz[i] = odxz*(v[i+nz+1]-v[i+nz-1]-v[i-nz+1]+v[i-nz-1]);       		vzz[i] = odzz*(v[i+1]-2.0*v[i]+v[i-1]);	}}void eiknl(Geo2d geo2dt,float *t,float *ov2,float tmax) /* 	compute traveltime in shadow zones by eikonal equation  input   t 		traveltimes form ray tracing   ov2 		slowness squares   tmax	 	upper limit of ordinary traveltime value  output:   t	traveltime (unchanged if t<=tmax)*/{	int nx=geo2dt.nx,nz=geo2dt.nz,ix,iz;	float dx=geo2dt.dx,dz=geo2dt.dz;	float tx2,tz2,t0,tl,tr,temp,odx2,*tt1,*tt2;	tt1 = alloc1float(nx);	tt2 = alloc1float(nx);	odx2 = 1.0/(dx*dx);	for(ix=0; ix<nx; ++ix)		tt1[ix] = t[ix*nz];	for(iz=1; iz<nz; ++iz){ 	    for(ix=0; ix<nx; ++ix) 		tt2[ix] = t[ix*nz+iz];	    for(ix=1; ix<nx; ++ix){/*	if traveltime is abnormal and the upper is normal	*/		t0 = tt1[ix];		if(tt2[ix] > tmax && t0 <= tmax) {			tl = tr = 0.0; 			if(ix > 0) tl = tt1[ix-1];			if(ix < nx-1) tr = tt1[ix+1];                        tx2 = (tl-t0)*(tl-t0);                        temp = (tr-t0)*(tr-t0);                        if(tx2>temp) tx2 = temp;                        temp = 0.25*(tl-tr)*(tl-tr);                        if(tx2>temp) tx2 = temp;                        tx2 *= odx2;			tz2 = 0.5*(ov2[ix*nz+iz-1]+ov2[ix*nz+iz])-tx2;			if(tz2 >= 0) tt2[ix] = t0+dz*sqrt(tz2);		}	    }	    for(ix=0; ix<nx; ++ix){		t[ix*nz+iz] = tt2[ix];		tt1[ix] = tt2[ix];	    }	}	free1float(tt1);	free1float(tt2);}void vel2Interp(Geo2d geo2dv,float *v,float *vxx,float *vxz,float *vzz,     float x,float z,     float *u,float *ux,float *uz,float *uxx,float *uxz,float *uzz) /*************************************************************************vel2Interp - Function to support interpolation of velocity and its		derivatives	 *************************************************************************Input:x,z		2D coordinate at which to interpolate v		velocity array(nz,nx) on unoform grids vxx,vxz,vzz	second derivaitve arrays(nz,nx) on uniform grids Output:  u 	v(x,z)ux  	dv/dxuz  	dv/dzuxx	ddv/dxdxuxz 	ddv/dzdxuzz	ddv/dzdz*************************************************************************Author: Zhenyue Liu, CSM 1995*************************************************************************/{	int k0,k1,k2,k3,jx,jz,nx=geo2dv.nx,nz=geo2dv.nz;	float fx=geo2dv.fx,dx=geo2dv.dx,odx=geo2dv.odx;	float fz=geo2dv.fz,dz=geo2dv.dz,odz=geo2dv.odz;	float ax,az,sx,sz,sxx,szz,a0,a1,a2,a3;	float g0,g1,g2,g3,gx0,gx1,gx2,gx3,gz0,gz1,gz2,gz3;/*	determine interpolate coefficients	*/	    ax = (x-fx)*odx;	    jx = ax;	    if(jx<0) jx = 0;	    if(jx>nx-2) jx = nx-2;	    sx = ax-jx;	    az = (z-fz)*odz;	    jz = az;	    if(jz<0) jz = 0;	    if(jz>nz-2) jz = nz-2;	    sz = az-jz;	    sxx = 0.5*sx*(1.0-sx)*dx*dx;	    szz = 0.5*sz*(1.0-sz)*dz*dz;	    a0 = (1.0-sx)*(1.0-sz);	    a1 = (1.0-sx)*sz;	    a2 = sx*(1.0-sz);	    a3 = sx*sz;/*	    set the table of indices for interpolation	*/	    k0 = nz*jx+jz;	    k1 = k0+1; 	    k2 = k0+nz;	    k3 = k2+1;	    g0 = v[k0];	    g1 = v[k1];	    g2 = v[k2];	    g3 = v[k3];	    gx0 = vxx[k0];	    gx1 = vxx[k1];	    gx2 = vxx[k2];	    gx3 = vxx[k3];	    gz0 = vzz[k0];	    gz1 = vzz[k1];	    gz2 = vzz[k2];	    gz3 = vzz[k3];/*	interpolation	*/	    *uxx = a0*gx0+a1*gx1+a2*gx2+a3*gx3;	    *uxz = a0*vxz[k0]+a1*vxz[k1]+a2*vxz[k2]+a3*vxz[k3];	    *uzz = a0*gz0+a1*gz1+a2*gz2+a3*gz3;	    *u = a0*g0+a1*g1+a2*g2+a3*g3-(sxx*(*uxx)+szz*(*uzz));	    *ux = ((1.0-sz)*(g2-g0-sxx*(gx2-gx0)-szz*(gz2-gz0))      		    +sz*(g3-g1-sxx*(gx3-gx1)-szz*(gz3-gz1)))*odx      		    +(sx-0.5)*dx*(*uxx);	    *uz = ((1.0-sx)*(g1-g0-sxx*(gx1-gx0)-szz*(gz1-gz0))      		    +sx*(g3-g2-sxx*(gx3-gx2)-szz*(gz3-gz2)))*odz      		    +(sz-0.5)*dz*(*uzz);}void vintp(Geo2d geo2dv,float *v,float x,float z,float *u) /************************************************************************* Function to support interpolation of a single fuction *************************************************************************Input:x,z		2D coordinate at which to interpolatev		array(nz,nx) on unoform grids Output: u		v(x,z)*************************************************************************Author: Zhenyue Liu, CSM 1995*************************************************************************/{	int k0,k1,k2,k3,jx,jz,nx=geo2dv.nx,nz=geo2dv.nz;	float fx=geo2dv.fx,odx=geo2dv.odx;	float fz=geo2dv.fz,odz=geo2dv.odz;	float ax,az,sx,sz;/*	determine interpolate coefficients	*/	    ax = (x-fx)*odx;	    jx = ax;	    if(jx<0) jx = 0;	    if(jx>nx-2) jx = nx-2;	    sx = ax-jx;	    az = (z-fz)*odz;	    jz = az;	    if(jz<0) jz = 0;	    if(jz>nz-2) jz = nz-2;	    sz = az-jz;/*	    set the table of indices for interpolation	*/	    k0 = nz*jx+jz;	    k1 = k0+1; 	    k2 = k0+nz;	    k3 = k2+1;/*	interpolation	*/	    *u = (1.0-sx)*((1.0-sz)*v[k0]+sz*v[k1])      			+sx*((1.0-sz)*v[k2]+sz*v[k3]);}

⌨️ 快捷键说明

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