-
Joeri Brackenhoff authoredJoeri Brackenhoff authored
getParameters3D.c 52.15 KiB
#include<stdlib.h>
#include<stdio.h>
#include<math.h>
#include<assert.h>
#include"par.h"
#include"fdelmodc3D.h"
#define MAX(x,y) ((x) > (y) ? (x) : (y))
#define MIN(x,y) ((x) < (y) ? (x) : (y))
#define NINT(x) ((long)((x)>0.0?(x)+0.5:(x)-0.5))
/**
*
* The routine getParameters reads in all parameters to set up a FD modeling.
* Model and source parameters are used to calculate stability and dispersion relations
* Source and receiver positions are calculated and checked if they fit into the model.
*
* AUTHOR:
* Jan Thorbecke (janth@xs4all.nl)
* The Netherlands
**/
float gaussGen();
long loptncr(long n);
long getModelInfo3D(char *file_name, long *n1, long *n2, long *n3,
float *d1, float *d2, float *d3, float *f1, float *f2, float *f3,
float *min, float *max, long *axis, long zeroch, long verbose);
long getWaveletInfo3D(char *file_src, long *n1, long *n2, float *d1, float *d2,
float *f1, float *f2, float *fmax, long *nxm, long verbose);
long getWaveletHeaders3D(char *file_src, long n1, long n2, float *gx, float *sx,
float *gy, float *sy, float *gelev, float *selev, long verbose);
long recvPar3D(recPar *rec, float sub_x0, float sub_y0, float sub_z0,
float dx, float dy, float dz, long nx, long ny, long nz);
long getParameters3D(modPar *mod, recPar *rec, snaPar *sna, wavPar *wav, srcPar *src,
shotPar *shot, bndPar *bnd, long verbose)
{
long isnapmax1, isnapmax2, isnapmax, sna_nrsna;
long n1, n2, n3, nx, ny, nz, nsrc, ix, axis, ioPz, is0, optn;
long npxsrc, npysrc, isx0, isy0, isx, isy;
long idzshot, idxshot, idyshot, nsrctext;
long src_ix0, src_iy0, src_iz0, src_ix1, src_iy1, src_iz1;
long disable_check;
float cp_min, cp_max, cs_min, cs_max, ro_min, ro_max;
float stabfactor,dispfactor, cmin, dt, fmax, scl, wfct, tapfact;
float zstart, xstart, ystart, d1, d2, d3, f1, f2, f3, sub_x0, sub_y0, sub_z0;
float srcendx, srcendy, srcendz, dx, dy, dz;
float xsrc, ysrc, zsrc, dxshot, dyshot, dzshot, dtshot;
float dxrcv, dyrcv, dzrcv, dxspread, dyspread, dzspread;
float tsnap1, tsnap2, dtsnap, dxsnap, dysnap, dzsnap, dtrcv;
float xsnap1, xsnap2, ysnap1, ysnap2, zsnap1, zsnap2, xmax, ymax, zmax;
float xsrc1, xsrc2, ysrc1, ysrc2, zsrc1, zsrc2, tsrc1, tsrc2, tlength, tactive;
float src_anglex, src_angley, src_velox, src_veloy, px, py, grad2rad, rdelay, scaledt;
float *xsrca, *ysrca, *zsrca, rrcv;
float Mxx, Myy, Mzz, Mxy, Myz, Mxz;
float rsrc, oxsrc, oysrc, ozsrc, dphisrc, ncsrc;
size_t nsamp;
long i, j, l;
long cfree;
long tapleft,tapright,taptop,tapbottom,tapfront, tapback;
long nxsrc, nysrc, nzsrc;
long largeSUfile;
long is,ntraces,length_random;
float rand;
char *src_positions, tmpname[1024];
char* src_txt;
FILE *fp;
if (!getparlong("verbose",&verbose)) verbose=0;
if (!getparlong("disable_check",&disable_check)) disable_check=0;
if (!getparlong("iorder",&mod->iorder)) mod->iorder=4;
if (!getparlong("ischeme",&mod->ischeme)) mod->ischeme=1;
if (!getparlong("sh",&mod->sh)) mod->sh=0;
if (!getparstring("file_cp",&mod->file_cp)) {
verr("parameter file_cp required!");
}
if (!getparstring("file_den",&mod->file_ro)) {
verr("parameter file_den required!");
}
if (mod->ischeme>2 && mod->ischeme!=5) {
if (!getparstring("file_cs",&mod->file_cs)) {
verr("parameter file_cs required!");
}
}
if (!getparstring("file_src",&wav->file_src)) wav->file_src=NULL;
if (!getparstring("file_snap",&sna->file_snap)) sna->file_snap="snap.su";
if (!getparstring("file_beam",&sna->file_beam)) sna->file_beam="beam.su";
if (!getparstring("file_rcv",&rec->file_rcv)) rec->file_rcv="recv.su";
if (!getparlong("grid_dir",&mod->grid_dir)) mod->grid_dir=0;
if (!getparlong("src_at_rcv",&src->src_at_rcv)) src->src_at_rcv=1;
/* read model parameters, which are used to set up source and receivers and check stability */
getModelInfo3D(mod->file_cp, &nz, &nx, &ny, &dz, &dx, &dy, &sub_z0, &sub_x0, &sub_y0, &cp_min, &cp_max, &axis, 1, verbose);
getModelInfo3D(mod->file_ro, &n1, &n2, &n3, &d1, &d2, &d3, &zstart, &xstart, &ystart, &ro_min, &ro_max, &axis, 0, verbose);
mod->cp_max = cp_max;
mod->cp_min = cp_min;
mod->ro_max = ro_max;
mod->ro_min = ro_min;
assert( (ro_min != 0.0) );
if (NINT(100*(dx/d2)) != 100)
vwarn("dx differs for file_cp and file_den!");
if (NINT(100*(dy/d3)) != 100)
vwarn("dy differs for file_cp and file_den!");
if (NINT(100*(dz/d1)) != 100)
vwarn("dz differs for file_cp and file_den!");
if (nx != n2)
vwarn("nx differs for file_cp and file_den!");
if (ny != n3)
vwarn("nx differs for file_cp and file_den!");
if (nz != n1)
vwarn("nz differs for file_cp and file_den!");
if (mod->ischeme>2 && mod->ischeme!=5) {
getModelInfo3D(mod->file_cs, &n1, &n2, &n3, &d1, &d2, &d3, &zstart, &xstart, &ystart, &cs_min, &cs_max, &axis, 1, verbose);
mod->cs_max = cs_max;
mod->cs_min = cs_min;
if (NINT(100*(dx/d2)) != 100)
vwarn("dx differs for file_cp and file_cs!");
if (NINT(100*(dy/d3)) != 100)
vwarn("dy differs for file_cp and file_cs!");
if (NINT(100*(dz/d1)) != 100)
vwarn("dz differs for file_cp and file_cs!");
if (nx != n2)
vwarn("nx differs for file_cp and file_cs!");
if (ny != n3)
vwarn("ny differs for file_cp and file_cs!");
if (nz != n1)
vwarn("nz differs for file_cp and file_cs!");
}
if (mod->ischeme==5) {
cs_max=0.0; cs_min=0.0;
mod->cs_max = cs_max;
mod->cs_min = cs_min;
}
mod->nfz = nz;
mod->nfx = nx;
mod->nfy = ny;
/* check if 1D, 2D or full 3D gridded model is given as input model */
if (nx==1 && ny==1 ) { // 1D model
if (!getparlong("nx",&nx)) nx=nz;
if (!getparlong("ny",&ny)) ny=nx;
dx=dz;
dy=dx;
sub_x0=-0.5*(nx-1)*(dx);
sub_y0=-0.5*(ny-1)*(dy);
}
else if (ny==1) { // 2D model
if (!getparlong("ny",&ny)) ny=nx;
dy=dx;
sub_y0=-0.5*(ny-1)*(dy);
fprintf(stderr,"get param ny=%ld dy=%f y0=%f\n", ny, dy, sub_y0);
}
mod->dz = dz;
mod->dx = dx;
mod->dy = dy;
mod->nz = nz;
mod->nx = nx;
mod->ny = ny;
// end of part1 ################################################################################################
/* define wavelet(s), modeling time and wavelet maximum frequency */
if (wav->file_src!=NULL) {
getWaveletInfo3D(wav->file_src, &wav->ns, &wav->nx, &wav->ds, &d2, &f1, &f2, &fmax, &ntraces, verbose);
if (wav->ds <= 0.0) {
vwarn("dt in wavelet (file_src) equal to 0.0 or negative.");
vwarn("Use parameter dt= to overule dt from file_src.");
}
wav->nt = wav->ns;
wav->dt = wav->ds;
if(!getparfloat("tmod",&mod->tmod)) mod->tmod = (wav->nt-1)*wav->dt;
if(!getparfloat("dt",&mod->dt)) mod->dt=wav->dt;
if (NINT(wav->ds*1000000) != NINT(mod->dt*1000000)) {
if (wav->dt > mod->dt) {
scaledt = wav->dt/mod->dt;
scaledt = floorf(wav->dt/mod->dt);
optn = loptncr(wav->ns);
wav->nt = floorf(scaledt*optn);
vmess("file_src dt-scalefactor=%f : wav.dt=%e ==interpolated==> mod.dt=%e", scaledt, wav->dt, mod->dt);
wav->dt = mod->dt;
}
else {
wav->dt = mod->dt; /* in case if wav.dt is smaller than 1e-7 and can not be read by SU-getpar */
}
}
if(!getparfloat("fmax",&wav->fmax)) wav->fmax=fmax;
}
else {
fmax = 50;
if(!getparfloat("dt",&mod->dt)) verr("dt must be given or use file_src=");
if(!getparfloat("tmod",&mod->tmod)) verr("tmod must be given");
if(!getparfloat("fmax",&wav->fmax)) wav->fmax=fmax;
fmax = wav->fmax;
wav->dt=mod->dt;
}
assert(mod->dt!=0.0);
/* check if receiver delays is defined; option inactive: add delay time to total modeling time */
if (!getparfloat("rec_delay",&rdelay)) rdelay=0.0;
rec->delay=NINT(rdelay/mod->dt);
mod->nt = NINT(mod->tmod/mod->dt);
dt = mod->dt;
if (!getparlong("src_type",&src->type)) src->type=1;
if (!getparfloat("src_Mxx",&src->Mxx)) src->Mxx=0.0;
if (!getparlong("src_orient",&src->orient)) {
src->orient=1;
if (getparlong("dipsrc",&src->orient)) src->orient=2; // for compatability with DELPHI's fdacmod
}
if (mod->ischeme<=2) {
if (src->type>1 && src->type<6)
verr("Invalid src_type for acoustic scheme!");
}
if (mod->ischeme==2 || mod->ischeme==4) {
if (!getparstring("file_qp",&mod->file_qp)) mod->file_qp=NULL;
if (!getparstring("file_qs",&mod->file_qs)) mod->file_qs=NULL;
if (!getparfloat("Qp",&mod->Qp)) mod->Qp=1;
if (!getparfloat("Qs",&mod->Qs)) mod->Qs=mod->Qp;
if (!getparfloat("fw",&mod->fw)) mod->fw=0.5*wav->fmax;
}
/* dissipative medium option for Evert */
if (mod->ischeme==-1) {
if (!getparfloat("qr",&mod->qr)) mod->qr=0.1;
}
assert(src->type > 0);
/* dispersion factor to 10 points per wavelength (2nd order)
or 5 points per wavelength (4th order) */
if (mod->iorder == 2) {
dispfactor=10;
stabfactor = 1.0/sqrt(2.0);
}
else {
dispfactor = 6;
//stabfactor = 0.606; /* courant number */
stabfactor = 0.495; //Joeri check: number changes in 3D case. Sei&Simes, 1995.
/*However as we will see in the sequel, the stability condition
has only an indicative role. We will have to choose p = c. A t/Ax much less
than the maximum allowed by the stability condition to fulfill the precision
criteria we have imposed.*/
}
// end of part2 ################################################################################################
/* origin of model in real (non-grid) coordinates */
mod->x0 = sub_x0;
mod->y0 = sub_y0;
mod->z0 = sub_z0;
xmax = sub_x0+(nx-1)*dx;
ymax = sub_y0+(ny-1)*dy;
zmax = sub_z0+(nz-1)*dz;
if (verbose) {
vmess("*******************************************");
vmess("************** general info ***************");
vmess("*******************************************");
vmess("tmod = %f",mod->tmod);
vmess("ntsam = %li dt = %f(%e)",mod->nt, mod->dt, mod->dt);
if (mod->ischeme == 1) vmess("Acoustic staggered grid, pressure/velocity");
if (mod->ischeme == 2) vmess("Visco-Acoustic staggered grid, pressure/velocity");
if (mod->ischeme == 3) vmess("Elastic staggered grid, stress/velocity");
if (mod->ischeme == 4) vmess("Visco-Elastic staggered grid, stress/velocity");
if (mod->ischeme == 5) vmess("Acoustic staggered grid, Txx/Tzz/velocity");
if (mod->grid_dir) vmess("Time reversed modelling");
else vmess("Forward modelling");
vmess("*******************************************");
vmess("*************** model info ****************");
vmess("*******************************************");
if (mod->nfx == 1) {
vmess(" 1-dimensional model is read from file");
}
else if (mod->nfy == 1) {
vmess(" 2-dimensional model is read from file");
}
else {
vmess(" 3-dimensional model is read from file");
}
vmess("nz = %li ny = %li nx = %li", nz, ny, nx);
vmess("dz = %8.4f dy = %8.4f dx = %8.4f", dz, dy, dx);
vmess("zmin = %8.4f zmax = %8.4f", sub_z0, zmax);
vmess("ymin = %8.4f ymax = %8.4f", sub_y0, ymax);
vmess("xmin = %8.4f xmax = %8.4f", sub_x0, xmax);
vmess("min(cp) = %9.3f max(cp) = %9.3f", cp_min, cp_max);
if (mod->ischeme>2 && mod->ischeme!=5) vmess("min(cs) = %9.3f max(cs) = %9.3f", cs_min, cs_max);
vmess("min(ro) = %9.3f max(ro) = %9.3f", ro_min, ro_max);
if (mod->ischeme==2 || mod->ischeme==4) {
if (mod->file_qp!=NULL) vmess("Qp from file %s ", mod->file_qp);
else vmess("Qp = %9.3f ", mod->Qp);
vmess("at freq = %5.3f", mod->fw);
}
if (mod->ischeme==4) {
if (mod->file_qs!=NULL) vmess("Qs from file %s ", mod->file_qs);
else vmess("Qs = %9.3f ", mod->Qs);
vmess("at freq = %5.3f", mod->fw);
}
}
if (mod->ischeme <= 2) {
cmin = cp_min;
}
else {
cmin = cs_min;
if ( (cmin<1e-20) || (cp_min<cs_min) ) cmin=cp_min;
}
if (verbose) {
vmess("*******************************************");
vmess("******** dispersion and stability *********");
vmess("*******************************************");
vmess("Dispersion criterion is %3d points per wavelength: ", NINT(dispfactor));
vmess(" ====> wavelength > %f m [dx*disp]", dx*dispfactor);
vmess("The maximum frequency in source wavelet must be:");
vmess(" ====> frequency < %f Hz. [Cmin/dx*disp]", cmin/(dx*dispfactor));
vmess("Stability criterion for current settings: ");
vmess(" ====> Cp < %f m/s [dx*disp/dt]", dx*stabfactor/dt);
if (wav->file_src != NULL) vmess(" For wavelet(s) in file_src fmax = %f", fmax);
vmess("Optimal discretisation for current model:");
vmess(" With maximum velocity = %f dt <= %e", cp_max,dx*stabfactor/cp_max);
vmess(" With maximum frequency = %f dx <= %e", wav->fmax, cmin/(wav->fmax*dispfactor));
}
/* Check stability and dispersion setting */
if (cp_max > dx*stabfactor/dt) {
vwarn("************ ! Stability ! ****************");
vwarn("From the input file maximum P-wave velocity");
vwarn("in the current model is %f !!", cp_max);
vwarn("Hence, adjust dx >= %.4f,",cp_max*dt/stabfactor);
vwarn(" or adjust dt <= %f,",dx*stabfactor/cp_max);
vwarn(" or lower the maximum velocity below %.3f m/s.",dx*stabfactor/dt);
vwarn("***************** !!! *********************");
if (!disable_check) verr("********* leaving program *********");
}
if (wav->fmax > cmin/(dx*dispfactor)) {
vwarn("*********** ! Dispersion ! ****************");
vwarn("The maximum frequency in the source wavelet is");
vwarn("%.3f for stable modeling fmax < %.3f ", wav->fmax, cmin/(dx*dispfactor));
vwarn("Hence, adjust dx <= %.4f",cmin/(wav->fmax*dispfactor));
vwarn(" or adjust fmax <= %f (overruled with parameter fmax=),",cmin/(dx*dispfactor));
vwarn(" or increase the minimum velocity above %.3f m/s.",dx*dispfactor*wav->fmax);
vwarn("***************** !!! *********************");
if (!disable_check) verr("********* leaving program *********");
}
/* to support old parameter interface */
if (!getparlong("cfree",&cfree)) taptop=1;
if (!getparlong("tapleft",&tapleft)) tapleft=0;
if (!getparlong("tapright",&tapright)) tapright=0;
if (!getparlong("taptop",&taptop)) taptop=0;
if (!getparlong("tapbottom",&tapbottom)) tapbottom=0;
if (!getparlong("tapfront",&tapfront)) tapfront=0;
if (!getparlong("tapback",&tapback)) tapback=0;
if (tapleft) bnd->lef=4;
else bnd->lef=1;
if (tapright) bnd->rig=4;
else bnd->rig=1;
if (taptop) bnd->top=4;
else bnd->top=1;
if (tapbottom) bnd->bot=4;
else bnd->bot=1;
if (tapfront) bnd->fro=4;
else bnd->fro=1;
if (tapback) bnd->bac=4;
else bnd->bac=1;
/* define the type of boundaries */
/* 1=free 2=pml 3=rigid 4=taper */
if (!getparlong("left",&bnd->lef) && !tapleft) bnd->lef=4;
if (!getparlong("right",&bnd->rig)&& !tapright) bnd->rig=4;
if (!getparlong("top",&bnd->top) && !taptop) bnd->top=1;
if (!getparlong("bottom",&bnd->bot) && !tapbottom) bnd->bot=4;
if (!getparlong("front",&bnd->fro) && !tapfront) bnd->fro=4;
if (!getparlong("back",&bnd->bac) && !tapback) bnd->bac=4;
/* calculate default taper length to be three wavelenghts */
if (!getparlong("ntaper",&bnd->ntap)) bnd->ntap=0; // bnd->ntap=3*NINT((cp_max/wav->fmax)/dx);
if (!bnd->ntap) if (!getparlong("npml",&bnd->ntap)) bnd->ntap=3*NINT((cp_max/wav->fmax)/dx);
if (!getparfloat("R",&bnd->R)) bnd->R=1e-5;
if (!getparfloat("m",&bnd->m)) bnd->m=2.0;
bnd->npml=bnd->ntap;
if (bnd->ntap) {
bnd->tapx = (float *)malloc(bnd->ntap*sizeof(float));
bnd->tapy = (float *)malloc(bnd->ntap*sizeof(float));
bnd->tapz = (float *)malloc(bnd->ntap*sizeof(float));
bnd->tapxz = (float *)malloc(bnd->ntap*bnd->ntap*sizeof(float));
bnd->tapxyz = (float *)malloc(bnd->ntap*bnd->ntap*bnd->ntap*sizeof(float));
if(!getparfloat("tapfact",&tapfact)) tapfact=0.30;
scl = tapfact/((float)bnd->ntap);
for (i=0; i<bnd->ntap; i++) {
wfct = (scl*i);
bnd->tapx[i] = exp(-(wfct*wfct));
bnd->tapy[i] = exp(-(wfct*wfct));
wfct = (scl*(i+0.5));
bnd->tapz[i] = exp(-(wfct*wfct));
}
//corner
for (j=0; j<bnd->ntap; j++) {
for (i=0; i<bnd->ntap; i++) {
wfct = (scl*sqrt(i*i+j*j));
bnd->tapxz[j*bnd->ntap+i] = exp(-(wfct*wfct));
}
}
//double corner
for (j=0; j<bnd->ntap; j++) {
for (i=0; i<bnd->ntap; i++) {
for (l=0; l<bnd->ntap; l++) {
wfct = (scl*sqrt(i*i+j*j+l*l));
bnd->tapxyz[l*(bnd->ntap)*(bnd->ntap)+j*(bnd->ntap)+i] = exp(-(wfct*wfct));
}
}
}
}
/* Vx: rox */
mod->ioXx=mod->iorder/2;
mod->ioXy=mod->iorder/2-1;
mod->ioXz=mod->iorder/2-1;
/* Vy: roy */
mod->ioYx=mod->iorder/2-1;
mod->ioYy=mod->iorder/2;
mod->ioYz=mod->iorder/2-1;
/* Vz: roz */
mod->ioZx=mod->iorder/2-1;
mod->ioZy=mod->iorder/2-1;
mod->ioZz=mod->iorder/2;
/* P, Txx, Tzz: lam, l2m */
mod->ioPx=mod->iorder/2-1;
mod->ioPy=mod->ioPx;
mod->ioPz=mod->ioPx;
/* Txz: mul */
mod->ioTx=mod->iorder/2;
mod->ioTy=mod->ioTx;
mod->ioTz=mod->ioTx;
/* end loop iteration in FD kernels */
/* Vx: rox */
mod->ieXx=nx+mod->ioXx;
mod->ieXy=ny+mod->ioXy;
mod->ieXz=nz+mod->ioXz;
/* Vy: roy */
mod->ieYx=nx+mod->ioYx;
mod->ieYy=ny+mod->ioYy;
mod->ieYz=nz+mod->ioYz;
/* Vz: roz */
mod->ieZx=nx+mod->ioZx;
mod->ieZy=ny+mod->ioZy;
mod->ieZz=nz+mod->ioZz;
/* P, Txx, Tzz: lam, l2m */
mod->iePx=nx+mod->ioPx;
mod->iePy=ny+mod->ioPy;
mod->iePz=nz+mod->ioPz;
/* Txz: muu */
mod->ieTx=nx+mod->ioTx;
mod->ieTy=ny+mod->ioTy;
mod->ieTz=nz+mod->ioTz;
mod->naz = mod->nz+mod->iorder;
mod->nay = mod->ny+mod->iorder;
mod->nax = mod->nx+mod->iorder;
/* for tapered and PML extra points are needed at the boundaries of the model */
if (bnd->top==4 || bnd->top==2) {
mod->naz += bnd->ntap;
mod->ioXz += bnd->ntap;
mod->ioYz += bnd->ntap;
mod->ioZz += bnd->ntap;
mod->ieXz += bnd->ntap;
mod->ieYz += bnd->ntap;
mod->ieZz += bnd->ntap;
/* For P/Tzz, Txx and Txz fields the tapered boundaries are calculated in the main kernels */
mod->iePz += bnd->ntap;
mod->ieTz += bnd->ntap;
}
if (bnd->bot==4 || bnd->bot==2) {
mod->naz += bnd->ntap;
/* For P/Tzz, Txx and Txz fields the tapered boundaries are calculated in the main kernels */
mod->iePz += bnd->ntap;
mod->ieTz += bnd->ntap;
}
if (bnd->lef==4 || bnd->lef==2) {
mod->nax += bnd->ntap;
mod->ioXx += bnd->ntap;
mod->ioYx += bnd->ntap;
mod->ioZx += bnd->ntap;
mod->ieXx += bnd->ntap;
mod->ieYx += bnd->ntap;
mod->ieZx += bnd->ntap;
/* For Tzz, Txx and Txz fields the tapered boundaries are calculated in the main kernels */
mod->iePx += bnd->ntap;
mod->ieTx += bnd->ntap;
}
if (bnd->rig==4 || bnd->rig==2) {
mod->nax += bnd->ntap;
/* For P/Tzz, Txx and Txz fields the tapered boundaries are calculated in the main kernels */
mod->iePx += bnd->ntap;
mod->ieTx += bnd->ntap;
}
if (bnd->fro==4 || bnd->fro==2) {
mod->nay += bnd->ntap;
mod->ioXy += bnd->ntap;
mod->ioYy += bnd->ntap;
mod->ioZy += bnd->ntap;
mod->ieXy += bnd->ntap;
mod->ieYy += bnd->ntap;
mod->ieZy += bnd->ntap;
/* For Tzz, Txx and Txz fields the tapered boundaries are calculated in the main kernels */
mod->iePy += bnd->ntap;
mod->ieTy += bnd->ntap;
}
if (bnd->bac==4 || bnd->bac==2) {
mod->nay += bnd->ntap;
/* For P/Tzz, Txx and Txz fields the tapered boundaries are calculated in the main kernels */
mod->iePy += bnd->ntap;
mod->ieTy += bnd->ntap;
}
/* Intialize the array which contains the topography surface */
if (bnd->top==4 || bnd->top==2) ioPz=mod->ioPz - bnd->ntap;
else ioPz=mod->ioPz;
ioPz=mod->ioPz;
bnd->surface = (long *)malloc((mod->nax*mod->nay+mod->naz)*sizeof(long));
for (ix=0; ix<mod->nax*mod->nay+mod->naz; ix++) {
bnd->surface[ix] = ioPz;
}
if (verbose) {
vmess("*******************************************");
vmess("************* boundary info ***************");
vmess("*******************************************");
vmess("*** 1=free 2=pml 3=rigid 4=tapered ***");
vmess("Top boundary : %li",bnd->top);
vmess("Left boundary : %li",bnd->lef);
vmess("Right boundary : %li",bnd->rig);
vmess("Bottom boundary : %li",bnd->bot);
vmess("Front boundary : %li",bnd->fro);
vmess("Back boundary : %li",bnd->bac);
vmess("taper length = %li points",bnd->ntap);
}
/* define the number and type of shots to model */
/* each shot can have multiple sources arranged in different ways */
if (!getparfloat("xsrc",&xsrc)) xsrc=sub_x0+((nx-1)*dx)/2.0;
if (!getparfloat("ysrc",&ysrc)) ysrc=sub_y0+((ny-1)*dy)/2.0;
if (!getparfloat("zsrc",&zsrc)) zsrc=sub_z0;
if (!getparlong("nshot",&shot->n)) shot->n=1;
if (!getparfloat("dxshot",&dxshot)) dxshot=dx;
if (!getparfloat("dyshot",&dyshot)) dyshot=dy;
if (!getparfloat("dzshot",&dzshot)) dzshot=0.0;
if (!getparfloat("dip",&src->dip)) src->dip=0.0;
if (!getparfloat("strike",&src->strike)) src->strike=0.0;
if (!getparfloat("rake",&src->rake)) src->rake=0.0;
src->dip = M_PI*(src->dip/180.0);
src->strike = M_PI*(src->strike/180.0);
src->rake = M_PI*(src->rake/180.0);
if (shot->n>1) {
idxshot=MAX(0,NINT(dxshot/dx));
idyshot=MAX(0,NINT(dyshot/dy));
idzshot=MAX(0,NINT(dzshot/dz));
}
else {
idxshot=0.0;
idyshot=0.0;
idzshot=0.0;
}
/* calculate the shot positions */
src_ix0=MAX(0,NINT((xsrc-sub_x0)/dx));
src_ix0=MIN(src_ix0,nx);
src_iy0=MAX(0,NINT((ysrc-sub_y0)/dy));
src_iy0=MIN(src_iy0,ny);
src_iz0=MAX(0,NINT((zsrc-sub_z0)/dz));
src_iz0=MIN(src_iz0,nz);
srcendx=(shot->n-1)*dxshot+xsrc;
srcendy=(shot->n-1)*dyshot+ysrc;
srcendz=(shot->n-1)*dzshot+zsrc;
src_ix1=MAX(0,NINT((srcendx-sub_x0)/dx));
src_ix1=MIN(src_ix1,nx);
src_iy1=MAX(0,NINT((srcendy-sub_y0)/dy));
src_iy1=MIN(src_iy1,ny);
src_iz1=MAX(0,NINT((srcendz-sub_z0)/dz));
src_iz1=MIN(src_iz1,nz);
shot->x = (long *)calloc(shot->n,sizeof(long));
shot->y = (long *)calloc(shot->n,sizeof(long));
shot->z = (long *)calloc(shot->n,sizeof(long));
for (is=0; is<shot->n; is++) {
shot->x[is] = src_ix0+is*idxshot;
shot->y[is] = src_iy0+is*idyshot;
shot->z[is] = src_iz0+is*idzshot;
if (shot->x[is] > nx-1) shot->n = is-1;
if (shot->y[is] > ny-1) shot->n = is-1;
if (shot->z[is] > nz-1) shot->n = is-1;
}
/* check if source array is defined */
nxsrc = countparval("xsrca");
nysrc = countparval("ysrca");
nzsrc = countparval("zsrca");
if (nxsrc != nzsrc) {
verr("Number of sources in array xsrca (%li), ysrca (%li), zsrca (%li) are not equal",nxsrc, nysrc, nzsrc);
}
/* source positions defined through txt file */
if (!getparstring("src_txt",&src_txt)) src_txt=NULL;
/* check if sources on a circle are defined */
if (getparfloat("rsrc", &rsrc)) {
if (!getparfloat("dphisrc",&dphisrc)) dphisrc=2.0;
if (!getparfloat("oxsrc",&oxsrc)) oxsrc=0.0;
if (!getparfloat("oysrc",&oysrc)) oysrc=0.0;
if (!getparfloat("ozsrc",&ozsrc)) ozsrc=0.0;
ncsrc = NINT(360.0/dphisrc);
src->n = nsrc;
src->x = (long *)malloc(ncsrc*sizeof(long));
src->y = (long *)malloc(ncsrc*sizeof(long));
src->z = (long *)malloc(ncsrc*sizeof(long));
for (ix=0; ix<ncsrc; ix++) {
src->x[ix] = NINT((oxsrc-sub_x0+rsrc*cos(((ix*dphisrc)/360.0)*(2.0*M_PI)))/dx);
src->y[ix] = NINT((oysrc-sub_y0+rsrc*sin(((ix*dphisrc)/360.0)*(2.0*M_PI)))/dy);
src->z[ix] = NINT((ozsrc-sub_z0+rsrc*sin(((ix*dphisrc)/360.0)*(2.0*M_PI)))/dz);
if (verbose>4) fprintf(stderr,"Source on Circle: xsrc[%li]=%li ysrc=%li zsrc=%li\n", ix, src->x[ix], src->y[ix], src->z[ix]);
}
}
/* TO DO propagate src_positions parameter and structure through code */
if (!getparstring("src_positions",&src_positions)) src_positions="single";
wav->random=0;
src->random=0;
src->plane=0;
src->array=0;
src->single=0;
if (strstr(src_positions, "single")) src->single=1;
else if (strstr(src_positions, "array")) src->array=1;
else if (strstr(src_positions, "random")) src->random=1;
else if (strstr(src_positions, "plane")) src->plane=1;
else src->single=1;
/* to maintain functionality of older parameters usage */
if (!getparlong("src_random",&src->random)) src->random=0;
if (!getparlong("plane_wave",&src->plane)) src->plane=0;
if (src->random) {
if (!getparlong("wav_random",&wav->random)) wav->random=1;
src->plane=0;
src->array=0;
src->single=0;
}
else {
if (!getparlong("wav_random",&wav->random)) wav->random=0;
}
if (src->plane) {
src->random=0;
src->array=0;
src->single=0;
}
if (!wav->random) assert (wav->file_src != NULL);
if (wav->random) {
wav->nt=mod->nt;
wav->dt=mod->dt;
wav->nx=1;
}
/* number of sources per shot modeling */
if (!getparlong("src_nxwindow",&src->nxwindow)) src->nxwindow=0;
if (!getparlong("src_nywindow",&src->nywindow)) src->nywindow=0;
src->window = 0;
if (!getparfloat("src_anglex",&src_anglex)) src_anglex=0.;
if (!getparfloat("src_angley",&src_angley)) src_angley=0.;
if (!getparfloat("src_velox",&src_velox)) src_velox=1500.;
if (!getparfloat("src_veloy",&src_veloy)) src_veloy=1500.;
if (!getparlong("distribution",&src->distribution)) src->distribution=0;
if (!getparlong("src_multiwav",&src->multiwav)) src->multiwav=0;
if (!getparfloat("amplitude", &src->amplitude)) src->amplitude=0.0;
if (!getparfloat("tlength", &tlength)) tlength=mod->dt*(mod->nt-1);
if (!getparlong("src_injectionrate", &src->injectionrate)) src->injectionrate=0;
if (src->random && nxsrc==0) {
if (!getparlong("nsrc",&nsrc)) nsrc=1;
if (!getparlong("seed",&wav->seed)) wav->seed=10;
if (!getparfloat("xsrc1", &xsrc1)) xsrc1=sub_x0;
if (!getparfloat("xsrc2", &xsrc2)) xsrc2=xmax;
if (!getparfloat("ysrc1", &ysrc1)) ysrc1=sub_y0;
if (!getparfloat("ysrc2", &ysrc2)) ysrc2=ymax;
if (!getparfloat("zsrc1", &zsrc1)) zsrc1=sub_z0;
if (!getparfloat("zsrc2", &zsrc2)) zsrc2=zmax;
if (!getparfloat("tsrc1", &tsrc1)) tsrc1=0.0;
if (!getparfloat("tsrc2", &tsrc2)) tsrc2=mod->tmod;
if (!getparfloat("tactive", &tactive)) tactive=tsrc2;
tsrc2 = MIN(tsrc2, mod->tmod);
if (!getparfloat("tlength", &tlength)) tlength=tsrc2-tsrc1;
if (!getparlong("length_random", &length_random)) length_random=1;
dxshot = xsrc2-xsrc1;
dyshot = ysrc2-ysrc1;
dzshot = zsrc2-zsrc1;
dtshot = tsrc2-tsrc1;
if (wav->random) {
if (!getparlong("src_multiwav",&src->multiwav)) src->multiwav=1;
if (src->multiwav) wav->nx = nsrc;
else wav->nx = 1;
}
if (wav->random) wav->nt = NINT(tlength/mod->dt)+1;
src->tbeg = (float *)malloc(nsrc*sizeof(float));
src->tend = (float *)malloc(nsrc*sizeof(float));
wav->nsamp = (size_t *)malloc((nsrc+1)*sizeof(size_t));
src->x = (long *)malloc(nsrc*sizeof(long));
src->y = (long *)malloc(nsrc*sizeof(long));
src->z = (long *)malloc(nsrc*sizeof(long));
nsamp = 0;
srand48(wav->seed);
for (is=0; is<nsrc; is++) {
rand = (float)drand48();
src->x[is] = NINT((xsrc1+rand*dxshot-sub_x0)/dx);
rand = (float)drand48();
src->y[is] = NINT((ysrc1+rand*dyshot-sub_y0)/dy);
rand = (float)drand48();
src->z[is] = NINT((zsrc1+rand*dzshot-sub_z0)/dz);
if (length_random) rand = (float)drand48();
else rand = 0.0;
src->tbeg[is] = tsrc1+rand*(dtshot);
if (wav->random) {
if (src->distribution) rand = fabsf(tlength+gaussGen()*tlength);
else rand = (float)drand48()*tlength;
if (length_random!=1) rand = tlength;
src->tend[is] = MIN(src->tbeg[is]+rand, tactive);
wav->nsamp[is] = (size_t)(NINT((src->tend[is]-src->tbeg[is])/mod->dt)+1);
}
else {
src->tend[is] = MIN(src->tbeg[is]+(wav->nt-1)*wav->dt,mod->tmod);
wav->nsamp[is] = wav->nt;
}
nsamp += wav->nsamp[is];
if (verbose>3) {
vmess("Random xsrc=%f ysrc=%f zsrc=%f src_tbeg=%f src_tend=%f nsamp=%ld",src->x[is]*dx, src->y[is]*dy, src->z[is]*dz, src->tbeg[is], src->tend[is], wav->nsamp[is]);
}
}
wav->nsamp[nsrc] = nsamp; /* put total number of samples in last position */
wav->nst = nsamp; /* put total number of samples in nst part */
/* write time and length of source signals */
if (verbose>3) {
float *dum;
dum = (float *)calloc(mod->nt, sizeof(float));
for (is=0; is<nsrc; is++) {
dum[(long)floor(src->tbeg[is]/mod->dt)] = src->tend[is]-src->tbeg[is];
}
FILE *fp;
sprintf(tmpname,"srcTimeLengthN=%li.bin",mod->nt);
fp = fopen(tmpname, "w+");
fwrite(dum, sizeof(float), mod->nt, fp);
fclose(fp);
free(dum);
}
}
else if ( (nxsrc != 0) || (src_txt != NULL) ) {
/* source array is defined */
if (src_txt!=NULL) {
/* Sources from a Text File */
/* Open text file */
nsrctext=0;
fp=fopen(src_txt,"r");
assert(fp!=NULL);
/* Get number of lines */
while (!feof(fp)) if (fgetc(fp)=='\n') nsrctext++;
fseek(fp,-1,SEEK_CUR);
if (fgetc(fp)!='\n') nsrctext++; /* Checks if last line terminated by /n */
if (verbose) vmess("Number of sources in src_txt file: %li",nsrctext);
rewind(fp);
nsrc=nsrctext;
}
else {
nsrc=nxsrc;
}
/* Allocate arrays */
src->x = (long *)malloc(nsrc*sizeof(long));
src->y = (long *)malloc(nsrc*sizeof(long));
src->z = (long *)malloc(nsrc*sizeof(long));
src->tbeg = (float *)malloc(nsrc*sizeof(float));
src->tend = (float *)malloc(nsrc*sizeof(float));
xsrca = (float *)malloc(nsrc*sizeof(float));
ysrca = (float *)malloc(nsrc*sizeof(float));
zsrca = (float *)malloc(nsrc*sizeof(float));
if (src_txt!=NULL) {
/* Read in source coordinates */
for (i=0;i<nsrc;i++) {
if (fscanf(fp,"%e %e %e\n",&xsrca[i],&ysrca[i],&zsrca[i])!=3) vmess("Source Text File: Can not parse coordinates on line %li.",i);
}
/* Close file */
fclose(fp);
}
else {
getparfloat("xsrca", xsrca);
getparfloat("ysrca", ysrca);
getparfloat("zsrca", zsrca);
}
/* Process coordinates */
for (is=0; is<nsrc; is++) {
src->x[is] = NINT((xsrca[is]-sub_x0)/dx);
src->y[is] = NINT((ysrca[is]-sub_y0)/dy);
src->z[is] = NINT((zsrca[is]-sub_z0)/dz);
src->tbeg[is] = 0.0;
src->tend[is] = (wav->nt-1)*wav->dt;
if (verbose>3) fprintf(stderr,"Source Array: xsrc[%li]=%f ysrc=%f zsrc=%f\n", is, xsrca[is], ysrca[is], zsrca[is]);
}
src->random = 1;
wav->nsamp = (size_t *)malloc((nsrc+1)*sizeof(size_t));
if (wav->random) {
if (!getparlong("src_multiwav",&src->multiwav)) src->multiwav=1;
if (src->multiwav) wav->nx = nsrc;
else wav->nx = 1;
wav->nt = NINT(tlength/mod->dt)+1;
nsamp=0;
for (is=0; is<nsrc; is++) {
rand = (float)drand48()*tlength;
src->tend[is] = MIN(src->tbeg[is]+rand, mod->tmod);
wav->nsamp[is] = (size_t)(NINT((src->tend[is]-src->tbeg[is])/mod->dt)+1);
nsamp += wav->nsamp[is];
}
wav->nsamp[nsrc] = nsamp; /* put total number of samples in last position */
wav->nst = nsamp; /* put total number of samples in nst part */
}
else {
nsamp=0;
for (is=0; is<nsrc; is++) {
wav->nsamp[is] = wav->nt;
nsamp += wav->nsamp[is];
}
wav->nsamp[nsrc] = nsamp; /* put total number of samples in last position */
wav->nst = nsamp; /* put total number of samples in nst part */
}
free(xsrca);
free(ysrca);
free(zsrca);
}
else if (wav->nx > 1) {
/* read file_src for number of sources and receiver positions */
if (!getparlong("src_multiwav",&src->multiwav)) src->multiwav=1;
float *gx, *sx, *gy, *sy, *gelev, *selev;
gx = (float *)malloc(wav->nx*sizeof(float));
sx = (float *)malloc(wav->nx*sizeof(float));
gy = (float *)malloc(wav->nx*sizeof(float));
sy = (float *)malloc(wav->nx*sizeof(float));
gelev = (float *)malloc(wav->nx*sizeof(float));
selev = (float *)malloc(wav->nx*sizeof(float));
getWaveletHeaders3D(wav->file_src, wav->ns, wav->nx, gx, sx, gy, sy, gelev, selev, verbose);
nsrc = wav->nx;
src->x = (long *)malloc(nsrc*sizeof(long));
src->y = (long *)malloc(nsrc*sizeof(long));
src->z = (long *)malloc(nsrc*sizeof(long));
src->tbeg = (float *)malloc(nsrc*sizeof(float));
src->tend = (float *)malloc(nsrc*sizeof(float));
wav->nsamp = (size_t *)malloc((nsrc+1)*sizeof(size_t));
nsamp=0;
for (is=0; is<nsrc; is++) {
if (src->src_at_rcv>0){
src->x[is] = NINT((gx[is]-sub_x0)/dx);
src->y[is] = NINT((gy[is]-sub_y0)/dy);
src->z[is] = NINT((gelev[is]-sub_z0)/dz);
if (verbose>3) fprintf(stderr,"Source Array: xsrc[%li]=%f %li ysrc=%f %li zsrc=%f %li\n", is, gx[is], src->x[is], gy[is], src->y[is], gelev[is], src->z[is]);
}
else {
src->x[is]=NINT((sx[is]-sub_x0)/dx);
src->y[is]=NINT((sy[is]-sub_y0)/dy);
src->z[is]=NINT((selev[is]-sub_z0)/dz);
if (verbose>3) fprintf(stderr,"Source Array: xsrc[%li]=%f %li ysrc=%f %li zsrc=%f %li\n", is, sx[is], src->x[is], sy[is], src->y[is], selev[is], src->z[is]);
}
src->tbeg[is] = 0.0;
src->tend[is] = (wav->nt-1)*wav->dt;
wav->nsamp[is] = (size_t)(NINT((src->tend[is]-src->tbeg[is])/mod->dt)+1);
nsamp += wav->nsamp[is];
}
wav->nsamp[nsrc] = nsamp; /* put total number of samples in last position */
free(gx);
free(sx);
free(gy);
free(sy);
free(gelev);
free(selev);
}
else {
if (src->plane) {
if (!getparlong("npxsrc",&npxsrc)) npxsrc=1;
if (!getparlong("npysrc",&npysrc)) npysrc=1;
}
else {
npxsrc=1;
npysrc=1;
}
if (npxsrc > nx) {
vwarn("Number of sources used in plane wave (%li) is larger than ",npxsrc);
vwarn("number of gridpoints in X (%li). Plane wave will be clipped to the edges of the model",nx);
npxsrc = mod->nx;
}
if (npysrc > ny) {
vwarn("Number of sources used in plane wave (%li) is larger than ",npysrc);
vwarn("number of gridpoints in Y (%li). Plane wave will be clipped to the edges of the model",ny);
npysrc = mod->ny;
}
nsrc = npxsrc*npysrc;
/* for a source defined on mutliple gridpoint calculate p delay factor */
src->x = (long *)malloc(nsrc*sizeof(long));
src->y = (long *)malloc(nsrc*sizeof(long));
src->z = (long *)malloc(nsrc*sizeof(long));
src->tbeg = (float *)malloc(nsrc*sizeof(float));
src->tend = (float *)malloc(nsrc*sizeof(float));
grad2rad = 17.453292e-3;
px = sin(src_anglex*grad2rad)/src_velox;
py = sin(src_angley*grad2rad)/src_veloy;
if (py < 0.0) {
for (isy=0; isy<npysrc; isy++) {
if (px < 0.0) {
for (isx=0; isx<npxsrc; isx++) {
src->tbeg[isy*npxsrc+isx] = fabsf((npysrc-isy-1)*dy*py) + fabsf((npxsrc-isx-1)*dx*px);
}
}
else {
for (isx=0; isx<npxsrc; isx++) {
src->tbeg[isy*npxsrc+isx] = fabsf((npysrc-isy-1)*dy*py) + isx*dx*px;
}
}
}
}
else {
for (isy=0; isy<npysrc; isy++) {
if (px < 0.0) {
for (isx=0; isx<npxsrc; isx++) {
src->tbeg[isy*npxsrc+isx] = isy*dy*py + fabsf((npxsrc-isx-1)*dx*px);
}
}
else {
for (isx=0; isx<npxsrc; isx++) {
src->tbeg[isy*npxsrc+isx] = isy*dy*py + isx*dx*px;
}
}
}
}
for (is=0; is<nsrc; is++) {
src->tend[is] = src->tbeg[is] + (wav->nt-1)*wav->dt;
}
isx0 = -1*floor((npxsrc-1)/2);
isy0 = -1*floor((npysrc-1)/2);
for (isy=0; isy<npysrc; isy++) {
for (isx=0; isx<npxsrc; isx++) {
src->x[isy*npxsrc+isx] = isx0 + isx;
src->y[isy*npxsrc+isx] = isy0 + isy;
src->z[isy*npxsrc+isx] = 0;
}
}
if (wav->random) {
if (!getparlong("src_multiwav",&src->multiwav)) src->multiwav=1;
if (src->multiwav) wav->nx = nsrc;
else wav->nx = 1;
wav->nt = NINT(tlength/mod->dt)+1;
wav->nsamp = (size_t *)malloc((wav->nx+1)*sizeof(size_t));
nsamp=0;
for (is=0; is<wav->nx; is++) {
rand = (float)drand48()*tlength;
src->tend[is] = MIN(src->tbeg[is]+rand, mod->tmod);
wav->nsamp[is] = (size_t)(NINT((src->tend[is]-src->tbeg[is])/mod->dt)+1);
nsamp += wav->nsamp[is];
}
wav->nsamp[nsrc] = nsamp; /* put total number of samples in last position */
wav->nst = nsamp; /* put total number of samples in nst part */
}
else {
wav->nsamp = (size_t *)malloc((nsrc+1)*sizeof(size_t));
nsamp=0;
for (is=0; is<nsrc; is++) {
wav->nsamp[is] = wav->nt;
nsamp += wav->nsamp[is];
}
wav->nsamp[nsrc] = nsamp; /* put total number of samples in last position */
wav->nst = nsamp; /* put total number of samples in nst part */
}
src->nx = npxsrc;
src->ny = npysrc;
}
if (src->multiwav) {
if (wav->nx != nsrc) {
vwarn("src_multiwav has been defined but number of traces in");
vwarn("file_src = %li is not equal to nsrc = %li", wav->nx, nsrc);
vwarn("last trace in file_src will be repeated.");
}
else {
if (wav->file_src != NULL) vmess("Using all traces in file_src for a real shot");
}
}
src->n=nsrc;
if (verbose) {
vmess("*******************************************");
vmess("************* wavelet info ****************");
vmess("*******************************************");
vmess("wav_nt = %6li wav_nx = %li", wav->ns, wav->nx);
vmess("src_type = %6li src_orient = %li", src->type, src->orient);
vmess("number of sources = %li", shot->n);
vmess("fmax = %8.2f", fmax);
fprintf(stderr," %s: Source type : ",xargv[0]);
switch ( src->type ) {
case 1 : fprintf(stderr,"P "); break;
case 2 : fprintf(stderr,"Txz "); break;
case 3 : fprintf(stderr,"Tzz "); break;
case 4 : fprintf(stderr,"Txx "); break;
case 5 : fprintf(stderr,"S-potential"); break;
case 6 : fprintf(stderr,"Fx "); break;
case 7 : fprintf(stderr,"Fz "); break;
case 8 : fprintf(stderr,"P-potential"); break;
case 9 : fprintf(stderr,"Double-couple"); break;
case 10 : fprintf(stderr,"Moment tensor"); break;
}
fprintf(stderr,"\n");
if (src->type==9) {
Mxx = -1.0*(sin(src->dip)*cos(src->rake)*sin(2.0*src->strike)+sin(src->dip*2.0)*sin(src->rake)*sin(src->strike)*sin(src->strike));
Myy = sin(src->dip)*cos(src->rake)*sin(2.0*src->strike)-sin(src->dip*2.0)*sin(src->rake)*cos(src->strike)*cos(src->strike);
Mzz = sin(src->dip*2.0)*sin(src->rake);
Mxz = -1.0*(cos(src->dip)*cos(src->rake)*cos(src->strike)+cos(src->dip*2.0)*sin(src->rake)*sin(src->strike));
Mxy = sin(src->dip)*cos(src->rake)*cos(src->strike*2.0)+0.5*(sin(src->dip*2.0)*sin(src->rake)*sin(src->strike*2.0));
Myz = -1.0*(cos(src->dip)*cos(src->rake)*sin(src->strike)-cos(src->dip*2.0)*sin(src->rake)*cos(src->strike));
vmess("Strike %.3f (%.2f degrees) Rake %.3f (%.2f degrees) Dip %.3f (%.2f degrees)",src->strike,180.0*src->strike/M_PI,src->rake,180.0*src->rake/M_PI,src->dip,180.0*src->dip/M_PI);
vmess("Mxx %.2f Myy %.2f Mzz %.2f",Mxx,Myy,Mzz);
vmess("Mxy %.2f Mxz %.2f Myz %.2f",Mxy,Mxz,Myz);
}
if (wav->random) vmess("Wavelet has a random signature with fmax=%.2f", wav->fmax);
if (src->n>1) {
vmess("*******************************************");
vmess("*********** source array info *************");
vmess("*******************************************");
vmess("Areal source array is defined with %li sources (x=%li, y=%li).",nsrc,npxsrc,npysrc);
vmess("Memory requirement for sources = %.2f MB.",sizeof(float)*(nsamp/(1024.0*1024.0)));
if (src->plane) vmess("Computed px-value = %f. and py-value = %f",px,py);
}
if (src->random) {
vmess("Sources are placed at random locations in domain: ");
vmess(" x[%.2f : %.2f] y[%.2f : %.2f] z[%.2f : %.2f] ", xsrc1, xsrc2, ysrc1, ysrc2, zsrc1, zsrc2);
vmess(" and all start in time window t[%.3f : %.3f].", tsrc1, tsrc2);
vmess(" after time %.3f the sources will not be active anymore.", tactive);
}
}
/* define snapshots and beams */
if (!getparfloat("tsnap1", &tsnap1)) tsnap1=0.1;
if (!getparfloat("tsnap2", &tsnap2)) tsnap2=0.0;
if (!getparfloat("dtsnap", &dtsnap)) dtsnap=0.1;
if (!getparfloat("dxsnap", &dxsnap)) dxsnap=dx;
if (!getparfloat("dysnap", &dysnap)) dysnap=dy;
if (!getparfloat("dzsnap", &dzsnap)) dzsnap=dz;
if (!getparfloat("xsnap1", &xsnap1)) xsnap1=sub_x0;
if (!getparfloat("xsnap2", &xsnap2)) xsnap2=xmax;
if (!getparfloat("ysnap1", &ysnap1)) ysnap1=sub_y0;
if (!getparfloat("ysnap2", &ysnap2)) ysnap2=ymax;
if (!getparfloat("zsnap1", &zsnap1)) zsnap1=sub_z0;
if (!getparfloat("zsnap2", &zsnap2)) zsnap2=zmax;
if (!getparlong("sna_vxvztime", &sna->vxvztime)) sna->vxvztime=0;
if (!getparlong("beam", &sna->beam)) sna->beam=0;
if (!getparlong("snapwithbnd", &sna->withbnd)) sna->withbnd=0;
if (!getparlong("sna_type_vz", &sna->type.vz)) sna->type.vz=1;
if (!getparlong("sna_type_vy", &sna->type.vy)) sna->type.vy=0;
if (!getparlong("sna_type_vx", &sna->type.vx)) sna->type.vx=0;
if (mod->ischeme>2) {
sna->type.p=0;
if (!getparlong("sna_type_txx", &sna->type.txx)) sna->type.txx=0;
if (!getparlong("sna_type_tyy", &sna->type.tyy)) sna->type.tyy=0;
if (!getparlong("sna_type_tzz", &sna->type.tzz)) sna->type.tzz=0;
if (!getparlong("sna_type_txz", &sna->type.txz)) sna->type.txz=0;
if (!getparlong("sna_type_txy", &sna->type.txy)) sna->type.txy=0;
if (!getparlong("sna_type_tyz", &sna->type.tyz)) sna->type.tyz=0;
if (!getparlong("sna_type_pp", &sna->type.pp)) sna->type.pp=0;
if (!getparlong("sna_type_ss", &sna->type.ss)) sna->type.ss=0;
}
else {
if (!getparlong("sna_type_p", &sna->type.p)) sna->type.p=1;
sna->type.txx=0;
sna->type.tyy=0;
sna->type.tzz=0;
sna->type.txz=0;
sna->type.txy=0;
sna->type.tyz=0;
sna->type.pp=0;
sna->type.ss=0;
}
sna->nsnap = 0;
if (tsnap2 >= tsnap1) {
sna_nrsna = 1+NINT((tsnap2-tsnap1)/dtsnap);
sna->skipdt = MAX(1,NINT(dtsnap/dt));
sna->skipdx = MAX(1,NINT(dxsnap/dx));
sna->skipdy = MAX(1,NINT(dysnap/dy));
sna->skipdz = MAX(1,NINT(dzsnap/dz));
sna->delay = NINT(tsnap1/dt);
isnapmax1 = (sna_nrsna-1)*sna->skipdt;
isnapmax2 = floor( (mod->nt-(sna->delay + 1))/sna->skipdt) * sna->skipdt;
isnapmax = (sna->delay + 1) + MIN(isnapmax1,isnapmax2);
sna->nsnap = floor((isnapmax-(sna->delay + 1))/sna->skipdt) + 1;
sna->x1=NINT((MIN(MAX(sub_x0,xsnap1),xmax)-sub_x0)/dx);
sna->x2=NINT((MIN(MAX(sub_x0,xsnap2),xmax)-sub_x0)/dx);
sna->y1=NINT((MIN(MAX(sub_y0,ysnap1),ymax)-sub_y0)/dy);
sna->y2=NINT((MIN(MAX(sub_y0,ysnap2),ymax)-sub_y0)/dy);
sna->z1=NINT((MIN(MAX(sub_z0,zsnap1),zmax)-sub_z0)/dz);
sna->z2=NINT((MIN(MAX(sub_z0,zsnap2),zmax)-sub_z0)/dz);
dxsnap=dx*sna->skipdx;
dysnap=dy*sna->skipdy;
dzsnap=dz*sna->skipdz;
sna->nx=1+(((sna->x2-sna->x1))/sna->skipdx);
sna->ny=1+(((sna->y2-sna->y1))/sna->skipdy);
sna->nz=1+(((sna->z2-sna->z1))/sna->skipdz);
if (verbose) {
vmess("*******************************************");
vmess("************* snap shot info **************");
vmess("*******************************************");
vmess("tsnap1 = %f tsnap2 = %f ", tsnap1, tsnap2);
vmess("dtsnap = %f Nsnap = %li ", dtsnap, sna->nsnap);
vmess("nzsnap = %li nysnap = %li nxsnap = %li ", sna->nz, sna->ny, sna->nx);
vmess("dzsnap = %f dysnap = %f dxsnap = %f ", dzsnap, dysnap, dxsnap);
vmess("zmin = %f zmax = %f ", sub_z0+dz*sna->z1, sub_z0+dz*sna->z2);
vmess("ymin = %f ymax = %f ", sub_y0+dy*sna->y1, sub_y0+dy*sna->y2);
vmess("xmin = %f xmax = %f ", sub_x0+dx*sna->x1, sub_x0+dx*sna->x2);
if (sna->vxvztime) vmess("vx/vy/vz snapshot time : t+0.5*dt ");
else vmess("vx/vy/vz snapshot time : t-0.5*dt ");
fprintf(stderr," %s: Snapshot types : ",xargv[0]);
if (sna->type.vz) fprintf(stderr,"Vz ");
if (sna->type.vy) fprintf(stderr,"Vy ");
if (sna->type.vx) fprintf(stderr,"Vx ");
if (sna->type.p) fprintf(stderr,"p ");
if (mod->ischeme>2) {
if (sna->type.txx) fprintf(stderr,"Txx ");
if (sna->type.tyy) fprintf(stderr,"Tyy ");
if (sna->type.tzz) fprintf(stderr,"Tzz ");
if (sna->type.txz) fprintf(stderr,"Txz ");
if (sna->type.txy) fprintf(stderr,"Txy ");
if (sna->type.tyz) fprintf(stderr,"Tyz ");
if (sna->type.pp) fprintf(stderr,"P ");
if (sna->type.ss) fprintf(stderr,"S ");
}
fprintf(stderr,"\n");
}
}
else {
sna->nsnap = 0;
if (verbose) vmess("*************** no snapshots **************");
}
if (sna->beam) {
sna->skipdx = MAX(1,NINT(dxsnap/dx));
sna->skipdy = MAX(1,NINT(dysnap/dy));
sna->skipdz = MAX(1,NINT(dzsnap/dz));
sna->x1=NINT((MIN(MAX(sub_x0,xsnap1),xmax)-sub_x0)/dx);
sna->x2=NINT((MIN(MAX(sub_x0,xsnap2),xmax)-sub_x0)/dx);
sna->y1=NINT((MIN(MAX(sub_y0,ysnap1),ymax)-sub_y0)/dy);
sna->y2=NINT((MIN(MAX(sub_y0,ysnap2),ymax)-sub_y0)/dy);
sna->z1=NINT((MIN(MAX(sub_z0,zsnap1),zmax)-sub_z0)/dz);
sna->z2=NINT((MIN(MAX(sub_z0,zsnap2),zmax)-sub_z0)/dz);
dxsnap=dx*sna->skipdx;
dysnap=dy*sna->skipdy;
dzsnap=dz*sna->skipdz;
sna->nx=1+(((sna->x2-sna->x1))/sna->skipdx);
sna->ny=1+(((sna->y2-sna->y1))/sna->skipdy);
sna->nz=1+(((sna->z2-sna->z1))/sna->skipdz);
if (verbose) {
vmess("*******************************************");
vmess("**************** beam info ****************");
vmess("*******************************************");
vmess("nzsnap = %li nysnap =%li nxsnap = %li ", sna->nz, sna->ny, sna->nx);
vmess("dzsnap = %f dysnap = %f dxsnap = %f ", dzsnap, dysnap, dxsnap);
vmess("zmin = %f zmax = %f ", sub_z0+dz*sna->z1, sub_z0+dz*sna->z2);
vmess("ymin = %f ymax = %f ", sub_y0+dy*sna->y1, sub_y0+dy*sna->y2);
vmess("xmin = %f xmax = %f ", sub_x0+dx*sna->x1, sub_x0+dx*sna->x2);
fprintf(stderr," %s: Beam types : ",xargv[0]);
if (sna->type.vz) fprintf(stderr,"Vz ");
if (sna->type.vy) fprintf(stderr,"Vy ");
if (sna->type.vx) fprintf(stderr,"Vx ");
if (sna->type.p) fprintf(stderr,"p ");
if (mod->ischeme>2) {
if (sna->type.txx) fprintf(stderr,"Txx ");
if (sna->type.tyy) fprintf(stderr,"Tyy ");
if (sna->type.tzz) fprintf(stderr,"Tzz ");
if (sna->type.txz) fprintf(stderr,"Txz ");
if (sna->type.txy) fprintf(stderr,"Txy ");
if (sna->type.tyz) fprintf(stderr,"Tyz ");
if (sna->type.pp) fprintf(stderr,"P ");
if (sna->type.ss) fprintf(stderr,"S ");
}
fprintf(stderr,"\n");
}
}
else {
if (verbose) vmess("**************** no beams *****************");
}
/* define receivers */
if (!getparlong("largeSUfile",&largeSUfile)) largeSUfile=0;
if (!getparlong("sinkdepth",&rec->sinkdepth)) rec->sinkdepth=0;
if (!getparlong("sinkdepth_src",&src->sinkdepth)) src->sinkdepth=0;
if (!getparlong("sinkvel",&rec->sinkvel)) rec->sinkvel=0;
if (!getparfloat("dtrcv",&dtrcv)) dtrcv=0.004;
/* TODO check if dtrcv is integer multiple of dt */
rec->skipdt=NINT(dtrcv/dt);
dtrcv = mod->dt*rec->skipdt;
if (!getparfloat("rec_delay",&rdelay)) rdelay=0.0;
if (!getparlong("rec_ntsam",&rec->nt)) rec->nt=NINT((mod->tmod-rdelay)/dtrcv)+1;
if (!getparlong("rec_int_p",&rec->int_p)) rec->int_p=0;
if (!getparlong("rec_int_vx",&rec->int_vx)) rec->int_vx=0;
if (!getparlong("rec_int_vy",&rec->int_vy)) rec->int_vy=0;
if (!getparlong("rec_int_vz",&rec->int_vz)) rec->int_vz=0;
if (!getparlong("max_nrec",&rec->max_nrec)) rec->max_nrec=15000;
if (!getparlong("scale",&rec->scale)) rec->scale=0;
if (!getparfloat("dxspread",&dxspread)) dxspread=0;
if (!getparfloat("dyspread",&dyspread)) dyspread=0;
if (!getparfloat("dzspread",&dzspread)) dzspread=0;
rec->nt=MIN(rec->nt, NINT((mod->tmod-rdelay)/dtrcv)+1);
/* allocation of receiver arrays is done in recvPar */
/* calculates the receiver coordinates */
recvPar3D(rec, sub_x0, sub_y0, sub_z0, dx, dy, dz, nx, ny, nz);
if (!getparlong("rec_type_vz", &rec->type.vz)) rec->type.vz=1;
if (!getparlong("rec_type_vy", &rec->type.vy)) rec->type.vy=0;
if (!getparlong("rec_type_vx", &rec->type.vx)) rec->type.vx=0;
if (!getparlong("rec_type_ud", &rec->type.ud)) rec->type.ud=0;
if (mod->ischeme!=1 && rec->type.ud==1) {
warn("Receiver decomposition only implemented for acoustis scheme (1)");
}
if (mod->ischeme>2) {
rec->type.p=0;
if (!getparlong("rec_type_txx", &rec->type.txx)) rec->type.txx=0;
if (!getparlong("rec_type_tyy", &rec->type.tyy)) rec->type.tyy=0;
if (!getparlong("rec_type_tzz", &rec->type.tzz)) rec->type.tzz=0;
if (!getparlong("rec_type_txz", &rec->type.txz)) rec->type.txz=0;
if (!getparlong("rec_type_txy", &rec->type.txy)) rec->type.txy=0;
if (!getparlong("rec_type_tyz", &rec->type.tyz)) rec->type.tyz=0;
if (!getparlong("rec_type_pp", &rec->type.pp)) rec->type.pp=0;
if (!getparlong("rec_type_ss", &rec->type.ss)) rec->type.ss=0;
/* for up and downgoing waves store all x-positons for Vz, Vx, Txz, Tzz into an array */
}
else {
if (!getparlong("rec_type_p", &rec->type.p)) rec->type.p=1;
rec->type.txx=0;
rec->type.tyy=0;
rec->type.tzz=0;
rec->type.txz=0;
rec->type.txy=0;
rec->type.tyz=0;
rec->type.pp=0;
rec->type.ss=0;
/* for up and downgoing waves store all x-positons for P and Vz into an array */
}
/* receivers are on a circle, use default interpolation to real (not on a grid-point) receiver position */
if (getparfloat("rrcv", &rrcv)) {
if (!getparlong("rec_int_p",&rec->int_p)) rec->int_p=3;
if (!getparlong("rec_int_vx",&rec->int_vx)) rec->int_vx=3;
if (!getparlong("rec_int_vy",&rec->int_vy)) rec->int_vy=3;
if (!getparlong("rec_int_vz",&rec->int_vz)) rec->int_vz=3;
}
if (rec->int_p==3) {
rec->int_vx=3;
rec->int_vy=3;
rec->int_vz=3;
}
if (verbose) {
if (rec->n) {
dxrcv = rec->xr[MIN(1,rec->n-1)]-rec->xr[0];
dyrcv = rec->yr[MIN(1,rec->n-1)]-rec->yr[0];
dzrcv = rec->zr[MIN(1,rec->n-1)]-rec->zr[0];
vmess("*******************************************");
vmess("************* receiver info ***************");
vmess("*******************************************");
vmess("ntrcv = %li nrcv = %li ", rec->nt, rec->n);
vmess("dtrcv = %f ", dtrcv );
vmess("dzrcv = %f dyrcv = %f dxrcv = %f ", dzrcv, dyrcv, dxrcv);
vmess("time-delay = %f = points = %li", rdelay, rec->delay);
if ( fmax > (1.0/(2.0*dtrcv)) ) {
vwarn("Receiver time sampling (dtrcv) is aliased.");
vwarn("time sampling should be < %.6f", 1.0/(2.0*fmax) );
}
vmess("Receiver sampling can be => %.6e", 1.0/(2.0*fmax));
vmess("Receiver array at coordinates: ");
vmess("zmin = %f zmax = %f ", rec->zr[0]+sub_z0, rec->zr[rec->n-1]+sub_z0);
vmess("ymin = %f ymax = %f ", rec->yr[0]+sub_y0, rec->yr[rec->n-1]+sub_y0);
vmess("xmin = %f xmax = %f ", rec->xr[0]+sub_x0, rec->xr[rec->n-1]+sub_x0);
vmess("which are gridpoints: ");
vmess("izmin = %li izmax = %li ", rec->z[0], rec->z[rec->n-1]);
vmess("iymin = %li iymax = %li ", rec->y[0], rec->y[rec->n-1]);
vmess("ixmin = %li ixmax = %li ", rec->x[0], rec->x[rec->n-1]);
if (rec->type.p) {
fprintf(stderr," %s: Receiver interpolation for P: ",xargv[0]);
if(rec->int_p==0) fprintf(stderr,"p->p\n");
if(rec->int_p==1) fprintf(stderr,"p->vz\n");
if(rec->int_p==2) fprintf(stderr,"p->vx\n");
if(rec->int_p==3) fprintf(stderr,"interpolate to actual (no-grid) position of receiver\n");
}
if (rec->type.vx) {
fprintf(stderr," %s: Receiver interpolation for Vx: ",xargv[0]);
if(rec->int_vx==0) fprintf(stderr,"vx->vx\n");
if(rec->int_vx==1) fprintf(stderr,"vx->vz\n");
if(rec->int_vx==2) fprintf(stderr,"vx->txx/tzz\n");
if(rec->int_vx==3) fprintf(stderr,"interpolate to real(no-grid) position of receiver\n");
}
if (rec->type.vy) {
fprintf(stderr," %s: Receiver interpolation for Vx: ",xargv[0]);
if(rec->int_vy==0) fprintf(stderr,"vy->vy\n");
if(rec->int_vy==1) fprintf(stderr,"vy->vz\n");
if(rec->int_vy==2) fprintf(stderr,"vy->tyy/tzz\n");
if(rec->int_vy==3) fprintf(stderr,"interpolate to real(no-grid) position of receiver\n");
}
if (rec->type.vz) {
fprintf(stderr," %s: Receiver interpolation for Vz: ",xargv[0]);
if(rec->int_vz==0) fprintf(stderr,"vz->vz\n");
if(rec->int_vz==1) fprintf(stderr,"vz->vx\n");
if(rec->int_vz==2) fprintf(stderr,"vz->txx/tzz(P)\n");
if(rec->int_vz==3) fprintf(stderr,"interpolate to real(no-grid) position of receiver\n");
}
fprintf(stderr," %s: Receiver types : ",xargv[0]);
if (rec->type.vz) fprintf(stderr,"Vz ");
if (rec->type.vy) fprintf(stderr,"Vy ");
if (rec->type.vx) fprintf(stderr,"Vx ");
if (rec->type.p) fprintf(stderr,"p ");
if (rec->type.ud) fprintf(stderr,"P+ P- ");
if (mod->ischeme>2) {
if (rec->type.txx) fprintf(stderr,"Txx ");
if (rec->type.tyy) fprintf(stderr,"Tyy ");
if (rec->type.tzz) fprintf(stderr,"Tzz ");
if (rec->type.txz) fprintf(stderr,"Txz ");
if (rec->type.txy) fprintf(stderr,"Txy ");
if (rec->type.tyz) fprintf(stderr,"Tyz ");
if (rec->type.pp) fprintf(stderr,"P ");
if (rec->type.ss) fprintf(stderr,"S ");
}
fprintf(stderr,"\n");
if ( ( ((mod->nt*mod->dt-rec->delay)/rec->skipdt)+1) > 16384) {
vwarn("Number of samples in receiver file is larger that SU can handle ");
vwarn("use the paramater rec_ntsam=nt (with nt < 16384) to avoid this");
}
if ((mod->nt-rec->delay)*mod->dt > rec->nt*dtrcv) {
long nfiles = ceil((mod->nt*mod->dt)/(rec->nt*dtrcv));
long lastn = floor((mod->nt)%(rec->nt*rec->skipdt)/rec->skipdt)+1;
vmess("Receiver recordings will be written to %li files",nfiles);
vmess("Last file will contain %li samples",lastn);
}
}
else {
vmess("*************** no receivers **************");
}
}
return 0;
}