-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathsem_solver.h
More file actions
192 lines (167 loc) · 6.19 KB
/
sem_solver.h
File metadata and controls
192 lines (167 loc) · 6.19 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
//************************************************************************
// proxy application v.0.0.1
//
// SEMsolver.hpp: simple 2D acoustic wave equation solver
//
// The SEMsolver class serves as a base class for the Spectral Element Method
// solver. It provides core functionality to initialize FE operators,
// advance pressure fields, apply forcing terms, and handle absorbing
// boundaries.
//************************************************************************
#ifndef SEM_SOLVER_HPP_
#define SEM_SOLVER_HPP_
#include <data_type.h>
#include <model.h>
#include <solver_base.h>
#include <cmath>
struct SEMsolverData : SolverBase::DataStruct
{
SEMsolverData(int i1, int i2, ARRAY_REAL_VIEW rhsTerm,
ARRAY_REAL_VIEW pnGlobal, VECTOR_INT_VIEW rhsElement,
ARRAY_REAL_VIEW rhsWeights)
: m_i1(i1),
m_i2(i2),
m_rhsTerm(rhsTerm),
m_pnGlobal(pnGlobal),
m_rhsElement(rhsElement),
m_rhsWeights(rhsWeights)
{
}
void print() const override
{
std::cout << "SEMsolverData: i1=" << m_i1 << ", i2=" << m_i2 << std::endl;
std::cout << "RHS Term size: " << m_rhsTerm.extent(0) << std::endl;
std::cout << "Pn Global size: " << m_pnGlobal.extent(0) << std::endl;
std::cout << "RHS Element size: " << m_rhsElement.extent(0) << std::endl;
std::cout << "RHS Weights size: " << m_rhsWeights.extent(0) << std::endl;
}
int m_i1;
int m_i2;
ARRAY_REAL_VIEW m_rhsTerm;
ARRAY_REAL_VIEW m_pnGlobal;
VECTOR_INT_VIEW m_rhsElement;
ARRAY_REAL_VIEW m_rhsWeights;
};
template <int ORDER, typename INTEGRAL_TYPE, typename MESH_TYPE>
class SEMsolver : public SolverBase
{
public:
/**
* @brief Default constructor.
*/
SEMsolver() = default;
/**
* @brief Destructor.
*/
~SEMsolver() = default;
/**
* @brief Initialize all finite element structures:
* basis functions, integrals, global arrays, and sponge boundaries.
*
* @param mesh BaseMesh structure containing the domain information.
* @param sponge_size Thickness (in elements) of absorbing sponge layers
* in each direction [x, y, z] to prevent reflections.
* @param surface_sponge Enable sponge at free surface (typically false
* for geophysics to preserve natural reflections).
*/
virtual void computeFEInit(model::ModelApi<float, int> &mesh,
const float sponge_size[3],
const bool surface_sponge,
const float taper_delta_) override final;
/**
* @brief Compute one time step of the SEM wave equation solver.
*
* Advances the pressure field using explicit time integration.
*
* @param timeSample Current time index into the RHS (source) term
* @param dt Delta time for this iteration
* @param i1 Index for previous pressure field
* @param i2 Index for current pressure field
* @param rhsTerm Right-hand side forcing term [node][time]
* @param pnGlobal Global pressure field [node][time]
* @param rhsElement List of active source elements
* @param rhsWeights Forcing weights per source node
*/
virtual void computeOneStep(const float &dt, const int &timeSample,
DataStruct &data) override final;
/**
* @brief Output pressure values at a specific time step.
*
* Typically used for recording seismograms or snapshots.
*
* @param indexTimeStep Time index to output
* @param i1 Index for pressure buffer
* @param myElementSource Element containing the receiver
* @param pnGlobal Global pressure field [node][time]
*/
virtual void outputPnValues(const int &indexTimeStep, int &i1,
int &myElementSource,
const ARRAY_REAL_VIEW &pnGlobal) override final;
/**
* @brief Initialize arrays required by the finite element solver.
*/
void initFEarrays();
/**
* @brief Allocate memory for FE-related arrays (mass, stiffness, etc.).
*/
void allocateFEarrays();
/**
* @brief Initialize sponge (absorbing layer) coefficients.
*/
void initSpongeValues();
/**
* @brief Reset global FE vectors (mass, stiffness) before accumulation.
*
* @param numNodes Total number of global nodes.
*/
void resetGlobalVectors(int numNodes);
/**
* @brief Apply external forcing to the global pressure field.
*
* @param timeSample Current time sample index
* @param i2 Current pressure index
* @param rhsTerm RHS forcing term array
* @param rhsElement Indices of source elements
* @param pnGlobal Global pressure field (modified in-place)
* @param rhsWeights Forcing weights per node
*/
void applyRHSTerm(int timeSample, float dt, int i2,
const ARRAY_REAL_VIEW &rhsTerm,
const VECTOR_INT_VIEW &rhsElement,
const ARRAY_REAL_VIEW &pnGlobal,
const ARRAY_REAL_VIEW &rhsWeights);
/**
* @brief Assemble local element contributions to global FE vectors.
*
* @param i2 Current pressure field index
* @param pnGlobal Global pressure field
*/
void computeElementContributions(int i2, const ARRAY_REAL_VIEW &pnGlobal);
/**
* @brief Update the global pressure field at interior nodes.
*
* Applies the time integration scheme.
*
* @param i1 Previous time step index
* @param i2 Current time step index
* @param pnGlobal Pressure field array (updated in-place)
*/
void updatePressureField(float dt, int i1, int i2,
const ARRAY_REAL_VIEW &pnGlobal);
private:
MESH_TYPE m_mesh;
static constexpr int nPointsElement = (ORDER + 1) * (ORDER + 1) * (ORDER + 1);
float sponge_size_[3];
bool surface_sponge_;
float taper_delta_; // attenuation parameter
// Basis functions and integral objects
INTEGRAL_TYPE myQkIntegrals;
typename INTEGRAL_TYPE::PrecomputedData m_precomputedIntegralData;
// Sponge tapering
VECTOR_REAL_VIEW spongeTaperCoeff;
// Global FE vectors
VECTOR_REAL_VIEW massMatrixGlobal;
VECTOR_REAL_VIEW yGlobal;
void computeFEInit(MESH_TYPE const &mesh);
};
#endif // SEM_SOLVER_HPP_