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