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

📄 normray.c

📁 该程序主要用于三角网
💻 C
📖 第 1 页 / 共 4 页
字号:
						break;
					}
				}
			}

			if (infofp!=NULL)
				fprintf(infofp,"^^^\n"
					"Interaction with interface %d at "
					"(x=%g,z=%g).\n",
					temp,rslast->x,rslast->z);

			/* if ray at stopping edge, stop */
			if (stop) {
				if (infofp!=NULL)
					fprintf(infofp,"Hit stopping edge.  "
							"Ray stopped.\n");
				break;
			}

			/* else if ray at reflecting edge, reflect */
			else if (refl)
				rs = reflectRayFromEdge(rs,infofp);

			/* else trace ray across edge */
			else
				rs = traceRayAcrossEdge(rs,infofp);
			
		} while (rs!=NULL);
		
		/* reinitialize RayChecks for new ray */
		for (i=0; i<kk; ++i) {
			rc[i].hitseq = rc[i].hitseq-rc[i].nhits;
			rc[i].nhits = 0;
		}

		/* save ray end parameters */
		fa = rslast->f->fa;
		re[iangle].sigma = rslast->sigma;
		re[iangle].x = rslast->x;
		re[iangle].z = rslast->z;
		re[iangle].px = rslast->px;
		re[iangle].pz = rslast->pz;
		re[iangle].t = rslast->t;
		re[iangle].q1 = rslast->q1;
		re[iangle].p1 = rslast->p1;
		re[iangle].q2 = rslast->q2;
		re[iangle].p2 = rslast->p2;
		re[iangle].kmah = rslast->kmah;
		re[iangle].nref = rslast->nref;
		re[iangle].sb = sb;
		re[iangle].se = fa->s00+fa->dsdx*rslast->x+fa->dsdz*rslast->z;
		re[iangle].dsdxe = fa->dsdx;
		re[iangle].dsdze = fa->dsdz;
		re[iangle].ab = angle;
		re[iangle].kend = temp;
		re[iangle].ampli = rslast->ampli;
		re[iangle].ampliphase = rslast->ampliphase;
		re[iangle].atten = rslast->atten;
		re[iangle].dangle = dangle;

		/* optional output of rayend information */
		if (infofp!=NULL) {
			fprintf(infofp,
				"---------------------------------------"
				"------------\n\n"
				"The following information is stored at "
				"the rayend:\n\n");
			fprintf(infofp,
				"Ray stops at (%g,%g) at interface %d\n",
				re[iangle].x,re[iangle].z,re[iangle].kend);
			fprintf(infofp,
				"Takeoff angle=%g   Emergence angle=%g\n",
				re[iangle].ab*180./PI,-asin(re[iangle].px
				*1./sqrt(re[iangle].se))*180./PI);
			fprintf(infofp,"Takeoff velocity=%g   "
				"Emergence velocity=%g\n",
				1./sqrt(sb),1./sqrt(re[iangle].se));
			fprintf(infofp,"Slowness components px=%g   pz=%g\n",
				re[iangle].px,re[iangle].pz);
			fprintf(infofp,"Traveltime=%g   Sigma=%g\n",
				re[iangle].t,re[iangle].sigma);
			fprintf(infofp,"kmah index=%d   "
				"Number of reflections=%d\n",
				re[iangle].kmah,re[iangle].nref);
			fprintf(infofp,"Ray propagator q1=%g   q2=%g\n",
				re[iangle].q1,re[iangle].q2);
			fprintf(infofp,"Ray propagator p1=%g   p2=%g\n",
				re[iangle].p1,re[iangle].p2);
			fprintf(infofp,"Attenuation factor=%g   "
				"Angle increment=%g\n",
				re[iangle].atten,dangle*180./PI);
			fprintf(infofp,"Refl/Transm Amplitude=%g   Phase=%g\n",
				re[iangle].ampli,re[iangle].ampliphase); 
			fprintf(infofp,
				"---------------------------------------"
				"------------\n\n");
		}
	}
}

void writeRays (FILE *rayfp, int nxz, int nray, RayStep *rs[],
	RayEnd re[], int krecord, int prim, FILE *infofp)
