コード例 #1
0
RankFourTensor
TensorMechanicsPlasticOrthotropic::dflowPotential_dstress(const RankTwoTensor & stress,
                                                          Real /*intnl*/) const
{
  if (_associative)
  {
    const RankTwoTensor j2prime = _l1 * stress;
    const RankTwoTensor j3prime = _l2 * stress;
    const RankTwoTensor dj2 = dj2_dSkl(j2prime);
    const RankTwoTensor dj3 = j3prime.ddet();
    const Real j2 = -j2prime.generalSecondInvariant();
    const Real j3 = j3prime.det();
    const RankFourTensor dr =
        dfj2_dj2(j2, j3) *
            _l1.innerProductTranspose(dj2).outerProduct(_l1.innerProductTranspose(dj2)) +
        dfj2_dj3(j2, j3) *
            _l1.innerProductTranspose(dj2).outerProduct(_l2.innerProductTranspose(dj3)) +
        dfj3_dj2(j2, j3) *
            _l2.innerProductTranspose(dj3).outerProduct(_l1.innerProductTranspose(dj2)) +
        dfj3_dj3(j2, j3) *
            _l2.innerProductTranspose(dj3).outerProduct(_l2.innerProductTranspose(dj3));
    const RankTwoTensor r = _b * dI_sigma() +
                            dphi_dj2(j2, j3) * _l1.innerProductTranspose(dj2_dSkl(j2prime)) +
                            dphi_dj3(j2, j3) * _l2.innerProductTranspose(j3prime.ddet());
    const Real norm = r.L2norm();
    return dr / norm - (r / Utility::pow<3>(norm)).outerProduct(dr.innerProductTranspose(r));
  }
  else
    return TensorMechanicsPlasticJ2::dflowPotential_dstress(stress, 0);
}
コード例 #2
0
void
StressDivergenceTensors::computeFiniteDeformJacobian()
{
  const RankTwoTensor I(RankTwoTensor::initIdentity);
  const RankFourTensor II_ijkl = I.mixedProductIkJl(I);

  // Bring back to unrotated config
  const RankTwoTensor unrotated_stress =
      (*_rotation_increment)[_qp].transpose() * _stress[_qp] * (*_rotation_increment)[_qp];

  // Incremental deformation gradient Fhat
  const RankTwoTensor Fhat =
      (*_deformation_gradient)[_qp] * (*_deformation_gradient_old)[_qp].inverse();
  const RankTwoTensor Fhatinv = Fhat.inverse();

  const RankTwoTensor rot_times_stress = (*_rotation_increment)[_qp] * unrotated_stress;
  const RankFourTensor dstress_drot =
      I.mixedProductIkJl(rot_times_stress) + I.mixedProductJkIl(rot_times_stress);
  const RankFourTensor rot_rank_four =
      (*_rotation_increment)[_qp].mixedProductIkJl((*_rotation_increment)[_qp]);
  const RankFourTensor drot_dUhatinv = Fhat.mixedProductIkJl(I);

  const RankTwoTensor A = I - Fhatinv;

  // Ctilde = Chat^-1 - I
  const RankTwoTensor Ctilde = A * A.transpose() - A - A.transpose();
  const RankFourTensor dCtilde_dFhatinv =
      -I.mixedProductIkJl(A) - I.mixedProductJkIl(A) + II_ijkl + I.mixedProductJkIl(I);

  // Second order approximation of Uhat - consistent with strain increment definition
  // const RankTwoTensor Uhat = I - 0.5 * Ctilde - 3.0/8.0 * Ctilde * Ctilde;

  RankFourTensor dUhatinv_dCtilde =
      0.5 * II_ijkl - 1.0 / 8.0 * (I.mixedProductIkJl(Ctilde) + Ctilde.mixedProductIkJl(I));
  RankFourTensor drot_dFhatinv = drot_dUhatinv * dUhatinv_dCtilde * dCtilde_dFhatinv;

  drot_dFhatinv -= Fhat.mixedProductIkJl((*_rotation_increment)[_qp].transpose());
  _finite_deform_Jacobian_mult[_qp] = dstress_drot * drot_dFhatinv;

  const RankFourTensor dstrain_increment_dCtilde =
      -0.5 * II_ijkl + 0.25 * (I.mixedProductIkJl(Ctilde) + Ctilde.mixedProductIkJl(I));
  _finite_deform_Jacobian_mult[_qp] +=
      rot_rank_four * _Jacobian_mult[_qp] * dstrain_increment_dCtilde * dCtilde_dFhatinv;
  _finite_deform_Jacobian_mult[_qp] += Fhat.mixedProductJkIl(_stress[_qp]);

  const RankFourTensor dFhat_dFhatinv = -Fhat.mixedProductIkJl(Fhat.transpose());
  const RankTwoTensor dJ_dFhatinv = dFhat_dFhatinv.innerProductTranspose(Fhat.ddet());

  // Component from Jacobian derivative
  _finite_deform_Jacobian_mult[_qp] += _stress[_qp].outerProduct(dJ_dFhatinv);

  // Derivative of Fhatinv w.r.t. undisplaced coordinates
  const RankTwoTensor Finv = (*_deformation_gradient)[_qp].inverse();
  const RankFourTensor dFhatinv_dGradu = -Fhatinv.mixedProductIkJl(Finv.transpose());
  _finite_deform_Jacobian_mult[_qp] = _finite_deform_Jacobian_mult[_qp] * dFhatinv_dGradu;
}
コード例 #3
0
// Jacobian for stress update algorithm
void
FiniteStrainPlasticMaterial::getJac(const RankTwoTensor & sig,
                                    const RankFourTensor & E_ijkl,
                                    Real flow_incr,
                                    RankFourTensor & dresid_dsig)
{
  RankTwoTensor sig_dev, df_dsig, flow_dirn;
  RankTwoTensor dfi_dft, dfi_dsig;
  RankFourTensor dft_dsig, dfd_dft, dfd_dsig;
  Real sig_eqv;
  Real f1, f2, f3;
  RankFourTensor temp;

  sig_dev = sig.deviatoric();
  sig_eqv = getSigEqv(sig);
  df_dsig = dyieldFunction_dstress(sig);
  flow_dirn = flowPotential(sig);

  f1 = 3.0 / (2.0 * sig_eqv);
  f2 = f1 / 3.0;
  f3 = 9.0 / (4.0 * Utility::pow<3>(sig_eqv));

  dft_dsig = f1 * _deltaMixed - f2 * _deltaOuter - f3 * sig_dev.outerProduct(sig_dev);

  dfd_dsig = dft_dsig;
  dresid_dsig = E_ijkl.invSymm() + dfd_dsig * flow_incr;
}
コード例 #4
0
//Jacobian for stress update algorithm
void
FiniteStrainPlasticMaterial::getJac(RankTwoTensor sig, RankFourTensor E_ijkl, Real flow_incr, RankFourTensor* dresid_dsig)
{

  RankTwoTensor sig_dev, flow_tensor, flow_dirn;
  RankTwoTensor dfi_dft,dfi_dsig;
  RankFourTensor dft_dsig,dfd_dft,dfd_dsig;
  Real sig_eqv/*,val*/;
  Real f1,f2,f3;
  RankFourTensor temp;


  sig_dev=getSigDev(sig);
  sig_eqv=getSigEqv(sig);
  getFlowTensor(sig,&flow_tensor);
  flow_dirn=flow_tensor;


  f1=3.0/(2.0*sig_eqv);
  f2=f1/3.0;
  f3=9.0/(4.0*pow(sig_eqv,3.0));

  for (int i=0;i<3;i++)
    for (int j=0;j<3;j++)
      for (int k=0;k<3;k++)
        for (int l=0;l<3;l++)
          dft_dsig(i,j,k,l)=f1*deltaFunc(i,k)*deltaFunc(j,l)-f2*deltaFunc(i,j)*deltaFunc(k,l)-f3*sig_dev(i,j)*sig_dev(k,l);

  dfd_dsig=dft_dsig;
  *dresid_dsig=E_ijkl.invSymm()+dfd_dsig*flow_incr;


}
コード例 #5
0
//Jacobian for stress update algorithm
void
FiniteStrainRatePlasticMaterial::getJac(const RankTwoTensor & sig, const RankFourTensor & E_ijkl, Real flow_incr, Real yield_stress, RankFourTensor & dresid_dsig)
{
  unsigned i, j, k ,l;
  RankTwoTensor sig_dev, flow_tensor, flow_dirn,fij;
  RankTwoTensor dfi_dft;
  RankFourTensor dft_dsig, dfd_dft, dfd_dsig, dfi_dsig;
  Real sig_eqv;
  Real f1, f2, f3;
  Real dfi_dseqv;

  sig_dev = sig.deviatoric();
  sig_eqv = getSigEqv(sig);

  getFlowTensor(sig, yield_stress, flow_tensor);

  flow_dirn = flow_tensor;
  dfi_dseqv = _ref_pe_rate * _dt * _exponent * std::pow(macaulayBracket(sig_eqv / yield_stress - 1.0), _exponent - 1.0) / yield_stress;

  for (i = 0; i < 3; ++i)
    for (j = 0; j < 3; ++j)
      for (k = 0; k < 3; ++k)
        for (l = 0; l < 3; ++l)
          dfi_dsig(i,j,k,l) = flow_dirn(i,j) * flow_dirn(k,l) * dfi_dseqv; //d_flow_increment/d_sig

  f1 = 0.0;
  f2 = 0.0;
  f3 = 0.0;

  if (sig_eqv > 1e-8)
  {
    f1 = 3.0 / (2.0 * sig_eqv);
    f2 = f1 / 3.0;
    f3 = 9.0 / (4.0 * std::pow(sig_eqv, 3.0));
  }

  for (i = 0; i < 3; ++i)
    for (j = 0; j < 3; ++j)
      for (k = 0; k < 3; ++k)
        for (l = 0; l < 3; ++l)
          dft_dsig(i,j,k,l) = f1 * deltaFunc(i,k) * deltaFunc(j,l) - f2 * deltaFunc(i,j) * deltaFunc(k,l) - f3 * sig_dev(i,j) * sig_dev(k,l); //d_flow_dirn/d_sig - 2nd part

  dfd_dsig = dft_dsig; //d_flow_dirn/d_sig
  dresid_dsig = E_ijkl.invSymm() + dfd_dsig * flow_incr + dfi_dsig; //Jacobian
}
コード例 #6
0
//Jacobian for stress update algorithm
void
FiniteStrainRatePlasticMaterial::getJac(const RankTwoTensor & sig, const RankFourTensor & E_ijkl, Real flow_incr, Real yield_stress, RankFourTensor & dresid_dsig)
{
  RankTwoTensor sig_dev, flow_tensor, flow_dirn,fij;
  RankTwoTensor dfi_dft;
  RankFourTensor dfd_dft, dfd_dsig, dfi_dsig;
  Real sig_eqv;
  Real f1, f2, f3;
  Real dfi_dseqv;

  sig_dev = sig.deviatoric();
  sig_eqv = getSigEqv(sig);

  getFlowTensor(sig, yield_stress, flow_tensor);

  flow_dirn = flow_tensor;
  dfi_dseqv = _ref_pe_rate * _dt * _exponent * std::pow(macaulayBracket(sig_eqv / yield_stress - 1.0), _exponent - 1.0) / yield_stress;

  dfi_dsig = flow_dirn.outerProduct(flow_dirn) * dfi_dseqv; //d_flow_increment/d_sig

  f1 = 0.0;
  f2 = 0.0;
  f3 = 0.0;

  if (sig_eqv > 1e-8)
  {
    f1 = 3.0 / (2.0 * sig_eqv);
    f2 = f1 / 3.0;
    f3 = 9.0 / (4.0 * std::pow(sig_eqv, 3.0));
  }

  dfd_dsig = f1 * _deltaMixed - f2 * _deltaOuter - f3 * sig_dev.outerProduct(sig_dev); //d_flow_dirn/d_sig - 2nd part

  //Jacobian
  dresid_dsig = E_ijkl.invSymm() + dfd_dsig * flow_incr + dfi_dsig;
}
コード例 #7
0
void
RedbackMechMaterialCC::getJac(const RankTwoTensor & sig,
                              const RankFourTensor & E_ijkl,
                              Real flow_incr,
                              Real sig_eqv,
                              Real pressure,
                              Real p_yield_stress,
                              Real q_yield_stress,
                              Real pc,
                              RankFourTensor & dresid_dsig)
{
  unsigned i, j, k, l;
  RankTwoTensor sig_dev, flow_dirn_vol, flow_dirn_dev, fij, flow_dirn, flow_tensor;
  RankTwoTensor dfi_dft;
  RankFourTensor dfd_dsig, dfi_dsig;
  Real f1, f2;
  Real dfi_dseqv_dev, dfi_dseqv_vol, dfi_dseqv;

  pc *= -1;

  sig_dev = sig.deviatoric();

  dfi_dseqv = getDerivativeFlowIncrement(sig, pressure, sig_eqv, pc, q_yield_stress, p_yield_stress);
  getFlowTensor(sig, sig_eqv, pressure, pc, flow_dirn);

  /* The following calculates the tensorial derivative (Jacobian) of the residual with respect to stress, dr_dsig
   * It consists of two terms: The first is
   * dr_dsig = (dfi_dseqv_dev*flow_dirn_dev(k,l)) * flow_dirn_dev(i,j)
   * which is the tensorial product of the flow increment tensor times the flow direction tensor
   *
   * The second is the product of the flow increment tensor times the derivative of the flow direction tensor
   * with respect to the stress tensor. See also REDBACK's documentation
   * */

  // This loop calculates the first term
  for (i = 0; i < 3; ++i)
    for (j = 0; j < 3; ++j)
      for (k = 0; k < 3; ++k)
        for (l = 0; l < 3; ++l)
          dfi_dsig(i, j, k, l) = flow_dirn(i, j) * flow_dirn(k, l) * dfi_dseqv;

  // Real flow_tensor_norm = flow_dirn.L2norm();

  // This loop calculates the second term. Read REDBACK's documentation
  // (same as J2 plasticity case)
  f1 = 0.0;
  f2 = 0.0;
  if (sig_eqv > 1e-8)
  {
    f1 = 3.0 / (_slope_yield_surface * _slope_yield_surface);
    f2 = 2.0 / 9.0 - 1.0 / (_slope_yield_surface * _slope_yield_surface);
  }
  for (i = 0; i < 3; ++i)
    for (j = 0; j < 3; ++j)
      for (k = 0; k < 3; ++k)
        for (l = 0; l < 3; ++l)
          dfd_dsig(i, j, k, l) =
            f1 * deltaFunc(i, k) * deltaFunc(j, l) -
            f2 * deltaFunc(i, j) * deltaFunc(k, l); // d_flow_dirn/d_sig - 2nd part (J2 plasticity)

  // dfd_dsig = dft_dsig1/flow_tensor_norm - 3.0 * dft_dsig2 /
  // (2*sig_eqv*flow_tensor_norm*flow_tensor_norm*flow_tensor_norm); //d_flow_dirn/d_sig
  // TODO: check if the previous two lines (i.e normalizing the flow vector) should be activated or not. Currently we
  // are using the non-unitary flow vector

  dresid_dsig = E_ijkl.invSymm() + dfd_dsig * flow_incr + dfi_dsig; // Jacobian
}
コード例 #8
0
void
CappedDruckerPragerCosseratStressUpdate::consistentTangentOperator(
    const RankTwoTensor & /*stress_trial*/,
    Real /*p_trial*/,
    Real /*q_trial*/,
    const RankTwoTensor & stress,
    Real /*p*/,
    Real q,
    Real gaE,
    const yieldAndFlow & smoothed_q,
    const RankFourTensor & Eijkl,
    bool compute_full_tangent_operator,
    RankFourTensor & cto) const
{
  if (!compute_full_tangent_operator)
  {
    cto = Eijkl;
    return;
  }

  RankFourTensor EAijkl;
  for (unsigned i = 0; i < _tensor_dimensionality; ++i)
    for (unsigned j = 0; j < _tensor_dimensionality; ++j)
      for (unsigned k = 0; k < _tensor_dimensionality; ++k)
        for (unsigned l = 0; l < _tensor_dimensionality; ++l)
        {
          cto(i, j, k, l) = 0.5 * (Eijkl(i, j, k, l) + Eijkl(j, i, k, l));
          EAijkl(i, j, k, l) = 0.5 * (Eijkl(i, j, k, l) - Eijkl(j, i, k, l));
        }

  const RankTwoTensor s_over_q =
      (q == 0.0 ? RankTwoTensor()
                : (0.5 * (stress + stress.transpose()) -
                   stress.trace() * RankTwoTensor(RankTwoTensor::initIdentity) / 3.0) /
                      q);
  const RankTwoTensor E_s_over_q = Eijkl.innerProductTranspose(s_over_q); // not symmetric in kl
  const RankTwoTensor Ekl =
      RankTwoTensor(RankTwoTensor::initIdentity).initialContraction(Eijkl); // symmetric in kl

  for (unsigned i = 0; i < _tensor_dimensionality; ++i)
    for (unsigned j = 0; j < _tensor_dimensionality; ++j)
      for (unsigned k = 0; k < _tensor_dimensionality; ++k)
        for (unsigned l = 0; l < _tensor_dimensionality; ++l)
        {
          cto(i, j, k, l) -= (i == j) * (1.0 / 3.0) *
                             (Ekl(k, l) * (1.0 - _dp_dpt) + 0.5 * E_s_over_q(k, l) * (-_dp_dqt));
          cto(i, j, k, l) -=
              s_over_q(i, j) * (Ekl(k, l) * (-_dq_dpt) + 0.5 * E_s_over_q(k, l) * (1.0 - _dq_dqt));
        }

  if (smoothed_q.dg[1] != 0.0)
  {
    const RankFourTensor Tijab = _Ehost * (gaE / _Epp) * smoothed_q.dg[1] * d2qdstress2(stress);
    RankFourTensor inv = RankFourTensor(RankFourTensor::initIdentitySymmetricFour) + Tijab;
    try
    {
      inv = inv.transposeMajor().invSymm();
    }
    catch (const MooseException & e)
    {
      // Cannot form the inverse, so probably at some degenerate place in stress space.
      // Just return with the "best estimate" of the cto.
      mooseWarning("CappedDruckerPragerCosseratStressUpdate: Cannot invert 1+T in consistent "
                   "tangent operator computation at quadpoint ",
                   _qp,
                   " of element ",
                   _current_elem->id());
      return;
    }
    cto = (cto.transposeMajor() * inv).transposeMajor();
  }
  cto += EAijkl;
}
コード例 #9
0
/**
 * Implements the return-map algorithm via a Newton-Raphson process.
 * This idea is fully explained in Simo and Hughes "Computational
 * Inelasticity" Springer 1997, for instance, as well as many other
 * books on plasticity.
 * The basic idea is as follows.
 * Given: sig_old - the stress at the start of the "time step"
 *        plastic_strain_old - the plastic strain at the start of the "time step"
 *        eqvpstrain_old - equivalent plastic strain at the start of the "time step"
 *                         (In general we would be given some number of internal
 *                         parameters that the yield function depends upon.)
 *        delta_d - the prescribed strain increment for this "time step"
 * we want to determine the following parameters at the end of this "time step":
 *        sig - the stress
 *        plastic_strain - the plastic strain
 *        eqvpstrain - the equivalent plastic strain (again, in general, we would
 *                     have an arbitrary number of internal parameters).
 *
 * To determine these parameters, introduce
 *    the "yield function", f
 *    the "consistency parameter", flow_incr
 *    the "flow potential", flow_dirn_ij
 *    the "internal potential", internalPotential (in general there are as many internalPotential
 *        functions as there are internal parameters).
 * All three of f, flow_dirn_ij, and internalPotential, are functions of
 * sig and eqvpstrain.
 * To find sig, plastic_strain and eqvpstrain, we need to solve the following
 *   resid_ij = 0
 *   f = 0
 *   rep = 0
 * This is done by using Newton-Raphson.
 * There are 8 equations here: six from resid_ij=0 (more generally there are nine
 * but in this case resid is symmetric); one from f=0; one from rep=0 (more generally, for N
 * internal parameters there are N of these equations).
 *
 * resid_ij = flow_incr*flow_dirn_ij - (plastic_strain - plastic_strain_old)_ij
 *          = flow_incr*flow_dirn_ij - (E^{-1}(trial_stress - sig))_ij
 * Here trial_stress = E*(strain - plastic_strain_old)
 *      sig = E*(strain - plastic_strain)
 * Note: flow_dirn_ij is evaluated at sig and eqvpstrain (not the old values).
 *
 * f is the yield function, evaluated at sig and eqvpstrain
 *
 * rep = -flow_incr*internalPotential - (eqvpstrain - eqvpstrain_old)
 * Here internalPotential are evaluated at sig and eqvpstrain (not the old values).
 *
 * The Newton-Raphson procedure has sig, flow_incr, and eqvpstrain as its
 * variables.  Therefore we need the derivatives of resid_ij, f, and rep
 * with respect to these parameters
 *
 * In this associative J2 with isotropic hardening, things are a little more specialised.
 * (1) f = sqrt(3*s_ij*s_ij/2) - K(eqvpstrain)    (this is called "isotropic hardening")
 * (2) associativity means that flow_dirn_ij = df/d(sig_ij) = s_ij*sqrt(3/2/(s_ij*s_ij)), and
 *     this means that flow_dirn_ij*flow_dirn_ij = 3/2, so when resid_ij=0, we get
 *     (plastic_strain_dot)_ij*(plastic_strain_dot)_ij = (3/2)*flow_incr^2, where
 *     plastic_strain_dot = plastic_strain - plastic_strain_old
 * (3) The definition of equivalent plastic strain is through
 *     eqvpstrain_dot = sqrt(2*plastic_strain_dot_ij*plastic_strain_dot_ij/3), so
 *     using (2), we obtain eqvpstrain_dot = flow_incr, and this yields
 *     internalPotential = -1 in the "rep" equation.
 */
