Peano
riemannsolverAnisotropic.h
Go to the documentation of this file.
1 #pragma once
2 #define ANISOTROPIC
3 
4 #include "idx.h"
6 
7 namespace 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 
49  inline void riemannSolverBoundary(
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
float zs
Definition: ModeCalc.py:147
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 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 riemannSolver(double *FL, double *FR, const double *const QL, const double *const QR, const double dt, const int direction, bool isBoundaryFace, int faceIndex)
void riemannSolverBC0(T v, T sigma, T z, T r, T &v_hat, T &sigma_hat)
j
Definition: euler.py:95