20 #ifndef GEOS_PHYSICSSOLVERS_WAVEPROPAGATION_PRECOMPUTESOURCESANDRECEIVERSKERNEL_HPP_
21 #define GEOS_PHYSICSSOLVERS_WAVEPROPAGATION_PRECOMPUTESOURCESANDRECEIVERSKERNEL_HPP_
29 using EXEC_POLICY = parallelDevicePolicy< >;
55 template<
typename EXEC_POLICY,
typename FE_TYPE >
78 real32 const timeSourceFrequency,
79 real32 const timeSourceDelay,
82 bool useSourceWaveletTables )
84 constexpr
localIndex numNodesPerElem = FE_TYPE::numNodes;
88 real64 const center[3] = { elemCenter[k][0],
95 for(
localIndex isrc = 0; isrc < sourceCoordinates.size( 0 ); ++isrc )
97 if( sourceIsAccessible[isrc] == 0 )
99 real64 const coords[3] = { sourceCoordinates[isrc][0],
100 sourceCoordinates[isrc][1],
101 sourceCoordinates[isrc][2] };
102 bool const sourceFound =
103 computationalGeometry::isPointInsideConvexPolyhedronRobust( k,
108 baseNodeLocalToGlobal,
109 elementLocalToGlobal,
114 real64 coordsOnRefElem[3]{};
117 WaveSolverUtils::computeCoordinatesOnReferenceElement< FE_TYPE >( coords,
122 sourceIsAccessible[isrc] = 1;
123 real64 Ntest[numNodesPerElem];
124 FE_TYPE::calcN( coordsOnRefElem, Ntest );
126 for(
localIndex a = 0; a < numNodesPerElem; ++a )
128 sourceNodeIds[isrc][a] = elemsToNodes( k, a );
129 sourceConstants[isrc][a] = Ntest[a];
132 for(
localIndex cycle = 0; cycle < sourceValue.size( 0 ); ++cycle )
134 real64 const time_n = cycle * dt;
135 if( useSourceWaveletTables )
137 sourceValue[cycle][isrc]= sourceWaveletTableWrappers[ isrc ].compute( &time_n );
141 sourceValue[cycle][isrc] = WaveSolverUtils::evaluateRicker( cycle * dt, timeSourceFrequency, timeSourceDelay, rickerOrder );
153 for(
localIndex ircv = 0; ircv < receiverCoordinates.size( 0 ); ++ircv )
155 if( receiverIsLocal[ircv] == 0 )
157 real64 const coords[3] = { receiverCoordinates[ircv][0],
158 receiverCoordinates[ircv][1],
159 receiverCoordinates[ircv][2] };
161 real64 coordsOnRefElem[3]{};
162 bool const receiverFound =
163 computationalGeometry::isPointInsideConvexPolyhedronRobust( k,
168 baseNodeLocalToGlobal,
169 elementLocalToGlobal,
173 if( receiverFound && elemGhostRank[k] < 0 )
175 WaveSolverUtils::computeCoordinatesOnReferenceElement< FE_TYPE >( coords,
180 receiverIsLocal[ircv] = 1;
182 real64 Ntest[numNodesPerElem];
183 FE_TYPE::calcN( coordsOnRefElem, Ntest );
185 for(
localIndex a = 0; a < numNodesPerElem; ++a )
187 receiverNodeIds[ircv][a] = elemsToNodes( k, a );
188 receiverConstants[ircv][a] = Ntest[a];
226 template<
typename EXEC_POLICY,
typename FE_TYPE >
253 constexpr
localIndex numNodesPerElem = FE_TYPE::numNodes;
257 real64 const center[3] = { elemCenter[k][0],
264 for(
localIndex isrc = 0; isrc < sourceCoordinates.size( 0 ); ++isrc )
266 if( sourceIsAccessible[isrc] == 0 )
268 real64 const coords[3] = { sourceCoordinates[isrc][0],
269 sourceCoordinates[isrc][1],
270 sourceCoordinates[isrc][2] };
272 bool const sourceFound =
273 computationalGeometry::isPointInsideConvexPolyhedronRobust( k,
278 baseNodeLocalToGlobal,
279 elementLocalToGlobal,
284 real64 coordsOnRefElem[3]{};
286 WaveSolverUtils::computeCoordinatesOnReferenceElement< FE_TYPE >( coords,
291 sourceIsAccessible[isrc] = 1;
292 sourceElem[isrc] = k;
293 sourceRegion[isrc] = regionIndex;
294 real64 Ntest[numNodesPerElem];
295 FE_TYPE::calcN( coordsOnRefElem, Ntest );
297 for(
localIndex a = 0; a < numNodesPerElem; ++a )
299 sourceNodeIds[isrc][a] = elemsToNodes[k][a];
300 sourceConstants[isrc][a] = Ntest[a];
311 for(
localIndex ircv = 0; ircv < receiverCoordinates.size( 0 ); ++ircv )
313 if( receiverIsLocal[ircv] == 0 )
315 real64 const coords[3] = { receiverCoordinates[ircv][0],
316 receiverCoordinates[ircv][1],
317 receiverCoordinates[ircv][2] };
319 real64 coordsOnRefElem[3]{};
320 bool const receiverFound =
321 computationalGeometry::isPointInsideConvexPolyhedronRobust( k,
326 baseNodeLocalToGlobal,
327 elementLocalToGlobal,
331 if( receiverFound && elemGhostRank[k] < 0 )
333 WaveSolverUtils::computeCoordinatesOnReferenceElement< FE_TYPE >( coords,
337 receiverIsLocal[ircv] = 1;
338 receiverElem[ircv] = k;
339 receiverRegion[ircv] = regionIndex;
341 real64 Ntest[numNodesPerElem];
342 FE_TYPE::calcN( coordsOnRefElem, Ntest );
344 for(
localIndex a = 0; a < numNodesPerElem; ++a )
346 receiverNodeIds[ircv][a] = elemsToNodes[k][a];
347 receiverConstants[ircv][a] = Ntest[a];
392 template<
typename EXEC_POLICY,
typename FE_TYPE >
421 constexpr
localIndex numNodesPerElem = FE_TYPE::numNodes;
430 real64 const center[3] = { elemCenter[k][0],
437 for(
localIndex isrc = 0; isrc < sourceCoordinates.size( 0 ); ++isrc )
439 if( sourceIsAccessible[isrc] == 0 )
441 real64 const coords[3] = { sourceCoordinates[isrc][0],
442 sourceCoordinates[isrc][1],
443 sourceCoordinates[isrc][2] };
451 xLocal[a][i] = baseNodeCoords( baseElemsToNodes( k, a ), i );
456 bool const sourceFound =
457 computationalGeometry::isPointInsideConvexPolyhedronRobust( k,
462 baseNodeLocalToGlobal,
463 elementLocalToGlobal,
469 real64 coordsOnRefElem[3]{};
472 WaveSolverUtils::computeCoordinatesOnReferenceElement< FE_TYPE >( coords,
476 sourceIsAccessible[isrc] = 1;
478 real64 N[numNodesPerElem];
479 real64 gradN[numNodesPerElem][3];
480 FE_TYPE::calcN( coordsOnRefElem, N );
481 FE_TYPE::calcGradNWithCorners( coordsOnRefElem, xLocal, gradN );
483 for(
localIndex q=0; q< numNodesPerElem; ++q )
485 real64 inc[3] = { 0, 0, 0 };
486 sourceNodeIds[isrc][q] = elemsToNodes( k, q );
487 inc[0] += sourceForce[0] * N[q];
488 inc[1] += sourceForce[1] * N[q];
489 inc[2] += sourceForce[2] * N[q];
491 LvArray::tensorOps::Ri_add_symAijBj< 3 >( inc, moment.
data, gradN[q] );
492 sourceConstantsx[isrc][q] += inc[0];
493 sourceConstantsy[isrc][q] += inc[1];
494 sourceConstantsz[isrc][q] += inc[2];
509 samplePointLocations[ 0 ] = 0;
513 for(
integer i = 0; i < nSamples; ++i )
515 samplePointLocations[ i ] = -0.5 + (
real64) i / ( linearDASSamples - 1 );
523 sampleIntegrationConstants[ 0 ] = -1.0;
524 sampleIntegrationConstants[ 1 ] = 1.0;
527 else if( nSamples == 1 )
529 sampleIntegrationConstants[ 0 ] = 1.0;
533 for(
integer i = 0; i < linearDASSamples; i++ )
535 sampleIntegrationConstants[ i ] = 1.0 / nSamples;
540 for(
localIndex ircv = 0; ircv < receiverCoordinates.size( 0 ); ++ircv )
542 R1Tensor receiverCenter = { receiverCoordinates[ ircv ][ 0 ], receiverCoordinates[ ircv ][ 1 ], receiverCoordinates[ ircv ][ 2 ] };
546 receiverVector = { 0, 0, 0 };
554 for(
integer iSample = 0; iSample < nSamples; ++iSample )
557 real64 const coords[3] = { receiverCenter[ 0 ] + receiverVector[ 0 ] * receiverLength * samplePointLocations[ iSample ],
558 receiverCenter[ 1 ] + receiverVector[ 1 ] * receiverLength * samplePointLocations[ iSample ],
559 receiverCenter[ 2 ] + receiverVector[ 2 ] * receiverLength * samplePointLocations[ iSample ] };
560 bool const sampleFound =
561 computationalGeometry::isPointInsideConvexPolyhedronRobust( k,
566 baseNodeLocalToGlobal,
567 elementLocalToGlobal,
570 if( sampleFound && elemGhostRank[k] < 0 )
572 real64 coordsOnRefElem[3]{};
579 xLocal[a][i] = baseNodeCoords( baseElemsToNodes( k, a ), i );
583 WaveSolverUtils::computeCoordinatesOnReferenceElement< FE_TYPE >( coords,
587 real64 N[numNodesPerElem];
588 real64 gradN[numNodesPerElem][3];
589 FE_TYPE::calcN( coordsOnRefElem, N );
590 FE_TYPE::calcGradNWithCorners( coordsOnRefElem, xLocal, gradN );
591 for(
localIndex a = 0; a < numNodesPerElem; ++a )
593 receiverNodeIds[ircv][iSample * numNodesPerElem + a] = elemsToNodes( k,
597 receiverConstants[ircv][iSample * numNodesPerElem + a] += ( gradN[a][0] * receiverVector[0] + gradN[a][1] * receiverVector[1] + gradN[a][2] * receiverVector[2] ) *
598 sampleIntegrationConstants[ iSample ];
602 receiverConstants[ircv][iSample * numNodesPerElem + a] += N[a] * sampleIntegrationConstants[ iSample ];
605 receiverIsLocal[ ircv ] = 2;
609 real64 const coords[3] = { receiverCenter[ 0 ], receiverCenter[ 1 ], receiverCenter[ 2 ] };
610 bool const receiverFound =
611 computationalGeometry::isPointInsideConvexPolyhedronRobust( k,
616 baseNodeLocalToGlobal,
617 elementLocalToGlobal,
620 if( receiverFound && elemGhostRank[k] < 0 )
622 receiverIsLocal[ ircv ] = 1;
#define GEOS_HOST_DEVICE
Marks a host-device function.
T data[SIZE]
Underlying array.
ArrayView< T, 1 > arrayView1d
Alias for 1D array view.
float real32
32-bit floating point type.
LvArray::ArrayOfArraysView< T, INDEX_TYPE const, CONST_SIZES, LvArray::ChaiBuffer > ArrayOfArraysView
View of array of variable-sized arrays. See LvArray::ArrayOfArraysView for details.
double real64
64-bit floating point type.
GEOS_LOCALINDEX_TYPE localIndex
Local index type (for indexing objects within an MPI partition).
std::int32_t integer
Signed integer type.
ArrayView< T, 2, USD > arrayView2d
Alias for 2D array view.
Array< T, 1 > array1d
Alias for 1D array.
static void Compute1DSourceAndReceiverConstants(localIndex const size, ArrayOfArraysView< localIndex const > const baseFacesToNodes, arrayView2d< real64 const, nodes::REFERENCE_POSITION_USD > const baseNodeCoords, arrayView1d< globalIndex const > const baseNodeLocalToGlobal, arrayView1d< globalIndex const > const elementLocalToGlobal, ArrayOfArraysView< localIndex const > const baseNodesToElements, arrayView2d< localIndex const, cells::NODE_MAP_USD > const &baseElemsToNodes, arrayView1d< integer const > const elemGhostRank, arrayView2d< localIndex const, cells::NODE_MAP_USD > const &elemsToNodes, arrayView2d< localIndex const > const elemsToFaces, arrayView2d< real64 const > const &elemCenter, arrayView2d< real64 const > const sourceCoordinates, arrayView1d< localIndex > const sourceIsAccessible, arrayView2d< localIndex > const sourceNodeIds, arrayView2d< real64 > const sourceConstants, arrayView2d< real64 const > const receiverCoordinates, arrayView1d< localIndex > const receiverIsLocal, arrayView2d< localIndex > const receiverNodeIds, arrayView2d< real64 > const receiverConstants, arrayView2d< real32 > const sourceValue, real64 const dt, real32 const timeSourceFrequency, real32 const timeSourceDelay, localIndex const rickerOrder, arrayView1d< TableFunction::KernelWrapper const > const sourceWaveletTableWrappers, bool useSourceWaveletTables)
Launches the precomputation of the source and receiver terms for 1D solution (2nd order acoustic)
static void Compute1DSourceAndReceiverConstantsWithElementsAndRegionStorage(localIndex const size, localIndex const regionIndex, ArrayOfArraysView< localIndex const > const baseFacesToNodes, arrayView2d< real64 const, nodes::REFERENCE_POSITION_USD > const baseNodeCoords, arrayView1d< globalIndex const > const baseNodeLocalToGlobal, arrayView1d< globalIndex const > const elementLocalToGlobal, ArrayOfArraysView< localIndex const > const baseNodesToElements, arrayView2d< localIndex const, cells::NODE_MAP_USD > const &baseElemsToNodes, arrayView1d< integer const > const elemGhostRank, arrayView2d< localIndex const, cells::NODE_MAP_USD > const &elemsToNodes, arrayView2d< localIndex const > const elemsToFaces, arrayView2d< real64 const > const &elemCenter, arrayView2d< real64 const > const sourceCoordinates, arrayView1d< localIndex > const sourceIsAccessible, arrayView1d< localIndex > const sourceElem, arrayView2d< localIndex > const sourceNodeIds, arrayView2d< real64 > const sourceConstants, arrayView1d< localIndex > const sourceRegion, arrayView2d< real64 const > const receiverCoordinates, arrayView1d< localIndex > const receiverIsLocal, arrayView1d< localIndex > const receiverElem, arrayView2d< localIndex > const receiverNodeIds, arrayView2d< real64 > const receiverConstants, arrayView1d< localIndex > const receiverRegion)
Launches the precomputation of the source and receiver terms with storage of elements and region in w...
static void Compute3DSourceAndReceiverConstantsWithDAS(localIndex const size, ArrayOfArraysView< localIndex const > const baseFacesToNodes, arrayView2d< real64 const, nodes::REFERENCE_POSITION_USD > const baseNodeCoords, arrayView1d< globalIndex const > const baseNodeLocalToGlobal, arrayView1d< globalIndex const > const elementLocalToGlobal, ArrayOfArraysView< localIndex const > const baseNodesToElements, arrayView2d< localIndex const, cells::NODE_MAP_USD > const &baseElemsToNodes, arrayView1d< integer const > const elemGhostRank, arrayView2d< localIndex const, cells::NODE_MAP_USD > const &elemsToNodes, arrayView2d< localIndex const > const elemsToFaces, arrayView2d< real64 const > const &elemCenter, arrayView2d< real64 const > const sourceCoordinates, arrayView1d< localIndex > const sourceIsAccessible, arrayView2d< localIndex > const sourceNodeIds, arrayView2d< real64 > const sourceConstantsx, arrayView2d< real64 > const sourceConstantsy, arrayView2d< real64 > const sourceConstantsz, arrayView2d< real64 const > const receiverCoordinates, arrayView1d< localIndex > const receiverIsLocal, arrayView2d< localIndex > const receiverNodeIds, arrayView2d< real64 > const receiverConstants, WaveSolverUtils::DASType useDAS, integer linearDASSamples, arrayView2d< real64 const > const linearDASGeometry, R1Tensor const sourceForce, R2SymTensor const sourceMoment)
Launches the precomputation of the source and receiver terms for 3D arrays solution and DAS receiver ...
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