b2api
B2000++ API Reference Manual, VERSION 4.6
 
Loading...
Searching...
No Matches
b2material_util.H
Go to the documentation of this file.
1//------------------------------------------------------------------------
2// b2material_util.H --
3//
4// Helper classes for elastic material implementations.
5//
6// written by Thomas Ludwig
7// Neda Ebrahimi Pour <neda.ebrahimipour@dlr.de>
8//
9// (c) 2015,2016,2017 SMR Engineering & Development SA
10// 2502 Bienne, Switzerland
11//
12// (c) 2023 Deutsches Zentrum für Luft- und Raumfahrt (DLR) e.V.
13// Linder Höhe, 51147 Köln
14//
15// All Rights Reserved. Proprietary source code. The contents of
16// this file may not be disclosed to third parties, copied or
17// duplicated in any form, in whole or in part, without the prior
18// written permission of SMR.
19//------------------------------------------------------------------------
20
21#ifndef B2_MATERIAL_UTIL_H_
22#define B2_MATERIAL_UTIL_H_
23
24#include <algorithm>
25#include <cmath>
26
27#include "b2domain_database.H"
28#include "model/b2solver.H"
29#include "utils/b2linear_algebra.H"
30#include "utils/b2rtable.H"
32
36
37namespace {
38
39// Multiply by 1/2 the off-diagonal entries of a strain tensor and
40// store it in the gradient_container.
41//
42template <typename T>
43inline void set_field_value_strain(
44 b2000::GradientContainer* gradient_container,
45 const b2000::GradientContainer::FieldDescription& descr, const T strain[6]) {
46 const T strain_storage[6] = {strain[0], strain[1], strain[2],
47 T(.5) * strain[3], T(.5) * strain[4], T(.5) * strain[5]};
48 gradient_container->set_field_value(descr, strain_storage);
49}
50
51template <typename T>
52inline void set_field_value_shell_strain(
53 b2000::GradientContainer* gradient_container,
54 const b2000::GradientContainer::FieldDescription& descr, const T strain[8]) {
55 const T strain_storage[8] = {
56 strain[0], strain[1], strain[2], strain[3],
57 strain[4], strain[5], T(.5) * strain[6], T(.5) * strain[7],
58 };
59 gradient_container->set_field_value(descr, strain_storage);
60}
61
62template <typename T>
63inline void set_field_value_strain_2(
64 b2000::GradientContainer* gradient_container,
65 const b2000::GradientContainer::FieldDescription& descr, const T strain_2d[3],
66 const T strain_normal) {
67 const T strain_storage[6] = {strain_2d[0], strain_2d[1], strain_normal,
68 T(.5) * strain_2d[2], T(0), T(0)};
69 gradient_container->set_field_value(descr, strain_storage);
70}
71
72template <typename T>
73inline void set_field_value_stress_2(
74 b2000::GradientContainer* gradient_container,
75 const b2000::GradientContainer::FieldDescription& descr, const T stress_2d[3],
76 const T stress_normal) {
77 const T stress_storage[6] = {stress_2d[0], stress_2d[1], stress_normal,
78 stress_2d[2], T(0), T(0)};
79 gradient_container->set_field_value(descr, stress_storage);
80}
81
82} // namespace
83
84namespace b2000 { namespace b2dbv3 {
85
90template <typename T>
94
98
101 T M[3][3];
102
106
109 T G[3][3];
110
113 T G_d[3][3];
114
119
124
129
134
139
144
148
152
156
163 ElasticityHelper(const T material_ref[3][3], const T covariant_base[3][3])
164 : has_thermal_expansion(false),
165 has_material_ref(material_ref != 0),
166 has_covariant_base(covariant_base != 0),
167 failure_index(0.) {
168 // Material basis (orthogonal reference frame) and its transpose.
169 if (has_material_ref) {
170 assert(material_ref != 0);
171 std::copy(&material_ref[0][0], &material_ref[0][0] + 9, &M[0][0]);
172 } else {
174 }
175
176 // Element covariant and contravariant basis.
177 if (has_covariant_base) {
178 assert(covariant_base != 0);
179 b2000::copy_3_3(covariant_base, G);
180 b2000::get_base_opposite_variance(G, G_d);
181 } else {
182 // Everything is aligned with the global coordinate system.
185 }
186
187 std::fill_n(strain_gl_bg, 6, 0);
188 std::fill_n(strain_gl_bg_te, 6, 0);
189 std::fill_n(strain_gl_mat, 6, 0);
190 std::fill_n(strain_gl_mat_te, 6, 0);
191 std::fill_n(stress_pk2_bg, 6, 0);
192 std::fill_n(stress_pk2_mat, 6, 0);
193 std::fill_n(stress_cauchy_bg, 6, 0);
194 std::fill_n(stress_cauchy_mat, 6, 0);
195 }
196
214 const bool planestress, const T strain[6], const T temperature, const T alpha[6]) {
215 has_thermal_expansion = false;
216
217 if (strain != 0) {
218 transform_strain_from_base_A_to_I(G, strain, strain_gl_bg);
219 transform_strain_from_I_to_base_B(M, strain_gl_bg, strain_gl_mat);
220 }
221 if (alpha != 0 && temperature != 0) {
223 strain_gl_mat_te[0] = strain_gl_mat[0] - alpha[0] * temperature;
224 strain_gl_mat_te[1] = strain_gl_mat[1] - alpha[1] * temperature;
225 if (planestress) {
226 strain_gl_mat_te[2] = 0; // no valid zz strain
227 } else {
228 strain_gl_mat_te[2] = strain_gl_mat[2] - alpha[2] * temperature;
229 }
230 strain_gl_mat_te[3] = strain_gl_mat[3] - alpha[3] * temperature;
231 strain_gl_mat_te[4] = strain_gl_mat[4] - alpha[4] * temperature;
232 strain_gl_mat_te[5] = strain_gl_mat[5] - alpha[5] * temperature;
233 } else {
235 }
236 }
237
262 const T stress_mat[6], // may be 0
263 const T d_stress_d_strain_mat[21], T stress[6], T d_stress_d_strain[21]) {
264 if (d_stress_d_strain != 0) {
265 assert(d_stress_d_strain_mat != 0);
266 transform_constitutive_tensor_from_base_A_ov_to_base_B(
267 M, G_d, d_stress_d_strain_mat, d_stress_d_strain);
268 }
269
270 //
271 // Calculate the stresses.
272 //
273 if (stress_mat != 0) {
274 std::copy(stress_mat, stress_mat + 6, stress_pk2_mat);
275 } else {
276 // Linear material: Calculate stress from constitutive matrix.
277 assert(d_stress_d_strain_mat != 0);
278 b2linalg::Matrix<T, b2linalg::Mlower_packed_constref> C_mat(6, d_stress_d_strain_mat);
279 b2linalg::Vector<T, b2linalg::Vdense_constref> e_mat(6, strain_gl_mat_te);
280 b2linalg::Vector<T, b2linalg::Vdense_ref> s_mat(6, stress_pk2_mat);
281 s_mat = C_mat * e_mat;
282 }
283 transform_stress_from_base_A_ov_to_I(M, stress_pk2_mat, stress_pk2_bg);
284 if (stress != 0) { transform_stress_from_I_to_base_B(G_d, stress_pk2_bg, stress); }
285 }
286
303 void store(
304 const bool linear, const T displacement_gradient[3][3],
305 const FailureCriterion* failure_criterion, b2000::GradientContainer* gradient_container) {
306 // Failure criterion.
307 if (failure_criterion != nullptr) {
308 if (failure_criterion->get_type() == FailureCriterion::STRESS) {
310 failure_criterion->process_stress(stress_pk2_mat, gradient_container);
311 } else {
313 failure_criterion->process_strain(strain_gl_mat, false, gradient_container);
314 }
315 }
316
317 if (gradient_container == nullptr) { return; }
318
319 // Transform the PK2 stress to the Cauchy stress.
320 if (!linear && displacement_gradient != 0) {
321 T deformation_gradient[3][3] = {};
322 if (has_covariant_base) {
323 // T G_inv[3][3];
324 // invert_3_3(G, G_inv);
325 b2000::inner_product_3_3_NT(displacement_gradient, G_d, deformation_gradient);
326 } else {
327 std::copy(
328 &displacement_gradient[0][0], &displacement_gradient[0][0] + 9,
329 &deformation_gradient[0][0]);
330 }
331 deformation_gradient[0][0] += 1;
332 deformation_gradient[1][1] += 1;
333 deformation_gradient[2][2] += 1;
334 const T det = 1 / b2000::determinant_3_3(deformation_gradient);
335 if (has_material_ref) {
336 T deformation_gradient_aligned_ortho[3][3];
338 deformation_gradient, M, deformation_gradient_aligned_ortho);
339 b2000::transform_stress_from_base_A_ov_to_I(
340 deformation_gradient_aligned_ortho, stress_pk2_mat, stress_cauchy_bg);
341 } else {
342 transform_stress_from_base_A_ov_to_I(
343 deformation_gradient, stress_pk2_mat, stress_cauchy_bg);
344 }
345 for (int i = 0; i != 6; ++i) { stress_cauchy_bg[i] *= det; }
346 } else {
348 }
349
350 //
351 // Store MBASE.
352 //
353 if (has_material_ref) {
354 static const b2000::GradientContainer::FieldDescription descr = {
355 "MBASE_IP",
356 "e1x.e1y.e1z.e2x.e2y.e2z.e3x.e3y.e3z",
357 "Material base vectors, undeformed configuration",
358 3,
359 9,
360 1,
361 3,
362 false,
363 typeid(T)};
364 if (gradient_container->compute_field_value(descr.name)) {
365 gradient_container->set_field_value(descr, &M[0][0]);
366 }
367 }
368
369 //
370 // Store the different strain and stress tensors.
371 //
372 if (1) {
373 static const b2000::GradientContainer::FieldDescription descr = {
374 "STRAIN",
375 "Exx.Eyy.Ezz.Exy.Eyz.Exz",
376 "Green-Lagrange/linear strain, global reference frame, no thermal expansion",
377 3,
378 6,
379 2,
380 3,
381 true,
382 typeid(T)};
383 if (gradient_container->compute_field_value(descr.name)) {
384 set_field_value_strain(gradient_container, descr, strain_gl_bg);
385 }
386 }
387
388 if (0) {
389 static const b2000::GradientContainer::FieldDescription descr = {
390 "STRAIN_MATERIAL",
391 "Exx.Eyy.Ezz.Exy.Eyz.Exz",
392 "Green-Lagrange/linear strain, material reference frame, no thermal expansion",
393 3,
394 6,
395 2,
396 3,
397 true,
398 typeid(T)};
399 if (gradient_container->compute_field_value(descr.name)) {
400 set_field_value_strain(gradient_container, descr, strain_gl_mat);
401 }
402 }
403
404 if (0 && has_thermal_expansion) {
405 static const b2000::GradientContainer::FieldDescription descr = {
406 "STRAIN_MECHANICAL",
407 "Exx.Eyy.Ezz.Exy.Eyz.Exz",
408 "Green-Lagrange/linear strain, global reference frame, thermal expansion",
409 3,
410 6,
411 2,
412 3,
413 true,
414 typeid(T)};
415 if (gradient_container->compute_field_value(descr.name)) {
416 b2000::transform_strain_from_base_A_ov_to_I(M, strain_gl_mat_te, strain_gl_bg_te);
417 set_field_value_strain(gradient_container, descr, strain_gl_bg_te);
418 }
419 }
420
421 if (0 && has_thermal_expansion) {
422 static const b2000::GradientContainer::FieldDescription descr = {
423 "STRAIN_MECHANICAL_MATERIAL",
424 "Exx.Eyy.Ezz.Exy.Eyz.Exz",
425 "Green-Lagrange/linear strain, material reference frame, thermal expansion",
426 3,
427 6,
428 2,
429 3,
430 true,
431 typeid(T)};
432 if (gradient_container->compute_field_value(descr.name)) {
433 set_field_value_strain(gradient_container, descr, strain_gl_mat_te);
434 }
435 }
436
437 if (1) {
438 static const b2000::GradientContainer::FieldDescription descr = {
439 "STRESS",
440 "Sxx.Syy.Szz.Sxy.Syz.Sxz",
441 "Cauchy/linear stress, global reference frame",
442 3,
443 6,
444 2,
445 3,
446 true,
447 typeid(T)};
448 if (gradient_container->compute_field_value(descr.name)) {
449 gradient_container->set_field_value(descr, stress_cauchy_bg);
450 }
451 }
452
453 if (0) {
454 static const b2000::GradientContainer::FieldDescription descr = {
455 "STRESS_MATERIAL",
456 "Sxx.Syy.Szz.Sxy.Syz.Sxz",
457 "Cauchy/linear stress, material reference frame",
458 3,
459 6,
460 2,
461 3,
462 true,
463 typeid(T)};
464 if (gradient_container->compute_field_value(descr.name)) {
465 b2000::transform_stress_from_I_to_base_B(M, stress_cauchy_bg, stress_cauchy_mat);
466 gradient_container->set_field_value(descr, stress_cauchy_mat);
467 }
468 }
469
470 if (0) {
471 static const b2000::GradientContainer::FieldDescription descr = {
472 "STRESS_PK2",
473 "Sxx.Syy.Szz.Sxy.Syz.Sxz",
474 "Second-Piola Kirchhoff stress, global reference frame",
475 3,
476 6,
477 2,
478 3,
479 true,
480 typeid(T)};
481 if (gradient_container->compute_field_value(descr.name)) {
482 transform_stress_from_base_A_ov_to_I(M, stress_pk2_mat, stress_pk2_bg);
483 gradient_container->set_field_value(descr, stress_pk2_bg);
484 }
485 }
486
487 if (0) {
488 static const b2000::GradientContainer::FieldDescription descr = {
489 "STRESS_PK2_MATERIAL",
490 "Sxx.Syy.Szz.Sxy.Syz.Sxz",
491 "Second-Piola Kirchhoff stress in the material reference frame",
492 3,
493 6,
494 2,
495 3,
496 true,
497 typeid(T)};
498 if (gradient_container->compute_field_value(descr.name)) {
499 gradient_container->set_field_value(descr, stress_pk2_mat);
500 }
501 }
502
503 if (0) {
504 static const b2000::GradientContainer::FieldDescription descr = {
505 "ENERGY_DENSITY",
506 "Elastic.Kinetic.RateDissipated.Dissipated",
507 "Free elastic, kinetic, rate of dissipated energy and "
508 "dissipated energy, per unit volume, in the undeformed "
509 "configuration",
510 3,
511 4,
512 -1,
513 0,
514 false,
515 typeid(T)};
516 if (gradient_container->compute_field_value(descr.name)) {
517 T es = 0;
518 for (int i = 0; i != 6; ++i) { es += strain_gl_mat[i] * stress_pk2_mat[i]; }
519 const T e[4] = {0.5 * es, 0, 0, 0};
520 gradient_container->set_field_value(descr, e);
521 }
522 }
523 }
524};
525
530template <typename T>
534
538
541 T M[3][3];
542
546
549 T G[3][3];
550
553 T G_d[3][3];
554
559
564
569
573
580 ElasticityHelperShellResultants(const T material_ref[3][3], const T covariant_base[3][3])
581 : has_thermal_expansion(false),
582 has_material_ref(material_ref != 0),
583 has_covariant_base(covariant_base != 0),
584 failure_index(0.) {
585 // Material basis (orthogonal reference frame) and its transpose.
586 if (has_material_ref) {
587 assert(material_ref != 0);
588 std::copy(&material_ref[0][0], &material_ref[0][0] + 9, &M[0][0]);
589 } else {
591 }
592
593 // Element covariant and contravariant basis.
594 if (has_covariant_base) {
595 assert(covariant_base != 0);
596 copy_3_3(covariant_base, G);
597 get_base_opposite_variance(G, G_d);
598 } else {
599 // Everything is aligned with the global coordinate system.
602 }
603
604 std::fill_n(strain_gl_mat, 8, 0);
605 std::fill_n(strain_gl_mat_te, 8, 0);
606 std::fill_n(stress_pk2_mat, 8, 0);
607 }
608
625 void set_strain(const T strain[8], const T temperature, const T alpha[8]) {
626 has_thermal_expansion = false;
627
628 if (strain != 0) {
629 b2000::transform_shell_strain_from_base_A_to_base_B(G, M, strain, strain_gl_mat);
630 }
631 if (alpha != 0 && temperature != 0) {
633 strain_gl_mat_te[0] = strain_gl_mat[0] - alpha[0] * temperature;
634 strain_gl_mat_te[1] = strain_gl_mat[1] - alpha[1] * temperature;
635 strain_gl_mat_te[2] = strain_gl_mat[2] - alpha[2] * temperature;
636 strain_gl_mat_te[3] = strain_gl_mat[3] - alpha[3] * temperature;
637 strain_gl_mat_te[4] = strain_gl_mat[4] - alpha[4] * temperature;
638 strain_gl_mat_te[5] = strain_gl_mat[5] - alpha[5] * temperature;
639 strain_gl_mat_te[6] = strain_gl_mat[6] - alpha[6] * temperature;
640 strain_gl_mat_te[7] = strain_gl_mat[7] - alpha[7] * temperature;
641 } else {
643 }
644 }
645
648
672 const T stress_mat[8], // may be 0
673 const T d_stress_d_strain_mat[36], T stress[8], T d_stress_d_strain[36]) {
674 if (d_stress_d_strain != 0) {
675 assert(d_stress_d_strain_mat != 0);
676 transform_shell_constitutive_tensor_from_base_A_ov_to_base_B(
677 M, G_d, d_stress_d_strain_mat, d_stress_d_strain);
678 }
679
680 //
681 // Calculate the stresses.
682 //
683 if (stress_mat != 0) {
684 std::copy(stress_mat, stress_mat + 8, stress_pk2_mat);
685 } else {
686 // Linear material: Calculate stress from constitutive matrix.
687 assert(d_stress_d_strain_mat != 0);
688 b2linalg::Matrix<T, b2linalg::Mlower_packed_constref> C_mat(8, d_stress_d_strain_mat);
689 b2linalg::Vector<T, b2linalg::Vdense_constref> e_mat(8, strain_gl_mat_te);
690 b2linalg::Vector<T, b2linalg::Vdense_ref> s_mat(8, stress_pk2_mat);
691 s_mat = C_mat * e_mat;
692 }
693 if (stress != 0) {
694 b2000::transform_shell_stress_from_base_A_to_base_B(M, G_d, stress_pk2_mat, stress);
695 }
696 }
697
708 void store(
709 const bool linear, const b2dbv3::FailureCriterion* failure_criterion,
710 b2000::GradientContainer* gradient_container) {
711 // // Failure criterion.
712 // if (failure_criterion != 0) {
713 // if (failure_criterion->get_type() == FailureCriterion::STRESS)
714 // failure_index = failure_criterion->process_shell_stress(
715 // stress_pk2_mat, gradient_container);
716 // else
717 // failure_index = failure_criterion->process_shell_strain(
718 // strain_gl_mat, false, gradient_container);
719 // }
720
721 if (gradient_container == nullptr) { return; }
722
723 //
724 // Store MBASE.
725 //
726 if (has_material_ref) {
727 static const b2000::GradientContainer::FieldDescription descr = {
728 "MBASE_IP",
729 "e1x.e1y.e1z.e2x.e2y.e2z.e3x.e3y.e3z",
730 "Material base vectors, undeformed configuration",
731 3,
732 9,
733 1,
734 3,
735 false,
736 typeid(T)};
737 if (gradient_container->compute_field_value(descr.name)) {
738 gradient_container->set_field_value(descr, &M[0][0]);
739 }
740 }
741
742 //
743 // Store the different strain and stress tensors.
744 //
745 {
746 static const b2000::GradientContainer::FieldDescription descr = {
747 "STRAIN_SHELL_MATERIAL",
748 "Mxx.Myy.Mxy.Bxx.Byy.Bxy.Tyz.Txz",
749 "Green-Lagrange/linear strain, material reference "
750 "frame, no thermal expansion",
751 3,
752 8,
753 -1,
754 -1,
755 false,
756 typeid(T)};
757 if (gradient_container->compute_field_value(descr.name)) {
758 set_field_value_shell_strain(gradient_container, descr, strain_gl_mat);
759 }
760 }
761 {
762 static const b2000::GradientContainer::FieldDescription descr = {
763 "STRESS_SHELL_MATERIAL",
764 "Mxx.Myy.Mxy.Bxx.Byy.Bxy.Tyz.Txz",
765 "Second Piola-Kirchhoff/linear stress, material "
766 "reference frame, no thermal expansion",
767 3,
768 8,
769 -1,
770 -1,
771 false,
772 typeid(T)};
773 if (gradient_container->compute_field_value(descr.name)) {
774 gradient_container->set_field_value(descr, stress_pk2_mat);
775 }
776 }
777 }
778};
779
784template <typename T>
788
792
794 T M[2][2];
795
799
802 T G[2][2];
803
806 T G_d[2][2];
807
812
817
822
827
831
836
841
845
849
853
857
864 ElasticityHelper2D(const T material_ref[2][2], const T covariant_base[2][2])
865 : has_thermal_expansion(false),
866 has_material_ref(material_ref != 0),
867 has_covariant_base(covariant_base != 0),
868 strain_normal(0),
869 stress_normal(0),
870 failure_index(0) {
871 if (has_material_ref) {
872 assert(material_ref != 0);
873 std::copy(&material_ref[0][0], &material_ref[0][0] + 4, &M[0][0]);
874 } else {
876 }
877
878 if (has_covariant_base) {
879 assert(covariant_base != 0);
880 b2000::copy_2_2(covariant_base, G);
881 b2000::get_base_opposite_variance(G, G_d);
882 } else {
883 // Everything is aligned with the global coordinate system.
886 }
887
888 std::fill_n(strain_gl_bg, 3, 0);
889 std::fill_n(strain_gl_bg_te, 3, 0);
890 std::fill_n(strain_gl_mat, 3, 0);
891 std::fill_n(strain_gl_mat_te, 3, 0);
892 std::fill_n(stress_pk2_bg, 3, 0);
893 std::fill_n(stress_pk2_mat, 3, 0);
894 std::fill_n(stress_cauchy_bg, 3, 0);
895 std::fill_n(stress_cauchy_mat, 3, 0);
896 }
897
914 void set_strain(const T strain[3], const T temperature, const T alpha[3]) {
915 // Compute the Linear/Green-Lagrange strain in the branch-global
916 // and material reference frames.
917 has_thermal_expansion = false;
918 if (strain != 0) {
919 transform_strain_from_base_A_to_I(G, strain, strain_gl_bg);
920 transform_strain_from_I_to_base_B(M, strain_gl_bg, strain_gl_mat);
921 }
922 if (alpha != 0) {
924 strain_gl_mat_te[0] = strain_gl_mat[0] - alpha[0] * temperature;
925 strain_gl_mat_te[1] = strain_gl_mat[1] - alpha[1] * temperature;
926 strain_gl_mat_te[2] = strain_gl_mat[2] - alpha[2] * temperature;
927 } else {
929 }
930 }
931
956 const T stress_mat[3], // may be 0
957 const T d_stress_d_strain_mat[6], T stress[3], T d_stress_d_strain[6]) {
958 if (d_stress_d_strain) {
959 assert(d_stress_d_strain_mat != 0);
960 transform_constitutive_tensor_from_base_A_ov_to_base_B(
961 M, G_d, d_stress_d_strain_mat, d_stress_d_strain);
962 }
963
964 //
965 // Calculate the stresses.
966 //
967 if (stress_mat != 0) {
968 std::copy(stress_mat, stress_mat + 3, stress_pk2_mat);
969 } else {
970 // Linear material: Calculate stress from constitutive matrix.
971 assert(d_stress_d_strain_mat != 0);
972 b2linalg::Matrix<T, b2linalg::Mlower_packed_constref> C_mat(3, d_stress_d_strain_mat);
973 b2linalg::Vector<T, b2linalg::Vdense_constref> e_mat(3, strain_gl_mat_te);
974 b2linalg::Vector<T, b2linalg::Vdense_ref> s_mat(3, stress_pk2_mat);
975 s_mat = C_mat * e_mat;
976 }
977 transform_stress_from_base_A_ov_to_I(M, stress_pk2_mat, stress_pk2_bg);
978 if (stress != 0) { transform_stress_from_I_to_base_B(G_d, stress_pk2_bg, stress); }
979 }
980
997 void store(
998 const bool linear, const T displacement_gradient[2][2],
999 const FailureCriterion* failure_criterion, b2000::GradientContainer* gradient_container) {
1000 // Failure criterion.
1001 if (failure_criterion) {
1002 if (failure_criterion->get_type() == FailureCriterion::STRESS) {
1003 const T stress_pk2_mat_6[6] = {
1006 failure_criterion->process_stress(stress_pk2_mat_6, gradient_container);
1007 } else {
1008 const T strain_gl_mat_6[6] = {
1011 failure_criterion->process_strain(strain_gl_mat_6, false, gradient_container);
1012 }
1013 }
1014
1015 if (!gradient_container) { return; }
1016
1017 // Transform the PK2 stress to the Cauchy stress.
1018 if (!linear && displacement_gradient) {
1019 T deformation_gradient[2][2] = {};
1020 if (has_covariant_base) {
1021 b2000::inner_product_2_2_NT(displacement_gradient, G_d, deformation_gradient);
1022 } else {
1023 std::copy(
1024 &displacement_gradient[0][0], &displacement_gradient[0][0] + 4,
1025 &deformation_gradient[0][0]);
1026 }
1027 deformation_gradient[0][0] += 1;
1028 deformation_gradient[1][1] += 1;
1029 const T det = 1 / b2000::determinant_2_2(deformation_gradient);
1030 if (has_material_ref) {
1031 T deformation_gradient_aligned_ortho[2][2];
1033 deformation_gradient, M, deformation_gradient_aligned_ortho);
1034 b2000::transform_stress_from_base_A_ov_to_I(
1035 deformation_gradient_aligned_ortho, stress_pk2_mat, stress_cauchy_bg);
1036 } else {
1037 b2000::transform_stress_from_base_A_ov_to_I(
1038 deformation_gradient, stress_pk2_mat, stress_cauchy_bg);
1039 }
1040 for (int i = 0; i != 3; ++i) { stress_cauchy_bg[i] *= det; }
1041 } else {
1043 }
1044
1045 //
1046 // Store MBASE.
1047 //
1048 if (has_material_ref) {
1049 static const b2000::GradientContainer::FieldDescription descr = {
1050 "MBASE_IP",
1051 "e1x.e1y.e1z.e2x.e2y.e2z.e3x.e3y.e3z",
1052 "Material base vectors, undeformed configuration",
1053 3,
1054 9,
1055 1,
1056 3,
1057 false,
1058 typeid(T)};
1059 if (gradient_container->compute_field_value(descr.name)) {
1060 T mbase_3_3[3][3] = {
1061 {M[0][0], M[0][1], 0.},
1062 {M[1][0], M[1][1], 0.},
1063 {0., 0., 1.},
1064 };
1065 gradient_container->set_field_value(descr, &mbase_3_3[0][0]);
1066 }
1067 }
1068
1069 //
1070 // Store the different strain and stress tensors.
1071 //
1072 if (1) {
1073 static const b2000::GradientContainer::FieldDescription descr = {
1074 "STRAIN",
1075 "Exx.Eyy.Ezz.Exy.Eyz.Exz",
1076 "Green-Lagrange/linear strain, global reference "
1077 "frame, no thermal expansion",
1078 3,
1079 6,
1080 2,
1081 3,
1082 true,
1083 typeid(T)};
1084 if (gradient_container->compute_field_value(descr.name)) {
1085 set_field_value_strain_2(gradient_container, descr, strain_gl_bg, strain_normal);
1086 }
1087 }
1088
1089 if (0) {
1090 static const b2000::GradientContainer::FieldDescription descr = {
1091 "STRAIN_MATERIAL",
1092 "Exx.Eyy.Ezz.Exy.Eyz.Exz",
1093 "Green-Lagrange/linear strain, material reference "
1094 "frame, no thermal expansion",
1095 3,
1096 6,
1097 2,
1098 3,
1099 true,
1100 typeid(T)};
1101 if (gradient_container->compute_field_value(descr.name)) {
1102 set_field_value_strain_2(gradient_container, descr, strain_gl_mat, strain_normal);
1103 }
1104 }
1105
1106 if (0 && has_thermal_expansion) {
1107 static const b2000::GradientContainer::FieldDescription descr = {
1108 "STRAIN_MECHANICAL",
1109 "Exx.Eyy.Ezz.Exy.Eyz.Exz",
1110 "Green-Lagrange/linear strain, global reference "
1111 "frame, thermal expansion",
1112 3,
1113 6,
1114 2,
1115 3,
1116 true,
1117 typeid(T)};
1118 if (gradient_container->compute_field_value(descr.name)) {
1119 b2000::transform_strain_from_base_A_ov_to_I(M, strain_gl_mat_te, strain_gl_bg_te);
1120 set_field_value_strain_2(gradient_container, descr, strain_gl_bg_te, strain_normal);
1121 }
1122 }
1123
1124 if (0 && has_thermal_expansion) {
1125 static const b2000::GradientContainer::FieldDescription descr = {
1126 "STRAIN_MECHANICAL_MATERIAL",
1127 "Exx.Eyy.Ezz.Exy.Eyz.Exz",
1128 "Green-Lagrange/linear strain, material reference "
1129 "frame, thermal expansion",
1130 3,
1131 6,
1132 2,
1133 3,
1134 true,
1135 typeid(T)};
1136 if (gradient_container->compute_field_value(descr.name)) {
1137 set_field_value_strain_2(
1138 gradient_container, descr, strain_gl_mat_te, strain_normal);
1139 }
1140 }
1141
1142 if (1) {
1143 static const b2000::GradientContainer::FieldDescription descr = {
1144 "STRESS",
1145 "Sxx.Syy.Szz.Sxy.Syz.Sxz",
1146 "Cauchy/linear stress, global reference frame",
1147 3,
1148 6,
1149 2,
1150 3,
1151 true,
1152 typeid(T)};
1153 if (gradient_container->compute_field_value(descr.name)) {
1154 set_field_value_stress_2(
1155 gradient_container, descr, stress_cauchy_bg, stress_normal);
1156 }
1157 }
1158
1159 if (0) {
1160 static const b2000::GradientContainer::FieldDescription descr = {
1161 "STRESS_MATERIAL",
1162 "Sxx.Syy.Szz.Sxy.Syz.Sxz",
1163 "Cauchy/linear stress, material reference frame",
1164 3,
1165 6,
1166 2,
1167 3,
1168 true,
1169 typeid(T)};
1170 if (gradient_container->compute_field_value(descr.name)) {
1171 b2000::transform_stress_from_I_to_base_B(M, stress_cauchy_bg, stress_cauchy_mat);
1172 set_field_value_stress_2(
1173 gradient_container, descr, stress_cauchy_mat, stress_normal);
1174 }
1175 }
1176
1177 if (0) {
1178 static const b2000::GradientContainer::FieldDescription descr = {
1179 "STRESS_PK2",
1180 "Sxx.Syy.Szz.Sxy.Syz.Sxz",
1181 "Second-Piola Kirchhoff stress, global reference frame",
1182 3,
1183 6,
1184 2,
1185 3,
1186 true,
1187 typeid(T)};
1188 if (gradient_container->compute_field_value(descr.name)) {
1189 b2000::transform_stress_from_base_A_ov_to_I(M, stress_pk2_mat, stress_pk2_bg);
1190 set_field_value_stress_2(gradient_container, descr, stress_pk2_bg, stress_normal);
1191 }
1192 }
1193
1194 if (0) {
1195 static const b2000::GradientContainer::FieldDescription descr = {
1196 "STRESS_PK2_MATERIAL",
1197 "Sxx.Syy.Szz.Sxy.Syz.Sxz",
1198 "Second-Piola Kirchhoff stress, material reference frame",
1199 3,
1200 6,
1201 2,
1202 3,
1203 true,
1204 typeid(T)};
1205 if (gradient_container->compute_field_value(descr.name)) {
1206 set_field_value_stress_2(gradient_container, descr, stress_pk2_mat, stress_normal);
1207 }
1208 }
1209
1210 if (0) {
1211 static const b2000::GradientContainer::FieldDescription descr = {
1212 "ENERGY_DENSITY",
1213 "Elastic.Kinetic.RateDissipated.Dissipated",
1214 "Free elastic, kinetic, rate of dissipated energy and "
1215 "dissipated energy, per unit volume, in the undeformed "
1216 "configuration",
1217 3,
1218 4,
1219 -1,
1220 0,
1221 false,
1222 typeid(T)};
1223 if (gradient_container->compute_field_value(descr.name)) {
1224 const T e[4] = {0.5 * dot_3(strain_gl_mat, stress_pk2_mat), 0, 0, 0};
1225 gradient_container->set_field_value(descr, e);
1226 }
1227 }
1228 }
1229};
1230
1233template <typename T>
1235 std::string not_supported;
1236 bool isotropic;
1237 bool orthotropic;
1238 bool anisotropic;
1239 T d_stress_d_strain_mat[21];
1240 T alpha[6];
1241 T density;
1242
1243 LayerData() : isotropic(true), orthotropic(false), anisotropic(false), density(0) {
1244 std::fill_n(d_stress_d_strain_mat, 21, 0.);
1245 std::fill_n(alpha, 6, 0.);
1246 }
1247
1248 void init_25d(const RTable& rtable, const std::string& prefix = "") {
1249 const std::string sub_type = rtable.get_string(prefix + "SUBTYPE");
1250 isotropic = (sub_type == "ISOTROPIC");
1251 orthotropic = (sub_type == "ORTHOTROPIC" || sub_type == "ORTHOTROPIC25D");
1252 anisotropic = (sub_type == "ANISOTROPIC");
1253
1254 const T sh = rtable.get<T>(prefix + "SHEAR_CORRECTION_FACTOR", T(5) / T(6));
1255 if (anisotropic) {
1256 // Anisotropic material. Material matrix is defined in
1257 // database and is stored in row-major format, upper-triangle.
1258 // This is equal to column-major format, lower-triangle.
1259 d_stress_d_strain_mat[0] = rtable.get<T>(prefix + "C1111", 0.);
1260 d_stress_d_strain_mat[1] = rtable.get<T>(prefix + "C1122", 0.);
1261 d_stress_d_strain_mat[2] = rtable.get<T>(prefix + "C1133", 0.);
1262 d_stress_d_strain_mat[3] = rtable.get<T>(prefix + "C1112", 0.);
1263 d_stress_d_strain_mat[4] = rtable.get<T>(prefix + "C1123", 0.);
1264 d_stress_d_strain_mat[5] = rtable.get<T>(prefix + "C1113", 0.);
1265 d_stress_d_strain_mat[6] = rtable.get<T>(prefix + "C2222", 0.);
1266 d_stress_d_strain_mat[7] = rtable.get<T>(prefix + "C2233", 0.);
1267 d_stress_d_strain_mat[8] = rtable.get<T>(prefix + "C2212", 0.);
1268 d_stress_d_strain_mat[9] = rtable.get<T>(prefix + "C2223", 0.);
1269 d_stress_d_strain_mat[10] = rtable.get<T>(prefix + "C2213", 0.);
1270 d_stress_d_strain_mat[11] = rtable.get<T>(prefix + "C3333", 0.);
1271 d_stress_d_strain_mat[12] = rtable.get<T>(prefix + "C3312", 0.);
1272 d_stress_d_strain_mat[13] = rtable.get<T>(prefix + "C3323", 0.);
1273 d_stress_d_strain_mat[14] = rtable.get<T>(prefix + "C3313", 0.);
1274 d_stress_d_strain_mat[15] = rtable.get<T>(prefix + "C1212", 0.);
1275 d_stress_d_strain_mat[16] = rtable.get<T>(prefix + "C1223", 0.);
1276 d_stress_d_strain_mat[17] = rtable.get<T>(prefix + "C1213", 0.);
1277 d_stress_d_strain_mat[18] = rtable.get<T>(prefix + "C2323", 0.);
1278 d_stress_d_strain_mat[19] = rtable.get<T>(prefix + "C2313", 0.);
1279 d_stress_d_strain_mat[20] = rtable.get<T>(prefix + "C1313", 0.);
1280 } else if (isotropic || orthotropic) {
1281 // Extract parameters.
1282 T e1, e2, e3;
1283 T nu12, nu23, nu13;
1284 T g12, g23, g13;
1285 if (orthotropic) {
1286 e1 = rtable.get<T>(prefix + "E1");
1287 e2 = rtable.get<T>(prefix + "E2");
1288 e3 = rtable.get<T>(prefix + "E3", e2);
1289 nu12 = rtable.get<T>(prefix + "NU12");
1290 nu13 = rtable.get<T>(prefix + "NU13", nu12);
1291 nu23 = rtable.get<T>(prefix + "NU23", nu13);
1292 g12 = rtable.get<T>(prefix + "G12");
1293 g23 = rtable.get<T>(prefix + "G23", g12);
1294 g13 = rtable.get<T>(prefix + "G13", g12);
1295 } else {
1296 e1 = e2 = e3 = rtable.get<T>(prefix + "E");
1297 nu12 = nu23 = nu13 = rtable.get<T>(prefix + "NU");
1298 g12 = g23 = g13 = rtable.get<T>(prefix + "G", e1 / (T(2) * (T(1) + nu12)));
1299 }
1300
1301 // Initialize constitutive matrix.
1302 std::fill_n(d_stress_d_strain_mat, 21, T(0));
1303 {
1304 const T c11 = T(1) / e1;
1305 const T c22 = T(1) / e2;
1306 const T c12 = -nu12 * c11;
1307 const T inv_det = T(1) / (c11 * c22 - c12 * c12);
1308 d_stress_d_strain_mat[0] = c22 * inv_det;
1309 d_stress_d_strain_mat[1] = -c12 * inv_det;
1310 d_stress_d_strain_mat[6] = c11 * inv_det;
1311 }
1312 d_stress_d_strain_mat[15] = g12;
1313 d_stress_d_strain_mat[18] = g23 * sh;
1314 d_stress_d_strain_mat[20] = g13 * sh;
1315 } else {
1316 std::ostringstream o;
1317 o << rtable.errmsg_context << "The material type " << sub_type
1318 << " cannot be used with shell elements.";
1319 not_supported = o.str();
1320 return;
1321 }
1322
1323 const T alpha_r = rtable.get<T>(prefix + "ALPHA", T(0));
1324 alpha[0] = rtable.get<T>(prefix + "ALPHA11", alpha_r);
1325 alpha[1] = rtable.get<T>(prefix + "ALPHA22", alpha_r);
1326 alpha[2] = T(0); // no valid transverse normal strain
1327 const T alpha12 = rtable.get<T>(prefix + "ALPHA12", T(0));
1328 alpha[3] = T(2) * alpha12;
1329 alpha[4] = T(2) * rtable.get<T>(prefix + "ALPHA23", T(0));
1330 alpha[5] = T(2) * rtable.get<T>(prefix + "ALPHA13", T(0));
1331
1332 density = rtable.get<T>(prefix + "DENSITY", T(0));
1333 }
1334};
1335
1336}} // namespace b2000::b2dbv3
1337
1338#endif // B2_MATERIAL_UTIL_H_
Interface to C++ representations of FE solvers.
Definition b2solution.H:54
virtual void set_field_value(const FieldDescription &descr, const int *value)
Definition b2solution.H:146
virtual bool compute_field_value(const std::string &name) const
Definition b2solution.H:221
Definition b2rtable.H:427
T get(const std::string &key) const
Definition b2rtable.H:647
std::string get_string(const std::string &key) const
Definition b2rtable.H:633
std::string errmsg_context
Will be pre-pended to error messages.
Definition b2rtable.H:430
Definition b2failure_criterion.H:42
virtual double process_strain(const double strain_mat[6], const bool engineering, b2000::GradientContainer *gradient_container) const
Definition b2failure_criterion.H:87
virtual double process_stress(const double stress_mat[6], b2000::GradientContainer *gradient_container) const
Definition b2failure_criterion.H:60
virtual int get_type() const =0
Returns STRAIN or STRESS.
Contains the base classes for implementing Finite Elements.
Definition b2boundary_condition.H:32
void set_identity_3_3(T1 a[3][3])
Definition b2tensor_calculus.H:511
void inner_product_2_2_NT(const T a[2][2], const T b[2][2], T c[2][2])
Definition b2tensor_calculus.H:863
void inner_product_3_3_NN(const T a[3][3], const T b[3][3], T c[3][3])
Definition b2tensor_calculus.H:808
T determinant_3_3(const T a[3][3])
Definition b2tensor_calculus.H:669
void set_identity_2_2(T1 a[2][2])
Definition b2tensor_calculus.H:518
void copy_2_2(const T1 a[2][2], T1 b[2][2])
Definition b2tensor_calculus.H:539
void inner_product_3_3_NT(const T a[3][3], const T b[3][3], T c[3][3])
Definition b2tensor_calculus.H:848
void inner_product_2_2_NN(const T a[2][2], const T b[2][2], T c[2][2])
Definition b2tensor_calculus.H:838
void copy_3_3(const T1 a[3][3], T1 b[3][3])
Definition b2tensor_calculus.H:525
T dot_3(const T a[3], const T b[3])
Definition b2tensor_calculus.H:328
T determinant_2_2(const T a[2][2])
Definition b2tensor_calculus.H:683
std::string name
Definition b2solution.H:73
Definition b2material_util.H:785
T strain_gl_mat[3]
Definition b2material_util.H:821
T G[2][2]
Definition b2material_util.H:802
T stress_cauchy_bg[3]
Definition b2material_util.H:844
ElasticityHelper2D(const T material_ref[2][2], const T covariant_base[2][2])
Definition b2material_util.H:864
T strain_gl_mat_te[3]
Definition b2material_util.H:826
T stress_normal
Definition b2material_util.H:852
bool has_thermal_expansion
Whether STRAIN_MECHANICAL fields will be written.
Definition b2material_util.H:787
T G_d[2][2]
Definition b2material_util.H:806
T M[2][2]
Material reference frame. Is initialized in the constructor.
Definition b2material_util.H:794
T stress_pk2_bg[3]
Definition b2material_util.H:835
void set_stress_and_or_d_stress_d_strain_mat(const T stress_mat[3], const T d_stress_d_strain_mat[6], T stress[3], T d_stress_d_strain[6])
Definition b2material_util.H:955
bool has_covariant_base
Definition b2material_util.H:798
T strain_gl_bg[3]
Definition b2material_util.H:811
T stress_pk2_mat[3]
Definition b2material_util.H:840
T strain_gl_bg_te[3]
Definition b2material_util.H:816
T stress_cauchy_mat[3]
Definition b2material_util.H:848
void set_strain(const T strain[3], const T temperature, const T alpha[3])
Definition b2material_util.H:914
T failure_index
Definition b2material_util.H:856
void store(const bool linear, const T displacement_gradient[2][2], const FailureCriterion *failure_criterion, b2000::GradientContainer *gradient_container)
Definition b2material_util.H:997
bool has_material_ref
Definition b2material_util.H:791
T strain_normal
Definition b2material_util.H:830
Definition b2material_util.H:531
bool has_material_ref
Definition b2material_util.H:537
T G_d[3][3]
Definition b2material_util.H:553
T failure_index
Definition b2material_util.H:572
void store(const bool linear, const b2dbv3::FailureCriterion *failure_criterion, b2000::GradientContainer *gradient_container)
Definition b2material_util.H:708
void set_strain(const T strain[8], const T temperature, const T alpha[8])
Definition b2material_util.H:625
T strain_gl_mat_te[8]
Definition b2material_util.H:563
T M[3][3]
Definition b2material_util.H:541
T stress_pk2_mat[8]
Definition b2material_util.H:568
T G[3][3]
Definition b2material_util.H:549
void set_stress_and_or_d_stress_d_strain_mat(const T stress_mat[8], const T d_stress_d_strain_mat[36], T stress[8], T d_stress_d_strain[36])
Definition b2material_util.H:671
T strain_gl_mat[8]
Definition b2material_util.H:558
ElasticityHelperShellResultants(const T material_ref[3][3], const T covariant_base[3][3])
Definition b2material_util.H:580
bool has_thermal_expansion
Whether STRAIN_MECHANICAL fields will be written.
Definition b2material_util.H:533
bool has_covariant_base
Definition b2material_util.H:545
Definition b2material_util.H:91
T G[3][3]
Definition b2material_util.H:109
bool has_material_ref
Definition b2material_util.H:97
T strain_gl_bg_te[6]
Definition b2material_util.H:123
T stress_pk2_bg[6]
Definition b2material_util.H:138
void set_stress_and_or_d_stress_d_strain_mat(const T stress_mat[6], const T d_stress_d_strain_mat[21], T stress[6], T d_stress_d_strain[21])
Definition b2material_util.H:261
T strain_gl_bg[6]
Definition b2material_util.H:118
T M[3][3]
Definition b2material_util.H:101
T strain_gl_mat_te[6]
Definition b2material_util.H:133
T strain_gl_mat[6]
Definition b2material_util.H:128
T stress_cauchy_bg[6]
Definition b2material_util.H:147
T failure_index
Definition b2material_util.H:155
bool has_covariant_base
Definition b2material_util.H:105
bool has_thermal_expansion
Whether STRAIN_MECHANICAL fields will be written.
Definition b2material_util.H:93
void set_strain(const bool planestress, const T strain[6], const T temperature, const T alpha[6])
Definition b2material_util.H:213
ElasticityHelper(const T material_ref[3][3], const T covariant_base[3][3])
Definition b2material_util.H:163
void store(const bool linear, const T displacement_gradient[3][3], const FailureCriterion *failure_criterion, b2000::GradientContainer *gradient_container)
Definition b2material_util.H:303
T G_d[3][3]
Definition b2material_util.H:113
T stress_pk2_mat[6]
Definition b2material_util.H:143
T stress_cauchy_mat[6]
Definition b2material_util.H:151
Definition b2material_util.H:1234