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

📄 sumiggbzo.c

📁 su 的源代码库
💻 C
📖 第 1 页 / 共 4 页
字号:
		zt = z+hhalf*dz;		at = a+hhalf*da;		p1t = p1+hhalf*dp1;		q1t = q1+hhalf*dq1;		p2t = p2+hhalf*dp2;		q2t = q2+hhalf*dq2;		c = cos(at);		s = sin(at);		cc = c*c;		ss = s*s;		vel2Interp(vel2,xt,zt,			&v,&dvdx,&dvdz,&ddvdxdx,&ddvdxdz,&ddvdzdz);		ddvdndn = ddvdxdx*cc-2.0*ddvdxdz*s*c+ddvdzdz*ss;		vv = v*v;				/* step 2 of 4th-order Runge-Kutta */		dxt =  v*s;		dzt =  v*c;		dat =  dvdz*s-dvdx*c;		dp1t = -ddvdndn*q1t/v;		dq1t = vv*p1t;		dp2t = -ddvdndn*q2t/v;		dq2t =  vv*p2t;		xt = x+hhalf*dxt;		zt = z+hhalf*dzt;		at = a+hhalf*dat;		p1t = p1+hhalf*dp1t;		q1t = q1+hhalf*dq1t;		p2t = p2+hhalf*dp2t;		q2t = q2+hhalf*dq2t;		c = cos(at);		s = sin(at);		cc = c*c;		ss = s*s;		vel2Interp(vel2,xt,zt,			&v,&dvdx,&dvdz,&ddvdxdx,&ddvdxdz,&ddvdzdz);		ddvdndn = ddvdxdx*cc-2.0*ddvdxdz*s*c+ddvdzdz*ss;		vv = v*v;				/* step 3 of 4th-order Runge-Kutta */		dxm =  v*s;		dzm =  v*c;		dam =  dvdz*s-dvdx*c;		dp1m = -ddvdndn*q1t/v;		dq1m = vv*p1t;		dp2m = -ddvdndn*q2t/v;		dq2m =  vv*p2t;		xt = x+h*dxm;		zt = z+h*dzm;		at = a+h*dam;		p1t = p1+h*dp1m;		q1t = q1+h*dq1m;		p2t = p2+h*dp2m;		q2t = q2+h*dq2m;		dxm += dxt;		dzm += dzt;		dam += dat;		dp1m += dp1t;		dq1m += dq1t;		dp2m += dp2t;		dq2m += dq2t;		c = cos(at);		s = sin(at);		cc = c*c;		ss = s*s;		vel2Interp(vel2,xt,zt,			&v,&dvdx,&dvdz,&ddvdxdx,&ddvdxdz,&ddvdzdz);		ddvdndn = ddvdxdx*cc-2.0*ddvdxdz*s*c+ddvdzdz*ss;		vv = v*v;				/* step 4 of 4th-order Runge-Kutta */		dxt =  v*s;		dzt =  v*c;		dat =  dvdz*s-dvdx*c;		dp1t = -ddvdndn*q1t/v;		dq1t = vv*p1t;		dp2t = -ddvdndn*q2t/v;		dq2t =  vv*p2t;		x += hsixth*(dx+dxt+2.0*dxm);		z += hsixth*(dz+dzt+2.0*dzm);		a += hsixth*(da+dat+2.0*dam);		p1 += hsixth*(dp1+dp1t+2.0*dp1m);		q1 += hsixth*(dq1+dq1t+2.0*dq1m);		p2 += hsixth*(dp2+dp2t+2.0*dp2m);		q2 += hsixth*(dq2+dq2t+2.0*dq2m);		c = cos(a);		s = sin(a);		cc = c*c;		ss = s*s;		vel2Interp(vel2,x,z,			&v,&dvdx,&dvdz,&ddvdxdx,&ddvdxdz,&ddvdzdz);		ddvdndn = ddvdxdx*cc-2.0*ddvdxdz*s*c+ddvdzdz*ss;		vv = v*v;		/* update kmah index */		if ((q2<=0.0 && q2old>0.0) || (q2>=0.0 && q2old<0.0)) kmah++;				/* update time */		t += dt;		/* save ray parameters */		rs[it].t = t;		rs[it].a = a;		rs[it].x = x;		rs[it].z = z;		rs[it].c = c;		rs[it].s = s;		rs[it].q1 = q1;		rs[it].p1 = p1;		rs[it].q2 = q2;		rs[it].p2 = p2;		rs[it].kmah = kmah;		rs[it].v = v;		rs[it].dvdx = dvdx;		rs[it].dvdz = dvdz;	}	/* free velocity interpolator */	vel2Free(vel2);	/* return ray */	ray->nrs = it;	ray->rs = rs;	ray->nc = 0;	ray->c = NULL;	return ray;}void freeRay (Ray *ray)/*****************************************************************************Free a ray.******************************************************************************Input:ray		ray to be freed*****************************************************************************/{	if (ray->c!=NULL) free1((void*)ray->c);	free1((void*)ray->rs);	free1((void*)ray);}int nearestRayStep (Ray *ray, float x, float z)/*****************************************************************************Determine index of ray step nearest to point (x,z).******************************************************************************Input:ray		rayx		x coordinatez		z coordinateReturned:	index of nearest ray step*****************************************************************************/{	int nrs=ray->nrs,ic=ray->ic,nc=ray->nc;	RayStep *rs=ray->rs;	Circle *c=ray->c;	int irs,irsf,irsl,irsmin=0,update,jc,js,kc;	float dsmin,ds,dx,dz,dmin,rdmin,xrs,zrs;	/* if necessary, make circles localizing ray steps */	if (c==NULL) {		ray->ic = ic = 0;		ray->nc = nc = sqrt((float)nrs);		ray->c = c = makeCircles(nc,nrs,rs);	}		/* initialize minimum distance and minimum distance-squared */	dx = x-c[ic].x;	dz = z-c[ic].z;	dmin = 2.0*(sqrt(dx*dx+dz*dz)+c[ic].r);	dsmin = dmin*dmin;	/* loop over all circles */	for (kc=0,jc=ic,js=0; kc<nc; ++kc) {				/* distance-squared to center of circle */		dx = x-c[jc].x;		dz = z-c[jc].z;		ds = dx*dx+dz*dz;		/* radius of circle plus minimum distance (so far) */		rdmin = c[jc].r+dmin;		/* if circle could possible contain a nearer ray step */		if (ds<=rdmin*rdmin) {			/* search circle for nearest ray step */ 			irsf = c[jc].irsf;			irsl = c[jc].irsl;			update = 0;			for (irs=irsf; irs<=irsl; ++irs) {				xrs = rs[irs].x;				zrs = rs[irs].z;				dx = x-xrs;				dz = z-zrs;				ds = dx*dx+dz*dz;				if (ds<dsmin) {					dsmin = ds;					irsmin = irs;					update = 1;				}			}			/* if a nearer ray step was found inside circle */			if (update) {				/* update minimum distance */				dmin = sqrt(dsmin);				/* remember the circle */				ic = jc;			}		}				/* search circles in alternating directions */		js = (js>0)?-js-1:-js+1;		jc += js;		if (jc<0 || jc>=nc) {			js = (js>0)?-js-1:-js+1;			jc += js;		}	}	/* remember the circle containing the nearest ray step */	ray->ic = ic;	if (irsmin<0 || irsmin>=nrs)		warn("irsmin=%d",irsmin);	/* return index of nearest ray step */	return irsmin;}int xxx_nearestRayStep (Ray *ray, float x, float z)/*****************************************************************************Determine index of ray step nearest to point (x,z).  Simple (slow) version.******************************************************************************Input:ray		rayx		x coordinatez		z coordinateReturned:	index of nearest ray step*****************************************************************************/{	int nrs=ray->nrs;	RayStep *rs=ray->rs;	int irs,irsmin=0;	float dsmin,ds,dx,dz,xrs,zrs;	for (irs=0,dsmin=FLT_MAX; irs<nrs; ++irs) {		xrs = rs[irs].x;		zrs = rs[irs].z;		dx = x-xrs;		dz = z-zrs;		ds = dx*dx+dz*dz;		if (ds<dsmin) {			dsmin = ds;			irsmin = irs;		}	}	return irsmin;}Circle *makeCircles (int nc, int nrs, RayStep *rs)/*****************************************************************************Make circles used to speed up determination of nearest ray step.******************************************************************************Input:nc		number of circles to makenrs		number of ray stepsrs		array[nrs] of ray stepsReturned:	array[nc] of circles*****************************************************************************/{	int nrsc,ic,irsf,irsl,irs;	float xmin,xmax,zmin,zmax,x,z,r;	Circle *c;	/* allocate space for circles */	c = (Circle*)alloc1(nc,sizeof(Circle));	/* determine typical number of ray steps per circle */	nrsc = 1+(nrs-1)/nc;	/* loop over circles */	for (ic=0; ic<nc; ++ic) {				/* index of first and last raystep */		irsf = ic*nrsc;		irsl = irsf+nrsc-1;		if (irsf>=nrs) irsf = nrs-1;		if (irsl>=nrs) irsl = nrs-1;		/* coordinate bounds of ray steps */		xmin = xmax = rs[irsf].x;		zmin = zmax = rs[irsf].z;		for (irs=irsf+1; irs<=irsl; ++irs) {			if (rs[irs].x<xmin) xmin = rs[irs].x;			if (rs[irs].x>xmax) xmax = rs[irs].x;			if (rs[irs].z<zmin) zmin = rs[irs].z;			if (rs[irs].z>zmax) zmax = rs[irs].z;		}		/* center and radius of circle */		x = 0.5*(xmin+xmax);		z = 0.5*(zmin+zmax);		r = sqrt((x-xmin)*(x-xmin)+(z-zmin)*(z-zmin));		/* set circle */		c[ic].irsf = irsf;		c[ic].irsl = irsl;		c[ic].x = x;		c[ic].z = z;		c[ic].r = r;	}	return c;}/*****************************************************************************Functions to support interpolation of velocity and its derivatives.******************************************************************************Functions:vel2Alloc	allocate and initialize an interpolator for v(x,z)vel2Interp	interpolate v(x,z) and its derivatives******************************************************************************Notes:Interpolation is performed by piecewise cubic Hermite polynomials,so that velocity and first derivatives are continuous.  Therefore,velocity v, first derivatives dv/dx and dv/dz, and the mixedderivative ddv/dxdz are continuous.  However, second derivativesddv/dxdx and ddv/dzdz are discontinuous.*****************************************************************************//* number of pre-computed, tabulated interpolators */#define NTABLE 101/* length of each interpolator in table (4 for piecewise cubic) */#define LTABLE 4/* table of pre-computed interpolators, for 0th, 1st, and 2nd derivatives */static float tbl[3][NTABLE][LTABLE];/* constants */static int ix=1-LTABLE/2-LTABLE,iz=1-LTABLE/2-LTABLE;static float ltable=LTABLE,ntblm1=NTABLE-1;/* indices for 0th, 1st, and 2nd derivatives */static int kx[6]={0,1,0,2,1,0};static int kz[6]={0,0,1,0,1,2};/* function to build interpolator tables; sets tabled=1 when built */static void buildTables (void);static int tabled=0;/* interpolator for velocity function v(x,z) of two variables */typedef struct Vel2Struct {	int nx;		/* number of x samples */	int nz;		/* number of z samples */	int nxm;	/* number of x samples minus LTABLE */	int nzm;	/* number of x samples minus LTABLE */	float xs,xb,zs,zb,sx[3],sz[3],**vu;} Vel2;void* vel2Alloc (int nx, float dx, float fx,	int nz, float dz, float fz, float **v)/*****************************************************************************Allocate and initialize an interpolator for v(x,z) and its derivatives.******************************************************************************Input:nx		number of x samplesdx		x sampling intervalfx		first x samplenz		number of z samplesdz		z sampling intervalfz		first z samplev		array[nx][nz] of uniformly sampled v(x,z)Returned:	pointer to interpolator*****************************************************************************/{	Vel2 *vel2;	/* allocate space */	vel2 = (Vel2*)alloc1(1,sizeof(Vel2));	/* set state variables used for interpolation */	vel2->nx = nx;	vel2->nxm = nx-LTABLE;	vel2->xs = 1.0/dx;	vel2->xb = ltable-fx*vel2->xs;	vel2->sx[0] = 1.0;	vel2->sx[1] = vel2->xs;	vel2->sx[2] = vel2->xs*vel2->xs;	vel2->nz = nz;	vel2->nzm = nz-LTABLE;	vel2->zs = 1.0/dz;	vel2->zb = ltable-fz*vel2->zs;	vel2->sz[0] = 1.0;	vel2->sz[1] = vel2->zs;	vel2->sz[2] = vel2->zs*vel2->zs;	vel2->vu = v;		/* if necessary, build interpolator coefficient tables */	if (!tabled) buildTables();	return vel2;}void vel2Free (void *vel2)/*****************************************************************************Free an interpolator for v(x,z) and its derivatives.******************************************************************************Input:vel2		pointer to interpolator as returned by vel2Alloc()*****************************************************************************/{	free1(vel2);}void vel2Interp (void *vel2, float x, float z,	float *v, float *vx, float *vz, float *vxx, float *vxz, float *vzz)/*****************************************************************************Interpolation of a velocity function v(x,z) and its derivatives.******************************************************************************Input:vel2		pointer to interpolator as returned by vel2Alloc()x		x coordinate at which to interpolate v(x,z) and derivativesz		z coordinate at which to interpolate v(x,z) and derivativesOutput:v		v(x,z)vx		dv/dxvz		dv/dzvxx		ddv/dxdxvxz		ddv/dxdzvzz		ddv/dzdz*****************************************************************************/{	Vel2 *v2=vel2;	int nx=v2->nx,nz=v2->nz,nxm=v2->nxm,nzm=v2->nzm;	float xs=v2->xs,xb=v2->xb,zs=v2->zs,zb=v2->zb,		*sx=v2->sx,*sz=v2->sz,**vu=v2->vu;	int i,jx,lx,mx,jz,lz,mz,jmx,jmz,mmx,mmz;	float ax,bx,*px,az,bz,*pz,sum,vd[6];	/* determine offsets into vu and interpolation coefficients */	ax = xb+x*xs;	jx = (int)ax;	bx = ax-jx;	lx = (bx>=0.0)?bx*ntblm1+0.5:(bx+1.0)*ntblm1-0.5;	lx *= LTABLE;	mx = ix+jx;	az = zb+z*zs;	jz = (int)az;	bz = az-jz;	lz = (bz>=0.0)?bz*ntblm1+0.5:(bz+1.0)*ntblm1-0.5;	lz *= LTABLE;	mz = iz+jz;		/* if totally within input array, use fast method */	if (mx>=0 && mx<=nxm && mz>=0 && mz<=nzm) {		for (i=0; i<6; ++i) {			px = &(tbl[kx[i]][0][0])+lx;			pz = &(tbl[kz[i]][0][0])+lz;			vd[i] = sx[kx[i]]*sz[kz[i]]*(				vu[mx][mz]*px[0]*pz[0]+				vu[mx][mz+1]*px[0]*pz[1]+				vu[mx][mz+2]*px[0]*pz[2]+				vu[mx][mz+3]*px[0]*pz[3]+				vu[mx+1][mz]*px[1]*pz[0]+				vu[mx+1][mz+1]*px[1]*pz[1]+				vu[mx+1][mz+2]*px[1]*pz[2]+				vu[mx+1][mz+3]*px[1]*pz[3]+				vu[mx+2][mz]*px[2]*pz[0]+				vu[mx+2][mz+1]*px[2]*pz[1]+				vu[mx+2][mz+2]*px[2]*pz[2]+				vu[mx+2][mz+3]*px[2]*pz[3]+				vu[mx+3][mz]*px[3]*pz[0]+

⌨️ 快捷键说明

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