21 #ifndef GEOS_PHYSICSSOLVERS_WAVEPROPAGATION_WAVESOLVERUTILS_HPP_
22 #define GEOS_PHYSICSSOLVERS_WAVEPROPAGATION_WAVESOLVERUTILS_HPP_
26 #include "LvArray/src/tensorOps.hpp"
33 static constexpr
real64 epsilonLoc = 1e-8;
35 using EXEC_POLICY = parallelDevicePolicy< >;
36 using wsCoordType =
real32;
55 real32 const delay = t0 > 0 ? t0 : 1 / f0;
57 real32 const alpha = -pow( f0 * M_PI, 2 );
58 real32 const time_d = time_n - delay;
59 real32 const gaussian = exp( alpha * pow( time_d, 2 ));
65 pulse = sgn * gaussian;
68 pulse = sgn * (2 * alpha * time_d) * gaussian;
71 pulse = sgn * (2 * alpha + 4 * pow( alpha, 2 ) * pow( time_d, 2 )) * gaussian;
74 pulse = sgn * (12 * pow( alpha, 2 ) * time_d + 8 * pow( alpha, 3 ) * pow( time_d, 3 )) * gaussian;
77 pulse = sgn * (12 * pow( alpha, 2 ) + 48 * pow( alpha, 3 ) * pow( time_d, 2 ) + 16 * pow( alpha, 4 ) * pow( time_d, 4 )) * gaussian;
80 GEOS_ERROR(
"This option is not supported yet, rickerOrder must be in range {0:4}" );
96 bool const outputSeismoTrace,
100 if( !outputSeismoTrace )
return;
103 RAJA::ReduceSum< ReducePolicy< serialPolicy >,
localIndex > count( 0 );
105 forAll< serialPolicy >( nReceivers, [=] (
localIndex const ircv )
107 if( receiverIsLocal[ircv] == 1 )
110 string const fn =
joinPath( outputDir, GEOS_FMT(
"{}_{}_{:03}.txt", prefix, name, ircv ) );
111 std::ofstream f( fn, std::ios::out | std::ios::trunc );
116 GEOS_ERROR_IF( nReceivers != total, GEOS_FMT(
": Invalid distribution of receivers: nReceivers={} != MPI::sum={}.", nReceivers, total ) );
133 bool const outputSeismoTrace,
141 writeSeismoTrace( prefix, name, outputSeismoTrace, nReceivers, receiverIsLocal, nsamplesSeismoTrace, varAtReceiversx );
142 writeSeismoTrace( prefix, name, outputSeismoTrace, nReceivers, receiverIsLocal, nsamplesSeismoTrace, varAtReceiversy );
143 writeSeismoTrace( prefix, name, outputSeismoTrace, nReceivers, receiverIsLocal, nsamplesSeismoTrace, varAtReceiversz );
158 bool const outputSeismoTrace,
164 if( !outputSeismoTrace )
return;
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 ));
357 if( s < 0 )
return false;
371 template<
typename FE_TYPE >
377 real64 (& coordsOnRefElem)[3] )
383 LvArray::tensorOps::copy< 3 >( xLocal[a], nodeCoords[ elemsToNodes[ a ] ] );
387 FE_TYPE::invJacobianTransformation( 0, xLocal, invJ );
391 coordsOnRefElem[i] = -1.0;
394 coordsOnRefElem[i] += invJ[i][j] * (coords[j] - xLocal[0][j]);
417 RAJA::ReduceSum< parallelDeviceReduce, real64 > tmp( 0.0 );
420 tmp+= vector1[a]*vector2[a];
438 real64 v1 = cd * cos( azimuth );
439 real64 v2 = cd * sin( azimuth );
441 R1Tensor dasVector = { v1, v2, v3 };
451 "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.
ENUM_STRINGS(LinearSolverParameters::SolverType, "direct", "cg", "gmres", "fgmres", "bicgstab", "preconditioner")
Declare strings associated with enumeration values.
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::int32_t integer
Signed integer type.
std::string joinPath(ARGS const &... args)
Join parts of a path.
ArrayView< T, 2, USD > arrayView2d
Alias for 2D array view.
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 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.