Peano
PMLElastic.py
Go to the documentation of this file.
1 
2 
3 def initial(pointwise_initial_conditions):
4  return """
5  std::fill_n(Q, (NumberOfAuxiliaryVariables + NumberOfUnknowns) * (Order + 1) * (Order + 1) * (Order + 1), 0);
6 
7  context->initUnknownsPatch(Q, x, h, 0.0, 0.0,
8  [&](
9  const {{SOLUTION_STORAGE_PRECISION}}* const x,
10  const tarch::la::Vector<DIMENSIONS,double>& center,
11  const double t,
12  const double dt,
13  {{SOLUTION_STORAGE_PRECISION}}* Q
14  ) -> void { """ + pointwise_initial_conditions + """
15  }
16  );
17 
18  // Initialisation of PML parameters
19  auto dmp_pml_width_x = pml_cell_width * h[0];
20  auto dmp_pml_width_y = pml_cell_width * h[1];
21  auto dmp_pml_width_z = pml_cell_width * h[2];
22 
23  auto dmp_pml_right_x = DomainOffset[0] + DomainSize[0] - dmp_pml_width_x;
24  auto dmp_pml_right_y = DomainOffset[1] + DomainSize[1] - dmp_pml_width_y;
25  auto dmp_pml_right_z = DomainOffset[2] + DomainSize[2] - dmp_pml_width_z;
26 
27  auto dmp_pml_left_x = DomainOffset[0] + dmp_pml_width_x;
28  auto dmp_pml_left_y = DomainOffset[1] + dmp_pml_width_y;
29  auto dmp_pml_left_z = DomainOffset[2] + dmp_pml_width_z;
30 
31  constexpr double amplitude_nominator = 6.0;
32 
33  auto dmp_amplitude_x = (pml_power + 1) * amplitude_nominator / (2 * dmp_pml_width_x) * log(1.0 / pml_rel_error);
34  auto dmp_amplitude_y = (pml_power + 1) * amplitude_nominator / (2 * dmp_pml_width_y) * log(1.0 / pml_rel_error);
35  auto dmp_amplitude_z = (pml_power + 1) * amplitude_nominator / (2 * dmp_pml_width_z) * log(1.0 / pml_rel_error);
36 
37  double offset_x = x[0] - h[0] * 0.5;
38  double offset_y = x[1] - h[1] * 0.5;
39  double offset_z = x[2] - h[2] * 0.5;
40 
41  toolbox::curvi::idx4 idx(Order + 1, Order + 1, Order + 1, NumberOfUnknowns + NumberOfAuxiliaryVariables);
42 
43  for (int k = 0; k < Order + 1; k++) {
44  double computational_z = (offset_z + h[2] * kernels::{{SOLVER_NAME}}::Quadrature<{{SOLUTION_STORAGE_PRECISION}}>::nodes[k]);
45  for (int j = 0; j < Order + 1; j++) {
46  double computational_y = (offset_y + h[1] * kernels::{{SOLVER_NAME}}::Quadrature<{{SOLUTION_STORAGE_PRECISION}}>::nodes[j]);
47  for (int i = 0; i < Order + 1; i++) {
48  double computational_x = (offset_x + h[0] * kernels::{{SOLVER_NAME}}::Quadrature<{{SOLUTION_STORAGE_PRECISION}}>::nodes[i]);
49 
50  if (_TOP != 0) { // No PML on surface
51  if (computational_x < dmp_pml_left_x) {
52  Q[idx(
53  k, j, i, Shortcuts::dmp_pml + 0
54  )] = dmp_amplitude_x * pow((dmp_pml_left_x - computational_x) / dmp_pml_width_x, pml_power);
55  }
56  }
57  if (_TOP != 1) { // No PML on surface
58  if (computational_y <= dmp_pml_left_y) {
59  Q[idx(
60  k, j, i, Shortcuts::dmp_pml + 1
61  )] = dmp_amplitude_y * pow((dmp_pml_left_y - computational_y) / dmp_pml_width_y, pml_power);
62  }
63  }
64  if (_TOP != 2) { // No PML on surface
65  if (computational_z <= dmp_pml_left_z) {
66  Q[idx(
67  k, j, i, Shortcuts::dmp_pml + 2
68  )] = dmp_amplitude_z * pow((dmp_pml_left_z - computational_z) / dmp_pml_width_z, pml_power);
69  }
70  }
71  if (computational_x >= dmp_pml_right_x) {
72  Q[idx(
73  k, j, i, Shortcuts::dmp_pml + 0
74  )] = dmp_amplitude_x * pow((computational_x - dmp_pml_right_x) / dmp_pml_width_x, pml_power);
75  }
76  if (computational_y >= dmp_pml_right_y) {
77  Q[idx(
78  k, j, i, Shortcuts::dmp_pml + 1
79  )] = dmp_amplitude_y * pow((computational_y - dmp_pml_right_y) / dmp_pml_width_y, pml_power);
80  }
81  if (computational_z >= dmp_pml_right_z) {
82  Q[idx(
83  k, j, i, Shortcuts::dmp_pml + 2
84  )] = dmp_amplitude_z * pow((computational_z - dmp_pml_right_z) / dmp_pml_width_z, pml_power);
85  }
86  }
87  }
88  }
89 """
90 
91 
92 def boundary():
93  return """
94  for (int i = 0; i < NumberOfUnknowns; i++) {
95  Qoutside[i] = Qinside[i];
96  }
97 """
98 
99 def eigenvalue():
100  return """
101  // Check for NaN in any of the velocities
102  assert(("Check for Nans in velocity", !(std::isnan(Q[Shortcuts::v + 0]) || std::isnan(Q[Shortcuts::v + 1]) || std::isnan(Q[Shortcuts::v + 2]))));
103 
104  auto cp = Q[Shortcuts::cp];
105  auto cs = Q[Shortcuts::cs];
106  auto q_x = Q[Shortcuts::metric_derivative + 0];
107  auto q_y = Q[Shortcuts::metric_derivative + 1];
108  auto q_z = Q[Shortcuts::metric_derivative + 2];
109  auto r_x = Q[Shortcuts::metric_derivative + 3];
110  auto r_y = Q[Shortcuts::metric_derivative + 4];
111  auto r_z = Q[Shortcuts::metric_derivative + 5];
112  auto s_x = Q[Shortcuts::metric_derivative + 6];
113  auto s_y = Q[Shortcuts::metric_derivative + 7];
114  auto s_z = Q[Shortcuts::metric_derivative + 8];
115 
116  double lambda[10]{1.0};
117 
118  lambda[0] = std::sqrt(q_x * q_x + q_y * q_y + q_z * q_z) * cp;
119  lambda[1] = std::sqrt(q_x * q_x + q_y * q_y + q_z * q_z) * cs;
120  lambda[2] = std::sqrt(q_x * q_x + q_y * q_y + q_z * q_z) * cs;
121 
122  lambda[3] = std::sqrt(r_x * r_x + r_y * r_y + r_z * r_z) * cp;
123  lambda[4] = std::sqrt(r_x * r_x + r_y * r_y + r_z * r_z) * cs;
124  lambda[5] = std::sqrt(r_x * r_x + r_y * r_y + r_z * r_z) * cs;
125 
126  lambda[6] = std::sqrt(s_x * s_x + s_y * s_y + s_z * s_z) * cp;
127  lambda[7] = std::sqrt(s_x * s_x + s_y * s_y + s_z * s_z) * cs;
128  lambda[8] = std::sqrt(s_x * s_x + s_y * s_y + s_z * s_z) * cs;
129  lambda[9] = 1.0;
130 
131  return *std::max_element(lambda, lambda + 10);
132 """
133 
134 def flux():
135  return """
136  auto sigma_xx = Q[Shortcuts::sigma + 0];
137  auto sigma_yy = Q[Shortcuts::sigma + 1];
138  auto sigma_zz = Q[Shortcuts::sigma + 2];
139  auto sigma_xy = Q[Shortcuts::sigma + 3];
140  auto sigma_xz = Q[Shortcuts::sigma + 4];
141  auto sigma_yz = Q[Shortcuts::sigma + 5];
142 
143  auto jacobian = Q[Shortcuts::jacobian];
144 
145  auto rho = Q[Shortcuts::rho];
146  auto rho_inv = 1.0 / rho;
147 
148  std::fill_n(F, NumberOfUnknowns, 0.0);
149 
150  toolbox::curvi::idx2 idx_pml(DIMENSIONS, 9);
151 
152  switch (normal) {
153  case 0: {
154  auto q_x = Q[Shortcuts::metric_derivative + 0];
155  auto q_y = Q[Shortcuts::metric_derivative + 1];
156  auto q_z = Q[Shortcuts::metric_derivative + 2];
157  F[Shortcuts::v + 0] = -jacobian * (q_x * sigma_xx + q_y * sigma_xy + q_z * sigma_xz);
158  F[Shortcuts::v + 1] = -jacobian * (q_x * sigma_xy + q_y * sigma_yy + q_z * sigma_yz);
159  F[Shortcuts::v + 2] = -jacobian * (q_x * sigma_xz + q_y * sigma_yz + q_z * sigma_zz);
160  F[Shortcuts::pml + idx_pml(0, Shortcuts::v + 0)] = F[Shortcuts::v + 0];
161  F[Shortcuts::pml + idx_pml(0, Shortcuts::v + 1)] = F[Shortcuts::v + 1];
162  F[Shortcuts::pml + idx_pml(0, Shortcuts::v + 2)] = F[Shortcuts::v + 2];
163  } break;
164  case 1: {
165  auto r_x = Q[Shortcuts::metric_derivative + 3];
166  auto r_y = Q[Shortcuts::metric_derivative + 4];
167  auto r_z = Q[Shortcuts::metric_derivative + 5];
168  F[Shortcuts::v + 0] = -jacobian * (r_x * sigma_xx + r_y * sigma_xy + r_z * sigma_xz);
169  F[Shortcuts::v + 1] = -jacobian * (r_x * sigma_xy + r_y * sigma_yy + r_z * sigma_yz);
170  F[Shortcuts::v + 2] = -jacobian * (r_x * sigma_xz + r_y * sigma_yz + r_z * sigma_zz);
171  F[Shortcuts::pml + idx_pml(1, Shortcuts::v + 0)] = F[Shortcuts::v + 0];
172  F[Shortcuts::pml + idx_pml(1, Shortcuts::v + 1)] = F[Shortcuts::v + 1];
173  F[Shortcuts::pml + idx_pml(1, Shortcuts::v + 2)] = F[Shortcuts::v + 2];
174  } break;
175  case 2: {
176  auto s_x = Q[Shortcuts::metric_derivative + 6];
177  auto s_y = Q[Shortcuts::metric_derivative + 7];
178  auto s_z = Q[Shortcuts::metric_derivative + 8];
179  F[Shortcuts::v + 0] = -jacobian * (s_x * sigma_xx + s_y * sigma_xy + s_z * sigma_xz);
180  F[Shortcuts::v + 1] = -jacobian * (s_x * sigma_xy + s_y * sigma_yy + s_z * sigma_yz);
181  F[Shortcuts::v + 2] = -jacobian * (s_x * sigma_xz + s_y * sigma_yz + s_z * sigma_zz);
182  F[Shortcuts::pml + idx_pml(2, Shortcuts::v + 0)] = F[Shortcuts::v + 0];
183  F[Shortcuts::pml + idx_pml(2, Shortcuts::v + 1)] = F[Shortcuts::v + 1];
184  F[Shortcuts::pml + idx_pml(2, Shortcuts::v + 2)] = F[Shortcuts::v + 2];
185  }
186  }
187 """
188 
189 def ncp():
190  return """
191  toolbox::curvi::idx2 idx_pml(DIMENSIONS, 9);
192  auto rho = Q[Shortcuts::rho];
193  auto cp = Q[Shortcuts::cp];
194  auto cs = Q[Shortcuts::cs];
195  auto jacobian = Q[Shortcuts::jacobian];
196  auto dmp_pml_x = Q[Shortcuts::dmp_pml + 0];
197  auto dmp_pml_y = Q[Shortcuts::dmp_pml + 1];
198  auto dmp_pml_z = Q[Shortcuts::dmp_pml + 2];
199  auto mu = rho * cs * cs;
200  auto lambda = rho * cp * cp - 2 * mu;
201  auto rho_inv = 1.0 / (rho * jacobian);
202 
203  std::fill_n(BTimesDeltaQ, NumberOfUnknowns, 0.0);
204 
205  switch (normal) {
206  case 0: {
207  auto u_q = deltaQ[Shortcuts::v + 0];
208  auto v_q = deltaQ[Shortcuts::v + 1];
209  auto w_q = deltaQ[Shortcuts::v + 2];
210  auto q_x = Q[Shortcuts::metric_derivative + 0];
211  auto q_y = Q[Shortcuts::metric_derivative + 1];
212  auto q_z = Q[Shortcuts::metric_derivative + 2];
213  auto lam_temp = lambda * (-q_x * u_q - q_y * v_q - q_z * w_q);
214  BTimesDeltaQ[Shortcuts::sigma + 0] = -2 * mu * q_x * u_q + lam_temp;
215  BTimesDeltaQ[Shortcuts::sigma + 1] = -2 * mu * q_y * v_q + lam_temp;
216  BTimesDeltaQ[Shortcuts::sigma + 2] = -2 * mu * q_z * w_q + lam_temp;
217  BTimesDeltaQ[Shortcuts::sigma + 3] = -mu * (q_y * u_q + q_x * v_q); // sigma_xy
218  BTimesDeltaQ[Shortcuts::sigma + 4] = -mu * (q_z * u_q + q_x * w_q); // sigma_xz
219  BTimesDeltaQ[Shortcuts::sigma + 5] = -mu * (q_z * v_q + q_y * w_q); // sigma_yz
220  BTimesDeltaQ[Shortcuts::pml + idx_pml(0, Shortcuts::sigma + 0)] = -dmp_pml_x * q_x * u_q;
221  BTimesDeltaQ[Shortcuts::pml + idx_pml(0, Shortcuts::sigma + 1)] = -dmp_pml_x * q_y * v_q;
222  BTimesDeltaQ[Shortcuts::pml + idx_pml(0, Shortcuts::sigma + 2)] = -dmp_pml_x * q_z * w_q;
223  BTimesDeltaQ[Shortcuts::pml + idx_pml(0, Shortcuts::sigma + 3)] = -dmp_pml_x * (q_y * u_q + q_x * v_q);
224  BTimesDeltaQ[Shortcuts::pml + idx_pml(0, Shortcuts::sigma + 4)] = -dmp_pml_x * (q_z * u_q + q_x * w_q);
225  BTimesDeltaQ[Shortcuts::pml + idx_pml(0, Shortcuts::sigma + 5)] = -dmp_pml_x * (q_z * v_q + q_y * w_q);
226  } break;
227  case 1: {
228  auto u_r = deltaQ[Shortcuts::v + 0];
229  auto v_r = deltaQ[Shortcuts::v + 1];
230  auto w_r = deltaQ[Shortcuts::v + 2];
231  auto r_x = Q[Shortcuts::metric_derivative + 3];
232  auto r_y = Q[Shortcuts::metric_derivative + 4];
233  auto r_z = Q[Shortcuts::metric_derivative + 5];
234  auto lam_temp = lambda * (-r_x * u_r - r_y * v_r - r_z * w_r);
235  BTimesDeltaQ[Shortcuts::sigma + 0] = -2 * mu * r_x * u_r + lam_temp;
236  BTimesDeltaQ[Shortcuts::sigma + 1] = -2 * mu * r_y * v_r + lam_temp;
237  BTimesDeltaQ[Shortcuts::sigma + 2] = -2 * mu * r_z * w_r + lam_temp;
238  BTimesDeltaQ[Shortcuts::sigma + 3] = -mu * (r_y * u_r + r_x * v_r); // sigma_xy
239  BTimesDeltaQ[Shortcuts::sigma + 4] = -mu * (r_z * u_r + r_x * w_r); // sigma_xz
240  BTimesDeltaQ[Shortcuts::sigma + 5] = -mu * (r_z * v_r + r_y * w_r); // sigma_yz
241  BTimesDeltaQ[Shortcuts::pml + idx_pml(1, Shortcuts::sigma + 0)] = -dmp_pml_y * r_x * u_r;
242  BTimesDeltaQ[Shortcuts::pml + idx_pml(1, Shortcuts::sigma + 1)] = -dmp_pml_y * r_y * v_r;
243  BTimesDeltaQ[Shortcuts::pml + idx_pml(1, Shortcuts::sigma + 2)] = -dmp_pml_y * r_z * w_r;
244  BTimesDeltaQ[Shortcuts::pml + idx_pml(1, Shortcuts::sigma + 3)] = -dmp_pml_y * (r_y * u_r + r_x * v_r);
245  BTimesDeltaQ[Shortcuts::pml + idx_pml(1, Shortcuts::sigma + 4)] = -dmp_pml_y * (r_z * u_r + r_x * w_r);
246  BTimesDeltaQ[Shortcuts::pml + idx_pml(1, Shortcuts::sigma + 5)] = -dmp_pml_y * (r_z * v_r + r_y * w_r);
247  } break;
248  case 2: {
249  auto u_s = deltaQ[Shortcuts::v + 0];
250  auto v_s = deltaQ[Shortcuts::v + 1];
251  auto w_s = deltaQ[Shortcuts::v + 2];
252  auto s_x = Q[Shortcuts::metric_derivative + 6];
253  auto s_y = Q[Shortcuts::metric_derivative + 7];
254  auto s_z = Q[Shortcuts::metric_derivative + 8];
255  auto lam_temp = lambda * (-s_x * u_s - s_y * v_s - s_z * w_s);
256  BTimesDeltaQ[Shortcuts::sigma + 0] = -2 * mu * s_x * u_s + lam_temp;
257  BTimesDeltaQ[Shortcuts::sigma + 1] = -2 * mu * s_y * v_s + lam_temp;
258  BTimesDeltaQ[Shortcuts::sigma + 2] = -2 * mu * s_z * w_s + lam_temp;
259  BTimesDeltaQ[Shortcuts::sigma + 3] = -mu * (s_y * u_s + s_x * v_s); // sigma_xy
260  BTimesDeltaQ[Shortcuts::sigma + 4] = -mu * (s_z * u_s + s_x * w_s); // sigma_xz
261  BTimesDeltaQ[Shortcuts::sigma + 5] = -mu * (s_z * v_s + s_y * w_s); // sigma_yz
262  BTimesDeltaQ[Shortcuts::pml + idx_pml(2, Shortcuts::sigma + 0)] = -dmp_pml_z * s_x * u_s;
263  BTimesDeltaQ[Shortcuts::pml + idx_pml(2, Shortcuts::sigma + 1)] = -dmp_pml_z * s_y * v_s;
264  BTimesDeltaQ[Shortcuts::pml + idx_pml(2, Shortcuts::sigma + 2)] = -dmp_pml_z * s_z * w_s;
265  BTimesDeltaQ[Shortcuts::pml + idx_pml(2, Shortcuts::sigma + 3)] = -dmp_pml_z * (s_y * u_s + s_x * v_s);
266  BTimesDeltaQ[Shortcuts::pml + idx_pml(2, Shortcuts::sigma + 4)] = -dmp_pml_z * (s_z * u_s + s_x * w_s);
267  BTimesDeltaQ[Shortcuts::pml + idx_pml(2, Shortcuts::sigma + 5)] = -dmp_pml_z * (s_z * v_s + s_y * w_s);
268  }
269  }
270 """
271 
273  return """
274  auto rho = Q[Shortcuts::rho];
275  auto cp = Q[Shortcuts::cp];
276  auto cs = Q[Shortcuts::cs];
277 
278  auto dmp_pml_x = Q[Shortcuts::dmp_pml + 0];
279  auto dmp_pml_y = Q[Shortcuts::dmp_pml + 1];
280  auto dmp_pml_z = Q[Shortcuts::dmp_pml + 2];
281 
282  auto mu = rho * cs * cs;
283  auto lambda = rho * cp * cp - 2 * mu;
284  auto rho_inv = 1.0 / rho;
285 
286  auto alpha_x = (pml_alpha_const + pml_alpha_scalar * dmp_pml_x);
287  auto alpha_y = (pml_alpha_const + pml_alpha_scalar * dmp_pml_y);
288  auto alpha_z = (pml_alpha_const + pml_alpha_scalar * dmp_pml_z);
289 
290  toolbox::curvi::idx2 idx_pml(DIMENSIONS, 9);
291 
292  const auto* Q_pml = Q + Shortcuts::pml;
293  auto* S_pml = S + Shortcuts::pml;
294 
295  S[0] = rho_inv * (Q_pml[idx_pml(0, 0)] + Q_pml[idx_pml(1, 0)] + Q_pml[idx_pml(2, 0)]);
296  S[1] = rho_inv * (Q_pml[idx_pml(0, 1)] + Q_pml[idx_pml(1, 1)] + Q_pml[idx_pml(2, 1)]);
297  S[2] = rho_inv * (Q_pml[idx_pml(0, 2)] + Q_pml[idx_pml(1, 2)] + Q_pml[idx_pml(2, 2)]);
298 
299  S[3] = (2 * mu + lambda) * Q_pml[idx_pml(0, 3)] + lambda * (Q_pml[idx_pml(0, 4)] + Q_pml[idx_pml(0, 5)])
300  + (2 * mu + lambda) * Q_pml[idx_pml(1, 3)] + lambda * (Q_pml[idx_pml(1, 4)] + Q_pml[idx_pml(1, 5)])
301  + (2 * mu + lambda) * Q_pml[idx_pml(2, 3)] + lambda * (Q_pml[idx_pml(2, 4)] + Q_pml[idx_pml(2, 5)]);
302 
303  S[4] = (2 * mu + lambda) * Q_pml[idx_pml(0, 4)] + lambda * (Q_pml[idx_pml(0, 3)] + Q_pml[idx_pml(0, 5)])
304  + (2 * mu + lambda) * Q_pml[idx_pml(1, 4)] + lambda * (Q_pml[idx_pml(1, 3)] + Q_pml[idx_pml(1, 5)])
305  + (2 * mu + lambda) * Q_pml[idx_pml(2, 4)] + lambda * (Q_pml[idx_pml(2, 3)] + Q_pml[idx_pml(2, 5)]);
306 
307  S[5] = (2 * mu + lambda) * Q_pml[idx_pml(0, 5)] + lambda * (Q_pml[idx_pml(0, 3)] + Q_pml[idx_pml(0, 4)])
308  + (2 * mu + lambda) * Q_pml[idx_pml(1, 5)] + lambda * (Q_pml[idx_pml(1, 3)] + Q_pml[idx_pml(1, 4)])
309  + (2 * mu + lambda) * Q_pml[idx_pml(2, 5)] + lambda * (Q_pml[idx_pml(2, 3)] + Q_pml[idx_pml(2, 4)]);
310 
311  S[6] = mu * (Q_pml[idx_pml(0, 6)] + Q_pml[idx_pml(1, 6)] + Q_pml[idx_pml(2, 6)]);
312  S[7] = mu * (Q_pml[idx_pml(0, 7)] + Q_pml[idx_pml(1, 7)] + Q_pml[idx_pml(2, 7)]);
313  S[8] = mu * (Q_pml[idx_pml(0, 8)] + Q_pml[idx_pml(1, 8)] + Q_pml[idx_pml(2, 8)]);
314 
315  for (int j = 0; j < 9; j++) {
316  S_pml[idx_pml(0, j)] = (dmp_pml_x + alpha_x) * Q_pml[idx_pml(0, j)];
317  S_pml[idx_pml(1, j)] = (dmp_pml_y + alpha_y) * Q_pml[idx_pml(1, j)];
318  S_pml[idx_pml(2, j)] = (dmp_pml_z + alpha_z) * Q_pml[idx_pml(2, j)];
319  }
320 """
321 
323  return """
324  auto rho = Q[Shortcuts::rho];
325  auto cp = Q[Shortcuts::cp];
326  auto cs = Q[Shortcuts::cs];
327 
328  auto jacobian = Q[Shortcuts::jacobian];
329 
330  auto dmp_pml_x = Q[Shortcuts::dmp_pml + 0];
331  auto dmp_pml_y = Q[Shortcuts::dmp_pml + 1];
332  auto dmp_pml_z = Q[Shortcuts::dmp_pml + 2];
333 
334  auto mu = rho * cs * cs;
335  auto lambda = rho * cp * cp - 2 * mu;
336  auto rho_inv = 1.0 / (rho * jacobian);
337 
338  toolbox::curvi::idx2 idx_pml(DIMENSIONS, 9);
339 
340  // Rhs uses the same formula regardless of dimension, hence no switch necessary
341 
342  rhs[Shortcuts::v + 0] = rho_inv * rhs[Shortcuts::v + 0];
343  rhs[Shortcuts::v + 1] = rho_inv * rhs[Shortcuts::v + 1];
344  rhs[Shortcuts::v + 2] = rho_inv * rhs[Shortcuts::v + 2];
345 
346  for (int j = 0; j < 3; j++) {
347  rhs[Shortcuts::pml + idx_pml(0, j)] = dmp_pml_x / jacobian * rhs[Shortcuts::pml + idx_pml(0, j)];
348  rhs[Shortcuts::pml + idx_pml(1, j)] = dmp_pml_y / jacobian * rhs[Shortcuts::pml + idx_pml(1, j)];
349  rhs[Shortcuts::pml + idx_pml(2, j)] = dmp_pml_z / jacobian * rhs[Shortcuts::pml + idx_pml(2, j)];
350  }
351 """
352 
354  return """
355  auto result = ::exahype2::RefinementCommand::Keep;
356  return result;
357 """
358 
360  return """
361  Numerics::riemannSolver<VariableShortcuts{{SOLVER_NAME}}, {{CORRECTOR_COMPUTATION_PRECISION}}, Order, NumberOfUnknowns, NumberOfAuxiliaryVariables, 1>(
362  FL, FR, QL, QR, dt, direction, isBoundaryFace, faceIndex
363  );
364 """
365 
367  return """
368 #define _CUSTOM_COORDINATES
369 #define ASAGI_NOMPI
370 #define _TOP 1
371 
372 #include "../ExaSeis_core/Curvilinear/ContextCurvilinear.h"
373 #include "../ExaSeis_core/Numerics/riemannsolverPML.h"
374 """
375 
377  return """
378 ContextCurvilinear<{{NAMESPACE | join("::")}}::VariableShortcuts{{SOLVER_NAME}},
379  {{NAMESPACE | join("::")}}::{{CLASSNAME}}::Order + 1,
380  ({{NAMESPACE | join("::")}}::{{CLASSNAME}}::NumberOfUnknowns + {{NAMESPACE | join("::")}}::{{CLASSNAME}}::NumberOfAuxiliaryVariables),
381  {{SOLUTION_STORAGE_PRECISION}}>* {{NAMESPACE | join("::")}}::{{CLASSNAME}}::context;
382 """
383 
385  return """
386 public:
387  double QuadraturePoints1d[Order+1];
388 
389 protected:
390  static ContextCurvilinear<VariableShortcuts{{SOLVER_NAME}}, Order + 1, (NumberOfAuxiliaryVariables + NumberOfUnknowns), {{SOLUTION_STORAGE_PRECISION}}>* context;
391 
392  static constexpr int pml_cell_width = 1;
393  static constexpr double pml_alpha_const = 1.5;
394  static constexpr double pml_alpha_scalar = 0.0;
395  static constexpr double pml_rel_error = 0.001;
396  static constexpr int pml_power = 1;
397 """
398 
399 def init_grid_step_implementation(scenario_string):
400  return """
401  std::copy_n(
402  kernels::{{SOLVER_NAME}}::Quadrature<{{SOLUTION_STORAGE_PRECISION}}>::nodes,
403  (Order+1),
404  QuadraturePoints1d
405  );
406 
407  std::string topography_string = \"""" + scenario_string + """.yaml";
408 
409  //setting coarsestMeshLevel and maxAdaptiveMeshLevel
410  double maxDSize = std::numeric_limits<double>::min();
411  double minDSize = std::numeric_limits<double>::max();
412  tarch::la::Vector<DIMENSIONS, double> sizes = DomainSize;
413 
414  for(int i=0; i<DIMENSIONS; i++){
415  if(sizes[i]>maxDSize){
416  maxDSize = sizes[i];
417  }
418  if(sizes[i]<minDSize){
419  minDSize = sizes[i];
420  }
421  }
422 
423  int depth = 0;
424 
425  //finding coarsest possible Mesh level
426  while(maxDSize>MaxAdmissibleCellH){
427  depth += 1;
428  maxDSize /= 3.0;
429  }
430 
431  double realCoarsestMeshSize = maxDSize;
432  double coarsestMeshLevel = depth;
433 
434  depth = 0;
435  while(minDSize>MinAdmissibleCellH){
436  depth += 1;
437  minDSize /= 3.0;
438  }
439 
440  context = new ContextCurvilinear<VariableShortcuts{{SOLVER_NAME}}, Order + 1, (NumberOfAuxiliaryVariables + NumberOfUnknowns), {{SOLUTION_STORAGE_PRECISION}}>(
441  topography_string,
442  coarsestMeshLevel,
443  realCoarsestMeshSize,
444  depth,
445  DomainOffset, DomainSize,
446  kernels::{{SOLVER_NAME}}::Quadrature<{{SOLUTION_STORAGE_PRECISION}}>::nodes,
447  kernels::{{SOLVER_NAME}}::DGMatrices<{{SOLUTION_STORAGE_PRECISION}}>::dudx
448  );
449 
450  std::cout << "PML is using " << pml_cell_width << " elements" << std::endl;
451  std::cout << "Freesurface set at " << _TOP * 2 << std::endl;
452 """
453 
455  return """
456  delete context;
457 """
def userIncludes()
Definition: PMLElastic.py:366
def boundary()
Definition: PMLElastic.py:92
def flux()
Definition: PMLElastic.py:134
def riemann_solver()
Definition: PMLElastic.py:359
def ncp()
Definition: PMLElastic.py:189
def algebraic_source()
Definition: PMLElastic.py:272
def initial(pointwise_initial_conditions)
Definition: PMLElastic.py:3
def abstractUserDefinitions()
Definition: PMLElastic.py:376
def init_grid_step_implementation(scenario_string)
Definition: PMLElastic.py:399
def abstractDeclarations()
Definition: PMLElastic.py:384
def eigenvalue()
Definition: PMLElastic.py:99
def refinement_criterion()
Definition: PMLElastic.py:353
def abstractDestructor()
Definition: PMLElastic.py:454
def multiplyMaterialParameterMatrix()
Definition: PMLElastic.py:322