MFEM v4.9.0
Finite element discretization library
Loading...
Searching...
No Matches
dinvariants.hpp
Go to the documentation of this file.
1// Copyright (c) 2010-2025, Lawrence Livermore National Security, LLC. Produced
2// at the Lawrence Livermore National Laboratory. All Rights reserved. See files
3// LICENSE and NOTICE for details. LLNL-CODE-806117.
4//
5// This file is part of the MFEM library. For more information and source code
6// availability visit https://mfem.org.
7//
8// MFEM is free software; you can redistribute it and/or modify it under the
9// terms of the BSD-3 license. We welcome feedback and contributions, see file
10// CONTRIBUTING.md for details.
11
12#ifndef MFEM_DINVARIANTS_HPP
13#define MFEM_DINVARIANTS_HPP
14
15#include "../config/config.hpp"
16#include "dtensor.hpp"
17#include <cmath>
18
19namespace mfem
20{
21
22namespace kernels
23{
24
26{
27public:
28 class Buffers
29 {
31 private:
32 const real_t * J_ = nullptr;
33 real_t * dI1_ = nullptr;
34 real_t * dI1b_ = nullptr;
35 real_t * ddI1_ = nullptr;
36 real_t * ddI1b_ = nullptr;
37 real_t * dI2_ = nullptr;
38 real_t * dI2b_ = nullptr;
39 real_t * ddI2_ = nullptr;
40 real_t * ddI2b_ = nullptr;
41 public:
42 MFEM_HOST_DEVICE Buffers() {}
43 MFEM_HOST_DEVICE Buffers &J(const real_t *b) { J_ = b; return *this; }
44 MFEM_HOST_DEVICE Buffers &dI1(real_t *b) { dI1_ = b; return *this; }
45 MFEM_HOST_DEVICE Buffers &dI1b(real_t *b) { dI1b_ = b; return *this; }
46 MFEM_HOST_DEVICE Buffers &ddI1(real_t *b) { ddI1_ = b; return *this; }
47 MFEM_HOST_DEVICE Buffers &ddI1b(real_t *b) { ddI1b_ = b; return *this; }
48 MFEM_HOST_DEVICE Buffers &dI2(real_t *b) { dI2_ = b; return *this; }
49 MFEM_HOST_DEVICE Buffers &dI2b(real_t *b) { dI2b_ = b; return *this; }
50 MFEM_HOST_DEVICE Buffers &ddI2(real_t *b) { ddI2_ = b; return *this; }
51 MFEM_HOST_DEVICE Buffers &ddI2b(real_t *b) { ddI2b_ = b; return *this; }
52 };
53
54private:
55 real_t const * const J;
56 real_t * const dI1, * const dI1b, * const ddI1, * const ddI1b;
57 real_t * const dI2, * const dI2b, * const ddI2, * const ddI2b;
58
59public:
60 MFEM_HOST_DEVICE
62 J(b.J_),
63 dI1(b.dI1_), dI1b(b.dI1b_), ddI1(b.ddI1_), ddI1b(b.ddI1b_),
64 dI2(b.dI2_), dI2b(b.dI2b_), ddI2(b.ddI2_), ddI2b(b.ddI2b_) { }
65
66 MFEM_HOST_DEVICE inline real_t Get_I2b(real_t &sign_detJ) // det(J) + sign
67 {
68 const real_t I2b = J[0]*J[3] - J[1]*J[2];
69 sign_detJ = I2b >= 0.0 ? 1.0 : -1.0;
70 return sign_detJ * I2b;
71 }
72
73 MFEM_HOST_DEVICE inline real_t Get_I2b() // det(J)
74 {
75 real_t sign_detJ;
76 return Get_I2b(sign_detJ);
77 }
78
79 MFEM_HOST_DEVICE inline real_t Get_I2() // det(J)^{2}
80 {
81 const real_t I2b = Get_I2b();
82 return I2b * I2b;
83 }
84
85 MFEM_HOST_DEVICE inline real_t Get_I1() // I1 = ||J||_F^2
86 {
87 return J[0]*J[0] + J[1]*J[1] + J[2]*J[2] + J[3]*J[3];
88 }
89
90 MFEM_HOST_DEVICE inline real_t Get_I1b() // I1b = I1/det(J)
91 {
92 return Get_I1() / Get_I2b();
93 }
94
95 MFEM_HOST_DEVICE inline real_t *Get_dI1()
96 {
97 dI1[0] = 2*J[0]; dI1[2] = 2*J[2];
98 dI1[1] = 2*J[1]; dI1[3] = 2*J[3];
99 return dI1;
100 }
101
102 // Requires dI2b.
103 MFEM_HOST_DEVICE inline real_t *Get_dI1b()
104 {
105 // I1b = I1/I2b
106 // dI1b = (1/I2b)*dI1 - (I1/I2b^2)*dI2b = (2/I2b)*[J - (I1b/2)*dI2b]
107 const real_t c1 = 2.0/Get_I2b();
108 const real_t c2 = Get_I1b()/2.0;
109 Get_dI2b();
110 dI1b[0] = c1*(J[0] - c2*dI2b[0]);
111 dI1b[1] = c1*(J[1] - c2*dI2b[1]);
112 dI1b[2] = c1*(J[2] - c2*dI2b[2]);
113 dI1b[3] = c1*(J[3] - c2*dI2b[3]);
114 return dI1b;
115 }
116
117 // Requires dI2b.
118 MFEM_HOST_DEVICE inline real_t *Get_dI2()
119 {
120 // I2 = I2b^2
121 // dI2 = 2*I2b*dI2b = 2*det(J)*adj(J)^T
122 const real_t c1 = 2*Get_I2b();
123 Get_dI2b();
124 dI2[0] = c1*dI2b[0];
125 dI2[1] = c1*dI2b[1];
126 dI2[2] = c1*dI2b[2];
127 dI2[3] = c1*dI2b[3];
128 return dI2;
129 }
130
131 MFEM_HOST_DEVICE inline real_t *Get_dI2b()
132 {
133 // I2b = det(J)
134 // dI2b = adj(J)^T
135 real_t sign_detJ;
136 Get_I2b(sign_detJ);
137 dI2b[0] = sign_detJ*J[3];
138 dI2b[1] = -sign_detJ*J[2];
139 dI2b[2] = -sign_detJ*J[1];
140 dI2b[3] = sign_detJ*J[0];
141 return dI2b;
142 }
143
144 // ddI1_ijkl = 2 I_ijkl = 2 δ_ik δ_jl
145 MFEM_HOST_DEVICE inline real_t *Get_ddI1(int i, int j)
146 {
147 // ddI1_ijkl = 2 I_ijkl = 2 δ_ik δ_jl
148 DeviceMatrix ddi1(ddI1,2,2);
149 for (int k=0; k<2; k++)
150 {
151 for (int l=0; l<2; l++)
152 {
153 ddi1(k,l) = (i==k && j==l) ? 2.0 : 0.0;
154 }
155 }
156 return ddI1;
157 }
158
159 // Requires dI2b + ddI1.
160 // ddI1b = X1 + X2 + X3, where
161 // X1_ijkl = (I1b/I2) [ dI2b_ij dI2b_kl + dI2b_kj dI2b_il ]
162 // X2_ijkl = (1/I2b) ddI1_ijkl
163 // X3_ijkl = -(2/I2) (J_ij dI2b_kl + dI2b_ij J_kl)
164 MFEM_HOST_DEVICE inline real_t *Get_ddI1b(int i, int j)
165 {
166 real_t X1_p[4], X2_p[4], X3_p[4];
167
168 // X1_ijkl = (I1b/I2) [ dI2b_ij dI2b_kl + dI2b_kj dI2b_il ]
169 const real_t I2 = Get_I2();
170 const real_t I1b = Get_I1b();
171 ConstDeviceMatrix di2b(Get_dI2b(),2,2);
172 const real_t alpha = I1b / I2;
173 DeviceMatrix X1(X1_p,2,2);
174 for (int k=0; k<2; k++)
175 {
176 for (int l=0; l<2; l++)
177 {
178 X1(k,l) = alpha * (di2b(i,j)*di2b(k,l) + di2b(k,j)*di2b(i,l));
179 }
180 }
181 // X2_ijkl = (1/I2b) ddI1_ijkl
182 DeviceMatrix X2(X2_p,2,2);
183 const real_t beta = 1.0 / Get_I2b();
184 ConstDeviceMatrix ddi1(Get_ddI1(i,j),2,2);
185 for (int k=0; k<2; k++)
186 {
187 for (int l=0; l<2; l++)
188 {
189 X2(k,l) = beta * ddi1(k,l);
190 }
191 }
192 // X3_ijkl = -(2/I2) (J_ij dI2b_kl + dI2b_ij J_kl)
193 DeviceMatrix X3(X3_p,2,2);
194 const real_t gamma = -2.0/Get_I2();
195 ConstDeviceMatrix Jpt(J,2,2);
196 for (int k=0; k<2; k++)
197 {
198 for (int l=0; l<2; l++)
199 {
200 X3(k,l) = gamma * (Jpt(i,j)*di2b(k,l) + di2b(i,j)*Jpt(k,l));
201 }
202 }
203 DeviceMatrix ddi1b(ddI1b,2,2);
204 for (int k=0; k<2; k++)
205 {
206 for (int l=0; l<2; l++)
207 {
208 ddi1b(k,l) = X1(k,l) + X2(k,l) + X3(k,l);
209 }
210 }
211 return ddI1b;
212 }
213
214 // Requires dI2b.
215 // ddI2_ijkl = 2 dI2b_ij dI2b_kl + 2 (dI2b_ij dI2b_kl - dI2b_kj dI2b_il)
216 MFEM_HOST_DEVICE inline real_t *Get_ddI2(int i, int j)
217 {
218 DeviceMatrix ddi2(ddI2,2,2);
219 ConstDeviceMatrix di2b(Get_dI2b(),2,2);
220 for (int k=0; k<2; k++)
221 {
222 for (int l=0; l<2; l++)
223 {
224 ddi2(k,l) = 2*di2b(i,j)*di2b(k,l)
225 + 2*(di2b(i,j)*di2b(k,l) - di2b(k,j)*di2b(i,l));
226 }
227 }
228 return ddI2;
229 }
230
231 // Requires dI2b.
232 // ddI2b_ijkl = (1/I2b) (δ_ks δ_it - δ_kt δ_si) dI2b_tj dI2b_sl
233 MFEM_HOST_DEVICE inline real_t *Get_ddI2b(int i, int j)
234 {
235 DeviceMatrix ddi2b(ddI2b,2,2);
236 const real_t alpha = 1.0/Get_I2b();
237 ConstDeviceMatrix di2b(Get_dI2b(),2,2);
238 for (int k=0; k<2; k++)
239 {
240 for (int l=0; l<2; l++)
241 {
242 ddi2b(k,l) = 0.0;
243 for (int s=0; s<2; s++)
244 {
245 for (int t=0; t<2; t++)
246 {
247 const real_t ks_it = k==s && i==t ? 1.0 : 0.0;
248 const real_t kt_si = k==t && s==i ? 1.0 : 0.0;
249 ddi2b(k,l) += alpha * (ks_it - kt_si) * di2b(t,j) * di2b(s,l);
250 }
251 }
252 }
253 }
254 return ddI2b;
255 }
256};
257
258
260{
261public:
263 {
265 private:
266 const real_t * J_ = nullptr;
267 real_t * B_ = nullptr;
268 real_t * dI1_ = nullptr;
269 real_t * dI1b_ = nullptr;
270 real_t * ddI1_ = nullptr;
271 real_t * ddI1b_ = nullptr;
272 real_t * dI2_ = nullptr;
273 real_t * dI2b_ = nullptr;
274 real_t * ddI2_ = nullptr;
275 real_t * ddI2b_ = nullptr;
276 real_t * dI3b_ = nullptr;
277 real_t * ddI3b_ = nullptr;
278 public:
279 MFEM_HOST_DEVICE Buffers() {}
280 MFEM_HOST_DEVICE Buffers &J(const real_t *b) { J_ = b; return *this; }
281 MFEM_HOST_DEVICE Buffers &B(real_t *b) { B_ = b; return *this; }
282 MFEM_HOST_DEVICE Buffers &dI1(real_t *b) { dI1_ = b; return *this; }
283 MFEM_HOST_DEVICE Buffers &dI1b(real_t *b) { dI1b_ = b; return *this; }
284 MFEM_HOST_DEVICE Buffers &ddI1(real_t *b) { ddI1_ = b; return *this; }
285 MFEM_HOST_DEVICE Buffers &ddI1b(real_t *b) { ddI1b_ = b; return *this; }
286 MFEM_HOST_DEVICE Buffers &dI2(real_t *b) { dI2_ = b; return *this; }
287 MFEM_HOST_DEVICE Buffers &dI2b(real_t *b) { dI2b_ = b; return *this; }
288 MFEM_HOST_DEVICE Buffers &ddI2(real_t *b) { ddI2_ = b; return *this; }
289 MFEM_HOST_DEVICE Buffers &ddI2b(real_t *b) { ddI2b_ = b; return *this; }
290 MFEM_HOST_DEVICE Buffers &dI3b(real_t *b) { dI3b_ = b; return *this; }
291 MFEM_HOST_DEVICE Buffers &ddI3b(real_t *b) { ddI3b_ = b; return *this; }
292 };
293
294private:
295 real_t const * const J;
296 real_t * const B;
297 real_t * const dI1, * const dI1b, * const ddI1, * const ddI1b;
298 real_t * const dI2, * const dI2b, * const ddI2, * const ddI2b;
299 real_t * const dI3b, * const ddI3b;
300
301public:
302 MFEM_HOST_DEVICE
304 J(b.J_), B(b.B_),
305 dI1(b.dI1_), dI1b(b.dI1b_), ddI1(b.ddI1_), ddI1b(b.ddI1b_),
306 dI2(b.dI2_), dI2b(b.dI2b_), ddI2(b.ddI2_), ddI2b(b.ddI2b_),
307 dI3b(b.dI3b_), ddI3b(b.ddI3b_) { }
308
309 MFEM_HOST_DEVICE inline real_t Get_I3b(real_t &sign_detJ) // det(J) + sign
310 {
311 const real_t I3b = + J[0]*(J[4]*J[8] - J[7]*J[5])
312 - J[1]*(J[3]*J[8] - J[5]*J[6])
313 + J[2]*(J[3]*J[7] - J[4]*J[6]);
314 sign_detJ = I3b >= 0.0 ? 1.0 : -1.0;
315 return sign_detJ * I3b;
316 }
317
318 MFEM_HOST_DEVICE inline real_t Get_I3b() // det(J)
319 {
320 const real_t I3b = + J[0]*(J[4]*J[8] - J[7]*J[5])
321 - J[1]*(J[3]*J[8] - J[5]*J[6])
322 + J[2]*(J[3]*J[7] - J[4]*J[6]);
323 return I3b;
324 }
325
326 MFEM_HOST_DEVICE inline real_t Get_I3() // det(J)^{2}
327 {
328 const real_t I3b = Get_I3b();
329 return I3b * I3b;
330 }
331
332 MFEM_HOST_DEVICE inline real_t Get_I3b_p() // I3b^{-2/3}
333 {
334 real_t sign_detJ;
335 const real_t i3b = Get_I3b(sign_detJ);
336 return sign_detJ * std::pow(i3b, -2./3.);
337 }
338
339 MFEM_HOST_DEVICE inline real_t Get_I3b_p(real_t &sign_detJ) // I3b^{-2/3}
340 {
341 const real_t i3b = Get_I3b(sign_detJ);
342 return sign_detJ * std::pow(i3b, -2./3.);
343 }
344
345 MFEM_HOST_DEVICE inline real_t Get_I1()
346 {
347 B[0] = J[0]*J[0] + J[3]*J[3] + J[6]*J[6];
348 B[1] = J[1]*J[1] + J[4]*J[4] + J[7]*J[7];
349 B[2] = J[2]*J[2] + J[5]*J[5] + J[8]*J[8];
350 const real_t I1 = B[0] + B[1] + B[2];
351 return I1;
352 }
353
354 MFEM_HOST_DEVICE inline
355 real_t Get_I1b() // det(J)^{-2/3}*I_1 = I_1/I_3^{1/3}
356 {
357 const real_t I1b = Get_I1() * Get_I3b_p();
358 return I1b;
359 }
360
361 MFEM_HOST_DEVICE inline void Get_B_offd()
362 {
363 // B = J J^t
364 // B[3]=B(0,1), B[4]=B(0,2), B[5]=B(1,2)
365 B[3] = J[0]*J[1] + J[3]*J[4] + J[6]*J[7]; // B(0,1)
366 B[4] = J[0]*J[2] + J[3]*J[5] + J[6]*J[8]; // B(0,2)
367 B[5] = J[1]*J[2] + J[4]*J[5] + J[7]*J[8]; // B(1,2)
368 }
369
370 MFEM_HOST_DEVICE inline real_t Get_I2()
371 {
372 Get_B_offd();
373 const real_t I1 = Get_I1();
374 const real_t BF2 = B[0]*B[0] + B[1]*B[1] + B[2]*B[2] +
375 2*(B[3]*B[3] + B[4]*B[4] + B[5]*B[5]);
376 const real_t I2 = (I1*I1 - BF2)/2;
377 return I2;
378 }
379
380 MFEM_HOST_DEVICE inline real_t Get_I2b() // I2b = I2*I3b^{-4/3}
381 {
382 const real_t I3b_p = Get_I3b_p();
383 return Get_I2() * I3b_p * I3b_p;
384 }
385
386 MFEM_HOST_DEVICE inline real_t *Get_dI1()
387 {
388 for (int i = 0; i < 9; i++) { dI1[i] = 2*J[i]; }
389 return dI1;
390 }
391
392 MFEM_HOST_DEVICE inline real_t *Get_dI1b()
393 {
394 // I1b = I3b^{-2/3}*I1
395 // dI1b = 2*I3b^{-2/3}*(J - (1/3)*I1/I3b*dI3b)
396 real_t sign_detJ;
397 const real_t I3b = Get_I3b(sign_detJ);
398 const real_t I3b_p = Get_I3b_p();
399 const real_t c1 = 2.0 * I3b_p;
400 const real_t c2 = Get_I1()/(3.0 * I3b);
401 Get_dI3b(sign_detJ);
402 for (int i = 0; i < 9; i++) { dI1b[i] = c1*(J[i] - c2*dI3b[i]); }
403 return dI1b;
404 }
405
406 MFEM_HOST_DEVICE inline real_t *Get_dI2()
407 {
408 // dI2 = 2 I_1 J - 2 J J^t J = 2 (I_1 I - B) J
409 const real_t I1 = Get_I1();
410 Get_B_offd();
411 // B[0]=B(0,0), B[1]=B(1,1), B[2]=B(2,2)
412 // B[3]=B(0,1), B[4]=B(0,2), B[5]=B(1,2)
413 const real_t C[6] =
414 {
415 2*(I1 - B[0]), 2*(I1 - B[1]), 2*(I1 - B[2]),
416 -2*B[3], -2*B[4], -2*B[5]
417 };
418 // | C[0] C[3] C[4] | | J[0] J[3] J[6] |
419 // dI2 = | C[3] C[1] C[5] | | J[1] J[4] J[7] |
420 // | C[4] C[5] C[2] | | J[2] J[5] J[8] |
421 dI2[0] = C[0]*J[0] + C[3]*J[1] + C[4]*J[2];
422 dI2[1] = C[3]*J[0] + C[1]*J[1] + C[5]*J[2];
423 dI2[2] = C[4]*J[0] + C[5]*J[1] + C[2]*J[2];
424
425 dI2[3] = C[0]*J[3] + C[3]*J[4] + C[4]*J[5];
426 dI2[4] = C[3]*J[3] + C[1]*J[4] + C[5]*J[5];
427 dI2[5] = C[4]*J[3] + C[5]*J[4] + C[2]*J[5];
428
429 dI2[6] = C[0]*J[6] + C[3]*J[7] + C[4]*J[8];
430 dI2[7] = C[3]*J[6] + C[1]*J[7] + C[5]*J[8];
431 dI2[8] = C[4]*J[6] + C[5]*J[7] + C[2]*J[8];
432 return dI2;
433 }
434
435 MFEM_HOST_DEVICE inline real_t *Get_dI2b()
436 {
437 // I2b = det(J)^{-4/3}*I2 = I3b^{-4/3}*I2
438 // dI2b = (-4/3)*I3b^{-7/3}*I2*dI3b + I3b^{-4/3}*dI2
439 // = I3b^{-4/3} * [ dI2 - (4/3)*I2/I3b*dI3b ]
440 real_t sign_detJ;
441 const real_t I2 = Get_I2();
442 const real_t I3b_p = Get_I3b_p();
443 const real_t I3b = Get_I3b(sign_detJ);
444 const real_t c1 = I3b_p*I3b_p;
445 const real_t c2 = (4*I2/I3b)/3;
446 Get_dI2();
447 Get_dI3b(sign_detJ);
448 for (int i = 0; i < 9; i++) { dI2b[i] = c1*(dI2[i] - c2*dI3b[i]); }
449 return dI2b;
450 }
451
452 MFEM_HOST_DEVICE inline real_t *Get_dI3b(const real_t sign_detJ)
453 {
454 // I3b = det(J)
455 // dI3b = adj(J)^T
456 dI3b[0] = sign_detJ*(J[4]*J[8] - J[5]*J[7]); // 0 3 6
457 dI3b[1] = sign_detJ*(J[5]*J[6] - J[3]*J[8]); // 1 4 7
458 dI3b[2] = sign_detJ*(J[3]*J[7] - J[4]*J[6]); // 2 5 8
459 dI3b[3] = sign_detJ*(J[2]*J[7] - J[1]*J[8]);
460 dI3b[4] = sign_detJ*(J[0]*J[8] - J[2]*J[6]);
461 dI3b[5] = sign_detJ*(J[1]*J[6] - J[0]*J[7]);
462 dI3b[6] = sign_detJ*(J[1]*J[5] - J[2]*J[4]);
463 dI3b[7] = sign_detJ*(J[2]*J[3] - J[0]*J[5]);
464 dI3b[8] = sign_detJ*(J[0]*J[4] - J[1]*J[3]);
465 return dI3b;
466 }
467
468 // ddI1_ijkl = 2 I_ijkl = 2 δ_ik δ_jl
469 MFEM_HOST_DEVICE inline real_t *Get_ddI1(int i, int j)
470 {
471 DeviceMatrix ddi1(ddI1,3,3);
472 for (int k=0; k<3; k++)
473 {
474 for (int l=0; l<3; l++)
475 {
476 const real_t I_ijkl = (i==k && j==l) ? 1.0 : 0.0;
477 ddi1(k,l) = 2.0 * I_ijkl;
478 }
479 }
480 return ddI1;
481 }
482
483 // ddI1b = X1 + X2 + X3, where
484 // X1_ijkl = (2/3*I1b/I3) [ 2/3 dI3b_ij dI3b_kl + dI3b_kj dI3b_il ]
485 // X2_ijkl = (I3b^{-2/3}) ddI1_ijkl
486 // X3_ijkl = -(4/3*I3b^{-5/3}) (J_ij dI3b_kl + dI3b_ij J_kl)
487 MFEM_HOST_DEVICE inline real_t *Get_ddI1b(int i, int j)
488 {
489 // X1_ijkl = (2/3*I1b/I3) [ 2/3 dI3b_ij dI3b_kl + dI3b_kj dI3b_il ]
490 real_t sign_detJ;
491 Get_I3b(sign_detJ);
492 real_t X1_p[9], X2_p[9], X3_p[9];
493 DeviceMatrix X1(X1_p,3,3);
494 const real_t I3 = Get_I3();
495 const real_t I1b = Get_I1b();
496 const real_t alpha = (2./3.)*I1b/I3;
497 ConstDeviceMatrix di3b(Get_dI3b(sign_detJ),3,3);
498 for (int k=0; k<3; k++)
499 {
500 for (int l=0; l<3; l++)
501 {
502 X1(k,l) = alpha * ((2./3.)*di3b(i,j) * di3b(k,l) +
503 di3b(k,j)*di3b(i,l));
504 }
505 }
506 // ddI1_ijkl = 2 δ_ik δ_jl
507 // X2_ijkl = (I3b^{-2/3}) ddI1_ijkl
508 DeviceMatrix X2(X2_p,3,3);
509 const real_t beta = Get_I3b_p();
510 for (int k=0; k<3; k++)
511 {
512 for (int l=0; l<3; l++)
513 {
514 const real_t ddI1_ijkl = (i==k && j==l) ? 2.0 : 0.0;
515 X2(k,l) = beta * ddI1_ijkl;
516 }
517 }
518 // X3_ijkl = -(4/3*I3b^{-5/3}) (J_ij dI3b_kl + dI3b_ij J_kl)
519 DeviceMatrix X3(X3_p,3,3);
520 const real_t I3b = Get_I3b();
521 const real_t gamma = -(4./3.)*Get_I3b_p()/I3b;
522 ConstDeviceMatrix Jpt(J,3,3);
523 for (int k=0; k<3; k++)
524 {
525 for (int l=0; l<3; l++)
526 {
527 X3(k,l) = gamma * (Jpt(i,j) * di3b(k,l) + di3b(i,j) * Jpt(k,l));
528 }
529 }
530 DeviceMatrix ddi1b(ddI1b,3,3);
531 for (int k=0; k<3; k++)
532 {
533 for (int l=0; l<3; l++)
534 {
535 ddi1b(k,l) = X1(k,l) + X2(k,l) + X3(k,l);
536 }
537 }
538 return ddI1b;
539 }
540
541 // ddI2 = x1 + x2 + x3
542 // x1_ijkl = (2 I1) δ_ik δ_jl
543 // x2_ijkl = 2 ( 2 δ_ku δ_iv - δ_ik δ_uv - δ_kv δ_iu ) J_vj J_ul
544 // x3_ijkl = -2 (J J^t)_ik δ_jl = -2 B_ik δ_jl
545 MFEM_HOST_DEVICE inline real_t *Get_ddI2(int i, int j)
546 {
547 real_t x1_p[9], x2_p[9], x3_p[9];
548 DeviceMatrix x1(x1_p,3,3), x2(x2_p,3,3), x3(x3_p,3,3);
549 // x1_ijkl = (2 I1) δ_ik δ_jl
550 const real_t I1 = Get_I1();
551 for (int k=0; k<3; k++)
552 {
553 for (int l=0; l<3; l++)
554 {
555 const real_t ik_jl = (i==k && j==l) ? 1.0 : 0.0;
556 x1(k,l) = 2.0 * I1 * ik_jl;
557 }
558 }
559 // x2_ijkl = 2 ( 2 δ_ku δ_iv - δ_ik δ_uv - δ_kv δ_iu ) J_vj J_ul
560 ConstDeviceMatrix Jpt(J,3,3);
561 for (int k=0; k<3; k++)
562 {
563 for (int l=0; l<3; l++)
564 {
565 x2(k,l) = 0.0;
566 for (int u=0; u<3; u++)
567 {
568 for (int v=0; v<3; v++)
569 {
570 const real_t ku_iv = k==u && i==v ? 1.0 : 0.0;
571 const real_t ik_uv = i==k && u==v ? 1.0 : 0.0;
572 const real_t kv_iu = k==v && i==u ? 1.0 : 0.0;
573 x2(k,l) += 2.0*(2.*ku_iv-ik_uv-kv_iu)*Jpt(v,j)*Jpt(u,l);
574 }
575 }
576 }
577 }
578 // x3_ijkl = -2 B_ik δ_jl
579 B[0] = J[0]*J[0] + J[3]*J[3] + J[6]*J[6];
580 B[1] = J[1]*J[1] + J[4]*J[4] + J[7]*J[7];
581 B[2] = J[2]*J[2] + J[5]*J[5] + J[8]*J[8];
582 B[3] = J[0]*J[1] + J[3]*J[4] + J[6]*J[7]; // B(0,1)
583 B[4] = J[0]*J[2] + J[3]*J[5] + J[6]*J[8]; // B(0,2)
584 B[5] = J[1]*J[2] + J[4]*J[5] + J[7]*J[8]; // B(1,2)
585 const real_t b_p[9] =
586 {
587 B[0], B[3], B[4],
588 B[3], B[1], B[5],
589 B[4], B[5], B[2]
590 };
591 ConstDeviceMatrix b(b_p,3,3);
592 for (int k=0; k<3; k++)
593 {
594 for (int l=0; l<3; l++)
595 {
596 const real_t jl = j==l ? 1.0 : 0.0;
597 x3(k,l) = -2.0 * b(i,k) * jl;
598 }
599 }
600 // ddI2 = x1 + x2 + x3
601 DeviceMatrix ddi2(ddI2,3,3);
602 for (int k=0; k<3; k++)
603 {
604 for (int l=0; l<3; l++)
605 {
606 ddi2(k,l) = x1(k,l) + x2(k,l) + x3(k,l);
607 }
608 }
609 return ddI2;
610 }
611
612 // ddI2b = X1 + X2 + X3
613 // X1_ijkl = 16/9 det(J)^{-10/3} I2 dI3b_ij dI3b_kl +
614 // 4/3 det(J)^{-10/3} I2 dI3b_il dI3b_kj
615 // X2_ijkl = -4/3 det(J)^{-7/3} (dI2_ij dI3b_kl + dI2_kl dI3b_ij)
616 // X3_ijkl = det(J)^{-4/3} ddI2_ijkl
617 MFEM_HOST_DEVICE inline real_t *Get_ddI2b(int i, int j)
618 {
619 real_t X1_p[9], X2_p[9], X3_p[9];
620 // X1_ijkl = 16/9 det(J)^{-10/3} I2 dI3b_ij dI3b_kl +
621 // 4/3 det(J)^{-10/3} I2 dI3b_il dI3b_kj
622 real_t sign_detJ;
623 DeviceMatrix X1(X1_p,3,3);
624 const real_t I3b_p = Get_I3b_p(); // I3b^{-2/3}
625 const real_t I3b = Get_I3b(sign_detJ); // det(J)
626 const real_t I2 = Get_I2();
627 const real_t I3b_p43 = I3b_p*I3b_p;
628 const real_t I3b_p73 = I3b_p*I3b_p/I3b;
629 const real_t I3b_p103 = I3b_p*I3b_p/(I3b*I3b);
630 ConstDeviceMatrix di3b(Get_dI3b(sign_detJ),3,3);
631 for (int k=0; k<3; k++)
632 {
633 for (int l=0; l<3; l++)
634 {
635 const real_t up = (16./9.)*I3b_p103*I2*di3b(i,j)*di3b(k,l);
636 const real_t down = (4./3.)*I3b_p103*I2*di3b(i,l)*di3b(k,j);
637 X1(k,l) = up + down;
638 }
639 }
640 // X2_ijkl = -4/3 det(J)^{-7/3} (dI2_ij dI3b_kl + dI2_kl dI3b_ij)
641 DeviceMatrix X2(X2_p,3,3);
642 ConstDeviceMatrix di2(Get_dI2(),3,3);
643 for (int k=0; k<3; k++)
644 {
645 for (int l=0; l<3; l++)
646 {
647 X2(k,l) = -(4./3.)*I3b_p73*(di2(i,j)*di3b(k,l)+di2(k,l)*di3b(i,j));
648 }
649 }
650 // X3_ijkl = det(J)^{-4/3} ddI2_ijkl
651 DeviceMatrix X3(X3_p,3,3);
652 ConstDeviceMatrix ddi2(Get_ddI2(i,j),3,3);
653 for (int k=0; k<3; k++)
654 {
655 for (int l=0; l<3; l++)
656 {
657 X3(k,l) = I3b_p43 * ddi2(k,l);
658 }
659 }
660 // ddI2b = X1 + X2 + X3
661 DeviceMatrix ddi2b(ddI2b,3,3);
662 for (int k=0; k<3; k++)
663 {
664 for (int l=0; l<3; l++)
665 {
666 ddi2b(k,l) = X1(k,l) + X2(k,l) + X3(k,l);
667 }
668 }
669 return ddI2b;
670 }
671
672 // dI3b = adj(J)^T
673 // ddI3b_ijkl = (1/I3b) (δ_ks δ_it - δ_kt δ_si) dI3b_tj dI3b_sl
674 MFEM_HOST_DEVICE inline real_t *Get_ddI3b(int i, int j)
675 {
676 const real_t c1 = 1./Get_I3b();
677 ConstDeviceMatrix di3b(dI3b,3,3);
678 DeviceMatrix ddi3b(ddI3b,3,3);
679 for (int k=0; k<3; k++)
680 {
681 for (int l=0; l<3; l++)
682 {
683 ddi3b(k,l) = 0.0;
684 for (int s=0; s<3; s++)
685 {
686 for (int t=0; t<3; t++)
687 {
688 const real_t ks_it = k==s && i==t ? 1.0 : 0.0;
689 const real_t kt_si = k==t && s==i ? 1.0 : 0.0;
690 ddi3b(k,l) += c1*(ks_it-kt_si)*di3b(t,j)*di3b(s,l);
691 }
692 }
693 }
694 }
695 return ddI3b;
696 }
697};
698
699} // namespace kernels
700
701} // namespace mfem
702
703#endif // MFEM_DINVARIANTS_HPP
A basic generic Tensor class, appropriate for use on the GPU.
Definition dtensor.hpp:84
MFEM_HOST_DEVICE Buffers & dI2(real_t *b)
MFEM_HOST_DEVICE Buffers & dI2b(real_t *b)
MFEM_HOST_DEVICE Buffers & ddI2b(real_t *b)
MFEM_HOST_DEVICE Buffers & J(const real_t *b)
MFEM_HOST_DEVICE Buffers & ddI2(real_t *b)
MFEM_HOST_DEVICE Buffers & dI1(real_t *b)
MFEM_HOST_DEVICE Buffers & ddI1b(real_t *b)
MFEM_HOST_DEVICE Buffers & ddI1(real_t *b)
MFEM_HOST_DEVICE Buffers & dI1b(real_t *b)
MFEM_HOST_DEVICE real_t * Get_ddI2b(int i, int j)
MFEM_HOST_DEVICE real_t * Get_dI2()
MFEM_HOST_DEVICE real_t Get_I2()
MFEM_HOST_DEVICE InvariantsEvaluator2D(Buffers &b)
MFEM_HOST_DEVICE real_t * Get_ddI1b(int i, int j)
MFEM_HOST_DEVICE real_t * Get_dI2b()
MFEM_HOST_DEVICE real_t * Get_ddI2(int i, int j)
MFEM_HOST_DEVICE real_t Get_I2b()
MFEM_HOST_DEVICE real_t Get_I1()
MFEM_HOST_DEVICE real_t Get_I2b(real_t &sign_detJ)
MFEM_HOST_DEVICE real_t * Get_ddI1(int i, int j)
MFEM_HOST_DEVICE real_t * Get_dI1()
MFEM_HOST_DEVICE real_t * Get_dI1b()
MFEM_HOST_DEVICE real_t Get_I1b()
MFEM_HOST_DEVICE Buffers & dI2(real_t *b)
MFEM_HOST_DEVICE Buffers & ddI1(real_t *b)
MFEM_HOST_DEVICE Buffers & J(const real_t *b)
MFEM_HOST_DEVICE Buffers & B(real_t *b)
MFEM_HOST_DEVICE Buffers & ddI2(real_t *b)
MFEM_HOST_DEVICE Buffers & dI1(real_t *b)
MFEM_HOST_DEVICE Buffers & dI3b(real_t *b)
MFEM_HOST_DEVICE Buffers & dI2b(real_t *b)
MFEM_HOST_DEVICE Buffers & dI1b(real_t *b)
MFEM_HOST_DEVICE Buffers & ddI2b(real_t *b)
MFEM_HOST_DEVICE Buffers & ddI1b(real_t *b)
MFEM_HOST_DEVICE Buffers & ddI3b(real_t *b)
MFEM_HOST_DEVICE real_t Get_I3()
MFEM_HOST_DEVICE real_t Get_I3b(real_t &sign_detJ)
MFEM_HOST_DEVICE real_t Get_I3b_p()
MFEM_HOST_DEVICE real_t * Get_dI2()
MFEM_HOST_DEVICE real_t * Get_dI1b()
MFEM_HOST_DEVICE real_t * Get_dI3b(const real_t sign_detJ)
MFEM_HOST_DEVICE void Get_B_offd()
MFEM_HOST_DEVICE real_t * Get_ddI2b(int i, int j)
MFEM_HOST_DEVICE real_t Get_I3b()
MFEM_HOST_DEVICE real_t Get_I1b()
MFEM_HOST_DEVICE real_t * Get_ddI2(int i, int j)
MFEM_HOST_DEVICE real_t * Get_ddI1(int i, int j)
MFEM_HOST_DEVICE real_t Get_I1()
MFEM_HOST_DEVICE real_t * Get_dI1()
MFEM_HOST_DEVICE real_t * Get_dI2b()
MFEM_HOST_DEVICE InvariantsEvaluator3D(Buffers &b)
MFEM_HOST_DEVICE real_t * Get_ddI1b(int i, int j)
MFEM_HOST_DEVICE real_t Get_I3b_p(real_t &sign_detJ)
MFEM_HOST_DEVICE real_t Get_I2b()
MFEM_HOST_DEVICE real_t Get_I2()
MFEM_HOST_DEVICE real_t * Get_ddI3b(int i, int j)
const real_t alpha
Definition ex15.cpp:369
real_t b
Definition lissajous.cpp:42
real_t u(const Vector &xvec)
Definition lor_mms.hpp:22
float real_t
Definition config.hpp:46