void
FiniteStrainPlasticMaterial::returnMap(const RankTwoTensor & sig_old,
                                       const Real eqvpstrain_old,
                                       const RankTwoTensor & plastic_strain_old,
                                       const RankTwoTensor & delta_d,
                                       const RankFourTensor & E_ijkl,
                                       RankTwoTensor & sig,
                                       Real & eqvpstrain,
                                       RankTwoTensor & plastic_strain)
{
  // the yield function, must be non-positive
  // Newton-Raphson sets this to zero if trial stress enters inadmissible region
  Real f;

  // the consistency parameter, must be non-negative
  // change in plastic strain in this timestep = flow_incr*flow_potential
  Real flow_incr = 0.0;

  // direction of flow defined by the potential
  RankTwoTensor flow_dirn;

  // Newton-Raphson sets this zero
  // resid_ij = flow_incr*flow_dirn_ij - (plastic_strain - plastic_strain_old)
  RankTwoTensor resid;

  // Newton-Raphson sets this zero
  // rep = -flow_incr*internalPotential - (eqvpstrain - eqvpstrain_old)
  Real rep;

  // change in the stress (sig) in a Newton-Raphson iteration
  RankTwoTensor ddsig;

  // change in the consistency parameter in a Newton-Raphson iteration
  Real dflow_incr = 0.0;

  // change in equivalent plastic strain in one Newton-Raphson iteration
  Real deqvpstrain = 0.0;

  // convenience variable that holds the change in plastic strain incurred during the return
  // delta_dp = plastic_strain - plastic_strain_old
  // delta_dp = E^{-1}*(trial_stress - sig), where trial_stress = E*(strain - plastic_strain_old)
  RankTwoTensor delta_dp;

  // d(yieldFunction)/d(stress)
  RankTwoTensor df_dsig;

  // d(resid_ij)/d(sigma_kl)
  RankFourTensor dr_dsig;

  // dr_dsig_inv_ijkl*dr_dsig_klmn = 0.5*(de_ij de_jn + de_ij + de_jm), where de_ij = 1 if i=j, but
  // zero otherwise
  RankFourTensor dr_dsig_inv;

  // d(yieldFunction)/d(eqvpstrain)
  Real fq;

  // yield stress at the start of this "time step" (ie, evaluated with
  // eqvpstrain_old).  It is held fixed during the Newton-Raphson return,
  // even if eqvpstrain != eqvpstrain_old.
  Real yield_stress;

  // measures of whether the Newton-Raphson process has converged
  Real err1, err2, err3;

  // number of Newton-Raphson iterations performed
  unsigned int iter = 0;

  // maximum number of Newton-Raphson iterations allowed
  unsigned int maxiter = 100;

  // plastic loading occurs if yieldFunction > toly
  Real toly = 1.0e-8;

  // Assume this strain increment does not induce any plasticity
  // This is the elastic-predictor
  sig = sig_old + E_ijkl * delta_d; // the trial stress
  eqvpstrain = eqvpstrain_old;
  plastic_strain = plastic_strain_old;

  yield_stress = getYieldStress(eqvpstrain); // yield stress at this equivalent plastic strain
  if (yieldFunction(sig, yield_stress) > toly)
  {
    // the sig just calculated is inadmissable.  We must return to the yield surface.
    // This is done iteratively, using a Newton-Raphson process.

    delta_dp.zero();

    sig = sig_old + E_ijkl * delta_d; // this is the elastic predictor

    flow_dirn = flowPotential(sig);

    resid = flow_dirn * flow_incr - delta_dp; // Residual 1 - refer Hughes Simo
    f = yieldFunction(sig, yield_stress);
    rep = -eqvpstrain + eqvpstrain_old - flow_incr * internalPotential(); // Residual 3 rep=0

    err1 = resid.L2norm();
    err2 = std::abs(f);
    err3 = std::abs(rep);

    while ((err1 > _rtol || err2 > _ftol || err3 > _eptol) &&
           iter < maxiter) // Stress update iteration (hardness fixed)
    {
      iter++;

      df_dsig = dyieldFunction_dstress(sig);
      getJac(sig, E_ijkl, flow_incr, dr_dsig);   // gets dr_dsig = d(resid_ij)/d(sig_kl)
      fq = dyieldFunction_dinternal(eqvpstrain); // d(f)/d(eqvpstrain)

      /**
       * The linear system is
       *   ( dr_dsig  flow_dirn  0  )( ddsig       )   ( - resid )
       *   ( df_dsig     0       fq )( dflow_incr  ) = ( - f     )
       *   (   0         1       -1 )( deqvpstrain )   ( - rep   )
       * The zeroes are: d(resid_ij)/d(eqvpstrain) = flow_dirn*d(df/d(sig_ij))/d(eqvpstrain) = 0
       * and df/d(flow_dirn) = 0  (this is always true, even for general hardening and
       * non-associative)
       * and d(rep)/d(sig_ij) = -flow_incr*d(internalPotential)/d(sig_ij) = 0
       */

      dr_dsig_inv = dr_dsig.invSymm();

      /**
       * Because of the zeroes and ones, the linear system is not impossible to
       * solve by hand.
       * NOTE: andy believes there was originally a sign-error in the next line.  The
       *       next line is unchanged, however andy's definition of fq is negative of
       *       the original definition of fq.  andy can't see any difference in any tests!
       */
      dflow_incr = (f - df_dsig.doubleContraction(dr_dsig_inv * resid) + fq * rep) /
                   (df_dsig.doubleContraction(dr_dsig_inv * flow_dirn) - fq);
      ddsig =
          dr_dsig_inv *
          (-resid -
           flow_dirn * dflow_incr); // from solving the top row of linear system, given dflow_incr
      deqvpstrain =
          rep + dflow_incr; // from solving the bottom row of linear system, given dflow_incr

      // update the variables
      flow_incr += dflow_incr;
      delta_dp -= E_ijkl.invSymm() * ddsig;
      sig += ddsig;
      eqvpstrain += deqvpstrain;

      // evaluate the RHS equations ready for next Newton-Raphson iteration
      flow_dirn = flowPotential(sig);
      resid = flow_dirn * flow_incr - delta_dp;
      f = yieldFunction(sig, yield_stress);
      rep = -eqvpstrain + eqvpstrain_old - flow_incr * internalPotential();

      err1 = resid.L2norm();
      err2 = std::abs(f);
      err3 = std::abs(rep);
    }

    if (iter >= maxiter)
      mooseError("Constitutive failure");

    plastic_strain += delta_dp;
  }
}
コード例 #10
0
RankFourTensor
TensorMechanicsPlasticTensileMulti::consistentTangentOperator(const RankTwoTensor & trial_stress, const RankTwoTensor & stress, const Real & intnl,
                                                       const RankFourTensor & E_ijkl, const std::vector<Real> & cumulative_pm) const
{
  if (!_use_custom_cto)
    return TensorMechanicsPlasticModel::consistentTangentOperator(trial_stress, stress, intnl, E_ijkl, cumulative_pm);

  mooseAssert(cumulative_pm.size() == 3, "TensorMechanicsPlasticTensileMulti size of cumulative_pm should be 3 but it is " << cumulative_pm.size());

  if (cumulative_pm[2] <= 0) // All cumulative_pm are non-positive, so this is admissible
    return E_ijkl;


  // Need the eigenvalues at the returned configuration
  std::vector<Real> eigvals;
  stress.symmetricEigenvalues(eigvals);

  // need to rotate to and from principal stress space
  // using the eigenvectors of the trial configuration
  // (not the returned configuration).
  std::vector<Real> trial_eigvals;
  RankTwoTensor trial_eigvecs;
  trial_stress.symmetricEigenvaluesEigenvectors(trial_eigvals, trial_eigvecs);

  // The returnMap will have returned to the Tip, Edge or
  // Plane.  The consistentTangentOperator describes the
  // change in stress for an arbitrary change in applied
  // strain.  I assume that the change in strain will not
  // change the type of return (Tip remains Tip, Edge remains
  // Edge, Plane remains Plane).
  // I assume isotropic elasticity.
  //
  // The consistent tangent operator is a little different
  // than cases where no rotation to principal stress space
  // is made during the returnMap.  Let S_ij be the stress
  // in original coordinates, and s_ij be the stress in the
  // principal stress coordinates, so that
  // s_ij = diag(eigvals[0], eigvals[1], eigvals[2])
  // We want dS_ij under an arbitrary change in strain (ep->ep+dep)
  // dS = S(ep+dep) - S(ep)
  //    = R(ep+dep) s(ep+dep) R(ep+dep)^T - R(ep) s(ep) R(ep)^T
  // Here R = the rotation to principal-stress space, ie
  // R_ij = eigvecs[i][j] = i^th component of j^th eigenvector
  // Expanding to first order in dep,
  // dS = R(ep) (s(ep+dep) - s(ep)) R(ep)^T
  //      + dR/dep s(ep) R^T + R(ep) s(ep) dR^T/dep
  // The first line is all that is usually calculated in the
  // consistent tangent operator calculation, and is called
  // cto below.
  // The second line involves changes in the eigenvectors, and
  // is called sec below.

  RankFourTensor cto;
  Real hard = dtensile_strength(intnl);
  Real la = E_ijkl(0,0,1,1);
  Real mu = 0.5*(E_ijkl(0,0,0,0) - la);

  if (cumulative_pm[1] <= 0)
  {
    // only cumulative_pm[2] is positive, so this is return to the Plane
    Real denom = hard + la + 2*mu;
    Real al = la*la/denom;
    Real be = la*(la + 2*mu)/denom;
    Real ga = hard*(la + 2*mu)/denom;
    std::vector<Real> comps(9);
    comps[0] = comps[4] = la + 2*mu - al;
    comps[1] = comps[3] = la - al;
    comps[2] = comps[5] = comps[6] = comps[7] = la - be;
    comps[8] = ga;
    cto.fillFromInputVector(comps, RankFourTensor::principal);
  }
  else if (cumulative_pm[0] <= 0)
  {
    // both cumulative_pm[2] and cumulative_pm[1] are positive, so Edge
    Real denom = 2*hard + 2*la + 2*mu;
    Real al = hard*2*la/denom;
    Real be = hard*(2*la + 2*mu)/denom;
    std::vector<Real> comps(9);
    comps[0] = la + 2*mu - 2*la*la/denom;
    comps[1] = comps[2] = al;
    comps[3] = comps[6] = al;
    comps[4] = comps[5] = comps[7] = comps[8] = be;
    cto.fillFromInputVector(comps, RankFourTensor::principal);
  }
  else
  {
    // all cumulative_pm are positive, so Tip
    Real denom = 3*hard + 3*la + 2*mu;
    std::vector<Real> comps(2);
    comps[0] = hard*(3*la + 2*mu)/denom;
    comps[1] = 0;
    cto.fillFromInputVector(comps, RankFourTensor::symmetric_isotropic);
  }

  cto.rotate(trial_eigvecs);


  // drdsig = change in eigenvectors under a small stress change
  // drdsig(i,j,m,n) = dR(i,j)/dS_mn
  // The formula below is fairly easily derived:
  // S R = R s, so taking the variation
  // dS R + S dR = dR s + R ds, and multiplying by R^T
  // R^T dS R + R^T S dR = R^T dR s + ds .... (eqn 1)
  // I demand that RR^T = 1 = R^T R, and also that
  // (R+dR)(R+dR)^T = 1 = (R+dT)^T (R+dR), which means
  // that dR = R*c, for some antisymmetric c, so Eqn1 reads
  // R^T dS R + s c = c s + ds
  // Grabbing the components of this gives ds/dS (already
  // in RankTwoTensor), and c, which is:
  //   dR_ik/dS_mn = drdsig(i, k, m, n) = trial_eigvecs(m, b)*trial_eigvecs(n, k)*trial_eigvecs(i, b)/(trial_eigvals[k] - trial_eigvals[b]);
  // (sum over b!=k).

  RankFourTensor drdsig;
  for (unsigned k = 0 ; k < 3 ; ++k)
    for (unsigned b = 0 ; b < 3 ; ++b)
    {
      if (b == k)
        continue;
      for (unsigned m = 0 ; m < 3 ; ++m)
        for (unsigned n = 0 ; n < 3 ; ++n)
          for (unsigned i = 0 ; i < 3 ; ++i)
            drdsig(i, k, m, n) += trial_eigvecs(m, b)*trial_eigvecs(n, k)*trial_eigvecs(i, b)/(trial_eigvals[k] - trial_eigvals[b]);
    }



  // With diagla = diag(eigvals[0], eigvals[1], digvals[2])
  // The following implements
  // ans(i, j, a, b) += (drdsig(i, k, m, n)*trial_eigvecs(j, l)*diagla(k, l) + trial_eigvecs(i, k)*drdsig(j, l, m, n)*diagla(k, l))*E_ijkl(m, n, a, b);
  // (sum over k, l, m and n)

  RankFourTensor ans;
  for (unsigned i = 0 ; i < 3 ; ++i)
    for (unsigned j = 0 ; j < 3 ; ++j)
      for (unsigned a = 0 ; a < 3 ; ++a)
        for (unsigned k = 0 ; k < 3 ; ++k)
          for (unsigned m = 0 ; m < 3 ; ++m)
            ans(i, j, a, a) += (drdsig(i, k, m, m)*trial_eigvecs(j, k) + trial_eigvecs(i, k)*drdsig(j, k, m, m))*eigvals[k]*la;  //E_ijkl(m, n, a, b) = la*(m==n)*(a==b);

  for (unsigned i = 0 ; i < 3 ; ++i)
    for (unsigned j = 0 ; j < 3 ; ++j)
      for (unsigned a = 0 ; a < 3 ; ++a)
        for (unsigned b = 0 ; b < 3 ; ++b)
          for (unsigned k = 0 ; k < 3 ; ++k)
          {
            ans(i, j, a, b) += (drdsig(i, k, a, b)*trial_eigvecs(j, k) + trial_eigvecs(i, k)*drdsig(j, k, a, b))*eigvals[k]*mu;  //E_ijkl(m, n, a, b) = mu*(m==a)*(n==b)
            ans(i, j, a, b) += (drdsig(i, k, b, a)*trial_eigvecs(j, k) + trial_eigvecs(i, k)*drdsig(j, k, b, a))*eigvals[k]*mu;  //E_ijkl(m, n, a, b) = mu*(m==b)*(n==a)
          }


  return cto + ans;

}
コード例 #11
0
/*
 *Solves for incremental plastic rate of deformation tensor and stress in unrotated frame.
 *Input: Strain incrment, 4th order elasticity tensor, stress tensor in previous incrmenent and
 *plastic rate of deformation tensor gradient.
 */
