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

📄 susynvxz.c

📁 su 的源代码库
💻 C
字号:
/* Copyright (c) Colorado School of Mines, 2006.*//* All rights reserved.                       *//* SUSYNVXZ: $Revision: 1.19 $ ; $Date: 2006/11/07 22:58:42 $	*/#include "su.h" #include "segy.h" /*********************** self documentation **********************/char *sdoc[] = {" 									"," SUSYNVXZ - SYNthetic seismograms of common offset V(X,Z) media via	"," 		Kirchhoff-style modeling				"," 									"," susynvxz >outfile [optional parameters]				"," 									"," Required Parameters:							"," <vfile		file containing velocities v[nx][nz]		"," nx=			number of x samples (2nd dimension)		"," nz=			number of z samples (1st dimension)		"," Optional Parameters:							"," nxb=nx		band centered at midpoint			"," nxd=1			skipped number of midponits			"," dx=100		x sampling interval (m)				"," fx=0.0		first x sample					"," dz=100		z sampling interval (m)				"," nt=101		number of time samples				"," dt=0.04		time sampling interval (sec)			"," ft=0.0		first time (sec)				"," nxo=1		 	number of offsets				"," dxo=50		offset sampling interval (m)			"," fxo=0.0		first offset (m)				"," nxm=101		number of midpoints				"," dxm=50		midpoint sampling interval (m)			"," fxm=0.0		first midpoint (m)				"," fpeak=0.2/dt		peak frequency of symmetric Ricker wavelet (Hz)	"," ref=\"1:1,2;4,2\"	reflector(s):  \"amplitude:x1,z1;x2,z2;x3,z3;...\""," smooth=0		=1 for smooth (piecewise cubic spline) reflectors"," ls=0			=1 for line source; default is point source	"," tmin=10.0*dt		minimum time of interest (sec)			"," ndpfz=5		number of diffractors per Fresnel zone		"," verbose=0		=1 to print some useful information		"," 									"," Notes:								"," This algorithm is based on formula (58) in Geo. Pros. 34, 686-703,	"," by N. Bleistein.							"," 									"," Offsets are signed - may be positive or negative.			", " Traveltime and amplitude are calculated by finite differences which	"," is done only in part of midpoints; in the skiped midpoint, interpolation"," is used to calculate traveltime and amplitude.			", "									"," More than one ref (reflector) may be specified.			"," Note that reflectors are encoded as quoted strings, with an optional	"," reflector amplitude: preceding the x,z coordinates of each reflector.	"," Default amplitude is 1.0 if amplitude: part of the string is omitted.	","									",NULL};/* *   CWP:  Zhenyue Liu, 07/20/92 *	Many subroutines borrowed from Dave Hale's program: SUSYNLV * * Trace header fields set: trid, counit, ns, dt, delrt, *				tracl. tracr, *				cdp, cdpt, d2, f2, offset, sx, gx *//**************** end self doc ***********************************//* these structures are defined in par.h -- this is documentation only * * typedef struct ReflectorSegmentStruct { *	float x;	( x coordinate of segment midpoint ) *	float z;	( z coordinate of segment midpoint ) *	float s;	( x component of unit-normal-vector ) *	float c;	( z component of unit-normal-vector ) * } ReflectorSegment; * typedef struct ReflectorStruct { *	int ns;			( number of reflector segments ) *	float ds;		( segment length ) *	float a;		( amplitude of reflector ) *	ReflectorSegment *rs;	( array[ns] of reflector segments ) * } Reflector; * typedef struct WaveletStruct { *	int lw;			( length of wavelet ) *	int iw;			( index of first wavelet sample ) *	float *wv;		( wavelet sample values ) * } Wavelet; * *//* parameters for half-derivative filter */#define LHD 20#define NHD 1+2*LHD/* prototypes */static void makeone (float **ts, float **as, float **sgs, float **tg, 	float **ag, float **sgg, float ex, float ez, float dx,  	float dz, float fx, float vs0, float vg0, int ls, Wavelet *w,	int nr, Reflector *r, int nt, float dt, float ft, float *trace);/* segy trace */segy tr;intmain (int argc, char **argv){	int 	nr,ir,ls,smooth,ndpfz,ns,ixo,ixm,nxo,nxm,nt,		nx,nz,nxb,nxd,ixd,i,ix,iz,nx1,nx0,nxd1,		verbose,tracl,		*nxz;	float   tmin,temp,temp1,		dsmax,fpeak,dx,dz,fx,ex,fx1,ex1,		dxm,dxo,dt,fxm,fxo,ft,xo,xm,vs0,vg0,		xs,xg,ez,		*ar,**xr,**zr,		**vold,**ts,**as,**sgs,**tg,**ag,**sgg,**bas,**bag,		**v,**ts1=NULL,**as1=NULL,**sgs1=NULL,		**tg1=NULL,**ag1=NULL,**sgg1=NULL;	FILE *vfp=stdin;	Reflector *r;	Wavelet *w;	/* hook up getpar to handle the parameters */	initargs(argc,argv);	requestdoc(0);	/* get required parameters */	if (!getparint("nx",&nx)) err("must specify nx!\n");	if (!getparint("nz",&nz)) err("must specify nz!\n");		/* get optional parameters */	if (!getparint("nxb",&nxb)) nxb = nx;	if (!getparint("nxd",&nxd)) nxd = 1;	if (!getparfloat("dx",&dx)) dx = 100;	if (!getparfloat("fx",&fx)) fx = 0.0;	if (!getparfloat("dz",&dz)) dz = 100;	if (!getparint("nt",&nt)) nt = 101; CHECK_NT("nt",nt);	if (!getparfloat("dt",&dt)) dt = 0.04;	if (!getparfloat("ft",&ft)) ft = 0.0;	if (!getparint("nxo",&nxo)) nxo = 1;	if (!getparfloat("dxo",&dxo)) dxo = 50;	if (!getparfloat("fxo",&fxo)) fxo = 0.0;	if (!getparint("nxm",&nxm)) nxm = 101;	if (!getparfloat("dxm",&dxm)) dxm = 50;	if (!getparfloat("fxm",&fxm)) fxm = 0.0;	if (!getparfloat("fpeak",&fpeak)) fpeak = 0.2/dt;	if (!getparint("ls",&ls)) ls = 0;	if (!getparfloat("tmin",&tmin)) tmin = 10.0*dt;	if (!getparint("ndpfz",&ndpfz)) ndpfz = 5;	if (!getparint("smooth",&smooth)) smooth = 0;	if (!getparint("verbose",&verbose)) verbose = 0;		/* check the ranges of shots and receivers */	ex = fx+(nx-1)*dx;	ez = (nz-1)*dz; 	for (ixm=0; ixm<nxm; ++ixm) 		for (ixo=0; ixo<nxo; ++ixo) {			/* compute source and receiver coordinates */			xs = fxm+ixm*dxm-0.5*(fxo+ixo*dxo);			xg = xs+fxo+ixo*dxo;			if (fx>xs || ex<xs || fx>xg || ex<xg) 		err("shot or receiver lie outside of specified (x,z) grid\n");	} 				decodeReflectors(&nr,&ar,&nxz,&xr,&zr);	if (!smooth) breakReflectors(&nr,&ar,&nxz,&xr,&zr);	/* allocate space */	vold = ealloc2float(nz,nx);	/* read velocities */	if(fread(vold[0],sizeof(float),nx*nz,vfp)!=nx*nz)		err("cannot read %d velocities from file %s",nx*nz,vfp);	/* determine maximum reflector segment length */	tmin = MAX(tmin,MAX(ft,dt));	dsmax = vold[0][0]/(2*ndpfz)*sqrt(tmin/fpeak); 		/* make reflectors */	makeref(dsmax,nr,ar,nxz,xr,zr,&r);	/* count reflector segments */	for (ir=0,ns=0; ir<nr; ++ir)		ns += r[ir].ns;	/* make wavelet */	makericker(fpeak,dt,&w);		/* if requested, print information */	if (verbose) {		warn("\nSUSYNVXZ:");		warn("Total number of small reflecting segments is %d.\n",ns);	}		/* set constant segy trace header parameters */	memset( (void *) &tr, 0, sizeof(segy));	tr.trid = 1;	tr.counit = 1;	tr.ns = nt;	tr.dt = 1.0e6*dt;	tr.delrt = 1.0e3*ft;		/* allocate space */	nx1 = 1+2*nxb;	ts = ealloc2float(nz,nx1);	as = ealloc2float(nz,nx1);	sgs = ealloc2float(nz,nx1);	tg = ealloc2float(nz,nx1);	ag = ealloc2float(nz,nx1);	sgg = ealloc2float(nz,nx1);	v = ealloc2float(nz,nx1);	bas = ealloc2float(nz,nx1);	bag = ealloc2float(nz,nx1);	if(nxd>1) {		/* allocate space for interpolation */		ts1 = ealloc2float(nz,nx1);		as1 = ealloc2float(nz,nx1);		sgs1 = ealloc2float(nz,nx1);		tg1 = ealloc2float(nz,nx1);		ag1 = ealloc2float(nz,nx1);		sgg1 = ealloc2float(nz,nx1);  	}			/* loop over offsets and midpoints */	for (ixo=0, tracl=0; ixo<nxo; ++ixo){	    xo = fxo+ixo*dxo;	    if(ABS(xo)>nxb*dx) err("\t band NXB is too small!\n");	    nxd1 = nxd;	    for (ixm=0; ixm<nxm; ixm +=nxd1){		xm = fxm+ixm*dxm;   		xs = xm-0.5*xo;		xg = xs+xo;		/* set range for traveltimes' calculation */		fx1 = xm-nxb*dx;		ex1 = MIN(ex+(nxd1-1)*dxm,xm+nxb*dx);		nx1 = 1+(ex1-fx1)/dx;			nx0 = (fx1-fx)/dx;		temp = (fx1-fx)/dx-nx0;		/* transpose velocity such that the first row is at fx1 */		for(ix=0;ix<nx1;++ix)		    for(iz=0;iz<nz;++iz){		    	if(ix<-nx0) 			   	v[ix][iz] = vold[0][iz];		    	else if(ix+nx0>nx-2) 				v[ix][iz]=vold[nx-1][iz];			else				v[ix][iz] = vold[ix+nx0][iz]*(1.0-temp)					+temp*vold[ix+nx0+1][iz];		    }					if(ixm==0 || nxd1==1){		/* No interpolation */				/* compute traveltimes, propagation angles, sigmas 	  		 from shot and receiver respectively	*/			eiktam(xs,0.,nz,dz,0.,nx1,dx,fx1,v,ts,as,sgs,bas);			eiktam(xg,0.,nz,dz,0.,nx1,dx,fx1,v,tg,ag,sgg,bag);			ixd = NINT((xs-fx)/dx);			vs0 = vold[ixd][0];			ixd = NINT((xg-fx)/dx);			vg0 = vold[ixd][0];							/* make one trace */			ex1 = MIN(ex,xm+nxb*dx);			makeone(ts,as,sgs,tg,ag,sgg,ex1,ez,dx,dz,fx1,vs0,vg0,				ls,w,nr,r,nt,dt,ft,tr.data);			/* set segy trace header parameters */			tr.tracl = tr.tracr = ++tracl;			tr.cdp = 1+ixm;			tr.cdpt = 1+ixo;			tr.offset = NINT(xo);			tr.sx = NINT(xs);			tr.gx = NINT(xg);			/* write trace */			puttr(&tr);		}		else {			/* Linear interpolation */						eiktam(xs,0,nz,dz,0,nx1,dx,fx1,v,ts1,as1,sgs1,bas);			eiktam(xg,0,nz,dz,0,nx1,dx,fx1,v,tg1,ag1,sgg1,bag);			ixd = NINT((xs-fx)/dx);			vs0 = vold[ixd][0];			ixd = NINT((xg-fx)/dx);			vg0 = vold[ixd][0];					    	xm -= nxd1*dxm;		    for(i=1; i<=nxd1; ++i) {		    	xm += dxm;			xs = xm-0.5*xo;			xg = xs+xo;			fx1 = xm-nxb*dx;				ex1 = MIN(ex+(nxd1-1)*dxm,xm+nxb*dx);			nx1 = 1+(ex1-fx1)/dx;				temp = nxd1-i;			temp1 = 1.0/(nxd1-i+1);			for(ix=0;ix<nx1;++ix)			    for(iz=0;iz<nz;++iz){			    if(i==nxd1){			   	ts[ix][iz] = ts1[ix][iz];			   	tg[ix][iz] = tg1[ix][iz];			   	sgs[ix][iz] = sgs1[ix][iz];			   	ag[ix][iz] = ag1[ix][iz];			   	sgg[ix][iz] = sgg1[ix][iz];			   	as[ix][iz] = as1[ix][iz];				}			    else{			   	ts[ix][iz] = (temp*ts[ix][iz]					+ts1[ix][iz])*temp1;			   	tg[ix][iz] = (temp*tg[ix][iz]					+tg1[ix][iz])*temp1;			    	as[ix][iz] = (temp*as[ix][iz]					+as1[ix][iz])*temp1;			   	sgs[ix][iz] = (temp*sgs[ix][iz]					+sgs1[ix][iz])*temp1;			   	ag[ix][iz] = (temp*ag[ix][iz]					+ag1[ix][iz])*temp1;			   	sgg[ix][iz] = (temp*sgg[ix][iz]					+sgg1[ix][iz])*temp1;				}			}							/* make one trace */			ex1 = MIN(ex,xm+nxb*dx);			makeone(ts,as,sgs,tg,ag,sgg,ex1,ez,dx,dz,fx1,vs0,vg0,				ls,w,nr,r,nt,dt,ft,tr.data);			/* set segy trace header parameters */			tr.tracl = tr.tracr = ++tracl;			tr.cdp = 1+ixm-nxd1+i;			tr.cdpt = 1+ixo;			tr.offset = NINT(xo);			tr.d2=dxm;			tr.f2=fxm;			tr.sx = NINT(xs);			tr.gx = NINT(xg);			/* write trace */			puttr(&tr);		    }		}		    /* set skip parameter */		    if(ixm<nxm-1 && ixm>nxm-1-nxd1) nxd1 = nxm-1-ixm;	    }	    warn("\t finish offset %f\n",xo);	}	free2float(vold);	free2float(ts);	free2float(bas);	free2float(sgs);	free2float(as);	free2float(v);	free2float(tg);	free2float(bag);	free2float(sgg);	free2float(ag);	if(nxd>1) {		free2float(ts1);		free2float(as1);		free2float(sgs1);		free2float(tg1);		free2float(ag1);		free2float(sgg1);  	}	return(CWP_Exit());}static void makeone (float **ts, float **as, float **sgs, 	float **tg, float **ag, float **sgg, float ex, float ez, float dx, 	float dz, float fx, float vs0, float vg0, int ls, Wavelet *w,	int nr, Reflector *r, int nt, float dt, float ft, float *trace)/*****************************************************************************Make one synthetic seismogram ******************************************************************************Input:**v		array[nx][nz] containing velocities nz		number of z samplesdz		z sampling intervalnx		number of x samplesdx		x sampling intervalfx		first x samplels		=1 for line source amplitudes; =0 for point sourcew		wavelet to convolve with tracexs		x coordinate of sourcexg		x coordinate of receiver groupnr		number of reflectorsr		array[nr] of reflectorsnt		number of time samplesdt		time sampling intervalft		first time sampleOutput:trace		array[nt] containing synthetic seismogram*****************************************************************************/{	int it,ir,is,ns,ix,iz;	float ar,ds,xd,zd,cd,sd,xi,zi,ci,cr,time,amp,sx,sz,		tsd,asd,sgsd,tgd,agd,sggd,		*temp;	ReflectorSegment *rs;	int lhd=LHD,nhd=NHD;	static float hd[NHD];	static int madehd=0;	/* if half-derivative filter not yet made, make it */	if (!madehd) {		mkhdiff(dt,lhd,hd);		madehd = 1;	} 	/* zero trace */	for (it=0; it<nt; ++it)		trace[it] = 0.0;		/* loop over reflectors */	for (ir=0; ir<nr; ++ir) {		/* amplitude, number of segments, segment length */		ar = r[ir].a;		ns = r[ir].ns;		ds = r[ir].ds;		rs = r[ir].rs;			/* loop over diffracting segments */		for (is=0; is<ns; ++is) {					/* diffractor midpoint, unit-normal, and length */			xd = rs[is].x;			zd = rs[is].z;			cd = rs[is].c;			sd = rs[is].s;						/* check range of reflector */			if(xd<fx || xd>=ex || zd>=ez)				continue;			/* determine sample indices */			xi = (xd-fx)/dx;			ix = xi;			zi = zd/dz;			iz = zi;			/* bilinear interpolation */			sx = xi-ix;			sz = zi-iz;			tsd = (1.0-sz)*((1.0-sx)*ts[ix][iz] + 						sx*ts[ix+1][iz]) +					sz*((1.0-sx)*ts[ix][iz+1] +						sx*ts[ix+1][iz+1]);			asd = (1.0-sz)*((1.0-sx)*as[ix][iz] + 						sx*as[ix+1][iz]) +					sz*((1.0-sx)*as[ix][iz+1] +						sx*as[ix+1][iz+1]);			sgsd = (1.0-sz)*((1.0-sx)*sgs[ix][iz] + 						sx*sgs[ix+1][iz]) +					sz*((1.0-sx)*sgs[ix][iz+1] +						sx*sgs[ix+1][iz+1]);			tgd = (1.0-sz)*((1.0-sx)*tg[ix][iz] + 						sx*tg[ix+1][iz]) +					sz*((1.0-sx)*tg[ix][iz+1] +						sx*tg[ix+1][iz+1]);			agd = (1.0-sz)*((1.0-sx)*ag[ix][iz] + 						sx*ag[ix+1][iz]) +					sz*((1.0-sx)*ag[ix][iz+1] +						sx*ag[ix+1][iz+1]);			sggd = (1.0-sz)*((1.0-sx)*sgg[ix][iz] + 						sx*sgg[ix+1][iz]) +					sz*((1.0-sx)*sgg[ix][iz+1] +						sx*sgg[ix+1][iz+1]);						/* cosines of incidence and reflection angles */			ci = cd*cos(asd)+sd*sin(asd);			cr = cd*cos(agd)+sd*sin(agd);			/* two-way time and amplitude */			time = tsd+tgd;			if (ls)			     amp = sqrt(vs0*vg0/(sgsd*sggd));			else			     amp = sqrt(vs0*vg0/(sgsd*sggd*(sgsd+sggd)));					   			amp *= ABS(ci+cr)*ar*ds;					/* add sinc wavelet to trace */			addsinc(time,amp,nt,dt,ft,trace);		}	}		/* allocate workspace */	temp = ealloc1float(nt);		/* apply half-derivative filter to trace */	conv(nhd,-lhd,hd,nt,0,trace,nt,0,temp);	/* convolve wavelet with trace */	conv(w->lw,w->iw,w->wv,nt,0,temp,nt,0,trace);		/* free workspace */	free1float(temp);}

⌨️ 快捷键说明

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