Real
FiniteStrainPlasticMaterial::dyieldFunction_dinternal(const Real equivalent_plastic_strain)
{
  return -getdYieldStressdPlasticStrain(equivalent_plastic_strain);
}
/*
 *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;
}