@@ -96,41 +96,48 @@ class Ogden: public HyperelasticMaterial<DataTypes>
9696
9797 void deriveSPKTensor (StrainInformation<DataTypes> *sinfo, const MaterialParameters<DataTypes> ¶m,MatrixSym &SPKTensorGeneral) override
9898 {
99- Real k0=param.parameterArray [0 ];
100- Real mu1=param.parameterArray [1 ];
101- Real alpha1=param.parameterArray [2 ];
102- MatrixSym C=sinfo->deformationTensor ;
99+ const MatrixSym& C=sinfo->deformationTensor ;
100+ const Real k0 = param.parameterArray [0 ];
101+ const Real mu1 = param.parameterArray [1 ];
102+ const Real alpha1 = param.parameterArray [2 ];
103+ const Real fj = pow (sinfo->J , -alpha1/3 .0_sreal);
104+
105+ // Solve eigen problem for C
103106 Eigen::Matrix<Real,3 ,3 > CEigen;
104107 CEigen (0 ,0 )=C[0 ]; CEigen (0 ,1 )=C[1 ]; CEigen (1 ,0 )=C[1 ]; CEigen (1 ,1 )=C[2 ]; CEigen (1 ,2 )=C[4 ]; CEigen (2 ,1 )=C[4 ];
105108 CEigen (2 ,0 )=C[3 ]; CEigen (0 ,2 )=C[3 ]; CEigen (2 ,2 )=C[5 ];
106109
107- /* Eigen::SelfAdjointEigenSolver<EigenMatrix>*/
108- Eigen::EigenSolver<Eigen::Matrix<Real, 3 , 3 > > EigenProblemSolver (CEigen,true );
110+ // Disable temporarilly until fixed / *Eigen::SelfAdjointEigenSolver<EigenMatrix>*/
111+ Eigen::EigenSolver<Eigen::Matrix<Real, 3 , 3 > > EigenProblemSolver (CEigen, true );
109112 if (EigenProblemSolver.info () != Eigen::Success)
110113 {
111114 dmsg_warning (" Ogden" ) << " SelfAdjointEigenSolver iterations failed to converge" ;
112115 return ;
113116 }
114- EigenMatrix Evect= EigenProblemSolver.eigenvectors ().real ();
115- CoordEigen Evalue= EigenProblemSolver.eigenvalues ().real ();
117+ const EigenMatrix Evect = EigenProblemSolver.eigenvectors ().real (); // orthonormal eigenvectors
118+ const CoordEigen Evalue = EigenProblemSolver.eigenvalues ().real ();
116119
117- Real trCalpha=pow (Evalue[0 ],alpha1/(Real)2 )+pow (Evalue[1 ],alpha1/(Real)2 )+pow (Evalue[2 ],alpha1/(Real)2 );
118- Matrix3 Pinverse;
119- Pinverse (0 ,0 )=Evect (0 ,0 ); Pinverse (1 ,1 )=Evect (1 ,1 ); Pinverse (2 ,2 )=Evect (2 ,2 ); Pinverse (0 ,1 )=Evect (1 ,0 ); Pinverse (1 ,0 )=Evect (0 ,1 ); Pinverse (2 ,0 )=Evect (0 ,2 );
120- Pinverse (0 ,2 )=Evect (2 ,0 ); Pinverse (2 ,1 )=Evect (1 ,2 ); Pinverse (1 ,2 )=Evect (2 ,1 );
121- MatrixSym Dalpha_1=MatrixSym (pow (Evalue[0 ],alpha1/(Real)2.0 -(Real)1.0 ),0 ,pow (Evalue[1 ],alpha1/(Real)2.0 -(Real)1.0 ),0 ,0 ,pow (Evalue[2 ],alpha1/(Real)2.0 -(Real)1.0 ));
122- MatrixSym Calpha_1; Matrix3 Ca;
123- Ca=Pinverse.transposed ()*Dalpha_1.SymMatMultiply (Pinverse);
124- Calpha_1.Mat2Sym (Ca,Calpha_1);
125- MatrixSym inversematrix;
126- invertMatrix (inversematrix,sinfo->deformationTensor );
127- // SPKTensorGeneral=(-(Real)1.0/(Real)3.0*trCalpha*inversematrix+Calpha_1)*(mu1/alpha1*pow(sinfo->J,-alpha1/(Real)3.0))+inversematrix*k0*log(sinfo->J);
128- Real fj= (Real)(pow (sinfo->J ,(Real)(-alpha1/3.0 )));
129- // Contributions to S from derivatives of strain energy w.r.t. C from
130- const MatrixSym partialLambda = 0.5 * Calpha_1;
131- const MatrixSym partialFJ = -1 / 6 . * trCalpha * inversematrix;
132- const MatrixSym partialLogJ = k0 * log (sinfo->J ) * inversematrix;
133- SPKTensorGeneral = 2 . * fj * mu1 / alpha1 * (partialLambda + partialFJ) + partialLogJ;
120+ // trace of C^(alpha1/2)
121+ const Real aBy2 = alpha1*0 .5_sreal;
122+ const Real trCaBy2 = pow (Evalue[0 ], aBy2) + pow (Evalue[1 ], aBy2) + pow (Evalue[2 ], aBy2);
123+
124+ // Transpose (also inverse) of the eigenvector matrix
125+ Matrix3 EigenBasis;
126+ for (auto m = 0 ; m < Evect.rows (); ++m)
127+ for (auto n = 0 ; n < Evect.cols (); ++n) EigenBasis (m, n) = Evect (m, n);
128+
129+ // Construct C^(alpha1/2 - 1) from eigenbasis: V * D * V^T; D_i = lambda_i^(alpha1/2 - 1)
130+ const Real aBy2Minus1 = aBy2 - 1_sreal;
131+ const MatrixSym D = MatrixSym (pow (Evalue[0 ], aBy2Minus1), 0 , pow (Evalue[1 ], aBy2Minus1), 0 , 0 , pow (Evalue[2 ], aBy2Minus1));
132+ const Matrix3 Ca = EigenBasis*D.SymMatMultiply (EigenBasis.transposed ());
133+ MatrixSym CaBy2Minus1;
134+ sofa::type::MatSym<3 >::Mat2Sym (Ca, CaBy2Minus1);
135+
136+ // Invert deformation tensor
137+ MatrixSym invC;
138+ invertMatrix (invC, C);
139+
140+ SPKTensorGeneral = fj * mu1 / alpha1 * (CaBy2Minus1 + -1_sreal/3_sreal * trCaBy2 * invC) + k0*log (sinfo->J )*invC;
134141 }
135142
136143
0 commit comments