Example #1
0
RankTwoTensor
RankTwoTensor::dsin3Lode(const Real r0) const
{
  Real bar = secondInvariant();
  if (bar <= r0)
    return RankTwoTensor();
  else
    return -1.5 * std::sqrt(3.0) * (dthirdInvariant() / std::pow(bar, 1.5) - 1.5 * dsecondInvariant() * thirdInvariant() / std::pow(bar, 2.5));
}
Example #2
0
Real
RankTwoTensor::sin3Lode(const Real r0, const Real r0_value) const
{
  Real bar = secondInvariant();
  if (bar <= r0)
    // in this case the Lode angle is not defined
    return r0_value;
  else
    // the min and max here gaurd against precision-loss when bar is tiny but nonzero.
    return std::max(std::min(-1.5 * std::sqrt(3.0) * thirdInvariant() / std::pow(bar, 1.5), 1.0), -1.0);
}
    /** The elasticity tensor in material description.
     *  Using expressions (6.193/4) from Holzapfel (2000), identifying the
     *  invariant \f$ I_2 \f$ from here with his \f$ I_3 \f$, and discarding all
     *  terms in that book with derivatives w.r.t \f$ I_2 \f$ gives finally
     *  \f[
     *       C_{ABCD} =
     *          \delta_1 \delta_{AB} \delta_{CD} +
     *          \delta_3 (\delta_{AB} C^{-1}_{CD} + C^{-1}_{AB} \delta_{CD})
     *          \delta_6 C^{-1}_{AB} C^{-1}_{CD} +
     *    \frac{\delta_7}{2} (C^{-1}_{AC} C^{-1}_{BD} + C^{-1}_{AD} C^{-1}_{BC} )
     *  \f]
     *  where the factors are
     *  \f[
     *     \delta_1 = 4 \frac{\partial^2 W}{\partial I_1^2} \qquad
     *     \delta_3 = 4 \det{C} \frac{\partial^2 W}{\partial I_1 \partial I_2}
     *     \qquad
     *     \delta_6 = 4 \left( \det(C) \frac{\partial   W}{\partial I_2} +
     *                       \det(C)^2 \frac{\partial^2 W}{\partial I_2^2} \right)
     *     \qquad
     *     \delta_7 = -4 \det{C} \frac{\partial W}{\partial I_2}
     *  \f]
     *
     *  Note: The storage is based on the minor symmetries.
     *  \param[in]  F  Deformation gradient
     *  \param[out] C  Elasticity tensor
     */
    void materialElasticityTensor( const Tensor& F, ElastTensor& CE ) const
    {
        // compute Cauchy-Green stretch tensor
        Tensor C;
        mat::rightCauchyGreen( F, C );

        Tensor Cinv;
        const double detC = mat::inverseAndDet( C, Cinv );

        // invariants
        const double I1 = firstInvariant( C );
        const double I2 = secondInvariant( C );

        // energy derivatives
        const double dWdI2 = energy_.dWdI2( I1, I2 );

        const double d2WdI1dI1 = energy_.d2WdI1dI1( I1, I2 );
        const double d2WdI2dI2 = energy_.d2WdI2dI2( I1, I2 );
        const double d2WdI1dI2 = energy_.d2WdI1dI2( I1, I2 );

        // constant factors (non-zero ones)
        const double d1 =  4. * d2WdI1dI1;
        const double d3 =  4. * detC * d2WdI1dI2;
        const double d6 =  4. * ( detC * dWdI2 + detC*detC * d2WdI2dI2 );
        const double d7 = -4. * detC * dWdI2;
        
        // clear to zero 
        CE = ElastTensor::Constant( 0. );

        // go through all 81 indices
        for ( unsigned I = 0; I < 3; I++ ) {
            for ( unsigned J = 0; J <=I ; J++ ) {
                const unsigned v1 = mat::Voigt::apply( I, J );
                
                for ( unsigned K = 0; K < 3; K++ ) {
                    for ( unsigned L = 0; L <=K ; L++ ) {

                        const unsigned v2 = mat::Voigt::apply( K, L );
                        
                        CE( v1, v2 ) +=
                            d1    * (I==J and K==L ? 1. : 0.) +
                            d3    * (I==J ? Cinv(K,L) : 0.) +
                            d3    * (K==L ? Cinv(I,J) : 0.) + 
                            d6    *  Cinv(I,J) * Cinv(K,L) +
                            d7/2. * (Cinv(I,K) * Cinv(J,L) + Cinv(I,L) * Cinv(J,K));
                    }
                }
            }
        }

        return;
    }
