KASKADE 7 development version
materialLaws.hh
Go to the documentation of this file.
1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2/* */
3/* This file is part of the library KASKADE 7 */
4/* https://www.zib.de/research/projects/kaskade7-finite-element-toolbox */
5/* */
6/* Copyright (C) 2015-2019 Zuse Institute Berlin */
7/* */
8/* KASKADE 7 is distributed under the terms of the ZIB Academic License. */
9/* see $KASKADE/academic.txt */
10/* */
11/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
12
13#ifndef FEM_DIFFOPS_MATERIALLAWS_HH
14#define FEM_DIFFOPS_MATERIALLAWS_HH
15
16#include <cassert>
17
18#include "dune/common/config.h"
19#include "dune/common/fmatrix.hh"
20
21#include "fem/diffops/elasto.hh"
22#include "linalg/determinant.hh"
23
24namespace Kaskade
25{
26 namespace Elastomechanics
27 {
35 namespace MaterialLaws
36 {
51 template <int dim_, class Scalar_, class MaterialLaw>
53 {
54 public:
55 using Scalar = Scalar_;
56 static int const dim = dim_;
59
65 Tensor stress() const
66 {
67 Tensor sigma;
68
69 for (int i=0; i<dim; ++i)
70 for (int j=0; j<=i; ++j)
71 {
72 Tensor E(0);
73 E[i][j] = 1;
74 sigma[i][j] = static_cast<MaterialLaw const*>(this)->d1(E);
75 }
76
77 for (int i=0; i<dim-1; ++i)
78 for (int j=i+1; j<dim; ++j)
79 sigma[i][j] = sigma[j][i];
80
81 return sigma;
82 }
83
103 {
104 int const n = dim*(dim+1)/2;
106
107 // For the Voigt notation it holds that x^T C y = W''[unpack(x),unpack(y)].
108 // Due to symmetry of C, we only compute the lower half directly...
109 for (int i=0; i<n; ++i)
110 {
112 x[i] = 1;
113 auto X = unpack(x);
114
115 for (int j=0; j<=i; ++j)
116 {
118 y[j] = 1;
119 auto Y = unpack(y);
120
121 C[i][j] = static_cast<MaterialLaw const*>(this)->d2(X,Y);
122 }
123 }
124
125 // ... and copy it to the upper half.
126 for (int i=0; i<n-1; ++i)
127 for (int j=i+1; j<n; ++j)
128 C[i][j] = C[j][i];
129
130 return C;
131 }
132 };
133
134 // ---------------------------------------------------------------------------------------------------------
135
155 template <class Material>
156 class InvariantsMaterialLaw: public MaterialLawBase<Material::dim,typename Material::Scalar,InvariantsMaterialLaw<Material>>
157 {
158 public:
159 using Scalar = typename Material::Scalar;
160 static int const dim = Material::dim;
162
166 template <class ... Args>
168 : invariants(Tensor(0.0))
169 , material(args...)
170 {}
171
182 {
183 invariants = ShiftedInvariants<dim,Scalar>(2.0*e);
184 material.setLinearizationPoint(invariants.d0());
185 }
186
190 Scalar d0() const
191 {
192 return material.d0();
193 }
194
198 Scalar d1(Tensor const& e1) const
199 {
200 return 2*material.d1(invariants.d1(e1));
201 }
202
206 Scalar d2(Tensor const& e1, Tensor const& e2) const
207 {
208 return 4*(material.d2(invariants.d1(e1),invariants.d1(e2)) + material.d1(invariants.d2(e1,e2)));
209 }
210
214 private:
216 Material material;
217 };
218
235 template <class Material, class DeviatoricPenalty>
237 : public MaterialLawBase<Material::dim,typename Material::Scalar,CompressibleInvariantsMaterialLaw<Material,DeviatoricPenalty>>
238 {
239 public:
240 using Scalar = typename Material::Scalar;
241 static int const dim = Material::dim;
243
244 template <class ... Args>
245 CompressibleInvariantsMaterialLaw(Tensor const& E, Args... args): bE(E), material(bE.d0(),args...), deviator(bE.determinant().d0()) {}
246
252 {
254 deviator = DeviatoricPenalty(bE.determinant().d0());
255 material.setLinearizationPoint(bE.d0());
256 }
257
261 Scalar d0() const
262 {
263 return material.d0() + deviator.d0();
264 }
265
269 Scalar d1(Tensor const& e1) const
270 {
271 return material.d1(bE.d1(e1)) + deviator.d1(bE.determinant().d1(e1));
272 }
273
277 Scalar d2(Tensor const& e1, Tensor const& e2) const
278 {
279 return material.d2(bE.d1(e1),bE.d1(e2)) + material.d1(bE.d2(e1,e2))
280 + deviator.d2(bE.determinant().d1(e1),bE.determinant().d1(e2)) + deviator.d1(bE.determinant().d2(e1,e2));
281 }
282
283 private:
286 DeviatoricPenalty deviator;
287 };
288
289 // ---------------------------------------------------------------------------------------------------------
290 // ---------------------------------------------------------------------------------------------------------
291
292
315 template <int dim, class Scalar=double>
316 class StVenantKirchhoff: public MaterialLawBase<dim,Scalar,StVenantKirchhoff<dim,Scalar>>
317 {
319
320 public:
321
323
327 StVenantKirchhoff() = default;
328
334 StVenantKirchhoff(ElasticModulus const& moduli, Scalar alpha_=0)
335 : lambda(moduli.lame()), mu(moduli.shear()), alpha(alpha_)
336 , detC(unitMatrix<Scalar,dim>())
337 {
338 }
339
351 StVenantKirchhoff(ElasticModulus const& moduli, Tensor const& e_)
352 : lambda(moduli.lame()), mu(moduli.shear()), e(e_), tre(trace(e))
353 , detC(unitMatrix<Scalar,dim>()+2*e)
354 {
355 }
356
366 {
367 e = e_;
368 tre = trace(e);
369 detC = Det(unitMatrix<Scalar,dim>()+2*e);
370 }
371
375 Scalar d0() const
376 {
377 Scalar w = lambda*tre*tre/2 + mu*contraction(e,e);
378 if (alpha > 0)
379 {
380 auto detc = detC.d0();
381 if (detc <= 0)
382 w = std::numeric_limits<Scalar>::infinity();
383 else
384 w += alpha*(1/detc-1 + 2*tre);
385 }
386 return w;
387 }
388
392 Scalar d1(Tensor const& e1) const
393 {
394 Scalar dw = lambda*tre*trace(e1) + 2*mu*contraction(e,e1);
395 if (alpha > 0)
396 dw += alpha*(-std::pow(detC.d0(),-2)*detC.d1(e1)*2 + 2*trace(e1));
397 return dw;
398 }
399
403 Scalar d2(Tensor const& e1, Tensor const& e2) const
404 {
405 Scalar ddw = lambda*trace(e1)*trace(e2) + 2*mu*contraction(e1,e2);
406 if (alpha > 0)
407 ddw += alpha*( 2*std::pow(detC.d0(),-3)*detC.d1(e1)*2*detC.d1(e2)*2
408 - std::pow(detC.d0(),-2)*detC.d2(e1,e2)*4 );
409 return ddw;
410 }
411
415 Scalar d3(Tensor const& e1, Tensor const& e2, Tensor const& e3) const
416 {
417 if (alpha > 0)
418 return alpha * ( -6*std::pow(detC.d0(),-4)*detC.d1(e1)*2*detC.d1(e2)*2*detC.d1(e3)*2
419 + 2*std::pow(detC.d0(),-3)*detC.d2(e1,e3)*4*detC.d1(e2)*2
420 + 2*std::pow(detC.d0(),-3)*detC.d1(e1)*2*detC.d2(e2,e3)*4
421 + 2*std::pow(detC.d0(),-3)*detC.d1(e3)*detC.d2(e1,e2)*4
422 - std::pow(detC.d0(),-2)*detC.d3(e1,e2,e3)*8 );
423 else
424 return 0;
425 }
426
430 Scalar d4(Tensor const& , Tensor const& , Tensor const&, Tensor const& ) const
431 {
432 // That's even easier for a quadratic energy...
433 if (alpha > 0)
434 abort(); // not yet implemented
435 return 0;
436 }
437
442 private:
443 Scalar lambda = 1; // Lame parameter
444 Scalar mu = 1; // Lame parameter
445 Scalar alpha = 0; // compression penalty factor
446 Tensor e = 0; // the strain tensor
447 Scalar tre = 0; // trace of strain tensor
448 Determinant<dim,Scalar> detC; // determinant of Green-Lagrange tensor
449 };
450
451 // ---------------------------------------------------------------------------------------------------------
452
466 template <int dim, class Scalar=double>
467 class OrthotropicLinearMaterial : public MaterialLawBase<dim,Scalar,OrthotropicLinearMaterial<dim,Scalar>>
468 {
469
471
472 public:
473
490 : orth(orth_), orthT(transpose(orth_)), e(0)
491 {
492 Dune::FieldMatrix<Scalar,dim*(dim+1)/2,dim*(dim+1)/2> compliance(0);
493 if (dim==3)
494 {
495 // see http://en.wikipedia.org/wiki/Orthotropic_material
496 compliance[0][0] = 1 / mat_[0][0]; // 1/E_11
497 compliance[0][1] = - mat_[1][0] / mat_[0][0]; // - nu_12 / E_11 = - nu_21 / E_22
498 compliance[0][2] = - mat_[2][0] / mat_[0][0]; // - nu_13 / E_11 = - nu_31 / E_33
499 compliance[1][0] = compliance[0][1]; // symmetry
500 compliance[1][1] = 1 / mat_[1][1];
501 compliance[1][2] = - mat_[2][1] / mat_[1][1]; // - nu_23 / E_22 = - nu_32 / E_33
502 compliance[2][0] = compliance[0][2]; // symmetry
503 compliance[2][1] = compliance[1][2]; // symmetry
504 compliance[2][2] = 1 / mat_[2][2];
505
506 compliance[3][3] = 1 / mat_[1][2]; // 1 / G_23
507 compliance[4][4] = 1 / mat_[0][2]; // 1 / G_13
508 compliance[5][5] = 1 / mat_[0][1]; // 1 / G_12
509 }
510 else if (dim==2)
511 {
512 compliance[0][0] = 1 / mat_[0][0]; // 1/E_11;
513 compliance[0][1] = - mat_[1][0] / mat_[0][0]; // - nu_12 / E_11 = - nu_21 / E_22
514 compliance[1][0] = compliance[0][1]; // symmetry
515 compliance[1][1] = 1 / mat_[1][1]; // 1/E_22
516
517 compliance[2][2] = 1/mat_[0][1]; // 1 / G_12
518 }
519
520 // stiffness tensor is inverse of compliance tensor
521 stiffness = compliance;
522 stiffness.invert();
523 }
524
539 Dune::FieldMatrix<Scalar,dim,dim> const& mat1, Dune::FieldVector<Scalar,dim*(dim-1)/2> const& mat2)
540 : orth(orth_), orthT(transpose(orth_)), stiffness(0), e(0)
541 {
542 for (int i=0; i<dim; ++i)
543 for (int j=0; j<dim; ++j)
544 stiffness[i][j] = mat1[i][j];
545 for (int i=0; i<dim*(dim-1)/2; ++i)
546 stiffness[dim+i][dim+i] = mat2[i];
547 }
548
555 : orth(unitMatrix<Scalar,dim>()), orthT(unitMatrix<Scalar,dim>()), stiffness(0), e(0)
556 {
557 Scalar lambda = p.lame(), mu = p.shear();
558 if (dim==2)
559 {
560 stiffness[0][0] = stiffness[1][1] = 2*mu + lambda;
561 stiffness[1][0] = stiffness[0][1] = lambda;
562 stiffness[2][2] = mu;
563 }
564 if (dim==3)
565 abort();
566 }
567
575
584 Dune::FieldMatrix<Scalar,dim*(dim+1)/2,dim*(dim+1)/2> const& stiffnessMatrix() const { return stiffness; }
585
590 {
591 e = e_;
592 }
593
597 Scalar d0() const
598 {
599 auto eps = pack(orthT*e*orth);
600 auto sigma = stiffness * eps;
601 return 0.5 * (sigma*eps);
602 }
603
608 Scalar d1(Tensor const& e1) const
609 {
610 auto eps = pack(orthT*e*orth);
611 auto eps1 = pack(orthT*e1*orth);
612 auto sigma = stiffness * eps1;
613 return sigma*eps;
614 }
615
620 Scalar d2(Tensor const& e1, Tensor const &e2) const
621 {
622 auto eps1 = pack(orthT*e1*orth);
623 auto eps2 = pack(orthT*e2*orth);
624 auto sigma = stiffness * eps2;
625 return sigma*eps1;
626 }
627
628 Scalar d3(Tensor const& e1, Tensor const& e2, Tensor const &e3) const
629 {
630 return 0.0;
631 }
632
633 Scalar d4(Tensor const& e1, Tensor const& e2, Tensor const &e3, Tensor const &e4) const
634 {
635 return 0.0;
636 }
637
638 private:
639 Dune::FieldMatrix<Scalar,dim,dim> orth; // the orthonormal matrix mapping material to global coordinates
640 Dune::FieldMatrix<Scalar,dim,dim> orthT; // the transposed orthonormal matrix mapping material to global coordinates (for convenience)
641 Dune::FieldMatrix<Scalar,dim*(dim+1)/2,dim*(dim+1)/2> stiffness;
642 Dune::FieldMatrix<Scalar,dim,dim> e; // the linearization point
643 };
644 // ---------------------------------------------------------------------------------------------------------
645
646 template <int dim, class Scalar=double>
647 class OrthotropicNonLinearMaterial : public MaterialLawBase<dim,Scalar,OrthotropicLinearMaterial<dim,Scalar>>
648 {
649
651
652 public:
653
670 : orth(orth_), orthT(transpose(orth_)), e(0), a(0), G(0)
671 {
672
673
674
675 Scalar D = 0.75 * (2/(mat_[0][0]*mat_[1][1]) + 2/(mat_[1][1]*mat_[2][2]) + 2/(mat_[2][2]*mat_[0][0])
676 - 1/(mat_[0][0]*mat_[0][0]) - 1/(mat_[1][1]*mat_[1][1]) - 1/(mat_[2][2]*mat_[2][2]));
677
678 //Materialparameters aij
679a[0][0] = 1/D * (2/(3*mat_[1][1]) + 2/(3*mat_[2][2]) - 1/(3*mat_[0][0]));
680a[0][1] = 1/D * (1/(6*mat_[0][0]) + 1/(6*mat_[1][1]) - 5/(6*mat_[2][2]));
681a[0][2] = 1/D * (1/(6*mat_[0][0]) + 1/(6*mat_[2][2]) - 5/(6*mat_[1][1]));
682
683a[1][0] = 1/D * (1/(6*mat_[1][1]) + 1/(6*mat_[0][0]) - 5/(6*mat_[2][2]));
684a[1][1] = 1/D * (2/(3*mat_[2][2]) + 2/(3*mat_[0][0]) - 1/(3*mat_[1][1]));
685a[1][2] = 1/D * (1/(6*mat_[1][1]) + 1/(6*mat_[2][2]) - 5/(6*mat_[0][0]));
686
687a[2][0] = 1/D * (1/(6*mat_[2][2]) + 1/(6*mat_[0][0]) - 5/(6*mat_[1][1]));
688a[2][1] = 1/D * (1/(6*mat_[2][2]) + 1/(6*mat_[1][1]) - 5/(6*mat_[0][0]));
689a[2][2] = 1/D * (2/(3*mat_[1][1]) + 2/(3*mat_[0][0]) - 1/(3*mat_[2][2]));
690
691 //std::cout << a << "\n";
692
693 //Materialparameters Gij
694 G[0][1] = mat_[0][1]; G[0][2] = mat_[0][2];
695 G[1][0] = mat_[0][1]; G[1][2] = mat_[1][2];
696 G[2][0] = mat_[0][2]; G[2][1] = mat_[1][2];
697
698 // stiffness tensor see http://en.wikipedia.org/wiki/Orthotropic_material
699 stiffness[0][0] = a[0][0] ; stiffness[0][1] = a[0][1] ; stiffness[0][2] = a[0][2] ;
700 stiffness[1][0] = a[1][0] ; stiffness[1][1] = a[1][1] ; stiffness[1][2] = a[1][2] ;
701 stiffness[2][0] = a[2][0] ; stiffness[2][1] = a[2][1] ; stiffness[2][2] = a[2][2] ;
702
703 stiffness[3][3] = mat_[1][2];
704 stiffness[4][4] = mat_[0][2];
705 stiffness[5][5] = mat_[0][1];
706
707 //std::cout << stiffness << "\n";
708
709 // Structural tensor
710 x[0] =1;x[1] =0;x[2] =0;
711 y[0] =0;y[1] =1;y[2] =0;
712 z[0] =0;z[1] =0;z[2] =1;
713
714 L[0] = outerProduct(orth*x,orth*x);
715 L[1] = outerProduct(orth*y,orth*y);
716 L[2] = outerProduct(orth*z,orth*z);
717
718 /*
719 std::cout << "L0"<< "\n" <<L[0] << "\n" << std::endl;
720 std::cout << "L1"<< "\n" <<L[1] << "\n" << std::endl;
721 std::cout << "L2"<< "\n" <<L[2] << "\n" << std::endl;
722 */
723
724 }
725
740 Dune::FieldMatrix<Scalar,dim,dim> const& mat1, Dune::FieldVector<Scalar,dim*(dim-1)/2> const& mat2)
741 : orth(orth_), orthT(transpose(orth_)), stiffness(0), e(0)
742 {
743 for (int i=0; i<dim; ++i)
744 for (int j=0; j<dim; ++j)
745 stiffness[i][j] = mat1[i][j];
746 for (int i=0; i<dim*(dim-1)/2; ++i)
747 stiffness[dim+i][dim+i] = mat2[i];
748 }
749
756 : orth(unitMatrix<Scalar,dim>()), orthT(unitMatrix<Scalar,dim>()), stiffness(0), e(0)
757 {
758 Scalar lambda = p.lame(), mu = p.shear();
759 if (dim==2)
760 {
761 stiffness[0][0] = stiffness[1][1] = 2*mu + lambda;
762 stiffness[1][0] = stiffness[0][1] = lambda;
763 stiffness[2][2] = mu;
764 }
765 if (dim==3)
766 abort();
767 }
768
776
785 Dune::FieldMatrix<Scalar,dim*(dim+1)/2,dim*(dim+1)/2> const& stiffnessMatrix() const { return stiffness; }
786
791 {
792 e = e_;
793 }
794
798 Scalar d0() const
799 {
800
801 Scalar shear = 0 , eps = 0;
803
804 for(unsigned int i = 0 ; i < dim ; ++i)
805 {
806 for(unsigned int j = 0 ; j < dim ; ++j)
807 {
808 //eps += a[i][j]*contraction(transpose(e),L[i])*contraction(transpose(e),L[j]);
809 eps += a[i][j]*trace(e*(L[i]))*trace(e*(L[j]));
810 }
811 }
812
813 for(unsigned int i = 0 ; i < dim ; ++i)
814 {
815 auto A = e*L[i];
816 for(unsigned int j = 0 ; j < dim ; ++j)
817 {
818 if(i==j)
819 {continue;}
820
821 auto B = e.rightmultiplyany(L[j]);
822
823 shear += G[i][j]*trace(A.rightmultiplyany(B));
824 }
825 }
826
827
828 return 0.5 * eps + shear;
829 }
830
835 Scalar d1(Tensor const& e1) const
836 {
837 Scalar shear = 0 , eps = 0;
838 Dune::FieldMatrix<Scalar, 3 ,3> A(0), B(0), C(0), D(0);
839
840 for(unsigned int i = 0 ; i < dim ; ++i)
841 {
842 for(unsigned int j = 0 ; j < dim ; ++j)
843 {
844 eps += a[i][j]*(trace(e*(L[i]))*trace(e1*(L[j]))
845 +trace(e1*(L[i]))*trace(e*(L[j])));
846 }
847 }
848
849 for(unsigned int i = 0 ; i < dim ; ++i)
850 {
851 auto A = e.rightmultiplyany(L[i]);
852 auto C = e1.rightmultiplyany(L[i]);
853
854 for(unsigned int j = 0 ; j < dim ; ++j)
855 {
856 if(i==j)
857 {continue;}
858
859 auto B = e1.rightmultiplyany(L[j]);
860 auto D = e.rightmultiplyany(L[j]);
861
862 shear += G[i][j]*(trace(A.rightmultiplyany(B))+trace(C.rightmultiplyany(D)));
863 }
864 }
865
866
867
868
869 return 0.5 * eps + shear;
870 }
871
876 Scalar d2(Tensor const& e1, Tensor const &e2) const
877 {
878
879 Scalar shear = 0 , eps = 0;
880 Dune::FieldMatrix<Scalar, 3 ,3> A(0),B(0),C(0),D(0);
881
882 for(unsigned int i = 0 ; i < dim ; ++i)
883 {
884 for(unsigned int j = 0 ; j < dim ; ++j)
885 {
886 eps += a[i][j]*(trace(e2*L[i])*trace(e1*L[j])
887 +trace(e1*L[i])*trace(e2 *L[j]));
888 }
889 }
890
891 for(unsigned int i = 0 ; i < dim ; ++i)
892 {
893 auto A = e2*L[i];
894 auto C = e1*L[i];
895
896 for(unsigned int j = 0 ; j < dim ; ++j)
897 {
898 if(i==j)
899 {continue;}
900
901 auto B = e1*L[j];
902 auto D = e2*L[j];
903
904 shear += G[i][j]*(trace(A.rightmultiplyany(B))+trace(C.rightmultiplyany(D)));
905 }
906 }
907
908 return 0.5 * eps + shear;
909 }
910
911 Scalar d3(Tensor const& e1, Tensor const& e2, Tensor const &e3) const
912 {
913 return 0.0;
914 }
915
916 Scalar d4(Tensor const& e1, Tensor const& e2, Tensor const &e3, Tensor const &e4) const
917 {
918 return 0.0;
919 }
920
921 private:
922 Dune::FieldMatrix<Scalar,dim,dim> orth; // the orthonormal matrix mapping material to global coordinates
923 Dune::FieldMatrix<Scalar,dim,dim> orthT; // the transposed orthonormal matrix mapping material to global coordinates (for convenience)
924 Dune::FieldMatrix<Scalar,dim*(dim+1)/2,dim*(dim+1)/2> stiffness;
925 Dune::FieldMatrix<Scalar,dim,dim> e; // the linearization point
926 Dune::FieldMatrix<Scalar,dim,dim> a; // Materialparameters
927 Dune::FieldMatrix<Scalar,dim,dim> G; // Materialparameters
930
931 };
932 // ---------------------------------------------------------------------------------------------------------
933
960 template <int dimension>
962 {
963 public:
967 using Scalar = double;
968
972 static int const dim = dimension;
973
978
985 MooneyRivlin(double c1_, double c2_, double c3_=0.0)
986 : c1(c1_), c2(dim==3?c2_:0), c3(c3_)
987 {}
988
993 {
994 i1 = i[0];
995 i2 = i[1];
996 id = i[dim-1];
997 }
998
1002 Scalar d0() const
1003 {
1004 return c1*i1 + c2*i2 + c3*id*id/(1+id);
1005 }
1006
1010 Scalar d1(Invariants const& di1) const
1011 {
1012 return c1*di1[0] + c2*di1[1] + c3*id*(2+id)/square(1+id)*di1[dim-1];
1013 }
1014
1018 Scalar d2(Invariants const& di1, Invariants const& di2) const
1019 {
1020 return 2 / power(1+id,3) *di1[dim-1]*di2[dim-1];
1021 }
1022
1023 private:
1024 double i1, i2, id, c1, c2, c3;
1025 };
1026
1027 // ------------------------------------------------------------------------------------------
1028
1049 template <int dimension>
1050 class NeoHookean: public MooneyRivlin<dimension>
1051 {
1052 public:
1054
1059 NeoHookean(ElasticModulus const& moduli): MooneyRivlin<dimension>(moduli.shear()/2,0)
1060 {}
1061 };
1062
1063 // ------------------------------------------------------------------------------------------
1064
1081 template <int dimension>
1083 {
1084 public:
1088 using Scalar = double;
1089
1093 static int const dim = dimension;
1094
1099
1105 : mu(moduli.shear()), a(2*moduli.poisson()/(1-2*moduli.poisson())), pstable(1,0)
1106 {
1107 assert(a>0);
1108 }
1109
1114 {
1115 i1 = i[0];
1116 i3 = i[dimension-1];
1117 pstable = Pstable(-a/2,i3);
1118 }
1119
1123 Scalar d0() const
1124 {
1125 return mu*(i1 + 2*pstable.d0()/a)/2;
1126 }
1127
1131 Scalar d1(Invariants const& di1) const
1132 {
1133 return mu*(di1[0] + 2*pstable.d1(di1[dimension-1])/a)/2;
1134 }
1135
1139 Scalar d2(Invariants const& di1, Invariants const& di2) const
1140 {
1141 return mu*pstable.d2(di1[dimension-1],di2[dimension-1])/a;
1142 }
1143
1144 private:
1145 double i1, i3, mu, a;
1146 Pstable pstable;
1147 };
1148
1149
1150 // ---------------------------------------------------------------------------------------------------------
1151
1165 template <class HyperelasticEnergy>
1166 class ViscoPlasticEnergy: public HyperelasticEnergy
1167 {
1168 public:
1169 using Scalar = typename HyperelasticEnergy::Scalar;
1170 static int const dim = HyperelasticEnergy::dim;
1171
1173
1178
1184 template<typename... Args>
1185 ViscoPlasticEnergy(Tensor const& evp_, Args&&... args): HyperelasticEnergy(std::forward<Args>(args)...), evp(evp_)
1186 {}
1187
1192 {
1193 HyperelasticEnergy::setLinearizationPoint(e-evp);
1194 }
1195
1196 private:
1197 Tensor evp;
1198 };
1199
1200 // ---------------------------------------------------------------------------------------------------------
1201
1226 template <int dim, class Scalar>
1228
1229 // ---------------------------------------------------------------------------------------------------------
1230
1247 template <int dim, class Scalar=double>
1248 Dune::FieldVector<Scalar,dim*(dim+1)/2>
1249 duvautLionsJ2Flow(Dune::FieldMatrix<Scalar,dim,dim> const& cauchyStress, Dune::FieldMatrix<Scalar,dim*(dim+1)/2,dim*(dim+1)/2> const& C, double tau, double sigmaY);
1250
1251 // ---------------------------------------------------------------------------------------------------------
1252
1253 }
1254 }
1255}
1256
1257#endif
A class for computing determinants and their derivatives.
Material parameters for isotropic linearly elastic materials.
Definition: elasto.hh:53
double shear() const
Returns the shear modulus , also known as Lame's second parameter .
Definition: elasto.hh:76
double lame() const
Returns the first Lame parameter .
Definition: elasto.hh:85
DetIpm1< dim, Scalar > const & determinant() const
The shifted determinant of the original Green Lagrange strain tensor.
Definition: elasto.hh:598
Tensor d0() const
The isochoric linearized Green-Lagrange strain tensor .
Definition: elasto.hh:573
Tensor d2(Tensor const &dE1, Tensor const &dE2) const
The second derivative of the linearized Green-Lagrange strain tensor in direction dv,...
Definition: elasto.hh:590
Tensor d1(Tensor const &dE) const
The first derivative of the linearized Green-Lagrange strain tensor in direction de.
Definition: elasto.hh:581
Blatz-Ko material law for rubber foams in terms of the shifted invariants of the doubled Green-Lagra...
Scalar d2(Invariants const &di1, Invariants const &di2) const
Evaluates the second directional derivative .
double Scalar
The scalar field type (usually double).
Scalar d1(Invariants const &di1) const
Evaluates the first directional derivative .
void setLinearizationPoint(Invariants const &i)
Sets a new linearization point.
Scalar d0() const
Evaluates the stored energy density .
static int const dim
The spatial dimension (2 or 3).
BlatzKo(ElasticModulus const &moduli)
Constructor.
Adaptor for hyperelastic material laws, providing an easy way to formulate compressible material laws...
Scalar d1(Tensor const &e1) const
Evaluates the first directional derivative .
void setLinearizationPoint(Tensor const &e)
Defines a new evaluation/linearization point.
Scalar d0() const
Evaluates the stored energy density .
Scalar d2(Tensor const &e1, Tensor const &e2) const
Evaluates the second directional derivative .
Adaptor for hyperelastic material laws, providing an easy way to formulate incompressible material la...
Scalar d0() const
Evaluates the stored energy density .
Scalar d1(Tensor const &e1) const
Evaluates the first directional derivative .
Scalar d2(Tensor const &e1, Tensor const &e2) const
Evaluates the second directional derivative .
void setLinearizationPoint(Tensor const &e)
Defines a new evaluation/linearization point.
Base class for hyperelastic material laws, providing default implementations of the stress and the ta...
Definition: materialLaws.hh:53
Tensor stress() const
Returns the second Piola-Kirchhoff stress tensor corresponding to the current strain .
Definition: materialLaws.hh:65
VoigtTensor strainToStressMatrix() const
Returns the tangent stiffness tensor mapping strain tensor variations to stress tensor (2nd Piola-Ki...
Mooney-Rivlin material law formulated in terms of the (shifted) invariants of the doubled Green-Lagr...
double Scalar
The scalar field type (usually double).
static int const dim
The spatial dimension (2 or 3).
MooneyRivlin(double c1_, double c2_, double c3_=0.0)
Constructor.
Scalar d0() const
Evaluates the stored energy density .
Scalar d1(Invariants const &di1) const
Evaluates the first directional derivative .
void setLinearizationPoint(Invariants const &i)
Sets a new linearization point.
Scalar d2(Invariants const &di1, Invariants const &di2) const
Evaluates the second directional derivative .
Neo-Hookean material law formulated in terms of the shifted invariants of the doubled Green-Lagrange...
NeoHookean(ElasticModulus const &moduli)
Constructor.
Scalar d1(Tensor const &e1) const
Computes the first derivative of the elastic energy in the direction .
Scalar d4(Tensor const &e1, Tensor const &e2, Tensor const &e3, Tensor const &e4) const
OrthotropicLinearMaterial(ElasticModulus const &p)
Default constructor.
OrthotropicLinearMaterial(Dune::FieldMatrix< Scalar, dim, dim > const &orth_, Dune::FieldMatrix< Scalar, dim, dim > const &mat_)
Constructor.
Dune::FieldMatrix< Scalar, dim *(dim+1)/2, dim *(dim+1)/2 > const & stiffnessMatrix() const
Returns the stiffness tensor.
void setLinearizationPoint(Tensor const &e_)
Defines the GreenLagrangeTensor around which to linearize.
Scalar d3(Tensor const &e1, Tensor const &e2, Tensor const &e3) const
OrthotropicLinearMaterial(Dune::FieldMatrix< Scalar, dim, dim > const &orth_, Dune::FieldMatrix< Scalar, dim, dim > const &mat1, Dune::FieldVector< Scalar, dim *(dim-1)/2 > const &mat2)
Constructor.
Scalar d2(Tensor const &e1, Tensor const &e2) const
Computes the second derivative of the elastic energy in directions .
OrthotropicNonLinearMaterial(ElasticModulus const &p)
Default constructor.
Scalar d3(Tensor const &e1, Tensor const &e2, Tensor const &e3) const
Dune::FieldMatrix< Scalar, dim *(dim+1)/2, dim *(dim+1)/2 > const & stiffnessMatrix() const
Returns the stiffness tensor.
Scalar d4(Tensor const &e1, Tensor const &e2, Tensor const &e3, Tensor const &e4) const
void setLinearizationPoint(Tensor const &e_)
Defines the GreenLagrangeTensor around which to linearize.
Scalar d1(Tensor const &e1) const
Computes the first derivative of the elastic energy in the direction .
OrthotropicNonLinearMaterial(Dune::FieldMatrix< Scalar, dim, dim > const &orth_, Dune::FieldMatrix< Scalar, dim, dim > const &mat_)
Constructor.
OrthotropicNonLinearMaterial(Dune::FieldMatrix< Scalar, dim, dim > const &orth_, Dune::FieldMatrix< Scalar, dim, dim > const &mat1, Dune::FieldVector< Scalar, dim *(dim-1)/2 > const &mat2)
Constructor.
Scalar d2(Tensor const &e1, Tensor const &e2) const
Computes the second derivative of the elastic energy in directions .
The St. Venant-Kirchhoff material, foundation of linear elastomechanics.
Scalar d1(Tensor const &e1) const
Evaluates the first directional derivative .
Scalar d3(Tensor const &e1, Tensor const &e2, Tensor const &e3) const
Evaluates the third directional derivative .
StVenantKirchhoff(ElasticModulus const &moduli, Scalar alpha_=0)
Constructor.
Scalar d0() const
Evaluates the stored energy density .
Scalar d2(Tensor const &e1, Tensor const &e2) const
Evaluates the second directional derivative .
void setLinearizationPoint(Tensor const &e_)
Defines the linearization/evaluation point for subsequent calls to d0, d1, d2.
StVenantKirchhoff(ElasticModulus const &moduli, Tensor const &e_)
Constructor.
StVenantKirchhoff()=default
Pretty useless default constructor.
Scalar d4(Tensor const &, Tensor const &, Tensor const &, Tensor const &) const
Evaluates the fourth directional derivative .
An adaptor for using hyperelastic stored energies for viscoplasticity.
void setLinearizationPoint(Tensor const &e)
Sets a new linearization point.
ViscoPlasticEnergy(Tensor const &evp_, Args &&... args)
Constructor.
Numerically stable evaluation of .
Definition: elasto.hh:211
double d1(double dx) const
Definition: elasto.hh:220
double d2(double dx1, double dx2) const
Definition: elasto.hh:221
Invariants d1(Tensor const &dA) const
Invariants d2(Tensor const &dA1, Tensor const &dA2) const
A class for representing tensors of arbitrary static rank and extents.
Definition: tensor.hh:86
Dune::FieldVector< Scalar, n *(n+1)/2 > pack(Dune::FieldMatrix< Scalar, n, n > const &e, Scalar s=2.0)
Returns the Voigt vector representation of a symmetric matrix (with or without doubled off-diagonal e...
Dune::FieldMatrix< Scalar, ElastoDetails::dim(n), ElastoDetails::dim(n)> unpack(Dune::FieldVector< Scalar, n > const &c, Scalar s=2.0)
Returns the symmetric matrix representation of a Voigt vector with or without doubled off-diagonal en...
Dune::FieldMatrix< T, n, m > outerProduct(Dune::FieldVector< T, n > const &x, Dune::FieldVector< T, m > const &y)
outer vector product .
Definition: fixdune.hh:164
T trace(Dune::FieldMatrix< T, n, n > const &A)
Matrix trace .
Definition: fixdune.hh:515
Dune::FieldMatrix< T, n, n > unitMatrix()
Returns the identity matrix of size n .
Definition: fixdune.hh:555
T determinant(Dune::FieldMatrix< T, n, n > const &A)
Matrix determinant .
Definition: fixdune.hh:531
T contraction(Dune::FieldMatrix< T, n, m > const &A, Dune::FieldMatrix< T, n, m > const &B)
Matrix contraction (Frobenius product) .
Definition: fixdune.hh:494
R power(R base, int exp)
Computes integral powers of values in a multiplicative half-group.
Definition: power.hh:30
R square(R x)
returns the square of its argument.
Definition: power.hh:49
Scalar vonMisesStress(Dune::FieldMatrix< Scalar, dim, dim > const &stress)
Computes the von Mises equivalent stress .
Dune::FieldVector< Scalar, dim *(dim+1)/2 > duvautLionsJ2Flow(Dune::FieldMatrix< Scalar, dim, dim > const &cauchyStress, Dune::FieldMatrix< Scalar, dim *(dim+1)/2, dim *(dim+1)/2 > const &C, double tau, double sigmaY)
A simple Duvaut-Lions flow rule with (von Mises) yield surface.
Functional::Scalar d1(Assembler &assembler, Functional const &f, typename Functional::AnsatzVars::VariableSet &x, typename Functional::Scalar tolerance=1e-6, typename Functional::Scalar increment=1e-12, bool toFile=false, std::string const &filename=std::string("d1error"))
Functional::Scalar d2(Assembler &assembler, Functional const &f, typename Functional::AnsatzVars::VariableSet const &x, typename Functional::Scalar increment=1e-12, typename Functional::Scalar tolerance=1e-6, bool toFile=false, std::string const &savefilename=std::string("d2error"))
T transpose(T x)