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 >
77 constexpr
localIndex numNodesPerElem = FE_TYPE::numNodes;
81 real64 const center[3] = { elemCenter[k][0],
88 for(
localIndex isrc = 0; isrc < sourceCoordinates.size( 0 ); ++isrc )
90 if( sourceIsAccessible[isrc] == 0 )
92 real64 const coords[3] = { sourceCoordinates[isrc][0],
93 sourceCoordinates[isrc][1],
94 sourceCoordinates[isrc][2] };
95 bool const sourceFound =
96 computationalGeometry::isPointInsideConvexPolyhedronRobust( k,
101 baseNodeLocalToGlobal,
102 elementLocalToGlobal,
107 real64 coordsOnRefElem[3]{};
110 WaveSolverUtils::computeCoordinatesOnReferenceElement< FE_TYPE >( coords,
115 sourceIsAccessible[isrc] = 1;
116 real64 Ntest[numNodesPerElem];
117 FE_TYPE::calcN( coordsOnRefElem, Ntest );
119 for(
localIndex a = 0; a < numNodesPerElem; ++a )
121 sourceNodeIds[isrc][a] = elemsToNodes( k, a );
122 sourceConstants[isrc][a] = Ntest[a];
132 for(
localIndex ircv = 0; ircv < receiverCoordinates.size( 0 ); ++ircv )
134 if( receiverIsLocal[ircv] == 0 )
136 real64 const coords[3] = { receiverCoordinates[ircv][0],
137 receiverCoordinates[ircv][1],
138 receiverCoordinates[ircv][2] };
140 real64 coordsOnRefElem[3]{};
141 bool const receiverFound =
142 computationalGeometry::isPointInsideConvexPolyhedronRobust( k,
147 baseNodeLocalToGlobal,
148 elementLocalToGlobal,
152 if( receiverFound && elemGhostRank[k] < 0 )
154 WaveSolverUtils::computeCoordinatesOnReferenceElement< FE_TYPE >( coords,
159 receiverIsLocal[ircv] = 1;
161 real64 Ntest[numNodesPerElem];
162 FE_TYPE::calcN( coordsOnRefElem, Ntest );
164 for(
localIndex a = 0; a < numNodesPerElem; ++a )
166 receiverNodeIds[ircv][a] = elemsToNodes( k, a );
167 receiverConstants[ircv][a] = Ntest[a];
205 template<
typename EXEC_POLICY,
typename FE_TYPE >
232 constexpr
localIndex numNodesPerElem = FE_TYPE::numNodes;
236 real64 const center[3] = { elemCenter[k][0],
243 for(
localIndex isrc = 0; isrc < sourceCoordinates.size( 0 ); ++isrc )
245 if( sourceIsAccessible[isrc] == 0 )
247 real64 const coords[3] = { sourceCoordinates[isrc][0],
248 sourceCoordinates[isrc][1],
249 sourceCoordinates[isrc][2] };
251 bool const sourceFound =
252 computationalGeometry::isPointInsideConvexPolyhedronRobust( k,
257 baseNodeLocalToGlobal,
258 elementLocalToGlobal,
263 real64 coordsOnRefElem[3]{};
265 WaveSolverUtils::computeCoordinatesOnReferenceElement< FE_TYPE >( coords,
270 sourceIsAccessible[isrc] = 1;
271 sourceElem[isrc] = k;
272 sourceRegion[isrc] = regionIndex;
273 real64 Ntest[numNodesPerElem];
274 FE_TYPE::calcN( coordsOnRefElem, Ntest );
276 for(
localIndex a = 0; a < numNodesPerElem; ++a )
278 sourceNodeIds[isrc][a] = elemsToNodes[k][a];
279 sourceConstants[isrc][a] = Ntest[a];
290 for(
localIndex ircv = 0; ircv < receiverCoordinates.size( 0 ); ++ircv )
292 if( receiverIsLocal[ircv] == 0 )
294 real64 const coords[3] = { receiverCoordinates[ircv][0],
295 receiverCoordinates[ircv][1],
296 receiverCoordinates[ircv][2] };
298 real64 coordsOnRefElem[3]{};
299 bool const receiverFound =
300 computationalGeometry::isPointInsideConvexPolyhedronRobust( k,
305 baseNodeLocalToGlobal,
306 elementLocalToGlobal,
310 if( receiverFound && elemGhostRank[k] < 0 )
312 WaveSolverUtils::computeCoordinatesOnReferenceElement< FE_TYPE >( coords,
316 receiverIsLocal[ircv] = 1;
317 receiverElem[ircv] = k;
318 receiverRegion[ircv] = regionIndex;
320 real64 Ntest[numNodesPerElem];
321 FE_TYPE::calcN( coordsOnRefElem, Ntest );
323 for(
localIndex a = 0; a < numNodesPerElem; ++a )
325 receiverNodeIds[ircv][a] = elemsToNodes[k][a];
326 receiverConstants[ircv][a] = Ntest[a];
371 template<
typename EXEC_POLICY,
typename FE_TYPE >
400 constexpr
localIndex numNodesPerElem = FE_TYPE::numNodes;
409 real64 const center[3] = { elemCenter[k][0],
416 for(
localIndex isrc = 0; isrc < sourceCoordinates.size( 0 ); ++isrc )
418 if( sourceIsAccessible[isrc] == 0 )
420 real64 const coords[3] = { sourceCoordinates[isrc][0],
421 sourceCoordinates[isrc][1],
422 sourceCoordinates[isrc][2] };
430 xLocal[a][i] = baseNodeCoords( baseElemsToNodes( k, a ), i );
435 bool const sourceFound =
436 computationalGeometry::isPointInsideConvexPolyhedronRobust( k,
441 baseNodeLocalToGlobal,
442 elementLocalToGlobal,
448 real64 coordsOnRefElem[3]{};
451 WaveSolverUtils::computeCoordinatesOnReferenceElement< FE_TYPE >( coords,
455 sourceIsAccessible[isrc] = 1;
457 real64 N[numNodesPerElem];
458 real64 gradN[numNodesPerElem][3];
459 FE_TYPE::calcN( coordsOnRefElem, N );
460 FE_TYPE::calcGradNWithCorners( coordsOnRefElem, xLocal, gradN );
462 for(
localIndex q=0; q< numNodesPerElem; ++q )
464 real64 inc[3] = { 0, 0, 0 };
465 sourceNodeIds[isrc][q] = elemsToNodes( k, q );
466 inc[0] += sourceForce[0] * N[q];
467 inc[1] += sourceForce[1] * N[q];
468 inc[2] += sourceForce[2] * N[q];
470 LvArray::tensorOps::Ri_add_symAijBj< 3 >( inc, moment.
data, gradN[q] );
471 sourceConstantsx[isrc][q] += inc[0];
472 sourceConstantsy[isrc][q] += inc[1];
473 sourceConstantsz[isrc][q] += inc[2];
488 samplePointLocations[ 0 ] = 0;
492 for(
integer i = 0; i < nSamples; ++i )
494 samplePointLocations[ i ] = -0.5 + (
real64) i / ( linearDASSamples - 1 );
502 sampleIntegrationConstants[ 0 ] = -1.0;
503 sampleIntegrationConstants[ 1 ] = 1.0;
506 else if( nSamples == 1 )
508 sampleIntegrationConstants[ 0 ] = 1.0;
512 for(
integer i = 0; i < linearDASSamples; i++ )
514 sampleIntegrationConstants[ i ] = 1.0 / nSamples;
519 for(
localIndex ircv = 0; ircv < receiverCoordinates.size( 0 ); ++ircv )
521 R1Tensor receiverCenter = { receiverCoordinates[ ircv ][ 0 ], receiverCoordinates[ ircv ][ 1 ], receiverCoordinates[ ircv ][ 2 ] };
525 receiverVector = { 0, 0, 0 };
533 for(
integer iSample = 0; iSample < nSamples; ++iSample )
536 real64 const coords[3] = { receiverCenter[ 0 ] + receiverVector[ 0 ] * receiverLength * samplePointLocations[ iSample ],
537 receiverCenter[ 1 ] + receiverVector[ 1 ] * receiverLength * samplePointLocations[ iSample ],
538 receiverCenter[ 2 ] + receiverVector[ 2 ] * receiverLength * samplePointLocations[ iSample ] };
539 bool const sampleFound =
540 computationalGeometry::isPointInsideConvexPolyhedronRobust( k,
545 baseNodeLocalToGlobal,
546 elementLocalToGlobal,
549 if( sampleFound && elemGhostRank[k] < 0 )
551 real64 coordsOnRefElem[3]{};
558 xLocal[a][i] = baseNodeCoords( baseElemsToNodes( k, a ), i );
562 WaveSolverUtils::computeCoordinatesOnReferenceElement< FE_TYPE >( coords,
566 real64 N[numNodesPerElem];
567 real64 gradN[numNodesPerElem][3];
568 FE_TYPE::calcN( coordsOnRefElem, N );
569 FE_TYPE::calcGradNWithCorners( coordsOnRefElem, xLocal, gradN );
570 for(
localIndex a = 0; a < numNodesPerElem; ++a )
572 receiverNodeIds[ircv][iSample * numNodesPerElem + a] = elemsToNodes( k,
576 receiverConstants[ircv][iSample * numNodesPerElem + a] += ( gradN[a][0] * receiverVector[0] + gradN[a][1] * receiverVector[1] + gradN[a][2] * receiverVector[2] ) *
577 sampleIntegrationConstants[ iSample ];
581 receiverConstants[ircv][iSample * numNodesPerElem + a] += N[a] * sampleIntegrationConstants[ iSample ];
584 receiverIsLocal[ ircv ] = 2;
588 real64 const coords[3] = { receiverCenter[ 0 ], receiverCenter[ 1 ], receiverCenter[ 2 ] };
589 bool const receiverFound =
590 computationalGeometry::isPointInsideConvexPolyhedronRobust( k,
595 baseNodeLocalToGlobal,
596 elementLocalToGlobal,
599 if( receiverFound && elemGhostRank[k] < 0 )
601 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.
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)
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