RankFourTensor
TensorMechanicsPlasticDruckerPrager::dflowPotential_dstress(const RankTwoTensor & stress,
                                                            Real /*intnl*/) const
{
  RankFourTensor dr_dstress;
  dr_dstress = 0.5 * stress.d2secondInvariant() / std::sqrt(stress.secondInvariant());
  dr_dstress += -0.5 * 0.5 * stress.dsecondInvariant().outerProduct(stress.dsecondInvariant()) /
                std::pow(stress.secondInvariant(), 1.5);
  return dr_dstress;
}
Esempio n. 2
0
void
RankTwoTensorTest::d2secondInvariantTest()
{
  // Here i do a finite-difference calculation of the second
  // derivative and compare with the closed-solution form
  Real ep = 1E-5; // small finite-difference parameter

  RankTwoTensor d1; // first derivative of secondInvariant - from RankTwoTensor - do a finite-difference of this
  RankFourTensor d2; // second derivative of second Invariant - from RankTwoTensor
  RankTwoTensor mep; // matrix with shifted entries
  RankTwoTensor d1ep; // first derivative of secondInvariant of mep


  mep = _m3;
  d1 = _m3.dsecondInvariant();
  d2 = _m3.d2secondInvariant();
  for (unsigned i = 0; i < 3; i++)
    for (unsigned j = 0; j < 3; j++)
    {
      for (unsigned int k = 0; k < 3; k++)
        for (unsigned int l = 0; l < 3; l++)
        {
          mep(k, l) += ep;
          d1ep = mep.dsecondInvariant();
          CPPUNIT_ASSERT_DOUBLES_EQUAL((d1ep(i, j) - d1(i, j))/ep, d2(i, j, k, l), ep);
          mep(k, l) -= ep;
        }
    }

  mep = _unsymmetric1;
  d1 = _unsymmetric1.dsecondInvariant();
  d2 = _unsymmetric1.d2secondInvariant();
  for (unsigned i = 0; i < 3; i++)
    for (unsigned j = 0; j < 3; j++)
    {
      for (unsigned int k = 0; k < 3; k++)
        for (unsigned int l = 0; l < 3; l++)
        {
          mep(k, l) += ep;
          d1ep = mep.dsecondInvariant();
          CPPUNIT_ASSERT_DOUBLES_EQUAL((d1ep(i, j) - d1(i, j))/ep, d2(i, j, k, l), ep);
          mep(k, l) -= ep;

          // note that because d1 and d2 explicitly symmeterise the matrix
          // the derivative may or may not explicitly symmeterise
          mep(k, l) += 0.5*ep;
          mep(l, k) += 0.5*ep;
          d1ep = mep.dsecondInvariant();
          CPPUNIT_ASSERT_DOUBLES_EQUAL((d1ep(i, j) - d1(i, j))/ep, d2(i, j, k, l), ep);
          mep(k, l) -= 0.5*ep;
          mep(l, k) -= 0.5*ep;
        }
    }
}
RankTwoTensor
TensorMechanicsPlasticTensile::dyieldFunction_dstress(const RankTwoTensor & stress,
                                                      Real /*intnl*/) const
{
  Real mean_stress = stress.trace() / 3.0;
  RankTwoTensor dmean_stress = stress.dtrace() / 3.0;
  Real sin3Lode = stress.sin3Lode(_lode_cutoff, 0);
  if (sin3Lode <= _sin3tt)
  {
    // the non-edge-smoothed version
    std::vector<Real> eigvals;
    std::vector<RankTwoTensor> deigvals;
    stress.dsymmetricEigenvalues(eigvals, deigvals);
    Real denom = std::sqrt(smooth(stress) + Utility::pow<2>(eigvals[2] - mean_stress));
    return dmean_stress + (0.5 * dsmooth(stress) * dmean_stress +
                           (eigvals[2] - mean_stress) * (deigvals[2] - dmean_stress)) /
                              denom;
  }
  else
  {
    // the edge-smoothed version
    Real kk = _aaa + _bbb * sin3Lode + _ccc * Utility::pow<2>(sin3Lode);
    RankTwoTensor dkk = (_bbb + 2.0 * _ccc * sin3Lode) * stress.dsin3Lode(_lode_cutoff);
    Real sibar2 = stress.secondInvariant();
    RankTwoTensor dsibar2 = stress.dsecondInvariant();
    Real denom = std::sqrt(smooth(stress) + sibar2 * Utility::pow<2>(kk));
    return dmean_stress + (0.5 * dsmooth(stress) * dmean_stress +
                           0.5 * dsibar2 * Utility::pow<2>(kk) + sibar2 * kk * dkk) /
                              denom;
  }
}
RankTwoTensor
FiniteStrainPlasticMaterial::dyieldFunction_dstress(const RankTwoTensor & sig)
{
  RankTwoTensor deriv = sig.dsecondInvariant();
  deriv *= std::sqrt(3.0 / sig.secondInvariant()) / 2.0;
  return deriv;
}
RankTwoTensor
TensorMechanicsPlasticJ2::dyieldFunction_dstress(const RankTwoTensor & stress, Real /*intnl*/) const
{
  Real sII = stress.secondInvariant();
  if (sII == 0.0)
    return RankTwoTensor();
  else
    return 0.5 * std::sqrt(3.0 / sII) * stress.dsecondInvariant();
}
Esempio n. 6
0
RankFourTensor
TensorMechanicsPlasticTensile::dflowPotential_dstress(const RankTwoTensor & stress, const Real & intnl) const
{
  Real mean_stress = stress.trace()/3.0;
  RankTwoTensor dmean_stress = stress.dtrace()/3.0;
  Real sin3Lode = stress.sin3Lode(_lode_cutoff, 0);
  if (sin3Lode <= _sin3tt)
  {
    // the non-edge-smoothed version
    std::vector<Real> eigvals;
    std::vector<RankTwoTensor> deigvals;
    std::vector<RankFourTensor> d2eigvals;
    stress.dsymmetricEigenvalues(eigvals, deigvals);
    stress.d2symmetricEigenvalues(d2eigvals);

    Real denom = std::sqrt(_small_smoother2 + std::pow(eigvals[2] - mean_stress, 2));

    RankFourTensor dr_dstress = (eigvals[2] - mean_stress)*d2eigvals[2]/denom;
    for (unsigned i = 0 ; i < 3 ; ++i)
      for (unsigned j = 0 ; j < 3 ; ++j)
        for (unsigned k = 0 ; k < 3 ; ++k)
          for (unsigned l = 0 ; l < 3 ; ++l)
            dr_dstress(i, j, k, l) += (1 - std::pow((eigvals[2] - mean_stress)/denom, 2))*(deigvals[2](i, j) - dmean_stress(i, j))*(deigvals[2](k, l) - dmean_stress(k, l))/denom;
    return dr_dstress;
  }
  else
  {
    // the edge-smoothed version
    RankTwoTensor dsin3Lode = stress.dsin3Lode(_lode_cutoff);
    Real kk = _aaa + _bbb*sin3Lode + _ccc*std::pow(sin3Lode, 2);
    RankTwoTensor dkk = (_bbb + 2*_ccc*sin3Lode)*dsin3Lode;
    RankFourTensor d2kk = (_bbb + 2*_ccc*sin3Lode)*stress.d2sin3Lode(_lode_cutoff);
    for (unsigned i = 0 ; i < 3 ; ++i)
      for (unsigned j = 0 ; j < 3 ; ++j)
        for (unsigned k = 0 ; k < 3 ; ++k)
          for (unsigned l = 0 ; l < 3 ; ++l)
            d2kk(i, j, k, l) += 2*_ccc*dsin3Lode(i, j)*dsin3Lode(k, l);

    Real sibar2 = stress.secondInvariant();
    RankTwoTensor dsibar2 = stress.dsecondInvariant();
    RankFourTensor d2sibar2 = stress.d2secondInvariant();

    Real denom = std::sqrt(_small_smoother2 + sibar2*std::pow(kk, 2));
    RankFourTensor dr_dstress = (0.5*d2sibar2*std::pow(kk, 2) + sibar2*kk*d2kk)/denom;
    for (unsigned i = 0 ; i < 3 ; ++i)
      for (unsigned j = 0 ; j < 3 ; ++j)
        for (unsigned k = 0 ; k < 3 ; ++k)
          for (unsigned l = 0 ; l < 3 ; ++l)
          {
            dr_dstress(i, j, k, l) += (dsibar2(i, j)*dkk(k, l)*kk + dkk(i, j)*dsibar2(k, l)*kk + sibar2*dkk(i, j)*dkk(k, l))/denom;
            dr_dstress(i, j, k, l) -= (0.5*dsibar2(i, j)*std::pow(kk, 2) + sibar2*kk*dkk(i, j))*(0.5*dsibar2(k, l)*std::pow(kk, 2) + sibar2*kk*dkk(k, l))/std::pow(denom, 3);
          }
    return dr_dstress;
  }
}
RankFourTensor
TensorMechanicsPlasticJ2::dflowPotential_dstress(const RankTwoTensor & stress, Real /*intnl*/) const
{
  Real sII = stress.secondInvariant();
  if (sII == 0)
    return RankFourTensor();

  RankFourTensor dfp = 0.5 * std::sqrt(3.0 / sII) * stress.d2secondInvariant();
  Real pre = -0.25 * std::sqrt(3.0) * std::pow(sII, -1.5);
  RankTwoTensor dII = stress.dsecondInvariant();
  for (unsigned i = 0; i < 3; ++i)
    for (unsigned j = 0; j < 3; ++j)
      for (unsigned k = 0; k < 3; ++k)
        for (unsigned l = 0; l < 3; ++l)
          dfp(i, j, k, l) += pre * dII(i, j) * dII(k, l);
  return dfp;
}
RankFourTensor
TensorMechanicsPlasticTensile::dflowPotential_dstress(const RankTwoTensor & stress,
                                                      Real /*intnl*/) const
{
  Real mean_stress = stress.trace() / 3.0;
  RankTwoTensor dmean_stress = stress.dtrace() / 3.0;
  Real sin3Lode = stress.sin3Lode(_lode_cutoff, 0);
  if (sin3Lode <= _sin3tt)
  {
    // the non-edge-smoothed version
    std::vector<Real> eigvals;
    std::vector<RankTwoTensor> deigvals;
    std::vector<RankFourTensor> d2eigvals;
    stress.dsymmetricEigenvalues(eigvals, deigvals);
    stress.d2symmetricEigenvalues(d2eigvals);

    Real denom = std::sqrt(smooth(stress) + Utility::pow<2>(eigvals[2] - mean_stress));
    Real denom3 = Utility::pow<3>(denom);
    RankTwoTensor numer_part = deigvals[2] - dmean_stress;
    RankTwoTensor numer_full =
        0.5 * dsmooth(stress) * dmean_stress + (eigvals[2] - mean_stress) * numer_part;
    Real d2smooth_over_denom = d2smooth(stress) / denom;

    RankFourTensor dr_dstress = (eigvals[2] - mean_stress) * d2eigvals[2] / denom;
    for (unsigned i = 0; i < 3; ++i)
      for (unsigned j = 0; j < 3; ++j)
        for (unsigned k = 0; k < 3; ++k)
          for (unsigned l = 0; l < 3; ++l)
          {
            dr_dstress(i, j, k, l) +=
                0.5 * d2smooth_over_denom * dmean_stress(i, j) * dmean_stress(k, l);
            dr_dstress(i, j, k, l) += numer_part(i, j) * numer_part(k, l) / denom;
            dr_dstress(i, j, k, l) -= numer_full(i, j) * numer_full(k, l) / denom3;
          }
    return dr_dstress;
  }
  else
  {
    // the edge-smoothed version
    RankTwoTensor dsin3Lode = stress.dsin3Lode(_lode_cutoff);
    Real kk = _aaa + _bbb * sin3Lode + _ccc * Utility::pow<2>(sin3Lode);
    RankTwoTensor dkk = (_bbb + 2.0 * _ccc * sin3Lode) * dsin3Lode;
    RankFourTensor d2kk = (_bbb + 2.0 * _ccc * sin3Lode) * stress.d2sin3Lode(_lode_cutoff);
    for (unsigned i = 0; i < 3; ++i)
      for (unsigned j = 0; j < 3; ++j)
        for (unsigned k = 0; k < 3; ++k)
          for (unsigned l = 0; l < 3; ++l)
            d2kk(i, j, k, l) += 2.0 * _ccc * dsin3Lode(i, j) * dsin3Lode(k, l);

    Real sibar2 = stress.secondInvariant();
    RankTwoTensor dsibar2 = stress.dsecondInvariant();
    RankFourTensor d2sibar2 = stress.d2secondInvariant();

    Real denom = std::sqrt(smooth(stress) + sibar2 * Utility::pow<2>(kk));
    Real denom3 = Utility::pow<3>(denom);
    Real d2smooth_over_denom = d2smooth(stress) / denom;
    RankTwoTensor numer_full =
        0.5 * dsmooth(stress) * dmean_stress + 0.5 * dsibar2 * kk * kk + sibar2 * kk * dkk;

    RankFourTensor dr_dstress = (0.5 * d2sibar2 * Utility::pow<2>(kk) + sibar2 * kk * d2kk) / denom;
    for (unsigned i = 0; i < 3; ++i)
      for (unsigned j = 0; j < 3; ++j)
        for (unsigned k = 0; k < 3; ++k)
          for (unsigned l = 0; l < 3; ++l)
          {
            dr_dstress(i, j, k, l) +=
                0.5 * d2smooth_over_denom * dmean_stress(i, j) * dmean_stress(k, l);
            dr_dstress(i, j, k, l) +=
                (dsibar2(i, j) * dkk(k, l) * kk + dkk(i, j) * dsibar2(k, l) * kk +
                 sibar2 * dkk(i, j) * dkk(k, l)) /
                denom;
            dr_dstress(i, j, k, l) -= numer_full(i, j) * numer_full(k, l) / denom3;
          }
    return dr_dstress;
  }
}
RankTwoTensor
TensorMechanicsPlasticDruckerPrager::df_dsig(const RankTwoTensor & stress, Real bbb) const
{
  return 0.5 * stress.dsecondInvariant() / std::sqrt(stress.secondInvariant()) +
         stress.dtrace() * bbb;
}