GEOS
WaveSolverBase.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 TotalEnergies
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 
16 
21 #ifndef GEOS_PHYSICSSOLVERS_WAVEPROPAGATION_WAVESOLVERBASE_HPP_
22 #define GEOS_PHYSICSSOLVERS_WAVEPROPAGATION_WAVESOLVERBASE_HPP_
23 
24 
25 #include "mesh/MeshFields.hpp"
27 #include "common/LifoStorage.hpp"
29 #if !defined( GEOS_USE_HIP )
31 #endif
32 #include "mesh/DomainPartition.hpp"
33 #include "WaveSolverUtils.hpp"
34 
35 #if !defined( GEOS_USE_HIP )
36 #define SEM_FE_TYPES \
37  finiteElement::Q1_Hexahedron_Lagrange_GaussLobatto, \
38  finiteElement::Q2_Hexahedron_Lagrange_GaussLobatto, \
39  finiteElement::Q3_Hexahedron_Lagrange_GaussLobatto, \
40  finiteElement::Q4_Hexahedron_Lagrange_GaussLobatto, \
41  finiteElement::Q5_Hexahedron_Lagrange_GaussLobatto
42 #else
43 #define SEM_FE_TYPES
44 #endif
45 
46 #define SELECTED_FE_TYPES SEM_FE_TYPES
47 
48 namespace geos
49 {
50 
52 {
53 public:
54 
55  static constexpr real64 epsilonLoc = WaveSolverUtils::epsilonLoc;
56  using EXEC_POLICY = WaveSolverUtils::EXEC_POLICY;
57  using wsCoordType = WaveSolverUtils::wsCoordType;
58 
59  WaveSolverBase( const std::string & name,
60  Group * const parent );
61 
62  virtual ~WaveSolverBase() override;
63 
64  WaveSolverBase() = delete;
65  WaveSolverBase( WaveSolverBase const & ) = delete;
66  WaveSolverBase( WaveSolverBase && ) = default;
67 
68  WaveSolverBase & operator=( WaveSolverBase const & ) = delete;
69  WaveSolverBase & operator=( WaveSolverBase && ) = delete;
70 
71  virtual void initializePreSubGroups() override;
72 
73  virtual real64 solverStep( real64 const & time_n,
74  real64 const & dt,
75  integer const cycleNumber,
76  DomainPartition & domain ) override;
77 
78 
79  virtual real64 explicitStep( real64 const & time_n,
80  real64 const & dt,
81  integer const cycleNumber,
82  DomainPartition & domain ) override;
83 
85  {
86  static constexpr char const * sourceCoordinatesString() { return "sourceCoordinates"; }
87  static constexpr char const * sourceValueString() { return "sourceValue"; }
88 
89  static constexpr char const * timeSourceFrequencyString() { return "timeSourceFrequency"; }
90  static constexpr char const * timeSourceDelayString() { return "timeSourceDelay"; }
91  static constexpr char const * rickerOrderString() { return "rickerOrder"; }
92 
93  static constexpr char const * receiverCoordinatesString() { return "receiverCoordinates"; }
94 
95  static constexpr char const * sourceNodeIdsString() { return "sourceNodeIds"; }
96  static constexpr char const * sourceConstantsString() { return "sourceConstants"; }
97  static constexpr char const * sourceIsAccessibleString() { return "sourceIsAccessible"; }
98 
99  static constexpr char const * receiverNodeIdsString() { return "receiverNodeIds"; }
100  static constexpr char const * receiverConstantsString() {return "receiverConstants"; }
101  static constexpr char const * receiverIsLocalString() { return "receiverIsLocal"; }
102 
103  static constexpr char const * outputSeismoTraceString() { return "outputSeismoTrace"; }
104  static constexpr char const * dtSeismoTraceString() { return "dtSeismoTrace"; }
105  static constexpr char const * indexSeismoTraceString() { return "indexSeismoTrace"; }
106  static constexpr char const * forwardString() { return "forward"; }
107  static constexpr char const * saveFieldsString() { return "saveFields"; }
108  static constexpr char const * shotIndexString() { return "shotIndex"; }
109  static constexpr char const * enableLifoString() { return "enableLifo"; }
110  static constexpr char const * lifoSizeString() { return "lifoSize"; }
111  static constexpr char const * lifoOnDeviceString() { return "lifoOnDevice"; }
112  static constexpr char const * lifoOnHostString() { return "lifoOnHost"; }
113 
114  static constexpr char const * useDASString() { return "useDAS"; }
115  static constexpr char const * linearDASSamplesString() { return "linearDASSamples"; }
116  static constexpr char const * linearDASGeometryString() { return "linearDASGeometry"; }
117  static constexpr char const * linearDASVectorXString() { return "linearDASVectorX"; }
118  static constexpr char const * linearDASVectorYString() { return "linearDASVectorY"; }
119  static constexpr char const * linearDASVectorZString() { return "linearDASVectorZ"; }
120 
121  static constexpr char const * usePMLString() { return "usePML"; }
122  static constexpr char const * parametersPMLString() { return "parametersPML"; }
123 
124  static constexpr char const * receiverElemString() { return "receiverElem"; }
125  static constexpr char const * receiverRegionString() { return "receiverRegion"; }
126  static constexpr char const * freeSurfaceString() { return "FreeSurface"; }
127 
128  static constexpr char const * timestepStabilityLimitString() { return "timestepStabilityLimit"; }
129  static constexpr char const * timeStepString() { return "timeStep"; }
130 
131  static constexpr char const * attenuationTypeString() { return "attenuationType"; }
132  static constexpr char const * slsReferenceAngularFrequenciesString() { return "slsReferenceAngularFrequencies"; }
133  static constexpr char const * slsAnelasticityCoefficientsString() { return "slsAnelasticityCoefficients"; }
134 
135  static constexpr char const * sourceWaveletTableNames() { return "sourceWaveletTableNames"; }
136  };
137 
141  void reinit() override final;
142 
143  SortedArray< localIndex > const & getSolverNodesSet() { return m_solverTargetNodesSet; }
144 
145  void computeTargetNodeSet( arrayView2d< localIndex const, cells::NODE_MAP_USD > const & elemsToNodes,
146  localIndex const subRegionSize,
147  localIndex const numQuadraturePointsPerElem );
148 
155  template< typename F, typename T >
157  {
158  RAJA::ReduceMin< ReducePolicy< EXEC_POLICY >, T > minF( LvArray::NumericLimits< T >::max );
159 
160  forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&] ( string const &,
161  MeshLevel & mesh,
162  string_array const & regionNames )
163  {
164  mesh.getElemManager().forElementSubRegions< CellElementSubRegion >( regionNames, [&]( localIndex const,
165  CellElementSubRegion & elementSubRegion )
166  {
167  arrayView1d< T const > const f = elementSubRegion.getField< F >();
168  forAll< EXEC_POLICY >( elementSubRegion.size(), [=] GEOS_HOST_DEVICE ( localIndex const e ) {
169  minF.min( f[e] );
170  } );
171  } );
172  } );
173  T minFVal = minF.get();
174  return MpiWrapper::min< T >( minFVal );
175  }
176 
182  template< typename ... Qs >
184  {
185  // compute miniumum quality factor
186  real32 minQVal = LvArray::NumericLimits< real32 >::max;
187  ( (minQVal = std::min( minQVal, computeGlobalMinOfElemField< Qs, real32 >( domain ) ) ), ... );
188  if( m_slsAnelasticityCoefficients.size( 0 ) == 1 && m_slsAnelasticityCoefficients[ 0 ] < 0 )
189  {
190  m_slsAnelasticityCoefficients[ 0 ] = 2.0 * minQVal / ( minQVal - 1.0 );
191  }
192  // test if anelasticity is too high and artifacts could appear
193  real32 ySum = 0.0;
194  for( integer l = 0; l < m_slsAnelasticityCoefficients.size( 0 ); l++ )
195  {
196  ySum += m_slsAnelasticityCoefficients[ l ];
197  }
198  GEOS_WARNING_IF( ySum > minQVal, "The anelasticity parameters are too high for the given quality factor. This could lead to solution artifacts such as zero-velocity waves." );
199  }
200 
201 protected:
202 
203  virtual void postInputInitialization() override;
204 
210  bool directoryExists( std::string const & directoryName );
211 
217  virtual void applyFreeSurfaceBC( real64 const time, DomainPartition & domain ) = 0;
218 
221  virtual real64 computeTimeStep( real64 & dtOut ) = 0;
222 
226  virtual void initializePML() = 0;
227 
228  virtual void incrementIndexSeismoTrace( real64 const time_n );
229 
240  virtual void computeAllSeismoTraces( real64 const time_n,
241  real64 const dt,
242  arrayView1d< real32 const > const var_np1,
243  arrayView1d< real32 const > const var_n,
244  arrayView2d< real32 > varAtReceivers,
245  arrayView1d< real32 > coeffs = {},
246  bool add = false );
255  virtual void compute2dVariableAllSeismoTraces( localIndex const regionIndex,
256  real64 const time_n,
257  real64 const dt,
258  arrayView2d< real32 const > const var_np1,
259  arrayView2d< real32 const > const var_n,
260  arrayView2d< real32 > varAtReceivers );
261 
267  virtual void applyPML( real64 const time, DomainPartition & domain ) = 0;
268 
275  virtual void precomputeSourceAndReceiverTerm( MeshLevel & baseMesh, MeshLevel & mesh, string_array const & regionNames ) = 0;
276 
286  virtual real64 explicitStepForward( real64 const & time_n,
287  real64 const & dt,
288  integer const cycleNumber,
289  DomainPartition & domain,
290  integer const computeGradient ) = 0;
300  virtual real64 explicitStepBackward( real64 const & time_n,
301  real64 const & dt,
302  integer const cycleNumber,
303  DomainPartition & domain,
304  integer const computeGradient ) = 0;
305 
306 
307  virtual void registerDataOnMesh( Group & meshBodies ) override;
308 
309  localIndex getNumNodesPerElem();
310 
313 
316 
319 
322 
325 
328 
331 
334 
337 
340 
343 
346 
349 
352 
355 
358 
361 
364 
367 
370 
373 
374  // Indicate the current shot computed for naming saved temporary data
375  integer m_shotIndex;
376 
379 
384 
385  //Time step computed with power iteration
386  real64 m_timeStep;
387 
390 
393 
396 
399 
402 
405 
408 
411 
414 
417 
420 
423 
425  std::unique_ptr< LifoStorage< real32, localIndex > > m_lifo;
426 
429 
432 
435 
438 
440  {
443 
446 
449 
452  R1Tensor32 thicknessMaxXYZPML;
453 
456  R1Tensor32 waveSpeedMaxXYZPML;
457  };
458 
459 };
460 
461 namespace fields
462 {
464 DECLARE_FIELD( referencePosition32,
465  "referencePosition32",
466  reference32Type,
467  0,
468  NOPLOT,
469  WRITE_AND_READ,
470  "Copy of the referencePosition from NodeManager in 32 bits integer" );
471 }
472 } /* namespace geos */
473 
474 #endif /* GEOS_PHYSICSSOLVERS_WAVEPROPAGATION_WAVESOLVERBASE_HPP_ */
#define GEOS_WARNING_IF(EXP, msg)
Conditionally report a warning.
Definition: Logger.hpp:184
#define DECLARE_FIELD(NAME, KEY, TYPE, DEFAULT, PLOTLEVEL, RESTARTFLAG, DESCRIPTION)
Generates a traits struct.
Definition: MeshFields.hpp:39
Partition of the decomposed physical domain. It also manages the connexion information to its neighbo...
Group const & getMeshBodies() const
Get the mesh bodies, const version.
Class facilitating the representation of a multi-level discretization of a MeshBody.
Definition: MeshLevel.hpp:42
Base class for all physics solvers.
void forDiscretizationOnMeshTargets(Group const &meshBodies, LAMBDA &&lambda) const
Loop over the target discretization on all mesh targets and apply callback.
localIndex m_nsamplesSeismoTrace
Amount of seismoTrace that will be recorded for each receiver.
array1d< real32 > m_linearDASVectorX
X component of the linear DAS direction vector.
real32 m_timeSourceFrequency
Central frequency for the Ricker time source.
T computeGlobalMinOfElemField(DomainPartition &domain)
Computes the minimum value of the given element field over the whole mesh.
integer m_usePML
Flag to apply PML.
array1d< localIndex > m_receiverIsLocal
Flag that indicates whether the receiver is local or not to the MPI rank.
std::unique_ptr< LifoStorage< real32, localIndex > > m_lifo
LIFO to store p_dt2.
virtual void initializePML()=0
Initialize Perfectly Matched Layer (PML) information.
array1d< localIndex > m_sourceIsAccessible
Flag that indicates whether the source is local or not to the MPI rank.
virtual void applyPML(real64 const time, DomainPartition &domain)=0
Apply Perfectly Matched Layer (PML) to the regions defined in the geometry box from the xml.
virtual void computeAllSeismoTraces(real64 const time_n, real64 const dt, arrayView1d< real32 const > const var_np1, arrayView1d< real32 const > const var_n, arrayView2d< real32 > varAtReceivers, arrayView1d< real32 > coeffs={}, bool add=false)
Computes the traces on all receivers (see @computeSeismoTraces) up to time_n+dt.
localIndex m_lifoSize
lifo size (should be the total number of buffer to save in LIFO)
localIndex m_lifoOnDevice
Number of buffers to store on device by LIFO (if negative, opposite of percentage of remaining memory...
virtual real64 explicitStep(real64 const &time_n, real64 const &dt, integer const cycleNumber, DomainPartition &domain) override
Entry function for an explicit time integration step.
array2d< real64 > m_linearDASGeometry
Geometry parameters for a linear DAS fiber (dip, azimuth, gauge length)
SortedArray< localIndex > m_solverTargetNodesSet
A set of target nodes IDs that will be handled by the current solver.
virtual void registerDataOnMesh(Group &meshBodies) override
Register wrappers that contain data on the mesh objects.
array2d< real64 > m_sourceCoordinates
Coordinates of the sources in the mesh.
virtual void precomputeSourceAndReceiverTerm(MeshLevel &baseMesh, MeshLevel &mesh, string_array const &regionNames)=0
Locate sources and receivers positions in the mesh elements, evaluate the basis functions at each poi...
localIndex m_enableLifo
Flag to enable LIFO.
virtual real64 explicitStepForward(real64 const &time_n, real64 const &dt, integer const cycleNumber, DomainPartition &domain, integer const computeGradient)=0
Perform forward explicit step.
localIndex m_indexSeismoTrace
Cycle number for output SeismoTrace.
virtual void initializePreSubGroups() override
Called by Initialize() prior to initializing sub-Groups.
integer m_saveFields
Indicate if we want to save fields to restore them during backward.
array1d< localIndex > m_receiverElem
Array containing the elements which contain a receiver.
array1d< real32 > m_slsReferenceAngularFrequencies
Vector containing the reference frequencies for the standard-linear-solid (SLS) anelasticity model.
void reinit() override final
Re-initialize source and receivers positions in the mesh, and resize the pressureNp1_at_receivers arr...
integer m_linearDASSamples
Number of points used for strain integration for dipole DAS.
array1d< real32 > m_slsAnelasticityCoefficients
Vector containing the anelasticity coefficients for the standard-linear-solid (SLS) anelasticity mode...
localIndex m_rickerOrder
Flag that indicates the order of the Ricker to be used, order 2 by default.
virtual real64 explicitStepBackward(real64 const &time_n, real64 const &dt, integer const cycleNumber, DomainPartition &domain, integer const computeGradient)=0
Perform backward explicit step.
virtual void postInputInitialization() override
WaveSolverUtils::AttenuationType m_attenuationType
Flag to indicate which attenuation type will be modeled.
real64 m_dtSeismoTrace
Time step for seismoTrace output.
localIndex m_lifoOnHost
Number of buffers to store on host by LIFO (if negative, opposite of percentage of remaining memory)
integer m_outputSeismoTrace
Flag that indicates if we write the seismo trace in a file .txt, 0 no output, 1 otherwise.
array1d< real32 > m_linearDASVectorZ
Z component of the linear DAS direction vector.
array2d< localIndex > m_receiverNodeIds
Indices of the element nodes (in the right order) for each receiver point.
array2d< real64 > m_sourceConstants
Constant part of the source for the nodes listed in m_sourceNodeIds.
array2d< real64 > m_receiverCoordinates
Coordinates of the receivers in the mesh.
array2d< real32 > m_sourceValue
Precomputed value of the source terms.
WaveSolverUtils::DASType m_useDAS
Flag to indicate which DAS type will be modeled.
virtual void applyFreeSurfaceBC(real64 const time, DomainPartition &domain)=0
Apply free surface condition to the face defined in the geometry box of the xml.
virtual real64 solverStep(real64 const &time_n, real64 const &dt, integer const cycleNumber, DomainPartition &domain) override
entry function to perform a solver step
string_array m_sourceWaveletTableNames
Names of table functions for source wavelet (time dependency)
bool directoryExists(std::string const &directoryName)
Utility function to check if a directory exists.
array2d< localIndex > m_sourceNodeIds
Indices of the nodes (in the right order) for each source point.
localIndex m_forward
Indicate if we want to compute forward ou backward.
real32 m_timeSourceDelay
Source time delay (1 / f0 by default)
virtual void compute2dVariableAllSeismoTraces(localIndex const regionIndex, real64 const time_n, real64 const dt, arrayView2d< real32 const > const var_np1, arrayView2d< real32 const > const var_n, arrayView2d< real32 > varAtReceivers)
Computes the traces on all receivers (see @computeSeismoTraces) up to time_n+dt.
bool m_useSourceWaveletTables
Flag to indicate if source wavelet table functions are used.
array2d< real64 > m_receiverConstants
Basis function evaluated at the receiver for the nodes listed in m_receiverNodeIds.
array1d< localIndex > m_receiverRegion
Array containing the elements which contain the region which the receiver belongs.
array1d< real32 > m_linearDASVectorY
Y component of the linear DAS direction vector.
void initializeAnelasticityCoefficients(DomainPartition &domain)
Initializes the anealsticity coefficients if needed, and checks that the anealsticity values are with...
array1d< TableFunction::KernelWrapper > m_sourceWaveletTableWrappers
Wrappers of table functions for source wavelet (time dependency)
ArrayView< T, 1 > arrayView1d
Alias for 1D array view.
Definition: DataTypes.hpp:188
stdVector< string > string_array
A 1-dimensional array of geos::string types.
Definition: DataTypes.hpp:401
float real32
32-bit floating point type.
Definition: DataTypes.hpp:96
Array< T, 2, PERMUTATION > array2d
Alias for 2D array.
Definition: DataTypes.hpp:200
std::string string
String type.
Definition: DataTypes.hpp:90
double real64
64-bit floating point type.
Definition: DataTypes.hpp:98
GEOS_LOCALINDEX_TYPE localIndex
Local index type (for indexing objects within an MPI partition).
Definition: DataTypes.hpp:84
std::int32_t integer
Signed integer type.
Definition: DataTypes.hpp:81
LvArray::SortedArray< T, localIndex, LvArray::ChaiBuffer > SortedArray
A sorted array of local indices.
Definition: DataTypes.hpp:275
ArrayView< T, 2, USD > arrayView2d
Alias for 2D array view.
Definition: DataTypes.hpp:204
Array< T, 1 > array1d
Alias for 1D array.
Definition: DataTypes.hpp:184
Structure to hold scoped key names.
R1Tensor32 xMaxPML
Maximum (x,y,z) coordinates of inner PML boundaries.
R1Tensor32 xMinPML
Mininum (x,y,z) coordinates of inner PML boundaries.
R1Tensor32 waveSpeedMinXYZPML
Wave speed in the PML region, used to compute the damping profile.
R1Tensor32 thicknessMinXYZPML
Thickness of the PML region, used to compute the damping profile.
real32 reflectivityPML
Desired reflectivity of the PML region, used to compute the damping profile.