/* for each ray, write x,z pairs */
{
	int iray,nrs,irs,nxzw,ns,is,icount;
	float sigmamax=0.0,sigma1,sigma2,x,z,px,pz,dsdx,dsdz,
		ds,xs,zs,dsigma;
	RayStep *rsi;
	FaceAttributes *fa;

	/* initialize counter */
	icount = 0;

	/* loop over rays */
	for (iray=0; iray<nray; ++iray) {

		if(caustic==0)
		   re[iray].kmah=1;

		if(nonsurface==1)
		   re[iray].z=0;

		if(re[iray].kmah!=0 && re[iray].z<0.000001){
		if (krecord==INT_MAX || (krecord==re[iray].kend
			&& (prim==INT_MAX || prim==re[iray].nref))) {

			/* count rays */
			++icount;
			++raycount;

			/* count ray steps while determining maximum sigma */
			for (nrs=0,rsi=rs[iray]; rsi!=NULL;
				++nrs,rsi=rsi->rsNext)
				sigmamax = rsi->sigma;

			/* initialize number of (x,z) written for this ray */
			nxzw = 0;

			/* loop over ray steps */
			for (irs=0,rsi=rs[iray]; irs<nrs;
				++irs,rsi=rsi->rsNext) {

				/* if sufficient number of (x,z) */
				/* have been written */
				if (nxzw>=nxz) break;

				/* ray parameters at this step */
				x = rsi->x;
				z = rsi->z;
				px = rsi->px;
				pz = rsi->pz;
				fa = rsi->f->fa;
				dsdx = fa->dsdx;
				dsdz = fa->dsdz;

				/* sigma at this step and next step */
				sigma1 = rsi->sigma;
				sigma2 = (irs<nrs-1)?rsi->rsNext->sigma:sigma1;

				/* number of sigma between this */
				/* step and next */
				ns = 1+(sigma2-sigma1)*(nxz-1)/(2.0*sigmamax);

				/* increment in sigma */
				ds = (sigma2-sigma1)/ns;

				/* loop over sigma */
				for (is=0,dsigma=0.0; is<ns; ++is,dsigma+=ds) {

					/* compute and write x and z */
					xs = x+dsigma*(px+dsigma*0.25*dsdx);
					zs = z+dsigma*(pz+dsigma*0.25*dsdz);
					if (efwrite(&zs,sizeof(float),1,rayfp)
						!=1)
						err("error writing rays!\n");
					if (efwrite(&xs,sizeof(float),1,rayfp)
						!=1)
						err("error writing rays!\n");


					/* if sufficient number written, */
					/* break */
					if (++nxzw>=nxz) break;
				}
			}

			/* if necessary, repeat last (x,z) */
			while (nxzw<nxz) {
				if (efwrite(&zs,sizeof(float),1,rayfp)!=1)
					err("error writing rays!\n");
				if (efwrite(&xs,sizeof(float),1,rayfp)!=1)
					err("error writing rays!\n");
				++nxzw;
			}

		} else {

			/* manipulate rayend information */
			re[iray].kend = -1;

		}

	    }

	} /* end loop over rays */

	if (infofp!=NULL)
		fprintf(infofp,"\nWrote %d rays to ray file.\n",icount);

	/* write number of rays to parameter file */
}

void writeWaves (FILE *wavefp, int nt, int nray, RayStep *rs[])
/* for each ray, write nt z(t),x(t) pairs uniformly sampled in time t */
{
	int iray,it;
	float tmax,dt,t1,t2,x1,z1,px1,pz1,sigma1,sigma2,s00,dsdx,dsdz,
		ax,bx,az,bz,at,bt,ct,ti,sigmah,sigmam,tm,
		dsigma,sigma,t,x,z,xstart,zstart;
	RayStep *rsi,*rs1,*rs2;
	FaceAttributes *fa;

	/* determine maximum time for all rays */
	for (iray=0,tmax=0.0; iray<nray; ++iray)
		for (rsi=rs[iray]; rsi!=NULL; rsi=rsi->rsNext)
			tmax = MAX(tmax,rsi->t);

	/* determine time sampling interval */
	dt = tmax/((nt>1)?nt-1:1);
	fprintf(stderr,"wavefront time increment = %g\n",dt);

	/* loop over rays */
	for (iray=0; iray<nray; ++iray) {

		/* initialize */
		rs1 = rs[iray];
		rs2 = rs1->rsNext;
		t1 = rs1->t;
		t2 = rs2->t;
		x1 = rs1->x;
		z1 = rs1->z;
		px1 = rs1->px;
		pz1 = rs1->pz;
		sigma1 = rs1->sigma;
		sigma2 = rs2->sigma;
		fa = rs1->f->fa;
		s00 = fa->s00;
		dsdx = fa->dsdx;
		dsdz = fa->dsdz;
		ax = px1;
		bx = 0.25*dsdx;
		az = pz1;
		bz = 0.25*dsdz;
		at = s00+dsdx*x1+dsdz*z1;
		bt = 0.5*(dsdx*px1+dsdz*pz1);
		ct = 0.0833333*(dsdx*dsdx+dsdz*dsdz);
		sigma = sigma1;
		t = t1;

		/* remember start x,z */
		xstart = x1;
		zstart = z1;

		/* loop over times */
		for (it=0,ti=0.0; it<nt; ++it,ti+=dt) {

			/* if necessary, go to next ray step */
			if (t2<ti) {
				do {
					rs1 = rs2;
					rs2 = rs1->rsNext;
					if (rs2==NULL) break;
				} while (rs2->t<ti);
				if (rs2==NULL) break;
				t1 = rs1->t;
				t2 = rs2->t;
				x1 = rs1->x;
				z1 = rs1->z;
				px1 = rs1->px;
				pz1 = rs1->pz;
				sigma1 = rs1->sigma;
				sigma2 = rs2->sigma;
				fa = rs1->f->fa;
				s00 = fa->s00;
				dsdx = fa->dsdx;
				dsdz = fa->dsdz;
				ax = px1;
				bx = 0.25*dsdx;
				az = pz1;
				bz = 0.25*dsdz;
				at = s00+dsdx*x1+dsdz*z1;
				bt = 0.5*(dsdx*px1+dsdz*pz1);
				ct = 0.0833333*(dsdx*dsdx+dsdz*dsdz);
				sigma = sigma1;
				t = t1;
			}

			/* determine dsigma for this time by bisection */
			sigmah = sigma2;
			while (t+0.01*dt<ti) {
				sigmam = 0.5*(sigma+sigmah);
				dsigma = sigmam-sigma1;
				tm = t1+dsigma*(at+dsigma*(bt+dsigma*ct));
				if (tm<ti) {
					t = tm;
					sigma = sigmam;
				} else {
					sigmah = sigmam;
				}
			}
			dsigma = sigma-sigma1;

			/* compute x and z */
			x = x1+dsigma*(ax+dsigma*bx);
			z = z1+dsigma*(az+dsigma*bz);

			/* write x and z */
			if (efwrite(&z,sizeof(float),1,wavefp)!=1)
				err("error writing waves!\n");
			if (efwrite(&x,sizeof(float),1,wavefp)!=1)
				err("error writing waves!\n");
		}

		/* finish writing x and z */
		while (it<nt) {
			if (efwrite(&zstart,sizeof(float),1,wavefp)!=1)
				err("error writing waves!\n");
			if (efwrite(&xstart,sizeof(float),1,wavefp)!=1)
				err("error writing waves!\n");
			++it;
		}
	}
}

