📄 gbbeam.c
字号:
"Ray %d is out of the aperature\n",ire); continue; } /* ray end parameters */ sigma = 1/sqrt(re[ire].sigma); x = re[ire].x; z = re[ire].z; t = re[ire].t; pz = re[ire].pz; q1 = re[ire].q1; p1 = re[ire].p1; q2 = re[ire].q2; p2 = re[ire].p2; kmah = re[ire].kmah; atten = re[ire].atten; ampli = re[ire].ampli; ampliphase = re[ire].ampliphase; dangle = re[ire].dangle; dsdx = re[ire].dsdxe; dsdz = re[ire].dsdze; v0 = 1.0/sqrt(re[ire].sb); a0 = re[ire].ab; /* compute ray dependant constants */ v2 = v*v; v4 = v2*v2; dvds = -0.5*v4*(dsdx*px+dsdz*pz); dvdn = -0.5*v4*(dsdx*pz-dsdz*px); /* useful ray dependant information */ if (infofp!=NULL) { fprintf(infofp, "\n***Ray emerges at (x=%g,z=%g) " "on interface %d.\n",x,z,kend); fprintf(infofp," Emergence angle=%g time=%g\n", asin(v*px)*180.0/PI,t); fprintf(infofp," v=%g dsdx=%g dsdz=%g\n", v,dsdx,dsdz); fprintf(infofp," dvds=%g dvdn=%g\n",dvds,dvdn); fprintf(infofp," ampli=%g ampliphase=%g\n", ampli,ampliphase); } if (dangle==0.0) dangle = 1.0; scale = sigma*dangle*sqrt(v/(v0*2*PI)); /* angularly dependent amplitude */ intlin(nang,ang,amp,amp[0],amp[nang-1],1,&a0,&a); /* complex beam epsilon */ if (bw!=0.0) { eps1 = 0.0; eps2 = -0.5*wpeak*bw*bw; } else { temp = c * ABS(p2/q2) + eps; eps1 = -q2/q1 * (p2*p1/(q2*q1) + temp*temp); eps1 = eps1/(p1*p1/(q1*q1) + temp*temp); eps2 = -temp/(p1*p1+q1*q1*temp*temp); } ceps = cmplx(eps1,eps2); /* complex p, q, and p/q */ cp = crmul(ceps,p1); cp.r += p2; cq = crmul(ceps,q1); cq.r += q2; cpoq = cdiv(cp,cq); cpoqr = cpoq.r; cpoqi = cpoq.i; /* if cpoqi negative, skip ray */ /* (cpoqi<0 leads to exponential growth!) */ if (cpoqi<0.0) { if (infofp!=NULL) fprintf(infofp,"cpoqi negative, skipping ray!"); continue; } /* complex q, adjusted for reflections */ cqr = (nref%2) ? cneg(cq) : cq; /* frequency-independent amplitude factor */ phase = -PI*((kmah+1)/2); camp = csqrt(cdiv(ceps,cqr)); if (infofp!=NULL) { temp = sqrt(2*((eps1*q1+q2)*(eps1*q1+q2) + eps2*eps2*q1*q1)/(-wpeak*eps2)); fprintf(infofp," Gaussian beam information:\n"); fprintf(infofp," Re(M)=%g \t Im(M)=%g\n", cpoqr,cpoqi); fprintf(infofp," const beam phase=%g degrees\n", 180.0/PI*atan(camp.i/(camp.r+eps))); fprintf(infofp," epsilon1=%g \t epsilon2=%g\n", eps1,eps2); fprintf(infofp," ray-end beam width=%g\n",temp); } /* complex reflection/transmission coefficient */ if (reftrans) { phase += ampliphase; camp = crmul(camp,ampli); } /* phase correction for 2.5-D spreading */ phase += PI/4.0; camp = crmul(camp,scale*ampa); camp = cmul(camp,cmplx(cos(phase),sin(phase))); campr = camp.r; campi = camp.i; /* precompute causal attenuation */ if (natten==2) { for (iw=0; iw<nw; ++iw) attenvec[iw] = atten*lnvec[iw]; } /* loop over receiver locations */ for (ig=0; ig<ng; ++ig) { /* delta x and delta z */ dx = xg[ig]-x; dz = zg[ig]-z; disq = dx*dx+dz*dz; /* delta t and delta s */ n = v*(pz*dx-px*dz); nn = n*n; /* do not extrapolate too far */ if (lscale!=FLT_MAX && disq>sqlscale) continue; /* count beams that influence this receiver */ ++count[ig]; dels = v*(px*dx+pz*dz)*(1.0-dvdn/v*n); delt = dels/v-0.5*dvds*dels*dels/v2; /* adjusted time */ ta = t+delt+0.5*cpoqr*nn-ft; /* uncomment for extrapolation information *//* if (infofp!=NULL) fprintf(infofp, " n=%g ds=%g dt=%g tt=%g\n", n,dels,delt,ta);*/ /* skip if outside time window */ if (ta<0.0 || ta>(nt-1)*dt) continue; /* compute cos and sin increments */ cosd = cos(dw*ta); sind = sin(dw*ta); /* compute exp increment */ if (natten==0) /* no attenuation */ expd = exp(-0.5*dw*cpoqi*nn); else /* include attenuation term */ expd = exp(-0.5*dw*(cpoqi*nn+atten)); /* initialize cos, sin, and exp */ cosw = 1.0; sinw = 0.0; expw = 1.0; /* if no attenuation or noncausal attenuation */ if (natten==0 || natten==1) { /* loop over frequencies */ for (iw=0; iw<nw; ++iw) { /* accumulate beam */ csyn[ig][iw].r += expw *(campr*cosw-campi*sinw); csyn[ig][iw].i += expw *(campr*sinw+campi*cosw); /* update cos, sin, and exp */ tempd = cosw*cosd-sinw*sind; sinw = cosw*sind+sinw*cosd; cosw = tempd; expw *= expd; /* if amplitude too small, break */ if (expw<0.01) break; } /* else, causal attenuation */ } else { /* loop over frequencies */ for (iw=0,w=0.0; iw<nw; ++iw,w+=dw) { /* compute cos and sin */ tempd = w*(ta-attenvec[iw]); cosw = cos(tempd); sinw = sin(tempd); /* accumulate beam */ csyn[ig][iw].r += expw *(campr*cosw-campi*sinw); csyn[ig][iw].i += expw *(campr*sinw+campi*cosw); /* update exp */ expw *= expd; /* if amplitude too small, break */ if (expw<0.01) break; } } } } /* make complex ricker wavelet */ for (iw=0,w=0.0; iw<nw; ++iw,w+=dw) { cwave[iw] = cricker(w,wpeak,delay); cwave[iw] = crmul(cwave[iw],sqrt(w)); } /* apply wavelet to synthetics and inverse Fourier transform */ for (ig=0; ig<ng; ++ig) { for (iw=0; iw<nw; ++iw) csyn[ig][iw] = cmul(csyn[ig][iw],cwave[iw]); pfacr(-1,ntfft,csyn[ig],syn); if (efwrite(syn,sizeof(float),nt,stdout)!=nt) err("error writing output traces!\n"); } /* receiver contibution check */ if (infofp!=NULL) { fprintf(infofp,"\nBeam contribution to each receiver " "*************************\n"); fprintf(infofp,"Receiver No\t x_coord. \t z_coord. \t " "No. of beams\n"); for (ig=0; ig<ng; ++ig) fprintf(infofp,"%d \t\t %g \t\t %g \t\t %d\n", ig,xg[ig],zg[ig],count[ig]); } /* free workspace */ free1float(syn); free1float(lnvec); free1float(attenvec); free1complex(cwave); free2complex(csyn);}static complex cricker (float w, float wpeak, float delay)/*****************************************************************************Compute Fourier transform of Ricker wavelet - complex function of frequency******************************************************************************Input:w frequency at which to evaluate transformwpeak peak (dominant) frequency in radiansdelay time shift (used for an approximately causal wavelet)******************************************************************************Notes:The amplitude of the Ricker wavelet at a frequency of 2.5*wpeak is approximately 4 percent of that at the dominant frequency wpeak.The Ricker wavelet effectively begins at time t = -2*PI/wpeak. Therefore,for practical purposes, a causal wavelet may be obtained by a time delayof 2*PI/wpeak.The Ricker wavelet has the shape of the second derivative of a Gaussian.******************************************************************************Author: Dave Hale, Colorado School of Mines, 02/28/91******************************************************************************/{ return crmul(cexp(cmplx(-pow(w/wpeak,2.0),delay*w)), 4.0*w*w*sqrt(PI)/pow(wpeak,3.0));}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -