b2api
B2000++ API Reference Manual, VERSION 4.6
 
Loading...
Searching...
No Matches
b2tensor_transformation.H
Go to the documentation of this file.
1//------------------------------------------------------------------------
2// b2tensor_transformation.H --
3//
4//
5// written by Thomas Ludwig
6// Neda Ebrahimi Pour <neda.ebrahimipour@dlr.de>
7//
8// (c) 2017 SMR Engineering & Development SA
9// 2502 Bienne, Switzerland
10//
11// (c) 2023 Deutsches Zentrum für Luft- und Raumfahrt (DLR) e.V.
12// Linder Höhe, 51147 Köln
13//
14// All Rights Reserved. Proprietary source code. The contents of
15// this file may not be disclosed to third parties, copied or
16// duplicated in any form, in whole or in part, without the prior
17// written permission of SMR.
18//------------------------------------------------------------------------
19
20#ifndef B2_TENSOR_TRANSFORMATION_H_
21#define B2_TENSOR_TRANSFORMATION_H_
22
23#include <algorithm>
24
25#include "utils/b2linear_algebra.H"
27
30
33
47
51
56
68
69namespace b2000 {
70
80template <typename T>
81inline void get_cartesian_base(const T base[3][3], T cartesian_base[3][3]) {
82 outer_product_3(base[0], base[1], cartesian_base[2]);
83 normalise_3(cartesian_base[2]);
84 copy_3(base[0], cartesian_base[0]);
85 normalise_3(cartesian_base[0]);
86 outer_product_3(cartesian_base[2], cartesian_base[0], cartesian_base[1]);
87}
88
89template <typename T>
90inline void get_base_opposite_variance(const T base[3][3], T base_ov[3][3]) {
91 transposed_invert_3_3(base, base_ov);
92}
93
94template <typename T>
95inline void get_base_opposite_variance(const T base[2][2], T base_ov[2][2]) {
96 transposed_invert_2_2(base, base_ov);
97}
98
99template <typename T>
100inline void transform_strain(const T Gab[3][3], const T strain_A[6], T strain_B[6]) {
101 const T EEA[3][3] = {
102 {strain_A[0], .5 * strain_A[3], .5 * strain_A[5]},
103 {.5 * strain_A[3], strain_A[1], .5 * strain_A[4]},
104 {.5 * strain_A[5], .5 * strain_A[4], strain_A[2]},
105 };
106 T EEB[3][3] = {};
107 for (int i = 0; i != 3; ++i) {
108 for (int j = 0; j != 3; ++j) {
109 for (int a = 0; a != 3; ++a) {
110 for (int b = 0; b != 3; ++b) { EEB[i][j] += EEA[a][b] * Gab[a][i] * Gab[b][j]; }
111 }
112 }
113 }
114 strain_B[0] = EEB[0][0];
115 strain_B[1] = EEB[1][1];
116 strain_B[2] = EEB[2][2];
117 strain_B[3] = EEB[0][1] + EEB[1][0];
118 strain_B[4] = EEB[1][2] + EEB[2][1];
119 strain_B[5] = EEB[0][2] + EEB[2][0];
120}
121
122template <typename T>
123inline void transform_strain(const T Gab[2][2], const T strain_A[3], T strain_B[3]) {
124 const T EEA[2][2] = {
125 {strain_A[0], .5 * strain_A[2]},
126 {.5 * strain_A[2], strain_A[1]},
127 };
128 T EEB[2][2] = {};
129 for (int i = 0; i != 2; ++i) {
130 for (int j = 0; j != 2; ++j) {
131 for (int a = 0; a != 2; ++a) {
132 for (int b = 0; b != 2; ++b) { EEB[i][j] += EEA[a][b] * Gab[a][i] * Gab[b][j]; }
133 }
134 }
135 }
136 strain_B[0] = EEB[0][0];
137 strain_B[1] = EEB[1][1];
138 strain_B[2] = EEB[0][1] + EEB[1][0];
139}
140
141template <typename T>
142inline void transform_strain_from_base_A_to_base_B(
143 const T base_A[3][3], const T base_B[3][3], const T strain_A[6], T strain_B[6]) {
144 T base_A_ov[3][3];
145 get_base_opposite_variance(base_A, base_A_ov);
146 T Gab[3][3] = {};
147 for (int i = 0; i != 3; ++i) {
148 for (int j = 0; j != 3; ++j) { Gab[i][j] = dot_3(base_A_ov[i], base_B[j]); }
149 }
150 transform_strain(Gab, strain_A, strain_B);
151}
152
153template <typename T>
154inline void transform_strain_from_base_A_to_base_B(
155 const T base_A[2][2], const T base_B[2][2], const T strain_A[3], T strain_B[3]) {
156 T base_A_ov[2][2];
157 get_base_opposite_variance(base_A, base_A_ov);
158 T Gab[2][2] = {};
159 for (int i = 0; i != 2; ++i) {
160 for (int j = 0; j != 2; ++j) { Gab[i][j] = dot_2(base_A_ov[i], base_B[j]); }
161 }
162 transform_strain(Gab, strain_A, strain_B);
163}
164
165template <typename T>
166inline void transform_strain_from_base_A_ov_to_base_B(
167 const T base_A_ov[3][3], const T base_B[3][3], const T strain_A[6], T strain_B[6]) {
168 T Gab[3][3] = {};
169 for (int i = 0; i != 3; ++i) {
170 for (int j = 0; j != 3; ++j) { Gab[i][j] = dot_3(base_A_ov[i], base_B[j]); }
171 }
172 transform_strain(Gab, strain_A, strain_B);
173}
174
175template <typename T>
176inline void transform_strain_from_base_A_ov_to_base_B(
177 const T base_A_ov[2][2], const T base_B[2][2], const T strain_A[3], T strain_B[3]) {
178 T Gab[2][2] = {};
179 for (int i = 0; i != 2; ++i) {
180 for (int j = 0; j != 2; ++j) { Gab[i][j] = dot_2(base_A_ov[i], base_B[j]); }
181 }
182 transform_strain(Gab, strain_A, strain_B);
183}
184
185template <typename T>
186inline void transform_strain_from_base_A_to_I(
187 const T base_A[3][3], const T strain_A[6], T strain_B[6]) {
188 T base_A_ov[3][3];
189 get_base_opposite_variance(base_A, base_A_ov);
190 transform_strain(base_A_ov, strain_A, strain_B);
191}
192
193template <typename T>
194inline void transform_strain_from_base_A_to_I(
195 const T base_A[2][2], const T strain_A[3], T strain_B[3]) {
196 T base_A_ov[2][2];
197 get_base_opposite_variance(base_A, base_A_ov);
198 transform_strain(base_A_ov, strain_A, strain_B);
199}
200
201template <typename T>
202inline void transform_strain_from_base_A_ov_to_I(
203 const T base_A_ov[3][3], const T strain_A[6], T strain_B[6]) {
204 transform_strain(base_A_ov, strain_A, strain_B);
205}
206
207template <typename T>
208inline void transform_strain_from_base_A_ov_to_I(
209 const T base_A_ov[2][2], const T strain_A[3], T strain_B[3]) {
210 transform_strain(base_A_ov, strain_A, strain_B);
211}
212
213template <typename T>
214inline void transform_strain_from_I_to_base_B(
215 const T base_B[3][3], const T strain_A[6], T strain_B[6]) {
216 T Gab[3][3];
217 transpose_3_3(base_B, Gab);
218 transform_strain(Gab, strain_A, strain_B);
219}
220
221template <typename T>
222inline void transform_strain_from_I_to_base_B(
223 const T base_B[2][2], const T strain_A[3], T strain_B[3]) {
224 T Gab[2][2];
225 transpose_2_2(base_B, Gab);
226 transform_strain(Gab, strain_A, strain_B);
227}
228
229template <typename T>
230inline void transform_stress(const T Gab[3][3], const T stress_A[6], T stress_B[6]) {
231 const T SSa[3][3] = {
232 {stress_A[0], stress_A[3], stress_A[5]},
233 {stress_A[3], stress_A[1], stress_A[4]},
234 {stress_A[5], stress_A[4], stress_A[2]},
235 };
236 T SSb[3][3] = {};
237 for (int i = 0; i != 3; ++i) {
238 for (int j = 0; j != 3; ++j) {
239 for (int a = 0; a != 3; ++a) {
240 for (int b = 0; b != 3; ++b) { SSb[i][j] += SSa[a][b] * Gab[a][i] * Gab[b][j]; }
241 }
242 }
243 }
244 stress_B[0] = SSb[0][0];
245 stress_B[1] = SSb[1][1];
246 stress_B[2] = SSb[2][2];
247 stress_B[3] = .5 * (SSb[0][1] + SSb[1][0]);
248 stress_B[4] = .5 * (SSb[1][2] + SSb[2][1]);
249 stress_B[5] = .5 * (SSb[0][2] + SSb[2][0]);
250}
251
252template <typename T>
253inline void transform_stress(const T Gab[2][2], const T stress_A[3], T stress_B[3]) {
254 const T SSa[3][3] = {
255 {stress_A[0], stress_A[2]},
256 {stress_A[2], stress_A[1]},
257 };
258 T SSb[2][2] = {};
259 for (int i = 0; i != 2; ++i) {
260 for (int j = 0; j != 2; ++j) {
261 for (int a = 0; a != 2; ++a) {
262 for (int b = 0; b != 2; ++b) { SSb[i][j] += SSa[a][b] * Gab[a][i] * Gab[b][j]; }
263 }
264 }
265 }
266 stress_B[0] = SSb[0][0];
267 stress_B[1] = SSb[1][1];
268 stress_B[2] = .5 * (SSb[0][1] + SSb[1][0]);
269}
270
271template <typename T>
272inline void transform_stress_from_base_A_to_base_B(
273 const T base_A[3][3], const T base_B[3][3], const T stress_A[6], T stress_B[6]) {
274 T base_A_ov[3][3];
275 get_base_opposite_variance(base_A, base_A_ov);
276 T Gab[3][3] = {};
277 for (int i = 0; i != 3; ++i) {
278 for (int j = 0; j != 3; ++j) { Gab[i][j] = dot_3(base_A_ov[i], base_B[j]); }
279 }
280 transform_stress(Gab, stress_A, stress_B);
281}
282
283template <typename T>
284inline void transform_stress_from_base_A_to_base_B(
285 const T base_A[2][2], const T base_B[2][2], const T stress_A[3], T stress_B[3]) {
286 T base_A_ov[2][2];
287 get_base_opposite_variance(base_A, base_A_ov);
288 T Gab[2][2] = {};
289 for (int i = 0; i != 2; ++i) {
290 for (int j = 0; j != 2; ++j) { Gab[i][j] = dot_2(base_A_ov[i], base_B[j]); }
291 }
292 transform_stress(Gab, stress_A, stress_B);
293}
294
295template <typename T>
296inline void transform_stress_from_base_A_ov_to_base_B(
297 const T base_A_ov[3][3], const T base_B[3][3], const T stress_A[6], T stress_B[6]) {
298 T Gab[3][3] = {};
299 for (int i = 0; i != 3; ++i) {
300 for (int j = 0; j != 3; ++j) { Gab[i][j] = dot_3(base_A_ov[i], base_B[j]); }
301 }
302 transform_stress(Gab, stress_A, stress_B);
303}
304
305template <typename T>
306inline void transform_stress_from_base_A_ov_to_base_B(
307 const T base_A_ov[2][2], const T base_B[2][2], const T stress_A[3], T stress_B[3]) {
308 T Gab[2][2] = {};
309 for (int i = 0; i != 2; ++i) {
310 for (int j = 0; j != 2; ++j) { Gab[i][j] = dot_2(base_A_ov[i], base_B[j]); }
311 }
312 transform_stress(Gab, stress_A, stress_B);
313}
314
315template <typename T>
316inline void transform_stress_from_base_A_to_I(
317 const T base_A[3][3], const T stress_A[6], T stress_B[6]) {
318 T base_A_ov[3][3];
319 get_base_opposite_variance(base_A, base_A_ov);
320 transform_stress(base_A_ov, stress_A, stress_B);
321}
322
323template <typename T>
324inline void transform_stress_from_base_A_to_I(
325 const T base_A[2][2], const T stress_A[3], T stress_B[3]) {
326 T base_A_ov[2][2];
327 get_base_opposite_variance(base_A, base_A_ov);
328 transform_stress(base_A_ov, stress_A, stress_B);
329}
330
331template <typename T>
332inline void transform_stress_from_base_A_ov_to_I(
333 const T base_A_ov[3][3], const T stress_A[6], T stress_B[6]) {
334 transform_stress(base_A_ov, stress_A, stress_B);
335}
336
337template <typename T>
338inline void transform_stress_from_base_A_ov_to_I(
339 const T base_A_ov[2][2], const T stress_A[3], T stress_B[3]) {
340 transform_stress(base_A_ov, stress_A, stress_B);
341}
342
343template <typename T>
344inline void transform_stress_from_I_to_base_B(
345 const T base_B[3][3], const T stress_A[6], T stress_B[6]) {
346 T Gab[3][3];
347 transpose_3_3(base_B, Gab);
348 transform_stress(Gab, stress_A, stress_B);
349}
350
351template <typename T>
352inline void transform_stress_from_I_to_base_B(
353 const T base_B[2][2], const T stress_A[3], T stress_B[3]) {
354 T Gab[2][2];
355 transpose_2_2(base_B, Gab);
356 transform_stress(Gab, stress_A, stress_B);
357}
358
359template <typename T>
360inline void transform_constitutive_tensor(
361 const T Gab[3][3], const T d_stress_d_strain_A[21], T d_stress_d_strain_B[21]) {
362 b2linalg::Matrix<T, b2linalg::Mlower_packed_constref> CCa(6, d_stress_d_strain_A);
363 b2linalg::Matrix<T, b2linalg::Mlower_packed_ref> CCb(6, d_stress_d_strain_B);
364 const int ia[6] = {0, 1, 2, 0, 1, 0};
365 const int ib[6] = {0, 1, 2, 1, 2, 2};
366
367 // Maps tensor indices a*3+b to index into vector.
368 const int ii[9] = {0, 3, 5, 3, 1, 4, 5, 4, 2};
369
370 for (int i = 0; i != 6; ++i) {
371 for (int j = 0; j <= i; ++j) {
372 CCb(i, j) = 0;
373 for (int ab = 0; ab != 9; ++ab) {
374 const int a = ab % 3;
375 const int b = ab / 3;
376 for (int cd = 0; cd != 9; ++cd) {
377 const int c = cd % 3;
378 const int d = cd / 3;
379 CCb(i, j) += CCa(ii[ab], ii[cd]) * Gab[a][ia[i]] * Gab[b][ib[i]] * Gab[c][ia[j]]
380 * Gab[d][ib[j]];
381 }
382 }
383 }
384 }
385}
386
387template <typename T>
388inline void transform_constitutive_tensor(
389 const T Gab[2][2], const T d_stress_d_strain_A[6], T d_stress_d_strain_B[6]) {
390 b2linalg::Matrix<T, b2linalg::Mlower_packed_constref> CCa(3, d_stress_d_strain_A);
391 b2linalg::Matrix<T, b2linalg::Mlower_packed_ref> CCb(3, d_stress_d_strain_B);
392 const int ia[3] = {0, 1, 0};
393 const int ib[3] = {0, 1, 1};
394
395 // Maps tensor indices a*2+b to index into vector.
396 const int ii[4] = {0, 2, 2, 1};
397
398 for (int i = 0; i != 3; ++i) {
399 for (int j = 0; j <= i; ++j) {
400 CCb(i, j) = 0;
401 for (int ab = 0; ab != 4; ++ab) {
402 const int a = ab % 2;
403 const int b = ab / 2;
404 for (int cd = 0; cd != 4; ++cd) {
405 const int c = cd % 2;
406 const int d = cd / 2;
407 CCb(i, j) += CCa(ii[ab], ii[cd]) * Gab[a][ia[i]] * Gab[b][ib[i]] * Gab[c][ia[j]]
408 * Gab[d][ib[j]];
409 }
410 }
411 }
412 }
413}
414
415template <typename T>
416inline void transform_constitutive_tensor_from_base_A_to_base_B(
417 const T base_A[3][3], const T base_B[3][3], const T d_stress_d_strain_A[21],
418 T d_stress_d_strain_B[21]) {
419 T base_A_ov[3][3];
420 get_base_opposite_variance(base_A, base_A_ov);
421 T Gab[3][3] = {};
422 for (int i = 0; i != 3; ++i) {
423 for (int j = 0; j != 3; ++j) { Gab[i][j] = dot_3(base_A_ov[i], base_B[j]); }
424 }
425 transform_constitutive_tensor(Gab, d_stress_d_strain_A, d_stress_d_strain_B);
426}
427
428template <typename T>
429inline void transform_constitutive_tensor_from_base_A_to_base_B(
430 const T base_A[2][2], const T base_B[2][2], const T d_stress_d_strain_A[6],
431 T d_stress_d_strain_B[6]) {
432 T base_A_ov[2][2];
433 get_base_opposite_variance(base_A, base_A_ov);
434 T Gab[2][2] = {};
435 for (int i = 0; i != 2; ++i) {
436 for (int j = 0; j != 2; ++j) { Gab[i][j] = dot_2(base_A_ov[i], base_B[j]); }
437 }
438 transform_constitutive_tensor(Gab, d_stress_d_strain_A, d_stress_d_strain_B);
439}
440
441template <typename T>
442inline void transform_constitutive_tensor_from_base_A_ov_to_base_B(
443 const T base_A_ov[3][3], const T base_B[3][3], const T d_stress_d_strain_A[21],
444 T d_stress_d_strain_B[21]) {
445 T Gab[3][3] = {};
446 for (int i = 0; i != 3; ++i) {
447 for (int j = 0; j != 3; ++j) { Gab[i][j] = dot_3(base_A_ov[i], base_B[j]); }
448 }
449 transform_constitutive_tensor(Gab, d_stress_d_strain_A, d_stress_d_strain_B);
450}
451
452template <typename T>
453inline void transform_constitutive_tensor_from_base_A_ov_to_base_B(
454 const T base_A_ov[2][2], const T base_B[2][2], const T d_stress_d_strain_A[6],
455 T d_stress_d_strain_B[6]) {
456 T Gab[2][2] = {};
457 for (int i = 0; i != 2; ++i) {
458 for (int j = 0; j != 2; ++j) { Gab[i][j] = dot_2(base_A_ov[i], base_B[j]); }
459 }
460 transform_constitutive_tensor(Gab, d_stress_d_strain_A, d_stress_d_strain_B);
461}
462
463template <typename T>
464inline void transform_constitutive_tensor_from_base_A_to_I(
465 const T base_A[3][3], const T d_stress_d_strain_A[21], T d_stress_d_strain_B[21]) {
466 T base_A_ov[3][3];
467 get_base_opposite_variance(base_A, base_A_ov);
468 transform_constitutive_tensor(base_A_ov, d_stress_d_strain_A, d_stress_d_strain_B);
469}
470
471template <typename T>
472inline void transform_constitutive_tensor_from_base_A_to_I(
473 const T base_A[2][2], const T d_stress_d_strain_A[6], T d_stress_d_strain_B[6]) {
474 T base_A_ov[2][2];
475 get_base_opposite_variance(base_A, base_A_ov);
476 transform_constitutive_tensor(base_A_ov, d_stress_d_strain_A, d_stress_d_strain_B);
477}
478
479template <typename T>
480inline void transform_constitutive_tensor_from_base_A_ov_to_I(
481 const T base_A_ov[3][3], const T d_stress_d_strain_A[21], T d_stress_d_strain_B[21]) {
482 transform_constitutive_tensor(base_A_ov, d_stress_d_strain_A, d_stress_d_strain_B);
483}
484
485template <typename T>
486inline void transform_constitutive_tensor_from_base_A_ov_to_I(
487 const T base_A_ov[2][2], const T d_stress_d_strain_A[6], T d_stress_d_strain_B[6]) {
488 transform_constitutive_tensor(base_A_ov, d_stress_d_strain_A, d_stress_d_strain_B);
489}
490
491template <typename T>
492inline void transform_constitutive_tensor_from_I_to_base_B(
493 const T base_B[3][3], const T d_stress_d_strain_A[21], T d_stress_d_strain_B[21]) {
494 T Gab[3][3] = {};
495 transpose_3_3(base_B, Gab);
496 transform_constitutive_tensor(Gab, d_stress_d_strain_A, d_stress_d_strain_B);
497}
498
499template <typename T>
500inline void transform_constitutive_tensor_from_I_to_base_B(
501 const T base_B[2][2], const T d_stress_d_strain_A[6], T d_stress_d_strain_B[6]) {
502 T Gab[2][2] = {};
503 transpose_2_2(base_B, Gab);
504 transform_constitutive_tensor(Gab, d_stress_d_strain_A, d_stress_d_strain_B);
505}
506
507template <typename T>
508inline void transform_shell_strain(const T Gab[3][3], const T strain_A[8], T strain_B[8]) {
509 // Transform the strain separately for the membrane and bending part.
510 for (int ii = 0; ii != 2; ++ii) {
511 const int o = 3 * ii;
512
513 // Copy the strain into a 3x3 matrix.
514 const T EEA[3][3] = {
515 {strain_A[o + 0], .5 * strain_A[o + 2], 0},
516 {.5 * strain_A[o + 2], strain_A[o + 1], 0},
517 {0, 0, 0},
518 };
519
520 // Transform the strain.
521 T EEB[3][3] = {};
522 for (int i = 0; i != 3; ++i) {
523 for (int j = 0; j != 3; ++j) {
524 for (int a = 0; a != 3; ++a) {
525 for (int b = 0; b != 3; ++b) { EEB[i][j] += EEA[a][b] * Gab[a][i] * Gab[b][j]; }
526 }
527 }
528 }
529
530 // Copy the transformed strain from the 3x3 matrix to the vector.
531 strain_B[o + 0] = EEB[0][0];
532 strain_B[o + 1] = EEB[1][1];
533 strain_B[o + 2] = EEB[0][1] + EEB[1][0];
534 }
535
536 // Transform the transverse-shear part
537 {
538 // Copy the strain into a 3x3 matrix.
539 const T EEA[3][3] = {
540 {0, 0, .5 * strain_A[7]},
541 {0, 0, .5 * strain_A[6]},
542 {.5 * strain_A[7], .5 * strain_A[6], 0},
543 };
544
545 // Transform the strain.
546 T EEB[3][3] = {};
547 for (int i = 0; i != 3; ++i) {
548 for (int j = 0; j != 3; ++j) {
549 for (int a = 0; a != 3; ++a) {
550 for (int b = 0; b != 3; ++b) { EEB[i][j] += EEA[a][b] * Gab[a][i] * Gab[b][j]; }
551 }
552 }
553 }
554
555 // Copy the transformed strain from the 3x3 matrix to the vector.
556 strain_B[6] = EEB[1][2] + EEB[2][1];
557 strain_B[7] = EEB[0][2] + EEB[2][0];
558 }
559}
560
561template <typename T>
562inline void transform_shell_strain_from_base_A_to_base_B(
563 const T base_A[3][3], const T base_B[3][3], const T strain_A[8], T strain_B[8]) {
564 T base_A_ov[3][3];
565 get_base_opposite_variance(base_A, base_A_ov);
566 T Gab[3][3] = {};
567 for (int i = 0; i != 3; ++i) {
568 for (int j = 0; j != 3; ++j) { Gab[i][j] = dot_3(base_A_ov[i], base_B[j]); }
569 }
570 transform_shell_strain(Gab, strain_A, strain_B);
571}
572
573template <typename T>
574inline void transform_shell_strain_from_base_A_ov_to_base_B(
575 const T base_A_ov[3][3], const T base_B[3][3], const T strain_A[8], T strain_B[8]) {
576 T Gab[3][3] = {};
577 for (int i = 0; i != 3; ++i) {
578 for (int j = 0; j != 3; ++j) { Gab[i][j] = dot_3(base_A_ov[i], base_B[j]); }
579 }
580 transform_shell_strain(Gab, strain_A, strain_B);
581}
582
583template <typename T>
584inline void transform_shell_strain_from_base_A_to_I(
585 const T base_A[3][3], const T strain_A[8], T strain_B[8]) {
586 T base_A_ov[3][3];
587 get_base_opposite_variance(base_A, base_A_ov);
588 transform_shell_strain(base_A_ov, strain_A, strain_B);
589}
590
591template <typename T>
592inline void transform_shell_strain_from_base_A_ov_to_I(
593 const T base_A_ov[3][3], const T strain_A[8], T strain_B[8]) {
594 transform_shell_strain(base_A_ov, strain_A, strain_B);
595}
596
597template <typename T>
598inline void transform_shell_strain_from_I_to_base_B(
599 const T base_B[3][3], const T strain_A[8], T strain_B[8]) {
600 T Gab[3][3];
601 transpose_3_3(base_B, Gab);
602 transform_shell_strain(Gab, strain_A, strain_B);
603}
604
605template <typename T>
606inline void transform_shell_stress(const T Gab[3][3], const T stress_A[8], T stress_B[8]) {
607 // Transform the stress separately for the membrane and bending part.
608 for (int ii = 0; ii != 2; ++ii) {
609 const int o = 3 * ii;
610
611 // Copy the stress into a 3x3 matrix.
612 const T SSA[3][3] = {
613 {stress_A[o + 0], stress_A[o + 2], 0},
614 {stress_A[o + 2], stress_A[o + 1], 0},
615 {0, 0, 0},
616 };
617
618 // Transform the stress.
619 T SSB[3][3] = {};
620 for (int i = 0; i != 3; ++i) {
621 for (int j = 0; j != 3; ++j) {
622 for (int a = 0; a != 3; ++a) {
623 for (int b = 0; b != 3; ++b) { SSB[i][j] += SSA[a][b] * Gab[a][i] * Gab[b][j]; }
624 }
625 }
626 }
627
628 // Copy the transformed stress from the 3x3 matrix to the vector.
629 stress_B[o + 0] = SSB[0][0];
630 stress_B[o + 1] = SSB[1][1];
631 stress_B[o + 2] = .5 * (SSB[0][1] + SSB[1][0]);
632 }
633
634 // Transform the transverse-shear part
635 {
636 // Copy the stress into a 3x3 matrix.
637 const T SSA[3][3] = {
638 {0, 0, stress_A[7]},
639 {0, 0, stress_A[6]},
640 {stress_A[7], stress_A[6], 0},
641 };
642
643 // Transform the stress.
644 T SSB[3][3] = {};
645 for (int i = 0; i != 3; ++i) {
646 for (int j = 0; j != 3; ++j) {
647 for (int a = 0; a != 3; ++a) {
648 for (int b = 0; b != 3; ++b) { SSB[i][j] += SSA[a][b] * Gab[a][i] * Gab[b][j]; }
649 }
650 }
651 }
652
653 // Copy the transformed stress from the 3x3 matrix to the vector.
654 stress_B[6] = .5 * (SSB[1][2] + SSB[2][1]);
655 stress_B[7] = .5 * (SSB[0][2] + SSB[2][0]);
656 }
657}
658
659template <typename T>
660inline void transform_shell_stress_from_base_A_to_base_B(
661 const T base_A[3][3], const T base_B[3][3], const T stress_A[8], T stress_B[8]) {
662 T base_A_ov[3][3];
663 get_base_opposite_variance(base_A, base_A_ov);
664 T Gab[3][3] = {};
665 for (int i = 0; i != 3; ++i) {
666 for (int j = 0; j != 3; ++j) { Gab[i][j] = dot_3(base_A_ov[i], base_B[j]); }
667 }
668 transform_shell_stress(Gab, stress_A, stress_B);
669}
670
671template <typename T>
672inline void transform_shell_stress_from_base_A_ov_to_base_B(
673 const T base_A_ov[3][3], const T base_B[3][3], const T stress_A[8], T stress_B[8]) {
674 T Gab[3][3] = {};
675 for (int i = 0; i != 3; ++i) {
676 for (int j = 0; j != 3; ++j) { Gab[i][j] = dot_3(base_A_ov[i], base_B[j]); }
677 }
678 transform_shell_stress(Gab, stress_A, stress_B);
679}
680
681template <typename T>
682inline void transform_shell_stress_from_base_A_to_I(
683 const T base_A[3][3], const T stress_A[8], T stress_B[8]) {
684 T base_A_ov[3][3];
685 get_base_opposite_variance(base_A, base_A_ov);
686 transform_shell_stress(base_A_ov, stress_A, stress_B);
687}
688
689template <typename T>
690inline void transform_shell_stress_from_base_A_ov_to_I(
691 const T base_A_ov[3][3], const T stress_A[8], T stress_B[8]) {
692 transform_shell_stress(base_A_ov, stress_A, stress_B);
693}
694
695template <typename T>
696inline void transform_shell_stress_from_I_to_base_B(
697 const T base_B[3][3], const T stress_A[8], T stress_B[8]) {
698 T Gab[3][3];
699 transpose_3_3(base_B, Gab);
700 transform_shell_stress(Gab, stress_A, stress_B);
701}
702
703template <typename T>
704inline void transform_shell_constitutive_tensor(
705 const T Gab[3][3], const T d_stress_d_strain_A[36], T d_stress_d_strain_B[36]) {
706 b2linalg::Matrix<T, b2linalg::Mlower_packed_constref> CCa(8, d_stress_d_strain_A);
707 b2linalg::Matrix<T, b2linalg::Mlower_packed_ref> CCb(8, d_stress_d_strain_B);
708
709 // Transform the A, D, B 3x3 matrices separately.
710 for (int ii = 0; ii != 3; ++ii) {
711 const int off_k[3] = {0, 3, 0};
712 const int off_l[3] = {0, 3, 3};
713 const int ind[3] = {0, 1, 3};
714
715 // Copy the 3x3 submatrix to a 6x6 matrix.
716 T tmp_a[21] = {};
717 b2linalg::Matrix<T, b2linalg::Mlower_packed_ref> C_tmp_a(6, &tmp_a[0]);
718 for (int l = 0; l != 3; ++l) {
719 for (int k = l; k != 3; ++k) {
720 C_tmp_a(ind[k], ind[l]) = CCa(off_k[ii] + k, off_l[ii] + l);
721 }
722 }
723
724 // Transform the 6x6 matrix.
725 T tmp_b[21];
726 transform_constitutive_tensor(Gab, tmp_a, tmp_b);
727
728 // Copy the 3x3 submatrix from the transformed 6x6 matrix.
729 b2linalg::Matrix<T, b2linalg::Mlower_packed_constref> C_tmp_b(6, &tmp_b[0]);
730 for (int l = 0; l != 3; ++l) {
731 for (int k = l; k != 3; ++k) {
732 CCb(off_k[ii] + k, off_l[ii] + l) = C_tmp_b(ind[k], ind[l]);
733 }
734 }
735 }
736
737 // Finally transform the transverse-shear part.
738 {
739 // Copy the 2x2 submatrix to a 6x6 matrix.
740 T tmp_a[21] = {};
741 tmp_a[18] = CCa(6, 6);
742 tmp_a[19] = CCa(6, 7);
743 tmp_a[20] = CCa(7, 7);
744
745 // Transform the 6x6 matrix.
746 T tmp_b[21];
747 transform_constitutive_tensor(Gab, tmp_a, tmp_b);
748
749 // Copy the 3x3 submatrix from the transformed 6x6 matrix.
750 CCb(6, 6) = tmp_b[18];
751 CCb(6, 7) = tmp_b[19];
752 CCb(7, 7) = tmp_b[20];
753 }
754}
755
756template <typename T>
757inline void transform_shell_constitutive_tensor_from_base_A_to_base_B(
758 const T base_A[3][3], const T base_B[3][3], const T d_stress_d_strain_A[36],
759 T d_stress_d_strain_B[36]) {
760 T base_A_ov[3][3];
761 get_base_opposite_variance(base_A, base_A_ov);
762 T Gab[3][3] = {};
763 for (int i = 0; i != 3; ++i) {
764 for (int j = 0; j != 3; ++j) { Gab[i][j] = dot_3(base_A_ov[i], base_B[j]); }
765 }
766 transform_shell_constitutive_tensor(Gab, d_stress_d_strain_A, d_stress_d_strain_B);
767}
768
769template <typename T>
770inline void transform_shell_constitutive_tensor_from_base_A_ov_to_base_B(
771 const T base_A_ov[3][3], const T base_B[3][3], const T d_stress_d_strain_A[36],
772 T d_stress_d_strain_B[36]) {
773 T Gab[3][3] = {};
774 for (int i = 0; i != 3; ++i) {
775 for (int j = 0; j != 3; ++j) { Gab[i][j] = dot_3(base_A_ov[i], base_B[j]); }
776 }
777 transform_shell_constitutive_tensor(Gab, d_stress_d_strain_A, d_stress_d_strain_B);
778}
779
780template <typename T>
781inline void transform_shell_constitutive_tensor_from_base_A_to_I(
782 const T base_A[3][3], const T d_stress_d_strain_A[36], T d_stress_d_strain_B[36]) {
783 T base_A_ov[3][3];
784 get_base_opposite_variance(base_A, base_A_ov);
785 transform_shell_constitutive_tensor(base_A_ov, d_stress_d_strain_A, d_stress_d_strain_B);
786}
787
788template <typename T>
789inline void transform_shell_constitutive_tensor_from_base_A_ov_to_I(
790 const T base_A_ov[3][3], const T d_stress_d_strain_A[36], T d_stress_d_strain_B[36]) {
791 transform_shell_constitutive_tensor(base_A_ov, d_stress_d_strain_A, d_stress_d_strain_B);
792}
793
794template <typename T>
795inline void transform_shell_constitutive_tensor_from_I_to_base_B(
796 const T base_B[3][3], const T d_stress_d_strain_A[36], T d_stress_d_strain_B[36]) {
797 T Gab[3][3] = {};
798 transpose_3_3(base_B, Gab);
799 transform_shell_constitutive_tensor(Gab, d_stress_d_strain_A, d_stress_d_strain_B);
800}
801
802} // namespace b2000
803
804#endif // B2_TENSOR_TRANSFORMATION_H_
Contains the base classes for implementing Finite Elements.
Definition b2boundary_condition.H:32
void copy_3(const T1 a[3], T1 b[3])
Definition b2tensor_calculus.H:214
T transposed_invert_3_3(const T a[3][3], T b[3][3])
Definition b2tensor_calculus.H:764
T normalise_3(T a[3])
Definition b2tensor_calculus.H:418
void outer_product_3(const T1 a[3], const T2 b[3], T3 c[3])
Definition b2tensor_calculus.H:389
void transpose_2_2(T1 a[2][2])
Definition b2tensor_calculus.H:623
void get_cartesian_base(const T base[3][3], T cartesian_base[3][3])
Definition b2tensor_transformation.H:81
T transposed_invert_2_2(const T a[2][2], T b[2][2])
Definition b2tensor_calculus.H:795
T dot_3(const T a[3], const T b[3])
Definition b2tensor_calculus.H:328
T dot_2(const T a[2], const T b[2])
Definition b2tensor_calculus.H:346
void transpose_3_3(T1 a[3][3])
Definition b2tensor_calculus.H:615