Peano
riemannsolverIsotropic.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include "idx.h"
5 
6 namespace 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>
19  inline void riemannSolverBoundary(
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
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 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