GEOS
PrecomputeSourcesAndReceiversKernel.hpp
Go to the documentation of this file.
1 /*
2  * ------------------------------------------------------------------------------------------------------------
3  * SPDX-License-Identifier: LGPL-2.1-only
4  *
5  * Copyright (c) 2016-2024 Lawrence Livermore National Security LLC
6  * Copyright (c) 2018-2024 Total, S.A
7  * Copyright (c) 2018-2024 The Board of Trustees of the Leland Stanford Junior University
8  * Copyright (c) 2023-2024 Chevron
9  * Copyright (c) 2019- GEOS/GEOSX Contributors
10  * All rights reserved
11  *
12  * See top level LICENSE, COPYRIGHT, CONTRIBUTORS, NOTICE, and ACKNOWLEDGEMENTS files for details.
13  * ------------------------------------------------------------------------------------------------------------
14  */
15 
20 #ifndef GEOS_PHYSICSSOLVERS_WAVEPROPAGATION_PRECOMPUTESOURCESANDRECEIVERSKERNEL_HPP_
21 #define GEOS_PHYSICSSOLVERS_WAVEPROPAGATION_PRECOMPUTESOURCESANDRECEIVERSKERNEL_HPP_
22 
23 namespace geos
24 {
25 
27 {
28 
29  using EXEC_POLICY = parallelDevicePolicy< >;
30 
55  template< typename EXEC_POLICY, typename FE_TYPE >
56  static void
58  ArrayOfArraysView< localIndex const > const baseFacesToNodes,
60  arrayView1d< globalIndex const > const baseNodeLocalToGlobal,
61  arrayView1d< globalIndex const > const elementLocalToGlobal,
62  ArrayOfArraysView< localIndex const > const baseNodesToElements,
64  arrayView1d< integer const > const elemGhostRank,
66  arrayView2d< localIndex const > const elemsToFaces,
67  arrayView2d< real64 const > const & elemCenter,
68  arrayView2d< real64 const > const sourceCoordinates,
69  arrayView1d< localIndex > const sourceIsAccessible,
70  arrayView2d< localIndex > const sourceNodeIds,
71  arrayView2d< real64 > const sourceConstants,
72  arrayView2d< real64 const > const receiverCoordinates,
73  arrayView1d< localIndex > const receiverIsLocal,
74  arrayView2d< localIndex > const receiverNodeIds,
75  arrayView2d< real64 > const receiverConstants )
76  {
77  constexpr localIndex numNodesPerElem = FE_TYPE::numNodes;
78 
79  forAll< EXEC_POLICY >( size, [=] GEOS_HOST_DEVICE ( localIndex const k )
80  {
81  real64 const center[3] = { elemCenter[k][0],
82  elemCenter[k][1],
83  elemCenter[k][2] };
84 
85  // Step 1: locate the sources, and precompute the source term
86 
88  for( localIndex isrc = 0; isrc < sourceCoordinates.size( 0 ); ++isrc )
89  {
90  if( sourceIsAccessible[isrc] == 0 )
91  {
92  real64 const coords[3] = { sourceCoordinates[isrc][0],
93  sourceCoordinates[isrc][1],
94  sourceCoordinates[isrc][2] };
95  bool const sourceFound =
96  computationalGeometry::isPointInsideConvexPolyhedronRobust( k,
97  baseNodeCoords,
98  elemsToFaces,
99  baseFacesToNodes,
100  baseNodesToElements,
101  baseNodeLocalToGlobal,
102  elementLocalToGlobal,
103  center,
104  coords );
105  if( sourceFound )
106  {
107  real64 coordsOnRefElem[3]{};
108 
109 
110  WaveSolverUtils::computeCoordinatesOnReferenceElement< FE_TYPE >( coords,
111  baseElemsToNodes[k],
112  baseNodeCoords,
113  coordsOnRefElem );
114 
115  sourceIsAccessible[isrc] = 1;
116  real64 Ntest[numNodesPerElem];
117  FE_TYPE::calcN( coordsOnRefElem, Ntest );
118 
119  for( localIndex a = 0; a < numNodesPerElem; ++a )
120  {
121  sourceNodeIds[isrc][a] = elemsToNodes( k, a );
122  sourceConstants[isrc][a] = Ntest[a];
123  }
124  }
125  }
126  } // end loop over all sources
127 
128 
129  // Step 2: locate the receivers, and precompute the receiver term
130 
132  for( localIndex ircv = 0; ircv < receiverCoordinates.size( 0 ); ++ircv )
133  {
134  if( receiverIsLocal[ircv] == 0 )
135  {
136  real64 const coords[3] = { receiverCoordinates[ircv][0],
137  receiverCoordinates[ircv][1],
138  receiverCoordinates[ircv][2] };
139 
140  real64 coordsOnRefElem[3]{};
141  bool const receiverFound =
142  computationalGeometry::isPointInsideConvexPolyhedronRobust( k,
143  baseNodeCoords,
144  elemsToFaces,
145  baseFacesToNodes,
146  baseNodesToElements,
147  baseNodeLocalToGlobal,
148  elementLocalToGlobal,
149  center,
150  coords );
151 
152  if( receiverFound && elemGhostRank[k] < 0 )
153  {
154  WaveSolverUtils::computeCoordinatesOnReferenceElement< FE_TYPE >( coords,
155  baseElemsToNodes[k],
156  baseNodeCoords,
157  coordsOnRefElem );
158 
159  receiverIsLocal[ircv] = 1;
160 
161  real64 Ntest[numNodesPerElem];
162  FE_TYPE::calcN( coordsOnRefElem, Ntest );
163 
164  for( localIndex a = 0; a < numNodesPerElem; ++a )
165  {
166  receiverNodeIds[ircv][a] = elemsToNodes( k, a );
167  receiverConstants[ircv][a] = Ntest[a];
168  }
169  }
170  }
171  } // end loop over receivers
172 
173  } );
174 
175  }
176 
177 
205  template< typename EXEC_POLICY, typename FE_TYPE >
206  static void
208  localIndex const regionIndex,
209  ArrayOfArraysView< localIndex const > const baseFacesToNodes,
211  arrayView1d< globalIndex const > const baseNodeLocalToGlobal,
212  arrayView1d< globalIndex const > const elementLocalToGlobal,
213  ArrayOfArraysView< localIndex const > const baseNodesToElements,
215  arrayView1d< integer const > const elemGhostRank,
217  arrayView2d< localIndex const > const elemsToFaces,
218  arrayView2d< real64 const > const & elemCenter,
219  arrayView2d< real64 const > const sourceCoordinates,
220  arrayView1d< localIndex > const sourceIsAccessible,
221  arrayView1d< localIndex > const sourceElem,
222  arrayView2d< localIndex > const sourceNodeIds,
223  arrayView2d< real64 > const sourceConstants,
224  arrayView1d< localIndex > const sourceRegion,
225  arrayView2d< real64 const > const receiverCoordinates,
226  arrayView1d< localIndex > const receiverIsLocal,
227  arrayView1d< localIndex > const receiverElem,
228  arrayView2d< localIndex > const receiverNodeIds,
229  arrayView2d< real64 > const receiverConstants,
230  arrayView1d< localIndex > const receiverRegion )
231  {
232  constexpr localIndex numNodesPerElem = FE_TYPE::numNodes;
233 
234  forAll< EXEC_POLICY >( size, [=] GEOS_HOST_DEVICE ( localIndex const k )
235  {
236  real64 const center[3] = { elemCenter[k][0],
237  elemCenter[k][1],
238  elemCenter[k][2] };
239 
240  // Step 1: locate the sources, and precompute the source term
241 
243  for( localIndex isrc = 0; isrc < sourceCoordinates.size( 0 ); ++isrc )
244  {
245  if( sourceIsAccessible[isrc] == 0 )
246  {
247  real64 const coords[3] = { sourceCoordinates[isrc][0],
248  sourceCoordinates[isrc][1],
249  sourceCoordinates[isrc][2] };
250 
251  bool const sourceFound =
252  computationalGeometry::isPointInsideConvexPolyhedronRobust( k,
253  baseNodeCoords,
254  elemsToFaces,
255  baseFacesToNodes,
256  baseNodesToElements,
257  baseNodeLocalToGlobal,
258  elementLocalToGlobal,
259  center,
260  coords );
261  if( sourceFound )
262  {
263  real64 coordsOnRefElem[3]{};
264 
265  WaveSolverUtils::computeCoordinatesOnReferenceElement< FE_TYPE >( coords,
266  baseElemsToNodes[k],
267  baseNodeCoords,
268  coordsOnRefElem );
269 
270  sourceIsAccessible[isrc] = 1;
271  sourceElem[isrc] = k;
272  sourceRegion[isrc] = regionIndex;
273  real64 Ntest[numNodesPerElem];
274  FE_TYPE::calcN( coordsOnRefElem, Ntest );
275 
276  for( localIndex a = 0; a < numNodesPerElem; ++a )
277  {
278  sourceNodeIds[isrc][a] = elemsToNodes[k][a];
279  sourceConstants[isrc][a] = Ntest[a];
280  }
281 
282  }
283  }
284  } // end loop over all sources
285 
286 
287  // Step 2: locate the receivers, and precompute the receiver term
288 
290  for( localIndex ircv = 0; ircv < receiverCoordinates.size( 0 ); ++ircv )
291  {
292  if( receiverIsLocal[ircv] == 0 )
293  {
294  real64 const coords[3] = { receiverCoordinates[ircv][0],
295  receiverCoordinates[ircv][1],
296  receiverCoordinates[ircv][2] };
297 
298  real64 coordsOnRefElem[3]{};
299  bool const receiverFound =
300  computationalGeometry::isPointInsideConvexPolyhedronRobust( k,
301  baseNodeCoords,
302  elemsToFaces,
303  baseFacesToNodes,
304  baseNodesToElements,
305  baseNodeLocalToGlobal,
306  elementLocalToGlobal,
307  center,
308  coords );
309 
310  if( receiverFound && elemGhostRank[k] < 0 )
311  {
312  WaveSolverUtils::computeCoordinatesOnReferenceElement< FE_TYPE >( coords,
313  baseElemsToNodes[k],
314  baseNodeCoords,
315  coordsOnRefElem );
316  receiverIsLocal[ircv] = 1;
317  receiverElem[ircv] = k;
318  receiverRegion[ircv] = regionIndex;
319 
320  real64 Ntest[numNodesPerElem];
321  FE_TYPE::calcN( coordsOnRefElem, Ntest );
322 
323  for( localIndex a = 0; a < numNodesPerElem; ++a )
324  {
325  receiverNodeIds[ircv][a] = elemsToNodes[k][a];
326  receiverConstants[ircv][a] = Ntest[a];
327  }
328  }
329  }
330  } // end loop over receivers
331 
332  } );
333 
334  }
335 
336 
337 
371  template< typename EXEC_POLICY, typename FE_TYPE >
372  static void
374  ArrayOfArraysView< localIndex const > const baseFacesToNodes,
376  arrayView1d< globalIndex const > const baseNodeLocalToGlobal,
377  arrayView1d< globalIndex const > const elementLocalToGlobal,
378  ArrayOfArraysView< localIndex const > const baseNodesToElements,
380  arrayView1d< integer const > const elemGhostRank,
382  arrayView2d< localIndex const > const elemsToFaces,
383  arrayView2d< real64 const > const & elemCenter,
384  arrayView2d< real64 const > const sourceCoordinates,
385  arrayView1d< localIndex > const sourceIsAccessible,
386  arrayView2d< localIndex > const sourceNodeIds,
387  arrayView2d< real64 > const sourceConstantsx,
388  arrayView2d< real64 > const sourceConstantsy,
389  arrayView2d< real64 > const sourceConstantsz,
390  arrayView2d< real64 const > const receiverCoordinates,
391  arrayView1d< localIndex > const receiverIsLocal,
392  arrayView2d< localIndex > const receiverNodeIds,
393  arrayView2d< real64 > const receiverConstants,
395  integer linearDASSamples,
396  arrayView2d< real64 const > const linearDASGeometry,
397  R1Tensor const sourceForce,
398  R2SymTensor const sourceMoment )
399  {
400  constexpr localIndex numNodesPerElem = FE_TYPE::numNodes;
401  integer nSamples = useDAS == WaveSolverUtils::DASType::none ? 1 : linearDASSamples;
402  array1d< real64 > const samplePointLocationsA( nSamples );
403  arrayView1d< real64 > const samplePointLocations = samplePointLocationsA.toView();
404  array1d< real64 > const sampleIntegrationConstantsA( nSamples );
405  arrayView1d< real64 > const sampleIntegrationConstants = sampleIntegrationConstantsA.toView();
406 
407  forAll< EXEC_POLICY >( size, [=] GEOS_HOST_DEVICE ( localIndex const k )
408  {
409  real64 const center[3] = { elemCenter[k][0],
410  elemCenter[k][1],
411  elemCenter[k][2] };
412 
413  // Step 1: locate the sources, and precompute the source term
414 
416  for( localIndex isrc = 0; isrc < sourceCoordinates.size( 0 ); ++isrc )
417  {
418  if( sourceIsAccessible[isrc] == 0 )
419  {
420  real64 const coords[3] = { sourceCoordinates[isrc][0],
421  sourceCoordinates[isrc][1],
422  sourceCoordinates[isrc][2] };
423 
424  real64 xLocal[8][3];
425 
426  for( localIndex a = 0; a < 8; ++a )
427  {
428  for( localIndex i = 0; i < 3; ++i )
429  {
430  xLocal[a][i] = baseNodeCoords( baseElemsToNodes( k, a ), i );
431  }
432  }
433 
434 
435  bool const sourceFound =
436  computationalGeometry::isPointInsideConvexPolyhedronRobust( k,
437  baseNodeCoords,
438  elemsToFaces,
439  baseFacesToNodes,
440  baseNodesToElements,
441  baseNodeLocalToGlobal,
442  elementLocalToGlobal,
443  center,
444  coords );
445 
446  if( sourceFound )
447  {
448  real64 coordsOnRefElem[3]{};
449 
450 
451  WaveSolverUtils::computeCoordinatesOnReferenceElement< FE_TYPE >( coords,
452  baseElemsToNodes[k],
453  baseNodeCoords,
454  coordsOnRefElem );
455  sourceIsAccessible[isrc] = 1;
456 
457  real64 N[numNodesPerElem];
458  real64 gradN[numNodesPerElem][3];
459  FE_TYPE::calcN( coordsOnRefElem, N );
460  FE_TYPE::calcGradNWithCorners( coordsOnRefElem, xLocal, gradN );
461  R2SymTensor moment = sourceMoment;
462  for( localIndex q=0; q< numNodesPerElem; ++q )
463  {
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];
469 
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];
474  }
475 
476  }
477  }
478  } // end loop over all sources
479 
480  // Step 2: locate the receivers, and precompute the receiver term
481 
482  // for geophones, we need only a point per receiver.
483  // for DAS, we need multiple points
484 
486  if( nSamples == 1 )
487  {
488  samplePointLocations[ 0 ] = 0;
489  }
490  else
491  {
492  for( integer i = 0; i < nSamples; ++i )
493  {
494  samplePointLocations[ i ] = -0.5 + (real64) i / ( linearDASSamples - 1 );
495  }
496  }
497 
500  if( useDAS == WaveSolverUtils::DASType::dipole )
501  {
502  sampleIntegrationConstants[ 0 ] = -1.0;
503  sampleIntegrationConstants[ 1 ] = 1.0;
504  }
506  else if( nSamples == 1 )
507  {
508  sampleIntegrationConstants[ 0 ] = 1.0;
509  }
510  else
511  {
512  for( integer i = 0; i < linearDASSamples; i++ )
513  {
514  sampleIntegrationConstants[ i ] = 1.0 / nSamples;
515  }
516  }
517 
519  for( localIndex ircv = 0; ircv < receiverCoordinates.size( 0 ); ++ircv )
520  {
521  R1Tensor receiverCenter = { receiverCoordinates[ ircv ][ 0 ], receiverCoordinates[ ircv ][ 1 ], receiverCoordinates[ ircv ][ 2 ] };
522  R1Tensor receiverVector;
523  if( useDAS == WaveSolverUtils::DASType::none )
524  {
525  receiverVector = { 0, 0, 0 };
526  }
527  else
528  {
529  receiverVector = WaveSolverUtils::computeDASVector( linearDASGeometry[ ircv ][ 0 ], linearDASGeometry[ ircv ][ 1 ] );
530  }
531  real64 receiverLength = useDAS == WaveSolverUtils::DASType::none ? 0 : linearDASGeometry[ ircv ][ 2 ];
533  for( integer iSample = 0; iSample < nSamples; ++iSample )
534  {
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,
541  baseNodeCoords,
542  elemsToFaces,
543  baseFacesToNodes,
544  baseNodesToElements,
545  baseNodeLocalToGlobal,
546  elementLocalToGlobal,
547  center,
548  coords );
549  if( sampleFound && elemGhostRank[k] < 0 )
550  {
551  real64 coordsOnRefElem[3]{};
552  real64 xLocal[8][3];
553 
554  for( localIndex a = 0; a < 8; ++a )
555  {
556  for( localIndex i=0; i < 3; ++i )
557  {
558  xLocal[a][i] = baseNodeCoords( baseElemsToNodes( k, a ), i );
559  }
560  }
561 
562  WaveSolverUtils::computeCoordinatesOnReferenceElement< FE_TYPE >( coords,
563  baseElemsToNodes[k],
564  baseNodeCoords,
565  coordsOnRefElem );
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 )
571  {
572  receiverNodeIds[ircv][iSample * numNodesPerElem + a] = elemsToNodes( k,
573  a );
575  {
576  receiverConstants[ircv][iSample * numNodesPerElem + a] += ( gradN[a][0] * receiverVector[0] + gradN[a][1] * receiverVector[1] + gradN[a][2] * receiverVector[2] ) *
577  sampleIntegrationConstants[ iSample ];
578  }
579  else
580  {
581  receiverConstants[ircv][iSample * numNodesPerElem + a] += N[a] * sampleIntegrationConstants[ iSample ];
582  }
583  }
584  receiverIsLocal[ ircv ] = 2;
585  }
586  } // end loop over samples
587  // determine if the current rank is the owner of this receiver
588  real64 const coords[3] = { receiverCenter[ 0 ], receiverCenter[ 1 ], receiverCenter[ 2 ] };
589  bool const receiverFound =
590  computationalGeometry::isPointInsideConvexPolyhedronRobust( k,
591  baseNodeCoords,
592  elemsToFaces,
593  baseFacesToNodes,
594  baseNodesToElements,
595  baseNodeLocalToGlobal,
596  elementLocalToGlobal,
597  center,
598  coords );
599  if( receiverFound && elemGhostRank[k] < 0 )
600  {
601  receiverIsLocal[ ircv ] = 1;
602  }
603  } // end loop over receivers
604  } );
605 
606  }
607 
608 };
609 
610 } // namespace geos
611 
612 #endif //GEOS_PHYSICSSOLVERS_WAVEPROPAGATION_PRECOMPUTESOURCESANDRECEIVERSKERNEL_HPP_
#define GEOS_HOST_DEVICE
Marks a host-device function.
Definition: GeosxMacros.hpp:49
T data[SIZE]
Underlying array.
Definition: Tensor.hpp:142
ArrayView< T, 1 > arrayView1d
Alias for 1D array view.
Definition: DataTypes.hpp:180
LvArray::ArrayOfArraysView< T, INDEX_TYPE const, CONST_SIZES, LvArray::ChaiBuffer > ArrayOfArraysView
View of array of variable-sized arrays. See LvArray::ArrayOfArraysView for details.
Definition: DataTypes.hpp:286
double real64
64-bit floating point type.
Definition: DataTypes.hpp:99
GEOS_LOCALINDEX_TYPE localIndex
Local index type (for indexing objects within an MPI partition).
Definition: DataTypes.hpp:85
std::int32_t integer
Signed integer type.
Definition: DataTypes.hpp:82
ArrayView< T, 2, USD > arrayView2d
Alias for 2D array view.
Definition: DataTypes.hpp:196
Array< T, 1 > array1d
Alias for 1D array.
Definition: DataTypes.hpp:176
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