From 40b281c5f78b0f7e6cef7292708c32b17f654bf8 Mon Sep 17 00:00:00 2001 From: "joeri.brackenhoff" <joeri.brackenhoff@login0.ogun.local> Date: Thu, 14 Mar 2019 10:47:56 -0300 Subject: [PATCH] 3D --- fdelmodc3D/acoustic4_3D.c | 174 +++ fdelmodc3D/applySource3D.c | 365 ++++++ fdelmodc3D/boundaries3D.c | 2253 +++++++++++++++++++++++++++++++++ fdelmodc3D/fdelmodc3D.c | 32 +- fdelmodc3D/getRecTimes3D.c | 324 +++++ fdelmodc3D/writeSrcRecPos3D.c | 160 +++ fdelmodc3D/writesufile3D.c | 162 +++ 7 files changed, 3449 insertions(+), 21 deletions(-) create mode 100644 fdelmodc3D/acoustic4_3D.c create mode 100644 fdelmodc3D/applySource3D.c create mode 100644 fdelmodc3D/boundaries3D.c create mode 100644 fdelmodc3D/getRecTimes3D.c create mode 100644 fdelmodc3D/writeSrcRecPos3D.c create mode 100644 fdelmodc3D/writesufile3D.c diff --git a/fdelmodc3D/acoustic4_3D.c b/fdelmodc3D/acoustic4_3D.c new file mode 100644 index 0000000..453d59f --- /dev/null +++ b/fdelmodc3D/acoustic4_3D.c @@ -0,0 +1,174 @@ +#include<stdlib.h> +#include<stdio.h> +#include<math.h> +#include<assert.h> +#include"fdelmodc3D.h" + +#define MIN(x,y) ((x) < (y) ? (x) : (y)) + +long applySource(modPar mod, srcPar src, wavPar wav, bndPar bnd, long itime, long ixsrc, long izsrc, float *vx, float *vz, float *tzz, float *txx, float *txz, float *rox, float *roz, float *l2m, float **src_nwav, long verbose); + +long storeSourceOnSurface(modPar mod, srcPar src, bndPar bnd, long ixsrc, long izsrc, float *vx, float *vz, float *tzz, float *txx, float *txz, long verbose); + +long reStoreSourceOnSurface(modPar mod, srcPar src, bndPar bnd, long ixsrc, long izsrc, float *vx, float *vz, float *tzz, float *txx, float *txz, long verbose); + +long boundariesP(modPar mod, bndPar bnd, float *vx, float *vz, float *tzz, float *txx, float *txz, float *rox, float *roz, float *l2m, float *lam, float *mul, long itime, long verbose); + +long boundariesV(modPar mod, bndPar bnd, float *vx, float *vz, float *tzz, float *txx, float *txz, float *rox, float *roz, float *l2m, float *lam, float *mul, long itime, long verbose); + +long acoustic4_3D(modPar mod, srcPar src, wavPar wav, bndPar bnd, long itime, long ixsrc, long iysrc, long izsrc, float **src_nwav, float *vx, float *vy, float *vz, float *p, float *rox, float *roy, float *roz, float *l2m, long verbose) +{ +/********************************************************************* + COMPUTATIONAL OVERVIEW OF THE 4th ORDER STAGGERED GRID: + + The captial symbols T (=P) Txz,Vx,Vz represent the actual grid + The indices ix,iz are related to the T grid, so the capital T + symbols represent the actual modelled grid. + + one cel (iz,ix) + | + V extra column of vx,txz + | + ------- V + | txz vz| txz vz txz vz txz vz txz vz txz vz txz + | | + | vx t | vx t vx t vx t vx t vx t vx + ------- + txz vz txz vz txz vz txz vz txz vz txz vz txz + + vx t vx T---Vx--T---Vx--T---Vx--T vx t vx + | | | | | | | + txz vz txz Vz--Txz-Vz--Txz-Vz Txz-Vz txz vz txz + | | | | | | | + vx t vx T---Vx--T---Vx--T---Vx--T vx t vx + | | | | | | | + txz vz txz Vz Txz-Vz Txz-Vz Txz-Vz txz vz txz + | | | | | | | + vx t vx T---Vx--T---Vx--T---Vx--T vx t vx + | | | | | | | + txz vz txz Vz Txz-Vz Txz-Vz Txz-Vz txz vz txz + | | | | | | | + vx t vx T---Vx--T---Vx--T---Vx--T vx t vx + + txz vz txz vz txz vz txz vz txz vz txz vz txz + + vx t vx t vx t vx t vx t vx t vx + + txz vz txz vz txz vz txz vz txz vz txz vz txz <--| + | + extra row of txz/vz | + + AUTHOR: + Jan Thorbecke (janth@xs4all.nl) + The Netherlands + +***********************************************************************/ + + float c1, c2; + long ix, iy, iz; + long n1, n2; + long ioXx, ioXy, ioXz, ioYx, ioYy, ioYz, ioZx, ioZy, ioZz, ioPx, ioPy, ioPz; + + c1 = 9.0/8.0; + c2 = -1.0/24.0; + n1 = mod.naz; + n2 = mod.nay; + + /* calculate vx for all grid points except on the virtual boundary*/ +#pragma omp for private (ix, iy, iz) nowait schedule(guided,1) + for (iy=mod.ioXy; iy<mod.ieXy; iy++) { +#pragma ivdep + for (ix=mod.ioXx; ix<mod.ieXx; ix++) { + for (iz=mod.ioXz; iz<mod.ieXz; iz++) { + vx[iy*n2*n1+ix*n1+iz] -= rox[iy*n2*n1+ix*n1+iz]*( + c1*(p[iy*n2*n1+ix*n1+iz] - p[iy*n2*n1+(ix-1)*n1+iz]) + + c2*(p[iy*n2*n1+(ix+1)*n1+iz] - p[iy*n2*n1+(ix-2)*n1+iz])); + } + } + } + + /* calculate vy for all grid points except on the virtual boundary*/ +#pragma omp for private (ix, iy, iz) nowait schedule(guided,1) + for (iy=mod.ioYy; iy<mod.ieYy; iy++) { +#pragma ivdep + for (ix=mod.ioYx; ix<mod.ieYx; ix++) { + for (iz=mod.ioYz; iz<mod.ieYz; iz++) { + vy[iy*n2*n1+ix*n1+iz] -= roy[iy*n2*n1+ix*n1+iz]*( + c1*(p[iy*n2*n1+ix*n1+iz] - p[(iy-1)*n2*n1+ix*n1+iz]) + + c2*(p[(iy+1)*n2*n1+ix*n1+iz] - p[(iy-2)*n2*n1+ix*n1+iz])); + } + } + } + + /* calculate vz for all grid points except on the virtual boundary */ +#pragma omp for private (ix, iy, iz) schedule(guided,1) + for (iy=mod.ioZy; iy<mod.ieZy; iy++) { +#pragma ivdep + for (ix=mod.ioZx; ix<mod.ieZx; ix++) { + for (iz=mod.ioZz; iz<mod.ieZz; iz++) { + vz[iy*n2*n1+ix*n1+iz] -= roz[iy*n2*n1+ix*n1+iz]*( + c1*(p[iy*n2*n1+ix*n1+iz] - p[iy*n2*n1+ix*n1+iz-1]) + + c2*(p[iy*n2*n1+ix*n1+iz+1] - p[iy*n2*n1+ix*n1+iz-2])); + } + } + } + + /* boundary condition clears velocities on boundaries */ + boundariesP3D(mod, bnd, vx, vy, vz, p, NULL, NULL, NULL, NULL, NULL, rox, roy, roz, l2m, NULL, NULL, itime, verbose); + + /* Add force source */ + if (src.type > 5) { + applySource3D(mod, src, wav, bnd, itime, ixsrc, iysrc, izsrc, vx, vy, vz, p, NULL, NULL, NULL, NULL, NULL, rox, roy, roz, l2m, src_nwav, verbose); + } + + /* this is needed because the P fields are not using tapered boundaries (bnd....=4) */ + if (bnd.top==2) mod.ioPz += bnd.npml; + if (bnd.bot==2) mod.iePz -= bnd.npml; + if (bnd.fro==2) mod.ioPy += bnd.npml; + if (bnd.bac==2) mod.iePy -= bnd.npml; + if (bnd.lef==2) mod.ioPx += bnd.npml; + if (bnd.rig==2) mod.iePx -= bnd.npml; + + /* calculate p/tzz for all grid points except on the virtual boundary */ +#pragma omp for private (ix, iy, iz) schedule(guided,1) +//#pragma omp for private (ix, iz) schedule(dynamic) +#pragma ivdep + for (ix=mod.ioPx; ix<mod.iePx; ix++) { +#pragma ivdep + for (iy=mod.ioPy; iy<mod.iePy; iy++) { + for (iz=mod.ioPz; iz<mod.iePz; iz++) { + p[iy*n1*n2+ix*n1+iz] -= l2m[iy*n1*n2+ix*n1+iz]*( + c1*(vx[iy*n1*n2+(ix+1)*n1+iz] - vx[iy*n1*n2+ix*n1+iz]) + + c2*(vx[iy*n1*n2+(ix+2)*n1+iz] - vx[iy*n1*n2+(ix-1)*n1+iz]) + + c1*(vy[(iy+1)*n1*n2+ix*n1+iz] - vy[iy*n1*n2+ix*n1+iz]) + + c2*(vy[(iy+2)*n1*n2+ix*n1+iz] - vy[(iy-1)*n1*n2+ix*n1+iz]) + + c1*(vz[iy*n1*n2+ix*n1+iz+1] - vz[iy*n1*n2+ix*n1+iz]) + + c2*(vz[iy*n1*n2+ix*n1+iz+2] - vz[iy*n1*n2+ix*n1+iz-1])); + } + } + } + if (bnd.top==2) mod.ioPz -= bnd.npml; + if (bnd.bot==2) mod.iePz += bnd.npml; + if (bnd.fro==2) mod.ioPy -= bnd.npml; + if (bnd.bac==2) mod.iePy += bnd.npml; + if (bnd.lef==2) mod.ioPx -= bnd.npml; + if (bnd.rig==2) mod.iePx += bnd.npml; + + /* Add stress source */ + if (src.type < 6) { + applySource3D(mod, src, wav, bnd, itime, ixsrc, iysrc, izsrc, vx, vy, vz, p, NULL, NULL, NULL, NULL, NULL, rox, roy, roz, l2m, src_nwav, verbose); + } + +/* Free surface: calculate free surface conditions for stresses */ + + /* check if there are sources placed on the free surface */ + storeSourceOnSurface3D(mod, src, bnd, ixsrc, iysrc, izsrc, vx, vy, vz, p, NULL, NULL, NULL, NULL, NULL, verbose); + + /* Free surface: calculate free surface conditions for stresses */ + boundariesV3D(mod, bnd, vx, vy, vz, p, NULL, NULL, NULL, NULL, NULL, rox, roy, roz, l2m, NULL, NULL, itime, verbose); + + /* restore source positions on the edge */ + reStoreSourceOnSurface3D(mod, src, bnd, ixsrc, iysrc, izsrc, vx, vy, vz, p, NULL, NULL, NULL, NULL, NULL, verbose); + + return 0; +} diff --git a/fdelmodc3D/applySource3D.c b/fdelmodc3D/applySource3D.c new file mode 100644 index 0000000..80298b3 --- /dev/null +++ b/fdelmodc3D/applySource3D.c @@ -0,0 +1,365 @@ +#include<stdlib.h> +#include<stdio.h> +#include<math.h> +#include<assert.h> +#include"fdelmodc3D.h" + +void vmess(char *fmt, ...); + +#define c1 (9.0/8.0) +#define c2 (-1.0/24.0) + +/********************************************************************* + * + * Add's the source amplitude(s) to the grid. + * + * For the acoustic schemes, the source-type must not be txx tzz or txz. + * + * AUTHOR: + * Jan Thorbecke (janth@xs4all.nl) + * The Netherlands + * + **********************************************************************/ + +long applySource3D(modPar mod, srcPar src, wavPar wav, bndPar bnd, long itime, long ixsrc, long iysrc, long izsrc, float *vx, float *vy, float *vz, float *tzz, float *tyy, float *txx, float *txz, float *txy, float *tyz, float *rox, float *roy, float *roz, float *l2m, float **src_nwav, long verbose) +{ + long is0, ibndz, ibndy, ibndx; + long isrc, ix, iy, iz, n1, n2; + long id1, id2, id3; + float src_ampl, time, scl, dt, sdx; + float Mxx, Myy, Mzz, Mxz, Myz, Mxy, rake; + static long first=1; + + if (src.type==6) { + ibndz = mod.ioXz; + ibndy = mod.ioXy; + ibndx = mod.ioXx; + } + else if (src.type==7) { + ibndz = mod.ioZz; + ibndy = mod.ioZy; + ibndx = mod.ioZx; + } + else if (src.type==2) { + ibndz = mod.ioTz; + ibndy = mod.ioTy; + ibndx = mod.ioTx; + if (bnd.lef==4 || bnd.lef==2) ibndx += bnd.ntap; + if (bnd.bac==4 || bnd.fro==2) ibndy += bnd.ntap; + if (bnd.top==4 || bnd.top==2) ibndz += bnd.ntap; + } + else { + ibndz = mod.ioPz; + ibndy = mod.ioPy; + ibndx = mod.ioPx; + if (bnd.lef==4 || bnd.lef==2) ibndx += bnd.ntap; + if (bnd.bac==4 || bnd.fro==2) ibndy += bnd.ntap; + if (bnd.top==4 || bnd.top==2) ibndz += bnd.ntap; + } + + n1 = mod.naz; + n2 = mod.nax; + dt = mod.dt; + sdx = 1.0/mod.dx; + + /* special txz source activated? */ + + if ((bnd.top==1) && (src.type==2)) { + iz = izsrc + ibndz; + if (iz==ibndz) { + if (src.orient != 1) { + if (first) { + vmess("Only monopole Txz source allowed at surface. Reset to monopole"); + first = 0; + } + src.orient=1; + } + } + } + +/* +* for plane wave sources the sources are placed +* around the central shot position +* the first source position has an offset in x of is0 +* +* itime = 0 corresponds with time=0 +* itime = 1 corresponds with time=dt +* src[0] (the first sample) corresponds with time = 0 +*/ + + is0 = -1*floor((src.n-1)/2); +#pragma omp for private (isrc, src_ampl, ix, iy, iz, time, id1, id2, id3, scl) + for (isrc=0; isrc<src.n; isrc++) { + src_ampl=0.0; + /* calculate the source position */ + if (src.random || src.multiwav) { + ix = src.x[isrc] + ibndx; + iy = src.y[isrc] + ibndy; + iz = src.z[isrc] + ibndz; + } + else { /* plane wave and point sources */ + ix = ixsrc + ibndx + is0 + isrc; + iy = iysrc + ibndy + is0 + isrc; + iz = izsrc + ibndz; + } + time = itime*dt - src.tbeg[isrc]; + id1 = floor(time/dt); + id2 = id1+1; + + /* delay not reached or no samples left in source wavelet? */ + if ( (time < 0.0) || ( (itime*dt) >= src.tend[isrc]) ) continue; + +// fprintf(stderr,"isrc=%li ix=%li iz=%li src.x=%li src.z=%li\n", isrc, ix, iz, src.x[isrc], src.z[isrc]); + + if (!src.multiwav) { /* only one wavelet for all sources */ + src_ampl = src_nwav[0][id1]*(id2-time/dt) + src_nwav[0][id2]*(time/dt-id1); + } + else { /* multi-wavelet sources */ + src_ampl = src_nwav[isrc][id1]*(id2-time/dt) + src_nwav[isrc][id2]*(time/dt-id1); + } + + if (src_ampl==0.0) continue; + if ( ((ix-ibndx)<0) || ((ix-ibndx)>mod.nx) ) continue; /* source outside grid */ + if ( ((iy-ibndy)<0) || ((iy-ibndy)>mod.ny) ) continue; /* source outside grid */ + + if (verbose>=4 && itime==0) { + vmess("Source %li positioned at grid ix=%li iy=%li iz=%li",isrc, ix, iy, iz); + } + + /* cosine squared windowing to reduce edge effects on shot arrays */ + if ( (src.n>1) && src.window) { + scl = 1.0; + if (isrc < src.window) { + scl = cos(0.5*M_PI*(src.window - isrc)/src.window); + } + else if (isrc > src.n-src.window+1) { + scl = cos(0.5*M_PI*(src.window - (src.n-isrc+1))/src.window); + } + src_ampl *= scl*scl; + } + + /* source scaling factor to compensate for discretisation */ + + /* old amplitude setting does not obey reciprocity */ + // src_ampl *= rox[ix*n1+iz]*l2m[ix*n1+iz]/(dt); + +/* in older version added factor 2.0 to be compliant with defined Green's functions in Marchenko algorithm */ +/* this is now set to 1.0 */ + src_ampl *= (1.0/mod.dx)*l2m[iy*n1*n2+ix*n1+iz]; + + if (verbose>5) { + vmess("Source %li at grid [ix=%li,iy=%li,iz=%li] at itime %li has value %e",isrc, ix, iy, iz, itime, src_ampl); + } + + /* Force source */ + + if (src.type == 6) { + vx[iy*n1*n2+ix*n1+iz] += src_ampl*rox[iy*n1*n2+ix*n1+iz]/(l2m[iy*n1*n2+ix*n1+iz]); + /* stable implementation from "Numerical Techniques for Conservation Laws with Source Terms" by Justin Hudson */ + //vx[ix*n1+iz] = 0.5*(vx[(ix+1)*n1+iz]+vx[(ix-1)*n1+iz])+src_ampl*rox[ix*n1+iz]/(l2m[ix*n1+iz]); + } + else if (src.type == 7) { + vz[iy*n1*n2+ix*n1+iz] += src_ampl*roz[iy*n1*n2+ix*n1+iz]/(l2m[iy*n1*n2+ix*n1+iz]); + /* stable implementation from "Numerical Techniques for Conservation Laws with Source Terms" by Justin Hudson */ + /* stable implementation changes amplitude and more work is needed */ + //vz[ix*n1+iz] = 0.5*(vz[ix*n1+iz-1]+vz[ix*n1+iz+1])+src_ampl*roz[ix*n1+iz]/(l2m[ix*n1+iz]); + //vz[ix*n1+iz] = 0.25*(vz[ix*n1+iz-2]+vz[ix*n1+iz-1]+vz[ix*n1+iz]+vz[ix*n1+iz+1])+src_ampl*roz[ix*n1+iz]/(l2m[ix*n1+iz]); + } /* src.type */ + + + /* Stress source */ + + if (mod.ischeme <= 2) { /* Acoustic scheme */ + /* Compressional source */ + if (src.type == 1) { + if (src.orient != 1) src_ampl=src_ampl/mod.dx; + + if (src.orient==1) { /* monopole */ + tzz[iy*n1*n2+ix*n1+iz] += src_ampl; + } + else if (src.orient==2) { /* dipole +/- */ + tzz[iy*n1*n2+ix*n1+iz] += src_ampl; + tzz[iy*n1*n2+ix*n1+iz+1] -= src_ampl; + } + else if (src.orient==3) { /* dipole - + */ + tzz[iy*n1*n2+ix*n1+iz] += src_ampl; + tzz[iy*n1*n2+(ix-1)*n1+iz] -= src_ampl; + } + else if (src.orient==4) { /* dipole +/0/- */ + if (iz > ibndz) + tzz[iy*n1*n2+ix*n1+iz-1]+= 0.5*src_ampl; + if (iz < mod.nz+ibndz-1) + tzz[iy*n1*n2+ix*n1+iz+1] -= 0.5*src_ampl; + } + else if (src.orient==5) { /* dipole + - */ + tzz[iy*n1*n2+ix*n1+iz] += src_ampl; + tzz[iy*n1*n2+(ix+1)*n1+iz] -= src_ampl; + } + } + } + else { /* Elastic scheme */ + /* Compressional source */ + if (src.type == 1) { + if (src.orient==1) { /* monopole */ + txx[iy*n1*n2+ix*n1+iz] += src_ampl; + tzz[iy*n1*n2+ix*n1+iz] += src_ampl; + } + else if (src.orient==2) { /* dipole +/- */ + txx[iy*n1*n2+ix*n1+iz] += src_ampl; + tzz[iy*n1*n2+ix*n1+iz] += src_ampl; + txx[iy*n1*n2+ix*n1+iz+1] -= src_ampl; + tzz[iy*n1*n2+ix*n1+iz+1] -= src_ampl; + } + else if (src.orient==3) { /* dipole - + */ + txx[iy*n1*n2+ix*n1+iz] += src_ampl; + tzz[iy*n1*n2+ix*n1+iz] += src_ampl; + txx[iy*n1*n2+(ix-1)*n1+iz] -= src_ampl; + tzz[iy*n1*n2+(ix-1)*n1+iz] -= src_ampl; + } + else if (src.orient==4) { /* dipole +/0/- */ + if (iz > ibndz) { + txx[iy*n1*n2+ix*n1+iz-1]+= 0.5*src_ampl; + tzz[iy*n1*n2+ix*n1+iz-1]+= 0.5*src_ampl; + } + if (iz < mod.nz+ibndz-1) { + txx[iy*n1*n2+ix*n1+iz+1] -= 0.5*src_ampl; + tzz[iy*n1*n2+ix*n1+iz+1] -= 0.5*src_ampl; + } + } + else if (src.orient==5) { /* dipole + - */ + txx[iy*n1*n2+ix*n1+iz] += src_ampl; + tzz[iy*n1*n2+ix*n1+iz] += src_ampl; + txx[iy*n1*n2+(ix+1)*n1+iz] -= src_ampl; + tzz[iy*n1*n2+(ix+1)*n1+iz] -= src_ampl; + } + } + else if (src.type == 2) { + /* Txz source */ + if ((iz == ibndz) && bnd.top==1) { + txz[iy*n1*n2+(ix-1)*n1+iz-1] += src_ampl; + txz[iy*n1*n2+ix*n1+iz-1] += src_ampl; + } + else { + txz[iy*n1*n2+ix*n1+iz] += src_ampl; + } + /* possible dipole orientations for a txz source */ + if (src.orient == 2) { /* dipole +/- */ + txz[iy*n1*n2+ix*n1+iz+1] -= src_ampl; + } + else if (src.orient == 3) { /* dipole - + */ + txz[iy*n1*n2+(ix-1)*n1+iz] -= src_ampl; + } + else if (src.orient == 4) { /* dipole +/O/- */ + /* correction: subtrace previous value to prevent z-1 values. */ + txz[iy*n1*n2+ix*n1+iz] -= 2.0*src_ampl; + txz[iy*n1*n2+ix*n1+iz+1] += src_ampl; + } + else if (src.orient == 5) { /* dipole + - */ + txz[iy*n1*n2+(ix+1)*n1+iz] -= src_ampl; + } + } + /* Tzz source */ + else if(src.type == 3) { + tzz[iy*n1*n2+ix*n1+iz] += src_ampl; + } + /* Txx source */ + else if(src.type == 4) { + txx[iy*n1*n2+ix*n1+iz] += src_ampl; + } + +/*********************************************************************** +* pure potential shear S source (experimental) +* Curl S-pot = CURL(F) = dF_x/dz - dF_z/dx +***********************************************************************/ + else if(src.type == 5) { + src_ampl = src_ampl*rox[iy*n1*n2+ix*n1+iz]/(l2m[iy*n1*n2+ix*n1+iz]); + if (src.orient == 3) src_ampl = -src_ampl; + /* first order derivatives */ + vx[iy*n1*n2+ix*n1+iz] += src_ampl*sdx; + vx[(iy-1)*n1*n2+ix*n1+iz-1] -= src_ampl*sdx; + vy[iy*n1*n2+ix*n1+iz] += src_ampl*sdx; + vy[iy*n1*n2+(ix-1)*n1+iz-1] -= src_ampl*sdx; + vz[iy*n1*n2+ix*n1+iz] -= src_ampl*sdx; + vz[(iy-1)*n1*n2+(ix-1)*n1+iz] += src_ampl*sdx; + + /* second order derivatives */ + /* + vx[ix*n1+iz] += c1*src_ampl*sdx; + vx[ix*n1+iz-1] -= c1*src_ampl*sdx; + vx[ix*n1+iz+1] += c2*src_ampl*sdx; + vx[ix*n1+iz-2] -= c2*src_ampl*sdx; + + vz[ix*n1+iz] -= c1*src_ampl*sdx; + vz[(ix-1)*n1+iz] += c1*src_ampl*sdx; + vz[(ix+1)*n1+iz] -= c2*src_ampl*sdx; + vz[(ix-2)*n1+iz] += c2*src_ampl*sdx; + */ + + /* determine second position of dipole */ + if (src.orient == 2) { /* dipole +/- vertical */ + iz += 1; + vx[iy*n1*n2+ix*n1+iz] -= src_ampl*sdx; + vx[(iy-1)*n1*n2+ix*n1+iz-1] += src_ampl*sdx; + vy[iy*n1*n2+ix*n1+iz] -= src_ampl*sdx; + vy[iy*n1*n2+(ix-1)*n1+iz-1] += src_ampl*sdx; + vz[iy*n1*n2+ix*n1+iz] += src_ampl*sdx; + vz[(iy-1)*n1*n2+(ix-1)*n1+iz] -= src_ampl*sdx; + } + else if (src.orient == 3) { /* dipole - + horizontal */ + ix += 1; + vx[iy*n1*n2+ix*n1+iz] -= src_ampl*sdx; + vx[(iy-1)*n1*n2+ix*n1+iz-1] += src_ampl*sdx; + vy[iy*n1*n2+ix*n1+iz] -= src_ampl*sdx; + vy[iy*n1*n2+(ix-1)*n1+iz-1] += src_ampl*sdx; + vz[iy*n1*n2+ix*n1+iz] += src_ampl*sdx; + vz[(iy-1)*n1*n2+(ix-1)*n1+iz] -= src_ampl*sdx; + } + } +/*********************************************************************** +* pure potential pressure P source (experimental) +* Divergence P-pot = DIV(F) = dF_x/dx + dF_z/dz +***********************************************************************/ + else if(src.type == 8) { + src_ampl = src_ampl*rox[iy*n1*n2+ix*n1+iz]/(l2m[iy*n1*n2+ix*n1+iz]); + if (src.orient == 3) src_ampl = -src_ampl; + vx[iy*n1*n2+(ix+1)*n1+iz] += src_ampl*sdx; + vx[iy*n1*n2+ix*n1+iz] -= src_ampl*sdx; + vy[(iy+1)*n1*n2+ix*n1+iz] += src_ampl*sdx; + vy[iy*n1*n2+ix*n1+iz] -= src_ampl*sdx; + vz[iy*n1*n2+ix*n1+iz+1] += src_ampl*sdx; + vz[iy*n1*n2+ix*n1+iz] -= src_ampl*sdx; + /* determine second position of dipole */ + if (src.orient == 2) { /* dipole +/- */ + iz += 1; + vx[iy*n1*n2+(ix+1)*n1+iz] -= src_ampl*sdx; + vx[iy*n1*n2+ix*n1+iz] += src_ampl*sdx; + vy[(iy+1)*n1*n2+ix*n1+iz] -= src_ampl*sdx; + vy[iy*n1*n2+ix*n1+iz] += src_ampl*sdx; + vz[iy*n1*n2+ix*n1+iz+1] -= src_ampl*sdx; + vz[iy*n1*n2+ix*n1+iz] += src_ampl*sdx; + } + else if (src.orient == 3) { /* dipole - + */ + ix += 1; + vx[iy*n1*n2+(ix+1)*n1+iz] -= src_ampl*sdx; + vx[iy*n1*n2+ix*n1+iz] += src_ampl*sdx; + vy[(iy+1)*n1*n2+ix*n1+iz] -= src_ampl*sdx; + vy[iy*n1*n2+ix*n1+iz] += src_ampl*sdx; + vz[iy*n1*n2+ix*n1+iz+1] -= src_ampl*sdx; + vz[iy*n1*n2+ix*n1+iz] += src_ampl*sdx; + } + } + else if(src.type == 9) { + rake = 0.5*M_PI; + Mxx = -1.0*(sin(src.dip)*cos(rake)*sin(2.0*src.strike)+sin(src.dip*2.0)*sin(rake)*sin(src.strike)*sin(src.strike)); + Mxz = -1.0*(cos(src.dip)*cos(rake)*cos(src.strike)+cos(src.dip*2.0)*sin(rake)*sin(src.strike)); + Mzz = sin(src.dip*2.0)*sin(rake); + + txx[iy*n1*n2+ix*n1+iz] -= Mxx*src_ampl; + tzz[iy*n1*n2+ix*n1+iz] -= Mzz*src_ampl; + txz[iy*n1*n2+ix*n1+iz] -= Mxz*src_ampl; + } /* src.type */ + } /* ischeme */ + } /* loop over isrc */ + + return 0; +} diff --git a/fdelmodc3D/boundaries3D.c b/fdelmodc3D/boundaries3D.c new file mode 100644 index 0000000..3f4f555 --- /dev/null +++ b/fdelmodc3D/boundaries3D.c @@ -0,0 +1,2253 @@ +#include<stdlib.h> +#include<stdio.h> +#include<math.h> +#include<assert.h> +#include"fdelmodc3D.h" + +void vmess(char *fmt, ...); + +long boundariesP3D(modPar mod, bndPar bnd, float *vx, float *vy, float *vz, float *tzz, float *tyy, float *txx, float *txz, float *txy, float *tyz, float *rox, float *roy, float *roz, float *l2m, float *lam, float *mul, long itime, long verbose) +{ +/********************************************************************* + + AUTHOR: + Jan Thorbecke (janth@xs4all.nl) + The Netherlands + +***********************************************************************/ + + float c1, c2; + float dp, dvx, dvy, dvz; + long ix, iy, iz, ixs, iys, izs, ibnd, ib, ibx, iby, ibz; + long nx, ny, nz, n1, n2, n3; + long is0, isrc; + long ixo, ixe, iyo, iye, izo, ize; + long npml, ipml, pml; + float kappu, alphu, sigmax, R, a, m, fac, dx, dy, dt; + float dpx, dpy, dpz, *p; + static float *Vxpml, *Vypml, *Vzpml, *sigmu, *RA; + static long allocated=0; + float Jx, Jy, Jz, rho, d; + + c1 = 9.0/8.0; + c2 = -1.0/24.0; + nx = mod.nx; + ny = mod.ny; + nz = mod.nz; + n1 = mod.naz; + n2 = mod.nax; + n3 = mod.nay; + dx = mod.dx; + dy = mod.dy; + dt = mod.dt; + fac = dt/dx; + if ( (bnd.top==2) || (bnd.bot==2) || (bnd.lef==2) || (bnd.rig==2) ) pml=1; + else pml=0; + + ibnd = mod.iorder/2-1; + + if (mod.ischeme <= 2) { /* Acoustic scheme */ + if (bnd.top==1) { /* free surface at top */ +#pragma omp for private (ix,iy) nowait + for (iy=mod.ioPy; iy<mod.iePy; iy++) { + for (ix=mod.ioPx; ix<mod.iePx; ix++) { + iz = bnd.surface[ix]; + vz[iy*n2*n1+ix*n1+iz] = vz[iy*n2*n1+ix*n1+iz+1]; + vz[iy*n2*n1+ix*n1+iz-1] = vz[iy*n2*n1+ix*n1+iz+2]; + } + } + } + } + +/************************************************************/ +/* rigid boundary condition clears velocities on boundaries */ +/************************************************************/ + + if (bnd.top==3) { /* rigid surface at top */ +#pragma omp for private (ix, iy, iz) nowait +#pragma ivdep + for (iy=1; iy<=ny; iy++) { + for (ix=1; ix<=nx; ix++) { + vx[iy*n2*n1+ix*n1+ibnd] = 0.0; + vy[iy*n2*n1+ix*n1+ibnd] = 0.0; + vz[iy*n2*n1+ix*n1+ibnd] = -vz[iy*n2*n1+ix*n1+ibnd+1]; + if (mod.iorder >= 4) vz[iy*n2*n1+ix*n1+ibnd-1] = -vz[iy*n2*n1+ix*n1+ibnd+2]; + if (mod.iorder >= 6) vz[iy*n2*n1+ix*n1+ibnd-2] = -vz[iy*n2*n1+ix*n1+ibnd+3]; + } + } + } + if (bnd.rig==3) { /* rigid surface at right */ +#pragma omp for private (ix, iy, iz) nowait +#pragma ivdep + for (iy=1; iy<=ny; iy++) { + for (iz=1; iz<=nz; iz++) { + vz[iy*n2*n1+(nx+ibnd-1)*n1+iz] = 0.0; + vy[iy*n2*n1+(nx+ibnd-1)*n1+iz] = 0.0; + vx[iy*n2*n1+(nx+ibnd)*n1+iz] = -vx[iy*n2*n1+(nx+ibnd-1)*n1+iz]; + if (mod.iorder == 4) vx[iy*n2*n1+(nx+2)*n1+iz] = -vx[iy*n2*n1+(nx-1)*n1+iz]; + if (mod.iorder == 6) { + vx[iy*n2*n1+(nx+1)*n1+iz] = -vx[iy*n2*n1+(nx)*n1+iz]; + vx[iy*n2*n1+(nx+3)*n1+iz] = -vx[iy*n2*n1+(nx-2)*n1+iz]; + } + } + } + }if (bnd.bac==3) { /* rigid surface at back */ +#pragma omp for private (ix, iy, iz) nowait +#pragma ivdep + for (ix=1; ix<=nx; ix++) { + for (iz=1; iz<=nz; iz++) { + vz[(ny+ibnd-1)*n2*n1+ix*n1+iz] = 0.0; + vx[(ny+ibnd-1)*n2*n1+ix*n1+iz] = 0.0; + vy[(ny+ibnd)*n2*n1+ix*n1+iz] = -vy[(ny+ibnd-1)*n2*n1+ix*n1+iz]; + if (mod.iorder == 4) vy[(ny+2)*n2*n1+ix*n1+iz] = -vy[(ny-1)*n2*n1+iy*n1+iz]; + if (mod.iorder == 6) { + vy[(ny+1)*n2*n1+ix*n1+iz] = -vy[ny*n2*n1+ix*n1+iz]; + vy[(ny+3)*n2*n1+ix*n1+iz] = -vy[(ny-2)*n2*n1+ix*n1+iz]; + } + } + } + } + if (bnd.bot==3) { /* rigid surface at bottom */ +#pragma omp for private (ix, iy, iz) nowait +#pragma ivdep + for (iy=1; iy<=ny; iy++) { + for (ix=1; ix<=nx; ix++) { + vx[iy*n2*n1+ix*n1+nz+ibnd-1] = 0.0; + vy[iy*n2*n1+ix*n1+nz+ibnd-1] = 0.0; + vz[iy*n2*n1+ix*n1+nz+ibnd] = -vz[iy*n2*n1+ix*n1+nz+ibnd-1]; + if (mod.iorder == 4) vz[iy*n2*n1+ix*n1+nz+2] = -vz[iy*n2*n1+ix*n1+nz-1]; + if (mod.iorder == 6) { + vz[iy*n2*n1+ix*n1+nz+1] = -vz[iy*n2*n1+ix*n1+nz]; + vz[iy*n2*n1+ix*n1+nz+3] = -vz[iy*n2*n1+ix*n1+nz-2]; + } + } + } + } + if (bnd.lef==3) { /* rigid surface at left */ +#pragma omp for private (ix, iy, iz) nowait +#pragma ivdep + for (iy=1; iy<=ny; iy++) { + for (iz=1; iz<=nz; iz++) { + vz[iy*n2*n1+ibnd*n1+iz] = 0.0; + vy[iy*n2*n1+ibnd*n1+iz] = 0.0; + vx[iy*n2*n1+ibnd*n1+iz] = -vx[iy*n2*n1+(ibnd+1)*n1+iz]; + if (mod.iorder == 4) vx[iy*n2*n1+0*n1+iz] = -vx[iy*n2*n1+3*n1+iz]; + if (mod.iorder == 6) { + vx[iy*n2*n1+1*n1+iz] = -vx[iy*n2*n1+4*n1+iz]; + vx[iy*n2*n1+0*n1+iz] = -vx[iy*n2*n1+5*n1+iz]; + } + } + } + } + if (bnd.fro==3) { /* rigid surface at front */ +#pragma omp for private (ix, iy, iz) nowait +#pragma ivdep + for (ix=1; ix<=nx; ix++) { + for (iz=1; iz<=nz; iz++) { + vz[ibnd*n2*n1+ix*n1+iz] = 0.0; + vx[ibnd*n2*n1+ix*n1+iz] = 0.0; + vy[ibnd*n2*n1+ix*n1+iz] = -vy[(ibnd+1)*n2*n1+ix*n1+iz]; + if (mod.iorder == 4) vy[0*n2*n1+ix*n1+iz] = -vy[3*n2*n1+ix*n1+iz]; + if (mod.iorder == 6) { + vy[1*n2*n1+ix*n1+iz] = -vy[4*n2*n1+ix*n1+iz]; + vy[0*n2*n1+ix*n1+iz] = -vy[5*n2*n1+ix*n1+iz]; + } + } + } + } + +/************************************************************/ +/* Tapered boundaries for both elastic and acoustic schemes */ +/* compute all field values in tapered areas */ +/************************************************************/ + + /*********/ + /* Top */ + /*********/ + if (bnd.top==4) { + + if (mod.ischeme <= 2) { /* Acoustic scheme */ + + /* Vx field */ + ixo = mod.ioXx; + ixe = mod.ieXx; + iyo = mod.ioXy; + iye = mod.ieXy; + izo = mod.ioXz-bnd.ntap; + ize = mod.ioXz; + + ibz = (bnd.ntap+izo-1); +#pragma omp for private(ix,iy,iz) + for (ix=ixo; ix<ixe; ix++) { +#pragma ivdep + for (iy=iyo; iy<iye; iy++) { + for (iz=izo; iz<ize; iz++) { + vx[iy*n1*n2+ix*n1+iz] -= rox[iy*n1*n2+ix*n1+iz]*( + c1*(tzz[iy*n1*n2+ix*n1+iz] - tzz[iy*n1*n2+(ix-1)*n1+iz]) + + c2*(tzz[iy*n1*n2+(ix+1)*n1+iz] - tzz[iy*n1*n2+(ix-2)*n1+iz])); + + vx[iy*n1*n2+ix*n1+iz] *= bnd.tapx[ibz-iz]; + } + } + } + /* right top corner */ + if (bnd.rig==4) { + ixo = mod.ieXx; + ixe = ixo+bnd.ntap; + ibz = (bnd.ntap+izo-1); + ibx = (ixo); +#pragma omp for private(ix,iy,iz) + for (ix=ixo; ix<ixe; ix++) { +#pragma ivdep + for (iy=iyo; iy<iye; iy++) { + for (iz=izo; iz<ize; iz++) { + vx[iy*n1*n2+ix*n1+iz] -= rox[iy*n1*n2+ix*n1+iz]*( + c1*(tzz[iy*n1*n2+ix*n1+iz] - tzz[iy*n1*n2+(ix-1)*n1+iz]) + + c2*(tzz[iy*n1*n2+(ix+1)*n1+iz] - tzz[iy*n1*n2+(ix-2)*n1+iz])); + + vx[iy*n1*n2+ix*n1+iz] *= bnd.tapxz[(ix-ibx)*bnd.ntap+(ibz-iz)]; + } + } + } + /* right top front corner */ + if (bnd.fro==4) { + iyo = mod.ioXy-bnd.ntap; + iye = mod.ioXy; + iby = (bnd.ntap+iyo-1); +#pragma omp for private(ix,iy,iz) + for (ix=ixo; ix<ixe; ix++) { +#pragma ivdep + for (iy=iyo; iy<iye; iy++) { + for (iz=izo; iz<ize; iz++) { + vx[iy*n1*n2+ix*n1+iz] -= rox[iy*n1*n2+ix*n1+iz]*( + c1*(tzz[iy*n1*n2+ix*n1+iz] - tzz[iy*n1*n2+(ix-1)*n1+iz]) + + c2*(tzz[iy*n1*n2+(ix+1)*n1+iz] - tzz[iy*n1*n2+(ix-2)*n1+iz])); + + vx[iy*n1*n2+ix*n1+iz] *= bnd.tapxyz[(iby-iy)*bnd.ntap*bnd.ntap+(ix-ibx)*bnd.ntap+(ibz-iz)]; + } + } + } + } + /* right top back corner */ + if (bnd.bac==4) { + iyo = mod.ieXy; + iye = mod.ieXy+bnd.ntap; + iby = (iyo); +#pragma omp for private(ix,iy,iz) + for (ix=ixo; ix<ixe; ix++) { +#pragma ivdep + for (iy=iyo; iy<iye; iy++) { + for (iz=izo; iz<ize; iz++) { + vx[iy*n1*n2+ix*n1+iz] -= rox[iy*n1*n2+ix*n1+iz]*( + c1*(tzz[iy*n1*n2+ix*n1+iz] - tzz[iy*n1*n2+(ix-1)*n1+iz]) + + c2*(tzz[iy*n1*n2+(ix+1)*n1+iz] - tzz[iy*n1*n2+(ix-2)*n1+iz])); + + vx[iy*n1*n2+ix*n1+iz] *= bnd.tapxyz[(iy-iby)*bnd.ntap*bnd.ntap+(ix-ibx)*bnd.ntap+(ibz-iz)]; + } + } + } + } + } + ixo = mod.ioXx; + ixe = mod.ieXx; + iyo = mod.ioXy; + iye = mod.ieXy; + izo = mod.ioXz-bnd.ntap; + ize = mod.ioXz; + + /* left top corner */ + if (bnd.lef==4) { + ixo = mod.ioXx-bnd.ntap; + ixe = mod.ioXx; + ibz = (bnd.ntap+izo-1); + ibx = (bnd.ntap+ixo-1); +#pragma omp for private(ix,iy,iz) + for (ix=ixo; ix<ixe; ix++) { +#pragma ivdep + for (iy=iyo; iy<iye; iy++) { + for (iz=izo; iz<ize; iz++) { + vx[iy*n1*n2+ix*n1+iz] -= rox[iy*n1*n2+ix*n1+iz]*( + c1*(tzz[iy*n1*n2+ix*n1+iz] - tzz[iy*n1*n2+(ix-1)*n1+iz]) + + c2*(tzz[iy*n1*n2+(ix+1)*n1+iz] - tzz[iy*n1*n2+(ix-2)*n1+iz])); + + vx[iy*n1*n2+ix*n1+iz] *= bnd.tapxz[(ibx-ix)*bnd.ntap+(ibz-iz)]; + } + } + } + /* left top front corner */ + if (bnd.fro==4) { + iyo = mod.ioXy-bnd.ntap; + iye = mod.ioXy; + iby = (bnd.ntap+iyo-1); +#pragma omp for private(ix,iy,iz) + for (ix=ixo; ix<ixe; ix++) { +#pragma ivdep + for (iy=iyo; iy<iye; iy++) { + for (iz=izo; iz<ize; iz++) { + vx[iy*n1*n2+ix*n1+iz] -= rox[iy*n1*n2+ix*n1+iz]*( + c1*(tzz[iy*n1*n2+ix*n1+iz] - tzz[iy*n1*n2+(ix-1)*n1+iz]) + + c2*(tzz[iy*n1*n2+(ix+1)*n1+iz] - tzz[iy*n1*n2+(ix-2)*n1+iz])); + + vx[iy*n1*n2+ix*n1+iz] *= bnd.tapxyz[(iby-iy)*bnd.ntap*bnd.ntap+(ibx-ix)*bnd.ntap+(ibz-iz)]; + } + } + } + } + /* left top back corner */ + if (bnd.bac==4) { + iyo = mod.ieXy; + iye = mod.ieXy+bnd.ntap; + iby = (iyo); +#pragma omp for private(ix,iy,iz) + for (ix=ixo; ix<ixe; ix++) { +#pragma ivdep + for (iy=iyo; iy<iye; iy++) { + for (iz=izo; iz<ize; iz++) { + vx[iy*n1*n2+ix*n1+iz] -= rox[iy*n1*n2+ix*n1+iz]*( + c1*(tzz[iy*n1*n2+ix*n1+iz] - tzz[iy*n1*n2+(ix-1)*n1+iz]) + + c2*(tzz[iy*n1*n2+(ix+1)*n1+iz] - tzz[iy*n1*n2+(ix-2)*n1+iz])); + + vx[iy*n1*n2+ix*n1+iz] *= bnd.tapxyz[(iy-iby)*bnd.ntap*bnd.ntap+(ibx-ix)*bnd.ntap+(ibz-iz)]; + } + } + } + } + } + /* front top corner */ + if (bnd.fro==4) { + ixo = mod.ioXx; + ixe = mod.ieXx; + iyo = mod.ioXy-bnd.ntap; + iye = mod.ioXy; + ibz = (bnd.ntap+izo-1); + iby = (bnd.ntap+iyo-1); +#pragma omp for private(ix,iy,iz) + for (ix=ixo; ix<ixe; ix++) { +#pragma ivdep + for (iy=iyo; iy<iye; iy++) { + for (iz=izo; iz<ize; iz++) { + vx[iy*n1*n2+ix*n1+iz] -= rox[iy*n1*n2+ix*n1+iz]*( + c1*(tzz[iy*n1*n2+ix*n1+iz] - tzz[iy*n1*n2+(ix-1)*n1+iz]) + + c2*(tzz[iy*n1*n2+(ix+1)*n1+iz] - tzz[iy*n1*n2+(ix-2)*n1+iz])); + + vx[iy*n1*n2+ix*n1+iz] *= bnd.tapxz[(iby-iy)*bnd.ntap+(ibz-iz)]; + } + } + } + } + /* Back top corner */ + if (bnd.bac==4) { + iyo = mod.ieXy; + iye = mod.ioXy+bnd.ntap; + ibz = (bnd.ntap+izo-1); + iby = (iyo); +#pragma omp for private(ix,iy,iz) + for (ix=ixo; ix<ixe; ix++) { +#pragma ivdep + for (iy=iyo; iy<iye; iy++) { + for (iz=izo; iz<ize; iz++) { + vx[iy*n1*n2+ix*n1+iz] -= rox[iy*n1*n2+ix*n1+iz]*( + c1*(tzz[iy*n1*n2+ix*n1+iz] - tzz[iy*n1*n2+(ix-1)*n1+iz]) + + c2*(tzz[iy*n1*n2+(ix+1)*n1+iz] - tzz[iy*n1*n2+(ix-2)*n1+iz])); + + vx[iy*n1*n2+ix*n1+iz] *= bnd.tapxz[(iy-iby)*bnd.ntap+(ibz-iz)]; + } + } + } + } + + /* Vy field */ + ixo = mod.ioYx; + ixe = mod.ieYx; + iyo = mod.ioYy; + iye = mod.ieYy; + izo = mod.ioYz-bnd.ntap; + ize = mod.ioYz; + + ib = (bnd.ntap+izo-1); +#pragma omp for private(ix,iy,iz) + for (ix=ixo; ix<ixe; ix++) { +#pragma ivdep + for (iy=iyo; iy<iye; iy++) { + for (iz=izo; iz<ize; iz++) { + vy[iy*n1*n2+ix*n1+iz] -= roy[iy*n1*n2+ix*n1+iz]*( + c1*(tzz[iy*n1*n2+ix*n1+iz] - tzz[(iy-1)*n1*n2+ix*n1+iz]) + + c2*(tzz[(iy+1)*n1*n2+ix*n1+iz] - tzz[(iy-2)*n1*n2+ix*n1+iz])); + + vy[iy*n1*n2+ix*n1+iz] *= bnd.tapy[ib-iz]; + } + } + } + /* right top corner */ + if (bnd.rig==4) { + ixo = mod.ieYx; + ixe = ixo+bnd.ntap; + ibz = (bnd.ntap+izo-1); + ibx = (ixo); +#pragma omp for private(ix,iy,iz) + for (ix=ixo; ix<ixe; ix++) { +#pragma ivdep + for (iy=iyo; iy<iye; iy++) { + for (iz=izo; iz<ize; iz++) { + vy[iy*n1*n2+ix*n1+iz] -= roy[iy*n1*n2+ix*n1+iz]*( + c1*(tzz[iy*n1*n2+ix*n1+iz] - tzz[(iy-1)*n1*n2+ix*n1+iz]) + + c2*(tzz[(iy+1)*n1*n2+ix*n1+iz] - tzz[(iy-2)*n1*n2+ix*n1+iz])); + + vy[iy*n1*n2+ix*n1+iz] *= bnd.tapxz[(ix-ibx)*bnd.ntap+(ibz-iz)]; + } + } + } + /* right top front corner */ + if (bnd.fro==4) { + iyo = mod.ioYy-bnd.ntap; + iye = mod.ioYy; + iby = (bnd.ntap+iyo-1); +#pragma omp for private(ix,iy,iz) + for (ix=ixo; ix<ixe; ix++) { +#pragma ivdep + for (iy=iyo; iy<iye; iy++) { + for (iz=izo; iz<ize; iz++) { + vy[iy*n1*n2+ix*n1+iz] -= roy[iy*n1*n2+ix*n1+iz]*( + c1*(tzz[iy*n1*n2+ix*n1+iz] - tzz[(iy-1)*n1*n2+ix*n1+iz]) + + c2*(tzz[(iy+1)*n1*n2+ix*n1+iz] - tzz[(iy-2)*n1*n2+ix*n1+iz])); + + vy[iy*n1*n2+ix*n1+iz] *= bnd.tapxyz[(iby-iy)*bnd.ntap*bnd.ntap+(ix-ibx)*bnd.ntap+(ibz-iz)]; + } + } + } + } + /* right top back corner */ + if (bnd.bac==4) { + iyo = mod.ieYy; + iye = mod.ieYy+bnd.ntap; + iby = (iyo); +#pragma omp for private(ix,iy,iz) + for (ix=ixo; ix<ixe; ix++) { +#pragma ivdep + for (iy=iyo; iy<iye; iy++) { + for (iz=izo; iz<ize; iz++) { + vy[iy*n1*n2+ix*n1+iz] -= roy[iy*n1*n2+ix*n1+iz]*( + c1*(tzz[iy*n1*n2+ix*n1+iz] - tzz[(iy-1)*n1*n2+ix*n1+iz]) + + c2*(tzz[(iy+1)*n1*n2+ix*n1+iz] - tzz[(iy-2)*n1*n2+ix*n1+iz])); + + vy[iy*n1*n2+ix*n1+iz] *= bnd.tapxyz[(iy-iby)*bnd.ntap*bnd.ntap+(ix-ibx)*bnd.ntap+(ibz-iz)]; + } + } + } + } + } + ixo = mod.ioYx; + ixe = mod.ieYx; + iyo = mod.ioYy; + iye = mod.ieYy; + izo = mod.ioYz-bnd.ntap; + ize = mod.ioYz; + + /* left top corner */ + if (bnd.lef==4) { + ixo = mod.ioYx-bnd.ntap; + ixe = mod.ioYx; + ibz = (bnd.ntap+izo-1); + ibx = (bnd.ntap+ixo-1); +#pragma omp for private(ix,iy,iz) + for (ix=ixo; ix<ixe; ix++) { +#pragma ivdep + for (iy=iyo; iy<iye; iy++) { + for (iz=izo; iz<ize; iz++) { + vy[iy*n1*n2+ix*n1+iz] -= roy[iy*n1*n2+ix*n1+iz]*( + c1*(tzz[iy*n1*n2+ix*n1+iz] - tzz[(iy-1)*n1*n2+ix*n1+iz]) + + c2*(tzz[(iy+1)*n1*n2+ix*n1+iz] - tzz[(iy-2)*n1*n2+ix*n1+iz])); + + vy[iy*n1*n2+ix*n1+iz] *= bnd.tapxz[(ibx-ix)*bnd.ntap+(ibz-iz)]; + } + } + } + /* left top front corner */ + if (bnd.fro==4) { + iyo = mod.ioYy-bnd.ntap; + iye = mod.ioYy; + iby = (bnd.ntap+iyo-1); +#pragma omp for private(ix,iy,iz) + for (ix=ixo; ix<ixe; ix++) { +#pragma ivdep + for (iy=iyo; iy<iye; iy++) { + for (iz=izo; iz<ize; iz++) { + vy[iy*n1*n2+ix*n1+iz] -= roy[iy*n1*n2+ix*n1+iz]*( + c1*(tzz[iy*n1*n2+ix*n1+iz] - tzz[(iy-1)*n1*n2+ix*n1+iz]) + + c2*(tzz[(iy+1)*n1*n2+ix*n1+iz] - tzz[(iy-2)*n1*n2+ix*n1+iz])); + + vy[iy*n1*n2+ix*n1+iz] *= bnd.tapxyz[(iby-iy)*bnd.ntap*bnd.ntap+(ibx-ix)*bnd.ntap+(ibz-iz)]; + } + } + } + } + /* left top back corner */ + if (bnd.bac==4) { + iyo = mod.ieYy; + iye = mod.ieYy+bnd.ntap; + iby = (iyo); +#pragma omp for private(ix,iy,iz) + for (ix=ixo; ix<ixe; ix++) { +#pragma ivdep + for (iy=iyo; iy<iye; iy++) { + for (iz=izo; iz<ize; iz++) { + vy[iy*n1*n2+ix*n1+iz] -= roy[iy*n1*n2+ix*n1+iz]*( + c1*(tzz[iy*n1*n2+ix*n1+iz] - tzz[(iy-1)*n1*n2+ix*n1+iz]) + + c2*(tzz[(iy+1)*n1*n2+ix*n1+iz] - tzz[(iy-2)*n1*n2+ix*n1+iz])); + + vy[iy*n1*n2+ix*n1+iz] *= bnd.tapxyz[(iy-iby)*bnd.ntap*bnd.ntap+(ibx-ix)*bnd.ntap+(ibz-iz)]; + } + } + } + } + } + /* front top corner */ + if (bnd.fro==4) { + ixo = mod.ioXx; + ixe = mod.ieXx; + iyo = mod.ioXy-bnd.ntap; + iye = mod.ioXy; + ibz = (bnd.ntap+izo-1); + iby = (bnd.ntap+iyo-1); +#pragma omp for private(ix,iy,iz) + for (ix=ixo; ix<ixe; ix++) { +#pragma ivdep + for (iy=iyo; iy<iye; iy++) { + for (iz=izo; iz<ize; iz++) { + vy[iy*n1*n2+ix*n1+iz] -= roy[iy*n1*n2+ix*n1+iz]*( + c1*(tzz[iy*n1*n2+ix*n1+iz] - tzz[(iy-1)*n1*n2+ix*n1+iz]) + + c2*(tzz[(iy+1)*n1*n2+ix*n1+iz] - tzz[(iy-2)*n1*n2+ix*n1+iz])); + + vy[iy*n1*n2+ix*n1+iz] *= bnd.tapxz[(iby-iy)*bnd.ntap+(ibz-iz)]; + } + } + } + } + /* Back top corner */ + if (bnd.bac==4) { + iyo = mod.ieXy; + iye = mod.ioXy+bnd.ntap; + ibz = (bnd.ntap+izo-1); + iby = (iyo); +#pragma omp for private(ix,iy,iz) + for (ix=ixo; ix<ixe; ix++) { +#pragma ivdep + for (iy=iyo; iy<iye; iy++) { + for (iz=izo; iz<ize; iz++) { + vy[iy*n1*n2+ix*n1+iz] -= roy[iy*n1*n2+ix*n1+iz]*( + c1*(tzz[iy*n1*n2+ix*n1+iz] - tzz[(iy-1)*n1*n2+ix*n1+iz]) + + c2*(tzz[(iy+1)*n1*n2+ix*n1+iz] - tzz[(iy-2)*n1*n2+ix*n1+iz])); + + vy[iy*n1*n2+ix*n1+iz] *= bnd.tapxz[(iy-iby)*bnd.ntap+(ibz-iz)]; + } + } + } + } + + + /* Vz field */ + ixo = mod.ioZx; + ixe = mod.ieZx; + iyo = mod.ioZy; + iye = mod.ieZy; + izo = mod.ioZz-bnd.ntap; + ize = mod.ioZz; + + ib = (bnd.ntap+izo-1); +#pragma omp for private (ix, iy, iz) + for (ix=ixo; ix<ixe; ix++) { +#pragma ivdep + for (iy=iyo; iy<iye; iy++) { + for (iz=izo; iz<ize; iz++) { + vz[iy*n1*n2+ix*n1+iz] -= roz[iy*n1*n2+ix*n1+iz]*( + c1*(tzz[iy*n1*n2+ix*n1+iz] - tzz[iy*n1*n2+ix*n1+iz-1]) + + c2*(tzz[iy*n1*n2+ix*n1+iz+1] - tzz[iy*n1*n2+ix*n1+iz-2])); + + vz[iy*n1*n2+ix*n1+iz] *= bnd.tapz[ib-iz]; + } + } + } + /* right top corner */ + if (bnd.rig==4) { + ixo = mod.ieZx; + ixe = ixo+bnd.ntap; + ibz = (bnd.ntap+izo-1); + ibx = (ixo); +#pragma omp for private(ix,iz) + for (ix=ixo; ix<ixe; ix++) { +#pragma ivdep + for (iy=iyo; iy<iye; iy++) { + for (iz=izo; iz<ize; iz++) { + vz[iy*n1*n2+ix*n1+iz] -= roz[iy*n1*n2+ix*n1+iz]*( + c1*(tzz[iy*n1*n2+ix*n1+iz] - tzz[iy*n1*n2+ix*n1+iz-1]) + + c2*(tzz[iy*n1*n2+ix*n1+iz+1] - tzz[iy*n1*n2+ix*n1+iz-2])); + + vz[iy*n1*n2+ix*n1+iz] *= bnd.tapxz[(ix-ibx)*bnd.ntap+(ibz-iz)]; + } + } + } + /* right top front corner */ + if (bnd.fro==4) { + iyo = mod.ioZy-bnd.ntap; + iye = mod.ioZy; + iby = (bnd.ntap+iyo-1); +#pragma omp for private(ix,iy,iz) + for (ix=ixo; ix<ixe; ix++) { +#pragma ivdep + for (iy=iyo; iy<iye; iy++) { + for (iz=izo; iz<ize; iz++) { + vz[iy*n1*n2+ix*n1+iz] -= roz[iy*n1*n2+ix*n1+iz]*( + c1*(tzz[iy*n1*n2+ix*n1+iz] - tzz[iy*n1*n2+ix*n1+iz-1]) + + c2*(tzz[iy*n1*n2+ix*n1+iz+1] - tzz[iy*n1*n2+ix*n1+iz-2])); + + vz[iy*n1*n2+ix*n1+iz] *= bnd.tapxyz[(iby-iy)*bnd.ntap*bnd.ntap+(ix-ibx)*bnd.ntap+(ibz-iz)]; + } + } + } + } + /* right top back corner */ + if (bnd.bac==4) { + iyo = mod.ieZy; + iye = mod.ieZy+bnd.ntap; + iby = (iyo); +#pragma omp for private(ix,iy,iz) + for (ix=ixo; ix<ixe; ix++) { +#pragma ivdep + for (iy=iyo; iy<iye; iy++) { + for (iz=izo; iz<ize; iz++) { + vz[iy*n1*n2+ix*n1+iz] -= roz[iy*n1*n2+ix*n1+iz]*( + c1*(tzz[iy*n1*n2+ix*n1+iz] - tzz[iy*n1*n2+ix*n1+iz-1]) + + c2*(tzz[iy*n1*n2+ix*n1+iz+1] - tzz[iy*n1*n2+ix*n1+iz-2])); + + vz[iy*n1*n2+ix*n1+iz] *= bnd.tapxyz[(iy-iby)*bnd.ntap*bnd.ntap+(ix-ibx)*bnd.ntap+(ibz-iz)]; + } + } + } + } + } + + ixo = mod.ioZx; + ixe = mod.ieZx; + iyo = mod.ioZy; + iye = mod.ieZy; + izo = mod.ioZz-bnd.ntap; + ize = mod.ioZz; + + /* left top corner */ + if (bnd.lef==4) { + ixo = mod.ioZx-bnd.ntap; + ixe = mod.ioZx; + ibz = (bnd.ntap+izo-1); + ibx = (bnd.ntap+ixo-1); +#pragma omp for private(ix,iy,iz) + for (ix=ixo; ix<ixe; ix++) { +#pragma ivdep + for (iz=izo; iz<ize; iz++) { + vz[iy*n1*n2+ix*n1+iz] -= roz[iy*n1*n2+ix*n1+iz]*( + c1*(tzz[iy*n1*n2+ix*n1+iz] - tzz[iy*n1*n2+ix*n1+iz-1]) + + c2*(tzz[iy*n1*n2+ix*n1+iz+1] - tzz[iy*n1*n2+ix*n1+iz-2])); + + vz[iy*n1*n2+ix*n1+iz] *= bnd.tapxz[(ibx-ix)*bnd.ntap+(ibz-iz)]; + } + } + /* left top front corner */ + if (bnd.fro==4) { + iyo = mod.ioZy-bnd.ntap; + iye = mod.ioZy; + iby = (bnd.ntap+iyo-1); +#pragma omp for private(ix,iy,iz) + for (ix=ixo; ix<ixe; ix++) { +#pragma ivdep + for (iy=iyo; iy<iye; iy++) { + for (iz=izo; iz<ize; iz++) { + vz[iy*n1*n2+ix*n1+iz] -= roz[iy*n1*n2+ix*n1+iz]*( + c1*(tzz[iy*n1*n2+ix*n1+iz] - tzz[iy*n1*n2+ix*n1+iz-1]) + + c2*(tzz[iy*n1*n2+ix*n1+iz+1] - tzz[iy*n1*n2+ix*n1+iz-2])); + + vz[iy*n1*n2+ix*n1+iz] *= bnd.tapxyz[(iby-iy)*bnd.ntap*bnd.ntap+(ibx-ix)*bnd.ntap+(ibz-iz)]; + } + } + } + } + /* left top back corner */ + if (bnd.bac==4) { + iyo = mod.ieZy; + iye = mod.ieZy+bnd.ntap; + iby = (iyo); +#pragma omp for private(ix,iy,iz) + for (ix=ixo; ix<ixe; ix++) { +#pragma ivdep + for (iy=iyo; iy<iye; iy++) { + for (iz=izo; iz<ize; iz++) { + vz[iy*n1*n2+ix*n1+iz] -= roz[iy*n1*n2+ix*n1+iz]*( + c1*(tzz[iy*n1*n2+ix*n1+iz] - tzz[iy*n1*n2+ix*n1+iz-1]) + + c2*(tzz[iy*n1*n2+ix*n1+iz+1] - tzz[iy*n1*n2+ix*n1+iz-2])); + + vz[iy*n1*n2+ix*n1+iz] *= bnd.tapxyz[(iy-iby)*bnd.ntap*bnd.ntap+(ibx-ix)*bnd.ntap+(ibz-iz)]; + } + } + } + } + } + /* front top corner */ + if (bnd.fro==4) { + ixo = mod.ioXx; + ixe = mod.ieXx; + iyo = mod.ioXy-bnd.ntap; + iye = mod.ioXy; + ibz = (bnd.ntap+izo-1); + iby = (bnd.ntap+iyo-1); +#pragma omp for private(ix,iy,iz) + for (ix=ixo; ix<ixe; ix++) { +#pragma ivdep + for (iy=iyo; iy<iye; iy++) { + for (iz=izo; iz<ize; iz++) { + vz[iy*n1*n2+ix*n1+iz] -= roz[iy*n1*n2+ix*n1+iz]*( + c1*(tzz[iy*n1*n2+ix*n1+iz] - tzz[iy*n1*n2+ix*n1+iz-1]) + + c2*(tzz[iy*n1*n2+ix*n1+iz+1] - tzz[iy*n1*n2+ix*n1+iz-2])); + + vz[iy*n1*n2+ix*n1+iz] *= bnd.tapxz[(iby-iy)*bnd.ntap+(ibz-iz)]; + } + } + } + } + /* Back top corner */ + if (bnd.bac==4) { + iyo = mod.ieXy; + iye = mod.ioXy+bnd.ntap; + ibz = (bnd.ntap+izo-1); + iby = (iyo); +#pragma omp for private(ix,iy,iz) + for (ix=ixo; ix<ixe; ix++) { +#pragma ivdep + for (iy=iyo; iy<iye; iy++) { + for (iz=izo; iz<ize; iz++) { + vz[iy*n1*n2+ix*n1+iz] -= roz[iy*n1*n2+ix*n1+iz]*( + c1*(tzz[iy*n1*n2+ix*n1+iz] - tzz[iy*n1*n2+ix*n1+iz-1]) + + c2*(tzz[iy*n1*n2+ix*n1+iz+1] - tzz[iy*n1*n2+ix*n1+iz-2])); + + vz[iy*n1*n2+ix*n1+iz] *= bnd.tapxz[(iy-iby)*bnd.ntap+(ibz-iz)]; + } + } + } + } + } + + } + + /*********/ + /* Bottom */ + /*********/ + if (bnd.bot==4) { + + if (mod.ischeme <= 2) { /* Acoustic scheme */ + + /* Vx field */ + ixo = mod.ioXx; + ixe = mod.ieXx; + iyo = mod.ioXy; + iye = mod.ieXy; + izo = mod.ieXz; + ize = mod.ieXz+bnd.ntap; + + ib = (ize-bnd.ntap); +#pragma omp for private(ix,iy,iz) + for (ix=ixo; ix<ixe; ix++) { +#pragma ivdep + for (iy=iyo; iy<iye; iy++) { + for (iz=izo; iz<ize; iz++) { + vx[iy*n1*n2+ix*n1+iz] -= rox[iy*n1*n2+ix*n1+iz]*( + c1*(tzz[iy*n1*n2+ix*n1+iz] - tzz[iy*n1*n2+(ix-1)*n1+iz]) + + c2*(tzz[iy*n1*n2+(ix+1)*n1+iz] - tzz[iy*n1*n2+(ix-2)*n1+iz])); + + vx[iy*n1*n2+ix*n1+iz] *= bnd.tapx[iz-ib]; + } + } + } + /* right bottom corner */ + if (bnd.rig==4) { + ixo = mod.ieXx; + ixe = ixo+bnd.ntap; + ibz = (izo); + ibx = (ixo); +#pragma omp for private(ix,iy,iz) + for (ix=ixo; ix<ixe; ix++) { +#pragma ivdep + for (iy=iyo; iy<iye; iy++) { + for (iz=izo; iz<ize; iz++) { + vx[iy*n1*n2+ix*n1+iz] -= rox[iy*n1*n2+ix*n1+iz]*( + c1*(tzz[iy*n1*n2+ix*n1+iz] - tzz[iy*n1*n2+(ix-1)*n1+iz]) + + c2*(tzz[iy*n1*n2+(ix+1)*n1+iz] - tzz[iy*n1*n2+(ix-2)*n1+iz])); + + vx[iy*n1*n2+ix*n1+iz] *= bnd.tapxz[(ix-ibx)*bnd.ntap+(iz-ibz)]; + } + } + } + /* right bottom front corner */ + if (bnd.fro==4) { + iyo = mod.ioXy-bnd.ntap; + iye = mod.ioXy; + iby = (bnd.ntap+iyo-1); +#pragma omp for private(ix,iy,iz) + for (ix=ixo; ix<ixe; ix++) { +#pragma ivdep + for (iy=iyo; iy<iye; iy++) { + for (iz=izo; iz<ize; iz++) { + vx[iy*n1*n2+ix*n1+iz] -= rox[iy*n1*n2+ix*n1+iz]*( + c1*(tzz[iy*n1*n2+ix*n1+iz] - tzz[iy*n1*n2+(ix-1)*n1+iz]) + + c2*(tzz[iy*n1*n2+(ix+1)*n1+iz] - tzz[iy*n1*n2+(ix-2)*n1+iz])); + + vx[iy*n1*n2+ix*n1+iz] *= bnd.tapxyz[(iby-iy)*bnd.ntap*bnd.ntap+(ix-ibx)*bnd.ntap+(iz-ibz)]; + } + } + } + } + /* right bottom back corner */ + if (bnd.bac==4) { + iyo = mod.ieXy; + iye = mod.ieXy+bnd.ntap; + iby = (iyo); +#pragma omp for private(ix,iy,iz) + for (ix=ixo; ix<ixe; ix++) { +#pragma ivdep + for (iy=iyo; iy<iye; iy++) { + for (iz=izo; iz<ize; iz++) { + vx[iy*n1*n2+ix*n1+iz] -= rox[iy*n1*n2+ix*n1+iz]*( + c1*(tzz[iy*n1*n2+ix*n1+iz] - tzz[iy*n1*n2+(ix-1)*n1+iz]) + + c2*(tzz[iy*n1*n2+(ix+1)*n1+iz] - tzz[iy*n1*n2+(ix-2)*n1+iz])); + + vx[iy*n1*n2+ix*n1+iz] *= bnd.tapxyz[(iy-iby)*bnd.ntap*bnd.ntap+(ix-ibx)*bnd.ntap+(iz-ibz)]; + } + } + } + } + } + + ixo = mod.ioXx; + ixe = mod.ieXx; + iyo = mod.ioXy; + iye = mod.ieXy; + izo = mod.ieXz; + ize = mod.ieXz+bnd.ntap; + + /* left bottom corner */ + if (bnd.lef==4) { + ixo = mod.ioXx-bnd.ntap; + ixe = mod.ioXx; + ibz = (izo); + ibx = (bnd.ntap+ixo-1); +#pragma omp for private(ix,iy,iz) + for (ix=ixo; ix<ixe; ix++) { +#pragma ivdep + for (iy=iyo; iy<iye; iy++) { + for (iz=izo; iz<ize; iz++) { + vx[iy*n1*n2+ix*n1+iz] -= rox[iy*n1*n2+ix*n1+iz]*( + c1*(tzz[iy*n1*n2+ix*n1+iz] - tzz[iy*n1*n2+(ix-1)*n1+iz]) + + c2*(tzz[iy*n1*n2+(ix+1)*n1+iz] - tzz[iy*n1*n2+(ix-2)*n1+iz])); + + vx[iy*n1*n2+ix*n1+iz] *= bnd.tapxz[(ibx-ix)*bnd.ntap+(iz-ibz)]; + } + } + } + /* left bottom front corner */ + if (bnd.fro==4) { + iyo = mod.ioXy-bnd.ntap; + iye = mod.ioXy; + iby = (bnd.ntap+iyo-1); +#pragma omp for private(ix,iy,iz) + for (ix=ixo; ix<ixe; ix++) { +#pragma ivdep + for (iy=iyo; iy<iye; iy++) { + for (iz=izo; iz<ize; iz++) { + vx[iy*n1*n2+ix*n1+iz] -= rox[iy*n1*n2+ix*n1+iz]*( + c1*(tzz[iy*n1*n2+ix*n1+iz] - tzz[iy*n1*n2+(ix-1)*n1+iz]) + + c2*(tzz[iy*n1*n2+(ix+1)*n1+iz] - tzz[iy*n1*n2+(ix-2)*n1+iz])); + + vx[iy*n1*n2+ix*n1+iz] *= bnd.tapxyz[(iby-iy)*bnd.ntap*bnd.ntap+(ibx-ix)*bnd.ntap+(iz-ibz)]; + } + } + } + } + /* left bottom back corner */ + if (bnd.bac==4) { + iyo = mod.ieXy; + iye = mod.ieXy+bnd.ntap; + iby = (iyo); +#pragma omp for private(ix,iy,iz) + for (ix=ixo; ix<ixe; ix++) { +#pragma ivdep + for (iy=iyo; iy<iye; iy++) { + for (iz=izo; iz<ize; iz++) { + vx[iy*n1*n2+ix*n1+iz] -= rox[iy*n1*n2+ix*n1+iz]*( + c1*(tzz[iy*n1*n2+ix*n1+iz] - tzz[iy*n1*n2+(ix-1)*n1+iz]) + + c2*(tzz[iy*n1*n2+(ix+1)*n1+iz] - tzz[iy*n1*n2+(ix-2)*n1+iz])); + + vx[iy*n1*n2+ix*n1+iz] *= bnd.tapxyz[(iy-iby)*bnd.ntap*bnd.ntap+(ibx-ix)*bnd.ntap+(iz-ibz)]; + } + } + } + } + } + /* front bottom corner */ + if (bnd.fro==4) { + ixo = mod.ioXx; + ixe = mod.ieXx; + iyo = mod.ioXy-bnd.ntap; + iye = mod.ioXy; + ibz = (izo); + iby = (bnd.ntap+iyo-1); +#pragma omp for private(ix,iy,iz) + for (ix=ixo; ix<ixe; ix++) { +#pragma ivdep + for (iy=iyo; iy<iye; iy++) { + for (iz=izo; iz<ize; iz++) { + vx[iy*n1*n2+ix*n1+iz] -= rox[iy*n1*n2+ix*n1+iz]*( + c1*(tzz[iy*n1*n2+ix*n1+iz] - tzz[iy*n1*n2+(ix-1)*n1+iz]) + + c2*(tzz[iy*n1*n2+(ix+1)*n1+iz] - tzz[iy*n1*n2+(ix-2)*n1+iz])); + + vx[iy*n1*n2+ix*n1+iz] *= bnd.tapxz[(iby-iy)*bnd.ntap+(iz-ibz)]; + } + } + } + } + /* Back bottom corner */ + if (bnd.bac==4) { + iyo = mod.ieXy; + iye = mod.ioXy+bnd.ntap; + ibz = (izo); + iby = (iyo); +#pragma omp for private(ix,iy,iz) + for (ix=ixo; ix<ixe; ix++) { +#pragma ivdep + for (iy=iyo; iy<iye; iy++) { + for (iz=izo; iz<ize; iz++) { + vx[iy*n1*n2+ix*n1+iz] -= rox[iy*n1*n2+ix*n1+iz]*( + c1*(tzz[iy*n1*n2+ix*n1+iz] - tzz[iy*n1*n2+(ix-1)*n1+iz]) + + c2*(tzz[iy*n1*n2+(ix+1)*n1+iz] - tzz[iy*n1*n2+(ix-2)*n1+iz])); + + vx[iy*n1*n2+ix*n1+iz] *= bnd.tapxz[(iy-iby)*bnd.ntap+(iz-ibz)]; + } + } + } + } + + /* Vy field */ + ixo = mod.ioYx; + ixe = mod.ieYx; + iyo = mod.ioYy; + iye = mod.ieYy; + izo = mod.ioYz; + ize = mod.ioYz+bnd.ntap; + + ib = (bnd.ntap+izo-1); +#pragma omp for private(ix,iy,iz) + for (ix=ixo; ix<ixe; ix++) { +#pragma ivdep + for (iy=iyo; iy<iye; iy++) { + for (iz=izo; iz<ize; iz++) { + vy[iy*n1*n2+ix*n1+iz] -= roy[iy*n1*n2+ix*n1+iz]*( + c1*(tzz[iy*n1*n2+ix*n1+iz] - tzz[(iy-1)*n1*n2+ix*n1+iz]) + + c2*(tzz[(iy+1)*n1*n2+ix*n1+iz] - tzz[(iy-2)*n1*n2+ix*n1+iz])); + + vy[iy*n1*n2+ix*n1+iz] *= bnd.tapy[iz-ib]; + } + } + } + /* right bottom corner */ + if (bnd.rig==4) { + ixo = mod.ieYx; + ixe = ixo+bnd.ntap; + ibz = (izo); + ibx = (ixo); +#pragma omp for private(ix,iy,iz) + for (ix=ixo; ix<ixe; ix++) { +#pragma ivdep + for (iy=iyo; iy<iye; iy++) { + for (iz=izo; iz<ize; iz++) { + vy[iy*n1*n2+ix*n1+iz] -= roy[iy*n1*n2+ix*n1+iz]*( + c1*(tzz[iy*n1*n2+ix*n1+iz] - tzz[(iy-1)*n1*n2+ix*n1+iz]) + + c2*(tzz[(iy+1)*n1*n2+ix*n1+iz] - tzz[(iy-2)*n1*n2+ix*n1+iz])); + + vy[iy*n1*n2+ix*n1+iz] *= bnd.tapxz[(ix-ibx)*bnd.ntap+(iz-ibz)]; + } + } + } + /* right bottom front corner */ + if (bnd.fro==4) { + iyo = mod.ioYy-bnd.ntap; + iye = mod.ioYy; + iby = (bnd.ntap+iyo-1); +#pragma omp for private(ix,iy,iz) + for (ix=ixo; ix<ixe; ix++) { +#pragma ivdep + for (iy=iyo; iy<iye; iy++) { + for (iz=izo; iz<ize; iz++) { + vy[iy*n1*n2+ix*n1+iz] -= roy[iy*n1*n2+ix*n1+iz]*( + c1*(tzz[iy*n1*n2+ix*n1+iz] - tzz[(iy-1)*n1*n2+ix*n1+iz]) + + c2*(tzz[(iy+1)*n1*n2+ix*n1+iz] - tzz[(iy-2)*n1*n2+ix*n1+iz])); + + vy[iy*n1*n2+ix*n1+iz] *= bnd.tapxyz[(iby-iy)*bnd.ntap*bnd.ntap+(ix-ibx)*bnd.ntap+(iz-ibz)]; + } + } + } + } + /* right bottom back corner */ + if (bnd.bac==4) { + iyo = mod.ieYy; + iye = mod.ieYy+bnd.ntap; + iby = (iyo); +#pragma omp for private(ix,iy,iz) + for (ix=ixo; ix<ixe; ix++) { +#pragma ivdep + for (iy=iyo; iy<iye; iy++) { + for (iz=izo; iz<ize; iz++) { + vy[iy*n1*n2+ix*n1+iz] -= roy[iy*n1*n2+ix*n1+iz]*( + c1*(tzz[iy*n1*n2+ix*n1+iz] - tzz[(iy-1)*n1*n2+ix*n1+iz]) + + c2*(tzz[(iy+1)*n1*n2+ix*n1+iz] - tzz[(iy-2)*n1*n2+ix*n1+iz])); + + vy[iy*n1*n2+ix*n1+iz] *= bnd.tapxyz[(iy-iby)*bnd.ntap*bnd.ntap+(ix-ibx)*bnd.ntap+(iz-ibz)]; + } + } + } + } + } + ixo = mod.ioYx; + ixe = mod.ieYx; + iyo = mod.ioYy; + iye = mod.ieYy; + izo = mod.ioYz; + ize = mod.ioYz+bnd.ntap; + + /* left bottom corner */ + if (bnd.lef==4) { + ixo = mod.ioYx-bnd.ntap; + ixe = mod.ioYx; + ibz = (izo); + ibx = (bnd.ntap+ixo-1); +#pragma omp for private(ix,iy,iz) + for (ix=ixo; ix<ixe; ix++) { +#pragma ivdep + for (iy=iyo; iy<iye; iy++) { + for (iz=izo; iz<ize; iz++) { + vy[iy*n1*n2+ix*n1+iz] -= roy[iy*n1*n2+ix*n1+iz]*( + c1*(tzz[iy*n1*n2+ix*n1+iz] - tzz[(iy-1)*n1*n2+ix*n1+iz]) + + c2*(tzz[(iy+1)*n1*n2+ix*n1+iz] - tzz[(iy-2)*n1*n2+ix*n1+iz])); + + vy[iy*n1*n2+ix*n1+iz] *= bnd.tapxz[(ibx-ix)*bnd.ntap+(iz-ibz)]; + } + } + } + /* left bottom front corner */ + if (bnd.fro==4) { + iyo = mod.ioYy-bnd.ntap; + iye = mod.ioYy; + iby = (bnd.ntap+iyo-1); +#pragma omp for private(ix,iy,iz) + for (ix=ixo; ix<ixe; ix++) { +#pragma ivdep + for (iy=iyo; iy<iye; iy++) { + for (iz=izo; iz<ize; iz++) { + vy[iy*n1*n2+ix*n1+iz] -= roy[iy*n1*n2+ix*n1+iz]*( + c1*(tzz[iy*n1*n2+ix*n1+iz] - tzz[(iy-1)*n1*n2+ix*n1+iz]) + + c2*(tzz[(iy+1)*n1*n2+ix*n1+iz] - tzz[(iy-2)*n1*n2+ix*n1+iz])); + + vy[iy*n1*n2+ix*n1+iz] *= bnd.tapxyz[(iby-iy)*bnd.ntap*bnd.ntap+(ibx-ix)*bnd.ntap+(iz-ibz)]; + } + } + } + } + /* left bottom back corner */ + if (bnd.bac==4) { + iyo = mod.ieYy; + iye = mod.ieYy+bnd.ntap; + iby = (iyo); +#pragma omp for private(ix,iy,iz) + for (ix=ixo; ix<ixe; ix++) { +#pragma ivdep + for (iy=iyo; iy<iye; iy++) { + for (iz=izo; iz<ize; iz++) { + vy[iy*n1*n2+ix*n1+iz] -= roy[iy*n1*n2+ix*n1+iz]*( + c1*(tzz[iy*n1*n2+ix*n1+iz] - tzz[(iy-1)*n1*n2+ix*n1+iz]) + + c2*(tzz[(iy+1)*n1*n2+ix*n1+iz] - tzz[(iy-2)*n1*n2+ix*n1+iz])); + + vy[iy*n1*n2+ix*n1+iz] *= bnd.tapxyz[(iy-iby)*bnd.ntap*bnd.ntap+(ibx-ix)*bnd.ntap+(iz-ibz)]; + } + } + } + } + } + /* front bottom corner */ + if (bnd.fro==4) { + ixo = mod.ioXx; + ixe = mod.ieXx; + iyo = mod.ioXy-bnd.ntap; + iye = mod.ioXy; + ibz = (izo); + iby = (bnd.ntap+iyo-1); +#pragma omp for private(ix,iy,iz) + for (ix=ixo; ix<ixe; ix++) { +#pragma ivdep + for (iy=iyo; iy<iye; iy++) { + for (iz=izo; iz<ize; iz++) { + vy[iy*n1*n2+ix*n1+iz] -= roy[iy*n1*n2+ix*n1+iz]*( + c1*(tzz[iy*n1*n2+ix*n1+iz] - tzz[(iy-1)*n1*n2+ix*n1+iz]) + + c2*(tzz[(iy+1)*n1*n2+ix*n1+iz] - tzz[(iy-2)*n1*n2+ix*n1+iz])); + + vy[iy*n1*n2+ix*n1+iz] *= bnd.tapxz[(iby-iy)*bnd.ntap+(iz-ibz)]; + } + } + } + } + /* Back bottom corner */ + if (bnd.bac==4) { + iyo = mod.ieXy; + iye = mod.ioXy+bnd.ntap; + ibz = (izo); + iby = (iyo); +#pragma omp for private(ix,iy,iz) + for (ix=ixo; ix<ixe; ix++) { +#pragma ivdep + for (iy=iyo; iy<iye; iy++) { + for (iz=izo; iz<ize; iz++) { + vy[iy*n1*n2+ix*n1+iz] -= roy[iy*n1*n2+ix*n1+iz]*( + c1*(tzz[iy*n1*n2+ix*n1+iz] - tzz[(iy-1)*n1*n2+ix*n1+iz]) + + c2*(tzz[(iy+1)*n1*n2+ix*n1+iz] - tzz[(iy-2)*n1*n2+ix*n1+iz])); + + vy[iy*n1*n2+ix*n1+iz] *= bnd.tapxz[(iy-iby)*bnd.ntap+(iz-ibz)]; + } + } + } + } + + /* Vz field */ + ixo = mod.ioZx; + ixe = mod.ieZx; + iyo = mod.ioZy; + iye = mod.ieZy; + izo = mod.ieZz; + ize = mod.ieZz+bnd.ntap; + + ib = (ize-bnd.ntap); +#pragma omp for private (ix, iz) + for (ix=ixo; ix<ixe; ix++) { +#pragma ivdep + for (iz=izo; iz<ize; iz++) { + vz[iy*n1*n2+ix*n1+iz] -= roz[iy*n1*n2+ix*n1+iz]*( + c1*(tzz[iy*n1*n2+ix*n1+iz] - tzz[iy*n1*n2+ix*n1+iz-1]) + + c2*(tzz[iy*n1*n2+ix*n1+iz+1] - tzz[iy*n1*n2+ix*n1+iz-2])); + vz[iy*n1*n2+ix*n1+iz] *= bnd.tapz[iz-ib]; + } + } + /* right bottom corner */ + if (bnd.rig==4) { + ixo = mod.ieZx; + ixe = ixo+bnd.ntap; + ibz = (izo); + ibx = (ixo); +#pragma omp for private(ix,iz) + for (ix=ixo; ix<ixe; ix++) { +#pragma ivdep + for (iz=izo; iz<ize; iz++) { + vz[iy*n1*n2+ix*n1+iz] -= roz[iy*n1*n2+ix*n1+iz]*( + c1*(tzz[iy*n1*n2+ix*n1+iz] - tzz[iy*n1*n2+ix*n1+iz-1]) + + c2*(tzz[iy*n1*n2+ix*n1+iz+1] - tzz[iy*n1*n2+ix*n1+iz-2])); + + vz[iy*n1*n2+ix*n1+iz] *= bnd.tapxz[(ix-ibx)*bnd.ntap+(iz-ibz)]; + } + } + /* right bottom front corner */ + if (bnd.fro==4) { + iyo = mod.ioYy-bnd.ntap; + iye = mod.ioYy; + iby = (bnd.ntap+iyo-1); +#pragma omp for private(ix,iy,iz) + for (ix=ixo; ix<ixe; ix++) { +#pragma ivdep + for (iy=iyo; iy<iye; iy++) { + for (iz=izo; iz<ize; iz++) { + vz[iy*n1*n2+ix*n1+iz] -= roz[iy*n1*n2+ix*n1+iz]*( + c1*(tzz[iy*n1*n2+ix*n1+iz] - tzz[iy*n1*n2+ix*n1+iz-1]) + + c2*(tzz[iy*n1*n2+ix*n1+iz+1] - tzz[iy*n1*n2+ix*n1+iz-2])); + + vz[iy*n1*n2+ix*n1+iz] *= bnd.tapxyz[(iby-iy)*bnd.ntap*bnd.ntap+(ix-ibx)*bnd.ntap+(iz-ibz)]; + } + } + } + } + /* right bottom back corner */ + if (bnd.bac==4) { + iyo = mod.ieYy; + iye = mod.ieYy+bnd.ntap; + iby = (iyo); +#pragma omp for private(ix,iy,iz) + for (ix=ixo; ix<ixe; ix++) { +#pragma ivdep + for (iy=iyo; iy<iye; iy++) { + for (iz=izo; iz<ize; iz++) { + vz[iy*n1*n2+ix*n1+iz] -= roz[iy*n1*n2+ix*n1+iz]*( + c1*(tzz[iy*n1*n2+ix*n1+iz] - tzz[iy*n1*n2+ix*n1+iz-1]) + + c2*(tzz[iy*n1*n2+ix*n1+iz+1] - tzz[iy*n1*n2+ix*n1+iz-2])); + + vz[iy*n1*n2+ix*n1+iz] *= bnd.tapxyz[(iy-iby)*bnd.ntap*bnd.ntap+(ix-ibx)*bnd.ntap+(iz-ibz)]; + } + } + } + } + } + /* left bottom corner */ + if (bnd.lef==4) { + ixo = mod.ioZx-bnd.ntap; + ixe = mod.ioZx; + ibz = (izo); + ibx = (bnd.ntap+ixo-1); +#pragma omp for private(ix,iz) + for (ix=ixo; ix<ixe; ix++) { +#pragma ivdep + for (iz=izo; iz<ize; iz++) { + vz[iy*n1*n2+ix*n1+iz] -= roz[iy*n1*n2+ix*n1+iz]*( + c1*(tzz[iy*n1*n2+ix*n1+iz] - tzz[iy*n1*n2+ix*n1+iz-1]) + + c2*(tzz[iy*n1*n2+ix*n1+iz+1] - tzz[iy*n1*n2+ix*n1+iz-2])); + + vz[iy*n1*n2+ix*n1+iz] *= bnd.tapxz[(ibx-ix)*bnd.ntap+(iz-ibz)]; + } + } + /* left bottom front corner */ + if (bnd.fro==4) { + iyo = mod.ioYy-bnd.ntap; + iye = mod.ioYy; + iby = (bnd.ntap+iyo-1); +#pragma omp for private(ix,iy,iz) + for (ix=ixo; ix<ixe; ix++) { +#pragma ivdep + for (iy=iyo; iy<iye; iy++) { + for (iz=izo; iz<ize; iz++) { + vz[iy*n1*n2+ix*n1+iz] -= roz[iy*n1*n2+ix*n1+iz]*( + c1*(tzz[iy*n1*n2+ix*n1+iz] - tzz[iy*n1*n2+ix*n1+iz-1]) + + c2*(tzz[iy*n1*n2+ix*n1+iz+1] - tzz[iy*n1*n2+ix*n1+iz-2])); + + vz[iy*n1*n2+ix*n1+iz] *= bnd.tapxyz[(iby-iy)*bnd.ntap*bnd.ntap+(ibx-ix)*bnd.ntap+(iz-ibz)]; + } + } + } + } + /* left bottom back corner */ + if (bnd.bac==4) { + iyo = mod.ieYy; + iye = mod.ieYy+bnd.ntap; + iby = (iyo); +#pragma omp for private(ix,iy,iz) + for (ix=ixo; ix<ixe; ix++) { +#pragma ivdep + for (iy=iyo; iy<iye; iy++) { + for (iz=izo; iz<ize; iz++) { + vy[iy*n1*n2+ix*n1+iz] -= roy[iy*n1*n2+ix*n1+iz]*( + c1*(tzz[iy*n1*n2+ix*n1+iz] - tzz[iy*n1*n2+ix*n1+iz-1]) + + c2*(tzz[iy*n1*n2+ix*n1+iz+1] - tzz[iy*n1*n2+ix*n1+iz-2])); + + vy[iy*n1*n2+ix*n1+iz] *= bnd.tapxyz[(iy-iby)*bnd.ntap*bnd.ntap+(ibx-ix)*bnd.ntap+(iz-ibz)]; + } + } + } + } + } + /* front bottom corner */ + if (bnd.fro==4) { + ixo = mod.ioXx; + ixe = mod.ieXx; + iyo = mod.ioXy-bnd.ntap; + iye = mod.ioXy; + ibz = (izo); + iby = (bnd.ntap+iyo-1); +#pragma omp for private(ix,iy,iz) + for (ix=ixo; ix<ixe; ix++) { +#pragma ivdep + for (iy=iyo; iy<iye; iy++) { + for (iz=izo; iz<ize; iz++) { + vz[iy*n1*n2+ix*n1+iz] -= roz[iy*n1*n2+ix*n1+iz]*( + c1*(tzz[iy*n1*n2+ix*n1+iz] - tzz[iy*n1*n2+ix*n1+iz-1]) + + c2*(tzz[iy*n1*n2+ix*n1+iz+1] - tzz[iy*n1*n2+ix*n1+iz-2])); + + vz[iy*n1*n2+ix*n1+iz] *= bnd.tapxz[(iby-iy)*bnd.ntap+(iz-ibz)]; + } + } + } + } + /* Back bottom corner */ + if (bnd.bac==4) { + iyo = mod.ieXy; + iye = mod.ioXy+bnd.ntap; + ibz = (izo); + iby = (iyo); +#pragma omp for private(ix,iy,iz) + for (ix=ixo; ix<ixe; ix++) { +#pragma ivdep + for (iy=iyo; iy<iye; iy++) { + for (iz=izo; iz<ize; iz++) { + vz[iy*n1*n2+ix*n1+iz] -= roz[iy*n1*n2+ix*n1+iz]*( + c1*(tzz[iy*n1*n2+ix*n1+iz] - tzz[iy*n1*n2+ix*n1+iz-1]) + + c2*(tzz[iy*n1*n2+ix*n1+iz+1] - tzz[iy*n1*n2+ix*n1+iz-2])); + + vz[iy*n1*n2+ix*n1+iz] *= bnd.tapxz[(iy-iby)*bnd.ntap+(iz-ibz)]; + } + } + } + } + + } + } + + /*********/ + /* Left */ + /*********/ + if (bnd.lef==4) { + + if (mod.ischeme <= 2) { /* Acoustic scheme */ + + /* Vx field */ + ixo = mod.ioXx-bnd.ntap; + ixe = mod.ioXx; + iyo = mod.ioXy; + iye = mod.ieXy; + izo = mod.ioXz; + ize = mod.ieXz; + + ib = (bnd.ntap+ixo-1); +#pragma omp for private(ix,iy,iz) + for (ix=ixo; ix<ixe; ix++) { +#pragma ivdep + for (iy=iyo; iy<iye; iy++) { + for (iz=izo; iz<ize; iz++) { + vx[iy*n1*n2+ix*n1+iz] -= rox[iy*n1*n2+ix*n1+iz]*( + c1*(tzz[iy*n1*n2+ix*n1+iz] - tzz[iy*n1*n2+(ix-1)*n1+iz]) + + c2*(tzz[iy*n1*n2+(ix+1)*n1+iz] - tzz[iy*n1*n2+(ix-2)*n1+iz])); + + vx[iy*n1*n2+ix*n1+iz] *= bnd.tapx[ib-ix]; + } + } + } + /* left front corner */ + if (bnd.fro==4) { + iyo = mod.ioXy-bnd.ntap; + iye = mod.ioXy; + ibx = (bnd.ntap+ixo-1); + iby = (bnd.ntap+iyo-1); +#pragma omp for private(ix,iy,iz) + for (ix=ixo; ix<ixe; ix++) { +#pragma ivdep + for (iy=iyo; iy<iye; iy++) { + for (iz=izo; iz<ize; iz++) { + vx[iy*n1*n2+ix*n1+iz] -= rox[iy*n1*n2+ix*n1+iz]*( + c1*(tzz[iy*n1*n2+ix*n1+iz] - tzz[iy*n1*n2+(ix-1)*n1+iz]) + + c2*(tzz[iy*n1*n2+(ix+1)*n1+iz] - tzz[iy*n1*n2+(ix-2)*n1+iz])); + + vx[iy*n1*n2+ix*n1+iz] *= bnd.tapxz[(iby-iy)*bnd.ntap+(ibx-ix)]; + } + } + } + } + /* left back corner */ + if (bnd.bac==4) { + iyo = mod.ieXy; + iye = mod.ieXy+bnd.ntap; + ibx = (bnd.ntap+ixo-1); + iby = (iyo); +#pragma omp for private(ix,iy,iz) + for (ix=ixo; ix<ixe; ix++) { +#pragma ivdep + for (iy=iyo; iy<iye; iy++) { + for (iz=izo; iz<ize; iz++) { + vx[iy*n1*n2+ix*n1+iz] -= rox[iy*n1*n2+ix*n1+iz]*( + c1*(tzz[iy*n1*n2+ix*n1+iz] - tzz[iy*n1*n2+(ix-1)*n1+iz]) + + c2*(tzz[iy*n1*n2+(ix+1)*n1+iz] - tzz[iy*n1*n2+(ix-2)*n1+iz])); + + vx[iy*n1*n2+ix*n1+iz] *= bnd.tapxz[(iy-iby)*bnd.ntap+(ibx-ix)]; + } + } + } + } + + /* Vy field */ + ixo = mod.ioYx-bnd.ntap; + ixe = mod.ioYx; + iyo = mod.ioYy; + iye = mod.ieYy; + izo = mod.ioYz; + ize = mod.ieYz; + + ib = (bnd.ntap+ixo-1); +#pragma omp for private(ix,iy,iz) + for (ix=ixo; ix<ixe; ix++) { +#pragma ivdep + for (iy=iyo; iy<iye; iy++) { + for (iz=izo; iz<ize; iz++) { + vy[iy*n1*n2+ix*n1+iz] -= roy[iy*n1*n2+ix*n1+iz]*( + c1*(tzz[iy*n1*n2+ix*n1+iz] - tzz[(iy-1)*n1*n2+ix*n1+iz]) + + c2*(tzz[(iy+1)*n1*n2+ix*n1+iz] - tzz[(iy-2)*n1*n2+ix*n1+iz])); + + vy[iy*n1*n2+ix*n1+iz] *= bnd.tapx[ib-ix]; + } + } + } + /* left front corner */ + if (bnd.fro==4) { + iyo = mod.ioYy-bnd.ntap; + iye = mod.ioYy; + ibx = (bnd.ntap+ixo-1); + iby = (bnd.ntap+iyo-1); +#pragma omp for private(ix,iy,iz) + for (ix=ixo; ix<ixe; ix++) { +#pragma ivdep + for (iy=iyo; iy<iye; iy++) { + for (iz=izo; iz<ize; iz++) { + vy[iy*n1*n2+ix*n1+iz] -= roy[iy*n1*n2+ix*n1+iz]*( + c1*(tzz[iy*n1*n2+ix*n1+iz] - tzz[(iy-1)*n1*n2+ix*n1+iz]) + + c2*(tzz[(iy+1)*n1*n2+ix*n1+iz] - tzz[(iy-2)*n1*n2+ix*n1+iz])); + + vy[iy*n1*n2+ix*n1+iz] *= bnd.tapxz[(iby-iy)*bnd.ntap+(ibx-ix)]; + } + } + } + } + /* left back corner */ + if (bnd.bac==4) { + iyo = mod.ieYy; + iye = mod.ieYy+bnd.ntap; + ibx = (bnd.ntap+ixo-1); + iby = (iyo); +#pragma omp for private(ix,iy,iz) + for (ix=ixo; ix<ixe; ix++) { +#pragma ivdep + for (iy=iyo; iy<iye; iy++) { + for (iz=izo; iz<ize; iz++) { + vy[iy*n1*n2+ix*n1+iz] -= roy[iy*n1*n2+ix*n1+iz]*( + c1*(tzz[iy*n1*n2+ix*n1+iz] - tzz[(iy-1)*n1*n2+ix*n1+iz]) + + c2*(tzz[(iy+1)*n1*n2+ix*n1+iz] - tzz[(iy-2)*n1*n2+ix*n1+iz])); + + vy[iy*n1*n2+ix*n1+iz] *= bnd.tapxz[(iy-iby)*bnd.ntap+(ibx-ix)]; + } + } + } + } + + /* Vz field */ + ixo = mod.ioZx-bnd.ntap; + ixe = mod.ioZx; + iyo = mod.ioZy; + iye = mod.ieZy; + izo = mod.ioZz; + ize = mod.ieZz; + + ib = (bnd.ntap+ixo-1); +#pragma omp for private (ix,iy,iz) + for (ix=ixo; ix<ixe; ix++) { +#pragma ivdep + for (iy=iyo; iy<iye; iy++) { + for (iz=izo; iz<ize; iz++) { + vz[iy*n1*n2+ix*n1+iz] -= roz[iy*n1*n2+ix*n1+iz]*( + c1*(tzz[iy*n1*n2+ix*n1+iz] - tzz[iy*n1*n2+ix*n1+iz-1]) + + c2*(tzz[iy*n1*n2+ix*n1+iz+1] - tzz[iy*n1*n2+ix*n1+iz-2])); + + vz[iy*n1*n2+ix*n1+iz] *= bnd.tapz[ib-ix]; + } + } + } + /* left front corner */ + if (bnd.fro==4) { + iyo = mod.ioZy-bnd.ntap; + iye = mod.ioZy; + ibx = (bnd.ntap+ixo-1); + iby = (bnd.ntap+iyo-1); +#pragma omp for private(ix,iy,iz) + for (ix=ixo; ix<ixe; ix++) { +#pragma ivdep + for (iy=iyo; iy<iye; iy++) { + for (iz=izo; iz<ize; iz++) { + vz[iy*n1*n2+ix*n1+iz] -= roz[iy*n1*n2+ix*n1+iz]*( + c1*(tzz[iy*n1*n2+ix*n1+iz] - tzz[iy*n1*n2+ix*n1+iz-1]) + + c2*(tzz[iy*n1*n2+ix*n1+iz+1] - tzz[iy*n1*n2+ix*n1+iz-2])); + + vz[iy*n1*n2+ix*n1+iz] *= bnd.tapxz[(iby-iy)*bnd.ntap+(ibx-ix)]; + } + } + } + } + /* left back corner */ + if (bnd.bac==4) { + iyo = mod.ieZy; + iye = mod.ieZy+bnd.ntap; + ibx = (bnd.ntap+ixo-1); + iby = (iyo); +#pragma omp for private(ix,iy,iz) + for (ix=ixo; ix<ixe; ix++) { +#pragma ivdep + for (iy=iyo; iy<iye; iy++) { + for (iz=izo; iz<ize; iz++) { + vz[iy*n1*n2+ix*n1+iz] -= roz[iy*n1*n2+ix*n1+iz]*( + c1*(tzz[iy*n1*n2+ix*n1+iz] - tzz[iy*n1*n2+ix*n1+iz-1]) + + c2*(tzz[iy*n1*n2+ix*n1+iz+1] - tzz[iy*n1*n2+ix*n1+iz-2])); + + vz[iy*n1*n2+ix*n1+iz] *= bnd.tapxz[(iy-iby)*bnd.ntap+(ibx-ix)]; + } + } + } + } + + } + + } + + /*********/ + /* Right */ + /*********/ + if (bnd.rig==4) { + + if (mod.ischeme <= 2) { /* Acoustic scheme */ + + /* Vx field */ + ixo = mod.ieXx; + ixe = mod.ieXx+bnd.ntap; + iyo = mod.ioXy; + iye = mod.ieXy; + izo = mod.ioXz; + ize = mod.ieXz; + + ib = (ixe-bnd.ntap); +#pragma omp for private(ix,iy,iz) + for (ix=ixo; ix<ixe; ix++) { +#pragma ivdep + for (iy=iyo; iy<iye; iy++) { + for (iz=izo; iz<ize; iz++) { + vx[iy*n1*n2+ix*n1+iz] -= rox[iy*n1*n2+ix*n1+iz]*( + c1*(tzz[iy*n1*n2+ix*n1+iz] - tzz[iy*n1*n2+(ix-1)*n1+iz]) + + c2*(tzz[iy*n1*n2+(ix+1)*n1+iz] - tzz[iy*n1*n2+(ix-2)*n1+iz])); + + vx[iy*n1*n2+ix*n1+iz] *= bnd.tapx[ix-ib]; + } + } + } + /* left front corner */ + if (bnd.fro==4) { + iyo = mod.ioXy-bnd.ntap; + iye = mod.ioXy; + ibx = (ixo); + iby = (bnd.ntap+iyo-1); +#pragma omp for private(ix,iy,iz) + for (ix=ixo; ix<ixe; ix++) { +#pragma ivdep + for (iy=iyo; iy<iye; iy++) { + for (iz=izo; iz<ize; iz++) { + vx[iy*n1*n2+ix*n1+iz] -= rox[iy*n1*n2+ix*n1+iz]*( + c1*(tzz[iy*n1*n2+ix*n1+iz] - tzz[iy*n1*n2+(ix-1)*n1+iz]) + + c2*(tzz[iy*n1*n2+(ix+1)*n1+iz] - tzz[iy*n1*n2+(ix-2)*n1+iz])); + + vx[iy*n1*n2+ix*n1+iz] *= bnd.tapxz[(iby-iy)*bnd.ntap+(ix-ibx)]; + } + } + } + } + /* left back corner */ + if (bnd.bac==4) { + iyo = mod.ieXy; + iye = mod.ieXy+bnd.ntap; + ibx = (ixo); + iby = (iyo); +#pragma omp for private(ix,iy,iz) + for (ix=ixo; ix<ixe; ix++) { +#pragma ivdep + for (iy=iyo; iy<iye; iy++) { + for (iz=izo; iz<ize; iz++) { + vx[iy*n1*n2+ix*n1+iz] -= rox[iy*n1*n2+ix*n1+iz]*( + c1*(tzz[iy*n1*n2+ix*n1+iz] - tzz[iy*n1*n2+(ix-1)*n1+iz]) + + c2*(tzz[iy*n1*n2+(ix+1)*n1+iz] - tzz[iy*n1*n2+(ix-2)*n1+iz])); + + vx[iy*n1*n2+ix*n1+iz] *= bnd.tapxz[(iy-iby)*bnd.ntap+(ix-ibx)]; + } + } + } + } + + /* Vy field */ + ixo = mod.ieYx; + ixe = mod.ieYx+bnd.ntap; + iyo = mod.ioYy; + iye = mod.ieYy; + izo = mod.ioYz; + ize = mod.ieYz; + + ib = (ixe-bnd.ntap); +#pragma omp for private(ix,iy,iz) + for (ix=ixo; ix<ixe; ix++) { +#pragma ivdep + for (iy=iyo; iy<iye; iy++) { + for (iz=izo; iz<ize; iz++) { + vy[iy*n1*n2+ix*n1+iz] -= roy[iy*n1*n2+ix*n1+iz]*( + c1*(tzz[iy*n1*n2+ix*n1+iz] - tzz[(iy-1)*n1*n2+ix*n1+iz]) + + c2*(tzz[(iy+1)*n1*n2+ix*n1+iz] - tzz[(iy-2)*n1*n2+ix*n1+iz])); + + vy[iy*n1*n2+ix*n1+iz] *= bnd.tapx[ix-ib]; + } + } + } + /* left front corner */ + if (bnd.fro==4) { + iyo = mod.ioYy-bnd.ntap; + iye = mod.ioYy; + ibx = (ixo); + iby = (bnd.ntap+iyo-1); +#pragma omp for private(ix,iy,iz) + for (ix=ixo; ix<ixe; ix++) { +#pragma ivdep + for (iy=iyo; iy<iye; iy++) { + for (iz=izo; iz<ize; iz++) { + vy[iy*n1*n2+ix*n1+iz] -= roy[iy*n1*n2+ix*n1+iz]*( + c1*(tzz[iy*n1*n2+ix*n1+iz] - tzz[(iy-1)*n1*n2+ix*n1+iz]) + + c2*(tzz[(iy+1)*n1*n2+ix*n1+iz] - tzz[(iy-2)*n1*n2+ix*n1+iz])); + + vy[iy*n1*n2+ix*n1+iz] *= bnd.tapxz[(iby-iy)*bnd.ntap+(ix-ibx)]; + } + } + } + } + /* left back corner */ + if (bnd.bac==4) { + iyo = mod.ieYy; + iye = mod.ieYy+bnd.ntap; + ibx = (ixo); + iby = (iyo); +#pragma omp for private(ix,iy,iz) + for (ix=ixo; ix<ixe; ix++) { +#pragma ivdep + for (iy=iyo; iy<iye; iy++) { + for (iz=izo; iz<ize; iz++) { + vy[iy*n1*n2+ix*n1+iz] -= roy[iy*n1*n2+ix*n1+iz]*( + c1*(tzz[iy*n1*n2+ix*n1+iz] - tzz[(iy-1)*n1*n2+ix*n1+iz]) + + c2*(tzz[(iy+1)*n1*n2+ix*n1+iz] - tzz[(iy-2)*n1*n2+ix*n1+iz])); + + vy[iy*n1*n2+ix*n1+iz] *= bnd.tapxz[(iy-iby)*bnd.ntap+(ix-ibx)]; + } + } + } + } + + /* Vz field */ + ixo = mod.ieZx; + ixe = mod.ieZx+bnd.ntap; + iyo = mod.ioZy; + iye = mod.ieZy; + izo = mod.ioZz; + ize = mod.ieZz; + + ib = (ixe-bnd.ntap); +#pragma omp for private (ix,iy,iz) + for (ix=ixo; ix<ixe; ix++) { +#pragma ivdep + for (iy=iyo; iy<iye; iy++) { + for (iz=izo; iz<ize; iz++) { + vz[iy*n1*n2+ix*n1+iz] -= roz[iy*n1*n2+ix*n1+iz]*( + c1*(tzz[iy*n1*n2+ix*n1+iz] - tzz[iy*n1*n2+ix*n1+iz-1]) + + c2*(tzz[iy*n1*n2+ix*n1+iz+1] - tzz[iy*n1*n2+ix*n1+iz-2])); + + vz[iy*n1*n2+ix*n1+iz] *= bnd.tapz[ix-ib]; + } + } + } + /* left front corner */ + if (bnd.fro==4) { + iyo = mod.ioZy-bnd.ntap; + iye = mod.ioZy; + ibx = (ixo); + iby = (bnd.ntap+iyo-1); +#pragma omp for private(ix,iy,iz) + for (ix=ixo; ix<ixe; ix++) { +#pragma ivdep + for (iy=iyo; iy<iye; iy++) { + for (iz=izo; iz<ize; iz++) { + vz[iy*n1*n2+ix*n1+iz] -= roz[iy*n1*n2+ix*n1+iz]*( + c1*(tzz[iy*n1*n2+ix*n1+iz] - tzz[iy*n1*n2+ix*n1+iz-1]) + + c2*(tzz[iy*n1*n2+ix*n1+iz+1] - tzz[iy*n1*n2+ix*n1+iz-2])); + + vz[iy*n1*n2+ix*n1+iz] *= bnd.tapxz[(iby-iy)*bnd.ntap+(ix-ibx)]; + } + } + } + } + /* left back corner */ + if (bnd.bac==4) { + iyo = mod.ieZy; + iye = mod.ieZy+bnd.ntap; + ibx = (ixo); + iby = (iyo); +#pragma omp for private(ix,iy,iz) + for (ix=ixo; ix<ixe; ix++) { +#pragma ivdep + for (iy=iyo; iy<iye; iy++) { + for (iz=izo; iz<ize; iz++) { + vz[iy*n1*n2+ix*n1+iz] -= roz[iy*n1*n2+ix*n1+iz]*( + c1*(tzz[iy*n1*n2+ix*n1+iz] - tzz[iy*n1*n2+ix*n1+iz-1]) + + c2*(tzz[iy*n1*n2+ix*n1+iz+1] - tzz[iy*n1*n2+ix*n1+iz-2])); + + vz[iy*n1*n2+ix*n1+iz] *= bnd.tapxz[(iy-iby)*bnd.ntap+(ix-ibx)]; + } + } + } + } + + } + + } + + /*********/ + /* Front */ + /*********/ + if (bnd.fro==4) { + + if (mod.ischeme <= 2) { /* Acoustic scheme */ + + /* Vx field */ + ixo = mod.ioXx; + ixe = mod.ieXx; + iyo = mod.ioXy-bnd.ntap; + iye = mod.ioXy; + izo = mod.ioXz; + ize = mod.ieXz; + + iby = (bnd.ntap+iyo+1); +#pragma omp for private(ix,iy,iz) + for (ix=ixo; ix<ixe; ix++) { +#pragma ivdep + for (iy=iyo; iy<iye; iy++) { + for (iz=izo; iz<ize; iz++) { + vx[iy*n1*n2+ix*n1+iz] -= rox[iy*n1*n2+ix*n1+iz]*( + c1*(tzz[iy*n1*n2+ix*n1+iz] - tzz[iy*n1*n2+(ix-1)*n1+iz]) + + c2*(tzz[iy*n1*n2+(ix+1)*n1+iz] - tzz[iy*n1*n2+(ix-2)*n1+iz])); + + vx[iy*n1*n2+ix*n1+iz] *= bnd.tapy[iby-iy]; + } + } + } + + /* Vy field */ + ixo = mod.ioYx; + ixe = mod.ieYx; + iyo = mod.ioYy-bnd.ntap; + iye = mod.ioYy; + izo = mod.ioYz; + ize = mod.ieYz; + + iby = (bnd.ntap+iyo+1); +#pragma omp for private(ix,iy,iz) + for (ix=ixo; ix<ixe; ix++) { +#pragma ivdep + for (iy=iyo; iy<iye; iy++) { + for (iz=izo; iz<ize; iz++) { + vy[iy*n1*n2+ix*n1+iz] -= roy[iy*n1*n2+ix*n1+iz]*( + c1*(tzz[iy*n1*n2+ix*n1+iz] - tzz[(iy-1)*n1*n2+ix*n1+iz]) + + c2*(tzz[(iy+1)*n1*n2+ix*n1+iz] - tzz[(iy-2)*n1*n2+ix*n1+iz])); + + vy[iy*n1*n2+ix*n1+iz] *= bnd.tapy[iby-iy]; + } + } + } + + /* Vz field */ + ixo = mod.ioZx; + ixe = mod.ieZx; + iyo = mod.ioZy-bnd.ntap; + iye = mod.ioZy; + izo = mod.ioZz; + ize = mod.ieZz; + + iby = (bnd.ntap+iyo+1); +#pragma omp for private (ix,iy,iz) + for (ix=ixo; ix<ixe; ix++) { +#pragma ivdep + for (iy=iyo; iy<iye; iy++) { + for (iz=izo; iz<ize; iz++) { + vz[iy*n1*n2+ix*n1+iz] -= roz[iy*n1*n2+ix*n1+iz]*( + c1*(tzz[iy*n1*n2+ix*n1+iz] - tzz[iy*n1*n2+ix*n1+iz-1]) + + c2*(tzz[iy*n1*n2+ix*n1+iz+1] - tzz[iy*n1*n2+ix*n1+iz-2])); + + vz[iy*n1*n2+ix*n1+iz] *= bnd.tapy[iby-iy]; + } + } + } + } + + } + + /********/ + /* Back */ + /********/ + if (bnd.bac==4) { + + if (mod.ischeme <= 2) { /* Acoustic scheme */ + + /* Vx field */ + ixo = mod.ioXx; + ixe = mod.ieXx; + iyo = mod.ieXy; + iye = mod.ieXy+bnd.ntap; + izo = mod.ioXz; + ize = mod.ieXz; + + iby = (iyo); +#pragma omp for private(ix,iy,iz) + for (ix=ixo; ix<ixe; ix++) { +#pragma ivdep + for (iy=iyo; iy<iye; iy++) { + for (iz=izo; iz<ize; iz++) { + vx[iy*n1*n2+ix*n1+iz] -= rox[iy*n1*n2+ix*n1+iz]*( + c1*(tzz[iy*n1*n2+ix*n1+iz] - tzz[iy*n1*n2+(ix-1)*n1+iz]) + + c2*(tzz[iy*n1*n2+(ix+1)*n1+iz] - tzz[iy*n1*n2+(ix-2)*n1+iz])); + + vx[iy*n1*n2+ix*n1+iz] *= bnd.tapy[iy-iby]; + } + } + } + + /* Vy field */ + ixo = mod.ioYx; + ixe = mod.ieYx; + iyo = mod.ieYy; + iye = mod.ieYy+bnd.ntap; + izo = mod.ioYz; + ize = mod.ieYz; + + iby = (iyo); +#pragma omp for private(ix,iy,iz) + for (ix=ixo; ix<ixe; ix++) { +#pragma ivdep + for (iy=iyo; iy<iye; iy++) { + for (iz=izo; iz<ize; iz++) { + vy[iy*n1*n2+ix*n1+iz] -= roy[iy*n1*n2+ix*n1+iz]*( + c1*(tzz[iy*n1*n2+ix*n1+iz] - tzz[(iy-1)*n1*n2+ix*n1+iz]) + + c2*(tzz[(iy+1)*n1*n2+ix*n1+iz] - tzz[(iy-2)*n1*n2+ix*n1+iz])); + + vy[iy*n1*n2+ix*n1+iz] *= bnd.tapy[iy-iby]; + } + } + } + + /* Vz field */ + ixo = mod.ioZx; + ixe = mod.ieZx; + iyo = mod.ioZy; + iye = mod.ieZy+bnd.ntap; + izo = mod.ioZz; + ize = mod.ieZz; + + iby = (iyo); +#pragma omp for private (ix,iy,iz) + for (ix=ixo; ix<ixe; ix++) { +#pragma ivdep + for (iy=iyo; iy<iye; iy++) { + for (iz=izo; iz<ize; iz++) { + vz[iy*n1*n2+ix*n1+iz] -= roz[iy*n1*n2+ix*n1+iz]*( + c1*(tzz[iy*n1*n2+ix*n1+iz] - tzz[iy*n1*n2+ix*n1+iz-1]) + + c2*(tzz[iy*n1*n2+ix*n1+iz+1] - tzz[iy*n1*n2+ix*n1+iz-2])); + + vz[iy*n1*n2+ix*n1+iz] *= bnd.tapy[iy-iby]; + } + } + } + } + + } + + if ( (npml != 0) && (itime==mod.nt-1) && pml) { +#pragma omp master +{ + if (allocated) { + free(Vxpml); + free(Vzpml); + free(sigmu); + free(RA); + allocated=0; + } +} + } + + return 0; +} + +long boundariesV3D(modPar mod, bndPar bnd, float *vx, float *vy, float *vz, float *tzz, float *tyy, float *txx, float *txz, float *txy, float *tyz, float *rox, float *roy, float *roz, float *l2m, float *lam, float *mul, long itime, long verbose) +{ +/********************************************************************* + + AUTHOR: + Jan Thorbecke (janth@xs4all.nl) + The Netherlands + +***********************************************************************/ + + float c1, c2; + float dp, dvx, dvy, dvz; + long ix, iy, iz, ixs, iys, izs, izp, ib; + long nx, ny, nz, n1, n2, n3; + long is0, isrc; + long ixo, ixe, iyo, iye, izo, ize; + long npml, ipml, ipml2, pml; + float kappu, alphu, sigmax, R, a, m, fac, dx, dy, dt; + float *p; + static float *Pxpml, *Pypml, *Pzpml, *sigmu, *RA; + static long allocated=0; + float Jx, Jy, Jz, rho, d; + + c1 = 9.0/8.0; + c2 = -1.0/24.0; + nx = mod.nx; + ny = mod.ny; + nz = mod.nz; + n1 = mod.naz; + n2 = mod.nax; + n3 = mod.nay; + dx = mod.dx; + dy = mod.dy; + dt = mod.dt; + fac = dt/dx; + if ( (bnd.top==2) || (bnd.bot==2) || (bnd.lef==2) || (bnd.rig==2) ) pml=1; + else pml=0; + +/************************************************************/ +/* PML boundaries for acoustic schemes */ +/* compute all field values in tapered areas */ +/************************************************************/ + + npml=bnd.npml; /* lenght of pml in grid-points */ + if ( (npml != 0) && (itime==0) && pml) { +#pragma omp master +{ + if (allocated) { + free(Pxpml); + free(Pypml); + free(Pzpml); + free(sigmu); + free(RA); + } + Pxpml = (float *)calloc(2*n1*n3*npml,sizeof(float)); + Pypml = (float *)calloc(2*n2*n1*npml,sizeof(float)); + Pzpml = (float *)calloc(2*n3*n2*npml,sizeof(float)); + sigmu = (float *)calloc(npml,sizeof(float)); + RA = (float *)calloc(npml,sizeof(float)); + allocated = 1; + + /* calculate sigmu and RA only once with fixed velocity Cp */ + m=bnd.m; /* scaling order */ + R=bnd.R; /* the theoretical reflection coefficient after discretization */ + kappu = 1.0; /* auxiliary attenuation coefficient for small angles */ + alphu=0.0; /* auxiliary attenuation coefficient for low frequencies */ + d = (npml-1)*dx; /* depth of pml */ + /* sigmu attenuation factor representing the loss in the PML depends on the grid position in the PML */ + + sigmax = ((3.0*mod.cp_min)/(2.0*d))*log(1.0/R); + for (ib=0; ib<npml; ib++) { /* ib=0 interface between PML and interior */ + a = (float) (ib/(npml-1.0)); + sigmu[ib] = sigmax*pow(a,m); + RA[ib] = (1.0)/(1.0+0.5*dt*sigmu[ib]); + } +} + } + +#pragma omp barrier + if (mod.ischeme == 1 && pml) { /* Acoustic scheme PML's */ + p = tzz; /* Tzz array pointer points to P-field */ + + if (bnd.top==2) mod.ioPz += bnd.npml; + if (bnd.bot==2) mod.iePz -= bnd.npml; + if (bnd.lef==2) mod.ioPx += bnd.npml; + if (bnd.rig==2) mod.iePx -= bnd.npml; + if (bnd.fro==2) mod.ioPy += bnd.npml; + if (bnd.bac==2) mod.iePy -= bnd.npml; + + /* PML top P */ + if (bnd.top == 2) { + /* PML top P-Vz-component */ +#pragma omp for private (ix, iy, iz, dvx, dvy, dvz, Jz, ipml) + for (iy=mod.ioPy; iy<mod.iePy; iy++) { + ipml2 = npml-1; + for (ix=mod.ioPx; ix<mod.iePx; ix++) { + ipml = npml-1; + for (iz=mod.ioPz-npml; iz<mod.ioPz; iz++) { + dvx = c1*(vx[iy*n2*n1+(ix+1)*n1+iz] - vx[iy*n2*n1+ix*n1+iz]) + + c2*(vx[iy*n2*n1+(ix+2)*n1+iz] - vx[iy*n2*n1+(ix-1)*n1+iz]); + dvy = c1*(vy[(iy+1)*n2*n1+ix*n1+iz] - vy[iy*n2*n1+ix*n1+iz]) + + c2*(vy[(iy+2)*n2*n1+ix*n1+iz] - vy[(iy-1)*n2*n1+ix*n1+iz]); + dvz = c1*(vz[iy*n2*n1+ix*n1+iz+1] - vz[iy*n2*n1+ix*n1+iz]) + + c2*(vz[iy*n2*n1+ix*n1+iz+2] - vz[iy*n2*n1+ix*n1+iz-1]); + Jz = RA[ipml2]*RA[ipml]*dvz - RA[ipml2]*RA[ipml]*dt*Pzpml[ix*npml+ipml]; + Pzpml[ix*npml+ipml] += sigmu[ipml]*Jz; + p[ix*n1+iz] -= l2m[ix*n1+iz]*(Jz+dvx); + ipml--; + } + } + } + } + + /* PML left P */ + if (bnd.lef == 2) { + /* PML left P-Vx-component */ +#pragma omp for private (ix, iz, dvx, dvz, Jx, ipml) + for (iz=mod.ioPz; iz<mod.iePz; iz++) { + ipml = npml-1; + for (ix=mod.ioPx-npml; ix<mod.ioPx; ix++) { + dvx = c1*(vx[(ix+1)*n1+iz] - vx[ix*n1+iz]) + + c2*(vx[(ix+2)*n1+iz] - vx[(ix-1)*n1+iz]); + dvz = c1*(vz[ix*n1+iz+1] - vz[ix*n1+iz]) + + c2*(vz[ix*n1+iz+2] - vz[ix*n1+iz-1]); + Jx = RA[ipml]*dvx - RA[ipml]*dt*Pxpml[iz*npml+ipml]; + Pxpml[iz*npml+ipml] += sigmu[ipml]*Jx; + p[ix*n1+iz] -= l2m[ix*n1+iz]*(Jx+dvz); + ipml--; + } + } + } + + /* PML corner left-top P */ + if (bnd.lef == 2 && bnd.top == 2) { + /* PML left P-Vx-component */ +#pragma omp for private (ix, iz, dvx, Jx, ipml) + for (iz=mod.ioPz-npml; iz<mod.ioPz; iz++) { + ipml = npml-1; + for (ix=mod.ioPx-npml; ix<mod.ioPx; ix++) { + dvx = c1*(vx[(ix+1)*n1+iz] - vx[ix*n1+iz]) + + c2*(vx[(ix+2)*n1+iz] - vx[(ix-1)*n1+iz]); + Jx = RA[ipml]*dvx - RA[ipml]*dt*Pxpml[iz*npml+ipml]; + Pxpml[iz*npml+ipml] += sigmu[ipml]*Jx; + p[ix*n1+iz] -= l2m[ix*n1+iz]*(Jx); + ipml--; + } + } + /* PML top P-Vz-component */ +#pragma omp for private (ix, iz, dvz, Jz, ipml) + for (ix=mod.ioPx-npml; ix<mod.ioPx; ix++) { + ipml = npml-1; + for (iz=mod.ioPz-npml; iz<mod.ioPz; iz++) { + dvz = c1*(vz[ix*n1+iz+1] - vz[ix*n1+iz]) + + c2*(vz[ix*n1+iz+2] - vz[ix*n1+iz-1]); + Jz = RA[ipml]*dvz - RA[ipml]*dt*Pzpml[ix*npml+ipml]; + Pzpml[ix*npml+ipml] += sigmu[ipml]*Jz; + p[ix*n1+iz] -= l2m[ix*n1+iz]*(Jz); + ipml--; + } + } + } + + /* PML right P */ + if (bnd.rig == 2) { + /* PML right P Vx-component */ +#pragma omp for private (ix, iz, dvx, dvz, Jx, ipml) + for (iz=mod.ioPz; iz<mod.iePz; iz++) { + ipml = 0; + for (ix=mod.iePx; ix<mod.iePx+npml; ix++) { + dvx = c1*(vx[(ix+1)*n1+iz] - vx[ix*n1+iz]) + + c2*(vx[(ix+2)*n1+iz] - vx[(ix-1)*n1+iz]); + dvz = c1*(vz[ix*n1+iz+1] - vz[ix*n1+iz]) + + c2*(vz[ix*n1+iz+2] - vz[ix*n1+iz-1]); + Jx = RA[ipml]*dvx - RA[ipml]*dt*Pxpml[n1*npml+iz*npml+ipml]; + Pxpml[n1*npml+iz*npml+ipml] += sigmu[ipml]*Jx; + p[ix*n1+iz] -= l2m[ix*n1+iz]*(Jx+dvz); + ipml++; + } + } + } + + /* PML corner right-top P */ + if (bnd.rig == 2 && bnd.top == 2) { + /* PML right P Vx-component */ +#pragma omp for private (ix, iz, dvx, Jx, ipml) + for (iz=mod.ioPz-npml; iz<mod.ioPz; iz++) { + ipml = 0; + for (ix=mod.iePx; ix<mod.iePx+npml; ix++) { + dvx = c1*(vx[(ix+1)*n1+iz] - vx[ix*n1+iz]) + + c2*(vx[(ix+2)*n1+iz] - vx[(ix-1)*n1+iz]); + Jx = RA[ipml]*dvx - RA[ipml]*dt*Pxpml[n1*npml+iz*npml+ipml]; + Pxpml[n1*npml+iz*npml+ipml] += sigmu[ipml]*Jx; + p[ix*n1+iz] -= l2m[ix*n1+iz]*(Jx); + ipml++; + } + } + /* PML top P-Vz-component */ +#pragma omp for private (ix, iz, dvz, Jz, ipml) + for (ix=mod.iePx; ix<mod.iePx+npml; ix++) { + ipml = npml-1; + for (iz=mod.ioPz-npml; iz<mod.ioPz; iz++) { + dvz = c1*(vz[ix*n1+iz+1] - vz[ix*n1+iz]) + + c2*(vz[ix*n1+iz+2] - vz[ix*n1+iz-1]); + Jz = RA[ipml]*dvz - RA[ipml]*dt*Pzpml[ix*npml+ipml]; + Pzpml[ix*npml+ipml] += sigmu[ipml]*Jz; + p[ix*n1+iz] -= l2m[ix*n1+iz]*(Jz); + ipml--; + } + } + } + + /* PML bottom P */ + if (bnd.bot == 2) { + /* PML bottom P Vz-component */ +#pragma omp for private (ix, iz, dvx, dvz, Jz, ipml) + for (ix=mod.ioPx; ix<mod.iePx; ix++) { + ipml = 0; + for (iz=mod.iePz; iz<mod.iePz+npml; iz++) { + dvx = c1*(vx[(ix+1)*n1+iz] - vx[ix*n1+iz]) + + c2*(vx[(ix+2)*n1+iz] - vx[(ix-1)*n1+iz]); + dvz = c1*(vz[ix*n1+iz+1] - vz[ix*n1+iz]) + + c2*(vz[ix*n1+iz+2] - vz[ix*n1+iz-1]); + Jz = RA[ipml]*dvz - RA[ipml]*dt*Pzpml[n2*npml+ix*npml+ipml]; + Pzpml[n2*npml+ix*npml+ipml] += sigmu[ipml]*Jz; + p[ix*n1+iz] -= l2m[ix*n1+iz]*(Jz+dvx); + ipml++; + } + } + } + + /* PML corner bottom-right P */ + if (bnd.bot == 2 && bnd.rig == 2) { + /* PML bottom P Vz-component */ +#pragma omp for private (ix, iz, dvz, Jz, ipml) + for (ix=mod.iePx; ix<mod.iePx+npml; ix++) { + ipml = 0; + for (iz=mod.iePz; iz<mod.iePz+npml; iz++) { + dvz = c1*(vz[ix*n1+iz+1] - vz[ix*n1+iz]) + + c2*(vz[ix*n1+iz+2] - vz[ix*n1+iz-1]); + Jz = RA[ipml]*dvz - RA[ipml]*dt*Pzpml[n2*npml+ix*npml+ipml]; + Pzpml[n2*npml+ix*npml+ipml] += sigmu[ipml]*Jz; + p[ix*n1+iz] -= l2m[ix*n1+iz]*(Jz); + ipml++; + } + } + /* PML right P Vx-component */ +#pragma omp for private (ix, iz, dvx, Jx, ipml) + for (iz=mod.iePz; iz<mod.iePz+npml; iz++) { + ipml = 0; + for (ix=mod.iePx; ix<mod.iePx+npml; ix++) { + dvx = c1*(vx[(ix+1)*n1+iz] - vx[ix*n1+iz]) + + c2*(vx[(ix+2)*n1+iz] - vx[(ix-1)*n1+iz]); + Jx = RA[ipml]*dvx - RA[ipml]*dt*Pxpml[n1*npml+iz*npml+ipml]; + Pxpml[n1*npml+iz*npml+ipml] += sigmu[ipml]*Jx; + p[ix*n1+iz] -= l2m[ix*n1+iz]*(Jx); + //p[ix*n1+iz] -= l2m[ix*n1+iz]*(dvx); + ipml++; + } + } + } + + /* PML corner left-bottom P */ + if (bnd.bot == 2 && bnd.lef == 2) { + /* PML bottom P Vz-component */ +#pragma omp for private (ix, iz, dvz, Jz, ipml) + for (ix=mod.ioPx-npml; ix<mod.ioPx; ix++) { + ipml = 0; + for (iz=mod.iePz; iz<mod.iePz+npml; iz++) { + dvz = c1*(vz[ix*n1+iz+1] - vz[ix*n1+iz]) + + c2*(vz[ix*n1+iz+2] - vz[ix*n1+iz-1]); + Jz = RA[ipml]*dvz - RA[ipml]*dt*Pzpml[n2*npml+ix*npml+ipml]; + Pzpml[n2*npml+ix*npml+ipml] += sigmu[ipml]*Jz; + p[ix*n1+iz] -= l2m[ix*n1+iz]*(Jz); + ipml++; + } + } + /* PML left P Vx-component */ +#pragma omp for private (ix, iz, dvx, Jx, ipml) + for (iz=mod.iePz; iz<mod.iePz+npml; iz++) { + ipml = npml-1; + for (ix=mod.ioPx-npml; ix<mod.ioPx; ix++) { + dvx = c1*(vx[(ix+1)*n1+iz] - vx[ix*n1+iz]) + + c2*(vx[(ix+2)*n1+iz] - vx[(ix-1)*n1+iz]); + Jx = RA[ipml]*dvx - RA[ipml]*dt*Pxpml[iz*npml+ipml]; + Pxpml[iz*npml+ipml] += sigmu[ipml]*Jx; + p[ix*n1+iz] -= l2m[ix*n1+iz]*(Jx); + ipml--; + } + } + } + if (bnd.top==2) mod.ioPz -= bnd.npml; + if (bnd.bot==2) mod.iePz += bnd.npml; + if (bnd.lef==2) mod.ioPx -= bnd.npml; + if (bnd.rig==2) mod.iePx += bnd.npml; + + } /* end acoustic PML */ + + + +/****************************************************************/ +/* Free surface: calculate free surface conditions for stresses */ +/****************************************************************/ + + + ixo = mod.ioPx; + ixe = mod.iePx; + iyo = mod.ioPy; + iye = mod.iePy; + izo = mod.ioPz; + ize = mod.iePz; + + if (mod.ischeme <= 2) { /* Acoustic scheme */ + if (bnd.top==1) { /* free surface at top */ +#pragma omp for private (ix,iy) nowait + for (ix=mod.ioPx; ix<mod.iePx; ix++) { + for (iy=mod.ioPy; iy<mod.iePy; iy++) { + iz = bnd.surface[iy*n2+ix]; + tzz[iy*n2*n1+ix*n1+iz] = 0.0; + //vz[ix*n1+iz] = -vz[ix*n1+iz+1]; + //vz[ix*n1+iz-1] = -vz[ix*n1+iz+2]; + } + } + } + if (bnd.rig==1) { /* free surface at right */ +#pragma omp for private (iy,iz) nowait + for (iz=mod.ioPz; iz<mod.iePz; iz++) { + for (iy=mod.ioPy; iy<mod.iePy; iy++) { + tzz[iy*n1*n2+(mod.iePx-1)*n1+iz] = 0.0; + } + } + } + if (bnd.fro==1) { /* free surface at front */ +#pragma omp for private (ix,iz) nowait + for (iz=mod.ioPz; iz<mod.iePz; iz++) { + for (ix=mod.ioPx; ix<mod.iePx; ix++) { + tzz[(mod.ioPy-1)*n1*n2+ix*n1+iz] = 0.0; + } + } + } + if (bnd.bot==1) { /* free surface at bottom */ +#pragma omp for private (ix,iy) nowait + for (ix=mod.ioPx; ix<mod.iePx; ix++) { + for (iy=mod.ioPy; iy<mod.iePy; iy++) { + tzz[iy*n1*n2+ix*n1+mod.iePz-1] = 0.0; + } + } + } + if (bnd.lef==1) { /* free surface at left */ +#pragma omp for private (iy,iz) nowait + for (iz=mod.ioPz; iz<mod.iePz; iz++) { + for (iy=mod.ioPy; iy<mod.iePy; iy++) { + tzz[iy*n1*n2+(mod.ioPx-1)*n1+iz] = 0.0; + } + } + } + if (bnd.bac==1) { /* free surface at back */ +#pragma omp for private (ix,iz) nowait + for (iz=mod.ioPz; iz<mod.iePz; iz++) { + for (ix=mod.ioPx; ix<mod.iePx; ix++) { + tzz[(mod.iePy-1)*n1*n2+ix*n1+iz] = 0.0; + } + } + } + } + + if ( (npml != 0) && (itime==mod.nt-1) && pml) { +#pragma omp master +{ + if (allocated) { + free(Pxpml); + free(Pypml); + free(Pzpml); + free(sigmu); + free(RA); + allocated=0; + } +} + } + + return 0; +} diff --git a/fdelmodc3D/fdelmodc3D.c b/fdelmodc3D/fdelmodc3D.c index a79ede1..8ba30a7 100644 --- a/fdelmodc3D/fdelmodc3D.c +++ b/fdelmodc3D/fdelmodc3D.c @@ -589,51 +589,41 @@ shared (shot, bnd, mod, src, wav, rec, ixsrc, iysrc, izsrc, it, src_nwav, verbos // vx, vz, tzz, rox, roz, l2m, verbose); // break; case -1 : /* Acoustic dissipative media FD kernel */ - acoustic4_qr(mod, src, wav, bnd, it, ixsrc, izsrc, src_nwav, - vx, vz, tzz, rox, roz, l2m, verbose); + vmess("Acoustic dissipative not yet available"); break; case 1 : /* Acoustic FD kernel */ if (mod.iorder==2) { - acoustic2(mod, src, wav, bnd, it, ixsrc, izsrc, src_nwav, - vx, vz, tzz, rox, roz, l2m, verbose); + vmess("Acoustic order 2 not yet available"); } else if (mod.iorder==4) { if (mod.sh) { - acousticSH4(mod, src, wav, bnd, it, ixsrc, izsrc, src_nwav, - vx, vz, tzz, rox, roz, l2m, verbose); + vmess("SH order 4 not yet available"); } else { - acoustic4(mod, src, wav, bnd, it, ixsrc, izsrc, src_nwav, - vx, vz, tzz, rox, roz, l2m, verbose); + acoustic4_3D(mod, src, wav, bnd, it, ixsrc, iysrc, izsrc, src_nwav, + vx, vy, vz, tzz, rox, roy, roz, l2m, verbose); } } else if (mod.iorder==6) { - acoustic6(mod, src, wav, bnd, it, ixsrc, izsrc, src_nwav, - vx, vz, tzz, rox, roz, l2m, verbose); + vmess("Acoustic order 6 not yet available"); } break; case 2 : /* Visco-Acoustic FD kernel */ - viscoacoustic4(mod, src, wav, bnd, it, ixsrc, izsrc, src_nwav, - vx, vz, tzz, rox, roz, l2m, tss, tep, q, verbose); + vmess("Visco-Acoustic order 4 not yet available"); break; case 3 : /* Elastic FD kernel */ if (mod.iorder==4) { - elastic4(mod, src, wav, bnd, it, ixsrc, izsrc, src_nwav, - vx, vz, tzz, txx, txz, rox, roz, l2m, lam, mul, verbose); + vmess("Elastic order 4 not yet available"); } else if (mod.iorder==6) { - elastic6(mod, src, wav, bnd, it, ixsrc, izsrc, src_nwav, - vx, vz, tzz, txx, txz, rox, roz, l2m, lam, mul, verbose); + vmess("Elastic order 6 not yet available"); } break; case 4 : /* Visco-Elastic FD kernel */ - viscoelastic4(mod, src, wav, bnd, it, ixsrc, izsrc, src_nwav, - vx, vz, tzz, txx, txz, rox, roz, l2m, lam, mul, - tss, tep, tes, r, q, p, verbose); + vmess("Visco-Elastic order 4 not yet available"); break; case 5 : /* Elastic FD kernel with S-velocity set to zero*/ - elastic4dc(mod, src, wav, bnd, it, ixsrc, izsrc, src_nwav, - vx, vz, tzz, txx, txz, rox, roz, l2m, lam, mul, verbose); + vmess("DC-Elastic order 4 not yet available"); break; } diff --git a/fdelmodc3D/getRecTimes3D.c b/fdelmodc3D/getRecTimes3D.c new file mode 100644 index 0000000..ea2c276 --- /dev/null +++ b/fdelmodc3D/getRecTimes3D.c @@ -0,0 +1,324 @@ +#include<stdlib.h> +#include<stdio.h> +#include<math.h> +#include<assert.h> +#include"fdelmodc3D.h" +#include"par.h" + +/** +* Stores the wavefield at the receiver positions. +* +* On a staggered grid the fields are all on different positions, +* to compensate for that the rec.int_vx and rec.int_vz options +* can be set. +* +* AUTHOR: +* Jan Thorbecke (janth@xs4all.nl) +* The Netherlands +**/ + +int getRecTimes3D(modPar mod, recPar rec, bndPar bnd, int itime, int isam, float *vx, float *vy, float *vz, float *tzz, float *tyy, float *txx, float *txz, float *txy, float *tyz, float *l2m, float *rox, float *roy, float *roz, float *rec_vx, float *rec_vy, float *rec_vz, float *rec_txx, float *rec_tyy, float *rec_tzz, float *rec_txz, float *rec_txy, float *rec_tyz, float *rec_p, float *rec_pp, float *rec_ss, float *rec_udp, float *rec_udvz, int verbose) +{ + int n1, n2, ibndx, ibndy, ibndz; + int irec, ix, iy, iz, ix2, iy2, iz2, ix1, iy1, iz1; + float dvx, dvy, dvz, rdz, rdy, rdx; + float C000, C100, C010, C001, C110, C101, C011, C111; + float *vz_t, c1, c2, lroz, field; + + ibndx = mod.ioPx; + ibndy = mod.ioPy; + ibndz = mod.ioPz; + if (bnd.lef==4 || bnd.lef==2) ibndx += bnd.ntap; + if (bnd.bac==4 || bnd.fro==2) ibndy += bnd.ntap; + if (bnd.top==4 || bnd.top==2) ibndz += bnd.ntap; + n1 = mod.naz; + n2 = mod.nax; + c1 = 9.0/8.0; + c2 = -1.0/24.0; + + if (!rec.n) return 0; + +/*********************************************************************** +* velocity or txz or potential registrations issues: +* rec_x and rec_z are related to actual txx/tzz/p positions. +* offsets from virtual boundaries must be taken into account. +* +* vx velocities have one sample less in x-direction +* vz velocities have one sample less in z-direction +* txz stresses have one sample less in z-direction and x-direction +* +* Note, in the acoustic scheme P is stored in the Tzz array. +***********************************************************************/ + + for (irec=0; irec<rec.n; irec++) { + iz = rec.z[irec]+ibndz; + iy = rec.y[irec]+ibndy; + ix = rec.x[irec]+ibndx; + iz1 = iz-1; + iy1 = iy-1; + ix1 = ix-1; + iz2 = iz+1; + iy2 = iy+1; + ix2 = ix+1; + /* interpolation to precise (not necessary on a grid point) position */ + if ( rec.int_p==3 ) { + + iz = (int)floorf(rec.zr[irec]/mod.dz)+ibndz; + iy = (int)floorf(rec.yr[irec]/mod.dy)+ibndy; + ix = (int)floorf(rec.xr[irec]/mod.dx)+ibndx; + rdz = (rec.zr[irec] - (iz-ibndz)*mod.dz)/mod.dz; + rdy = (rec.yr[irec] - (iy-ibndy)*mod.dy)/mod.dy; + rdx = (rec.xr[irec] - (ix-ibndx)*mod.dx)/mod.dx; + iz1 = iz-1; + iy1 = iy-1; + ix1 = ix-1; + iz2 = iz+1; + iy2 = iy+1; + ix2 = ix+1; + + /* + // Interpolate according to Dirk Kraaijpool's scheme + // Reference: "Seismic ray fields and ray field maps : theory and algorithms" , + // PhD thesis Utrecht University,Faculty of Geosciences, 2003) + + C00 = tzz[ix*n1+iz] + 0.5*((tzz[(ix+1)*n1+iz] +tzz[(ix-1)*n1+iz]+ + tzz[(ix )*n1+iz+1] +tzz[(ix )*n1+iz-1])/(2.0*mod.dx)); + C10 = tzz[(ix+1)*n1+iz] + 0.5*((tzz[(ix+2)*n1+iz] +tzz[(ix )*n1+iz]+ + tzz[(ix+1)*n1+iz+1] +tzz[(ix+1)*n1+iz-1])/(2.0*mod.dz)); + C01 = tzz[ix*n1+iz+1] + 0.5*((tzz[(ix+1)*n1+iz+1] +tzz[(ix-1)*n1+iz+1]+ + tzz[(ix)*n1+iz+2] +tzz[(ix )*n1+iz])/(2.0*mod.dx)); + C11 = tzz[(ix+1)*n1+iz+1]+ 0.5*((tzz[(ix+2)*n1+iz+1] +tzz[(ix )*n1+iz+1]+ + tzz[(ix+1)*n1+iz+2] +tzz[(ix+1)*n1+iz])/(2.0*mod.dz)); + */ + + if (rec.type.p){ + /* bi-linear interpolation */ + C000 = tzz[iy*n1*n2+ix*n1+iz]; + C100 = tzz[iy*n1*n2+(ix+1)*n1+iz]; + C010 = tzz[iy*n1*n2+ix*n1+iz+1]; + C001 = tzz[(iy+1)*n1*n2+ix*n1+iz]; + C110 = tzz[iy*n1*n2+(ix+1)*n1+iz+1]; + C101 = tzz[(iy+1)*n1*n2+ix*n1+iz+1]; + C011 = tzz[(iy+1)*n1*n2+(ix+1)*n1+iz]; + C111 = tzz[(iy+1)*n1*n2+(ix+1)*n1+iz+1]; + rec_p[irec*rec.nt+isam] = C000*(1.0-rdx)*(1.0-rdy)*(1.0-rdz) + + C100*rdx*(1.0-rdy)*(1.0-rdz) + + C010*(1.0-rdx)*(1.0-rdy)*rdz + + C11*rdx*rdz; + } + if (rec.type.txx) { + C00 = txx[ix*n1+iz]; + C10 = txx[(ix+1)*n1+iz]; + C01 = txx[ix*n1+iz+1]; + C11 = txx[(ix+1)*n1+iz+1]; + rec_txx[irec*rec.nt+isam] = C00*(1.0-rdx)*(1.0-rdz) + C10*rdx*(1.0-rdz) + + C01*(1.0-rdx)*rdz + C11*rdx*rdz; + } + if (rec.type.tzz) { + C00 = tzz[ix*n1+iz]; + C10 = tzz[(ix+1)*n1+iz]; + C01 = tzz[ix*n1+iz+1]; + C11 = tzz[(ix+1)*n1+iz+1]; + rec_tzz[irec*rec.nt+isam] = C00*(1.0-rdx)*(1.0-rdz) + C10*rdx*(1.0-rdz) + + C01*(1.0-rdx)*rdz + C11*rdx*rdz; + } + if (rec.type.txz) { + C00 = txz[ix2*n1+iz2]; + C10 = txz[(ix2+1)*n1+iz2]; + C01 = txz[ix2*n1+iz2+1]; + C11 = txz[(ix2+1)*n1+iz2+1]; + rec_txz[irec*rec.nt+isam] = C00*(1.0-rdx)*(1.0-rdz) + C10*rdx*(1.0-rdz) + + C01*(1.0-rdx)*rdz + C11*rdx*rdz; + } + if (rec.type.pp) { + C00 = (vx[ix2*n1+iz]-vx[ix*n1+iz] + + vz[ix*n1+iz2]-vz[ix*n1+iz])/mod.dx; + C10 = (vx[(ix2+1)*n1+iz]-vx[(ix+1)*n1+iz] + + vz[(ix+1)*n1+iz2]-vz[(ix+1)*n1+iz])/mod.dx; + C01 = (vx[ix2*n1+iz+1]-vx[ix*n1+iz+1] + + vz[ix*n1+iz2+1]-vz[ix*n1+iz+1])/mod.dx; + C11 = (vx[(ix2+1)*n1+iz+1]-vx[(ix+1)*n1+iz+1] + + vz[(ix+1)*n1+iz2+1]-vz[(ix+1)*n1+iz+1])/mod.dx; + rec_pp[irec*rec.nt+isam] = C00*(1.0-rdx)*(1.0-rdz) + C10*rdx*(1.0-rdz) + + C01*(1.0-rdx)*rdz + C11*rdx*rdz; + } + if (rec.type.ss) { + C00 = (vx[ix2*n1+iz2]-vx[ix2*n1+iz] - + (vz[ix2*n1+iz2]-vz[ix*n1+iz2]))/mod.dx; + C10 = (vx[(ix2+1)*n1+iz2]-vx[(ix2+1)*n1+iz] - + (vz[(ix2+1)*n1+iz2]-vz[(ix+1)*n1+iz2]))/mod.dx; + C01 = (vx[ix2*n1+iz2+1]-vx[ix2*n1+iz+1] - + (vz[ix2*n1+iz2+1]-vz[ix*n1+iz2+1]))/mod.dx;; + C11 = (vx[(ix2+1)*n1+iz2+1]-vx[(ix2+1)*n1+iz+1] - + (vz[(ix2+1)*n1+iz2+1]-vz[(ix+1)*n1+iz2+1]))/mod.dx; + rec_ss[irec*rec.nt+isam] = C00*(1.0-rdx)*(1.0-rdz) + C10*rdx*(1.0-rdz) + + C01*(1.0-rdx)*rdz + C11*rdx*rdz; + } + if (rec.type.vz) { + C00 = vz[ix*n1+iz2]; + C10 = vz[(ix+1)*n1+iz2]; + C01 = vz[ix*n1+iz2+1]; + C11 = vz[(ix+1)*n1+iz2+1]; + rec_vz[irec*rec.nt+isam] = C00*(1.0-rdx)*(1.0-rdz) + C10*rdx*(1.0-rdz) + + C01*(1.0-rdx)*rdz + C11*rdx*rdz; + } + if (rec.type.vx) { + C00 = vx[ix2*n1+iz]; + C10 = vx[(ix2+1)*n1+iz]; + C01 = vx[ix2*n1+iz+1]; + C11 = vx[(ix2+1)*n1+iz+1]; + rec_vx[irec*rec.nt+isam] = C00*(1.0-rdx)*(1.0-rdz) + C10*rdx*(1.0-rdz) + + C01*(1.0-rdx)*rdz + C11*rdx*rdz; + } + + } + else { /* read values directly from the grid points */ + if (verbose>=4 && isam==0) { + vmess("Receiver %d read at gridpoint ix=%d iz=%d",irec, ix, iz); + } + /* interpolation of receivers to same time step is only done for acoustic scheme */ + if (rec.type.p) { + if (rec.int_p == 1) { + if (mod.ischeme == 1) { /* interpolate Tzz times -1/2 Dt backward to Vz times */ + dvx = c1*(vx[(ix+1)*n1+iz] - vx[ix*n1+iz]) + + c2*(vx[(ix+2)*n1+iz] - vx[(ix-1)*n1+iz]); + dvz = c1*(vz[ix*n1+iz+1] - vz[ix*n1+iz]) + + c2*(vz[ix*n1+iz+2] - vz[ix*n1+iz-1]); + field = tzz[ix*n1+iz] + 0.5*l2m[ix*n1+iz]*(dvx+dvz); + dvx = c1*(vx[(ix+1)*n1+iz1] - vx[ix*n1+iz1]) + + c2*(vx[(ix+2)*n1+iz1] - vx[(ix-1)*n1+iz1]); + dvz = c1*(vz[ix*n1+iz1+1] - vz[ix*n1+iz1]) + + c2*(vz[ix*n1+iz1+2] - vz[ix*n1+iz1-1]); + field += tzz[ix*n1+iz1] + 0.5*l2m[ix*n1+iz1]*(dvx+dvz); + rec_p[irec*rec.nt+isam] = 0.5*field; + } + else { + rec_p[irec*rec.nt+isam] = 0.5*(tzz[ix*n1+iz1]+tzz[ix*n1+iz]); + } + } + else if (rec.int_p == 2) { + if (mod.ischeme == 1) { /* interpolate Tzz times -1/2 Dt backward to Vx times */ + dvx = c1*(vx[(ix+1)*n1+iz] - vx[ix*n1+iz]) + + c2*(vx[(ix+2)*n1+iz] - vx[(ix-1)*n1+iz]); + dvz = c1*(vz[ix*n1+iz+1] - vz[ix*n1+iz]) + + c2*(vz[ix*n1+iz+2] - vz[ix*n1+iz-1]); + field = tzz[ix*n1+iz] + 0.5*l2m[ix*n1+iz]*(dvx+dvz); + dvx = c1*(vx[(ix1+1)*n1+iz] - vx[ix1*n1+iz]) + + c2*(vx[(ix+2)*n1+iz] - vx[(ix1-1)*n1+iz]); + dvz = c1*(vz[ix1*n1+iz+1] - vz[ix1*n1+iz]) + + c2*(vz[ix1*n1+iz+2] - vz[ix1*n1+iz-1]); + field += tzz[ix1*n1+iz] + 0.5*l2m[ix1*n1+iz]*(dvx+dvz); + rec_p[irec*rec.nt+isam] = 0.5*field; + } + else { + rec_p[irec*rec.nt+isam] = 0.5*(tzz[ix1*n1+iz]+tzz[ix*n1+iz]); + } + } + else { + rec_p[irec*rec.nt+isam] = tzz[ix*n1+iz]; + } + } + if (rec.type.txx) rec_txx[irec*rec.nt+isam] = txx[ix*n1+iz]; + if (rec.type.tzz) rec_tzz[irec*rec.nt+isam] = tzz[ix*n1+iz]; + if (rec.type.txz) { /* time interpolation to be done */ + if (rec.int_vz == 2 || rec.int_vx == 2) { + rec_txz[irec*rec.nt+isam] = 0.25*( + txz[ix*n1+iz2]+txz[ix2*n1+iz2]+ + txz[ix*n1+iz]+txz[ix2*n1+iz]); + } + else { + rec_txz[irec*rec.nt+isam] = txz[ix2*n1+iz2]; + } + } + if (rec.type.pp) { + rec_pp[irec*rec.nt+isam] = (vx[ix2*n1+iz]-vx[ix*n1+iz] + + vz[ix*n1+iz2]-vz[ix*n1+iz])/mod.dx; + } + if (rec.type.ss) { + rec_ss[irec*rec.nt+isam] = (vx[ix2*n1+iz2]-vx[ix2*n1+iz] - + (vz[ix2*n1+iz2]-vz[ix*n1+iz2]))/mod.dx; + } + if (rec.type.vz) { +/* interpolate vz to vx position to the right and above of vz */ + if (rec.int_vz == 1) { + rec_vz[irec*rec.nt+isam] = 0.25*( + vz[ix*n1+iz2]+vz[ix1*n1+iz2]+ + vz[ix*n1+iz] +vz[ix1*n1+iz]); + } +/* interpolate vz to Txx/Tzz position by taking the mean of 2 values */ + else if (rec.int_vz == 2) { + if (mod.ischeme == 1) { /* interpolate Vz times +1/2 Dt forward to P times */ + field = vz[ix*n1+iz] - 0.5*roz[ix*n1+iz]*( + c1*(tzz[ix*n1+iz] - tzz[ix*n1+iz-1]) + + c2*(tzz[ix*n1+iz+1] - tzz[ix*n1+iz-2])); + field += vz[ix*n1+iz2] - 0.5*roz[ix*n1+iz2]*( + c1*(tzz[ix*n1+iz2] - tzz[ix*n1+iz2-1]) + + c2*(tzz[ix*n1+iz2+1] - tzz[ix*n1+iz2-2])); + rec_vz[irec*rec.nt+isam] = 0.5*field; + } + else { + rec_vz[irec*rec.nt+isam] = 0.5*(vz[ix*n1+iz2]+vz[ix*n1+iz]); + } + } + else { + rec_vz[irec*rec.nt+isam] = vz[ix*n1+iz2]; + //rec_vz[irec*rec.nt+isam] = vz[ix*n1+iz]; + //fprintf(stderr,"isam=%d vz[%d]=%e vz[%d]=%e vz[%d]=%e \n",isam, iz-1,vz[ix*n1+iz-1],iz,vz[ix*n1+iz], iz+1, vz[ix*n1+iz+1]); + } + } + if (rec.type.vx) { +/* interpolate vx to vz position to the left and below of vx */ + if (rec.int_vx == 1) { + rec_vx[irec*rec.nt+isam] = 0.25*( + vx[ix2*n1+iz]+vx[ix2*n1+iz1]+ + vx[ix*n1+iz]+vx[ix*n1+iz1]); + } +/* interpolate vx to Txx/Tzz position by taking the mean of 2 values */ + else if (rec.int_vx == 2) { + if (mod.ischeme == 1) { /* interpolate Vx times +1/2 Dt forward to P times */ + field = vx[ix*n1+iz] - 0.5*rox[ix*n1+iz]*( + c1*(tzz[ix*n1+iz] - tzz[(ix-1)*n1+iz]) + + c2*(tzz[(ix+1)*n1+iz] - tzz[(ix-2)*n1+iz])); + field += vx[ix2*n1+iz] - 0.5*rox[ix2*n1+iz]*( + c1*(tzz[ix2*n1+iz] - tzz[(ix2-1)*n1+iz]) + + c2*(tzz[(ix2+1)*n1+iz] - tzz[(ix2-2)*n1+iz])); + rec_vx[irec*rec.nt+isam] = 0.5*field; + } + else { + rec_vx[irec*rec.nt+isam] = 0.5*(vx[ix2*n1+iz]+vx[ix*n1+iz]); + } + } + else { + rec_vx[irec*rec.nt+isam] = vx[ix2*n1+iz]; + } + } + } + + } /* end of irec loop */ + + /* store all x-values on z-level for P Vz for up-down decomposition */ + if (rec.type.ud) { + iz = rec.z[0]+ibndz; + iz2 = iz+1; + vz_t = (float *)calloc(2*mod.nax,sizeof(float)); + /* P and Vz are staggered in time and need to correct for this */ + /* -1- compute Vz at next time step and average with current time step */ + lroz = mod.dt/(mod.dx*rec.rho); + for (ix=mod.ioZx; ix<mod.ieZx; ix++) { + vz_t[ix] = vz[ix*n1+iz] - lroz*( + c1*(tzz[ix*n1+iz] - tzz[ix*n1+iz-1]) + + c2*(tzz[ix*n1+iz+1] - tzz[ix*n1+iz-2])); + vz_t[mod.nax+ix] = vz[ix*n1+iz2] - lroz*( + c1*(tzz[ix*n1+iz2] - tzz[ix*n1+iz2-1]) + + c2*(tzz[ix*n1+iz2+1] - tzz[ix*n1+iz2-2])); + } + for (ix=0; ix<mod.nax; ix++) { + /* -2- compute average in time and depth to get Vz at same depth and time as P */ + rec_udvz[ix*rec.nt+isam] = 0.25*(vz[ix*n1+iz2]+vz[ix*n1+iz]+vz_t[mod.nax+ix]+vz_t[ix]); + rec_udp[ix*rec.nt+isam] = tzz[ix*n1+iz]; + } + free(vz_t); + } + + return 0; +} diff --git a/fdelmodc3D/writeSrcRecPos3D.c b/fdelmodc3D/writeSrcRecPos3D.c new file mode 100644 index 0000000..92b20b6 --- /dev/null +++ b/fdelmodc3D/writeSrcRecPos3D.c @@ -0,0 +1,160 @@ +#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)) + +/** +* Writes the source and receiver positions into a gridded file, +* which has the same size as the input gridded model files. +* Source positions have a value +1 and receivers -1. +* +* AUTHOR: +* Jan Thorbecke (janth@xs4all.nl) +* The Netherlands +**/ + +long writesufile3D(char *filename, float *data, long n1, long n2, float f1, float f2, float d1, float d2); + +long writeSrcRecPos3D(modPar *mod, recPar *rec, srcPar *src, shotPar *shot) +{ + FILE *fp; + float *dum, sub_x0, sub_y0, sub_z0, dx, dy, dz; + long is, nx, ny, nz, is0, ish, ix, iy, iz, ndot, idx, idy, idz; + char tmpname[1024]; + + ndot = 2; + nx = mod->nx; + ny = mod->ny; + nz = mod->nz; + dx = mod->dx; + dy = mod->dy; + dz = mod->dz; + sub_x0 = mod->x0; + sub_y0 = mod->y0; + sub_z0 = mod->z0; + + /* write velocity field with positions of the sources */ + dum = (float *)calloc(nx*ny*nz, sizeof(float)); + vmess("Positions: shot=%li src=%li rec=%li", shot->n, src->n, rec->n); + /* source positions for random shots */ + if (src->random) { + sprintf(tmpname,"SrcPositions%li.txt",src->n); + fp = fopen(tmpname, "w+"); + for (is=0; is<src->n; is++) { + for (idy=0; idy<=ndot; idy++) { + for (idx=0; idx<=ndot; idx++) { + for (idz=0; idz<=ndot; idz++) { + dum[(MAX(0,src->y[is]-idy))*nz*nx+(MAX(0,src->x[is]-idx))*nz+MAX(0,src->z[is]-idz)] = 1.0; + dum[(MAX(0,src->y[is]-idy))*nz*nx+(MAX(0,src->x[is]-idx))*nz+MIN(nz-1,src->z[is]+idz)] = 1.0; + dum[(MAX(0,src->y[is]-idy))*nz*nx+(MIN(nx-1,src->x[is]+idx))*nz+MAX(0,src->z[is]-idz)] = 1.0; + dum[(MAX(0,src->y[is]-idy))*nz*nx+(MIN(nx-1,src->x[is]+idx))*nz+MIN(nz-1,src->z[is]+idz)] = 1.0; + dum[(MIN(ny-1,src->y[is]+idy))*nz*nx+(MAX(0,src->x[is]-idx))*nz+MIN(nz-1,src->z[is]+idz)] = 1.0; + dum[(MIN(ny-1,src->y[is]+idy))*nz*nx+(MAX(0,src->x[is]-idx))*nz+MAX(0,src->z[is]-idz)] = 1.0; + dum[(MIN(ny-1,src->y[is]+idy))*nz*nx+(MIN(nx-1,src->x[is]+idx))*nz+MIN(nz-1,src->z[is]+idz)] = 1.0; + dum[(MIN(ny-1,src->y[is]+idy))*nz*nx+(MIN(nx-1,src->x[is]+idx))*nz+MAX(0,src->z[is]-idz)] = 1.0; + } + } + } + fprintf(fp, "%f %f %f\n", src->z[is]*dz+sub_z0, src->y[is]*dy+sub_y0, src->x[is]*dx+sub_x0); + } + fclose(fp); + } + /* source positions for single shot sources with plane waves */ + else if (src->plane) { + is0 = -1*floor((src->n-1)/2); + sprintf(tmpname,"SrcPositions%li.txt",shot->n); + fp = fopen(tmpname, "w+"); + for (ish=0; ish<shot->n; ish++) { + for (is=0; is<src->n; is++) { + ix = shot->x[ish] + 1 + is0 + is; + iy = shot->y[ish] + 1 + is0 + is; + iz = shot->z[ish] + 1; + dum[iy*nx*nz+ix*nz+iz] = 1.0; + + dum[(MAX(0,iy-1))*nx*nz+ix*nz+iz] = 1.0; + dum[(MIN(ny-1,iy+1))*nx*nz+ix*nz+iz] = 1.0; + dum[iy*nx*nz+(MAX(0,ix-1))*nz+iz] = 1.0; + dum[iy*nx*nz+(MIN(nx-1,ix+1))*nz+iz] = 1.0; + dum[iy*nx*nz+ix*nz+MAX(0,iz-1)] = 1.0; + dum[iy*nx*nz+ix*nz+MIN(nz-1,iz+1)] = 1.0; + fprintf(fp, "(%f, %f, %f)\n", ix*dx+sub_x0, iy*dy+sub_y0, iz*dz+sub_z0); + } + } + fclose(fp); + } + else if (src->multiwav) { + /* source positions for single shot sources with multiple wavelets */ + sprintf(tmpname,"SrcPositions%li.txt",shot->n); + fp = fopen(tmpname, "w+"); + for (ish=0; ish<shot->n; ish++) { + for (is=0; is<src->n; is++) { + ix = src->x[is]; + iy = src->y[is]; + iz = src->z[is]; + dum[iy*nx*nz+ix*nz+iz] = 1.0; + + dum[(MAX(0,iy-1))*nx*nz+ix*nz+iz] = 1.0; + dum[(MIN(ny-1,iy+1))*nx*nz+ix*nz+iz] = 1.0; + dum[iy*nx*nz+(MAX(0,ix-1))*nz+iz] = 1.0; + dum[iy*nx*nz+(MIN(nx-1,ix+1))*nz+iz] = 1.0; + dum[iy*nx*nz+ix*nz+MAX(0,iz-1)] = 1.0; + dum[iy*nx*nz+ix*nz+MIN(nz-1,iz+1)] = 1.0; + fprintf(fp, "(%f, %f, %f)\n", ix*dx+sub_x0, iy*dy+sub_y0, iz*dz+sub_z0); + } + } + fclose(fp); + } + else { + sprintf(tmpname,"SrcPositions%li.txt",shot->n); + fp = fopen(tmpname, "w+"); + for (is=0; is<shot->n; is++) { + for (idy=0; idy<=ndot; idy++) { + for (idx=0; idx<=ndot; idx++) { + for (idz=0; idz<=ndot; idz++) { + dum[(MAX(0,shot->y[is]-idy))*nz*nx+(MAX(0,shot->x[is]-idx))*nz+MAX(0,shot->z[is]-idz)] = 1.0; + dum[(MAX(0,shot->y[is]-idy))*nz*nx+(MAX(0,shot->x[is]-idx))*nz+MIN(nz-1,shot->z[is]+idz)] = 1.0; + dum[(MAX(0,shot->y[is]-idy))*nz*nx+(MIN(nx-1,shot->x[is]+idx))*nz+MAX(0,shot->z[is]-idz)] = 1.0; + dum[(MAX(0,shot->y[is]-idy))*nz*nx+(MIN(nx-1,shot->x[is]+idx))*nz+MIN(nz-1,shot->z[is]+idz)] = 1.0; + dum[(MIN(ny-1,shot->y[is]+idy))*nz*nx+(MAX(0,shot->x[is]-idx))*nz+MIN(nz-1,shot->z[is]+idz)] = 1.0; + dum[(MIN(ny-1,shot->y[is]+idy))*nz*nx+(MAX(0,shot->x[is]-idx))*nz+MAX(0,shot->z[is]-idz)] = 1.0; + dum[(MIN(ny-1,shot->y[is]+idy))*nz*nx+(MIN(nx-1,shot->x[is]+idx))*nz+MIN(nz-1,shot->z[is]+idz)] = 1.0; + dum[(MIN(ny-1,shot->y[is]+idy))*nz*nx+(MIN(nx-1,shot->x[is]+idx))*nz+MAX(0,shot->z[is]-idz)] = 1.0; + } + } + } + fprintf(fp, "%f %f %f\n", shot->z[is]*dz+sub_z0, shot->y[is]*dy+sub_y0, shot->x[is]*dx+sub_x0); + } + fclose(fp); + } + + /* receiver positions */ + sprintf(tmpname,"RcvPositions%li.txt",rec->n); + fp = fopen(tmpname, "w+"); + for (is=0; is<rec->n; is++) { + dum[rec->y[is]*nx*nz+rec->x[is]*nz+rec->z[is]] = -1.0; + dum[(MAX(0,rec->y[is]-1))*nx*nz+rec->x[is]*nz+rec->z[is]] = -1.0; + dum[(MIN(ny-1,rec->y[is]+1))*nx*nz+rec->x[is]*nz+rec->z[is]] = -1.0; + dum[rec->y[is]*nx*nz+(MAX(0,rec->x[is]-1))*nz+rec->z[is]] = -1.0; + dum[rec->y[is]*nx*nz+(MIN(nx-1,rec->x[is]+1))*nz+rec->z[is]] = -1.0; + dum[rec->y[is]*nx*nz+rec->x[is]*nz+MAX(0,rec->z[is]-1)] = -1.0; + dum[rec->y[is]*nx*nz+rec->x[is]*nz+MIN(nz-1,rec->z[is]+1)] = -1.0; + + if (rec->int_vx==3) { + fprintf(fp, "(%f, %f, %f)\n", rec->xr[is]*dx+sub_x0, rec->yr[is]*dy+sub_y0, rec->zr[is]*dz+sub_z0); + } + else { + fprintf(fp, "(%f, %f, %f)\n", rec->x[is]*dx+sub_x0, rec->y[is]*dy+sub_y0, rec->z[is]*dz+sub_z0); + } + } + fclose(fp); + writesufile3D("SrcRecPositions.su", dum, nz, nx*ny, sub_z0, sub_x0, dz, dx); + free(dum); + + return 0; +} diff --git a/fdelmodc3D/writesufile3D.c b/fdelmodc3D/writesufile3D.c new file mode 100644 index 0000000..6f2af26 --- /dev/null +++ b/fdelmodc3D/writesufile3D.c @@ -0,0 +1,162 @@ +#include <stdlib.h> +#include <stdio.h> +#include <assert.h> +#include <string.h> +#include "par.h" +#include "fdelmodc3D.h" +#include "SUsegy.h" +#include "segy.h" + +/** +* Writes an 2D array to a SU file +* +* AUTHOR: +* Jan Thorbecke (janth@xs4all.nl) +* The Netherlands +**/ + +#define TRCBYTES 240 + +#define MAX(x,y) ((x) > (y) ? (x) : (y)) +#define MIN(x,y) ((x) < (y) ? (x) : (y)) +#define ISODD(n) ((n) & 01) +#define NINT(x) ((long)((x)>0.0?(x)+0.5:(x)-0.5)) + +long writesufile3D(char *filename, float *data, long n1, long n2, float f1, float f2, float d1, float d2) +{ + FILE *file_out; + size_t nwrite, itrace; + long ns; + segy *hdr; + +/* Read in parameters */ + + + + if (n1 > USHRT_MAX) { + vwarn("Output file %s: number of samples is truncated from %li to USHRT_MAX.", filename, n1); + } + ns = MIN(n1,USHRT_MAX); + + file_out = fopen( filename, "w+" ); + assert( file_out ); + + hdr = (segy *)calloc(1,TRCBYTES); + hdr->ns = ns; + hdr->dt = NINT(1000000*(d1)); + hdr->d1 = d1; + hdr->d2 = d2; + hdr->f1 = f1; + hdr->f2 = f2; + hdr->fldr = 1; + hdr->trwf = n2; + + for (itrace=0; itrace<n2; itrace++) { + hdr->tracl = itrace+1; + nwrite = fwrite( hdr, 1, TRCBYTES, file_out ); + assert (nwrite == TRCBYTES); + nwrite = fwrite( &data[itrace*n1], sizeof(float), ns, file_out ); + assert (nwrite == ns); + } + fclose(file_out); + free(hdr); + + return 0; +} + +/** +* Writes an 2D array to a SU file +* special routine for src_nwav array which has a different number of samples for each shot +* +**/ + +long writesufilesrcnwav3D(char *filename, float **src_nwav, wavPar wav, long n1, long n2, float f1, float f2, float d1, float d2) +{ + FILE *file_out; + size_t nwrite, itrace; + float *trace; + long ns; + segy *hdr; + +/* Read in parameters */ + + if (n1 > USHRT_MAX) { + vwarn("Output file %s: number of samples is truncated from %li to USHRT_MAX.", filename, n1); + } + ns = MIN(n1,USHRT_MAX); + + file_out = fopen( filename, "w+" ); + assert( file_out ); + + trace = (float *)malloc(n1*sizeof(float)); + hdr = (segy *)calloc(1,TRCBYTES); + hdr->ns = ns; + hdr->dt = NINT(1000000*(d1)); + hdr->d1 = d1; + hdr->d2 = d2; + hdr->f1 = f1; + hdr->f2 = f2; + hdr->fldr = 1; + hdr->trwf = n2; + + for (itrace=0; itrace<n2; itrace++) { + hdr->tracl = itrace+1; + nwrite = fwrite( hdr, 1, TRCBYTES, file_out ); + assert (nwrite == TRCBYTES); + memset(trace, 0, n1*sizeof(float)); + memcpy(trace, &src_nwav[itrace][0], wav.nsamp[itrace]*sizeof(float)); + nwrite = fwrite( &trace[0], sizeof(float), ns, file_out ); + assert (nwrite == ns); + } + fclose(file_out); + free(hdr); + free(trace); + + return 0; +} + +/** +* Writes an 2D array to a SU file +* special routine which used segyhdrs which have ns defined as integer (32 bit) +* to handle more than 2^16 samples per trace. +* +**/ + +long writeSUfile3D(char *filename, float *data, long n1, long n2, float f1, float f2, float d1, float d2) +{ + FILE *file_out; + size_t nwrite, itrace; + SUsegy *SUhdr; + char *ptr; + +/* Read in parameters */ + + ptr = strstr(filename, " "); + *ptr = '\0'; + + file_out = fopen( filename, "w+" ); + assert( file_out ); + + SUhdr = (SUsegy *)calloc(1,TRCBYTES); + SUhdr->ns = n1; + SUhdr->dt = NINT(1000000*(d1)); + SUhdr->d1 = d1; + SUhdr->d2 = d2; + SUhdr->f1 = f1; + SUhdr->f2 = f2; + SUhdr->fldr = 1; + SUhdr->trwf = n2; + + for (itrace=0; itrace<n2; itrace++) { + SUhdr->tracl = itrace+1; + nwrite = fwrite( SUhdr, 1, TRCBYTES, file_out ); + assert (nwrite == TRCBYTES); + nwrite = fwrite( &data[itrace*n1], sizeof(float), n1, file_out ); + assert (nwrite == n1); + } + fclose(file_out); + free(SUhdr); + + return 0; +} + -- GitLab