📄 sumiggbzo.c
字号:
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 + -