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

📄 sufdmod2_pml.c

📁 su 的源代码库
💻 C
📖 第 1 页 / 共 4 页
字号:
		}	}        if (pml_thick != 0)		pml_init (nx, nz, dx, dz, dt, dvv, od, verbose);	/* loop  ver time steps */	for (it=0,t=0.0; it<nt; ++it,t+=dt) {			/* if verbose, print time step */		if (verbose>1) warn("it=%d  t=%g",it,t);			/* update source function */		if (ns==1)			ptsrc(xs[0],zs[0],nx,dx,fx,nz,dz,fz,dt,t,			      fmax,fpeak,tdelay,s);		else			exsrc(ns,xs,zs,nx,dx,fx,nz,dz,fz,dt,t,fmax,s);				/* do one time step */		tstep2(nx,dx,nz,dz,dt,dvv,od,s,pm,p,pp,abs);				/* write waves */		if (it%mt==0) {			/* set selected trace header fields for all traces */			cubetr.sx = xs[0];			cubetr.sdepth = zs[0];			cubetr.trid = 30 ;			cubetr.ns = nz ;			cubetr.d1 = dz ;			cubetr.d2 = dx ;			/* account for delay in source starting time */			cubetr.delrt = - 1000.0 * tdelay;			tracl = 0 ;			/* set selected trace header fields trace by trace */			for (ix=0 ; ix < nx ; ++ix) {				++tracl;				++tracr;				cubetr.offset = ix * dx - xs[0];				cubetr.tracl = (int) tracl;				cubetr.tracr = (int) tracr;				for (iz=0 ; iz < nz ; ++iz) {						cubetr.data[iz] = pp[ix][iz];				}				/* output traces of data cube */				fputtr(stdout, &cubetr);			}		}		/* if requested, save horizontal line of seismograms */		if (hs!=NULL) {			for (ix=0; ix<nx; ++ix)				hs[ix][it] = pp[ix][hs1];		}		/* if requested, save vertical line of seismograms */		if (vs!=NULL) {			for (iz=0; iz<nz; ++iz)				vs[iz][it] = pp[vs2][iz];		}		/* if requested, save seismograms at source locations */		if (ss!=NULL) {			for (is=0; is<ns; ++is)				ss[is][it] = pp[ixs[is]][izs[is]];		}		/* roll time slice pointers */		ptemp = pm;		pm = p;		p = pp;		pp = ptemp;	}	/* if requested, write horizontal line of seismograms */	if (hs!=NULL) {		horiztr.sx = xs[0];		horiztr.sdepth = zs[0];		horiztr.trid = 1;		horiztr.ns = nt ;		horiztr.dt = 1000000 * dt ;		horiztr.d2 = dx ;		/* account for delay in source starting time */		horiztr.delrt = -1000.0 * tdelay ; 		tracl = tracr = 0;		for (ix=0 ; ix < nx ; ++ix){			++tracl;			++tracr;			/* offset from first source location */			horiztr.offset = ix * dx - xs[0];			horiztr.tracl = (int) tracl;			horiztr.tracr = (int) tracr;			for (it = 0 ; it < nt ; ++it){				horiztr.data[it] = hs[ix][it];			}						fputtr(hseisfp , &horiztr);		}					fclose(hseisfp);	}	/* if requested, write vertical line of seismograms */	if (vs!=NULL) {		verttr.trid = 1;		verttr.ns = nt ;		verttr.sx = xs[0];		verttr.sdepth = zs[0];		verttr.dt = 1000000 * dt ;		verttr.d2 = dx ;		/* account for delay source starting time */		verttr.delrt = -1000.0 * tdelay ;		tracl = tracr = 0;		for (iz=0 ; iz < nz ; ++iz){			++tracl;			++tracr;			/* vertical line implies offset in z */			verttr.offset = iz * dz - zs[0];			verttr.tracl = (int) tracl;			verttr.tracr = (int) tracr;			for (it = 0 ; it < nt ; ++it){				verttr.data[it] = vs[iz][it];			}						fputtr(vseisfp , &verttr);		}		fclose(vseisfp);	}	/* if requested, write seismogram at source position */	if (ss!=NULL) {		srctr.trid = 1;		srctr.ns = nt ;		srctr.dt = 1000000 * dt ;		srctr.d2 = dx ;		srctr.delrt = -1000.0 * tdelay ;		tracl = tracr = 0;		for (is=0 ; is < ns ; ++is){			++tracl;			++tracr;			srctr.sx = xs[is];			srctr.sdepth = zs[is];			srctr.tracl = (int) tracl;			srctr.tracr = (int) tracr;			for (it = 0 ; it < nt ; ++it){				srctr.data[it] = ss[is][it];			}						fputtr(sseisfp , &srctr);		}		fclose(sseisfp);	}		/* free space before returning */	free2float(s);	free2float(dvv);	free2float(pm);	free2float(p);	free2float(pp);		if (od!=NULL) free2float(od);	if (hs!=NULL) free2float(hs);	if (vs!=NULL) free2float(vs);	if (ss!=NULL) free2float(ss);		return(CWP_Exit());}void exsrc (int ns, float *xs, float *zs,	int nx, float dx, float fx,	int nz, float dz, float fz,	float dt, float t, float fmax, float **s)/*****************************************************************************exsrc - update source pressure function for an extended source******************************************************************************Input:ns		number of x,z coordinates for extended sourcexs		array[ns] of x coordinates of extended sourcezs		array[ns] of z coordinates of extended sourcenx		number of x samplesdx		x sampling intervalfx		first x samplenz		number of z samplesdz		z sampling intervalfz		first z sampledt		time step (ignored)t		time at which to compute source functionfmax		maximum frequencyOutput:s		array[nx][nz] of source pressure at time t+dt******************************************************************************Author:  Dave Hale, Colorado School of Mines, 03/01/90******************************************************************************/{	int ix,iz,ixv,izv,is;	float sigma,tbias,ascale,tscale,ts,xn,zn,		v,xv,zv,dxdv,dzdv,xvn,zvn,amp,dv,dist,distprev;	static float *vs,(*xsd)[4],(*zsd)[4];	static int made=0;		/* if not already made, make spline coefficients */	if (!made) {		vs = alloc1float(ns);		xsd = (float(*)[4])alloc1float(ns*4);		zsd = (float(*)[4])alloc1float(ns*4);		for (is=0; is<ns; ++is)			vs[is] = is;		cmonot(ns,vs,xs,xsd);		cmonot(ns,vs,zs,zsd);		made = 1;	}		/* zero source array */	for (ix=0; ix<nx; ++ix)		for (iz=0; iz<nz; ++iz)			s[ix][iz] = 0.0 *dt ;		/* compute time-dependent part of source function */	sigma = 0.25/fmax;	tbias = 3.0*sigma;	ascale = -exp(0.5)/sigma;	tscale = 0.5/(sigma*sigma);	if (t>2.0*tbias) return;	ts = ascale*(t-tbias)*exp(-tscale*(t-tbias)*(t-tbias));		/* loop over extended source locations */	for (v=vs[0],distprev=0.0,dv=1.0; dv!=0.0; distprev=dist,v+=dv) {				/* determine x(v), z(v), dx/dv, and dz/dv along source */		intcub(0,ns,vs,xsd,1,&v,&xv);		intcub(0,ns,vs,zsd,1,&v,&zv);		intcub(1,ns,vs,xsd,1,&v,&dxdv);		intcub(1,ns,vs,zsd,1,&v,&dzdv);				/* determine increment along extended source */		if (dxdv==0.0)			dv = dz/ABS(dzdv);		else if (dzdv==0.0)			dv = dx/ABS(dxdv);		else			dv = MIN(dz/ABS(dzdv),dx/ABS(dxdv));		if (v+dv>vs[ns-1]) dv = vs[ns-1]-v;		dist = dv*sqrt(dzdv*dzdv+dxdv*dxdv)/sqrt(dx*dx+dz*dz);				/* determine source amplitude */		amp = (dist+distprev)/2.0;				/* let source contribute within limited distance */		xvn = (xv-fx)/dx;		zvn = (zv-fz)/dz;		ixv = NINT(xvn); 		izv = NINT(zvn);		for (ix=MAX(0,ixv-3); ix<=MIN(nx-1,ixv+3); ++ix) {			for (iz=MAX(0,izv-3); iz<=MIN(nz-1,izv+3); ++iz) {				xn = ix-xvn;				zn = iz-zvn;				s[ix][iz] += ts*amp*exp(-xn*xn-zn*zn);			}		}	}}/* prototype of subroutine used internally */static float ricker (float t, float fpeak);void ptsrc (float xs, float zs,	int nx, float dx, float fx,	int nz, float dz, float fz,	float dt, float t, float fmax, float fpeak, float tdelay, float **s)/*****************************************************************************ptsrc - update source pressure function for a point source******************************************************************************Input:xs		x coordinate of point sourcezs		z coordinate of point sourcenx		number of x samplesdx		x sampling intervalfx		first x samplenz		number of z samplesdz		z sampling intervalfz		first z sampledt		time step (ignored)t		time at which to compute source functionfmax		maximum frequency (ignored)fpeak		peak frequencyOutput:tdelay		time delay of beginning of source functions		array[nx][nz] of source pressure at time t+dt******************************************************************************Author:  Dave Hale, Colorado School of Mines, 03/01/90******************************************************************************/{	int ix,iz,ixs,izs;	float ts,xn,zn,xsn,zsn;		/* zero source array */	for (ix=0; ix<nx; ++ix)		for (iz=0; iz<nz; ++iz)			s[ix][iz] = 0.0 * dt*fmax;		/* compute time-dependent part of source function */	/* fpeak = 0.5*fmax;  this is now getparred */	tdelay = 1.0/fpeak;	if (t>2.0*tdelay) return;	ts = ricker(t-tdelay,fpeak);		/* let source contribute within limited distance */	xsn = (xs-fx)/dx;	zsn = (zs-fz)/dz;	ixs = NINT(xsn);	izs = NINT(zsn);	for (ix=MAX(0,ixs-3); ix<=MIN(nx-1,ixs+3); ++ix) {		for (iz=MAX(0,izs-3); iz<=MIN(nz-1,izs+3); ++iz) {			xn = ix-xsn;			zn = iz-zsn;			s[ix][iz] = ts*exp(-xn*xn-zn*zn);		}	}}static float ricker (float t, float fpeak)/*****************************************************************************ricker - Compute Ricker wavelet as a function of time******************************************************************************Input:t		time at which to evaluate Ricker waveletfpeak		peak (dominant) frequency of wavelet******************************************************************************Notes:The amplitude of the Ricker wavelet at a frequency of 2.5*fpeak is approximately 4 percent of that at the dominant frequency fpeak.The Ricker wavelet effectively begins at time t = -1.0/fpeak.  Therefore,for practical purposes, a causal wavelet may be obtained by a time delayof 1.0/fpeak.The Ricker wavelet has the shape of the second derivative of a Gaussian.******************************************************************************Author:  Dave Hale, Colorado School of Mines, 04/29/90******************************************************************************/{	float x,xx;		x = PI*fpeak*t;	xx = x*x;	/* return (-6.0+24.0*xx-8.0*xx*xx)*exp(-xx); */	/* return PI*fpeak*(4.0*xx*x-6.0*x)*exp(-xx); */	return exp(-xx)*(1.0-2.0*xx);}/* 2D finite differencing subroutine *//* functions declared and used internally */static void star1 (int nx, float dx, int nz, float dz, float dt,	float **dvv, float **od, float **s,	float **pm, float **p, float **pp);static void star2 (int nx, float dx, int nz, float dz, float dt,	float **dvv, float **od, float **s,	float **pm, float **p, float **pp);static void star3 (int nx, float dx, int nz, float dz, float dt,	float **dvv, float **od, float **s,	float **pm, float **p, float **pp);static void star4 (int nx, float dx, int nz, float dz, float dt,	float **dvv, float **od, float **s,	float **pm, float **p, float **pp);static void absorb (int nx, float dx, int nz, float dz, float dt,	float **dvv, float **od, float **pm, float **p, float **pp,	int *abs);void tstep2 (int nx, float dx, int nz, float dz, float dt,	float **dvv, float **od, float **s,	float **pm, float **p, float **pp, int *abs)/*****************************************************************************One time step of FD solution (2nd order in space) to acoustic wave equation******************************************************************************Input:nx		number of x samplesdx		x sampling intervalnz		number of z samplesdz		z sampling intervaldt		time stepdvv		array[nx][nz] of density*velocity^2od		array[nx][nz] of 1/density (NULL for constant density=1.0)s		array[nx][nz] of source pressure at time t+dtpm		array[nx][nz] of pressure at time t-dtp		array[nx][nz] of pressure at time tOutput:pp		array[nx][nz] of pressure at time t+dt******************************************************************************Notes:This function is optimized for special cases of constant density=1 and/orequal spatial sampling intervals dx=dz.  The slowest case is variabledensity and dx!=dz.  The fastest case is density=1.0 (od==NULL) and dx==dz.******************************************************************************Author:  Dave Hale, Colorado School of Mines, 03/13/90******************************************************************************/{	/* convolve with finite-difference star (special cases for speed) */	if (od!=NULL && dx!=dz) {		star1(nx,dx,nz,dz,dt,dvv,od,s,pm,p,pp);	} else if (od!=NULL && dx==dz) {		star2(nx,dx,nz,dz,dt,dvv,od,s,pm,p,pp);	} else if (od==NULL && dx!=dz) {		star3(nx,dx,nz,dz,dt,dvv,od,s,pm,p,pp);	} else {		star4(nx,dx,nz,dz,dt,dvv,od,s,pm,p,pp);	}		/* absorb along boundaries */        if (pml_thick == 0) {	   absorb(nx,dx,nz,dz,dt,dvv,od,pm,p,pp,abs);        } else {           pml_absorb(nx,dx,nz,dz,dt,dvv,od,pm,p,pp,abs);	}}/* convolve with finite-difference star for variable density and dx!=dz */static void star1 (int nx, float dx, int nz, float dz, float dt,	float **dvv, float **od, float **s,	float **pm, float **p, float **pp){

⌨️ 快捷键说明

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