Peano
CurvilinearElastic.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  context->initUnknownsPatch(Q, x, h, 0.0, 0.0,
7  [&](
8  const {{SOLUTION_STORAGE_PRECISION}}* const x,
9  const tarch::la::Vector<DIMENSIONS,double>& center,
10  const double t,
11  const double dt,
12  {{SOLUTION_STORAGE_PRECISION}}* Q
13  ) -> void { """ + pointwise_initial_conditions + """
14  }
15  );
16 """
17 
18 
19 def boundary():
20  return """
21  std::copy_n(Qinside, NumberOfUnknowns + NumberOfAuxiliaryVariables, Qoutside);
22 """
23 
24 def eigenvalue():
25  return """
26  auto cp = Q[Shortcuts::cp];
27  auto cs = Q[Shortcuts::cs];
28  auto q_x = Q[Shortcuts::metric_derivative + 0];
29  auto q_y = Q[Shortcuts::metric_derivative + 1];
30  auto q_z = Q[Shortcuts::metric_derivative + 2];
31  auto r_x = Q[Shortcuts::metric_derivative + 3];
32  auto r_y = Q[Shortcuts::metric_derivative + 4];
33  auto r_z = Q[Shortcuts::metric_derivative + 5];
34  auto s_x = Q[Shortcuts::metric_derivative + 6];
35  auto s_y = Q[Shortcuts::metric_derivative + 7];
36  auto s_z = Q[Shortcuts::metric_derivative + 8];
37 
38  double lambda[9] = {0.};
39 
40  lambda[0] = std::sqrt(q_x * q_x + q_y * q_y + q_z * q_z) * cp;
41  lambda[1] = std::sqrt(q_x * q_x + q_y * q_y + q_z * q_z) * cs;
42  lambda[2] = std::sqrt(q_x * q_x + q_y * q_y + q_z * q_z) * cs;
43 
44  lambda[3] = std::sqrt(r_x * r_x + r_y * r_y + r_z * r_z) * cp;
45  lambda[4] = std::sqrt(r_x * r_x + r_y * r_y + r_z * r_z) * cs;
46  lambda[5] = std::sqrt(r_x * r_x + r_y * r_y + r_z * r_z) * cs;
47 
48  lambda[6] = std::sqrt(s_x * s_x + s_y * s_y + s_z * s_z) * cp;
49  lambda[7] = std::sqrt(s_x * s_x + s_y * s_y + s_z * s_z) * cs;
50  lambda[8] = std::sqrt(s_x * s_x + s_y * s_y + s_z * s_z) * cs;
51 
52  return *std::max_element(lambda, lambda + 9);
53 """
54 
55 def flux():
56  return """
57  auto sigma_xx = Q[Shortcuts::sigma + 0];
58  auto sigma_yy = Q[Shortcuts::sigma + 1];
59  auto sigma_zz = Q[Shortcuts::sigma + 2];
60  auto sigma_xy = Q[Shortcuts::sigma + 3];
61  auto sigma_xz = Q[Shortcuts::sigma + 4];
62  auto sigma_yz = Q[Shortcuts::sigma + 5];
63 
64  auto jacobian = Q[Shortcuts::jacobian];
65 
66  switch (normal) {
67  case 0: {
68  auto q_x = Q[Shortcuts::metric_derivative + 0];
69  auto q_y = Q[Shortcuts::metric_derivative + 1];
70  auto q_z = Q[Shortcuts::metric_derivative + 2];
71  F[0] = -jacobian * (q_x * sigma_xx + q_y * sigma_xy + q_z * sigma_xz);
72  F[1] = -jacobian * (q_x * sigma_xy + q_y * sigma_yy + q_z * sigma_yz);
73  F[2] = -jacobian * (q_x * sigma_xz + q_y * sigma_yz + q_z * sigma_zz);
74  F[3] = 0.0;
75  F[4] = 0.0;
76  F[5] = 0.0;
77  F[6] = 0.0;
78  F[7] = 0.0;
79  F[8] = 0.0;
80  } break;
81  case 1: {
82  auto r_x = Q[Shortcuts::metric_derivative + 3];
83  auto r_y = Q[Shortcuts::metric_derivative + 4];
84  auto r_z = Q[Shortcuts::metric_derivative + 5];
85  F[0] = -jacobian * (r_x * sigma_xx + r_y * sigma_xy + r_z * sigma_xz);
86  F[1] = -jacobian * (r_x * sigma_xy + r_y * sigma_yy + r_z * sigma_yz);
87  F[2] = -jacobian * (r_x * sigma_xz + r_y * sigma_yz + r_z * sigma_zz);
88  F[3] = 0.0;
89  F[4] = 0.0;
90  F[5] = 0.0;
91  F[6] = 0.0;
92  F[7] = 0.0;
93  F[8] = 0.0;
94  } break;
95  case 2: {
96  auto s_x = Q[Shortcuts::metric_derivative + 6];
97  auto s_y = Q[Shortcuts::metric_derivative + 7];
98  auto s_z = Q[Shortcuts::metric_derivative + 8];
99  F[0] = -jacobian * (s_x * sigma_xx + s_y * sigma_xy + s_z * sigma_xz);
100  F[1] = -jacobian * (s_x * sigma_xy + s_y * sigma_yy + s_z * sigma_yz);
101  F[2] = -jacobian * (s_x * sigma_xz + s_y * sigma_yz + s_z * sigma_zz);
102  F[3] = 0.0;
103  F[4] = 0.0;
104  F[5] = 0.0;
105  F[6] = 0.0;
106  F[7] = 0.0;
107  F[8] = 0.0;
108  }
109  }
110 """
111 
112 def ncp():
113  return """
114  switch (normal) {
115  case 0: {
116  auto u_q = deltaQ[0];
117  auto v_q = deltaQ[1];
118  auto w_q = deltaQ[2];
119  auto q_x = Q[Shortcuts::metric_derivative + 0];
120  auto q_y = Q[Shortcuts::metric_derivative + 1];
121  auto q_z = Q[Shortcuts::metric_derivative + 2];
122  BTimesDeltaQ[0] = 0;
123  BTimesDeltaQ[1] = 0;
124  BTimesDeltaQ[2] = 0;
125  BTimesDeltaQ[3] = -q_x * u_q;
126  BTimesDeltaQ[4] = -q_y * v_q;
127  BTimesDeltaQ[5] = -q_z * w_q;
128  BTimesDeltaQ[6] = -(q_y * u_q + q_x * v_q); // sigma_xy
129  BTimesDeltaQ[7] = -(q_z * u_q + q_x * w_q); // sigma_xz
130  BTimesDeltaQ[8] = -(q_z * v_q + q_y * w_q); // sigma_yz
131  } break;
132  case 1: {
133  auto u_r = deltaQ[0];
134  auto v_r = deltaQ[1];
135  auto w_r = deltaQ[2];
136  auto r_x = Q[Shortcuts::metric_derivative + 3];
137  auto r_y = Q[Shortcuts::metric_derivative + 4];
138  auto r_z = Q[Shortcuts::metric_derivative + 5];
139  BTimesDeltaQ[0] = 0;
140  BTimesDeltaQ[1] = 0;
141  BTimesDeltaQ[2] = 0;
142  BTimesDeltaQ[3] = -r_x * u_r;
143  BTimesDeltaQ[4] = -r_y * v_r;
144  BTimesDeltaQ[5] = -r_z * w_r;
145  BTimesDeltaQ[6] = -(r_y * u_r + r_x * v_r); // sigma_xy
146  BTimesDeltaQ[7] = -(r_z * u_r + r_x * w_r); // sigma_xz
147  BTimesDeltaQ[8] = -(r_z * v_r + r_y * w_r); // sigma_yz
148  } break;
149  case 2: {
150  auto u_s = deltaQ[0];
151  auto v_s = deltaQ[1];
152  auto w_s = deltaQ[2];
153  auto s_x = Q[Shortcuts::metric_derivative + 6];
154  auto s_y = Q[Shortcuts::metric_derivative + 7];
155  auto s_z = Q[Shortcuts::metric_derivative + 8];
156  BTimesDeltaQ[0] = 0;
157  BTimesDeltaQ[1] = 0;
158  BTimesDeltaQ[2] = 0;
159  BTimesDeltaQ[3] = -s_x * u_s;
160  BTimesDeltaQ[4] = -s_y * v_s;
161  BTimesDeltaQ[5] = -s_z * w_s;
162  BTimesDeltaQ[6] = -(s_y * u_s + s_x * v_s); // sigma_xy
163  BTimesDeltaQ[7] = -(s_z * u_s + s_x * w_s); // sigma_xz
164  BTimesDeltaQ[8] = -(s_z * v_s + s_y * w_s); // sigma_yz
165  }
166  }
167 """
168 
170  return """
171  auto rho = Q[Shortcuts::rho];
172  auto c_p = Q[Shortcuts::cp];
173  auto c_s = Q[Shortcuts::cs];
174  auto mu = rho * c_s * c_s;
175  auto lambda = rho * c_p * c_p - 2 * mu;
176  auto jacobian = Q[Shortcuts::jacobian];
177  auto rho_inv = 1.0 / (rho * jacobian);
178 
179  // identical in all dimensions so no need for switch
180  rhs[0] = rho_inv * rhs[0];
181  rhs[1] = rho_inv * rhs[1];
182  rhs[2] = rho_inv * rhs[2];
183 
184  auto lam_temp = lambda * (rhs[3] + rhs[4] + rhs[5]);
185  rhs[3] = (2 * mu) * rhs[3] + lam_temp;
186  rhs[4] = (2 * mu) * rhs[4] + lam_temp;
187  rhs[5] = (2 * mu) * rhs[5] + lam_temp;
188 
189  rhs[6] = mu * rhs[6];
190  rhs[7] = mu * rhs[7];
191  rhs[8] = mu * rhs[8];
192 """
193 
195  return """
196  ::exahype2::RefinementCommand result = ::exahype2::RefinementCommand::Keep;
197 
198  return result;
199 """
200 
202  return """
203  std::fill_n(forceVector, 9, 0.);
204 
205  auto jacobian = Q[Shortcuts::jacobian];
206 
207  assertion2(n == 0, "Only a single pointSource for LOH1",n);
208 
209  constexpr double t0 = 0.1;
210  constexpr double M0 = 1000.0;
211 
212  double f = M0*t/(t0*t0)*std::exp(-t/t0);
213 
214  forceVector[Shortcuts::sigma + 4] = f;
215 
216  for (int i = 0; i < NumberOfUnknowns; i++) {
217  forceVector[i] = forceVector[i] / jacobian;
218  }
219 """
221  return """
222  pointSourceLocation[0][0] = 0.0;
223  pointSourceLocation[0][1] = 2.0;
224  pointSourceLocation[0][2] = 0.0;
225 
226  context->correctPointSourceLocation(pointSourceLocation);
227 """
228 
230  return """
231  if (isBoundaryFace) {
232  auto* FIn = faceIndex < DIMENSIONS ? FR : FL;
233  auto* FOut = faceIndex < DIMENSIONS ? FL : FR;
234  std::copy_n(FIn, NumberOfUnknowns+NumberOfAuxiliaryVariables, FOut);
235  }
236 
237  Numerics::riemannSolver<VariableShortcuts{{SOLVER_NAME}}, {{CORRECTOR_COMPUTATION_PRECISION}}, Order + 1, NumberOfUnknowns, (NumberOfUnknowns + NumberOfAuxiliaryVariables), 1>(
238  FL, FR, QL, QR, dt, direction, isBoundaryFace, faceIndex
239  );
240 """
241 
243  return """
244 #define _CUSTOM_COORDINATES
245 #define ASAGI_NOMPI
246 #define _TOP 1
247 
248 #include "../ExaSeis_core/Curvilinear/ContextCurvilinear.h"
249 
250 #include "../ExaSeis_core/Numerics/curvilinearRoutines.h"
251 #include "../ExaSeis_core/Numerics/riemannsolverIsotropic.h"
252 """
253 
255  return """
256 ContextCurvilinear<{{NAMESPACE | join("::")}}::VariableShortcuts{{SOLVER_NAME}},
257  {{NAMESPACE | join("::")}}::{{CLASSNAME}}::Order + 1,
258  ({{NAMESPACE | join("::")}}::{{CLASSNAME}}::NumberOfUnknowns + {{NAMESPACE | join("::")}}::{{CLASSNAME}}::NumberOfAuxiliaryVariables),
259  {{SOLUTION_STORAGE_PRECISION}}>* {{NAMESPACE | join("::")}}::{{CLASSNAME}}::context;
260 """
261 
263  return """
264 public:
265  double QuadraturePoints1d[Order+1];
266 protected:
267  static ContextCurvilinear<VariableShortcuts{{SOLVER_NAME}}, Order + 1, (NumberOfAuxiliaryVariables + NumberOfUnknowns), {{SOLUTION_STORAGE_PRECISION}}>* context;//(NumberOfUnknowns+NumberOfAuxiliaryVariables)>* context;
268 """
269 
270 def init_grid_step_implementation(scenario_string):
271  return """
272  std::copy_n(
273  kernels::{{SOLVER_NAME}}::Quadrature<{{SOLUTION_STORAGE_PRECISION}}>::nodes,
274  (Order+1),
275  QuadraturePoints1d
276  );
277 
278  std::string topography_string = \"""" + scenario_string + """.yaml";
279 
280  //setting coarsestMeshLevel and maxAdaptiveMeshLevel
281  double maxDSize = std::numeric_limits<double>::min();
282  double minDSize = std::numeric_limits<double>::max();
283  tarch::la::Vector<DIMENSIONS, double> sizes = DomainSize;
284 
285  for(int i=0; i<DIMENSIONS; i++){
286  if(sizes[i]>maxDSize){
287  maxDSize = sizes[i];
288  }
289  if(sizes[i]<minDSize){
290  minDSize = sizes[i];
291  }
292  }
293 
294  int depth = 0;
295 
296  //finding coarsest possible Mesh level
297  while(maxDSize>MaxAdmissibleCellH){
298  depth += 1;
299  maxDSize /= 3.0;
300  }
301 
302  double realCoarsestMeshSize = maxDSize;
303  double coarsestMeshLevel = depth;
304 
305  depth = 0;
306  while(minDSize>MinAdmissibleCellH){
307  depth += 1;
308  minDSize /= 3.0;
309  }
310 
311  context = new ContextCurvilinear<VariableShortcuts{{SOLVER_NAME}}, Order + 1, (NumberOfAuxiliaryVariables + NumberOfUnknowns), {{SOLUTION_STORAGE_PRECISION}}>(
312  topography_string,
313  coarsestMeshLevel,
314  realCoarsestMeshSize,
315  depth,
316  DomainOffset, DomainSize,
317  kernels::{{SOLVER_NAME}}::Quadrature<{{SOLUTION_STORAGE_PRECISION}}>::nodes,
318  kernels::{{SOLVER_NAME}}::DGMatrices<{{SOLUTION_STORAGE_PRECISION}}>::dudx
319  );
320 """
def initial(pointwise_initial_conditions)
def init_grid_step_implementation(scenario_string)