Example #4
0
RankFourTensor
RankTwoTensor::d2sin3Lode(const Real r0) const
{
  Real bar = secondInvariant();
  if (bar <= r0)
    return RankFourTensor();

  Real J3 = thirdInvariant();
  RankTwoTensor dII = dsecondInvariant();
  RankTwoTensor dIII = dthirdInvariant();
  RankFourTensor deriv = d2thirdInvariant()/std::pow(bar, 1.5) - 1.5*d2secondInvariant()*J3/std::pow(bar, 2.5);

  for (unsigned i = 0; i < N; ++i)
    for (unsigned j = 0; j < N; ++j)
      for (unsigned k = 0; k < N; ++k)
        for (unsigned l = 0; l < N; ++l)
          deriv(i, j, k, l) += (-1.5*dII(i, j)*dIII(k, l) -1.5 * dIII(i, j) * dII(k, l)) / std::pow(bar, 2.5) + 1.5*2.5*dII(i, j) * dII(k, l) * J3 / std::pow(bar, 3.5);

  deriv *= -1.5 * std::sqrt(3.0);
  return deriv;
}
Example #5
0
RankTwoTensor
RankTwoTensor::dthirdInvariant() const
{
  RankTwoTensor s = 0.5 * deviatoric();
  s += s.transpose();

  RankTwoTensor d;
  Real sec_over_three = secondInvariant() / 3.0;

  d(0, 0) = s(1, 1) * s(2, 2) - s(2, 1) * s(1, 2) + sec_over_three;
  d(0, 1) = s(2, 0) * s(1, 2) - s(1, 0) * s(2, 2);
  d(0, 2) = s(1, 0) * s(2, 1) - s(2, 0) * s(1, 1);
  d(1, 0) = s(2, 1) * s(0, 2) - s(0, 1) * s(2, 2);
  d(1, 1) = s(0, 0) * s(2, 2) - s(2, 0) * s(0, 2) + sec_over_three;
  d(1, 2) = s(2, 0) * s(0, 1) - s(0, 0) * s(2, 1);
  d(2, 0) = s(0, 1) * s(1, 2) - s(1, 1) * s(0, 2);
  d(2, 1) = s(1, 0) * s(0, 2) - s(0, 0) * s(1, 2);
  d(2, 2) = s(0, 0) * s(1, 1) - s(1, 0) * s(0, 1) + sec_over_three;

  return d;
}
    /** The second Piola-Kirchhoff stress tensor S.
     *  The definition \f$ S = \partial \psi / \partial E \f$ yields
     *  \f[
     *    S = 2 \left( \frac{\partial W}{\partial I_1} I +
     *                 \frac{\partial W}{\partial I_2} \det{C} C^{-1} \right)
     *  \f]
     *  \param[in]  F  Deformation gradient
     *  \param[out] S  2nd Piola-Kirchhoff stress tensor
     */
    void secondPiolaKirchhoff( const Tensor& F, Tensor& S ) const
    {
        // compute Cauchy-Green stretch tensor
        Tensor C;
        mat::rightCauchyGreen( F, C );

        Tensor Cinv;
        const double detC = mat::inverseAndDet( C, Cinv );
        
        // invariants
        const double I1 = firstInvariant( C );
        const double I2 = secondInvariant( C );

        // energy derivatives
        const double dWdI1 = energy_.dWdI1( I1, I2 );
        const double dWdI2 = energy_.dWdI2( I1, I2 );

        // evaluate the second Piola-Kirchhoff stress tensor
        S.noalias() =
            2. * dWdI1 * Tensor::Identity() + 2. * dWdI2 * detC * Cinv;
    }