20 #ifndef GEOS_PHYSICSSOLVERS_WAVEPROPAGATION_WAVESOLVERUTILS_HPP_ 
   21 #define GEOS_PHYSICSSOLVERS_WAVEPROPAGATION_WAVESOLVERUTILS_HPP_ 
   25 #include "LvArray/src/tensorOps.hpp" 
   32   static constexpr 
real64 epsilonLoc = 1e-8;
 
   34   using EXEC_POLICY = parallelDevicePolicy<>;
 
   35   using wsCoordType = 
real32;
 
   53     real32 const delay = t0 > 0 ? t0 : 1 / f0;
 
   55     real32 const alpha = -pow( f0 * M_PI, 2 );
 
   56     real32 const time_d = time_n - delay;
 
   57     real32 const gaussian = exp( alpha * pow( time_d, 2 ));
 
   63         pulse = sgn * gaussian;
 
   66         pulse = sgn * (2 * alpha * time_d) * gaussian;
 
   69         pulse = sgn * (2 * alpha + 4 * pow( alpha, 2 ) * pow( time_d, 2 )) * gaussian;
 
   72         pulse = sgn * (12 * pow( alpha, 2 ) * time_d + 8 * pow( alpha, 3 ) * pow( time_d, 3 )) * gaussian;
 
   75         pulse = sgn * (12 * pow( alpha, 2 ) + 48 * pow( alpha, 3 ) * pow( time_d, 2 ) + 16 * pow( alpha, 4 ) * pow( time_d, 4 )) * gaussian;
 
   78         GEOS_ERROR( 
"This option is not supported yet, rickerOrder must be in range {0:4}" );
 
   94                          bool const outputSeismoTrace,
 
   98     if( !outputSeismoTrace )
 
  102     RAJA::ReduceSum< ReducePolicy< serialPolicy >, 