void
FiniteStrainPlasticMaterial::solveStressResid(RankTwoTensor sig_old,RankTwoTensor delta_d,RankFourTensor E_ijkl, RankTwoTensor *dp, RankTwoTensor *sig)
{

  RankTwoTensor sig_new,delta_dp,dpn;
  RankTwoTensor flow_tensor, flow_dirn;
  RankTwoTensor resid,ddsig;
  RankFourTensor dr_dsig,dr_dsig_inv;
  Real /*sig_eqv,*/flow_incr,f,dflow_incr;
  Real err1,err2,err3;
  unsigned int plastic_flag;
  unsigned int iter,maxiter=100;
  Real eqvpstrain,eqvpstrain_old,deqvpstrain,fq,rep;
  Real yield_stress;


  sig_new=sig_old+E_ijkl*delta_d;
  eqvpstrain_old=eqvpstrain=_eqv_plastic_strain_old[_qp];
  yield_stress=getYieldStress(eqvpstrain);
  plastic_flag=isPlastic(sig_new,yield_stress);//Check of plasticity for elastic predictor

  if (plastic_flag==1)
  {

    iter=0;

    dflow_incr=0.0;
    flow_incr=0.0;
    delta_dp.zero();
    deqvpstrain=0.0;

    sig_new=sig_old+E_ijkl*delta_d;

    getFlowTensor(sig_new,&flow_tensor);
    flow_dirn=flow_tensor;


    resid=flow_dirn*flow_incr-delta_dp;//Residual 1 - refer Hughes Simo
    f=getSigEqv(sig_new)-yield_stress;//Residual 2 - f=0
    rep=-eqvpstrain+eqvpstrain_old+flow_incr;//Residual 3 rep=0

    err1=resid.L2norm();
    err2=fabs(f);
    err3=fabs(rep);


    while ((err1 > _rtol || err2 > _ftol || err3 > _eptol) && iter < maxiter )//Stress update iteration (hardness fixed)
    {


      iter++;

      getJac(sig_new,E_ijkl,flow_incr,&dr_dsig);//Jacobian
      dr_dsig_inv=dr_dsig.invSymm();
      fq=getdYieldStressdPlasticStrain(eqvpstrain);

      dflow_incr=(f-flow_tensor.doubleContraction(dr_dsig_inv*resid)+fq*rep)/(flow_tensor.doubleContraction(dr_dsig_inv*flow_dirn)-fq);
      ddsig=dr_dsig_inv*(-resid-flow_dirn*dflow_incr);

      flow_incr+=dflow_incr;
      delta_dp-=E_ijkl.invSymm()*ddsig;
      sig_new+=ddsig;
      deqvpstrain=rep+dflow_incr;
      eqvpstrain+=deqvpstrain;

      getFlowTensor(sig_new,&flow_tensor);
      flow_dirn=flow_tensor;

      resid=flow_dirn*flow_incr-delta_dp;
      f=getSigEqv(sig_new)-yield_stress;
      rep=-eqvpstrain+eqvpstrain_old+flow_incr;

      err1=resid.L2norm();
      err2=fabs(f);
      err3=fabs(rep);

    }

    if (iter>=maxiter)
    {
      _stress[_qp](2,2)=1e6;
      printf("Constitutive Error: Too many iterations %f %f %f \n",err1,err2, err3);//Convergence failure
      return;
    }

    dpn=*dp+delta_dp;

  }

  *dp=dpn;//Plastic strain in unrotated configuration
  *sig=sig_new;
  _eqv_plastic_strain[_qp]=eqvpstrain;
}
コード例 #12
0
void
RedbackMechMaterialCC::getJac(const RankTwoTensor & sig,
                              const RankFourTensor & E_ijkl,
                              Real flow_incr,
                              Real sig_eqv,
                              Real pressure,
                              Real p_yield_stress,
                              Real q_yield_stress,
                              Real yield_stress,
                              RankFourTensor & dresid_dsig)
{
  unsigned i, j, k, l;
  RankTwoTensor sig_dev, flow_dirn_vol, flow_dirn_dev, fij, flow_dirn, flow_tensor;
  RankTwoTensor dfi_dft;
  RankFourTensor dfd_dsig, dfi_dsig;
  Real f1, f2, f3;
  Real dfi_dp, dfi_dseqv;

  Real pc = -yield_stress;
  sig_dev = sig.deviatoric();

  getDerivativeFlowIncrement(dfi_dp, dfi_dseqv, sig, pressure, sig_eqv, pc, q_yield_stress, p_yield_stress);
  getFlowTensor(sig, sig_eqv, pressure, q_yield_stress, p_yield_stress, yield_stress, flow_dirn);

  /* The following calculates the tensorial derivative (Jacobian) of the
   *residual with respect to stress, dr_dsig
   * It consists of two terms: The first is
   * dr_dsig = (dfi_dseqv_dev*flow_dirn_dev(k,l)) * flow_dirn_dev(i,j)
   * which is the tensorial product of the flow increment tensor times the flow
   *direction tensor
   *
   * The second is the product of the flow increment tensor times the derivative
   *of the flow direction tensor
   * with respect to the stress tensor. See also REDBACK's documentation
   * */

  f1 = 0.0;
  f2 = 0.0;
  f3 = 0.0;
  if (sig_eqv > 1e-10)
  {
    f1 = 3.0 / (_slope_yield_surface * _slope_yield_surface);
    f2 = 2.0 / 9.0 - 1.0 / (_slope_yield_surface * _slope_yield_surface);
    f3 = 3.0 / (2.0 * sig_eqv);
  }
  // This loop calculates the first term
  for (i = 0; i < 3; ++i)
    for (j = 0; j < 3; ++j)
      for (k = 0; k < 3; ++k)
        for (l = 0; l < 3; ++l)
          dfi_dsig(i, j, k, l) = flow_dirn(i, j) * (f3 * sig_dev(k, l) * dfi_dseqv + dfi_dp * deltaFunc(k, l) / 3.0);

  // This loop calculates the second term.
  for (i = 0; i < 3; ++i)
    for (j = 0; j < 3; ++j)
      for (k = 0; k < 3; ++k)
        for (l = 0; l < 3; ++l)
          dfd_dsig(i, j, k, l) = f1 * deltaFunc(i, k) * deltaFunc(j, l) + f2 * deltaFunc(i, j) * deltaFunc(k, l);

  dresid_dsig = E_ijkl.invSymm() + dfd_dsig * flow_incr + dfi_dsig; // Jacobian
}
コード例 #13
0
ファイル: RankFourTensor.C プロジェクト: harterj/moose
void mooseSetToZero<RankFourTensor>(RankFourTensor & v)
{
  v.zero();
}
コード例 #14
0
/*
 *Solves for incremental plastic rate of deformation tensor and stress in unrotated frame.
 *Input: Strain incrment, 4th order elasticity tensor, stress tensor in previous incrmenent and
 *plastic rate of deformation tensor.
 */
