Peano
Loading...
Searching...
No Matches
DynamicRuptureElastic.py
Go to the documentation of this file.
1def initial(pointwise_initial_conditions):
2 return """
3 std::fill_n(Q, (NumberOfAuxiliaryVariables + NumberOfUnknowns) * (Order + 1) * (Order + 1) * (Order + 1), 0);
4
5 context->initUnknownsPatch(Q, x, h, 0.0, 0.0,
6 [&](
7 const {{SOLUTION_STORAGE_PRECISION}}* const x,
8 const tarch::la::Vector<DIMENSIONS,double>& center,
9 const double t,
10 const double dt,
11 {{SOLUTION_STORAGE_PRECISION}}* Q
12 ) -> void { """ + pointwise_initial_conditions + """
13 }
14 );
15"""
16
17def flux():
18 return """
19 auto sigma_xx = Q[Shortcuts::sigma + 0];
20 auto sigma_yy = Q[Shortcuts::sigma + 1];
21 auto sigma_zz = Q[Shortcuts::sigma + 2];
22 auto sigma_xy = Q[Shortcuts::sigma + 3];
23 auto sigma_xz = Q[Shortcuts::sigma + 4];
24 auto sigma_yz = Q[Shortcuts::sigma + 5];
25
26 auto jacobian = Q[Shortcuts::jacobian];
27
28 std::fill_n(F, NumberOfUnknowns, 0.);
29
30 switch (normal) {
31 case 0: {
32 auto q_x = Q[Shortcuts::metric_derivative + 0];
33 auto q_y = Q[Shortcuts::metric_derivative + 1];
34 auto q_z = Q[Shortcuts::metric_derivative + 2];
35 F[0] = -jacobian * (q_x * sigma_xx + q_y * sigma_xy + q_z * sigma_xz);
36 F[1] = -jacobian * (q_x * sigma_xy + q_y * sigma_yy + q_z * sigma_yz);
37 F[2] = -jacobian * (q_x * sigma_xz + q_y * sigma_yz + q_z * sigma_zz);
38 } break;
39 case 1: {
40 auto r_x = Q[Shortcuts::metric_derivative + 3];
41 auto r_y = Q[Shortcuts::metric_derivative + 4];
42 auto r_z = Q[Shortcuts::metric_derivative + 5];
43 F[0] = -jacobian * (r_x * sigma_xx + r_y * sigma_xy + r_z * sigma_xz);
44 F[1] = -jacobian * (r_x * sigma_xy + r_y * sigma_yy + r_z * sigma_yz);
45 F[2] = -jacobian * (r_x * sigma_xz + r_y * sigma_yz + r_z * sigma_zz);
46 } break;
47 case 2: {
48 auto s_x = Q[Shortcuts::metric_derivative + 6];
49 auto s_y = Q[Shortcuts::metric_derivative + 7];
50 auto s_z = Q[Shortcuts::metric_derivative + 8];
51 F[0] = -jacobian * (s_x * sigma_xx + s_y * sigma_xy + s_z * sigma_xz);
52 F[1] = -jacobian * (s_x * sigma_xy + s_y * sigma_yy + s_z * sigma_yz);
53 F[2] = -jacobian * (s_x * sigma_xz + s_y * sigma_yz + s_z * sigma_zz);
54 }
55 }
56"""
57
58def ncp():
59 return """
60 auto rho = Q[Shortcuts::rho];
61 auto cp = Q[Shortcuts::cp];
62 auto cs = Q[Shortcuts::cs];
63 auto jacobian = Q[Shortcuts::jacobian];
64 auto mu = rho * cs * cs;
65 auto lambda = rho * cp * cp - 2 * mu;
66 auto rho_inv = 1.0 / (rho * jacobian);
67
68 std::fill_n(BTimesDeltaQ, NumberOfUnknowns, 0.0);
69
70 switch (normal) {
71 case 0: {
72 auto u_q = deltaQ[Shortcuts::v + 0];
73 auto v_q = deltaQ[Shortcuts::v + 1];
74 auto w_q = deltaQ[Shortcuts::v + 2];
75 auto q_x = Q[Shortcuts::metric_derivative + 0];
76 auto q_y = Q[Shortcuts::metric_derivative + 1];
77 auto q_z = Q[Shortcuts::metric_derivative + 2];
78 BTimesDeltaQ[Shortcuts::sigma + 0] = -q_x*u_q;
79 BTimesDeltaQ[Shortcuts::sigma + 1] = -q_y*v_q;
80 BTimesDeltaQ[Shortcuts::sigma + 2] = -q_z*w_q;
81 BTimesDeltaQ[Shortcuts::sigma + 3] = -(q_y*u_q+q_x*v_q); //sigma_xy
82 BTimesDeltaQ[Shortcuts::sigma + 4] = -(q_z*u_q+q_x*w_q); //sigma_xz
83 BTimesDeltaQ[Shortcuts::sigma + 5] = -(q_z*v_q+q_y*w_q); //sigma_yz
84 } break;
85 case 1: {
86 auto u_r = deltaQ[Shortcuts::v + 0];
87 auto v_r = deltaQ[Shortcuts::v + 1];
88 auto w_r = deltaQ[Shortcuts::v + 2];
89 auto r_x = Q[Shortcuts::metric_derivative + 3];
90 auto r_y = Q[Shortcuts::metric_derivative + 4];
91 auto r_z = Q[Shortcuts::metric_derivative + 5];
92 BTimesDeltaQ[Shortcuts::sigma + 0] = -r_x*u_r;
93 BTimesDeltaQ[Shortcuts::sigma + 1] = -r_y*v_r;
94 BTimesDeltaQ[Shortcuts::sigma + 2] = -r_z*w_r;
95 BTimesDeltaQ[Shortcuts::sigma + 3] = -(r_y*u_r+r_x*v_r); //sigma_xy
96 BTimesDeltaQ[Shortcuts::sigma + 4] = -(r_z*u_r+r_x*w_r); //sigma_xz
97 BTimesDeltaQ[Shortcuts::sigma + 5] = -(r_z*v_r+r_y*w_r); //sigma_yz
98 } break;
99 case 2: {
100 auto u_s = deltaQ[Shortcuts::v + 0];
101 auto v_s = deltaQ[Shortcuts::v + 1];
102 auto w_s = deltaQ[Shortcuts::v + 2];
103 auto s_x = Q[Shortcuts::metric_derivative + 6];
104 auto s_y = Q[Shortcuts::metric_derivative + 7];
105 auto s_z = Q[Shortcuts::metric_derivative + 8];
106 BTimesDeltaQ[Shortcuts::sigma + 0] = -s_x*u_s;
107 BTimesDeltaQ[Shortcuts::sigma + 1] = -s_y*v_s;
108 BTimesDeltaQ[Shortcuts::sigma + 2] = -s_z*w_s;
109 BTimesDeltaQ[Shortcuts::sigma + 3] = -(s_y*u_s+s_x*v_s); //sigma_xy
110 BTimesDeltaQ[Shortcuts::sigma + 4] = -(s_z*u_s+s_x*w_s); //sigma_xz
111 BTimesDeltaQ[Shortcuts::sigma + 5] = -(s_z*v_s+s_y*w_s); //sigma_yz
112 }
113 }
114"""
115
117 return """
118 std::fill_n(S, NumberOfAuxiliaryVariables, 0);
119
120 S[9] = -Q[0];
121 S[10] = -Q[1];
122 S[11] = -Q[2];
123"""
124
126 return """
127 auto rho = Q[Shortcuts::rho];
128 auto cp = Q[Shortcuts::cp];
129 auto cs = Q[Shortcuts::cs];
130 auto jacobian = Q[Shortcuts::jacobian];
131
132 auto mu = rho * cs * cs;
133 auto lambda = rho * cp * cp - 2 * mu;
134 auto rho_inv=1.0/(rho*jacobian);
135
136 // Rhs uses the same formula regardless of dimension, hence no switch necessary
137
138 rhs[Shortcuts::v + 0] = rho_inv * rhs[Shortcuts::v + 0];
139 rhs[Shortcuts::v + 1] = rho_inv * rhs[Shortcuts::v + 1];
140 rhs[Shortcuts::v + 2] = rho_inv * rhs[Shortcuts::v + 2];
141
142 double lam_temp = lambda * (rhs[3] + rhs[4] + rhs[5]);
143
144 rhs[3]=(2*mu) * rhs[3] +lam_temp;
145 rhs[4]=(2*mu) * rhs[4] +lam_temp;
146 rhs[5]=(2*mu) * rhs[5] +lam_temp;
147
148 rhs[6]= mu*rhs[6];
149 rhs[7]= mu*rhs[7];
150 rhs[8]= mu*rhs[8];
151
152 rhs[9]= rhs[9];
153 rhs[10]= rhs[10];
154 rhs[11]= rhs[11];
155"""
156
158 return """
159 context->riemannSolver(
160 FL, FR,
161 QL, QR,
162 t, dt,
163 x, h,
164 direction,
165 isBoundaryFace,
166 faceIndex,
167 1 //surface
168 );
169"""
170
172 return """
173#define _CUSTOM_COORDINATES
174#define ASAGI_NOMPI
175#define _TOP 1
176
177#include "../ExaSeis_core/Curvilinear/ContextDynamicRupture.h"
178#include "../ExaSeis_core/Numerics/riemannsolverDynamicRupture.h"
179
180#include "peano4/datamanagement/CellMarker.h"
181"""
182
184 return """
185ContextDynamicRupture<{{NAMESPACE | join("::")}}::VariableShortcuts{{SOLVER_NAME}},
186 {{NAMESPACE | join("::")}}::{{CLASSNAME}}::Order + 1,
187 {{NAMESPACE | join("::")}}::{{CLASSNAME}}::NumberOfUnknowns,
188 {{NAMESPACE | join("::")}}::{{CLASSNAME}}::NumberOfAuxiliaryVariables,
189 {{SOLUTION_STORAGE_PRECISION}}>* {{NAMESPACE | join("::")}}::{{CLASSNAME}}::context;
190
191tarch::la::Vector<DIMENSIONS,double> {{NAMESPACE | join("::")}}::{{CLASSNAME}}::invertProjection(const tarch::la::Vector<DIMENSIONS,double> coordinates){
192
193 try {
194 double fixedCoords[3];
195 fixedCoords[toolbox::curvi::Coordinate::X] = coordinates[0];
196 fixedCoords[toolbox::curvi::Coordinate::Y] = coordinates[1];
197 fixedCoords[toolbox::curvi::Coordinate::Z] = coordinates[2];
198
199 tarch::la::Vector<DIMENSIONS,double> result;
200 toolbox::curvi::Interface* curviInterface = context->getInterface();
201 result[0] = curviInterface->invertProjection(toolbox::curvi::Coordinate::X, fixedCoords);
202 result[1] = curviInterface->invertProjection(toolbox::curvi::Coordinate::Y, fixedCoords);
203 result[2] = curviInterface->invertProjection(toolbox::curvi::Coordinate::Z, fixedCoords);
204
205 return result;
206 }
207 catch (std::domain_error e) {
208 logInfo("invertProjection()", "Caught an error with tracer at " << coordinates << ", and therefore not shifting its position");
209 return coordinates;
210 }
211}
212"""
213
215 return """
216public:
217 double QuadraturePoints1d[Order+1];
218
219 tarch::la::Vector<DIMENSIONS,double> invertProjection(const tarch::la::Vector<DIMENSIONS,double> coordinates);
220
221 static ContextDynamicRupture<VariableShortcuts{{SOLVER_NAME}}, Order + 1, NumberOfUnknowns, NumberOfAuxiliaryVariables, {{SOLUTION_STORAGE_PRECISION}}>* context;
222"""
223
224def init_grid_step_implementation(scenario_string):
225 return """
226 std::copy_n(
227 kernels::{{SOLVER_NAME}}::Quadrature<{{SOLUTION_STORAGE_PRECISION}}>::nodes,
228 (Order+1),
229 QuadraturePoints1d
230 );
231
232 std::string topography_string = \"""" + scenario_string + """.yaml";
233
234 //setting coarsestMeshLevel and maxAdaptiveMeshLevel
235 double maxDSize = std::numeric_limits<double>::min();
236 double minDSize = std::numeric_limits<double>::max();
237 tarch::la::Vector<DIMENSIONS, double> sizes = DomainSize;
238
239 for(int i=0; i<DIMENSIONS; i++){
240 if(sizes[i]>maxDSize){
241 maxDSize = sizes[i];
242 }
243 if(sizes[i]<minDSize){
244 minDSize = sizes[i];
245 }
246 }
247
248 int depth = 0;
249
250 //finding coarsest possible Mesh level
251 while(maxDSize>MaxAdmissibleCellH){
252 depth += 1;
253 maxDSize /= 3.0;
254 }
255
256 double realCoarsestMeshSize = maxDSize;
257 double coarsestMeshLevel = depth;
258
259 depth = 0;
260 while(minDSize>MinAdmissibleCellH){
261 depth += 1;
262 minDSize /= 3.0;
263 }
264
265 context = new ContextDynamicRupture<VariableShortcuts{{SOLVER_NAME}}, Order + 1, NumberOfUnknowns, NumberOfAuxiliaryVariables, {{SOLUTION_STORAGE_PRECISION}}>(
266 topography_string,
267 // filename_rupture_model,
268 coarsestMeshLevel,
269 realCoarsestMeshSize,
270 depth,
271 DomainOffset, DomainSize,
272 kernels::{{SOLVER_NAME}}::Quadrature<{{SOLUTION_STORAGE_PRECISION}}>::nodes,
273 kernels::{{SOLVER_NAME}}::DGMatrices<{{SOLUTION_STORAGE_PRECISION}}>::dudx
274 );
275
276 std::string filename_rupture_model = \"""" + scenario_string + """_fault.yaml";
277 context->initRuptureModel(filename_rupture_model);
278
279 logInfo("startGridInitialisationStep()", "Freesurface set at " << std::to_string(_TOP * 2));
280"""
281
283 return """
284 delete context;
285"""
init_grid_step_implementation(scenario_string)
initial(pointwise_initial_conditions)