localIndex > count( 0 );
 
  104     forAll< serialPolicy >( nReceivers, [=]( 
localIndex const ircv )
 
  106       if( receiverIsLocal[ircv] == 1 )
 
  109         string const fn = 
joinPath( outputDir, GEOS_FMT( 
"{}_{}_{:03}.txt", prefix, name, ircv ) );
 
  110         std::ofstream f( fn, std::ios::out | std::ios::trunc );
 
  115     GEOS_ERROR_IF( nReceivers != total, GEOS_FMT( 
": Invalid distribution of receivers: nReceivers={} != MPI::sum={}.", nReceivers, total ));
 
  132                                       bool const outputSeismoTrace,
 
  140     writeSeismoTrace( prefix, name, outputSeismoTrace, nReceivers, receiverIsLocal, nsamplesSeismoTrace, varAtReceiversx );
 
  141     writeSeismoTrace( prefix, name, outputSeismoTrace, nReceivers, receiverIsLocal, nsamplesSeismoTrace, varAtReceiversy );
 
  142     writeSeismoTrace( prefix, name, outputSeismoTrace, nReceivers, receiverIsLocal, nsamplesSeismoTrace, varAtReceiversz );
 
  157                                 bool const outputSeismoTrace,
 
  163     if( !outputSeismoTrace )
 
  167     forAll< serialPolicy >( nReceivers, [=]( 
localIndex const ircv )
 
  169       if( receiverIsLocal[ircv] == 1 )
 
  171         string const fn = 
joinPath( outputDir, GEOS_FMT( 
"{}_{}_{:03}.txt", prefix, name, ircv ) );
 
  172         std::ofstream f( fn, std::ios::app );
 
  175           GEOS_LOG_RANK( GEOS_FMT( 
"Append to seismo trace file {}", fn ) );
 
  176           for( 
localIndex iSample = 0; iSample < nsamplesSeismoTrace; ++iSample )
 
  179             f << iSample << 
" " << varAtReceivers[iSample][nReceivers] << 
" " << varAtReceivers[iSample][ircv] << std::endl;
 
  185           GEOS_WARNING( GEOS_FMT( 
"Failed to open output file {}", fn ) );
 
  219     real64 const time_np1 = time_n + dt;
 
  221     real32 const a1 = LvArray::math::abs( dt ) < epsilonLoc ? 1.0 : (time_np1 - timeSeismo) / dt;
 
  222     real32 const a2 = 1.0 - a1;
 
  224     localIndex const nReceivers = receiverConstants.size( 0 );
 
  227       if( receiverIsLocal[ircv] > 0 )
 
  229         real32 vtmp_np1 = 0.0, vtmp_n = 0.0;
 
  230         for( 
localIndex inode = 0; inode < receiverConstants.size( 1 ); ++inode )
 
  232           if( receiverNodeIds( ircv, inode ) >= 0 )
 
  234             vtmp_np1 += var_np1[receiverNodeIds( ircv, inode )] * receiverConstants( ircv, inode );
 
  235             vtmp_n += var_n[receiverNodeIds( ircv, inode )] * receiverConstants( ircv, inode );
 
  239         real32 receiverCoeff = coeffs.size( 0 ) == 0 ? 1.0 : coeffs( ircv );
 
  242           varAtReceivers( iSeismo, ircv ) += receiverCoeff * ( a1 * vtmp_n + a2 * vtmp_np1 );
 
  246           varAtReceivers( iSeismo, ircv ) = receiverCoeff * ( a1 * vtmp_n + a2 * vtmp_np1 );
 
  250         varAtReceivers( iSeismo, nReceivers ) = a1 * time_n + a2 * time_np1;
 
  283     real64 const time_np1 = time_n + dt;
 
  285     real32 const a1 = dt < epsilonLoc ? 1.0 : (time_np1 - timeSeismo) / dt;
 
  286     real32 const a2 = 1.0 - a1;
 
  288     localIndex const nReceivers = receiverConstants.size( 0 );
 
  292       if( receiverIsLocal[ircv] == 1 )
 
  294         if( receiverRegion[ircv] == regionIndex )
 
  296           real32 vtmp_np1 = 0.0, vtmp_n = 0.0;
 
  297           for( 
localIndex inode = 0; inode < receiverConstants.size( 1 ); ++inode )
 
  299             vtmp_np1 += var_np1( receiverElem[ircv], inode ) * receiverConstants( ircv, inode );
 
  300             vtmp_n += var_n( receiverElem[ircv], inode ) * receiverConstants( ircv, inode );
 
  303           varAtReceivers( iSeismo, ircv ) = a1 * vtmp_n + a2 * vtmp_np1;
 
  306           varAtReceivers( iSeismo, nReceivers ) = a1 * time_n + a2 * time_np1;
 
  325                        real64 const (&elemCenter)[3],
 
  329                        real64 const (&coords)[3] )
 
  333     for( 
localIndex kfe = 0; kfe < numFacesPerElem; ++kfe )
 
  337       real64 faceCenterOnFace[3] = {faceCenter[iface][0],
 
  338                                     faceCenter[iface][1],
 
  339                                     faceCenter[iface][2]};
 
  340       real64 faceNormalOnFace[3] = {faceNormal[iface][0],
 
  341                                     faceNormal[iface][1],
 
  342                                     faceNormal[iface][2]};
 
  345       LvArray::tensorOps::copy< 3 >( tmpVector, faceCenterOnFace );
 
  346       LvArray::tensorOps::subtract< 3 >( tmpVector, elemCenter );
 
  347       if( LvArray::tensorOps::AiBi< 3 >( tmpVector, faceNormalOnFace ) < 0.0 )
 
  349         LvArray::tensorOps::scale< 3 >( faceNormalOnFace, -1 );
 
  353       LvArray::tensorOps::subtract< 3 >( faceCenterOnFace, coords );
 
  354       localIndex const s = computationalGeometry::sign( LvArray::tensorOps::AiBi< 3 >( faceNormalOnFace, faceCenterOnFace ));
 
  371   template< 
typename FE_TYPE >
 
  376                                         real64 (& coordsOnRefElem)[3] )
 
  382       LvArray::tensorOps::copy< 3 >( xLocal[a], nodeCoords[elemsToNodes[a]] );
 
  386     FE_TYPE::invJacobianTransformation( 0, xLocal, invJ );
 
  390       coordsOnRefElem[i] = -1.0;
 
  393         coordsOnRefElem[i] += invJ[i][j] * (coords[j] - xLocal[0][j]);
 
  415     RAJA::ReduceSum< parallelDeviceReduce, real64 > tmp( 0.0 );
 
  417     { tmp += vector1[a] * vector2[a]; } );
 
  432     real64 v1 = cd * cos( azimuth );
 
  433     real64 v2 = cd * sin( azimuth );
 
  446   template< 
typename REAL >
 
  457     for( 
int i = 0; i < 4; i++ )
 
  461       int jstart = (i + 1) % 4;
 
  462       int j = (jstart + 1) % 4;
 
  465         for( 
int k = 0; k < 3; k++ )
 
  467           spxf[k][cf] = nodeCoords( elemsToNodes[j], k ) - nodeCoords( elemsToNodes[jstart], k );
 
  480       LvArray::tensorOps::crossProduct( cross, v1, v2 );
 
  481       hs = hs + LvArray::math::sqrt( LvArray::tensorOps::l2NormSquared< 3 >( cross ));
 
  484     for( 
int i = 0; i < 3; i++ )
 
  486       for( 
int k = 0; k < 3; k++ )
 
  488         spx[i][k] = nodeCoords( elemsToNodes[i], k ) - nodeCoords( elemsToNodes[3], k );
 
  493     return LvArray::math::abs( LvArray::tensorOps::determinant< 3 >( spx ) / hs );
 
  501               "strainIntegration" );
 
#define GEOS_HOST_DEVICE
Marks a host-device function.
 
#define GEOS_LOG_RANK(msg)
Log a message to the rank output stream.
 
#define GEOS_ERROR(msg)
Raise a hard error and terminate the program.
 
#define GEOS_WARNING(msg)
Report a warning.
 
