Peano
Loading...
Searching...
No Matches
riemannsolverPML.h
Go to the documentation of this file.
1#pragma once
2
3#include "./idx.h"
6
7namespace Numerics{
8
9 //Getter routines
10 template <class Shortcuts, typename T>
11 inline void computeParameters(const T*Q, T& rho, T& cp, T& cs, T& mu, T& lam){
12 rho = Q[Shortcuts::rho];
13 cp = Q[Shortcuts::cp ];
14 cs = Q[Shortcuts::cs ];
15 mu = cs * cs * rho;
16 lam = rho* cp * cp - 2.0 * mu;
17 }
18
19 template<typename T>
20 inline void riemannSolverBoundary(int faceIndex,T r, T vn , T vm , T vl, T Tn , T Tm ,T Tl , T zp, T zs , T& vn_hat , T& vm_hat ,T& vl_hat , T& Tn_hat , T& Tm_hat ,T& Tl_hat)
21 {
22 // if (faceIndex % 2 == 0) { //left face
23 if (faceIndex < DIMENSIONS) { //left face
27 }
28
29 // if (faceIndex % 2 == 1) { //right face
30 else { //right face
34 }
35 }
36
37
38 template<class Shortcuts, typename T, int order, int numberOfVariables, int numberOfParameters , int surface = 2>
39 void riemannSolver(T* FL,T* FR,const T* const QL,const T* const QR,const double dt,const int direction, bool isBoundaryFace, int faceIndex){
40
42 constexpr int basisSize = order+1;
43
46
47 T FLn ,FLm ,FLl ,FRn ,FRm ,FRl;
48 T FLx ,FLy ,FLz ,FRx ,FRy ,FRz;
51
52 for (int i = 0; i < basisSize; i++) {
53 for (int j = 0; j < basisSize; j++) {
54 const T* Q_m = QL+idx_QLR(i,j,0);
55 const T* Q_p = QR+idx_QLR(i,j,0);
56
57 T dmp_pml_x_m = Q_m[Shortcuts::dmp_pml + 0];
58 T dmp_pml_y_m = Q_m[Shortcuts::dmp_pml + 1];
59 T dmp_pml_z_m = Q_m[Shortcuts::dmp_pml + 2];
60
61 T dmp_pml_x_p = Q_p[Shortcuts::dmp_pml + 0];
62 T dmp_pml_y_p = Q_p[Shortcuts::dmp_pml + 1];
63 T dmp_pml_z_p = Q_p[Shortcuts::dmp_pml + 2];
64
65 T* F_m = FL+idx_FLR(i,j,0);
66 T* F_p = FR+idx_FLR(i,j,0);
69
72
73 T n_m[3],m_m[3],l_m[3];
74 T n_p[3],m_p[3],l_p[3];
75 T norm_p,norm_m;
76
79
80
81 T Tx_m,Ty_m,Tz_m;
82 T Tx_p,Ty_p,Tz_p;
85
86 T vx_m,vy_m,vz_m;
87 T vx_p,vy_p,vz_p;
90
93
94 T Tn_m,Tm_m,Tl_m;
95 T Tn_p,Tm_p,Tl_p;
96
97 // rotate fields into l, m, n basis
100
101 T vn_m,vm_m,vl_m;
102 T vn_p,vm_p,vl_p;
105
106
107 // extract local s-wave and p-wave impedances
108 T zs_m=rho_m*cs_m;
109 T zs_p=rho_p*cs_p;
110
111 T zp_m=rho_m*cp_m;
112 T zp_p=rho_p*cp_p;
113
114 // impedance must be greater than zero !
115 assertion3(!(zp_p <= 0.0 || zp_m <= 0.0),"Impedance must be greater than zero !",zp_p,zs_p);
116
117 // generate interface data preserving the amplitude of the outgoing charactertritics
118 // and satisfying interface conditions exactly.
123
124 if (isBoundaryFace) {
125 // 0 absorbing 1 free surface
126 T r= faceIndex == surface ? 1 : 0;
127 // double r=1.;
129 vn_m,vm_m,vl_m,
130 Tn_m,Tm_m,Tl_m,
131 zp_m,zs_m,
135 vn_p,vm_p,vl_p,
136 Tn_p,Tm_p,Tl_p,
137 zp_p,zs_p,
140 }else {
142 Tn_p, Tn_m,
143 zp_p , zp_m,
147 Tm_p, Tm_m,
148 zs_p , zs_m,
152 Tl_p, Tl_m,
153 zs_p , zs_m,
156 }
157
158 //generate fluctuations in the local basis coordinates: n, m, l
162 FLn);
166 FLm);
170 FLl);
171
175 FRn);
179 FRm);
183 FRl);
184
185
186
187 //Consider acoustic boundary
188 FL_n = FLn/zp_m;
189 if(zs_m > 0){
190 FL_m = FLm/zs_m;
191 FL_l = FLl/zs_m;
192 }else{
193 FL_m=0;
194 FL_l=0;
195 }
196
197 FR_n = FRn/zp_p;
198 if(zs_p > 0){
199 FR_m = FRm/zs_p;
200 FR_l = FRl/zs_p;
201 }else{
202 FR_m=0;
203 FR_l=0;
204 }
205
206 // rotate back to the physical coordinates x, y, z
208 FLn,FLm,FLl,
209 FLx,FLy,FLz);
211 FRn,FRm,FRl,
212 FRx,FRy,FRz);
214 FL_n,FL_m,FL_l,
215 FL_x,FL_y,FL_z);
217 FR_n,FR_m,FR_l,
218 FR_x,FR_y,FR_z);
219
220 // construct flux fluctuation vectors obeying the eigen structure of the PDE
221 // and choose physically motivated penalties such that we can prove
222 // numerical stability.
223 F_p[Shortcuts::v + 0] = norm_p/rho_p*FRx;
224 F_m[Shortcuts::v + 0] = norm_m/rho_m*FLx;
225
226 F_p[Shortcuts::v + 1] = norm_p/rho_p*FRy;
227 F_m[Shortcuts::v + 1] = norm_m/rho_m*FLy;
228
229 F_p[Shortcuts::v + 2] = norm_p/rho_p*FRz;
230 F_m[Shortcuts::v + 2] = norm_m/rho_m*FLz;
231
232 F_m[Shortcuts::sigma + 0] = norm_m*((2*mu_m+lam_m)*n_m[0]*FL_x+lam_m*n_m[1]*FL_y+lam_m*n_m[2]*FL_z);
233 F_m[Shortcuts::sigma + 1] = norm_m*((2*mu_m+lam_m)*n_m[1]*FL_y+lam_m*n_m[0]*FL_x+lam_m*n_m[2]*FL_z);
234 F_m[Shortcuts::sigma + 2] = norm_m*((2*mu_m+lam_m)*n_m[2]*FL_z+lam_m*n_m[0]*FL_x+lam_m*n_m[1]*FL_y);
235
236 F_p[Shortcuts::sigma + 0] = -norm_p*((2*mu_p+lam_p)*n_p[0]*FR_x+lam_p*n_p[1]*FR_y+lam_p*n_p[2]*FR_z);
237 F_p[Shortcuts::sigma + 1] = -norm_p*((2*mu_p+lam_p)*n_p[1]*FR_y+lam_p*n_p[0]*FR_x+lam_p*n_p[2]*FR_z);
238 F_p[Shortcuts::sigma + 2] = -norm_p*((2*mu_p+lam_p)*n_p[2]*FR_z+lam_p*n_p[0]*FR_x+lam_p*n_p[1]*FR_y);
239
240 F_m[Shortcuts::sigma + 3] = norm_m*mu_m*(n_m[1]*FL_x + n_m[0]*FL_y);
241 F_m[Shortcuts::sigma + 4] = norm_m*mu_m*(n_m[2]*FL_x + n_m[0]*FL_z);
242 F_m[Shortcuts::sigma + 5] = norm_m*mu_m*(n_m[2]*FL_y + n_m[1]*FL_z);
243
244 F_p[Shortcuts::sigma + 3] = -norm_p*mu_p*(n_p[1]*FR_x + n_p[0]*FR_y);
245 F_p[Shortcuts::sigma + 4] = -norm_p*mu_p*(n_p[2]*FR_x + n_p[0]*FR_z);
246 F_p[Shortcuts::sigma + 5] = -norm_p*mu_p*(n_p[2]*FR_y + n_p[1]*FR_z);
247
251
252 F_p[Shortcuts::pml + idx_pml(0,0)] = n_p[0]*dmp_pml_x_p*norm_p*FRx;
253 F_m[Shortcuts::pml + idx_pml(0,0)] = n_m[0]*dmp_pml_x_m*norm_m*FLx;
254
255 F_p[Shortcuts::pml + idx_pml(0,1)] = n_p[0]*dmp_pml_x_p*norm_p*FRy;
256 F_m[Shortcuts::pml + idx_pml(0,1)] = n_m[0]*dmp_pml_x_m*norm_m*FLy;
257
258 F_p[Shortcuts::pml + idx_pml(0,2)] = n_p[0]*dmp_pml_x_p*norm_p*FRz;
259 F_m[Shortcuts::pml + idx_pml(0,2)] = n_m[0]*dmp_pml_x_m*norm_m*FLz;
260
261 F_m[Shortcuts::pml + idx_pml(0,3)] = n_m[0]*dmp_pml_x_m*norm_m*n_m[0]*FL_x;
262 F_m[Shortcuts::pml + idx_pml(0,4)] = n_m[0]*dmp_pml_x_m*norm_m*n_m[1]*FL_y;
263 F_m[Shortcuts::pml + idx_pml(0,5)] = n_m[0]*dmp_pml_x_m*norm_m*n_m[2]*FL_z;
264
265 F_p[Shortcuts::pml + idx_pml(0,3)] = -n_p[0]*dmp_pml_x_p*norm_p*n_p[0]*FR_x;
266 F_p[Shortcuts::pml + idx_pml(0,4)] = -n_p[0]*dmp_pml_x_p*norm_p*n_p[1]*FR_y;
267 F_p[Shortcuts::pml + idx_pml(0,5)] = -n_p[0]*dmp_pml_x_p*norm_p*n_p[2]*FR_z;
268
269 F_m[Shortcuts::pml + idx_pml(0,6)] = n_m[0]*dmp_pml_x_m*norm_m*(n_m[1]*FL_x + n_m[0]*FL_y);
270 F_m[Shortcuts::pml + idx_pml(0,7)] = n_m[0]*dmp_pml_x_m*norm_m*(n_m[2]*FL_x + n_m[0]*FL_z);
271 F_m[Shortcuts::pml + idx_pml(0,8)] = n_m[0]*dmp_pml_x_m*norm_m*(n_m[2]*FL_y + n_m[1]*FL_z);
272
273 F_p[Shortcuts::pml + idx_pml(0,6)] = -n_p[0]*dmp_pml_x_p*norm_p*(n_p[1]*FR_x + n_p[0]*FR_y);
274 F_p[Shortcuts::pml + idx_pml(0,7)] = -n_p[0]*dmp_pml_x_p*norm_p*(n_p[2]*FR_x + n_p[0]*FR_z);
275 F_p[Shortcuts::pml + idx_pml(0,8)] = -n_p[0]*dmp_pml_x_p*norm_p*(n_p[2]*FR_y + n_p[1]*FR_z);
276
277 // fs.pml + idx_pml(0,0)or y-direction auxiliary variables
278 F_p[Shortcuts::pml + idx_pml(1,0)] = n_p[1]*dmp_pml_y_p*norm_p*FRx;
279 F_m[Shortcuts::pml + idx_pml(1,0)] = n_m[1]*dmp_pml_y_m*norm_m*FLx;
280
281 F_p[Shortcuts::pml + idx_pml(1,1)] = n_p[1]*dmp_pml_y_p*norm_p*FRy;
282 F_m[Shortcuts::pml + idx_pml(1,1)] = n_m[1]*dmp_pml_y_m*norm_m*FLy;
283
284 F_p[Shortcuts::pml + idx_pml(1,2)] = n_p[1]*dmp_pml_y_p*norm_p*FRz;
285 F_m[Shortcuts::pml + idx_pml(1,2)] = n_m[1]*dmp_pml_y_m*norm_m*FLz;
286
287 F_m[Shortcuts::pml + idx_pml(1,3)] = n_m[1]*dmp_pml_y_m*norm_m*n_m[0]*FL_x;
288 F_m[Shortcuts::pml + idx_pml(1,4)] = n_m[1]*dmp_pml_y_m*norm_m*n_m[1]*FL_y;
289 F_m[Shortcuts::pml + idx_pml(1,5)] = n_m[1]*dmp_pml_y_m*norm_m*n_m[2]*FL_z;
290
291 F_p[Shortcuts::pml + idx_pml(1,3)] = -n_p[1]*dmp_pml_y_p*norm_p*n_p[0]*FR_x;
292 F_p[Shortcuts::pml + idx_pml(1,4)] = -n_p[1]*dmp_pml_y_p*norm_p*n_p[1]*FR_y;
293 F_p[Shortcuts::pml + idx_pml(1,5)] = -n_p[1]*dmp_pml_y_p*norm_p*n_p[2]*FR_z;
294
295 F_m[Shortcuts::pml + idx_pml(1,6)] = n_m[1]*dmp_pml_y_m*norm_m*(n_m[1]*FL_x + n_m[0]*FL_y);
296 F_m[Shortcuts::pml + idx_pml(1,7)] = n_m[1]*dmp_pml_y_m*norm_m*(n_m[2]*FL_x + n_m[0]*FL_z);
297 F_m[Shortcuts::pml + idx_pml(1,8)] = n_m[1]*dmp_pml_y_m*norm_m*(n_m[2]*FL_y + n_m[1]*FL_z);
298
299 F_p[Shortcuts::pml + idx_pml(1,6)] = -n_p[1]*dmp_pml_y_p*norm_p*(n_p[1]*FR_x + n_p[0]*FR_y);
300 F_p[Shortcuts::pml + idx_pml(1,7)] = -n_p[1]*dmp_pml_y_p*norm_p*(n_p[2]*FR_x + n_p[0]*FR_z);
301 F_p[Shortcuts::pml + idx_pml(1,8)] = -n_p[1]*dmp_pml_y_p*norm_p*(n_p[2]*FR_y + n_p[1]*FR_z);
302
303 // fs.pml + idx_pml(0,0)or z-direction auxiliary variables
304 F_p[Shortcuts::pml + idx_pml(2,0)] = n_p[2]*dmp_pml_z_p*norm_p*FRx;
305 F_m[Shortcuts::pml + idx_pml(2,0)] = n_m[2]*dmp_pml_z_m*norm_m*FLx;
306
307 F_p[Shortcuts::pml + idx_pml(2,1)] = n_p[2]*dmp_pml_z_p*norm_p*FRy;
308 F_m[Shortcuts::pml + idx_pml(2,1)] = n_m[2]*dmp_pml_z_m*norm_m*FLy;
309
310 F_p[Shortcuts::pml + idx_pml(2,2)] = n_p[2]*dmp_pml_z_p*norm_p*FRz;
311 F_m[Shortcuts::pml + idx_pml(2,2)] = n_m[2]*dmp_pml_z_m*norm_m*FLz;
312
313 F_m[Shortcuts::pml + idx_pml(2,3)] = n_m[2]*dmp_pml_z_m*norm_m*n_m[0]*FL_x;
314 F_m[Shortcuts::pml + idx_pml(2,4)] = n_m[2]*dmp_pml_z_m*norm_m*n_m[1]*FL_y;
315 F_m[Shortcuts::pml + idx_pml(2,5)] = n_m[2]*dmp_pml_z_m*norm_m*n_m[2]*FL_z;
316
317 F_p[Shortcuts::pml + idx_pml(2,3)] = -n_p[2]*dmp_pml_z_p*norm_p*n_p[0]*FR_x;
318 F_p[Shortcuts::pml + idx_pml(2,4)] = -n_p[2]*dmp_pml_z_p*norm_p*n_p[1]*FR_y;
319 F_p[Shortcuts::pml + idx_pml(2,5)] = -n_p[2]*dmp_pml_z_p*norm_p*n_p[2]*FR_z;
320
321 F_m[Shortcuts::pml + idx_pml(2,6)] = n_m[2]*dmp_pml_z_m*norm_m*(n_m[1]*FL_x + n_m[0]*FL_y);
322 F_m[Shortcuts::pml + idx_pml(2,7)] = n_m[2]*dmp_pml_z_m*norm_m*(n_m[2]*FL_x + n_m[0]*FL_z);
323 F_m[Shortcuts::pml + idx_pml(2,8)] = n_m[2]*dmp_pml_z_m*norm_m*(n_m[2]*FL_y + n_m[1]*FL_z);
324
325 F_p[Shortcuts::pml + idx_pml(2,6)] = -n_p[2]*dmp_pml_z_p*norm_p*(n_p[1]*FR_x + n_p[0]*FR_y);
326 F_p[Shortcuts::pml + idx_pml(2,7)] = -n_p[2]*dmp_pml_z_p*norm_p*(n_p[2]*FR_x + n_p[0]*FR_z);
327 F_p[Shortcuts::pml + idx_pml(2,8)] = -n_p[2]*dmp_pml_z_p*norm_p*(n_p[2]*FR_y + n_p[1]*FR_z);
328 }
329 }
330 }
331}
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 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 riemannSolverBC0(T v, T sigma, T z, T r, T &v_hat, T &sigma_hat)