Peano
Loading...
Searching...
No Matches
riemannsolverAnisotropic.h
Go to the documentation of this file.
1#pragma once
2#define ANISOTROPIC
3
4#include "idx.h"
6
7namespace Numerics {
8 // Getter routines
9
10 template <class Shortcuts>
11 inline void getStiffnessTensor(const double*Q, double& c11,double& c22,double& c33,double& c44,double& c55,double& c66,double& c12,double& c13,double& c23){
12 c11 = Q[Shortcuts::c + 0];
13 c22 = Q[Shortcuts::c + 1];
14 c33 = Q[Shortcuts::c + 2];
15 c44 = Q[Shortcuts::c + 3];
16 c55 = Q[Shortcuts::c + 4];
17 c66 = Q[Shortcuts::c + 5];
18
19 c12 = Q[Shortcuts::c + 6];
20 c13 = Q[Shortcuts::c + 7];
21 c23 = Q[Shortcuts::c + 8];
22 }
23
24 template <class Shortcuts>
25 inline void computeParameters(const double* Q, double& rho, double& cp, double cs[], int direction) {
26 rho = Q[Shortcuts::rho];
27
28 cp = std::sqrt(Q[Shortcuts::c + direction] / rho);
29
30 switch (direction) {
31 case 0:
32 cs[0] = std::sqrt(Q[Shortcuts::c + 3] / rho);
33 cs[1] = std::sqrt(Q[Shortcuts::c + 4] / rho);
34 break;
35 case 1:
36 cs[0] = std::sqrt(Q[Shortcuts::c + 5] / rho);
37 cs[1] = std::sqrt(Q[Shortcuts::c + 3] / rho);
38 break;
39 case 2:
40 cs[0] = std::sqrt(Q[Shortcuts::c + 4] / rho);
41 cs[1] = std::sqrt(Q[Shortcuts::c + 5] / rho);
42 break;
43 default:
44 std::cout << "Direction : " << direction << " not defined" << std::endl;
45 std::exit(1);
46 }
47 }
48
50 int faceIndex,
51 double r,
52 double vn,
53 double vm,
54 double vl,
55 double Tn,
56 double Tm,
57 double Tl,
58 double zp,
59 double zs[2],
60 double& vn_hat,
61 double& vm_hat,
62 double& vl_hat,
63 double& Tn_hat,
64 double& Tm_hat,
65 double& Tl_hat
66 ) {
67 // if (faceIndex % 2 == 0) { //left face
68 if (faceIndex < DIMENSIONS) { //left face
69 riemannSolverBC0(vn, Tn, zp, r, vn_hat, Tn_hat);
70 riemannSolverBC0(vm, Tm, zs[0], r, vm_hat, Tm_hat);
71 riemannSolverBC0(vl, Tl, zs[1], r, vl_hat, Tl_hat);
72 }
73
74 // if (faceIndex % 2 == 1) { //right face
75 else { //right face
76 riemannSolverBCn(vn, Tn, zp, r, vn_hat, Tn_hat);
77 riemannSolverBCn(vm, Tm, zs[0], r, vm_hat, Tm_hat);
78 riemannSolverBCn(vl, Tl, zs[1], r, vl_hat, Tl_hat);
79 }
80 }
81
82 template <class Shortcuts, int order, int numberOfVariables, int numberOfParameters>
84 double* FL,
85 double* FR,
86 const double* const QL,
87 const double* const QR,
88 const double dt,
89 const int direction,
90 bool isBoundaryFace,
91 int faceIndex
92 ) {
93
94 constexpr int numberOfData = numberOfVariables + numberOfParameters;
95 constexpr int basisSize = order + 1;
96
97 kernels::idx3 idx_QLR(basisSize, basisSize, numberOfData);
98 kernels::idx3 idx_FLR(basisSize, basisSize, numberOfVariables);
99
100 double FLn, FLm, FLl, FRn, FRm, FRl;
101 double FLx, FLy, FLz, FRx, FRy, FRz;
102 double FL_n, FL_m, FL_l, FR_n, FR_m, FR_l;
103 double FL_x, FL_y, FL_z, FR_x, FR_y, FR_z;
104
105 for (int i = 0; i < basisSize; i++) {
106 for (int j = 0; j < basisSize; j++) {
107
108 const double* Q_p = QR + idx_QLR(i, j, 0);
109 const double* Q_m = QL + idx_QLR(i, j, 0);
110
111 double* F_m = FL + idx_FLR(i, j, 0);
112 double* F_p = FR + idx_FLR(i, j, 0);
113 double rho_m, cp_m, cs_m[2], c11_m, c22_m, c33_m, c44_m, c55_m, c66_m, c12_m, c13_m, c23_m;
114 double rho_p, cp_p, cs_p[2], c11_p, c22_p, c33_p, c44_p, c55_p, c66_p, c12_p, c13_p, c23_p;
115
116 Numerics::getStiffnessTensor<Shortcuts>(Q_m, c11_m, c22_m, c33_m, c44_m, c55_m, c66_m, c12_m, c13_m, c23_m);
117 Numerics::getStiffnessTensor<Shortcuts>(Q_p, c11_p, c22_p, c33_p, c44_p, c55_p, c66_p, c12_p, c13_p, c23_p);
118
119 computeParameters<Shortcuts>(Q_m, rho_m, cp_m, cs_m, direction);
120 computeParameters<Shortcuts>(Q_p, rho_p, cp_p, cs_p, direction);
121
122 double n_m[3], m_m[3], l_m[3];
123 double n_p[3], m_p[3], l_p[3];
124 double norm_p, norm_m;
125
126 getNormals<Shortcuts>(Q_m, direction, norm_m, n_m);
127 getNormals<Shortcuts>(Q_p, direction, norm_p, n_p);
128
129 double Tx_m, Ty_m, Tz_m;
130 double Tx_p, Ty_p, Tz_p;
131 computeTractions<Shortcuts>(Q_p, n_p, Tx_p, Ty_p, Tz_p);
132 computeTractions<Shortcuts>(Q_m, n_m, Tx_m, Ty_m, Tz_m);
133
134 double vx_m, vy_m, vz_m;
135 double vx_p, vy_p, vz_p;
136 getVelocities<Shortcuts>(Q_p, vx_p, vy_p, vz_p);
137 getVelocities<Shortcuts>(Q_m, vx_m, vy_m, vz_m);
138
139 createLocalBasis(n_p, m_p, l_p);
140 createLocalBasis(n_m, m_m, l_m);
141
142 double Tn_m, Tm_m, Tl_m;
143 double Tn_p, Tm_p, Tl_p;
144
145 // rotate fields into l, m, n basis
146 rotateIntoOrthogonalBasis(n_m, m_m, l_m, Tx_m, Ty_m, Tz_m, Tn_m, Tm_m, Tl_m);
147 rotateIntoOrthogonalBasis(n_p, m_p, l_p, Tx_p, Ty_p, Tz_p, Tn_p, Tm_p, Tl_p);
148
149 double vn_m, vm_m, vl_m;
150 double vn_p, vm_p, vl_p;
151 rotateIntoOrthogonalBasis(n_m, m_m, l_m, vx_m, vy_m, vz_m, vn_m, vm_m, vl_m);
152 rotateIntoOrthogonalBasis(n_p, m_p, l_p, vx_p, vy_p, vz_p, vn_p, vm_p, vl_p);
153
154 // extract local s-wave and p-wave impedances
155 double zs_m[2];
156 double zs_p[2];
157
158 zs_m[0] = rho_m * cs_m[0];
159 zs_m[1] = rho_m * cs_m[1];
160
161 zs_p[0] = rho_m * cs_p[0];
162 zs_p[1] = rho_m * cs_p[1];
163
164 double zp_m = rho_m * cp_m;
165 double zp_p = rho_p * cp_p;
166
167 // impedance must be greater than zero !
168 assertion3(!(zp_p <= 0.0 || zp_m <= 0.0), "Impedance must be greater than zero !", zp_p, zs_p);
169
170 // generate interface data preserving the amplitude of the outgoing charactertritics
171 // and satisfying interface conditions exactly.
172 double vn_hat_p, vm_hat_p, vl_hat_p;
173 double Tn_hat_p, Tm_hat_p, Tl_hat_p;
174 double vn_hat_m, vm_hat_m, vl_hat_m;
175 double Tn_hat_m, Tm_hat_m, Tl_hat_m;
176
177 if (isBoundaryFace) {
178 // 0 absorbing 1 free surface
179 double r = faceIndex == 2 ? 1 : 0;
180 // double r=1.;
182 faceIndex,
183 r,
184 vn_m,
185 vm_m,
186 vl_m,
187 Tn_m,
188 Tm_m,
189 Tl_m,
190 zp_m,
191 zs_m,
192 vn_hat_m,
193 vm_hat_m,
194 vl_hat_m,
195 Tn_hat_m,
196 Tm_hat_m,
197 Tl_hat_m
198 );
200 faceIndex,
201 r,
202 vn_p,
203 vm_p,
204 vl_p,
205 Tn_p,
206 Tm_p,
207 Tl_p,
208 zp_p,
209 zs_p,
210 vn_hat_p,
211 vm_hat_p,
212 vl_hat_p,
213 Tn_hat_p,
214 Tm_hat_p,
215 Tl_hat_p
216 );
217 } else {
218 riemannSolverNodal(vn_p, vn_m, Tn_p, Tn_m, zp_p, zp_m, vn_hat_p, vn_hat_m, Tn_hat_p, Tn_hat_m);
219 riemannSolverNodal(vm_p, vm_m, Tm_p, Tm_m, zs_p[0], zs_m[0], vm_hat_p, vm_hat_m, Tm_hat_p, Tm_hat_m);
220 riemannSolverNodal(vl_p, vl_m, Tl_p, Tl_m, zs_p[1], zs_m[1], vl_hat_p, vl_hat_m, Tl_hat_p, Tl_hat_m);
221 }
222
223 // generate fluctuations in the local basis coordinates: n, m, l
224 computeFluctuationsLeft(zp_m, Tn_m, Tn_hat_m, vn_m, vn_hat_m, FLn);
225 computeFluctuationsLeft(zs_m[0], Tm_m, Tm_hat_m, vm_m, vm_hat_m, FLm);
226 computeFluctuationsLeft(zs_m[1], Tl_m, Tl_hat_m, vl_m, vl_hat_m, FLl);
227
228 computeFluctuationsRight(zp_p, Tn_p, Tn_hat_p, vn_p, vn_hat_p, FRn);
229 computeFluctuationsRight(zs_p[0], Tm_p, Tm_hat_p, vm_p, vm_hat_p, FRm);
230 computeFluctuationsRight(zs_p[1], Tl_p, Tl_hat_p, vl_p, vl_hat_p, FRl);
231
232 // Consider acoustic boundary
233 FL_n = FLn / zp_m;
234 if (zs_m[0] > 0) {
235 FL_m = FLm / zs_m[0];
236 } else {
237 FL_m = 0;
238 }
239 if (zs_m[1] > 0) {
240 FL_l = FLl / zs_m[1];
241 } else {
242 FL_l = 0;
243 }
244
245 FR_n = FRn / zp_p;
246 if (zs_p[0] > 0) {
247 FR_m = FRm / zs_p[0];
248 } else {
249 FR_m = 0;
250 }
251
252 if (zs_p[1] > 0) {
253 FR_l = FRl / zs_p[1];
254 } else {
255 FR_l = 0;
256 }
257
258 // rotate back to the physical coordinates x, y, z
259 rotateIntoPhysicalBasis(n_m, m_m, l_m, FLn, FLm, FLl, FLx, FLy, FLz);
260 rotateIntoPhysicalBasis(n_p, m_p, l_p, FRn, FRm, FRl, FRx, FRy, FRz);
261 rotateIntoPhysicalBasis(n_m, m_m, l_m, FL_n, FL_m, FL_l, FL_x, FL_y, FL_z);
262 rotateIntoPhysicalBasis(n_p, m_p, l_p, FR_n, FR_m, FR_l, FR_x, FR_y, FR_z);
263
264 // construct flux fluctuation vectors obeying the eigen structure of the PDE
265 // and choose physically motivated penalties such that we can prove
266 // numerical stability.
267 F_p[Shortcuts::v + 0] = norm_p / rho_p * FRx;
268 F_m[Shortcuts::v + 0] = norm_m / rho_m * FLx;
269
270 F_p[Shortcuts::v + 1] = norm_p / rho_p * FRy;
271 F_m[Shortcuts::v + 1] = norm_m / rho_m * FLy;
272
273 F_p[Shortcuts::v + 2] = norm_p / rho_p * FRz;
274 F_m[Shortcuts::v + 2] = norm_m / rho_m * FLz;
275
276 F_m[Shortcuts::sigma + 0] = norm_m * (c11_m * n_m[0] * FL_x + c12_m * n_m[1] * FL_y + c13_m * n_m[2] * FL_z);
277 F_m[Shortcuts::sigma + 1] = norm_m * (c12_m * n_m[0] * FL_x + c22_m * n_m[1] * FL_y + c23_m * n_m[2] * FL_z);
278 F_m[Shortcuts::sigma + 2] = norm_m * (c13_m * n_m[0] * FL_x + c23_m * n_m[1] * FL_y + c33_m * n_m[2] * FL_z);
279
280 F_p[Shortcuts::sigma + 0] = -norm_p * (c11_p * n_p[0] * FR_x + c12_p * n_p[1] * FR_y + c13_p * n_p[2] * FR_z);
281 F_p[Shortcuts::sigma + 1] = -norm_p * (c12_p * n_p[0] * FR_x + c22_p * n_p[1] * FR_y + c23_p * n_p[2] * FR_z);
282 F_p[Shortcuts::sigma + 2] = -norm_p * (c13_p * n_p[0] * FR_x + c23_p * n_p[1] * FR_y + c33_p * n_p[2] * FR_z);
283
284 F_m[Shortcuts::sigma + 3] = norm_m * c44_m * (n_m[1] * FL_x + n_m[0] * FL_y);
285 F_m[Shortcuts::sigma + 4] = norm_m * c55_m * (n_m[2] * FL_x + n_m[0] * FL_z);
286 F_m[Shortcuts::sigma + 5] = norm_m * c66_m * (n_m[2] * FL_y + n_m[1] * FL_z);
287
288 F_p[Shortcuts::sigma + 3] = -norm_p * c44_p * (n_p[1] * FR_x + n_p[0] * FR_y);
289 F_p[Shortcuts::sigma + 4] = -norm_p * c55_p * (n_p[2] * FR_x + n_p[0] * FR_z);
290 F_p[Shortcuts::sigma + 5] = -norm_p * c66_p * (n_p[2] * FR_y + n_p[1] * FR_z);
291 }
292 }
293 }
294} // namespace Numerics
void computeFluctuationsLeft(T z, T myT, T T_hat, T v, T v_hat, T &F)
void riemannSolverBoundary(int faceIndex, double r, double vn, double vm, double vl, double Tn, double Tm, double Tl, double zp, double zs[2], double &vn_hat, double &vm_hat, double &vl_hat, double &Tn_hat, double &Tm_hat, double &Tl_hat)
void rotateIntoOrthogonalBasis(T *n, T *m, T *l, T Tx, T Ty, T Tz, T &Tn, T &Tm, T &Tl)
void riemannSolverNodal(T v_p, T v_m, T sigma_p, T sigma_m, T z_p, T z_m, T &v_hat_p, T &v_hat_m, T &sigma_hat_p, T &sigma_hat_m)
void riemannSolverBCn(T v, T sigma, T z, T r, T &v_hat, T &sigma_hat)
void createLocalBasis(T *n, T *m, T *l)
void computeParameters(const double *Q, double &rho, double &cp, double cs[], int direction)
void getVelocities(const T *Q, T &vx, T &vy, T &vz)
void getStiffnessTensor(const double *Q, double &c11, double &c22, double &c33, double &c44, double &c55, double &c66, double &c12, double &c13, double &c23)
void computeFluctuationsRight(T z, T myT, T T_hat, T v, T v_hat, T &F)
void rotateIntoPhysicalBasis(T *n, T *m, T *l, T Fn, T Fm, T Fl, T &Fx, T &Fy, T &Fz)
void computeTractions(const T *Q, const T *n, T &Tx, T &Ty, T &Tz)
void riemannSolverBC0(T v, T sigma, T z, T r, T &v_hat, T &sigma_hat)
void getNormals(const T *Q, int direction, T &norm, T *n)