#define GEOS_ERROR_IF(EXP, msg)
Conditionally raise a hard error and terminate the program.
 
static string const  & getOutputDirectory()
Getter for the output directory.
 
ArrayView< T, 1 > arrayView1d
Alias for 1D array view.
 
float real32
32-bit floating point type.
 
double real64
64-bit floating point type.
 
GEOS_LOCALINDEX_TYPE localIndex
Local index type (for indexing objects within an MPI partition).
 
ArraySlice< T, 1, USD > arraySlice1d
Alias for 1D array slice.
 
std::string joinPath(ARGS const &... args)
Join parts of a path.
 
ArrayView< T, 2, USD > arrayView2d
Alias for 2D array view.
 
int integer
Signed integer type.
 
ENUM_STRINGS(LinearSolverParameters::SolverType, "direct", "cg", "gmres", "fgmres", "bicgstab", "richardson", "preconditioner")
Declare strings associated with enumeration values.
 
static T sum(T const &value, MPI_Comm comm=MPI_COMM_GEOS)
Convenience function for a MPI_Allreduce using a MPI_SUM operation.
 
static GEOS_HOST_DEVICE void computeCoordinatesOnReferenceElement(real64 const (&coords)[3], arraySlice1d< localIndex const, cells::NODE_MAP_USD - 1 > const elemsToNodes, arrayView2d< real64 const, nodes::REFERENCE_POSITION_USD > const nodeCoords, real64(&coordsOnRefElem)[3])
Convert a mesh element point coordinate into a coordinate on the reference element.
 
static void compute2dVariableSeismoTrace(real64 const time_n, real64 const dt, localIndex const regionIndex, arrayView1d< localIndex const > const receiverRegion, real64 const timeSeismo, localIndex const iSeismo, arrayView1d< localIndex const > const receiverElem, arrayView2d< real64 const > const receiverConstants, arrayView1d< localIndex const > const receiverIsLocal, arrayView2d< real32 const > const var_np1, arrayView2d< real32 const > const var_n, arrayView2d< real32 > varAtReceivers)
Compute the seismo traces for 2d arrays.
 
static void writeSeismoTraceVector(char const *prefix, string const &name, bool const outputSeismoTrace, localIndex const nReceivers, arrayView1d< localIndex const > const receiverIsLocal, localIndex const nsamplesSeismoTrace, arrayView2d< real32 const > const varAtReceiversx, arrayView2d< real32 const > const varAtReceiversy, arrayView2d< real32 const > const varAtReceiversz)
Convenient helper for 3D vectors calling 3 times the scalar version with only the sampled variable ar...
 
static GEOS_HOST_DEVICE REAL computeReferenceLengthForPenalty(arraySlice1d< localIndex const, cells::NODE_MAP_USD - 1 > const elemsToNodes, arrayView2d< REAL const, nodes::REFERENCE_POSITION_USD > const nodeCoords)
Compute the reference size used for the tetrahederal DG penalty coefficient. This implementation uses...
 
static GEOS_HOST_DEVICE bool locateSourceElement(real64 const numFacesPerElem, real64 const (&elemCenter)[3], arrayView2d< real64 const > const faceNormal, arrayView2d< real64 const > const faceCenter, arraySlice1d< localIndex const > const elemsToFaces, real64 const (&coords)[3])
Check if the source point is inside an element or not.
 
static void dotProduct(localIndex const size, arrayView1d< real32 > const &vector1, arrayView1d< real32 > const &vector2, real64 &res)
Compute dotProduct between two vectors.
 
static void computeSeismoTrace(real64 const time_n, real64 const dt, real64 const timeSeismo, localIndex const iSeismo, arrayView2d< localIndex const > const receiverNodeIds, arrayView2d< real64 const > const receiverConstants, arrayView1d< localIndex const > const receiverIsLocal, arrayView1d< real32 const > const var_np1, arrayView1d< real32 const > const var_n, arrayView2d< real32 > varAtReceivers, arrayView1d< real32 > coeffs={}, bool add=false)
Compute the seismo traces.
 
@ none
deactivate attenuation (default)
 
@ sls
istandard-linear-solid description [Fichtner 2014]
 
static GEOS_HOST_DEVICE R1Tensor computeDASVector(real64 const dip, real64 const azimuth)
Converts the DAS direction from dip/azimuth to a 3D unit vector.
 
@ none
deactivate DAS computation
 
@ dipole
use dipole formulation for DAS
 
@ strainIntegration
use strain integration for DAS
 
static void writeSeismoTrace(char const *prefix, string const &name, bool const outputSeismoTrace, localIndex const nReceivers, arrayView1d< localIndex const > const receiverIsLocal, localIndex const nsamplesSeismoTrace, arrayView2d< real32 const > const varAtReceivers)
Write the seismo traces to a file.
 
static void initTrace(char const *prefix, string const &name, bool const outputSeismoTrace, localIndex const nReceivers, arrayView1d< localIndex const > const receiverIsLocal)
Initialize (clear) the trace file.