void HookesLaw::compute_stress_imp( unsigned int dim, const libMesh::TensorValue<libMesh::Real>& g_contra, const libMesh::TensorValue<libMesh::Real>& g_cov, const libMesh::TensorValue<libMesh::Real>& /*G_contra*/, const libMesh::TensorValue<libMesh::Real>& G_cov, libMesh::TensorValue<libMesh::Real>& stress ) { stress.zero(); for( unsigned int i = 0; i < dim; i++ ) { for( unsigned int j = 0; j < dim; j++ ) { for( unsigned int k = 0; k < dim; k++ ) { for( unsigned int l = 0; l < dim; l++ ) { libMesh::Real strain_kl = 0.5*(G_cov(k,l) - g_cov(k,l)); _C(i,j,k,l) = _lambda*g_contra(i,j)*g_contra(k,l) + _mu*(g_contra(i,k)*g_contra(j,l) + g_contra(i,l)*g_contra(j,k)); stress(i,j) += _C(i,j,k,l)*strain_kl; } } } } return; }
void IncompressiblePlaneStressHyperelasticity<StrainEnergy>::compute_stress_imp( unsigned int /*dim*/, const libMesh::TensorValue<libMesh::Real>& a_contra, const libMesh::TensorValue<libMesh::Real>& a_cov, const libMesh::TensorValue<libMesh::Real>& A_contra, const libMesh::TensorValue<libMesh::Real>& A_cov, libMesh::TensorValue<libMesh::Real>& stress ) { // We're treating a_* and A_* as 2x2, but we're cheating to pick up lambda^2 libMesh::Real lambda_sq = A_cov(2,2); libMesh::Real A_over_a = 1.0/lambda_sq; // We're incompressible libMesh::Real I1, I2; this->compute_I1_I2(a_contra,a_cov,A_contra,A_cov,lambda_sq,A_over_a,I1,I2); libMesh::Real a_term, A_term; this->compute_stress_terms( lambda_sq, A_over_a, I1, I2, a_term, A_term ); // Now compute stress stress.zero(); for( unsigned int alpha = 0; alpha < 2; alpha++ ) { for( unsigned int beta = 0; beta < 2; beta++ ) { stress(alpha,beta) = a_contra(alpha,beta)*a_term + A_contra(alpha,beta)*A_term; } } return; }
void IncompressiblePlaneStressHyperelasticity<StrainEnergy>::compute_stress_deriv_terms( libMesh::Real lambda_sq, libMesh::Real A_over_a, libMesh::Real I1, libMesh::Real I2, const libMesh::TensorValue<libMesh::Real>& a_contra, const libMesh::TensorValue<libMesh::Real>& A_contra, libMesh::TensorValue<libMesh::Real>& daterm_dstrain, libMesh::TensorValue<libMesh::Real>& dAterm_dstrain) const { daterm_dstrain.zero(); dAterm_dstrain.zero(); libMesh::Real dWdI1 = _W.dI1(I1,I2,1.0); // We're incompressible libMesh::Real dWdI2 = _W.dI2(I1,I2,1.0); // A = det(A_cov) = 1/det(A_contra) //libMesh::Real A = 1.0/( A_contra(0,0)*A_contra(1,1) - A_contra(0,1)*A_contra(1,0) ); for( unsigned int alpha = 0; alpha < 2; alpha++ ) { for( unsigned int beta = 0; beta < 2; beta++ ) { // a_term = 2.0*(dWdI1 + dWdI2*lambda^2); // => da_dstrain = 2.0*dWdI2*dlambda^2_dstrain // dlambda_sq_dstrain = -2*lambda^2 A^{alpha,beta} const libMesh::Real dlamsq_dstrain = -2.0*lambda_sq*A_contra(alpha,beta); daterm_dstrain(alpha,beta) = 2.0*dWdI2*dlamsq_dstrain; // A_term = 2.0*dWdI2*A_over_a + p; // A = det(A_cov) ==> dA_dstrain = 2*A*A_contra(alpha,beta) // p = -2.0*lambda_sq*( dWdI1 + dWdI2*(I1-lambda_sq) ); const libMesh::Real dI1_dstrain = 2.0*a_contra(alpha,beta) + dlamsq_dstrain; const libMesh::Real dp_dstrain = -2.0*dlamsq_dstrain*( dWdI1 + dWdI2*(I1-lambda_sq) ) -2.0*lambda_sq*dWdI2*(dI1_dstrain - dlamsq_dstrain); dAterm_dstrain(alpha,beta) = 2.0*dWdI2*A_over_a*(2.0*A_contra(alpha,beta)) + dp_dstrain; } } return; }
void Hyperelasticity<StrainEnergy>::compute_stress_imp( unsigned int dim, const libMesh::TensorValue<libMesh::Real>& g_contra, const libMesh::TensorValue<libMesh::Real>& g_cov, const libMesh::TensorValue<libMesh::Real>& G_contra, const libMesh::TensorValue<libMesh::Real>& G_cov, libMesh::TensorValue<libMesh::Real>& stress ) { stress.zero(); // Compute strain invariants libMesh::Real I3 = (g_contra*G_cov).det(); libMesh::Real I1 = 0.0; libMesh::Real I2 = 0.0; for( unsigned int i = 0; i < dim; i++ ) { for( unsigned int j = 0; j < dim; j++ ) { I1 += g_contra(i,j)*G_cov(i,j); I2 += G_contra(i,j)*g_cov(i,j); } } I2 *= I3; libMesh::Real dWdI1 = _W.dI1(I1,I2,I3); libMesh::Real dWdI2 = _W.dI2(I1,I2,I3); libMesh::Real dWdI3 = _W.dI3(I1,I2,I3); // Now compute stress for( unsigned int i = 0; i < dim; i++ ) { for( unsigned int j = 0; j < dim; j++ ) { for( unsigned int k = 0; k < dim; k++ ) { for( unsigned int l = 0; l < dim; l++ ) { stress(i,j) += 2.0*dWdI1*g_contra(i,j) + 2.0*dWdI2*(I1*g_contra(i,j) - g_contra(i,k)*g_contra(j,l)*G_cov(k,l)) + 2.0*dWdI3*G_contra(i,j); } } } } return; }
void IncompressiblePlaneStressHyperelasticity<StrainEnergy>::compute_stress_and_elasticity_imp( unsigned int /*dim*/, const libMesh::TensorValue<libMesh::Real>& a_contra, const libMesh::TensorValue<libMesh::Real>& a_cov, const libMesh::TensorValue<libMesh::Real>& A_contra, const libMesh::TensorValue<libMesh::Real>& A_cov, libMesh::TensorValue<libMesh::Real>& stress, ElasticityTensor& C) { // We're treating a_* and A_* as 2x2, but we're cheating to pick up lambda^2 libMesh::Real lambda_sq = A_cov(2,2); libMesh::Real A_over_a = 1.0/lambda_sq; // We're incompressible libMesh::Real I1, I2; this->compute_I1_I2(a_contra,a_cov,A_contra,A_cov,lambda_sq,A_over_a,I1,I2); libMesh::Real a_term, A_term; this->compute_stress_terms( lambda_sq, A_over_a, I1, I2, a_term, A_term ); libMesh::TensorValue<libMesh::Real> daterm_dstrain, dAterm_dstrain; this->compute_stress_deriv_terms( lambda_sq, A_over_a, I1, I2, a_contra, A_contra, daterm_dstrain, dAterm_dstrain ); ElasticityTensor dAcontra_dstrain; this->compute_Acontra_deriv( A_contra, dAcontra_dstrain ); // Now compute stress stress.zero(); for( unsigned int alpha = 0; alpha < 2; alpha++ ) { for( unsigned int beta = 0; beta < 2; beta++ ) { stress(alpha,beta) = a_contra(alpha,beta)*a_term + A_contra(alpha,beta)*A_term; for( unsigned int lambda = 0; lambda < 2; lambda++ ) { for( unsigned int mu = 0; mu < 2; mu++ ) { C(alpha,beta,lambda,mu) = a_contra(alpha,beta)*daterm_dstrain(lambda,mu) + dAcontra_dstrain(alpha,beta,lambda,mu)*A_term + A_contra(alpha,beta)*dAterm_dstrain(lambda,mu); } } } } return; }