Peano
Loading...
Searching...
No Matches
riemannsolverIsotropic.h
Go to the documentation of this file.
1#pragma once
2
3#include "idx.h"
5
6namespace Numerics {
7
8 // Getter routines
9 template <class Shortcuts, typename T>
10 inline void computeParameters(const T* Q, T& rho, T& cp, T& cs, T& mu, T& lam) {
11 rho = Q[Shortcuts::rho];
12 cp = Q[Shortcuts::cp];
13 cs = Q[Shortcuts::cs];
14 mu = cs * cs * rho;
15 lam = rho * cp * cp - 2.0 * mu;
16 }
17
18 template<typename T>
20 int faceIndex,
21 T r,
22 T vn,
23 T vm,
24 T vl,
25 T Tn,
26 T Tm,
27 T Tl,
28 T zp,
29 T zs,
30 T& vn_hat,
31 T& vm_hat,
32 T& vl_hat,
33 T& Tn_hat,
34 T& Tm_hat,
35 T& Tl_hat
36 ) {
37 // if (faceIndex % 2 == 0) { //left face
38 if (faceIndex < DIMENSIONS) { //left face
39 riemannSolverBC0(vn, Tn, zp, r, vn_hat, Tn_hat);
40 riemannSolverBC0(vm, Tm, zs, r, vm_hat, Tm_hat);
41 riemannSolverBC0(vl, Tl, zs, r, vl_hat, Tl_hat);
42 }
43
44 // if (faceIndex % 2 == 1) { //right face
45 else { //right face
46 riemannSolverBCn(vn, Tn, zp, r, vn_hat, Tn_hat);
47 riemannSolverBCn(vm, Tm, zs, r, vm_hat, Tm_hat);
48 riemannSolverBCn(vl, Tl, zs, r, vl_hat, Tl_hat);
49 }
50 }
51
52 template <class Shortcuts, typename T, int basisSize, int numberOfVariables, int numberOfData, int surface = 2>
54 T* FL,
55 T* FR,
56 const T* const QL,
57 const T* const QR,
58 const double dt,
59 const int direction,
60 bool isBoundaryFace,
61 int faceIndex
62 ) {
63
64 kernels::idx3 idx_QLR(basisSize, basisSize, numberOfData);
65 kernels::idx3 idx_FLR(basisSize, basisSize, numberOfVariables);
66
67 T FLn, FLm, FLl, FRn, FRm, FRl;
68 T FLx, FLy, FLz, FRx, FRy, FRz;
69 T FL_n, FL_m, FL_l, FR_n, FR_m, FR_l;
70 T FL_x, FL_y, FL_z, FR_x, FR_y, FR_z;
71
72 for (int i = 0; i < basisSize; i++) {
73#pragma simd
74 for (int j = 0; j < basisSize; j++) {
75
76 const T* Q_p = QR + idx_QLR(i, j, 0);
77 const T* Q_m = QL + idx_QLR(i, j, 0);
78
79 T* F_m = FL + idx_FLR(i, j, 0);
80 T* F_p = FR + idx_FLR(i, j, 0);
81 T rho_m, cp_m, cs_m, mu_m, lam_m;
82 T rho_p, cp_p, cs_p, mu_p, lam_p;
83
84 computeParameters<Shortcuts>(Q_m, rho_m, cp_m, cs_m, mu_m, lam_m);
85 computeParameters<Shortcuts>(Q_p, rho_p, cp_p, cs_p, mu_p, lam_p);
86
87 T n_m[3], m_m[3], l_m[3];
88 T n_p[3], m_p[3], l_p[3];
89 T norm_p, norm_m;
90
91 getNormals<Shortcuts>(Q_m, direction, norm_m, n_m);
92 getNormals<Shortcuts>(Q_p, direction, norm_p, n_p);
93
94 T Tx_m, Ty_m, Tz_m;
95 T Tx_p, Ty_p, Tz_p;
96 computeTractions<Shortcuts>(Q_p, n_p, Tx_p, Ty_p, Tz_p);
97 computeTractions<Shortcuts>(Q_m, n_m, Tx_m, Ty_m, Tz_m);
98
99 T vx_m, vy_m, vz_m;
100 T vx_p, vy_p, vz_p;
101 getVelocities<Shortcuts>(Q_p, vx_p, vy_p, vz_p);
102 getVelocities<Shortcuts>(Q_m, vx_m, vy_m, vz_m);
103
104 createLocalBasis(n_p, m_p, l_p);
105 createLocalBasis(n_m, m_m, l_m);
106
107 T Tn_m, Tm_m, Tl_m;
108 T Tn_p, Tm_p, Tl_p;
109
110 // rotate fields into l, m, n basis
111 rotateIntoOrthogonalBasis(n_m, m_m, l_m, Tx_m, Ty_m, Tz_m, Tn_m, Tm_m, Tl_m);
112 rotateIntoOrthogonalBasis(n_p, m_p, l_p, Tx_p, Ty_p, Tz_p, Tn_p, Tm_p, Tl_p);
113
114 T vn_m, vm_m, vl_m;
115 T vn_p, vm_p, vl_p;
116 rotateIntoOrthogonalBasis(n_m, m_m, l_m, vx_m, vy_m, vz_m, vn_m, vm_m, vl_m);
117 rotateIntoOrthogonalBasis(n_p, m_p, l_p, vx_p, vy_p, vz_p, vn_p, vm_p, vl_p);
118
119 // extract local s-wave and p-wave impedances
120 T zs_m = rho_m * cs_m;
121 T zs_p = rho_p * cs_p;
122
123 T zp_m = rho_m * cp_m;
124 T zp_p = rho_p * cp_p;
125
126 // impedance must be greater than zero !
127 assertion3(!(zp_p <= 0.0 || zp_m <= 0.0), "Impedance must be greater than zero !", zp_p, zp_m);
128
129 // generate interface data preserving the amplitude of the outgoing charactertritics
130 // and satisfying interface conditions exactly.
131 T vn_hat_p, vm_hat_p, vl_hat_p;
132 T Tn_hat_p, Tm_hat_p, Tl_hat_p;
133 T vn_hat_m, vm_hat_m, vl_hat_m;
134 T Tn_hat_m, Tm_hat_m, Tl_hat_m;
135
136 if (isBoundaryFace) {
137 // 0 absorbing 1 free surface
138 T r = faceIndex == surface ? 1 : 0;
139 // double r=1.;
141 faceIndex,
142 r,
143 vn_m,
144 vm_m,
145 vl_m,
146 Tn_m,
147 Tm_m,
148 Tl_m,
149 zp_m,
150 zs_m,
151 vn_hat_m,
152 vm_hat_m,
153 vl_hat_m,
154 Tn_hat_m,
155 Tm_hat_m,
156 Tl_hat_m
157 );
159 faceIndex,
160 r,
161 vn_p,
162 vm_p,
163 vl_p,
164 Tn_p,
165 Tm_p,
166 Tl_p,
167 zp_p,
168 zs_p,
169 vn_hat_p,
170 vm_hat_p,
171 vl_hat_p,
172 Tn_hat_p,
173 Tm_hat_p,
174 Tl_hat_p
175 );
176 } else {
177 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);
178 riemannSolverNodal(vm_p, vm_m, Tm_p, Tm_m, zs_p, zs_m, vm_hat_p, vm_hat_m, Tm_hat_p, Tm_hat_m);
179 riemannSolverNodal(vl_p, vl_m, Tl_p, Tl_m, zs_p, zs_m, vl_hat_p, vl_hat_m, Tl_hat_p, Tl_hat_m);
180 }
181
182 // generate fluctuations in the local basis coordinates: n, m, l
183 computeFluctuationsLeft(zp_m, Tn_m, Tn_hat_m, vn_m, vn_hat_m, FLn);
184 computeFluctuationsLeft(zs_m, Tm_m, Tm_hat_m, vm_m, vm_hat_m, FLm);
185 computeFluctuationsLeft(zs_m, Tl_m, Tl_hat_m, vl_m, vl_hat_m, FLl);
186
187 computeFluctuationsRight(zp_p, Tn_p, Tn_hat_p, vn_p, vn_hat_p, FRn);
188 computeFluctuationsRight(zs_p, Tm_p, Tm_hat_p, vm_p, vm_hat_p, FRm);
189 computeFluctuationsRight(zs_p, Tl_p, Tl_hat_p, vl_p, vl_hat_p, FRl);
190
191 // Consider acoustic boundary
192 FL_n = FLn / zp_m;
193 if (zs_m > 0) {
194 FL_m = FLm / zs_m;
195 FL_l = FLl / zs_m;
196 } else {
197 FL_m = 0;
198 FL_l = 0;
199 }
200
201 FR_n = FRn / zp_p;
202 if (zs_p > 0) {
203 FR_m = FRm / zs_p;
204 FR_l = FRl / zs_p;
205 } else {
206 FR_m = 0;
207 FR_l = 0;
208 }
209
210 // rotate back to the physical coordinates x, y, z
211 rotateIntoPhysicalBasis(n_m, m_m, l_m, FLn, FLm, FLl, FLx, FLy, FLz);
212 rotateIntoPhysicalBasis(n_p, m_p, l_p, FRn, FRm, FRl, FRx, FRy, FRz);
213 rotateIntoPhysicalBasis(n_m, m_m, l_m, FL_n, FL_m, FL_l, FL_x, FL_y, FL_z);
214 rotateIntoPhysicalBasis(n_p, m_p, l_p, FR_n, FR_m, FR_l, FR_x, FR_y, FR_z);
215
216 // construct flux fluctuation vectors obeying the eigen structure of the PDE
217 // and choose physically motivated penalties such that we can prove
218 // numerical stability.
219 F_p[Shortcuts::v + 0] = norm_p / rho_p * FRx;
220 F_m[Shortcuts::v + 0] = norm_m / rho_m * FLx;
221
222 F_p[Shortcuts::v + 1] = norm_p / rho_p * FRy;
223 F_m[Shortcuts::v + 1] = norm_m / rho_m * FLy;
224
225 F_p[Shortcuts::v + 2] = norm_p / rho_p * FRz;
226 F_m[Shortcuts::v + 2] = norm_m / rho_m * FLz;
227
228 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);
229 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);
230 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);
231
232 F_p[Shortcuts::sigma + 0] = -norm_p
233 * ((2 * mu_p + lam_p) * n_p[0] * FR_x + lam_p * n_p[1] * FR_y + lam_p * n_p[2] * FR_z);
234 F_p[Shortcuts::sigma + 1] = -norm_p
235 * ((2 * mu_p + lam_p) * n_p[1] * FR_y + lam_p * n_p[0] * FR_x + lam_p * n_p[2] * FR_z);
236 F_p[Shortcuts::sigma + 2] = -norm_p
237 * ((2 * mu_p + lam_p) * n_p[2] * FR_z + lam_p * n_p[0] * FR_x + lam_p * n_p[1] * FR_y);
238
239 F_m[Shortcuts::sigma + 3] = norm_m * mu_m * (n_m[1] * FL_x + n_m[0] * FL_y);
240 F_m[Shortcuts::sigma + 4] = norm_m * mu_m * (n_m[2] * FL_x + n_m[0] * FL_z);
241 F_m[Shortcuts::sigma + 5] = norm_m * mu_m * (n_m[2] * FL_y + n_m[1] * FL_z);
242
243 F_p[Shortcuts::sigma + 3] = -norm_p * mu_p * (n_p[1] * FR_x + n_p[0] * FR_y);
244 F_p[Shortcuts::sigma + 4] = -norm_p * mu_p * (n_p[2] * FR_x + n_p[0] * FR_z);
245 F_p[Shortcuts::sigma + 5] = -norm_p * mu_p * (n_p[2] * FR_y + n_p[1] * FR_z);
246 }
247 }
248 }
249
250} // 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 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)