diff --git a/fdelmodc3D/elastic4_3D.c b/fdelmodc3D/elastic4_3D.c new file mode 100644 index 0000000000000000000000000000000000000000..630ee02ac8c8d2499225963e2bbe6898a2c6a7be --- /dev/null +++ b/fdelmodc3D/elastic4_3D.c @@ -0,0 +1,227 @@ +#include<stdlib.h> +#include<stdio.h> +#include<math.h> +#include<assert.h> +#include"fdelmodc3D.h" + +#define MAX(x,y) ((x) > (y) ? (x) : (y)) + +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 storeSourceOnSurface3D(modPar mod, srcPar src, bndPar bnd, long ixsrc, long iysrc, long izsrc, + float *vx, float *vy, float *vz, float *tzz, float *tyy, float *txx, float *txz, float *txy, float *tyz, long verbose); + +long reStoreSourceOnSurface3D(modPar mod, srcPar src, bndPar bnd, long ixsrc, long iysrc, long izsrc, + float *vx, float *vy, float *vz, float *tzz, float *tyy, float *txx, float *txz, float *txy, float *tyz, long verbose); + +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); + +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); + +long elastic4_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 *tzz, float *tyy, float *txx, float *txz, float *txy, float *tyz, + float *rox, float *roy, float *roz, float *l2m, float *lam, float *mul, long verbose) +{ +/********************************************************************* + COMPUTATIONAL OVERVIEW OF THE 4th ORDER STAGGERED GRID: + + The captial symbols T (=Txx,Tzz) 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; + float dvx, dvy, dvz; + long ix, iy, iz; + long n1, n2; + + c1 = 9.0/8.0; + c2 = -1.0/24.0; + n1 = mod.naz; + n2 = mod.nax; + + /* 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++) { + for (ix=mod.ioXx; ix<mod.ieXx; ix++) { +#pragma ivdep + for (iz=mod.ioXz; iz<mod.ieXz; iz++) { + vx[iy*n2*n1+ix*n1+iz] -= rox[iy*n2*n1+ix*n1+iz]*( + c1*(txx[iy*n2*n1+ix*n1+iz] - txx[iy*n2*n1+(ix-1)*n1+iz] + + txy[(iy+1)*n2*n1+ix*n1+iz] - txy[iy*n2*n1+ix*n1+iz] + + txz[iy*n2*n1+ix*n1+iz+1] - txz[iy*n2*n1+ix*n1+iz]) + + c2*(txx[iy*n2*n1+(ix+1)*n1+iz] - txx[iy*n2*n1+(ix-2)*n1+iz] + + txy[(iy+2)*n2*n1+ix*n1+iz] - txy[(iy-1)*n2*n1+ix*n1+iz] + + txz[iy*n2*n1+ix*n1+iz+2] - txz[iy*n2*n1+ix*n1+iz-1]) ); + } + } + } + + /* calculate vy for all grid points except on the virtual boundary */ +#pragma omp for private (ix, iy, iz) schedule(guided,1) + for (iy=mod.ioYy; iy<mod.ieYy; iy++) { + for (ix=mod.ioYx; ix<mod.ieYx; ix++) { +#pragma ivdep + for (iz=mod.ioYz; iz<mod.ieYz; iz++) { + vy[iy*n2*n1+ix*n1+iz] -= roy[iy*n2*n1+ix*n1+iz]*( + c1*(tyy[iy*n2*n1+ix*n1+iz] - tyy[(iy-1)*n2*n1+ix*n1+iz] + + tyz[iy*n2*n1+ix*n1+iz+1] - tyz[iy*n2*n1+ix*n1+iz] + + txy[iy*n2*n1+(ix+1)*n1+iz] - txy[iy*n2*n1+ix*n1+iz]) + + c2*(tyy[(iy+1)*n2*n1+ix*n1+iz] - tyy[(iy-2)*n2*n1+ix*n1+iz] + + tyz[iy*n2*n1+ix*n1+iz+2] - tyz[iy*n2*n1+ix*n1+iz-1] + + txy[iy*n2*n1+(ix+2)*n1+iz] - txy[iy*n2*n1+(ix-1)*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++) { + for (ix=mod.ioZx; ix<mod.ieZx; ix++) { +#pragma ivdep + for (iz=mod.ioZz; iz<mod.ieZz; iz++) { + vz[iy*n2*n1+ix*n1+iz] -= roz[iy*n2*n1+ix*n1+iz]*( + c1*(tzz[iy*n2*n1+ix*n1+iz] - tzz[iy*n2*n1+ix*n1+iz-1] + + tyz[(iy+1)*n2*n1+ix*n1+iz] - tyz[iy*n2*n1+ix*n1+iz] + + txz[iy*n2*n1+(ix+1)*n1+iz] - txz[iy*n2*n1+ix*n1+iz]) + + c2*(tzz[iy*n2*n1+ix*n1+iz+1] - tzz[iy*n2*n1+ix*n1+iz-2] + + tyz[(iy+1)*n2*n1+ix*n1+iz] - tyz[iy*n2*n1+ix*n1+iz] + + txz[iy*n2*n1+(ix+2)*n1+iz] - txz[iy*n2*n1+(ix-1)*n1+iz]) ); + } + } + } + + /* Add force source */ + if (src.type > 5) { + applySource3D(mod, src, wav, bnd, itime, ixsrc, iysrc, izsrc, vx, vy, vz, tzz, tyy, txx, txz, txy, tyz, rox, roy, roz, l2m, src_nwav, verbose); + } + + /* boundary condition clears velocities on boundaries */ + boundariesP3D(mod, bnd, vx, vy, vz, tzz, tyy, txx, txz, txy, tyz, rox, roy, roz, l2m, lam, mul, itime, verbose); + + /* calculate Txx/tzz for all grid points except on the virtual boundary */ +#pragma omp for private (ix, iy, iz, dvx, dvy, dvz) nowait schedule(guided,1) + for (iy=mod.ioPy; iy<mod.iePy; iy++) { + for (ix=mod.ioPx; ix<mod.iePx; ix++) { +#pragma ivdep + for (iz=mod.ioPz; iz<mod.iePz; 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]); + txx[iy*n2*n1+ix*n1+iz] -= l2m[iy*n2*n1+ix*n1+iz]*dvx + lam[iy*n2*n1+ix*n1+iz]*(dvy + dvz); + tyy[iy*n2*n1+ix*n1+iz] -= l2m[iy*n2*n1+ix*n1+iz]*dvy + lam[iy*n2*n1+ix*n1+iz]*(dvz + dvx); + tzz[iy*n2*n1+ix*n1+iz] -= l2m[iy*n2*n1+ix*n1+iz]*dvz + lam[iy*n2*n1+ix*n1+iz]*(dvx + dvy); + } + } + } + + + + /* calculate Txz for all grid points except on the virtual boundary */ +#pragma omp for private (ix, iy, iz) schedule(guided,1) + for (iy=mod.ioTy; iy<mod.ieTy; iy++) { + for (ix=mod.ioTx; ix<mod.ieTx; ix++) { + #pragma ivdep + for (iz=mod.ioTz; iz<mod.ieTz; iz++) { + txz[iy*n2*n1+ix*n1+iz] -= mul[iy*n2*n1+ix*n1+iz]*( + c1*(vx[iy*n2*n1+ix*n1+iz] - vx[iy*n2*n1+ix*n1+iz-1] + + vz[iy*n2*n1+ix*n1+iz] - vz[iy*n2*n1+(ix-1)*n1+iz]) + + c2*(vx[iy*n2*n1+ix*n1+iz+1] - vx[iy*n2*n1+ix*n1+iz-2] + + vz[iy*n2*n1+(ix+1)*n1+iz] - vz[iy*n2*n1+(ix-2)*n1+iz]) ); + } + } + } + + /* calculate Txy for all grid points except on the virtual boundary */ +#pragma omp for private (ix, iy, iz) schedule(guided,1) + for (iy=mod.ioTy; iy<mod.ieTy; iy++) { + for (ix=mod.ioTx; ix<mod.ieTx; ix++) { + #pragma ivdep + for (iz=mod.ioTz; iz<mod.ieTz; iz++) { + txy[iy*n2*n1+ix*n1+iz] -= mul[iy*n2*n1+ix*n1+iz]*( + c1*(vx[iy*n2*n1+ix*n1+iz] - vx[(iy-1)*n2*n1+ix*n1+iz] + + vy[iy*n2*n1+ix*n1+iz] - vy[iy*n2*n1+(ix-1)*n1+iz]) + + c2*(vx[(iy+1)*n2*n1+ix*n1+iz] - vx[(iy-2)*n2*n1+ix*n1+iz] + + vy[iy*n2*n1+(ix+1)*n1+iz] - vy[iy*n2*n1+(ix-2)*n1+iz]) ); + } + } + } + + /* calculate Tyz for all grid points except on the virtual boundary */ +#pragma omp for private (ix, iy, iz) schedule(guided,1) + for (iy=mod.ioTy; iy<mod.ieTy; iy++) { + for (ix=mod.ioTx; ix<mod.ieTx; ix++) { + #pragma ivdep + for (iz=mod.ioTz; iz<mod.ieTz; iz++) { + tyz[iy*n2*n1+ix*n1+iz] -= mul[iy*n2*n1+ix*n1+iz]*( + c1*(vz[iy*n2*n1+ix*n1+iz] - vz[(iy-1)*n2*n1+ix*n1+iz] + + vy[iy*n2*n1+ix*n1+iz] - vy[iy*n2*n1+ix*n1+iz-1]) + + c2*(vz[(iy+1)*n2*n1+ix*n1+iz] - vz[(iy-2)*n2*n1+ix*n1+iz] + + vy[iy*n2*n1+ix*n1+iz+1] - vy[iy*n2*n1+ix*n1+iz-2]) ); + } + } + } + + /* Add stress source */ + if (src.type < 6) { + applySource3D(mod, src, wav, bnd, itime, ixsrc, iysrc, izsrc, vx, vy, vz, tzz, tyy, txx, txz, txy, tyz, rox, roy, roz, l2m, src_nwav, verbose); + } + + /* check if there are sources placed on the boundaries */ + storeSourceOnSurface3D(mod, src, bnd, ixsrc, iysrc, izsrc, vx, vy, vz, tzz, tyy, txx, txz, txy, tyz, verbose); + + /* Free surface: calculate free surface conditions for stresses */ + boundariesV3D(mod, bnd, vx, vy, vz, tzz, tyy, txx, txz, txy, tyz, rox, roy, roz, l2m, lam, mul, itime, verbose); + + /* restore source positions on the edge */ + reStoreSourceOnSurface3D(mod, src, bnd, ixsrc, iysrc, izsrc, vx, vy, vz, tzz, tyy, txx, txz, txy, tyz, verbose); + + return 0; +} \ No newline at end of file