static RayStep* traceRayInTri (RayStep *rs)
/* Trace ray in triangle.  Return pointer to new RayStep. */
{
	int kmah,nref;
	float x,z,px,pz,t,q1,p1,q2,p2,ddt,
		s00,dsdx,dsdz,xa,za,xb,zb,dx,dz,a,b,c,
		ds,q,sigma,dsigma,dsigma1,dsigma2,small,frac;
	float ampli,ampliphase,atten,qfac;
	EdgeUse *eu,*eut,*eusmall,*euzero=NULL;
	Face *f;
	FaceAttributes *fa;
	
	/* get input parameters */
	sigma =	rs->sigma;
	x = rs->x;
	z = rs->z;
	px = rs->px;
	pz = rs->pz;
	t = rs->t;
	q1 = rs->q1;
	p1 = rs->p1;
	q2 = rs->q2;
	p2 = rs->p2;
	kmah = rs->kmah;
	nref = rs->nref;
	eu = rs->eu;
	f = rs->f;
	ampli = rs->ampli;
	ampliphase = rs->ampliphase;
	atten = rs->atten;

	/* determine sloth function */
	fa = f->fa;
	s00 = fa->s00;
	dsdx = fa->dsdx;
	dsdz = fa->dsdz;

	/* determine Q-factor */
	qfac = fa->qfac;

	/* determine edge intersection with smallest positive dsigma */
	eusmall = NULL;
	small = FLT_MAX;
	eut = f->eu;
	do {
		/* edge endpoints */
		xa = eut->vu->v->y;  za = eut->vu->v->x;
		xb = eut->euCW->vu->v->y;  zb = eut->euCW->vu->v->x;

		/* coefficients b and c of equation to be solved for dsigma */
		dx = xb-xa;  dz = zb-za;
		b = dx*pz-dz*px;
		c = (eut==eu) ? 0.0 : dx*(z-za)-dz*(x-xa); 

		/* if sloth constant, solve linear equation */
		if (dsdx==0.0 && dsdz==0.0) {
			if (b!=0.0)
				dsigma1 = -c/b;
			else
				dsigma1 = FLT_MAX;
			dsigma2 = FLT_MAX;

		/* else, if sloth not constant, solve quadratic equation */
		} else {
			a = 0.25*(dx*dsdz-dz*dsdx);
			ds = b*b-4.0*a*c;
			if (ds<0.0) {
				dsigma1 = dsigma2 = FLT_MAX;
			} else {
				q = -0.5*((b<0.0)?b-sqrt(ds):b+sqrt(ds));
				if (a!=0.0)
					dsigma1 = q/a;
				else
					dsigma1 = FLT_MAX;
				if (q!=0.0)
					dsigma2 = c/q;
				else
					dsigma2 = FLT_MAX;
			}
		}
		
		/* remember edge with smallest positive dsigma */
		if (0.0<dsigma1 && dsigma1<small) {
			small = dsigma1;
			eusmall = eut;
		}
		if (0.0<dsigma2 && dsigma2<small) {
			small = dsigma2;
			eusmall = eut;
		}

		/* remember edge for which dsigma is zero */
		if (dsigma1==0.0) euzero = eut;
		if (dsigma2==0.0) euzero = eut;

		/* next edge use */

⌨️ 快捷键说明

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