void
FiniteStrainRatePlasticMaterial::returnMap(const RankTwoTensor & sig_old, const RankTwoTensor & delta_d, const RankFourTensor & E_ijkl, RankTwoTensor & dp, RankTwoTensor & sig)
{
  RankTwoTensor sig_new, delta_dp, dpn;
  RankTwoTensor flow_tensor, flow_dirn;
  RankTwoTensor resid,ddsig;
  RankFourTensor dr_dsig, dr_dsig_inv;
  Real flow_incr, flow_incr_tmp;
  Real err1, err3, tol1, tol3;
  unsigned int iterisohard, iter, maxiterisohard = 20, maxiter = 50;
  Real eqvpstrain;
  Real yield_stress, yield_stress_prev;

  tol1 = 1e-10;
  tol3 = 1e-6;

  iterisohard = 0;
  eqvpstrain = std::pow(2.0/3.0,0.5) * dp.L2norm();
  yield_stress = getYieldStress(eqvpstrain);

  err3 = 1.1 * tol3;

  while (err3 > tol3 && iterisohard < maxiterisohard) //Hardness update iteration
  {
    iterisohard++;
    iter = 0;
    delta_dp.zero();

    sig_new = sig_old + E_ijkl * delta_d;
    flow_incr=_ref_pe_rate*_dt * std::pow(macaulayBracket(getSigEqv(sig_new) / yield_stress - 1.0), _exponent);

    getFlowTensor(sig_new, yield_stress, flow_tensor);
    flow_dirn = flow_tensor;

    resid = flow_dirn * flow_incr - delta_dp;
    err1 = resid.L2norm();

    while (err1 > tol1  && iter < maxiter) //Stress update iteration (hardness fixed)
    {
      iter++;

      getJac(sig_new, E_ijkl, flow_incr, yield_stress, dr_dsig); //Jacobian
      dr_dsig_inv = dr_dsig.invSymm();

      ddsig = -dr_dsig_inv * resid;

      sig_new += ddsig; //Update stress
      delta_dp -= E_ijkl.invSymm() * ddsig; //Update plastic rate of deformation tensor

      flow_incr_tmp = _ref_pe_rate * _dt * std::pow(macaulayBracket(getSigEqv(sig_new) / yield_stress - 1.0), _exponent);

      if (flow_incr_tmp < 0.0) //negative flow increment not allowed
        mooseError("Constitutive Error-Negative flow increment: Reduce time increment.");

      flow_incr = flow_incr_tmp;

      getFlowTensor(sig_new, yield_stress, flow_tensor);
      flow_dirn = flow_tensor;

      resid = flow_dirn * flow_incr - delta_dp; //Residual

      err1=resid.L2norm();
    }

    if (iter>=maxiter)//Convergence failure
      mooseError("Constitutive Error-Too many iterations: Reduce time increment.\n"); //Convergence failure

    dpn = dp + delta_dp;
    eqvpstrain = std::pow(2.0/3.0, 0.5) * dpn.L2norm();

    yield_stress_prev = yield_stress;
    yield_stress = getYieldStress(eqvpstrain);

    err3 = std::abs(yield_stress-yield_stress_prev);
  }

  if (iterisohard>=maxiterisohard)
    mooseError("Constitutive Error-Too many iterations in Hardness Update:Reduce time increment.\n"); //Convergence failure

  dp = dpn; //Plastic rate of deformation tensor in unrotated configuration
  sig = sig_new;
}
コード例 #15
0
bool
FiniteStrainPlasticBase::returnMap(const RankTwoTensor & stress_old, const RankTwoTensor & plastic_strain_old, const std::vector<Real> & intnl_old, const RankTwoTensor & delta_d, const RankFourTensor & E_ijkl, RankTwoTensor & stress, RankTwoTensor & plastic_strain, std::vector<Real> & intnl, std::vector<Real> & f, unsigned int & iter)
{

  // Assume this strain increment does not induce any plasticity
  // This is the elastic-predictor
  stress = stress_old + E_ijkl * delta_d; // the trial stress
  plastic_strain = plastic_strain_old;
  for (unsigned i = 0; i < intnl_old.size() ; ++i)
    intnl[i] = intnl_old[i];
  iter = 0;

  yieldFunction(stress, intnl, f);

  Real nr_res2 = 0;
  for (unsigned i = 0 ; i < f.size() ; ++i)
    nr_res2 += 0.5*std::pow( std::max(f[i], 0.0)/_f_tol[i], 2);

  if (nr_res2 < 0.5)
    // a purely elastic increment.
    // All output variables have been calculated
    return true;


  // So, from here on we know that the trial stress
  // is inadmissible, and we have to return from that
  // value to the yield surface.  There are three
  // types of constraints we have to satisfy, listed
  // below, and calculated in calculateConstraints(...)

  // Plastic strain constraint, L2 norm must be zero (up to a tolerance)
  RankTwoTensor epp;

  // Yield function constraint passed to this function as
  // std::vector<Real> & f
  // Each yield function must be <= 0 (up to tolerance)

  // Internal constraint(s), must be zero (up to a tolerance)
  std::vector<Real> ic;


  // During the Newton-Raphson procedure, we'll be
  // changing the following parameters in order to
  // (attempt to) satisfy the constraints.
  RankTwoTensor dstress; // change in stress
  std::vector<Real> dpm; // change in plasticity multipliers ("consistency parameters")
  std::vector<Real>  dintnl; // change in internal parameters



  // The following are used in the Newton-Raphson

  // Inverse of E_ijkl (assuming symmetric)
  RankFourTensor E_inv = E_ijkl.invSymm();

  // convenience variable that holds the change in plastic strain incurred during the return
  // delta_dp = plastic_strain - plastic_strain_old
  // delta_dp = E^{-1}*(trial_stress - stress), where trial_stress = E*(strain - plastic_strain_old)
  RankTwoTensor delta_dp;

  // The "consistency parameters" (plastic multipliers)
  // Change in plastic strain in this timestep = pm*flowPotential
  // Each pm must be non-negative
  std::vector<Real> pm;
  pm.assign(numberOfYieldFunctions(), 0.0);

  // whether line-searching was successful
  bool ls_success = true;

  // The Newton-Raphson loops
  while (nr_res2 > 0.5 && iter < _max_iter && ls_success)
  {
    iter++;

    // calculate dstress, dpm and dintnl for one full Newton-Raphson step
    nrStep(stress, intnl_old, intnl, pm, E_inv, delta_dp, dstress, dpm, dintnl);

    // perform a line search
    // The line-search will exit with updated values
    ls_success = lineSearch(nr_res2, stress, intnl_old, intnl, pm, E_inv, delta_dp, dstress, dpm, dintnl, f, epp, ic);
  }


  if (iter >= _max_iter || !ls_success)
  {
    stress = stress_old;
    for (unsigned i = 0; i < intnl_old.size() ; ++i)
      intnl[i] = intnl_old[i];
    return false;
  }
  else
  {
    plastic_strain += delta_dp;
    return true;
  }

}