void homogeneousg(float *HomG, complex *cshot, complex *Refl, int nx, int nt, int nxs, int nts, float dt, float *xsyn, int Nsyn, float *xrcv, float *xsrc, float fxs2, float fxs, float dxs, float dxsrc, float dx, int ixa, int ixb, int ntfft, int nw, int nw_low, int nw_high, int mode, int reci, int nshots, int *ixpossyn, int npossyn, float *pmin, float *f1min, float *f1plus, float *f2p, float *G_d, int *muteW, int smooth, int shift, int above, int pad, int nt0, int *synpos, int verbose) { int i, j, l, ret; int iter, niter, ix, nfreq; float *iRN, *rtrace; complex *Fop, *ctrace, *chom; double t0, t2, tfft; tfft = 0.0; ret = 0; t0 = wallclock_time(); nfreq = ntfft/2+1; #pragma omp parallel default(shared) \ private(i,j,ctrace,chom,rtrace) { ctrace = (complex *)calloc(nfreq,sizeof(complex)); chom = (complex *)calloc(nfreq,sizeof(complex)); rtrace = (float *)calloc(ntfft,sizeof(float)); #pragma omp for for (l = 0; l < Nsyn; l++) { if (verbose > 2) vmess("Creating Homogeneous G at location %d out of %d",l+1,Nsyn); /* Construct the image */ for (i = 0; i < nxs; i++) { rc1fft(&f2p[l*nxs*ntfft+i*ntfft],ctrace,nt,-1); for (j = 0; j < nfreq; j++) { chom[j].r += 2*(ctrace[j].r*cshot[i*nfreq+j].r - ctrace[j].i*cshot[i*nfreq+j].i); } } cr1fft(&chom[0],rtrace,nt,1); for (i = 0; i < ntfft; i++) { HomG[i*Nsyn+synpos[l]] = rtrace[i]; } /*for (i = 0; i < ntfft/2; i++) { HomG[i*Nsyn+synpos[l]] = rtrace[ntfft/2+i]; } for (i = ntfft/2; i < ntfft; i++) { HomG[i*Nsyn+synpos[l]] = rtrace[i-ntfft/2]; }*/ } free(rtrace);free(chom);free(ctrace); } //free(Gmin); t2 = wallclock_time(); if (verbose) { vmess("Total Homogeneous G time = %.3f", t2-t0); } return; }
long defineSource3D(wavPar wav, srcPar src, modPar mod, recPar rec, float **src_nwav, long reverse, long verbose) { FILE *fp; size_t nread; long optn, nfreq, i, j, k, iwmax, tracesToDo; long iw, n1, namp, optnscale, nfreqscale; float scl, d1, df, deltom, om, tshift; float amp1, amp2, amp3; float *trace, maxampl, scale; complex *ctrace, tmp; segy hdr; scale = 1.0; n1 = wav.ns; if (wav.random) { /* initialize random sequence */ srand48(wav.seed+1); seedCMWC4096(); for (i=0; i<8192; i++) { amp1 = dcmwc4096(); } } else { /* read first header and last byte to get file size */ fp = fopen( wav.file_src, "r" ); assert( fp != NULL); nread = fread( &hdr, 1, TRCBYTES, fp ); assert(nread == TRCBYTES); /* read all traces */ tracesToDo = wav.nx; i = 0; while (tracesToDo) { memset(&src_nwav[i][0],0,wav.nt*sizeof(float)); nread = fread(&src_nwav[i][0], sizeof(float), hdr.ns, fp); assert (nread == hdr.ns); nread = fread( &hdr, 1, TRCBYTES, fp ); if (nread==0) break; tracesToDo--; i++; } fclose(fp); } optn = loptncr(n1); nfreq = optn/2 + 1; if (wav.nt != wav.ns) { vmess("Sampling in wavelet is %e while for modeling is set to %e", wav.ds, mod.dt); vmess("Wavelet sampling will be FFT-interpolated to sampling of modeling"); vmess("file_src Nt=%li sampling after interpolation=%li", wav.ns, wav.nt); optnscale = wav.nt; nfreqscale = optnscale/2 + 1; } else { optnscale = optn; nfreqscale = optnscale/2 + 1; } // fprintf(stderr,"define S optn=%li ns=%li %e nt=%li %e\n", optn, wav.ns, wav.ds, optnscale, wav.dt); ctrace = (complex *)calloc(nfreqscale,sizeof(complex)); trace = (float *)calloc(optnscale,sizeof(float)); df = 1.0/(optn*wav.ds); deltom = 2.*M_PI*df; scl = 1.0/optn; iwmax = nfreq; for (i=0; i<wav.nx; i++) { if (wav.random) { randomWavelet3D(wav, src, &src_nwav[i][0], src.tbeg[i], src.tend[i], verbose); } else { memset(&ctrace[0].r,0,nfreqscale*sizeof(complex)); memset(&trace[0],0,optnscale*sizeof(float)); memcpy(&trace[0],&src_nwav[i][0],n1*sizeof(float)); rc1fft(trace,ctrace,optn,-1); /* Scale source from file with -j/w (=1/(jw)) for volume source injections no scaling is applied for volume source injection rates */ if (src.injectionrate==0) { for (iw=1;iw<iwmax;iw++) { om = 1.0/(deltom*iw); tmp.r = om*ctrace[iw].i; tmp.i = -om*ctrace[iw].r; ctrace[iw].r = tmp.r; ctrace[iw].i = tmp.i; } } if (src.type < 6) { // shift wavelet with +1/2 DeltaT due to staggered in time tshift=-(0.5*rec.skipdt+1.5)*wav.dt; for (iw=1;iw<iwmax;iw++) { om = deltom*iw*tshift; tmp.r = ctrace[iw].r*cos(-om) - ctrace[iw].i*sin(-om); tmp.i = ctrace[iw].i*cos(-om) + ctrace[iw].r*sin(-om); ctrace[iw].r = tmp.r; ctrace[iw].i = tmp.i; } } /* zero frequency iw=0 set to 0 if the next sample has amplitude==0*/ amp1 = sqrt(ctrace[1].r*ctrace[1].r+ctrace[1].i*ctrace[1].i); if (amp1 == 0.0) { ctrace[0].r = ctrace[0].i = 0.0; } else { /* stabilization for w=0: extrapolate amplitudes to 0 */ amp2 = sqrt(ctrace[2].r*ctrace[2].r+ctrace[2].i*ctrace[2].i); amp3 = sqrt(ctrace[3].r*ctrace[3].r+ctrace[3].i*ctrace[3].i); ctrace[0].r = amp1+(2.0*(amp1-amp2)-(amp2-amp3)); ctrace[0].i = 0.0; if (ctrace[1].r < 0.0) { ctrace[0].r *= -1.0; } } for (iw=iwmax;iw<nfreqscale;iw++) { ctrace[iw].r = 0.0; ctrace[iw].i = 0.0; } memset(&trace[0],0,optnscale*sizeof(float)); cr1fft(ctrace,trace,optnscale,1); /* avoid a (small) spike in the last sample this is done to avoid diffraction from last wavelet sample which will act as a pulse */ maxampl=0.0; if (reverse) { for (j=0; j<wav.nt; j++) { src_nwav[i][j] = scl*(trace[wav.nt-j-1]-trace[0]); maxampl = MAX(maxampl,fabs(src_nwav[i][j])); } } else { for (j=0; j<wav.nt; j++) { src_nwav[i][j] = scl*(trace[j]-trace[wav.nt-1]); maxampl = MAX(maxampl,fabs(src_nwav[i][j])); } } if (verbose > 3) vmess("Wavelet sampling (FFT-interpolated) done for trace %li", i); } } /* set values smaller than 1e-5 maxampl to zero */ maxampl *= 1e-5; for (i=0; i<wav.nx; i++) { for (j=0; j<wav.nt; j++) { if (fabs(src_nwav[i][j]) < maxampl) src_nwav[i][j] = 0.0; } } free(ctrace); free(trace); /* use random amplitude gain factor for each source */ if (src.amplitude > 0.0) { namp=wav.nx*10; trace = (float *)calloc(2*namp,sizeof(float)); for (i=0; i<wav.nx; i++) { if (src.distribution) { scl = gaussGen()*src.amplitude; k = (long)MAX(MIN(namp*(scl+5*src.amplitude)/(10*src.amplitude),namp-1),0); d1 = 10.0*src.amplitude/(namp-1); } else { scl = (float)(drand48()-0.5)*src.amplitude; k = (long)MAX(MIN(namp*(scl+1*src.amplitude)/(2*src.amplitude),namp-1),0); d1 = 2.0*src.amplitude/(namp-1); } trace[k] += 1.0; /* trace[i] = scl; */ if (wav.random) n1 = wav.nsamp[i]; else n1 = wav.nt; for (j=0; j<n1; j++) { src_nwav[i][j] *= scl; } } if (verbose>2) writesufile3D("src_ampl.su", trace, namp, 1, -5*src.amplitude, 0.0, d1, 1); free(trace); } if (verbose>3) writesufilesrcnwav3D("src_nwav.su", src_nwav, wav, wav.nt, wav.nx, 0.0, 0.0, wav.dt, 1); return 0; }
long randomWavelet3D(wavPar wav, srcPar src, float *trace, float tbeg, float tend, long verbose) { long optn, nfreq, j, iwmax; long iw, n1, itbeg, itmax, nsmth; float df, amp1; float *rtrace; float x1, x2, z1, z2, dzdx1, dzdx2, a, b, c, d, t; complex *ctrace; n1 = wav.nt; /* this is set to the maximum length (tlength/dt) */ optn = loptncr(2*n1); nfreq = optn/2 + 1; ctrace = (complex *)calloc(nfreq,sizeof(complex)); rtrace = (float *)calloc(optn,sizeof(float)); df = 1.0/(optn*wav.dt); iwmax = MIN(NINT(wav.fmax/df),nfreq); for (iw=1;iw<iwmax;iw++) { ctrace[iw].r = (float)(drand48()-0.5); ctrace[iw].i = (float)(drand48()-0.5); } for (iw=iwmax;iw<nfreq;iw++) { ctrace[iw].r = 0.0; ctrace[iw].i = 0.0; } cr1fft(ctrace,rtrace,optn,1); /* find first zero crossing in wavelet */ amp1 = rtrace[0]; j = 1; if (amp1 < 0.0) { while (rtrace[j] < 0.0) j++; } else { while (rtrace[j] > 0.0) j++; } itbeg = j; /* find last zero crossing in wavelet */ // itmax = itbeg+MIN(NINT((tend-tbeg)/wav.dt),n1); itmax = MIN(NINT(itbeg+(tend-tbeg)/wav.dt),n1); amp1 = rtrace[itmax-1]; j = itmax; if (amp1 < 0.0) { while (rtrace[j] < 0.0 && j>itbeg) j--; } else { while (rtrace[j] > 0.0 && j>itbeg) j--; } itmax = j; /* make smooth transitions to zero aamplitude */ nsmth=MIN(10,itmax); x1 = 0.0; z1 = 0.0; dzdx1 = 0.0; x2 = nsmth; z2 = rtrace[itbeg+nsmth]; dzdx2 = (rtrace[itbeg+nsmth-2]-8.0*rtrace[itbeg+nsmth-1]+ 8.0*rtrace[itbeg+nsmth+1]-rtrace[itbeg+nsmth+2])/(12.0); spline3(x1, x2, z1, z2, dzdx1, dzdx2, &a, &b, &c, &d); for (j=0; j<nsmth; j++) { t = j; rtrace[itbeg+j] = a*t*t*t+b*t*t+c*t+d; } x1 = 0.0; z1 = rtrace[itmax-nsmth]; dzdx1 = (rtrace[itmax-nsmth-2]-8.0*rtrace[itmax-nsmth-1]+ 8.0*rtrace[itmax-nsmth+1]-rtrace[itmax-nsmth+2])/(12.0); x2 = nsmth; z2 = 0.0; dzdx2 = 0.0; spline3(x1, x2, z1, z2, dzdx1, dzdx2, &a, &b, &c, &d); for (j=0; j<nsmth; j++) { t = j; rtrace[itmax-nsmth+j] = a*t*t*t+b*t*t+c*t+d; } for (j=itbeg; j<itmax; j++) trace[j-itbeg] = rtrace[j]; free(ctrace); free(rtrace); return 0; }
int main(int argc, char **argv) { modPar mod; recPar rec; srcPar src; shotPar shot; rayPar ray; float *velocity, *slowness, *smooth, *trueslow, **inter; double t0, t1, t2, tinit, tray, tio; size_t size; int nw, n1, ix, iz, ir, ixshot, izshot; int nt, ntfft, nfreq, ig; int irec, sbox, ipos, nrx, nrz, nr; fcoord coordsx, coordgx, Time; icoord grid, isrc; float Jr, *ampl, *time, *ttime, *ttime_p, cp_average, *wavelet, dw, dt; float dxrcv, dzrcv, rdelay, tr, dt_tmp; segy hdr; char filetime[1024], fileamp[1024], *method, *file_rcvtime, *file_src; size_t nwrite, nread; int verbose; complex *cmute, *cwav; FILE *fpt, *fpa, *fpwav, *fprcv; t0= wallclock_time(); initargs(argc,argv); requestdoc(0); if(!getparint("verbose",&verbose)) verbose=0; if(!getparint("sbox", &sbox)) sbox = 1; if(!getparstring("method", &method)) method="jesper"; if (!getparfloat("rec_delay",&rdelay)) rdelay=0.0; getParameters(&mod, &rec, &src, &shot, &ray, verbose); /* read file_src if file_rcvtime is defined */ if (!getparstring("file_rcvtime",&file_rcvtime)) file_rcvtime=NULL; if (file_rcvtime != NULL) { if (!getparstring("file_src",&file_src)) file_src=NULL; if (!getparfloat("dt",&dt)) dt=0.004; if (file_src != NULL ) { fpwav = fopen( file_src, "r" ); assert( fpwav != NULL); nread = fread( &hdr, 1, TRCBYTES, fpwav ); assert(nread == TRCBYTES); ntfft = optncr(MAX(hdr.ns, rec.nt)); wavelet = (float *)calloc(ntfft,sizeof(float)); /* read first trace */ nread = fread(wavelet, sizeof(float), hdr.ns, fpwav); assert (nread == hdr.ns); fclose(fpwav); } else { ntfft = optncr(rec.nt); wavelet = (float *)calloc(ntfft,sizeof(float)); wavelet[0] = 1.0; } nfreq = ntfft/2+1; cwav = (complex *)calloc(nfreq,sizeof(complex)); cmute = (complex *)calloc(nfreq,sizeof(complex)); rc1fft(wavelet,cwav,ntfft,-1); dw = 2*M_PI/(ntfft*dt); } /* allocate arrays for model parameters: the different schemes use different arrays */ n1 = mod.nz; if(!strcmp(method,"fd")) nw = 0; else nw = ray.smoothwindow; velocity = (float *)calloc(mod.nx*mod.nz,sizeof(float)); slowness = (float *)calloc((mod.nx+2*nw)*(mod.nz+2*nw),sizeof(float)); trueslow = (float *)calloc(mod.nx*mod.nz,sizeof(float)); if(!strcmp(method,"fd")) { ttime = (float *)calloc(mod.nx*mod.nz,sizeof(float)); } /* read velocity and density files */ readModel(mod, velocity, slowness, nw); /* allocate arrays for wavefield and receiver arrays */ size = shot.n*rec.n; time = (float *)calloc(size,sizeof(float)); ampl = (float *)calloc(size,sizeof(float)); /* Sinking source and receiver arrays: If P-velocity==0 the source and receiver postions are placed deeper until the P-velocity changes. Setting the option rec.sinkvel only sinks the receiver position (not the source) and uses the velocity of the first receiver to sink through to the next layer. */ /* sink receivers to value different than sinkvel */ for (ir=0; ir<rec.n; ir++) { iz = rec.z[ir]; ix = rec.x[ir]; while(velocity[(ix)*n1+iz] == rec.sinkvel) iz++; rec.z[ir]=iz+rec.sinkdepth; rec.zr[ir]=rec.zr[ir]+(rec.z[ir]-iz)*mod.dz; // rec.zr[ir]=rec.z[ir]*mod.dz; if (verbose>3) vmess("receiver position %d at grid[ix=%d, iz=%d] = (x=%f z=%f)", ir, ix, rec.z[ir], rec.xr[ir]+mod.x0, rec.zr[ir]+mod.z0); } vmess(" - method for ray-tracing = %s", method); /* */ /* sink sources to value different than zero */ for (izshot=0; izshot<shot.nz; izshot++) { for (ixshot=0; ixshot<shot.nx; ixshot++) { iz = shot.z[izshot]; ix = shot.x[ixshot]; while(velocity[(ix)*n1+iz] == 0.0) iz++; shot.z[izshot]=iz+src.sinkdepth; } } if (verbose>3) writeSrcRecPos(&mod, &rec, &src, &shot); /* smooth slowness grid */ grid.x = mod.nx; grid.z = mod.nz; grid.y = 1; if ( nw != 0 ) { /* smooth slowness */ smooth = (float *)calloc(grid.x*grid.z,sizeof(float)); applyMovingAverageFilter(slowness, grid, nw, 2, smooth); memcpy(slowness,smooth,grid.x*grid.z*sizeof(float)); free(smooth); } /* prepare output file and headers */ strcpy(filetime, rec.file_rcv); name_ext(filetime, "_time"); fpt = fopen(filetime, "w"); assert(fpt != NULL); if (ray.geomspread) { strcpy(fileamp, rec.file_rcv); name_ext(fileamp, "_amp"); fpa = fopen(fileamp, "w"); assert(fpa != NULL); } if (file_rcvtime != NULL) { fprcv = fopen(file_rcvtime, "w"); assert(fprcv != NULL); } memset(&hdr,0,sizeof(hdr)); hdr.scalco = -1000; hdr.scalel = -1000; hdr.trid = 0; t1=wallclock_time(); tinit = t1-t0; tray=0.0; tio=0.0; /* Outer loop over number of shots */ for (izshot=0; izshot<shot.nz; izshot++) { for (ixshot=0; ixshot<shot.nx; ixshot++) { t2=wallclock_time(); if (verbose) { vmess("Modeling source %d at gridpoints ix=%d iz=%d", (izshot*shot.n)+ixshot, shot.x[ixshot], shot.z[izshot]); vmess(" which are actual positions x=%.2f z=%.2f", mod.x0+mod.dx*shot.x[ixshot], mod.z0+mod.dz*shot.z[izshot]); vmess("Receivers at gridpoint x-range ix=%d - %d", rec.x[0], rec.x[rec.n-1]); vmess(" which are actual positions x=%.2f - %.2f", mod.x0+rec.xr[0], mod.x0+rec.xr[rec.n-1]); vmess("Receivers at gridpoint z-range iz=%d - %d", rec.z[0], rec.z[rec.n-1]); vmess(" which are actual positions z=%.2f - %.2f", mod.z0+rec.zr[0], mod.z0+rec.zr[rec.n-1]); } coordsx.x = shot.x[ixshot]*mod.dx; coordsx.z = shot.z[izshot]*mod.dz; coordsx.y = 0; t1=wallclock_time(); tio += t1-t2; if (!strcmp(method,"jesper")) { #pragma omp parallel for default(shared) \ private (coordgx,irec,Time,Jr) for (irec=0; irec<rec.n; irec++) { coordgx.x=rec.xr[irec]; coordgx.z=rec.zr[irec]; coordgx.y = 0; getWaveParameter(slowness, grid, mod.dx, coordsx, coordgx, ray, &Time, &Jr); time[((izshot*shot.nx)+ixshot)*rec.n + irec] = Time.x + Time.y + 0.5*Time.z; ampl[((izshot*shot.nx)+ixshot)*rec.n + irec] = Jr; if (verbose>4) vmess("JS: shot=%f,%f receiver at %f,%f T0=%f T1=%f T2=%f Jr=%f",coordsx.x, coordsx.z, coordgx.x, coordgx.z, Time.x, Time.y, Time.z, Jr); } } else if(!strcmp(method,"fd")) { int mzrcv; isrc.x = shot.x[ixshot]; isrc.y = 0; isrc.z = shot.z[izshot]; mzrcv = 0; for (irec = 0; irec < rec.n; irec++) mzrcv = MAX(rec.z[irec], mzrcv); vidale(ttime,slowness,&isrc,grid,mod.dx,sbox, mzrcv); for (irec=0; irec<rec.n; irec++) { coordgx.x=mod.x0+rec.xr[irec]; coordgx.z=mod.z0+rec.zr[irec]; coordgx.y = 0; ipos = ((izshot*shot.nx)+ixshot)*rec.n + irec; time[ipos] = ttime[rec.z[irec]*mod.nx+rec.x[irec]]; /* compute average velocity between source and receiver */ nrx = (rec.x[irec]-isrc.x); nrz = (rec.z[irec]-isrc.z); nr = abs(nrx) + abs(nrz); cp_average = 0.0; for (ir=0; ir<nr; ir++) { ix = isrc.x + floor((ir*nrx)/nr); iz = isrc.z + floor((ir*nrz)/nr); //fprintf(stderr,"ir=%d ix=%d iz=%d velocity=%f\n", ir, ix, iz, velocity[ix*mod.nz+iz]); cp_average += velocity[ix*mod.nz+iz]; } cp_average = cp_average/((float)nr); ampl[ipos] = sqrt(time[ipos]*cp_average); if (verbose>4) vmess("FD: shot=%f,%f receiver at %f(%d),%f(%d) T=%e V=%f Ampl=%f",coordsx.x, coordsx.z, coordgx.x, rec.x[irec], coordgx.z, rec.z[irec], time[ipos], cp_average, ampl[ipos]); } } t2=wallclock_time(); tray += t2-t1; hdr.sx = 1000*(mod.x0+mod.dx*shot.x[ixshot]); hdr.sdepth = 1000*(mod.z0+mod.dz*shot.z[izshot]); hdr.selev = (int)(-1000.0*(mod.z0+mod.dz*shot.z[izshot])); hdr.fldr = ((izshot*shot.nx)+ixshot)+1; hdr.tracl = ((izshot*shot.nx)+ixshot)+1; hdr.tracf = ((izshot*shot.nx)+ixshot)+1; hdr.ntr = shot.n; hdr.dt = (unsigned short)1; hdr.trwf = shot.n; hdr.ns = rec.n; //hdr.d1 = (rec.x[1]-rec.x[0])*mod.dx; // discrete hdr.d1 = (rec.xr[1]-rec.xr[0]); hdr.f1 = mod.x0+rec.x[0]*mod.dx; hdr.d2 = (shot.x[MIN(shot.n-1,1)]-shot.x[0])*mod.dx; hdr.f2 = mod.x0+shot.x[0]*mod.dx; dt_tmp = (fabs(hdr.d1*((float)hdr.scalco))); hdr.dt = (unsigned short)dt_tmp; nwrite = fwrite( &hdr, 1, TRCBYTES, fpt); assert(nwrite == TRCBYTES); nwrite = fwrite( &time[((izshot*shot.nx)+ixshot)*rec.n], sizeof(float), rec.n, fpt); assert(nwrite == rec.n); fflush(fpt); if (ray.geomspread) { nwrite = fwrite( &hdr, 1, TRCBYTES, fpa); assert(nwrite == TRCBYTES); nwrite = fwrite( &l[((izshot*shot.nx)+ixshot)*rec.n], sizeof(float), rec.n, fpa); assert(nwrite == rec.n); fflush(fpa); } if (file_rcvtime != NULL) { hdr.ns = rec.nt; hdr.trwf = rec.n; hdr.ntr = ((izshot*shot.nx)+ixshot+1)*rec.n; hdr.dt = dt*1000000; hdr.d1 = dt; hdr.f1 = 0.0; hdr.d2 = (rec.xr[1]-rec.xr[0]); hdr.f2 = mod.x0+rec.x[0]*mod.dx; for (irec=0; irec<rec.n; irec++) { ipos = ((izshot*shot.nx)+ixshot)*rec.n + irec; hdr.tracf = irec+1; hdr.tracl = ((izshot*shot.nx)+ixshot*shot.nz)+irec+1; hdr.gx = 1000*(mod.x0+rec.xr[irec]); hdr.offset = (rec.xr[irec]-shot.x[ixshot]*mod.dx); hdr.gelev = (int)(-1000*(mod.z0+rec.zr[irec])); tr = time[ipos]+rdelay; for (ig=0; ig<nfreq; ig++) { cmute[ig].r = (cwav[ig].r*cos(ig*dw*tr-M_PI/4.0)-cwav[ig].i*sin(ig*dw*tr-M_PI/4.0))/(ntfft*ampl[ipos]); cmute[ig].i = (cwav[ig].i*cos(ig*dw*tr-M_PI/4.0)+cwav[ig].r*sin(ig*dw*tr-M_PI/4.0))/(ntfft*ampl[ipos]); } cr1fft(cmute,wavelet,ntfft,-1); nwrite = fwrite( &hdr, 1, TRCBYTES, fprcv); nwrite = fwrite( wavelet, sizeof(float), rec.nt, fprcv ); } } t1=wallclock_time(); tio += t1-t2; } /* end of ixshot loop */ } /* end of loop over number of shots */ fclose(fpt); if (file_rcvtime != NULL) fclose(fprcv); if (ray.geomspread) fclose(fpa); t1= wallclock_time(); if (verbose) { vmess("*******************************************"); vmess("************* runtime info ****************"); vmess("*******************************************"); vmess("Total compute time ray-tracing = %.2f s.", t1-t0); vmess(" - intializing arrays and model = %.3f", tinit); vmess(" - ray tracing = %.3f", tray); vmess(" - writing data to file = %.3f", tio); } /* free arrays */ initargs(argc,argv); /* this will free the arg arrays declared */ free(velocity); free(slowness); return 0; }
void synthesis(complex *Refl, complex *Fop, float *Top, float *iRN, int nx, int nt, int nxs, int nts, float dt, float *xsyn, int Nsyn, float *xrcv, float *xsrc, float fxs2, float fxs, float dxs, float dxsrc, float dx, int ixa, int ixb, int ntfft, int nw, int nw_low, int nw_high, int mode, int reci, int nshots, int *ixpossyn, int npossyn, double *tfft, int *first, int verbose) { int nfreq, size, iox, inx; float scl; int i, j, l, m, iw, ix, k; float *rtrace, idxs; complex *sum, *ctrace; int npe; static int *ixrcv; static double t0, t1, t; size = nxs*nts; nfreq = ntfft/2+1; /* scale factor 1/N for backward FFT, * scale dt for correlation/convolution along time, * scale dx (or dxsrc) for integration over receiver (or shot) coordinates */ scl = 1.0*dt/((float)ntfft); #ifdef _OPENMP npe = omp_get_max_threads(); /* parallelisation is over number of virtual source positions (Nsyn) */ if (npe > Nsyn) { vmess("Number of OpenMP threads set to %d (was %d)", Nsyn, npe); omp_set_num_threads(Nsyn); } #endif t0 = wallclock_time(); /* reset output data to zero */ memset(&iRN[0], 0, Nsyn*nxs*nts*sizeof(float)); idxs = 1.0/dxs; if (ixrcv == NULL) { ixrcv = (int *)malloc(nshots*nx*sizeof(int)); } for (k=0; k<nshots; k++) { for (i = 0; i < nx; i++) { ixrcv[k*nx+i] = NINT((xrcv[k*nx+i]-fxs)*idxs); } } ctrace = (complex *)calloc(ntfft,sizeof(complex)); if (!*first) { /* transform muted Ni (Top) to frequency domain, input for next iteration */ for (l = 0; l < Nsyn; l++) { /* set Fop to zero, so new operator can be defined within ixpossyn points */ //memset(&Fop[l*nxs*nw].r, 0, nxs*nw*2*sizeof(float)); bzero(&Fop[l*nxs*nw].r, nxs*nw*2*sizeof(float)); for (i = 0; i < npossyn; i++) { rc1fft(&Top[l*size+i*nts],ctrace,ntfft,-1); ix = ixpossyn[i]; for (iw=0; iw<nw; iw++) { Fop[l*nxs*nw+iw*nxs+ix].r = ctrace[nw_low+iw].r; Fop[l*nxs*nw+iw*nxs+ix].i = mode*ctrace[nw_low+iw].i; } } } } else { /* only for first call to synthesis */ /* transform G_d to frequency domain, over all nxs traces */ *first=0; for (l = 0; l < Nsyn; l++) { /* set Fop to zero, so new operator can be defined within all ix points */ //memset(&Fop[l*nxs*nw].r, 0, nxs*nw*2*sizeof(float)); bzero(&Fop[l*nxs*nw].r, nxs*nw*2*sizeof(float)); for (i = 0; i < nxs; i++) { rc1fft(&Top[l*size+i*nts],ctrace,ntfft,-1); for (iw=0; iw<nw; iw++) { Fop[l*nxs*nw+iw*nxs+i].r = ctrace[nw_low+iw].r; Fop[l*nxs*nw+iw*nxs+i].i = mode*ctrace[nw_low+iw].i; } } } } free(ctrace); t1 = wallclock_time(); *tfft += t1 - t0; for (k=0; k<nshots; k++) { /* if (verbose>=3) { vmess("source position: %.2f ixpossyn=%d", xsrc[k], ixpossyn[k]); vmess("receiver positions: %.2f <--> %.2f", xrcv[k*nx+0], xrcv[k*nx+nx-1]); } */ if ((NINT(xsrc[k]-fxs2) > 0) || (NINT(xrcv[k*nx+nx-1]-fxs2) > 0) || (NINT(xrcv[k*nx+nx-1]-fxs) < 0) || (NINT(xsrc[k]-fxs) < 0) || (NINT(xrcv[k*nx+0]-fxs) < 0) || (NINT(xrcv[k*nx+0]-fxs2) > 0) ) { vwarn("source/receiver positions are outside synthesis model"); vwarn("integration calculation is stopped at gather %d", k); vmess("xsrc = %.2f xrcv_1 = %.2f xrvc_N = %.2f", xsrc[k], xrcv[k*nx+0], xrcv[k*nx+nx-1]); break; } iox = 0; inx = nx; /*================ SYNTHESIS ================*/ #pragma omp parallel default(none) \ shared(iRN, dx, npe, nw, verbose) \ shared(Refl, Nsyn, reci, xrcv, xsrc, xsyn, fxs, nxs, dxs) \ shared(nx, ixa, ixb, dxsrc, iox, inx, k, nfreq, nw_low, nw_high) \ shared(Fop, size, nts, ntfft, scl, ixrcv, stderr) \ private(l, ix, j, m, i, sum, rtrace) { /* start of parallel region */ sum = (complex *)malloc(nfreq*sizeof(complex)); rtrace = (float *)calloc(ntfft,sizeof(float)); #pragma omp for schedule(guided,1) for (l = 0; l < Nsyn; l++) { ix = k; /* multiply R with Fop and sum over nx */ memset(&sum[0].r,0,nfreq*2*sizeof(float)); //for (j = 0; j < nfreq; j++) sum[j].r = sum[j].i = 0.0; for (j = nw_low, m = 0; j <= nw_high; j++, m++) { for (i = iox; i < inx; i++) { sum[j].r += Refl[k*nw*nx+m*nx+i].r*Fop[l*nw*nxs+m*nxs+ixrcv[k*nx+i]].r - Refl[k*nw*nx+m*nx+i].i*Fop[l*nw*nxs+m*nxs+ixrcv[k*nx+i]].i; sum[j].i += Refl[k*nw*nx+m*nx+i].i*Fop[l*nw*nxs+m*nxs+ixrcv[k*nx+i]].r + Refl[k*nw*nx+m*nx+i].r*Fop[l*nw*nxs+m*nxs+ixrcv[k*nx+i]].i; } } /* transfrom result back to time domain */ cr1fft(sum, rtrace, ntfft, 1); /* dx = receiver distance */ for (j = 0; j < nts; j++) iRN[l*size+ix*nts+j] += rtrace[j]*scl*dx; } /* end of parallel Nsyn loop */ free(sum); free(rtrace); #pragma omp single { #ifdef _OPENMP npe = omp_get_num_threads(); #endif } } /* end of parallel region */ if (verbose>3) vmess("*** Shot gather %d processed ***", k); } /* end of nshots (k) loop */ t = wallclock_time() - t0; if (verbose) { vmess("OMP: parallel region = %f seconds (%d threads)", t, npe); } return; }
void synthesis(complex *Refl, complex *Fop, float *Top, float *iRN, int nx, int nt, int nxs, int nts, float dt, float *xsyn, int Nfoc, float *xrcv, float *xsrc, int *xnx, float fxse, float fxsb, float dxs, float dxsrc, float dx, int ntfft, int nw, int nw_low, int nw_high, int mode, int reci, int nshots, int *ixpos, int npos, double *tfft, int *isxcount, int *reci_xsrc, int *reci_xrcv, float *ixmask, int verbose) { int nfreq, size, inx; float scl; int i, j, l, m, iw, ix, k, ixsrc, il, ik; float *rtrace, idxs; complex *sum, *ctrace; int npe; static int first=1, *ixrcv; static double t0, t1, t; size = nxs*nts; nfreq = ntfft/2+1; /* scale factor 1/N for backward FFT, * scale dt for correlation/convolution along time, * scale dx (or dxsrc) for integration over receiver (or shot) coordinates */ scl = 1.0*dt/((float)ntfft); #ifdef _OPENMP npe = omp_get_max_threads(); /* parallelisation is over number of shot positions (nshots) */ if (npe > nshots) { vmess("Number of OpenMP threads set to %d (was %d)", nshots, npe); omp_set_num_threads(nshots); } #endif t0 = wallclock_time(); /* reset output data to zero */ memset(&iRN[0], 0, Nfoc*nxs*nts*sizeof(float)); ctrace = (complex *)calloc(ntfft,sizeof(complex)); /* this first check is done to support an acquisition geometry that has more receiver than source * postions. In the first iteration the int R(x_r,x_s) Fop(x_r) d x_r results in a grid on x_s. * so for the next interations onlt x_s traces have to be computed on Fop */ if (!first) { /* transform muted Ni (Top) to frequency domain, input for next iteration */ for (l = 0; l < Nfoc; l++) { /* set Fop to zero, so new operator can be defined within ixpos points */ memset(&Fop[l*nxs*nw].r, 0, nxs*nw*2*sizeof(float)); for (i = 0; i < npos; i++) { rc1fft(&Top[l*size+i*nts],ctrace,ntfft,-1); ix = ixpos[i]; for (iw=0; iw<nw; iw++) { Fop[l*nxs*nw+iw*nxs+ix].r = ctrace[nw_low+iw].r; Fop[l*nxs*nw+iw*nxs+ix].i = mode*ctrace[nw_low+iw].i; } } } } else { /* only for first call to synthesis using all nxs traces in G_d */ /* transform G_d to frequency domain, over all nxs traces */ first=0; for (l = 0; l < Nfoc; l++) { /* set Fop to zero, so new operator can be defined within all ix points */ memset(&Fop[l*nxs*nw].r, 0, nxs*nw*2*sizeof(float)); for (i = 0; i < nxs; i++) { rc1fft(&Top[l*size+i*nts],ctrace,ntfft,-1); for (iw=0; iw<nw; iw++) { Fop[l*nxs*nw+iw*nxs+i].r = ctrace[nw_low+iw].r; Fop[l*nxs*nw+iw*nxs+i].i = mode*ctrace[nw_low+iw].i; } } } idxs = 1.0/dxs; ixrcv = (int *)malloc(nshots*nx*sizeof(int)); for (k=0; k<nshots; k++) { for (i = 0; i < nx; i++) { ixrcv[k*nx+i] = NINT((xrcv[k*nx+i]-fxsb)*idxs); } } } free(ctrace); t1 = wallclock_time(); *tfft += t1 - t0; if (reci == 0 || reci == 1) { /*================ SYNTHESIS ================*/ #pragma omp parallel default(none) \ shared(iRN, dx, npe, nw, verbose, nshots, xnx) \ shared(Refl, Nfoc, reci, xsrc, xsyn, fxsb, fxse, nxs, dxs) \ shared(nx, dxsrc, nfreq, nw_low, nw_high) \ shared(Fop, size, nts, ntfft, scl, ixrcv) \ private(l, ix, j, m, i, sum, rtrace, k, ixsrc, inx) { /* start of parallel region */ sum = (complex *)malloc(nfreq*sizeof(complex)); rtrace = (float *)calloc(ntfft,sizeof(float)); /* Loop over total number of shots */ #pragma omp for schedule(guided,1) for (k=0; k<nshots; k++) { if ((xsrc[k] < 0.999*fxsb) || (xsrc[k] > 1.001*fxse)) continue; ixsrc = NINT((xsrc[k] - fxsb)/dxs); inx = xnx[k]; /* number of traces per shot */ for (l = 0; l < Nfoc; l++) { /* compute integral over receiver positions */ /* multiply R with Fop and sum over nx */ memset(&sum[0].r,0,nfreq*2*sizeof(float)); for (j = nw_low, m = 0; j <= nw_high; j++, m++) { for (i = 0; i < inx; i++) { ix = ixrcv[k*nx+i]; sum[j].r += Refl[k*nw*nx+m*nx+i].r*Fop[l*nw*nxs+m*nxs+ix].r - Refl[k*nw*nx+m*nx+i].i*Fop[l*nw*nxs+m*nxs+ix].i; sum[j].i += Refl[k*nw*nx+m*nx+i].i*Fop[l*nw*nxs+m*nxs+ix].r + Refl[k*nw*nx+m*nx+i].r*Fop[l*nw*nxs+m*nxs+ix].i; } } /* transfrom result back to time domain */ cr1fft(sum, rtrace, ntfft, 1); /* place result at source position ixsrc; dx = receiver distance */ for (j = 0; j < nts; j++) iRN[l*size+ixsrc*nts+j] += rtrace[j]*scl*dx; } /* end of parallel Nfoc loop */ if (verbose>4) vmess("*** Shot gather %d processed ***", k); } /* end of nshots (k) loop */ free(sum); free(rtrace); } /* end of parallel region */ } /* end of if reci */ /* if reciprocal traces are enabled start a new loop over reciprocal shot positions */ if (reci != 0) { #pragma omp parallel default(none) \ shared(iRN, dx, nw, verbose) \ shared(Refl, Nfoc, reci, xsrc, xsyn, fxsb, fxse, nxs, dxs) \ shared(nx, dxsrc, nfreq, nw_low, nw_high) \ shared(reci_xrcv, reci_xsrc, ixmask, isxcount) \ shared(Fop, size, nts, ntfft, scl, ixrcv) \ private(l, ix, j, m, i, k, sum, rtrace, ik, il, ixsrc, inx) { /* start of parallel region */ sum = (complex *)malloc(nfreq*sizeof(complex)); rtrace = (float *)calloc(ntfft,sizeof(float)); #pragma omp for schedule(guided,1) for (k=0; k<nxs; k++) { if (isxcount[k] == 0) continue; ixsrc = k; inx = isxcount[ixsrc]; /* number of traces per reciprocal shot */ for (l = 0; l < Nfoc; l++) { /* compute integral over (reciprocal) source positions */ /* multiply R with Fop and sum over nx */ memset(&sum[0].r,0,nfreq*2*sizeof(float)); for (j = nw_low, m = 0; j <= nw_high; j++, m++) { for (i = 0; i < inx; i++) { il = reci_xrcv[ixsrc*nxs+i]; ik = reci_xsrc[ixsrc*nxs+i]; ix = NINT((xsrc[il] - fxsb)/dxs); sum[j].r += Refl[il*nw*nx+m*nx+ik].r*Fop[l*nw*nxs+m*nxs+ix].r - Refl[il*nw*nx+m*nx+ik].i*Fop[l*nw*nxs+m*nxs+ix].i; sum[j].i += Refl[il*nw*nx+m*nx+ik].i*Fop[l*nw*nxs+m*nxs+ix].r + Refl[il*nw*nx+m*nx+ik].r*Fop[l*nw*nxs+m*nxs+ix].i; } } /* transfrom result back to time domain */ cr1fft(sum, rtrace, ntfft, 1); /* place result at source position ixsrc; dxsrc = shot distance */ for (j = 0; j < nts; j++) iRN[l*size+ixsrc*nts+j] = ixmask[ixsrc]*(iRN[l*size+ixsrc*nts+j]+rtrace[j]*scl*dxsrc); } /* end of Nfoc loop */ } /* end of parallel reciprocal shots (k) loop */ free(sum); free(rtrace); } /* end of parallel region */ } /* end of if reci */ t = wallclock_time() - t0; if (verbose>2) { vmess("OMP: parallel region = %f seconds (%d threads)", t, npe); } return; }
int write_FFT_DataFile(FILE *fp, complex *data, Area data_area, int fldr, int nt, int nfft, int nw, int nw_low, float dt, int out_su, int conjg, int freq, int verbose) { int ix, iy, iw, i, nx, ny, sxy, nfreq, pos, sign; int xvmin, yvmin; size_t nwrite; float dx, dy, *trace; complex *ctrace; segy *hdr; nx = data_area.nx; ny = data_area.ny; sxy = data_area.sxy; dx = data_area.dx; dy = data_area.dy; xvmin = data_area.xmin; yvmin = data_area.ymin; nfreq = nfft/2 + 1; sign = 1; trace = (float *)calloc(nfft,sizeof(float)); ctrace = (complex *)malloc(nfreq*sizeof(complex)); hdr = (segy *)calloc(1,TRCBYTES); hdr[0].trid = 1; hdr[0].fldr = fldr; hdr[0].trwf = nx; hdr[0].ntr = nx*ny; hdr[0].ns = nt; hdr[0].dt = 1000000*dt; hdr[0].f1 = 0.0; hdr[0].f2 = xvmin; hdr[0].d1 = dt; hdr[0].d2 = dx; hdr[0].scalco = -1000; if (freq==0) { for (iy=0; iy<ny; iy++) { for (ix=0; ix<nx; ix++) { pos = iy*nx+ix; for (i=0; i<nfreq; i++) ctrace[i].r = ctrace[i].i = 0.0; for (iw=0; iw<nw; iw++) { ctrace[iw+nw_low].r = data[iw*sxy+pos].r; ctrace[iw+nw_low].i = conjg*data[iw*sxy+pos].i; } /* transform back to time */ cr1fft(ctrace, trace, nfft, sign); /* write to output file */ if (out_su) { hdr[0].gx = (int)(xvmin+ix*dx)*1000; hdr[0].gy = (int)(yvmin+iy*dy)*1000; hdr[0].f2 = xvmin+ix*dx; hdr[0].tracf = ix+1; hdr[0].tracl = iy*nx+ix+1; nwrite = fwrite(hdr, 1, TRCBYTES, fp); assert( nwrite == TRCBYTES ); nwrite = fwrite(trace, sizeof(float), nt, fp); assert( nwrite == nt ); } else { nwrite = fwrite(trace, sizeof(float), nt, fp); assert( nwrite == nt ); } } } } else { /* Frequency output slices */ hdr[0].trid = 122; hdr[0].fldr = fldr; hdr[0].trwf = ny; hdr[0].ntr = nw*ny; hdr[0].ns = nx; hdr[0].dt = 1000000*dt; hdr[0].f1 = 0.0; hdr[0].f2 = yvmin; for (iw=0; iw<nw; iw++) { for (iy=0; iy<ny; iy++) { /* write to output file */ if (out_su) { hdr[0].gx = (int)(xvmin)*1000; hdr[0].gy = (int)(yvmin+iy*dy)*1000; hdr[0].f1 = xvmin+ix*dx; hdr[0].f2 = yvmin+iy*dy; hdr[0].tracf = iy+1; hdr[0].tracl = iw*ny+iy+1; nwrite = fwrite(hdr, 1, TRCBYTES, fp); assert( nwrite == TRCBYTES ); nwrite = fwrite(&data[iw*sxy+iy*nx], sizeof(complex), nx, fp); assert( nwrite == nx ); } else { nwrite = fwrite(&data[iw*sxy+iy*nx], sizeof(complex), nx, fp); assert( nwrite == nx ); } } } } fflush(fp); free(trace); free(ctrace); free(hdr); return 0; }
int defineSource(wavPar wav, srcPar src, float **src_nwav, int reverse, int verbose) { FILE *fp; size_t nread; int optn, nfreq, i, j, k, iwmax, tracesToDo; int iw, n1, namp; float scl, d1, df, deltom, om, tshift; float amp1, amp2, amp3; float *trace, maxampl; complex *ctrace, tmp; segy hdr; n1 = wav.nt; if (wav.random) { /* initialize random sequence */ srand48(wav.seed+1); seedCMWC4096(); for (i=0; i<8192; i++) { amp1 = dcmwc4096(); } } else { /* read first header and last byte to get file size */ fp = fopen( wav.file_src, "r" ); assert( fp != NULL); nread = fread( &hdr, 1, TRCBYTES, fp ); assert(nread == TRCBYTES); /* read all traces */ tracesToDo = wav.nx; i = 0; while (tracesToDo) { memset(&src_nwav[i][0],0,n1*sizeof(float)); nread = fread(&src_nwav[i][0], sizeof(float), hdr.ns, fp); assert (nread == hdr.ns); nread = fread( &hdr, 1, TRCBYTES, fp ); if (nread==0) break; tracesToDo--; i++; } fclose(fp); } optn = optncr(2*n1); nfreq = optn/2 + 1; ctrace = (complex *)calloc(nfreq,sizeof(complex)); trace = (float *)calloc(optn,sizeof(float)); df = 1.0/(optn*wav.dt); deltom = 2.*M_PI*df; scl = 1.0/optn; maxampl=0.0; iwmax = nfreq; for (i=0; i<wav.nx; i++) { if (wav.random) { randomWavelet(wav, src, &src_nwav[i][0], src.tbeg[i], src.tend[i], verbose); } else { memset(&ctrace[0].r,0,nfreq*sizeof(complex)); memset(&trace[0],0,optn*sizeof(float)); memcpy(&trace[0],&src_nwav[i][0],n1*sizeof(float)); rc1fft(trace,ctrace,optn,-1); /* Scale source from file with -j/w (=1/(jw)) for volume source injections no scaling is applied for volume source injection rates */ if (src.injectionrate==0) { for (iw=1;iw<iwmax;iw++) { om = 1.0/(deltom*iw); tmp.r = om*ctrace[iw].i; tmp.i = -om*ctrace[iw].r; ctrace[iw].r = tmp.r; ctrace[iw].i = tmp.i; } } /* */ if (src.type < 6) { // shift wavelet with +1/2 DeltaT due to staggered in time tshift=0.5*wav.dt; for (iw=1;iw<iwmax;iw++) { om = deltom*iw*tshift; tmp.r = ctrace[iw].r*cos(-om) - ctrace[iw].i*sin(-om); tmp.i = ctrace[iw].i*cos(-om) + ctrace[iw].r*sin(-om); ctrace[iw].r = tmp.r; ctrace[iw].i = tmp.i; } } /* zero frequency iw=0 set to 0 if the next sample has amplitude==0*/ amp1 = sqrt(ctrace[1].r*ctrace[1].r+ctrace[1].i*ctrace[1].i); if (amp1 == 0.0) { ctrace[0].r = ctrace[0].i = 0.0; } else { /* stabilization for w=0: extrapolate amplitudes to 0 */ amp2 = sqrt(ctrace[2].r*ctrace[2].r+ctrace[2].i*ctrace[2].i); amp3 = sqrt(ctrace[3].r*ctrace[3].r+ctrace[3].i*ctrace[3].i); ctrace[0].r = amp1+(2.0*(amp1-amp2)-(amp2-amp3)); ctrace[0].i = 0.0; if (ctrace[1].r < 0.0) { ctrace[0].r *= -1.0; } } for (iw=iwmax;iw<nfreq;iw++) { ctrace[iw].r = 0.0; ctrace[iw].i = 0.0; } cr1fft(ctrace,trace,optn,1); /* avoid a (small) spike in the last sample this is done to avoid diffraction from last wavelet sample which will act as a pulse */ if (reverse) { for (j=0; j<n1; j++) src_nwav[i][j] = scl*(trace[n1-j-1]-trace[0]); // for (j=0; j<n1; j++) src_nwav[i][j] = scl*(trace[j]-trace[optn-1]); } else { for (j=0; j<n1; j++) src_nwav[i][j] = scl*(trace[j]-trace[optn-1]); } } } free(ctrace); free(trace); /* use random amplitude gain factor for each source */ if (src.amplitude > 0.0) { namp=wav.nx*10; trace = (float *)calloc(2*namp,sizeof(float)); for (i=0; i<wav.nx; i++) { if (src.distribution) { scl = gaussGen()*src.amplitude; k = (int)MAX(MIN(namp*(scl+5*src.amplitude)/(10*src.amplitude),namp-1),0); d1 = 10.0*src.amplitude/(namp-1); } else { scl = (float)(drand48()-0.5)*src.amplitude; k = (int)MAX(MIN(namp*(scl+1*src.amplitude)/(2*src.amplitude),namp-1),0); d1 = 2.0*src.amplitude/(namp-1); } trace[k] += 1.0; /* trace[i] = scl; */ if (wav.random) n1 = wav.nsamp[i]; else n1 = wav.nt; for (j=0; j<n1; j++) { src_nwav[i][j] *= scl; } } if (verbose>2) writesufile("src_ampl.su", trace, namp, 1, -5*src.amplitude, 0.0, d1, 1); /* qsort(trace,wav.nx,sizeof(float), comp); for (i=0; i<wav.nx; i++) { scl = trace[i]; trace[i] = normal(scl, 0.0, src.amplitude); } if (verbose>2) writesufile("src_ampl.su", trace, wav.nx, 1, -5*src.amplitude, 0.0, d1, 1); */ free(trace); } if (verbose>3) writesufilesrcnwav("src_nwav.su", src_nwav, wav, wav.nt, wav.nx, 0.0, 0.0, wav.dt, 1); /* set maximum amplitude in source file to 1.0 */ /* assert(maxampl != 0.0); scl = wav.dt/(maxampl); scl = 1.0/(maxampl); for (i=0; i<wav.nx; i++) { for (j=0; j<n1; j++) { src_nwav[i*n1+j] *= scl; } } */ return 0; }