diff --git a/NonLinearSolver/BoundaryConditions/nonLinearMicroBC.h b/NonLinearSolver/BoundaryConditions/nonLinearMicroBC.h
index 44175268101e22efe1cb6cc5521abf39273f8969..639f81c6ef169448cb1f40e0ef4c5b7410a0e985 100644
--- a/NonLinearSolver/BoundaryConditions/nonLinearMicroBC.h
+++ b/NonLinearSolver/BoundaryConditions/nonLinearMicroBC.h
@@ -213,7 +213,7 @@ public:
          FI(0,0) -= 1.;
          FI(1,1) -= 1.;
          FI(2,2) -= 1.;
-	       //FI.print();
+	     //  FI.print("FI");
          if (getOrder() == 2)
          {
            G = Gcur;
diff --git a/NonLinearSolver/Domain/partDomain.cpp b/NonLinearSolver/Domain/partDomain.cpp
index e7bdc57d478331232d62c80caf777fd023ea5cbb..2fa4d15fb8d981d68459b60e9fdcd8778719c321 100644
--- a/NonLinearSolver/Domain/partDomain.cpp
+++ b/NonLinearSolver/Domain/partDomain.cpp
@@ -594,8 +594,7 @@ void partDomain::computeBodyForceMultiplyPosition(const IPField* ipf, STensor3&
 	}
 };
 
-
-void partDomain::computeAverageHighOrderStressTangentModification(const IPField* ipf, double _rveVolume, STensor53& dPdGM, STensor63& dQdGM) const{
+void partDomain::computeAverageHighOrderStressTangentModification(const IPField* ipf, double _rveVolume, STensor53& dPdGM, STensor53& dQdFM, STensor63& dQdGM) const{
     static const STensor3 I(1.);
     if (g->size()>0){
 	IntPt* GP;
@@ -616,21 +615,71 @@ void partDomain::computeAverageHighOrderStressTangentModification(const IPField*
 	         Msg::Error("Body Force is not used, HighOrderStressTangent doesn't need to be modifiied!");
 	      }
 	      const STensor43& dBmdGM = vipv[i]->getConstRefTodBmdGM(); 
-	      const STensor43& dPmdFM = vipv[i]->getConstRefTodPmdFM(); 
-	      double ratio = detJ*weight;
+	      const STensor33& GM = vipv[i]->getConstRefToGM();
+	      const STensor63& dCmdFm = vipv[i]->getConstRefTodCmdFm();
+	      const STensor43& dFmdFM = vipv[i]->getConstRefToDFmdFM();
+	      const STensor53& dFmdGM = vipv[i]->getConstRefToDFmdGM();
+	      const STensor43& dPmdFm = vipv[i]->getConstRefToTangentModuli(); 	
+	      static STensor43 dPmdFM;  
+	      static STensor33 dFmdFM_GM;    
+	      STensorOperation::zero(dPmdFM);         
+	      STensorOperation::zero(dFmdFM_GM);     
+	      for (int ii=0; ii<3; ++ii)
+	        for (int jj=0; jj<3; ++jj)
+		  for (int kk=0; kk<3; ++kk)
+		   for (int ll=0; ll<3; ++ll)
+	             for (int p=0; p<3; ++p){
+	               dFmdFM_GM(ii,jj,kk) += dFmdFM(ii,jj,ll,p)*(GM(ll,p,kk)+ GM(ll,kk,p))*0.5;      
+	               for (int q=0; q<3; ++q){	      
+	                 dPmdFM(ii,jj,kk,ll) += dPmdFm(ii,jj,p,q)*dFmdFM(p,q,kk,ll);
+	               }
+	             }    	                
 	      
+	      double ratio = detJ*weight;	      
 	      for (int ii=0; ii<3; ++ii)
 	       for (int jj=0; jj<3; ++jj)
 		for (int kk=0; kk<3; ++kk)
 		 for (int ll=0; ll<3; ++ll)
-		  for (int mm=0; mm<3; ++mm)
+		  for (int mm=0; mm<3; ++mm){
+		    dPdGM(ii,jj,kk,ll,mm) -= dBmdGM(ii,kk,ll,mm)*pt[jj]*ratio;
 		    for (int nn=0; nn<3; ++nn){
-		      dPdGM(ii,jj,kk,ll,mm) += 0.5*(dPmdFM(ii,nn,kk,ll)*I(mm,nn)*pt[jj] + dPmdFM(ii,nn,kk,mm)*I(ll,nn)*pt[jj])*ratio;
-		      dQdGM(ii,jj,kk,ll,mm,nn) -= 0.5*dBmdGM(ii,ll,mm,nn)*pt[jj]*pt[kk]*ratio;			            
-		      dQdGM(ii,jj,kk,ll,mm,nn) += 0.5*dBmdGM(ii,ll,mm,nn)*_rveGeoInertia(jj,kk)*ratio/_rveVolume;
-	              dQdGM(ii,jj,kk,ll,mm,nn) -= 0.25*(dPmdFM(ii,jj,ll,mm)*_rveGeoInertia(nn,kk)+ dPmdFM(ii,kk,ll,mm)*_rveGeoInertia(nn,jj))*ratio/_rveVolume;
-	              dQdGM(ii,jj,kk,ll,mm,nn) -= 0.25*(dPmdFM(ii,jj,ll,nn)*_rveGeoInertia(mm,kk)+ dPmdFM(ii,kk,ll,nn)*_rveGeoInertia(mm,jj))*ratio/_rveVolume;				    
+		     dQdGM(ii,jj,kk,ll,mm,nn) -= 0.5*dBmdGM(ii,ll,mm,nn)*pt[jj]*pt[kk]*ratio;			            
+		     dQdGM(ii,jj,kk,ll,mm,nn) += 0.5*dBmdGM(ii,ll,mm,nn)*_rveGeoInertia(jj,kk)*ratio/_rveVolume;
+	             dQdGM(ii,jj,kk,ll,mm,nn) -= 0.25*(dPmdFM(ii,jj,ll,mm)*_rveGeoInertia(nn,kk)+ dPmdFM(ii,kk,ll,mm)*_rveGeoInertia(nn,jj))*ratio/_rveVolume;
+	             dQdGM(ii,jj,kk,ll,mm,nn) -= 0.25*(dPmdFM(ii,jj,ll,nn)*_rveGeoInertia(mm,kk)+ dPmdFM(ii,kk,ll,nn)*_rveGeoInertia(mm,jj))*ratio/_rveVolume;	    
 	            }   
+	         } 
+	     ///////////   dQdF, dQdG 
+	      static STensor53 dCm_GM;    
+	      STensorOperation::zero(dCm_GM);  
+	      for (int ii=0; ii<3; ++ii)
+               for (int jj=0; jj<3; ++jj)
+                for (int r=0; r<3; ++r)
+                  for (int s=0; s<3; ++s)
+                   for (int ll=0; ll<3; ++ll)
+	             for (int p=0; p<3; ++p)
+	               for (int q=0; q<3; ++q){
+	                 dCm_GM(ii,jj,r,s,ll) += dCmdFm(ii,jj,p,q,r,s)*dFmdFM_GM(p,q,ll);
+	               } 	       
+	         
+	     for (int ii=0; ii<3; ++ii)
+              for (int jj=0; jj<3; ++jj)
+               for (int kk=0; kk<3; ++kk)
+                for (int mm=0; mm<3; ++mm)
+                 for (int nn=0; nn<3; ++nn)
+                  for (int ll=0; ll<3; ++ll)
+	            for (int r=0; r<3; ++r)
+	              for (int s=0; s<3; ++s){
+	                 //dQdF
+		         dQdFM(ii,jj,kk,mm,nn) -= 0.5* dCm_GM(ii,jj,r,s,ll)*dFmdFM(r,s,mm,nn)*_rveGeoInertia(ll,kk)*ratio/_rveVolume;     
+		         dQdFM(ii,jj,kk,mm,nn) -= 0.5* dCm_GM(ii,kk,r,s,ll)*dFmdFM(r,s,mm,nn)*_rveGeoInertia(ll,jj)*ratio/_rveVolume; 
+		 
+		         //dQdG
+		         for (int t=0; t<3; ++t){
+		           dQdGM(ii,jj,kk,ll,mm,nn) -= 0.5* dCm_GM(ii,jj,r,s,t)*dFmdGM(r,s,ll,mm,nn)*_rveGeoInertia(t,kk)*ratio/_rveVolume;     
+		           dQdGM(ii,jj,kk,ll,mm,nn) -= 0.5* dCm_GM(ii,kk,r,s,t)*dFmdGM(r,s,ll,mm,nn)*_rveGeoInertia(t,jj)*ratio/_rveVolume;     
+	                 }   
+	               }                  
        }
     }
   }  
diff --git a/NonLinearSolver/Domain/partDomain.h b/NonLinearSolver/Domain/partDomain.h
index 0ae5514b05b29d41e117873719be658dba5a38d0..154a3d7f028daa99c96722c8a8fc28b1ce55148d 100644
--- a/NonLinearSolver/Domain/partDomain.h
+++ b/NonLinearSolver/Domain/partDomain.h
@@ -213,6 +213,7 @@ class partDomain
     virtual void computeIPVariable(AllIPState *aips,const unknownField *ufield,const IPStateBase::whichState ws, bool stiff)=0;
     virtual void setDeformationGradientGradient(AllIPState *aips, const STensor33 &GM, const IPStateBase::whichState ws)=0;
     virtual void setdFmdFM(AllIPState *aips, std::map<Dof, STensor3> &dUdF,const IPStateBase::whichState ws)=0;  
+    virtual void setdFmdGM(AllIPState *aips, std::map<Dof, STensor33> &dUdG,const IPStateBase::whichState ws)=0;  
     virtual void setValuesForBodyForce(AllIPState *aips, const IPStateBase::whichState ws)=0;
     virtual void computeIpv(AllIPState *aips,MElement *e, IPStateBase::whichState ws,
                              materialLaw *mlaw,fullVector<double> &disp, bool stiff)=0;
@@ -261,7 +262,7 @@ class partDomain
     virtual void computeAverageBodyForce(const IPField* ipf, SVector3& BM) const;
     virtual void computeActiveDissipationAverageStressIncrement(const IPField* ipf, STensor3& stress) const;
     virtual void computeAverageHighOrderStress(const IPField* ipf, STensor33& stress) const;
-    virtual void computeAverageHighOrderStressTangentModification(const IPField* ipf, double _rveVolume, STensor53& dPdGM, STensor63& dQdGM) const;
+    virtual void computeAverageHighOrderStressTangentModification(const IPField* ipf, double _rveVolume, STensor53& dPdGM, STensor53& dQdFM, STensor63& dQdGM) const;
     virtual double computeVolumeDomain(const IPField* ipf) const;
     virtual void computeBodyForceMultiplyPosition(const IPField* ipf, STensor3& BmX, STensor33& BmXoX) const;
 
diff --git a/NonLinearSolver/internalPoints/ipField.cpp b/NonLinearSolver/internalPoints/ipField.cpp
index cd5c1aa477dec89a9b8ff8e1637caa8012185e53..002702e3e4033ff6b2e424674710872feeb04cd1 100644
--- a/NonLinearSolver/internalPoints/ipField.cpp
+++ b/NonLinearSolver/internalPoints/ipField.cpp
@@ -513,7 +513,9 @@ std::string IPField::ToString(const int i){
   else if (i == DAMAGE_LAMVTMT20_MTX) return "DAMAGE_LAMVTMT20_MTX";
   else if (i == DAMAGE_LAMVTMT20_INC) return "DAMAGE_LAMVTMT20_INC";
 
-
+  else if (i == BODYFORCE_X) return "BODYFORCE_X";
+  else if (i == BODYFORCE_Y) return "BODYFORCE_Y";
+  else if (i == BODYFORCE_Z) return "BODYFORCE_Z";
   else if (i == S_XX) return "S_XX";
   else if (i == S_XY) return "S_XY";
   else if (i == S_XZ) return "S_XZ";
@@ -1007,6 +1009,19 @@ void IPField::setdFmdFM(std::map<Dof, STensor3> &dUdF, const IPStateBase::whichS
   }
 }
 
+void IPField::setdFmdGM(std::map<Dof, STensor33> &dUdG, const IPStateBase::whichState ws)
+{
+  std::vector<partDomain*>* domainVector = _solver->getDomainVector();
+  for(std::vector<partDomain*>::iterator itdom=domainVector->begin(); itdom!=domainVector->end(); ++itdom)
+  {
+    partDomain *dom = *itdom;
+    if(dom->hasBodyForceForHO())
+    {
+      dom->setdFmdGM(_AIPS,dUdG,ws);
+    }
+  }
+}
+
 void IPField::setValuesForBodyForce(const IPStateBase::whichState ws)
 {
   std::vector<partDomain*>* domainVector = _solver->getDomainVector();
diff --git a/NonLinearSolver/internalPoints/ipField.h b/NonLinearSolver/internalPoints/ipField.h
index 5e9327eddca8fad08df27a6e6af865a96e761fd7..4adb7bf88e543b1012f8c6d57b567f17310bff4e 100644
--- a/NonLinearSolver/internalPoints/ipField.h
+++ b/NonLinearSolver/internalPoints/ipField.h
@@ -237,7 +237,9 @@ class IPField : public elementsField {
                     DAMAGE_LAMVTMT15_MTX, DAMAGE_LAMVTMT15_INC, DAMAGE_LAMVTMT16_MTX, DAMAGE_LAMVTMT16_INC,
                     DAMAGE_LAMVTMT17_MTX, DAMAGE_LAMVTMT17_INC, DAMAGE_LAMVTMT18_MTX, DAMAGE_LAMVTMT18_INC,
                     DAMAGE_LAMVTMT19_MTX, DAMAGE_LAMVTMT19_INC, DAMAGE_LAMVTMT20_MTX, DAMAGE_LAMVTMT20_INC,
-
+                    // Body force
+                    BODYFORCE_X, BODYFORCE_Y, BODYFORCE_Z,
+                    // 
                     S_XX, S_XY, S_XZ, S_YY, S_YZ, S_ZZ,
                     G_XXX, G_XXY, G_XXZ, G_XYX, G_XYY, G_XYZ,G_XZX, G_XZY, G_XZZ,
                     G_YXX, G_YXY, G_YXZ, G_YYX, G_YYY, G_YYZ,G_YZX, G_YZY, G_YZZ,
@@ -562,6 +564,7 @@ class IPField : public elementsField {
   void compute1state(IPStateBase::whichState ws, bool stiff);
   void setDeformationGradientGradient(const STensor33 &GM,const IPStateBase::whichState ws);
   void setdFmdFM(std::map<Dof, STensor3> &dUdF, const IPStateBase::whichState ws);
+  void setdFmdGM(std::map<Dof, STensor33> &dUdG, const IPStateBase::whichState ws);
   void setValuesForBodyForce(const IPStateBase::whichState ws);
 
   // num allows to select a particular gauss' point. Ins value is used only if ev = crude
diff --git a/NonLinearSolver/internalPoints/ipFiniteStrain.h b/NonLinearSolver/internalPoints/ipFiniteStrain.h
index 0d832e0cf7924b04779ad93e4b1d2087686f2e77..6f700a57d72e163ca9c195ce29de4730005fe06a 100644
--- a/NonLinearSolver/internalPoints/ipFiniteStrain.h
+++ b/NonLinearSolver/internalPoints/ipFiniteStrain.h
@@ -87,13 +87,14 @@ class ipFiniteStrain : public IPVariableMechanics{
     virtual STensor43 &getRefTodBmdGM()=0;
     virtual const STensor43 &getConstRefToDFmdFM() const=0;
     virtual STensor43 &getRefToDFmdFM()=0;
+    virtual const STensor53 &getConstRefToDFmdGM() const=0;
+    virtual STensor53 &getRefToDFmdGM()=0;
     virtual const STensor63 &getConstRefTodCmdFm() const=0;
     virtual STensor63 &getRefTodCmdFm()=0;
     virtual STensor63 *getPtrTodCmdFm()=0;
     virtual const STensor43 &getConstRefTodPmdFM() const=0;
     virtual STensor43 &getRefTodPmdFM()=0;
-    virtual const STensor53 &getConstRefTodPMGdFm() const=0;
-    virtual STensor53 &getRefTodPMGdFm()=0;
+
 
     virtual IPVariable* clone() const =0;
     virtual void restart(){
diff --git a/NonLinearSolver/materialLaw/FiniteStrain.cpp b/NonLinearSolver/materialLaw/FiniteStrain.cpp
index a1b8ff59c94bae781db211bd46fcedeb03f89666..ffdcdf1f164715f522cf7d0b292cc0e0e607d707 100644
--- a/NonLinearSolver/materialLaw/FiniteStrain.cpp
+++ b/NonLinearSolver/materialLaw/FiniteStrain.cpp
@@ -888,7 +888,7 @@ int UpdateFandR(double** Fn, double** Rn, double* Vr, double** dR, double **Fnp1
     static double* lnlambdaalpha = NULL;
     static double** ealpha = NULL;
     int i,j;
-
+    int error=0;
     if (ds == NULL){
       mallocmatrix(&ds,3,3);
       mallocmatrix(&drFn,3,3);
@@ -913,7 +913,7 @@ int UpdateFandR(double** Fn, double** Rn, double* Vr, double** dR, double **Fnp1
     ds[0][1]= ds[1][0] = (Vr[3])/shearRatio;
     ds[0][2]= ds[2][0] = (Vr[4])/shearRatio;
     ds[1][2]= ds[2][1] = (Vr[5])/shearRatio;
-    Jacobian_Eigen( 3, ds, lnlambdaalpha, ealpha);
+    error=Jacobian_Eigen( 3, ds, lnlambdaalpha, ealpha);
     for (int i=0; i<3; i++){
       for (int j=0; j<3; j++){
         v[i][j]=exp(lnlambdaalpha[0])*ealpha[i][0]*ealpha[j][0]+exp(lnlambdaalpha[1])*ealpha[i][1]*ealpha[j][1]+exp(lnlambdaalpha[2])*ealpha[i][2]*ealpha[j][2];
@@ -923,7 +923,7 @@ int UpdateFandR(double** Fn, double** Rn, double* Vr, double** dR, double **Fnp1
     contraction1(dR, Fn, drFn);
     contraction1(dR, Rn, Rnp1);
     contraction1(v, drFn, Fnp1);
-    return 0;
+    return error;
 }
 /******************************************************************************/
 /* Update F   */
@@ -937,7 +937,7 @@ int UpdateF(double** Fn, double* Vr, double **Fnp1, double shearRatio)
    static double* lnlambdaalpha = NULL;
    static double** ealpha = NULL;
    int i,j;
-
+   int error=0;
     if (ds == NULL){
       mallocmatrix(&ds,3,3);
       mallocmatrix(&v,3,3);
@@ -962,14 +962,15 @@ int UpdateF(double** Fn, double* Vr, double **Fnp1, double shearRatio)
     ds[0][2]= ds[2][0] = (Vr[4])/shearRatio;
     ds[1][2]= ds[2][1] = (Vr[5])/shearRatio;
 
-    Jacobian_Eigen( 3, ds, lnlambdaalpha, ealpha);
+    error=Jacobian_Eigen( 3, ds, lnlambdaalpha, ealpha);
     for (int i=0; i<3; i++){
       for (int j=0; j<3; j++){
         v[i][j]=exp(lnlambdaalpha[0])*ealpha[i][0]*ealpha[j][0]+exp(lnlambdaalpha[1])*ealpha[i][1]*ealpha[j][1]+exp(lnlambdaalpha[2])*ealpha[i][2]*ealpha[j][2];
         }
     }
     contraction1(v, Fn, Fnp1);
+    return error;
+
 
-    return 0;
 }
 #endif
diff --git a/NonLinearSolver/materialLaw/Lamhomogenization.cpp b/NonLinearSolver/materialLaw/Lamhomogenization.cpp
index 2b77f3ded9ea454303732cac0c3ff01588df6e4b..d34c443db4deca539b13bd02a7619df4e2f1dd49 100755
--- a/NonLinearSolver/materialLaw/Lamhomogenization.cpp
+++ b/NonLinearSolver/materialLaw/Lamhomogenization.cpp
@@ -352,10 +352,10 @@ int Lam2plyNR(double* DE, double* DeA, double* DeB, Material* A_mat, Material* B
        //************** compute Jacobian  ***************************** 
 
        for(i=0;i<3;i++){
-           for(j=0;j<3;j++){
-               J[MO[i]][MO[j]] = CalgoA[MO[i]][MO[j]] + VA/VB*CalgoB[MO[i]][MO[j]];
+           for(j=0;j<6;j++){
+               J[MO[i]][j] = CalgoA[MO[i]][j] + VA/VB*CalgoB[MO[i]][j];
 	   }
-           J[MI[i]][MI[i]] = 1.0;
+           J[MI[i]][MI[i]] += 1.0;
        }
                
 	//COMPUTE MACRO TANGENT OPERATORS, CONTINUUM AND ALGORITHMIC
@@ -368,22 +368,23 @@ int Lam2plyNR(double* DE, double* DeA, double* DeB, Material* A_mat, Material* B
 	   }
 
             cleartens4(dFdE);
-	    for(i=0;i<3;i++){
-		for(j=0;j<3;j++){
-                    dFdE[MO[i]][MI[j]] = CalgoA[MO[i]][MI[j]] + VA/VB*CalgoB[MO[i]][MI[j]];
-                    dFdE[MI[i]][MI[j]] -= 1.0;
-                }
-            }
+	   // for(i=0;i<3;i++){
+	//	for(j=0;j<6;j++){
+          //          dFdE[MO[i]][MI[j]] = CalgoA[MO[i]][MI[j]] + VA/VB*CalgoB[MO[i]][MI[j]];
+          //      }
+           //     dFdE[MI[i]][MI[i]] -= 1.0;
+           // }
 
 	    for(i=0;i<3;i++){
 		for(j=0;j<6;j++){
                     dFdE[MO[i]][j] -= 1.0/VB*CalgoB[MO[i]][j]; 
                 }
+                dFdE[MI[i]][MI[i]] -= 1.0;
             }
 
 	    for(i=0;i<6;i++){
-	        for(m=0;m<6;m++){
-		    for(j=0;j<6;j++){
+	        for(j=0;j<6;j++){
+		    for(m=0;m<6;m++){
                         deAdE[i][j]+= invJ[i][m]*dFdE[m][j];		//warning: absolute value
 		    }
                     deBdE[i][j] = VA/VB*deAdE[i][j];
@@ -413,10 +414,10 @@ int Lam2plyNR(double* DE, double* DeA, double* DeB, Material* A_mat, Material* B
             for(i=0;i<6;i++){
                vec1[i]= VA*(statev[idsdv_A + A_mat->get_pos_strs()+i]) + VB*(statev[idsdv_B + B_mat->get_pos_strs()+i]);
             }
-          //  printf("stressA:, %f7,%f7,%f7,%f7,%f7,%f7\n",statev[idsdv_A + A_mat->get_pos_strs()+0],statev[idsdv_A + A_mat->get_pos_strs()+1],statev[idsdv_A + A_mat->get_pos_strs()+2],statev[idsdv_A + A_mat->get_pos_strs()+3],statev[idsdv_A + A_mat->get_pos_strs()+4],statev[idsdv_A + A_mat->get_pos_strs()+5]);
-          //  printf("stressB:, %f7,%f7,%f7,%f7,%f7,%f7\n",statev[idsdv_B + B_mat->get_pos_strs()+0],statev[idsdv_B + B_mat->get_pos_strs()+1],statev[idsdv_B + B_mat->get_pos_strs()+2],statev[idsdv_B + B_mat->get_pos_strs()+3],statev[idsdv_B + B_mat->get_pos_strs()+4],statev[idsdv_B + B_mat->get_pos_strs()+5]);
+         //   printf("stressA:, %f7,%f7,%f7,%f7,%f7,%f7\n",statev[idsdv_A + A_mat->get_pos_strs()+0],statev[idsdv_A + A_mat->get_pos_strs()+1],statev[idsdv_A + A_mat->get_pos_strs()+2],statev[idsdv_A + A_mat->get_pos_strs()+3],statev[idsdv_A + A_mat->get_pos_strs()+4],statev[idsdv_A + A_mat->get_pos_strs()+5]);
+         //   printf("stressB:, %f7,%f7,%f7,%f7,%f7,%f7\n",statev[idsdv_B + B_mat->get_pos_strs()+0],statev[idsdv_B + B_mat->get_pos_strs()+1],statev[idsdv_B + B_mat->get_pos_strs()+2],statev[idsdv_B + B_mat->get_pos_strs()+3],statev[idsdv_B + B_mat->get_pos_strs()+4],statev[idsdv_B + B_mat->get_pos_strs()+5]);
 
-          //  printf("strainA:, %f7,%f7,%f7,%f7,%f7,%f7\n",statev[idsdv_A + A_mat->get_pos_strn()+0],statev[idsdv_A + A_mat->get_pos_strn()+1],statev[idsdv_A + A_mat->get_pos_strn()+2],statev[idsdv_A + A_mat->get_pos_strn()+3],statev[idsdv_A + A_mat->get_pos_strn()+4],statev[idsdv_A + A_mat->get_pos_strn()+5]);
+         //   printf("strainA:, %f7,%f7,%f7,%f7,%f7,%f7\n",statev[idsdv_A + A_mat->get_pos_strn()+0],statev[idsdv_A + A_mat->get_pos_strn()+1],statev[idsdv_A + A_mat->get_pos_strn()+2],statev[idsdv_A + A_mat->get_pos_strn()+3],statev[idsdv_A + A_mat->get_pos_strn()+4],statev[idsdv_A + A_mat->get_pos_strn()+5]);
          //   printf("strainB:, %f7,%f7,%f7,%f7,%f7,%f7\n",statev[idsdv_B + B_mat->get_pos_strn()+0],statev[idsdv_B + B_mat->get_pos_strn()+1],statev[idsdv_B + B_mat->get_pos_strn()+2],statev[idsdv_B + B_mat->get_pos_strn()+3],statev[idsdv_B + B_mat->get_pos_strn()+4],statev[idsdv_B + B_mat->get_pos_strn()+5]);
             rot2(R66, vec1, &(statev[6])); 
 	    rot4(R66,Calgo_loc,Calgo); 
@@ -491,27 +492,28 @@ int TensPA(double VA, double** CA, double** CB, double** PA)
 
        addtens4(VA,CB, VB, CA, mat1);                     //mat1 = vaCb+vbCa
        for(i=0;i<3;i++){
-           for(j=0;j<3;j++){ 
-               A1[MO[i]][MO[j]] = mat1[MO[i]][MO[j]];
+           for(j=0;j<6;j++){ 
+               A1[MO[i]][j] = mat1[MO[i]][j];
+               A2[MO[i]][j] = CB[MO[i]][j];
            }
            A1[MI[i]][MI[i]] = 1.0;
-       }
- 
-       for(i=0;i<3;i++){
-           for(j=0;j<3;j++){ 
-               A2[MO[i]][MI[j]] = mat1[MO[i]][MI[j]];
-           }
-           for(k=0;k<6;k++){       
-               A2[MO[i]][k] = CB[MO[i]][k] - A2[MO[i]][k];
-           }
            A2[MI[i]][MI[i]] = 1.0;
        }
+ 
 
        inverse(A1,invA1,&error,6);
        if(error!=0){
 	   printf("Problem while inversing A1 operator in Lam2plyNR, A1=\n");
 	   printmatr(A1,6,6);
+
+           for(i=0;i<6;i++){
+               for(j=0;j<6;j++){ 
+                   PA[i][j] = 0.0;
+               }
+               PA[i][i] =1.0;
+           }  
            return error;
+      
 	}
 
         contraction44(invA1, A2, PA);  
diff --git a/NonLinearSolver/materialLaw/Weight.cpp b/NonLinearSolver/materialLaw/Weight.cpp
index 82224b0434befb2fb5386f0fbd7069403ae49593..ac9c4ab6b9fe46d4b9f88e9e4b60d1ea25c5ac08 100644
--- a/NonLinearSolver/materialLaw/Weight.cpp
+++ b/NonLinearSolver/materialLaw/Weight.cpp
@@ -738,14 +738,14 @@ void getARWeight(double theta, double phi, int Total_number_of_AR_per_phase, dou
   ARtable = fopen("ARtable.i01", "r");
   if(ARtable==NULL)
     printf("Error, no ARtable.i01 file\n");
-  int okf = fscanf(ARtable,"%s%*[^\n]",line);
-  okf =fscanf(ARtable, "%s", line);
+  fscanf(ARtable,"%s%*[^\n]",line);
+  fscanf(ARtable, "%s", line);
   Nfacets = atoi(line);
-  okf = fscanf(ARtable, "%s", line);
+  fscanf(ARtable, "%s", line);
   NAR = atoi(line);
   if(NAR!=Total_number_of_AR_per_phase)
     printf("NAR!=Total_number_of_AR_per_phase\n");
-  okf =fscanf(ARtable, "%s%*[^\n]", line);
+  fscanf(ARtable, "%s%*[^\n]", line);
   DAR = atof(line);
 
   if(listTheta==NULL)
@@ -757,23 +757,23 @@ void getARWeight(double theta, double phi, int Total_number_of_AR_per_phase, dou
     mallocmatrix(&pdfAR,Nfacets,NAR);
   }
   
-  okf =fscanf(ARtable,"%s%*[^\n]",line);
+  fscanf(ARtable,"%s%*[^\n]",line);
   for(i=0;i<Nfacets;i++)
   {
-    okf =fscanf(ARtable, "%s", line);
+    fscanf(ARtable, "%s", line);
     listTheta[i]=atof(line);
-    okf =fscanf(ARtable, "%s", line);
+    fscanf(ARtable, "%s", line);
     listPhi[i]=atof(line);
-    okf =fscanf(ARtable, "%s", line);
+    fscanf(ARtable, "%s", line);
     listSurf[i]=atof(line);
-    okf =fscanf(ARtable, "%s", line);
+    fscanf(ARtable, "%s", line);
     listVol[i]=atof(line);
     for(j=0;j<NAR;j++)
     {
       if(j<NAR-1)
-	okf =fscanf(ARtable, "%s", line);
+	fscanf(ARtable, "%s", line);
       else
-	okf =fscanf(ARtable, "%s%*[^\n]", line);
+	fscanf(ARtable, "%s%*[^\n]", line);
       pdfAR[i][j]=atof(line);
     }	
   }
diff --git a/NonLinearSolver/materialLaw/damage.cpp b/NonLinearSolver/materialLaw/damage.cpp
index 4e68eb600f1a16a3a33bb1f68040da8f892ed1eb..74901936830164bbb71fa5887f44b5be9ca5ea55 100644
--- a/NonLinearSolver/materialLaw/damage.cpp
+++ b/NonLinearSolver/materialLaw/damage.cpp
@@ -71,6 +71,12 @@ LCN_Damage::LCN_Damage(double* props, int iddam):Damage(props, iddam){
 	n = props[iddam+2];
         p0 = props[iddam+3];
         pos_maxD=nsdv-1;
+
+        pos_dDdp = pos_maxD+1;
+        pos_pbarTrans = pos_maxD+2;
+        pos_Dt = pos_maxD+3;
+        nsdv +=3;
+
 }
 
 //destructor
@@ -89,12 +95,167 @@ void LCN_Damage::print(){
 //damagebox
 void LCN_Damage::damagebox(double* statev_n, double* statev, int pos_strn, int pos_strs, int pos_dam, double** Calgo,double* dDdE, double *dDdp_bar, double alpha, int kinc, int kstep){
 
+	//  statev for damage  p_bar, dp_bar ,D, dD
+
+        double Y_n, Y, Y_a;        
+
+        double p_bar, dp_bar, p_bar_n;
+        double D, dD, D_n;
+        double Max_p_bar;
+        double Dtrans = 0.5;
+        double Pbar_trans = 0.0; 
+
+        // allocated once
+        static double* strs_n;
+        static double* strs;
+        static double* Estrn_n;
+        static double* Estrn;
+
+        static double* strn;
+        static double* pstrn;
+
+        int i, j;
+        double mat1;
+        double a,b,c,tmp ;
+        double Dc = statev[pos_dam+get_pos_maxD()];
+        if(Dc<0.7) Dc=0.95;
+        static bool initialized = false; 
+
+        //allocate memory
+	if(!initialized){
+          mallocvector(&strs_n,6);
+          mallocvector(&strs,6);
+          mallocvector(&Estrn_n,6);
+          mallocvector(&Estrn,6);
+
+          mallocvector(&strn,6);
+          mallocvector(&pstrn,6);
+ 
+          initialized = true;
+        }
+        cleartens2(strs_n);
+        cleartens2(strs);
+        cleartens2(Estrn_n);
+        cleartens2(Estrn);
+        cleartens2(strn);
+        cleartens2(pstrn);
 
-}
+  
+        p_bar_n= statev_n[pos_dam];                       
+        dp_bar= statev_n[pos_dam+1];
+               
+        D_n= statev_n[pos_dam+2];
+        Max_p_bar = statev_n[pos_dam+4];
+
+
+        p_bar= p_bar_n+dp_bar;  
+
+        dp_bar = p_bar - Max_p_bar;  
+
+        if(p_bar >= Max_p_bar){
+
+             Max_p_bar= p_bar;                    
+        }
+
+        cleartens2(dDdE);
+        *dDdp_bar=0.;
+        dD= 0.0;
+        if(Max_p_bar > p0 and D_n < Dc){
 
+             copyvect(&(statev_n[pos_strs]),strs_n,6);
+             copyvect(&(statev[pos_strs]),strs,6);
+                 
+             copyvect(&(statev_n[pos_strn]),strn,6);
+             copyvect(&(statev_n[pos_strn+18]),pstrn,6);
+             addtens2(1., strn, -1., pstrn, Estrn_n);
 
+             copyvect(&(statev[pos_strn]),strn,6);
+             copyvect(&(statev[pos_strn+18]),pstrn,6);
+             addtens2(1., strn, -1., pstrn, Estrn);
 
+             Y_n= 0.5*fabs(contraction22(strs_n, Estrn_n));
+             Y= 0.5*fabs(contraction22(strs, Estrn));
 
+             Y_a= (1.-alpha)*Y_n + alpha*Y;
+             
+             mat1=0.;
+             if(dp_bar>0.0 and Y_a>0.){
+                if (D_n < Dtrans){ 
+                    //  compute dDdp_bar               
+                    *dDdp_bar=pow(Y_a/S0, n);                    
+                    //  compute dDdE          
+                    dD= dp_bar*pow(Y_a/S0, n);
+                    mat1= alpha*n*dD/Y_a;
+                    cleartens2(dDdE);
+ 
+                    for(i=0;i<6;i++){
+                        for (j=0; j<6; j++) {
+                           dDdE[i] = dDdE[i] + Estrn[j]*Calgo[j][i];
+                       }
+                     dDdE[i]= mat1*dDdE[i];  
+                    }
+
+                    statev[pos_dam+pos_dDdp] = pow(Y_a/S0, n);
+                    statev[pos_dam+pos_pbarTrans] = Max_p_bar;
+                    statev[pos_dam+pos_Dt] = D_n + dD;
+                    D = D_n + dD;  
+                    if(D>=Dc)
+                    {
+                      D = Dc;
+                      statev[pos_dam+pos_dDdp] =  statev_n[pos_dam+pos_dDdp];
+                      statev[pos_dam+pos_pbarTrans] = statev_n[pos_dam+pos_pbarTrans];
+                      statev[pos_dam+pos_Dt] = statev_n[pos_dam+pos_Dt];
+                      dD=0.0;
+                      *dDdp_bar= 0.0; 
+                      cleartens2(dDdE);
+                    }
+                 }              
+                 else{
+                    double n = 1.5;
+                    Pbar_trans =  statev_n[pos_dam+pos_pbarTrans];
+                    tmp = statev_n[pos_dam+pos_dDdp]/Dc;
+                    
+                    c = (1.0-statev[pos_dam+pos_Dt]/Dc)*(n+1.0);
+                    b = 1.0-c;
+                    a = (n+1.0)*(n+1.0)*tmp/n/c;
+                    D =  Dc*(b+c*n/(n+exp(-a*(Max_p_bar-Pbar_trans))));
+ 
+                    statev[pos_dam+pos_dDdp] =  statev_n[pos_dam+pos_dDdp];
+                    statev[pos_dam+pos_pbarTrans] = statev_n[pos_dam+pos_pbarTrans];
+                    statev[pos_dam+pos_Dt] = statev_n[pos_dam+pos_Dt];
+
+                    *dDdp_bar = Dc*c*n*a*exp(-a*(Max_p_bar-Pbar_trans))/(n+exp(-a*(Max_p_bar-Pbar_trans)))/(n+exp(-a*(Max_p_bar-Pbar_trans)));
+                 }
+             } 
+             else{
+                  D = D_n;
+                  statev[pos_dam+pos_dDdp] =  statev_n[pos_dam+pos_dDdp];
+                  statev[pos_dam+pos_pbarTrans] = statev_n[pos_dam+pos_pbarTrans];
+                  statev[pos_dam+pos_Dt] = statev_n[pos_dam+pos_Dt];
+             }
+        }
+        else{
+             D = D_n;
+             statev[pos_dam+pos_dDdp] =  statev_n[pos_dam+pos_dDdp];
+             statev[pos_dam+pos_pbarTrans] = statev_n[pos_dam+pos_pbarTrans];
+             statev[pos_dam+pos_Dt] = statev_n[pos_dam+pos_Dt];
+        } 
+
+        if( D_n >= Dc) { 
+              D=D_n;//statev[pos_dam+get_pos_maxD()]; 
+              dD=0.0;
+              *dDdp_bar= 0.0; 
+              cleartens2(dDdE);
+        }
+          
+
+       // update damage variable in statev
+         statev[pos_dam]= p_bar;
+	 statev[pos_dam+2]= D;
+	 statev[pos_dam+3]= dD;
+	 statev[pos_dam+4]= Max_p_bar;   
+		
+}
 
 
 
@@ -114,6 +275,11 @@ LCN_Damage_Stoch::LCN_Damage_Stoch(double* props, int iddam):Damage(props, iddam
         p0 = props[iddam+3];
         pos_maxD=nsdv-1;
 
+        pos_dDdp = pos_maxD+1;
+        pos_pbarTrans = pos_maxD+2;
+        pos_Dt = pos_maxD+3;
+        nsdv +=3;
+
 }
 
 //destructor
@@ -131,7 +297,170 @@ void LCN_Damage_Stoch::print(){
 //damagebox
 void LCN_Damage_Stoch::damagebox(double* statev_n, double* statev, int pos_strn, int pos_strs, int pos_dam, double** Calgo,double* dDdE, double *dDdp_bar, double alpha, int kinc, int kstep){
 
+	//  statev for damage  p_bar, dp_bar ,D, dD
+
+        double Y_n, Y, Y_a;  
+        double S0, n;      
+
+        double p_bar, dp_bar, p_bar_n;
+        double D, dD, D_n;
+        double Max_p_bar;
 
+        // allocated once
+        static double* strs_n;
+        static double* strs;
+        static double* Estrn_n;
+        static double* Estrn;
+
+        static double* strn;
+        static double* pstrn;
+
+        int i, j;
+        double mat1;
+        double a,b,c,tmp;
+        double Dtrans = 0.5;
+        double Pbar_trans = 0.0; 
+        double Dc = statev[pos_dam+get_pos_maxD()];
+        if(Dc<0.7) Dc= 0.95;
+        
+        static bool initialized = false; 
+
+        //allocate memory
+	if(!initialized){
+          mallocvector(&strs_n,6);
+          mallocvector(&strs,6);
+          mallocvector(&Estrn_n,6);
+          mallocvector(&Estrn,6);
+
+          mallocvector(&strn,6);
+          mallocvector(&pstrn,6);
+ 
+          initialized = true;
+        }
+        cleartens2(strs_n);
+        cleartens2(strs);
+        cleartens2(Estrn_n);
+        cleartens2(Estrn);
+        cleartens2(strn);
+        cleartens2(pstrn);
+
+        S0 = statev_n[pos_dam+pos_DamParm1];
+        n = statev_n[pos_dam+pos_DamParm2];      
+  
+        p_bar_n= statev_n[pos_dam];                       
+        dp_bar= statev_n[pos_dam+1];
+               
+        D_n= statev_n[pos_dam+2];
+        Max_p_bar = statev_n[pos_dam+4];
+
+
+        p_bar= p_bar_n+dp_bar;  
+
+        dp_bar = p_bar - Max_p_bar;  
+
+       if(p_bar >= Max_p_bar){
+
+             Max_p_bar= p_bar;                    
+        }
+        
+        
+        cleartens2(dDdE);
+        *dDdp_bar=0.;
+        dD= 0.0;
+        if(Max_p_bar > p0 and D_n < Dc){
+
+             copyvect(&(statev_n[pos_strs]),strs_n,6);
+             copyvect(&(statev[pos_strs]),strs,6);
+                 
+             copyvect(&(statev_n[pos_strn]),strn,6);
+             copyvect(&(statev_n[pos_strn+18]),pstrn,6);
+             addtens2(1., strn, -1., pstrn, Estrn_n);
+
+             copyvect(&(statev[pos_strn]),strn,6);
+             copyvect(&(statev[pos_strn+18]),pstrn,6);
+             addtens2(1., strn, -1., pstrn, Estrn);
+
+             Y_n= 0.5*fabs(contraction22(strs_n, Estrn_n));
+             Y= 0.5*fabs(contraction22(strs, Estrn));
+
+             Y_a= (1.-alpha)*Y_n + alpha*Y;
+             
+             mat1=0.;
+             if(dp_bar>0.0 and Y_a>0.){
+                if (D_n < Dtrans){ 
+                    //  compute dDdp_bar               
+                    *dDdp_bar=pow(Y_a/S0, n);                    
+                    //  compute dDdE          
+                    dD= dp_bar*pow(Y_a/S0, n);
+                    mat1= alpha*n*dD/Y_a;
+                    cleartens2(dDdE);
+ 
+                    for(i=0;i<6;i++){
+                        for (j=0; j<6; j++) {
+                           dDdE[i] = dDdE[i] + Estrn[j]*Calgo[j][i];
+                       }
+                     dDdE[i]= mat1*dDdE[i];  
+                    }
+
+                    statev[pos_dam+pos_dDdp] = pow(Y_a/S0, n);
+                    statev[pos_dam+pos_pbarTrans] = Max_p_bar;
+                    statev[pos_dam+pos_Dt] = D_n + dD;
+                    D = D_n + dD;  
+                    if(D>=Dc)
+                    {
+                      D = Dc;
+                      statev[pos_dam+pos_dDdp] =  statev_n[pos_dam+pos_dDdp];
+                      statev[pos_dam+pos_pbarTrans] = statev_n[pos_dam+pos_pbarTrans];
+                      statev[pos_dam+pos_Dt] = statev_n[pos_dam+pos_Dt];
+                      dD=0.0;
+                      *dDdp_bar= 0.0; 
+                      cleartens2(dDdE);
+                    }
+                 }              
+                 else{
+                    double n = 1.5;
+                    Pbar_trans =  statev_n[pos_dam+pos_pbarTrans];
+                    tmp = statev_n[pos_dam+pos_dDdp]/Dc;
+                    
+                    c = (1.0-statev[pos_dam+pos_Dt]/Dc)*(n+1.0);
+                    b = 1.0-c;
+                    a = (n+1.0)*(n+1.0)*tmp/n/c;
+                    D =  Dc*(b+c*n/(n+exp(-a*(Max_p_bar-Pbar_trans))));
+ 
+                    statev[pos_dam+pos_dDdp] =  statev_n[pos_dam+pos_dDdp];
+                    statev[pos_dam+pos_pbarTrans] = statev_n[pos_dam+pos_pbarTrans];
+                    statev[pos_dam+pos_Dt] = statev_n[pos_dam+pos_Dt];
+
+                    *dDdp_bar = Dc*c*n*a*exp(-a*(Max_p_bar-Pbar_trans))/(n+exp(-a*(Max_p_bar-Pbar_trans)))/(n+exp(-a*(Max_p_bar-Pbar_trans)));
+                 }
+             } 
+             else{
+                  D = D_n;
+                  statev[pos_dam+pos_dDdp] =  statev_n[pos_dam+pos_dDdp];
+                  statev[pos_dam+pos_pbarTrans] = statev_n[pos_dam+pos_pbarTrans];
+                  statev[pos_dam+pos_Dt] = statev_n[pos_dam+pos_Dt];
+             }
+        }
+        else{
+             D = D_n;
+             statev[pos_dam+pos_dDdp] =  statev_n[pos_dam+pos_dDdp];
+             statev[pos_dam+pos_pbarTrans] = statev_n[pos_dam+pos_pbarTrans];
+             statev[pos_dam+pos_Dt] = statev_n[pos_dam+pos_Dt];
+        } 
+
+        if( D_n >= Dc) { 
+              D=D_n;//statev[pos_dam+get_pos_maxD()]; 
+              dD=0.0;
+              *dDdp_bar= 0.0; 
+              cleartens2(dDdE);
+        }
+          
+
+       // update damage variable in statev
+         statev[pos_dam]= p_bar;
+	 statev[pos_dam+2]= D;
+	 statev[pos_dam+3]= dD;
+	 statev[pos_dam+4]= Max_p_bar;   
         
 }
 
@@ -171,7 +500,55 @@ void LINN_Damage::print(){
 
 void LINN_Damage::damagebox(double* statev_n, double* statev, int pos_strn, int pos_strs, int pos_dam, double** Calgo,double* dDdE, double *dDdp_bar, double alpha, int kinc, int kstep){
 
+//  statev for damage  p_bar, dp_bar ,D, dD
 
+         double p_bar, dp_bar, p_bar_n;
+         double D, dD, D_n;
+         double Max_p_bar;
+
+                 p_bar_n= statev_n[pos_dam];                       
+                 dp_bar= statev_n[pos_dam+1];
+                 D_n= statev_n[pos_dam+2];
+                 Max_p_bar = statev_n[pos_dam+4];
+
+                 p_bar= p_bar_n+dp_bar;
+         
+           dp_bar =  p_bar -Max_p_bar;
+           
+           if (dp_bar >= 0) {
+                Max_p_bar = p_bar;
+
+                if(p_bar > p0){ 
+
+                    D=(p_bar-p0)/(pc-p0);    
+                    dD=D-D_n;
+                 
+                    *dDdp_bar= 1.0/(pc-p0);
+                    cleartens2(dDdE);
+        	}
+            }
+	    else {
+                   D=D_n;
+                   dD=0.0;
+                   cleartens2(dDdE);  
+                   *dDdp_bar= 0.0; 
+
+            }
+        if( D >= statev[pos_dam+get_pos_maxD()]) { //0.9){    //0.99
+                   D=statev[pos_dam+get_pos_maxD()]; //0.9;   //0.99
+                  dD=0.0;
+                   *dDdp_bar= 0.0; 
+                   cleartens2(dDdE);
+        }
+
+
+// update damage variable in statev
+         statev[pos_dam]= p_bar;
+	 statev[pos_dam+2]= D;
+	 statev[pos_dam+3]= dD;
+	 statev[pos_dam+4]= Max_p_bar;
+
+         cleartens2(dDdE);
          
 }
 
@@ -213,9 +590,56 @@ void EXPN_Damage::damagebox(double* statev_n, double* statev, int pos_strn, int
 
 //  statev for damage  p_bar, dp_bar ,D, dD
 
-  
+         double p_bar, dp_bar, p_bar_n;
+         double Max_p_bar;
+         double D, dD, D_n;
+         double para;
+
+                 p_bar_n= statev_n[pos_dam];                       // p_bar=p_bar_n+dp_bar
+                 dp_bar= statev_n[pos_dam+1];
+                
+                 D_n= statev_n[pos_dam+2];
+                 Max_p_bar = statev_n[pos_dam+4];
+
+
+                 p_bar= p_bar_n+dp_bar;
+         
+            dp_bar =  p_bar -Max_p_bar;
+
+            if(dp_bar >= 0.0){ 
+                    
+                    Max_p_bar= p_bar;
+
+                    para= -Beta*p_bar;
+                    D=1.0-exp(para);    
+                    dD=D-D_n;
+                    cleartens2(dDdE);
+        	}
+	    else{
+                    D=D_n;
+                    dD=0.0;
+                    *dDdp_bar= 0.0;
+                    cleartens2(dDdE); 
+                 }  
+       if( D > statev[pos_dam+get_pos_maxD()]) { //0.9){    //0.99
+                   D=statev[pos_dam+get_pos_maxD()]; //0.9;   //0.99
+                  dD=0.0;
+                   *dDdp_bar= 0.0; 
+                   cleartens2(dDdE);
+        }
+// update damage variable in statev
+         statev[pos_dam]= p_bar;
+	 statev[pos_dam+2]= D;
+	 statev[pos_dam+3]= dD;
+	 statev[pos_dam+4]= Max_p_bar;
+
+         cleartens2(dDdE);
+         *dDdp_bar= Beta*(1.0-D_n-alpha*dD);
+
 }
 
+
+
 ///******************************************************************************************************************************************************************
 //Sigmoid DAMAGE MODEL (nonlocal)
 //for nonlocal MT type 
@@ -251,11 +675,64 @@ void Sigmoid_Damage::print(){
 
 void Sigmoid_Damage::damagebox(double* statev_n, double* statev, int pos_strn, int pos_strs, int pos_dam, double** Calgo,double* dDdE, double *dDdp_bar, double alpha, int kinc, int kstep){
 
+//  statev for damage  p_bar, dp_bar ,D, dD
 
+         double p_bar, dp_bar, p_bar_n;
+         double Max_p_bar;
+         double D, dD, D_n;
+         double para;
+         double Dmax;
+         Dmax = statev[pos_dam+get_pos_maxD()];
+         if(Dmax<0.7) Dmax = 0.99;
+
+                 p_bar_n= statev_n[pos_dam];                       // p_bar=p_bar_n+dp_bar
+                 dp_bar= statev_n[pos_dam+1];
+                
+                 D_n= statev_n[pos_dam+2];
+                 Max_p_bar = statev_n[pos_dam+4];
+                 
+
+                 p_bar= p_bar_n+dp_bar;
+         
+            dp_bar =  p_bar -Max_p_bar;
+
+            if(dp_bar >= 0.0){ 
+                    
+                    Max_p_bar= p_bar;
+
+                    para= -Beta*(p_bar-pc);
+                    D=1.0/(1.0+exp(para));    
+
+                    cleartens2(dDdE);
+
+                    *dDdp_bar= Beta*D*(1.0-D);
+                    
+                    D = (D - D0)*Dmax/(1.0-D0);
+                    *dDdp_bar *= Dmax/(1.0-D0);
+                    dD=D-D_n;
+        	}
+	    else{
+                    D=D_n;
+                    dD=0.0;
+                    *dDdp_bar= 0.0;
+                    cleartens2(dDdE); 
+                 }  
+       if( D > Dmax) {
+                   D=Dmax; 
+                   dD=0.0;
+                   *dDdp_bar= 0.0; 
+                   cleartens2(dDdE);
+        }
+// update damage variable in statev
+         statev[pos_dam]= p_bar;
+	 statev[pos_dam+2]= D;
+	 statev[pos_dam+3]= dD;
+	 statev[pos_dam+4]= Max_p_bar;
+
+         cleartens2(dDdE);
                
 }
 	
-	
 
 ////////////////////////////////////////////////
 //////////end of new defined ling Wu 11/4/2011.
@@ -304,7 +781,170 @@ void PLN_Damage::print(){
 
 void PLN_Damage::damagebox(double* statev_n, double* statev, int pos_strn, int pos_strs, int pos_dam, double** Calgo,double* dDdE, double *dDdp_bar, double alpha, int kinc, int kstep){
 
- 
+         double p, p_bar, dp_bar, p_bar_n;
+         double Max_p_bar;
+         double D, dD, D_n;
+         double para1, para2, sq2;
+      
+         // for euivalent strain  
+         int i, j, k;
+         static double* strn = NULL; 
+         static double** S = NULL;
+         static double* e = NULL;
+         static double** U = NULL;
+         static double*** dedS = NULL;
+
+         static double** dpdS = NULL;
+
+         if(strn == NULL)
+         {
+           mallocvector(&strn,6);
+	   mallocmatrix(&S,3,3);
+           mallocvector(&e,3);
+	   mallocmatrix(&U,3,3);
+	   malloctens3(&dedS,3,3,3);
+	   mallocmatrix(&dpdS,3,3);
+         }
+         cleartens2(strn);
+         for(i=0;i<3;i++)
+         {
+           e[i]=0.;
+           for(j=0;j<3;j++)
+           {
+             S[i][j]=0.;
+             U[i][j]=0.;
+             dpdS[i][j]=0.;
+             for(k=0;k<3;k++)
+               dedS[i][j][k]=0.;
+           }
+         }
+          
+// compute equivalent strain p 
+    //****** before calling function Jacobian_Eigen a sembly of matrix from strain tensor is used
+    //******** strain: (e11,e22,e33,sq2*e12,sq2*e13,sq2*e23)
+         sq2 = sqrt(2.);
+         cleartens2(dDdE);
+
+         copyvect(&(statev[pos_strn]), strn, 6);
+         for (i=0; i<3; i++){
+            S[i][i] = strn[i];
+            e[i] = 0.;
+         }
+          S[0][1] = S[1][0] = strn[3]/sq2;
+          S[0][2] = S[2][0] = strn[4]/sq2;
+          S[1][2] = S[2][1] = strn[5]/sq2;
+
+    //**compute principle strain and keep in e ************************
+          Jacobian_Eigen( 3, S, e, U, dedS);
+  
+          para1 = 0.0;
+          for (int i=0; i<3; i++){
+               if(e[i] > 0.) { 
+                    para1 = para1 + e[i]*e[i]; 
+                }
+          }
+          p = sqrt(para1);
+
+//********* compute damage**********************
+
+                 p_bar_n = statev_n[pos_dam];                       // p_bar=p_bar_n+dp_bar
+                 dp_bar = statev_n[pos_dam+1];
+                 D_n = statev_n[pos_dam+2];
+                 Max_p_bar = statev_n[pos_dam+5];
+       
+
+#ifdef NONLOCALGMSH
+                 if(localDamage) dp_bar = p - statev_n[pos_dam+4];
+#else
+// add by wu ling try nonlocal mehod without finite element cacilation
+        
+                 dp_bar = p - statev_n[pos_dam+4];
+#endif
+
+                 p_bar= p_bar_n+dp_bar;    
+                
+            if(p_bar >= p0 && p_bar >= Max_p_bar)
+            {
+               Max_p_bar = p_bar;
+
+               if(pc > Max_p_bar)
+                    {
+                      para1 = pow((pc - Max_p_bar)/(pc-p0), Alpha);
+                      para2 = pow(p0/Max_p_bar, Beta);
+                      D = 1.0 - para2 * para1;
+                      *dDdp_bar= Beta*para2/ Max_p_bar * para1 + para2 * Alpha * pow((pc- Max_p_bar), (Alpha-1.0))/pow((pc-p0), Alpha);
+                      if(D > Dc)  //we can remove this, but then in cm3Libraries we need to update Dmax at crack transition in NonLocalDamageLaw
+                      {
+                        D=Dc;
+                        *dDdp_bar = 0;
+                      }
+                      if( D > statev[pos_dam+get_pos_maxD()]) { //0.9){    //0.99
+                           D=statev[pos_dam+get_pos_maxD()]; //0.9;   //0.99
+                           dD=0.0;
+                          *dDdp_bar= 0.0; 
+                      }
+                    }
+                    else if (pc <= Max_p_bar)
+                    { 
+                      D = Dc;
+                      *dDdp_bar= 0.;
+                    }
+                    dD=D-D_n;
+            }
+
+            else {
+                   D=D_n;
+                   dD=0.0;
+  
+                   *dDdp_bar= 0.0; 
+
+            }
+
+
+
+// update damage variable in statev
+         statev[pos_dam]= p_bar;
+	 statev[pos_dam+2]= D;
+	 statev[pos_dam+3]= dD;
+	 statev[pos_dam+5]= Max_p_bar;
+
+
+// compute equivalent strain p's derivatives to strain dpdE which is keept in dDdE
+    //****** before calling function Jacobian_Eigen a sembly of matrix from strain tensor is used
+    //******** strain: (e11,e22,e33,sq2*e12,sq2*e13,sq2*e23)
+
+         cleartens2(dDdE);
+   
+         for (int j=0; j<3; j++){
+                for (int k=0; k<3; k++){
+                       dpdS[j][k] = 0.0;
+                }
+          }
+
+          for (int i=0; i<3; i++){
+               if(e[i] > 0.) { 
+                      for (int j=0; j<3; j++){
+                            for (int k=0; k<3; k++){
+                            dpdS[j][k] = dpdS[j][k] + e[i]/p*dedS[i][j][k];
+                            }
+                      }
+                } 
+          }
+      // here we use dDdE to give back dpdE*****
+          
+          dDdE[0] = dpdS[0][0];
+          dDdE[1] = dpdS[1][1];
+          dDdE[2] = dpdS[2][2];
+
+          dDdE[3] = (dpdS[0][1]+dpdS[1][0])/sq2;
+          dDdE[4] = (dpdS[0][2]+dpdS[2][0])/sq2;
+          dDdE[5] = (dpdS[1][2]+dpdS[2][1])/sq2;
+
+
+
+     // update damage variable in statev
+	 statev[pos_dam+4]= p;
+
 }
 
 //****************************************************************************************
@@ -313,7 +953,40 @@ void PLN_Damage::damagebox(double* statev_n, double* statev, int pos_strn, int p
 //constructor
 Weibull_Damage::Weibull_Damage(double* props, int iddam):Damage(props,iddam){
 
-
+	nsdv = 2;                                     
+	L = props[iddam+1];
+        L0 = props[iddam+2];
+        S0 = props[iddam+3];
+        Alpha = props[iddam+4];
+	m = props[iddam+5];
+        NFiber = props[iddam+6];
+        Gc = props[iddam+7];
+        if(Gc>1.0e-15) n=props[iddam+8];
+        if(NFiber!= 0){
+            std::random_device rd; 
+            std::mt19937 gen(rd()); 
+            std::normal_distribution<double> d(0.0, 1.0); 
+            // get random number with normal distribution using gen as random source
+            Pdam = d(gen); 
+            double tmp;
+            tmp = pow(L/L0,-Alpha)*log((9+NFiber)/NFiber);
+            Strs_cr = S0*pow(tmp, 1.0/m);
+            pos_DamParm1 = 0;
+            pos_DamParm2 = 0;
+         }
+         else{
+            pos_DamParm1 = 1;
+            pos_DamParm2 = 2;
+            nsdv += 2;
+         }
+         pos_Fd_bar = pos_DamParm2+1;
+         pos_dFd_bar = pos_DamParm2+2;
+         pos_locFd = pos_DamParm2+3;
+         pos_maxD = pos_locFd+1;
+         pos_dDdS = pos_maxD +1;
+         pos_StrsTrans = pos_dDdS+1;
+         pos_Dt = pos_StrsTrans+1;
+         nsdv += 7;
 }
 
 //destructor
@@ -332,29 +1005,166 @@ void Weibull_Damage::print(){
 
 void Weibull_Damage::damagebox(double* statev_n, double* statev, int pos_strn, int pos_strs, int pos_dam, double** Calgo,double* dDdE, double *dDdFd_bar, double alpha, int kinc, int kstep){
 
- 
-}
-
-
-
+         double p, tmp;
+         double tmp_n;
+         double strs_eff;
+         double D;
+         double d, d_bar;
+         double p_norm, S_cr;
+         double a,b,c,y ;
+      
+         // for equivalent strain  
+         int num_fib;
+         int i, j, k;
+         static double* strn = NULL; 
+         static double* strs = NULL;
+         double tol = 1.0e-20;
+         double Dtrans = 0.25;//0.2; 
+         double sigma_trans = 0.0; 
+
+         if(strn == NULL)
+         {
+           mallocvector(&strn,6);
+	   mallocvector(&strs,6);
+         }
+
+         if(NFiber!= 0){
+            num_fib = NFiber; 
+            p_norm = Pdam; 
+         }
+         else{
+            num_fib = statev[pos_dam + pos_DamParm1]; 
+            p_norm = statev[pos_dam + pos_DamParm2];            
+         }
+
+         cleartens2(strn);
+         cleartens2(strs);
+      //********* compute Strs_eff, S_cr, d_bar  **********************
+         copyvect(&(statev[pos_strn]), strn, 6);
+         contraction42(Calgo, strn, strs);
+         strs_eff = strs[2];
+         
+        // compute equivalent strain p's derivatives to strain dpdE which is keept in dDdE
+         cleartens2(dDdE);
+         *dDdFd_bar= 0.0; 
+         D = 0.0;
+   // 1.  for the case of nonlocal--------------------------------
+         if(Gc>=1.0e-15){    
+             d_bar = statev_n[pos_dam+pos_Fd_bar] + statev_n[pos_dam + pos_dFd_bar];  
+             statev[pos_dam+pos_Fd_bar] = d_bar;            
+             D = 1.0 - pow(1.0-d_bar,n);            
+             if(strs_eff >= 0.0){
+                   if(D >= statev_n[pos_dam] and D< statev[pos_dam+get_pos_maxD()]) {
+                        statev[pos_dam]= D;
+                        *dDdFd_bar= n*pow(1.0-d_bar,n-1.0); 
+                   }
+                   else{
+                        statev[pos_dam] = statev_n[pos_dam];
+                        *dDdFd_bar= n*pow(1.0-d_bar,n-1.0);     
+                        statev[pos_dam+pos_locFd] = statev_n[pos_dam+pos_locFd];   
+                   }
+              }
+              else{
+                    statev[pos_dam] = statev_n[pos_dam];
+                    *dDdFd_bar= n*pow(1.0-d_bar,n-1.0);     
+                    statev[pos_dam+pos_locFd] = statev_n[pos_dam+pos_locFd];          
+              }
+              
+         }
+   // 2.  for the case of local------------------------------------
+         else{
+             tmp = pow(L/L0,-Alpha)*log((9.0+num_fib)/num_fib);
+             S_cr = S0*pow(tmp, 1.0/m); 
+             double Dc= statev[pos_dam+get_pos_maxD()];
+             if(Dc < 0.7) Dc = 0.95;
+           //  printf("pos_maxD: %i, Dc: %lf\n",pos_dam+get_pos_maxD(),Dc);
+             d = 0.0;
+             statev[pos_dam+pos_locFd] = 0.0;
+             statev[pos_dam + pos_Fd_bar] = 0.0;
+             S_cr = S_cr/2.;
+             if(strs_eff >= S_cr){
+                 tmp = pow(L/L0,Alpha)*pow(strs_eff/S0, m);
+                 p = 1.0-exp(-tmp);
+                 D = p + p_norm*sqrt(p*(1.0-p)/num_fib);
+
+                 if( D > statev_n[pos_dam]+tol and statev_n[pos_dam] < Dc ){
+           
+                     if(D < Dtrans){
+                         tmp = (1.0 + p_norm*(1.0-2.0*p)/2.0/sqrt(num_fib*p*(1.0-p)))*m/S0;
+                         tmp = tmp*pow(L/L0,Alpha)*pow(strs_eff/S0, m-1.0)*(1.0-p);
+                         if(tmp!=tmp) tmp=0.;
+                         statev[pos_dam+pos_StrsTrans] =  strs_eff;
+                         statev[pos_dam+pos_dDdS] = tmp;
+                         statev[pos_dam+pos_Dt] = D;
+                     }
+                     else{
+                         double n = 1.5;
+                         sigma_trans =  statev_n[pos_dam+pos_StrsTrans];
+                         tmp = statev_n[pos_dam+pos_dDdS]/Dc;
+                         c = (1.0-statev[pos_dam+pos_Dt]/Dc)*(n+1.0);
+                         b = 1.0-c;
+
+                         a = (n+1.0)*(n+1.0)*tmp/n/c;
+                         D =  Dc*(b+c*n/(n+exp(-a*(strs_eff-sigma_trans))));
+
+                         statev[pos_dam+pos_StrsTrans] =  statev_n[pos_dam+pos_StrsTrans];
+                         statev[pos_dam+pos_dDdS] = statev_n[pos_dam+pos_dDdS];
+                         statev[pos_dam+pos_Dt] = statev_n[pos_dam+pos_Dt];
+
+                         tmp = Dc*c*n*a*exp(-a*(strs_eff-sigma_trans))/(n+exp(-a*(strs_eff-sigma_trans)))/(n+exp(-a*(strs_eff-sigma_trans)));
+                     }
+                     if(D > statev_n[pos_dam]+tol and D < Dc){ //case in which we have unloading beyond Dsat: we predict a D increasing but when corrected for saturation it is actually decreasing
+                         dDdE[0] = tmp*Calgo[2][0];
+                         dDdE[1] = tmp*Calgo[2][1];
+                         dDdE[2] = tmp*Calgo[2][2];
+                         dDdE[3] = tmp*Calgo[2][3];
+                         dDdE[4] = tmp*Calgo[2][4];
+                         dDdE[5] = tmp*Calgo[2][5];
+
+                         statev[pos_dam]= D;
+                     }
+                     else if(D < statev_n[pos_dam]+tol and D < Dc){
+                         statev[pos_dam] = statev_n[pos_dam];
+                     }
+                     else // case D > Dc
+                     {
+                         statev[pos_dam]= Dc;
+                         statev[pos_dam+pos_StrsTrans] =  statev_n[pos_dam+pos_StrsTrans];
+                         statev[pos_dam+pos_dDdS] = statev_n[pos_dam+pos_dDdS];
+                         statev[pos_dam+pos_Dt] = statev_n[pos_dam+pos_Dt];
+                     }
+                 } 
+                 else {
+                     statev[pos_dam] = statev_n[pos_dam];
+                     statev[pos_dam+pos_StrsTrans] =  statev_n[pos_dam+pos_StrsTrans];
+                     statev[pos_dam+pos_dDdS] = statev_n[pos_dam+pos_dDdS];
+                     statev[pos_dam+pos_Dt] = statev_n[pos_dam+pos_Dt]; 
+                 }
+             }
+             else{
+                     statev[pos_dam] = statev_n[pos_dam];
+                     statev[pos_dam+pos_StrsTrans] =  statev_n[pos_dam+pos_StrsTrans];
+                     statev[pos_dam+pos_dDdS] = statev_n[pos_dam+pos_dDdS];
+                     statev[pos_dam+pos_Dt] = statev_n[pos_dam+pos_Dt]; 
+             }
+
+         }
 
-// JMC JMC JMC NEW
+}
 
-//LEMAITRE-CHABOCHE DAMAGE MODEL (nonlocal)
-//for nonlocal MT type 
-//PROPS: ID, S0, n
-//STATEV: D,dD,p_bar,dp_bar, plastic strn (6)
-//
-// output: dD increment of D in statev
-//         dDdE, dDdp_bar D w.r.t strain and p_bar respectivly
-//****************************************
+//Juan Manuel Calleja 2019
 //constructor
+
 BILIN_Damage::BILIN_Damage(double* props, int iddam):Damage(props, iddam){
 
-	nsdv = 6;                                     //p_bar dp_bar D dD, Max_p_bar,         Max_p_bar keep the highest history value of p_bar
+	nsdv = 8;                                     //p_bar dp_bar D dD, Max_p_bar,         Max_p_bar keep the highest history value of p_bar
 	S0 = props[iddam+1];
 	n = props[iddam+2];
         p0 = props[iddam+3];
+	ponset = props[iddam+4];
+        D_crit = props[iddam+5];
+	Alpha = props[iddam+6];
+	Beta = props[iddam+7];
         pos_maxD=nsdv-1;
 }
 
@@ -373,37 +1183,340 @@ void BILIN_Damage::print(){
 
 //damagebox
 void BILIN_Damage::damagebox(double* statev_n, double* statev, int pos_strn, int pos_strs, int pos_dam, double** Calgo,double* dDdE, double *dDdp_bar, double alpha, int kinc, int kstep){
+
+	//  statev for damage  p_bar, dp_bar ,D, dD
+
+        double Y_n, Y, Y_a, strain_x, stress_x;        
+
+        double p_bar, dp_bar, p_bar_n;
+        double D, dD, D_n, dp_bar_Save,p_bar_Save;
+        double Max_p_bar;
+
+        // allocated once
+        static double* strs_n;
+        static double* strs;
+        static double* Estrn_n;
+        static double* Estrn;
+
+        static double* strn; 
+        static double* pstrn;
+
+        int i, j;
+        double mat1;
+        
+        static bool initialized = false; 
+
+        //allocate memory
+	if(!initialized){
+          mallocvector(&strs_n,6);
+          mallocvector(&strs,6);
+          mallocvector(&Estrn_n,6);
+          mallocvector(&Estrn,6);
+
+          mallocvector(&strn,6);
+          mallocvector(&pstrn,6);
+ 
+          initialized = true;
+        }
+        cleartens2(strs_n);
+        cleartens2(strs);
+        cleartens2(Estrn_n);
+        cleartens2(Estrn);
+        cleartens2(strn);
+        cleartens2(pstrn);
+
+  
+        p_bar_n= statev_n[pos_dam];                       
+        dp_bar= statev_n[pos_dam+1];
+               
+        D_n= statev_n[pos_dam+2];
+        Max_p_bar = statev_n[pos_dam+4];
+        dp_bar_Save = statev_n[pos_dam+5];
+        p_bar_Save = statev_n[pos_dam+6];
+
+
+        p_bar= p_bar_n+dp_bar;  
+
+        dp_bar = p_bar - Max_p_bar;  
+
+       if(p_bar >= Max_p_bar){
+
+             Max_p_bar= p_bar;                    
+        }
+        
+        
+        if(Max_p_bar > p0){ 
+
+                 copyvect(&(statev_n[pos_strs]),strs_n,6);
+                 copyvect(&(statev[pos_strs]),strs,6);
+                 
+                 copyvect(&(statev_n[pos_strn]),strn,6);
+                 copyvect(&(statev_n[pos_strn+18]),pstrn,6);
+                 addtens2(1., strn, -1., pstrn, Estrn_n);
+
+                 copyvect(&(statev[pos_strn]),strn,6);
+                 copyvect(&(statev[pos_strn+18]),pstrn,6);
+                 addtens2(1., strn, -1., pstrn, Estrn);
+
+                 Y_n= 0.5*fabs(contraction22(strs_n, Estrn_n));
+                 Y= 0.5*fabs(contraction22(strs, Estrn));
+
+                 Y_a= (1.-alpha)*Y_n + alpha*Y;
+
+                 
+
+
+		 strain_x = strn[0];
+		 stress_x = strs[0];
+
+                 if(dp_bar>0.0 && p_bar<ponset)
+                 {                      
+                      dD= D_crit/ponset*dp_bar;
+		      *dDdp_bar=D_crit/ponset;
+
+
+                      cleartens2(dDdE);
+                      p_bar_Save=p_bar;
+                 } 
+
+		 else if(dp_bar>0.0 && p_bar>=ponset)
+                 {
+                      dD= D_crit/ponset*dp_bar + Alpha*pow(p_bar+dp_bar-ponset,Beta);
+                      *dDdp_bar = D_crit/ponset + Alpha*Beta*pow(p_bar+dp_bar-ponset,Beta-1.);
+
+                      cleartens2(dDdE);
+
+		      
+
+                 } 
+                 else{
+                      dD=0.;
+                      cleartens2(dDdE);
+                      *dDdp_bar=0.;
+                 }
+
+                 D= D_n + dD;
+       }
+        else {
+                   D=D_n;
+                   dD=0.0;
+ 
+                   *dDdp_bar= 0.0; 
+                   cleartens2(dDdE);
+
+        }
+
+        if( D > statev[pos_dam+get_pos_maxD()]) { 
+                   D=statev[pos_dam+get_pos_maxD()]; 
+                  dD=0.0;
+
+                   *dDdp_bar= 0.0; 
+                   cleartens2(dDdE);
+        }
+
+          
+
+       // update damage variable in statev
+         statev[pos_dam]= p_bar;
+	 statev[pos_dam+2]= D;
+	 statev[pos_dam+3]= dD;
+	 statev[pos_dam+4]= Max_p_bar;
+         statev[pos_dam+5]= dp_bar_Save;
+         statev[pos_dam+6] = p_bar_Save;
+
+      
+        
         		
 }
 
+
+
+
+
+
+//Juan Manuel Calleja 2020
+//constructor
+
 BILIN_Damage_Stoch::BILIN_Damage_Stoch(double* props, int iddam):Damage(props, iddam){
 
-        nsdv = 6;                                     //p_bar dp_bar D dD, Max_p_bar,         Max_p_bar keep the highest history value of p_bar
-        S0 = props[iddam+1];
-        n = props[iddam+2];
+	nsdv = 11;                                     //p_bar dp_bar D dD, Max_p_bar,         Max_p_bar keep the highest history value of p_bar
+	S0 = props[iddam+1];
+	n = props[iddam+2];
         p0 = props[iddam+3];
+	//ponset = props[iddam+4];
+        //D_crit = props[iddam+5];
+	//Alpha = props[iddam+6];
+	Beta = props[iddam+7];
+	pos_DamParm1 = nsdv-4;
+        pos_DamParm2 = nsdv-3;
+        pos_DamParm3 = nsdv-2;
         pos_maxD=nsdv-1;
 }
 
 //destructor
 BILIN_Damage_Stoch::~BILIN_Damage_Stoch(){
-        ;
+	;
 }
 
 //print
 void BILIN_Damage_Stoch::print(){
 
-        printf("Lemaitre-Chaboche nonlocaldamage law\n");
-        printf("S0: %lf, n: %lf\n", S0, n);
-
+	printf("Lemaitre-Chaboche nonlocaldamage law\n");
+	printf("S0: %lf, n: %lf\n", S0, n);
+	
 }
 
 //damagebox
 void BILIN_Damage_Stoch::damagebox(double* statev_n, double* statev, int pos_strn, int pos_strs, int pos_dam, double** Calgo,double* dDdE, double *dDdp_bar, double alpha, int kinc, int kstep){
 
+	//  statev for damage  p_bar, dp_bar ,D, dD
+
+        double Y_n, Y, Y_a, strain_x, stress_x;  
+        double ponset, D_crit, Alpha;     
+
+        double p_bar, dp_bar, p_bar_n;
+        double D, dD, D_n, dp_bar_Save,p_bar_Save;
+        double Max_p_bar;
+
+        // allocated once
+        static double* strs_n;
+        static double* strs;
+        static double* Estrn_n;
+        static double* Estrn;
+
+        static double* strn; 
+        static double* pstrn;
+
+        int i, j;
+        double mat1;
+        
+        static bool initialized = false; 
+
+        //allocate memory
+	if(!initialized){
+          mallocvector(&strs_n,6);
+          mallocvector(&strs,6);
+          mallocvector(&Estrn_n,6);
+          mallocvector(&Estrn,6);
+
+          mallocvector(&strn,6);
+          mallocvector(&pstrn,6);
+ 
+          initialized = true;
+        }
+        cleartens2(strs_n);
+        cleartens2(strs);
+        cleartens2(Estrn_n);
+        cleartens2(Estrn);
+        cleartens2(strn);
+        cleartens2(pstrn);
+
+        ponset = statev_n[pos_dam+pos_DamParm1];
+        D_crit = statev_n[pos_dam+pos_DamParm2];
+        Alpha = statev_n[pos_dam+pos_DamParm3];
+        p_bar_n= statev_n[pos_dam];                       
+        dp_bar= statev_n[pos_dam+1];
+               
+        D_n= statev_n[pos_dam+2];
+        Max_p_bar = statev_n[pos_dam+4];
+        dp_bar_Save = statev_n[pos_dam+5];
+        p_bar_Save = statev_n[pos_dam+6];
+
+
+        p_bar= p_bar_n+dp_bar;  
+
+        dp_bar = p_bar - Max_p_bar;  
+
+       if(p_bar >= Max_p_bar){
+
+             Max_p_bar= p_bar;                    
+        }
+        
+        
+        if(Max_p_bar > p0){ 
+
+                 copyvect(&(statev_n[pos_strs]),strs_n,6);
+                 copyvect(&(statev[pos_strs]),strs,6);
+                 
+                 copyvect(&(statev_n[pos_strn]),strn,6);
+                 copyvect(&(statev_n[pos_strn+18]),pstrn,6);
+                 addtens2(1., strn, -1., pstrn, Estrn_n);
+
+                 copyvect(&(statev[pos_strn]),strn,6);
+                 copyvect(&(statev[pos_strn+18]),pstrn,6);
+                 addtens2(1., strn, -1., pstrn, Estrn);
+
+                 Y_n= 0.5*fabs(contraction22(strs_n, Estrn_n));
+                 Y= 0.5*fabs(contraction22(strs, Estrn));
+
+                 Y_a= (1.-alpha)*Y_n + alpha*Y;
+
+                 
+
+
+		 strain_x = strn[0];
+		 stress_x = strs[0];
+
+                 if(dp_bar>0.0 && p_bar<ponset)
+                 {                      
+                      dD= D_crit/ponset*dp_bar;
+		      *dDdp_bar=D_crit/ponset;
+
+
+                      cleartens2(dDdE);
+                      p_bar_Save=p_bar;
+                 } 
+
+		 else if(dp_bar>0.0 && p_bar>=ponset)
+                 {
+                      dD= D_crit/ponset*dp_bar + Alpha*pow(p_bar+dp_bar-ponset,Beta);
+                      *dDdp_bar = D_crit/ponset + Alpha*Beta*pow(p_bar+dp_bar-ponset,Beta-1.);
+
+                      cleartens2(dDdE);
+
+		      
+
+                 } 
+                 else{
+                      dD=0.;
+                      cleartens2(dDdE);
+                      *dDdp_bar=0.;
+                 }
+
+                 D= D_n + dD;
+       }
+        else {
+                   D=D_n;
+                   dD=0.0;
+ 
+                   *dDdp_bar= 0.0; 
+                   cleartens2(dDdE);
+
+        }
+
+        if( D > statev[pos_dam+get_pos_maxD()]) { 
+                   D=statev[pos_dam+get_pos_maxD()]; 
+                  dD=0.0;
+
+                   *dDdp_bar= 0.0; 
+                   cleartens2(dDdE);
+        }
+
+          
+
+       // update damage variable in statev
+         statev[pos_dam]= p_bar;
+	 statev[pos_dam+2]= D;
+	 statev[pos_dam+3]= dD;
+	 statev[pos_dam+4]= Max_p_bar;
+         statev[pos_dam+5]= dp_bar_Save;
+         statev[pos_dam+6] = p_bar_Save;
+
+      
+        
+        		
 }
 
-// JMC JMC JMC NEW
 
 
 #endif
diff --git a/NonLinearSolver/materialLaw/damage.h b/NonLinearSolver/materialLaw/damage.h
index ccd86915800a9a2955a2943303e040df081c7490..93f1310d7d0d367b52b02bbfc183c74689d1188e 100755
--- a/NonLinearSolver/materialLaw/damage.h
+++ b/NonLinearSolver/materialLaw/damage.h
@@ -14,11 +14,13 @@ class Damage{
 		int ndamprops;
 		int nsdv;
                 int pos_maxD;
+                bool localDamage;
 		
 	public:
 		
 		Damage(double* props, int iddam){
 			dammodel = (int) props[iddam];
+			localDamage = false;
 		}
 		virtual ~Damage(){ ; }
 		inline int get_dammodel(){  return dammodel; }
@@ -43,7 +45,10 @@ class Damage{
                 virtual double getMaxD(double *statev, int pos_dam) const {return statev[pos_dam+get_pos_maxD()];}
                 virtual void setMaxD(double *statev, int pos_dam, double Dmax) { statev[pos_dam+get_pos_maxD()]=Dmax;}
                 virtual int getNbNonLocalVariables() const {return 1;}
-
+#ifdef NONLOCALGMSH
+                virtual void setLocalDamage() {localDamage=true;}
+                virtual void setNonLocalDamage() {localDamage=false;}
+#endif
 };
 
 //Linear elastic material
diff --git a/NonLinearSolver/materialLaw/homogenization.cpp b/NonLinearSolver/materialLaw/homogenization.cpp
index 192b5d47866e49787e2f9ff7ebac7dd4ef2773fa..4145a32c8bd81bb1f54131ba16efa3b03e100602 100644
--- a/NonLinearSolver/materialLaw/homogenization.cpp
+++ b/NonLinearSolver/materialLaw/homogenization.cpp
@@ -14,6 +14,15 @@
 using namespace MFH;
 #endif
 
+
+/*    
+
+
+                                                         Debut presque 
+
+
+                                                                                                           */
+
 /*******************************************************************************************************
 //Resolution of the localization problem on the equivalent inclusion system
 // INPUT:	DE: macro strain increment (given)
@@ -28,13 +37,282 @@ using namespace MFH;
 **********************************************************************************************************/
 //***************new tensor added by wu ling: double* dpdE, double* strs_dDdp_bar
 int impl_localization(int sch, double* DE, Material* mtx_mat, Material** icl_mat, double vfM, double* vfI, double** ar, double** angles,
-                double* statev_n, double* statev, int nsdv, int idsdv_m, int* idsdv_i, int mtx, int Nicl, double** C, double*** dC, double** Calgo, double* dpdE, double* strs_dDdp_bar, double *Sp_bar, double* dFd_d_bar, double* dstrs_dFd_bar, double *dFd_dE, double** c_gF, int kinc, int kstep, double dt){
-	return 0;
+	double* statev_n, double* statev, int nsdv, int idsdv_m, int* idsdv_i, int mtx, int Nicl, double** C, double*** dC, double** Calgo, double* dpdE, double* strs_dDdp_bar,double *Sp_bar, double* dFd_d_bar, double* dstrs_dFd_bar, double *dFd_dE, double** c_gF,  int kinc, int kstep, double dt){
+
+	int i,it,pos,j;
+	int iso_all;
+	int last;
+	int error,errorlu,errortmp;
+	int neq;
+	double res, res_r, res_rr; 
+	int corr;
+	double NORM;
+	double TOL_NR = 1e-6;
+
+        error=0;
+        static bool initialized=false;
+	static double** C_n=NULL;		//macro (SC) or matrix (MT) tangent operator at tn from which Eshelby's tensor is computed
+	static double** S_n_loc=NULL;	//Eshelby's tensor in the local frame of the current inclusion
+	static double** R66=NULL;		//rotation matrix	
+	static double** mat1=NULL;		//tmporary matrix
+	static double* DeM=NULL;		//matrix strain increment
+	static double* DeM_r=NULL;		//phase strain increment of the previous iteration
+	
+        if(!initialized)
+        {
+          initialized=true;
+ 	  //memory allocation
+	  mallocmatrix(&S_n_loc,6,6);
+	  mallocmatrix(&C_n,6,6);
+	  mallocmatrix(&R66,6,6);
+  	  mallocmatrix(&mat1,6,6);
+          mallocvector(&DeM,6);
+	  mallocvector(&DeM_r,6);
+        }
+        cleartens4(S_n_loc);
+	cleartens4(C_n);
+	cleartens4(R66);
+  	cleartens4(mat1);
+        cleartens2(DeM);
+	cleartens2(DeM_r);
+
+        static int NiclInitialized = 0;
+
+	static double*** S_n=NULL;		//array of Eshelby's tensor for each phase
+	static double** DeI=NULL;		//inclusion strain increments (unknowns of the NR system)
+	static double** DeI_r=NULL;
+        if(Nicl != NiclInitialized)
+        {
+          if(S_n!=NULL) freetens3(S_n,NiclInitialized,6);
+	  if(DeI_r!=NULL) freematrix(DeI_r,NiclInitialized);
+	  if(DeI!=NULL) freematrix(DeI,NiclInitialized);
+
+  	  malloctens3(&S_n,Nicl,6,6);
+	  mallocmatrix(&DeI,Nicl,6);
+	  mallocmatrix(&DeI_r,Nicl,6);
+
+          NiclInitialized = Nicl;
+	
+        }  
+        for(i=0;i<Nicl;i++)
+        {
+         cleartens4(S_n[i]);
+         cleartens2(DeI[i]);
+         cleartens2(DeI_r[i]);
+     
+        }
+	if(sch==MT){
+		neq=6;
+		mtx_mat->get_refOp(&(statev_n[idsdv_m]), C_n, kinc, kstep);	//reference operator to compute eshelby
+	}
+	else if(sch==SC){
+		neq = 6*Nicl + 36;
+		copymatr(C,C_n,6,6); 
+		
+	}
+	else{
+		printf("bad scheme in localization: %d\n",sch);
+	}
+
+        static int neqInitialized = 0;
+	static double* F=NULL; 		//residual vector;
+	static double** J=NULL;		//jacobian matrix
+	static double* F_r=NULL;		//residual vector of at the previous iteration
+
+	static int* indx=NULL;	  //permutation vector for LU decomposition
+	double odd;		//also used for LU decomposition		
+
+	double alpha1=0.5; 		//for mid-point integration rule in each phase (default value)
+
+          
+        if(neq!=neqInitialized)
+        {
+	  if(F!=NULL) free(F);		
+	  if(F_r!=NULL) free(F_r);
+	  if(J!=NULL) freematrix(J,neqInitialized);
+	  if(indx!=NULL) free(indx);
+  	  mallocvector(&F,neq);		
+	  mallocvector(&F_r,neq);
+	  mallocmatrix(&J,neq,neq);
+	  indx = (int*)malloc(neq*sizeof(int));
+          neqInitialized=neq;
+        }
+        for(i=0;i<neq;i++)
+        {
+          F[i]=0.;
+          F_r[i]=0.;
+          for(j=0;j<neq;j++)
+          {
+            J[i][j]=0.;
+          }
+        }
+	NORM = C_n[3][3]/100;  
+
+
+	//compute Eshelby's tensor for each inclusion phase	
+	for(i=0;i<Nicl;i++){
+			
+		eul_mat(angles[i],R66);
+		rot4(R66,C_n,mat1); 				//express (fictitious) matrix tangent operator in local axes
+		eshelby(mat1,ar[i][0],ar[i][1],S_n_loc);  	//(re-)compute Eshelby's tensor of previous timestep
+		
+		transpose(R66,R66,6,6);  			//transpose rotation matrix for inverse transformation
+		rot4(R66,S_n_loc,S_n[i]); 			//express eshelby's tensor in global axes
+	}	
+	
+
+
+	//first guess for DeM, DeI and C
+	if(kinc < 2){  //first increment of a step: use macro strain increment and elastic macro operator
+	
+		if(mtx) copyvect(DE,DeM,6);
+		for(i=0;i<Nicl;i++){		
+			copyvect(DE,DeI[i],6);
+		}
+		
+		if(sch==SC){
+			if(mtx) mtx_mat->get_elOp(C);	
+			else icl_mat[0]->get_elOp(C);
+		}
+		
+	}
+	else{	//else use solution of the previous time step
+		if(mtx){
+			pos = idsdv_m + mtx_mat->get_pos_dstrn();
+			copyvect(&(statev_n[pos]),DeM,6);
+		}
+		for(i=0;i<Nicl;i++){
+			pos = idsdv_i[i] + (icl_mat[i])->get_pos_dstrn();
+			copyvect(&(statev_n[pos]),DeI[0],6);
+		}
+	}
+
+	last=0;
+	it=0;	
+
+	
+	copymatr(C_n,C,6,6);
+
+	//compute first residual 
+
+	equationsNR(DE, DeM, DeI, mtx_mat, icl_mat, vfM, vfI, statev_n, statev, idsdv_m, idsdv_i, S_n, sch, mtx, Nicl, kinc, kstep, dt, last, 
+		neq, F, J, C, dC, Calgo, dpdE, strs_dDdp_bar, Sp_bar, dFd_d_bar, dstrs_dFd_bar, dFd_dE, c_gF, alpha1);
+	res = scalar_res(F,sch,Nicl,NORM);
+#ifdef NONLOCALGMSH
+#else
+	printf("1st Misf: %.10e\n",res);
+#endif
+
+
+	if(res<TOL_NR){
+		last=1;
+	}
+	res_r=res;
+
+	//NEWTON-RAPHSON LOOP
+	while(res>TOL_NR || last == 1){
+
+		it++;
+		corr=0;
+		ludcmp(J,neq,indx,&odd,&errorlu);									//compute LU decomposition of jacobian matrix
+		if(errorlu!=0){
+			printf("problem in LU decomposition of Jacobian matrix, iteration: %d\n",it);
+			error=1;
+                        break;
+		}
+		//solve NR system -> F contains now the NR correction
+		lubksb(J,neq,indx,F);  
+		
+		//store the solution at the previous iteration
+		copymatr(DeI,DeI_r,Nicl,6);
+		if(mtx) copyvect(DeM,DeM_r,6);
+		copymatr(C,mat1,6,6);
+		copyvect(F,F_r,neq);
+		res_r=res;		
+
+		//update strain increments
+		updateNR(DE, DeI, DeM, vfI, vfM, C, F,sch,mtx,Nicl);
+			
+		//compute new residual
+		equationsNR(DE, DeM, DeI, mtx_mat, icl_mat, vfM, vfI, statev_n, statev, idsdv_m, idsdv_i, S_n, sch, mtx, Nicl, kinc, kstep, dt, last, 
+		neq, F, J, C, dC, Calgo, dpdE, strs_dDdp_bar, Sp_bar, dFd_d_bar, dstrs_dFd_bar, dFd_dE, c_gF, alpha1);
+		res = scalar_res(F,sch,Nicl,NORM);
+
+		if((res<TOL_NR) && (last==0)){
+			last=1;
+		}else{
+			last=0;
+		}
+		//check if residual decreases
+			
+		while((res>res_r) && (error==0) && (res>TOL_NR) && (it>1) ){	
+			res_rr = res;
+			corr++;
+			//printf("Residual increases: %.10e -> reduce NR correction \n", res);
+			//reduce proposed correction
+			for(i=0;i<neq;i++){
+				F[i] = 0.5*F_r[i];
+			}
+
+			copyvect(F,F_r,neq);
+			//get back to the result of previous iteration
+			copymatr(DeI_r,DeI,Nicl,6);
+			if(mtx) copyvect(DeM_r,DeM,6);
+			copymatr(mat1,C,6,6);
+
+			updateNR(DE, DeI, DeM, vfI, vfM, C, F,sch,mtx,Nicl);
+          
+			//compute residual with the reduced correction
+			errortmp=equationsNR(DE, DeM, DeI, mtx_mat, icl_mat, vfM, vfI, statev_n, statev, idsdv_m, idsdv_i, S_n, sch, mtx, Nicl, kinc, kstep, dt, last, 
+		neq, F, J, C, dC, Calgo, dpdE, strs_dDdp_bar, Sp_bar, dFd_d_bar, dstrs_dFd_bar, dFd_dE, c_gF, alpha1);
+			res = scalar_res(F,sch,Nicl,NORM);
+			if(errortmp!=0) 
+                           error=errortmp;	 
+			//if corrections are inefficient
+			if((corr > 5) && (fabs(res-res_rr) < 1e-6)){
+				//printf("corrections are inefficient\n");
+                                //error=1;
+				break;
+			}
+
+		}//end while residual > previous residual
+#ifdef NONLOCALGMSH	
+#else
+		printf("iteration %d, Misf: %.10e\n",it,res);
+#endif
+		if (it>1500){
+			//printf("WARNING: too many iterations in Newton-Raphson loop\n");
+			
+			if(res<1e-4){	//not too bad - exit anyway
+				res=0;
+			}
+			else{
+                                error=1;
+				printf("No conv in NR loop, residual: %.10e\n",res);
+				res=0;
+			}
+			//compute algo tangent anyway...
+			last=1;
+			errortmp=equationsNR(DE, DeM, DeI, mtx_mat, icl_mat, vfM, vfI, statev_n, statev, idsdv_m, idsdv_i, S_n, sch, mtx, Nicl, kinc, kstep, dt, last, neq, F, J, C, dC, Calgo, dpdE,
+                        strs_dDdp_bar, Sp_bar, dFd_d_bar, dstrs_dFd_bar, dFd_dE, c_gF, alpha1);
+			last=0; //to exit the loop
+                        if(errortmp!=0) 
+                           error=1;
+		}
+
+	}  //end NR loop
+
+	//if(res > TOL_NR){
+	//	printf("Warning: tolerance not achieved in NR loops. last residual: %.10e\n",res);
+        //        error=1;
+	//}
+
+	return error;
 
 }
 
 /*******************************************************************************************************
-// EXPLICIT resolution of the localization problem on the equivalent inclusion system
+// resolution of the localization problem on the equivalent inclusion system
 // INPUT:	DE: macro strain increment (given)
 // 				DeM, DeI: strain increment in each phase at tn
 // 				C_n: reference tangent operator (MT->matrix, SC->macro) at tn for the computation of Eshelby's tensor
@@ -48,8 +326,206 @@ int impl_localization(int sch, double* DE, Material* mtx_mat, Material** icl_mat
 int expl_localization(int sch, double* DE, Material* mtx_mat, Material** icl_mat, double vfM, double* vfI, double** ar, double** angles,
 	double* statev_n, double* statev, int nsdv, int idsdv_m, int* idsdv_i, int mtx, int Nicl, double** C, double*** dC, double** Calgo, int kinc, int kstep, double dt){
 
+	int i,j,pos;
+	int errorlu,errortmp,error;
+        double tmp1,tmp2;
+
+	double*** S_n;
+	double** R66;
+	double** S_n_loc;
+
+	double** C_n;
+	double** invC;
+	double** SinvC;
+	double*** Ai, **invAi, **A_norm;
+	double** sumViAi, **invSumViAi;
+	double** diffC;
+	double** CiAi;
+	double** Ci, **Calgoi;
+
+	double* vec1;
+        double* vec2;
+        double* vec3;
+	double** mat1;
+	double*** cub1;
+        double** cg_temp;
+        double** cgF_temp;
+
+        double* dFd_d_bar;
+        double* dstrs_dFd_bar;
+        double *dFd_dE;
+
+	double* DeM;
+	double** DeI;
+        double Sp_bar;
+
+      
+	double alpha1=0.5;
+        error=0;
+	mallocmatrix(&C_n,6,6);
+	mallocmatrix(&R66,6,6);
+	mallocmatrix(&S_n_loc,6,6);
+	malloctens3(&S_n,Nicl,6,6);
+
+	mallocmatrix(&invC,6,6);
+	mallocmatrix(&SinvC,6,6);
+	mallocmatrix(&invAi,6,6);
+	mallocmatrix(&diffC,6,6);
+	mallocmatrix(&A_norm,6,6);
+	mallocmatrix(&sumViAi,6,6);
+	mallocmatrix(&invSumViAi,6,6);
+	mallocmatrix(&CiAi,6,6);
+	malloctens3(&Ai,Nicl,6,6);
+	mallocmatrix(&Ci,6,6);
+	mallocmatrix(&Calgoi,6,6);
+
+	mallocvector(&vec1,6);
+        mallocvector(&vec2,6);
+        mallocvector(&vec3,6);
+
+
+	mallocvector(&dFd_d_bar,1);
+        mallocvector(&dstrs_dFd_bar,6);
+        mallocvector(&dFd_dE,6);
+
+        mallocmatrix(&cg_temp,3,3);
+        mallocmatrix(&cgF_temp,3,3);
+
+
+	mallocmatrix(&mat1,6,6);
+	malloctens3(&cub1,6,6,6);
+
+	mallocmatrix(&DeI,Nicl,6);
+	DeM = NULL; //case with matrix not implemented yet...
+
+
+	if(sch==MT){
+		printf("explicit solver for MT not implemented\n");
+		return 1;
+	}
+
+	else if(sch==SC){
+
+		if(mtx){
+			printf("explicit solver for SC with matrix not implemented\n");  //j'etais la
+			return 1;
+		}
+
+		//first guess for C: use C of previous time step
+		copymatr(C,C_n,6,6);
+		
+		//first guess for DeM and DeI
+		if(kinc < 2){  //first increment of a step: use macro strain increment
+	
+			for(i=0;i<Nicl;i++){		
+				copyvect(DE,DeI[i],6);
+			}
+
+		}	
+		else{	//else use solution of the previous time step
+			for(i=0;i<Nicl;i++){
+				pos = idsdv_i[i] + (icl_mat[i])->get_pos_dstrn();
+				copyvect(&(statev_n[pos]),DeI[0],6);
+			}	
+		}
+
+
+
+
+		//compute Eshelby's tensor for each inclusion phase	
+		for(i=0;i<Nicl;i++){
+			
+			eul_mat(angles[i],R66);
+			rot4(R66,C_n,mat1);				//express (fictitious) matrix tangent operator in local axes
+			eshelby(mat1,ar[i][0],ar[i][1],S_n_loc);  	//(re-)compute Eshelby's tensor of previous timestep
+		
+			transpose(R66,R66,6,6); 			//transpose rotation matrix for inverse transformation
+			rot4(R66,S_n_loc,S_n[i]); 	   		 //express eshelby's tensor in global axes
+		}	
+
+		//inverse macro operator at tn
+		inverse(C_n,invC,&errortmp,6);
+                if(errortmp!=0) 
+                   error=1;
+
+		//reset reference and algo macro tangent operator to zero
+		cleartens4(Calgo);
+		cleartens4(C);
+		//1st loop over inclusions
+		for(i=0;i<Nicl;i++){
+
+			(icl_mat[i])->get_refOp(&(statev_n[idsdv_i[i]]), Ci, kinc, kstep);
+
+			addtens4(1.,Ci,-1.,C_n,diffC);
+			contraction44(S_n[i],invC,SinvC);
+			contraction44(SinvC,diffC,invAi);
+			for(j=0;j<6;j++)	invAi[j][j] +=1.;
+			inverse(invAi,Ai[i],&errortmp,6);
+                        if(errortmp!=0) 
+                           error=1;
+
+			addtens4(1.,sumViAi,vfI[i],Ai[i],sumViAi);
+		}
+
+		inverse(sumViAi,invSumViAi,&errortmp,6);
+                if(errortmp!=0) 
+                    error=1;
+		
+		//second loop over inclusions
+		for(i=0;i<Nicl;i++){
+			
+			contraction44(Ai[i],invSumViAi,A_norm);
+			//new strain increment
+			contraction42(A_norm,DE,DeI[i]);
+			//call constbox of inclusion
+			errortmp=(icl_mat[i])->constbox(DeI[i], &(statev_n[idsdv_i[i] + (icl_mat[i])->get_pos_strs()]),  &(statev[idsdv_i[i] + (icl_mat[i])->get_pos_strs()]), &(statev_n[idsdv_i[i]]), &(statev[idsdv_i[i]]), Ci, cub1, vec1, mat1, Calgoi, alpha1, vec2, vec3, &Sp_bar,  cg_temp, dFd_d_bar, dstrs_dFd_bar, dFd_dE, cgF_temp, &tmp1, &tmp2,kinc, kstep, dt);
+                        if(errortmp!=0) 
+                            error=1;
+
+
+			//build new macro operator - reference and algorithmic
+			contraction44(Ci,A_norm,CiAi);
+			addtens4(1.,C,vfI[i],CiAi,C);
+			
+			contraction44(Calgoi,A_norm,CiAi);
+			addtens4(1.,Calgo,vfI[i],CiAi,Calgo);	
+			
+			//not implemented yet: computation of dC 					
+
+		}
 	
-	return 0;
+	}
+
+	else{
+		printf("Wrong value for sch: must be MT or SC: %d\n",sch);
+		return 1;
+	}
+	
+	freematrix(DeI,Nicl);
+
+	freematrix(C_n,6);
+	freematrix(R66,6);
+	freematrix(invC,6);
+	freematrix(SinvC,6);
+	freematrix(invAi,6);
+	freematrix(A_norm,6);
+	freematrix(sumViAi,6);
+	freematrix(invSumViAi,6);
+	freematrix(CiAi,6);
+	freetens3(Ai,Nicl,6);
+	freematrix(Ci,6);
+	freematrix(Calgoi,6);
+		
+	free(vec1);
+        free(vec2);
+        free(vec3);
+	freematrix(mat1,6);
+	freetens3(cub1,6,6);
+
+        freematrix(cg_temp,3);
+        freematrix(cgF_temp,3);
+	
+	return error;
 
 }
 
@@ -57,11 +533,875 @@ int expl_localization(int sch, double* DE, Material* mtx_mat, Material** icl_mat
  //*****************New tenor added by wu ling: double* dpdE, double* strs_dDdp_bar ****************
 int equationsNR(double* DE, double* DeM, double** DeI, Material* mtx_mat, Material** icl_mat, double vfM, double* vfI, 
 	double* statev_n, double* statev, int idsdv_m, int* idsdv_i, double*** S0, int sch, int mtx, int Nicl, int kinc, int kstep, double dt, int last, 
-                int neq, double* F, double** J, double** C, double*** dC, double** Calgo, double* dpdE, double* strs_dDdp_bar,double *Sp_bar, double* dFd_d_bar, double* dstrs_dFd_bar, double *dFd_dE, double** c_gF, double alpha1)
+	int neq, double* F, double** J, double** C, double*** dC, double** Calgo,double* dpdE, double* strs_dDdp_bar, double *Sp_bar, double* dFd_d_bar, double* dstrs_dFd_bar, 
+        double *dFd_dE, double** c_gF, double alpha1)
+
 {
 
+	int i,j,k,m,n,l;
+	double V, VI;
+        double tmp1,tmp2;
+        double D_m, dDdp_bar;                             // wu ling  2011/10/17
+        double sum_strs_dDdp, sum_strs;
+
+	int error=0;
+        int errortmp=0;
+
+	static double** I=NULL;				//identity tensor
+
+	static double*** CalgoI=NULL, **CalgoM=NULL;		//algorithmic tangent operators of inclusions and matrix
+	static double** CI=NULL,**CM=NULL; 			//effective tangent operators of inclusions and matrix ...
+	static double*** dCMdde=NULL, ***dCIdde=NULL;		// ... and derivatives
+	static double* dtauI=NULL, *dtauM=NULL;		//increments of polarization stress in inclusion and matrix ...
+	static double** ddtauIdde=NULL, **ddtauMdde=NULL;	// ... and derivatives
+	static double** invC=NULL;				//inverse of macro tangent operator
+	static double** invJ=NULL;				//inverse of jacobian matrix
+	static double**S=NULL, ***invS=NULL;			//eshelby's tensor and its inverse
+	static double**AI=NULL;				//strain concentration tensor
+	static double** PI=NULL;				//Hill's polarization tensor
+
+	//some additional tensors...
+	static double** CIAI=NULL, **AIPI=NULL;
+	static double ***CinvS=NULL;				//C*S^{-1} 
+	static double **mat1=NULL, **mat2=NULL, **mat3=NULL, **mat4=NULL, **diffC=NULL;  //temporary matrices
+	static double* CIEI=NULL;				//CI*EI
+	static double* a=NULL;
+	static double *Ca=NULL, *vec1=NULL, *vec2=NULL, *vec3=NULL, *vec4=NULL, *vec5=NULL;	//temporary vectors
+	static double*** cub=NULL, ***cub2=NULL, ***cub3=NULL;
+	static double** Cf=NULL, *** dCfdde=NULL;
+
+	//for SC scheme
+	static double** sumVIAI=NULL; 					 
+	static double**invN=NULL;
+	static double**** dAIdEI=NULL;
+	static double ****sumVIdAIdC=NULL;
+
+	//for MT scheme
+	static double*** dBIdE=NULL;
+	static double*** dCIdE=NULL;
+	static double*** dCMdE=NULL;
+
+	//for algorithmic tangent operator	
+	static double**dFdE=NULL;				//derivative of residual w.r.t. macro strain increment
+	static double** dVdE=NULL;
+	static double** dSIdE=NULL, **dSMdE=NULL;
+	static double** dSIdV=NULL, **dSMdV=NULL;
+
+        static double* dpdEM=NULL;     // add by wu ling for damage
+        static double* dFdp=NULL;    // Ling wu 2011/10/18
+
+        static double** cg_temp=NULL;
+        static double** cgF_temp=NULL;
+        static double* dEIdp=NULL;
+        static double* dSIdp=NULL;
+        static double* dSMdp=NULL;
+        static double* Cp_bar=NULL;
+
+	//Memory allocation
+        static bool initialized=false;
+        if(!initialized)
+        {
+          initialized=true;
+ 	  mallocmatrix(&I,6,6);
+
+	  malloctens3(&dCMdde,6,6,6);
+	  malloctens3(&dCIdde,6,6,6);
+	  mallocvector(&a,6); 
+	  mallocvector(&Ca,6); 
+	  mallocvector(&vec1,6);
+	  mallocvector(&vec2,6);
+	  mallocvector(&vec3,6);
+	  mallocvector(&vec4,6);
+	  mallocvector(&vec5,6);
+	  mallocvector(&CIEI,6);
+
+	  mallocmatrix(&S,6,6);
+	  mallocmatrix(&CalgoM,6,6);
+	  mallocmatrix(&CI,6,6);
+	  mallocmatrix(&CM,6,6);
+	  mallocmatrix(&invC,6,6);
+	  mallocmatrix(&AI,6,6);
+	  mallocmatrix(&PI,6,6);
+	  mallocmatrix(&mat1,6,6);
+	  mallocmatrix(&mat2,6,6);
+	  mallocmatrix(&mat3,6,6);
+	  mallocmatrix(&mat4,6,6);
+	  mallocmatrix(&diffC,6,6);
+	  mallocmatrix(&CIAI,6,6);
+	  mallocmatrix(&AIPI,6,6);
+	  malloctens3(&cub,6,6,6);
+
+	  mallocvector(&dtauI,6);
+	  mallocvector(&dtauM,6);
+	  mallocmatrix(&ddtauIdde,6,6);
+	  mallocmatrix(&ddtauMdde,6,6);
+
+	  mallocmatrix(&dSIdE,6,6);
+	  mallocmatrix(&dSMdE,6,6);
+	  mallocmatrix(&Cf,6,6);
+	  malloctens3(&dCfdde,6,6,6);
+	  malloctens3(&cub2,6,6,6);
+          mallocvector(&dpdEM,6);   // add by wu ling for damage
+          mallocmatrix(&cg_temp,3,3);
+          mallocmatrix(&cgF_temp,3,3);
+
+
+          mallocvector(&dSIdp,6);
+          mallocvector(&dSMdp,6);
+          mallocvector(&Cp_bar,6);
+
+          mallocmatrix(&invN,6,6);
+	  mallocmatrix(&sumVIAI,6,6);
+	  malloctens4(&sumVIdAIdC,6,6,6,6);
+	  malloctens3(&dBIdE,6,6,6);
+	  malloctens3(&dCIdE,6,6,6);
+	  malloctens3(&dCMdE,6,6,6);
+	  malloctens3(&cub3,6,6,6);
+        }
+
+
+          cleartens4(I);
+
+	  cleartens6(dCMdde);
+	  cleartens6(dCIdde);
+	  cleartens2(a); 
+	  cleartens2(Ca); 
+	  cleartens2(vec1);
+	  cleartens2(vec2);
+	  cleartens2(vec3);
+	  cleartens2(vec4);
+	  cleartens2(vec5);
+	  cleartens2(CIEI);
+
+	  cleartens4(S);
+	  cleartens4(CalgoM);
+	  cleartens4(CI);
+	  cleartens4(CM);
+	  cleartens4(invC);
+	  cleartens4(AI);
+	  cleartens4(PI);
+	  cleartens4(mat1);
+	  cleartens4(mat2);
+	  cleartens4(mat3);
+	  cleartens4(mat4);
+	  cleartens4(diffC);
+	  cleartens4(CIAI);
+	  cleartens4(AIPI);
+	  cleartens6(cub);
+
+	  cleartens2(dtauI);
+	  cleartens2(dtauM);
+	  cleartens4(ddtauIdde);
+	  cleartens4(ddtauMdde);
+
+	  cleartens4(dSIdE);
+	  cleartens4(dSMdE);
+	  cleartens4(Cf);
+	  cleartens6(dCfdde);
+	  cleartens6(cub2);
+          cleartens2(dpdEM);   // add by wu ling for damage
+          for(i=0;i<3;i++)
+          {
+            for(j=0;j<3;j++)
+            {
+              cg_temp[i][j]=0.;
+              cgF_temp[i][j]=0.;
+            }
+          }
+
+
+          cleartens2(dSIdp);
+          cleartens2(dSMdp);
+          cleartens2(Cp_bar);
+
+          cleartens4(invN);
+	  cleartens4(sumVIAI);
+          for(i=0;i<6;i++)
+	     cleartens6(sumVIdAIdC[i]);
+	  cleartens6(dBIdE);
+	  cleartens6(dCIdE);
+	  cleartens6(dCMdE);
+	  cleartens6(cub3);
+
+        static int NiclInitialized=0;
+        if(NiclInitialized!=Nicl)
+        {
+          if(invS!=NULL) freetens3(invS,NiclInitialized,6);
+	  if(CalgoI!=NULL) freetens3(CalgoI,NiclInitialized,6);
+	  if(CinvS!=NULL) freetens3(CinvS,NiclInitialized,6);
+          if(dAIdEI!=NULL) freetens4(dAIdEI,NiclInitialized,6,6);
+
+	  malloctens3(&invS,Nicl,6,6);
+	  malloctens3(&CalgoI,Nicl,6,6);
+	  malloctens3(&CinvS,Nicl,6,6);
+	  malloctens4(&dAIdEI,Nicl,6,6,6);
+          NiclInitialized = Nicl;
+        }
+        for(i=0;i<Nicl;i++)
+        {
+            cleartens4(invS[i]);
+            cleartens4(CalgoI[i]);
+            cleartens4(CinvS[i]);
+            cleartens6(dAIdEI[i]);
+        }
+        static int neqInitialized=0;
+        if(neqInitialized!=neq)
+        {
+	  if(invJ!=NULL)  freematrix(invJ,neqInitialized);
+	  if(dSIdV!=NULL) freematrix(dSIdV,6);
+	  if(dSMdV!=NULL) freematrix(dSMdV,6);
+	  if(dFdE!=NULL)  freematrix(dFdE,neqInitialized);
+	  if(dVdE!=NULL)  freematrix(dVdE,neqInitialized);
+          if(dFdp!=NULL)  free(dFdp);    // add by wu ling for damage
+          if(dEIdp!=NULL) free(dEIdp);
+
+  	  mallocmatrix(&invJ,neq,neq); 
+	  mallocmatrix(&dFdE,neq,6);
+	  mallocmatrix(&dVdE,neq,6);
+	  mallocmatrix(&dSIdV,6,neq);
+	  mallocmatrix(&dSMdV,6,neq);
+	  mallocvector(&dFdp,neq);    // add by wu ling for damage
+          mallocvector(&dEIdp,neq);
+          neqInitialized=neq;
+        }
+        for(i=0;i<neq;i++)
+        {
+          for(j=0;j<neq;j++)
+          {
+            invJ[i][j]=0.;
+          }
+          cleartens2(dFdE[i]);
+          cleartens2(dVdE[i]);
+          dFdp[i]=0.;
+          dEIdp[i]=0.;
+        }
+        for(i=0;i<6;i++)
+        {
+          for(j=0;j<neq;j++)
+          {
+            dSIdV[i][j]=0.;
+            dSMdV[i][j]=0.;
+          }
+        }
+	for(i=0;i<6;i++){
+		I[i][i]=1.;
+	}
+
+	if(sch==SC){
+		V=1.;
+	}
+
+	else{ 
+		V=vfM;
+	}
+
+
+	//RESET TO ZERO...
+	for(i=0;i<neq;i++){
+		for(j=0;j<neq;j++){
+			J[i][j]=0.;
+		}
+		F[i]=0.;	
+	}
+
+
+	//printmatr(C,6,6);
+
+	// UPDATE MATRIX VARIABLES  (IF ANY)
+	if(mtx==1){
+		errortmp=mtx_mat->constbox(DeM, &(statev_n[idsdv_m + mtx_mat->get_pos_strs()]),  &(statev[idsdv_m + mtx_mat->get_pos_strs()]), &(statev_n[idsdv_m]), &(statev[idsdv_m]), CM, dCMdde, dtauM, ddtauMdde, CalgoM, alpha1, dpdEM, strs_dDdp_bar, Sp_bar, cg_temp, dFd_d_bar, dstrs_dFd_bar, dFd_dE, cgF_temp,&tmp1,&tmp2, kinc, kstep, dt);
+                if(errortmp!=0) 
+                  error=1;
+
+//***************// wu ling  2011/10/17****************
+                   
+                 if(mtx_mat->get_pos_dam()>=0) D_m = statev[idsdv_m + mtx_mat->get_pos_dam()+2];                
+		 else D_m = 0.;
+                 copyvect(&(statev[idsdv_m + mtx_mat->get_pos_strs()]),vec1, 6);
+                 sum_strs_dDdp=0.0;
+                 sum_strs=0.0; 
+                 for (i=0;i<6;i++){
+                   if( D_m <1.)
+	                vec1[i] +=vec1[i]/(1.-D_m); //put in effective stress
+                   sum_strs_dDdp -= strs_dDdp_bar[i];
+                   sum_strs +=vec1[i];
+                 }
+                 if(fabs(sum_strs)>1.e-16) dDdp_bar = sum_strs_dDdp/sum_strs;
+		 else if(fabs(vec1[0])>1.e-16) dDdp_bar  = -strs_dDdp_bar[0]/vec1[0];
+		 else if(fabs(vec1[1])>1.e-16) dDdp_bar  = -strs_dDdp_bar[1]/vec1[1];
+		 else if(fabs(vec1[2])>1.e-16) dDdp_bar  = -strs_dDdp_bar[2]/vec1[2];
+		 else if(fabs(vec1[3])>1.e-16) dDdp_bar  = -strs_dDdp_bar[3]/vec1[3];
+		 else if(fabs(vec1[4])>1.e-16) dDdp_bar  = -strs_dDdp_bar[4]/vec1[4];
+		 else if(fabs(vec1[5])>1.e-16) dDdp_bar  = -strs_dDdp_bar[5]/vec1[5];
+                 else dDdp_bar  = 0.;
+
+
+//end***************// wu ling  2011/10/17****************
+
+		if(sch == MT) {
+			copymatr(CM,C,6,6);					//if MT: set C equal to CM	 
+		}	
+		
+	}
+	// COMPUTE INVERSE OF MACRO/MATRIX TANGENT OPERATOR
+	inverse(C,invC,&errortmp,6);
+	if(errortmp!=0){
+		printf("Problem while inversing macro tangent operator in equationsNR, C=\n");
+		printmatr(C,6,6);
+                error=errortmp;
+		return error;
+	}
+
+	// LOOP OVER INCLUSION PHASES 
+	for(k=0;k<Nicl;k++){
+		VI=vfI[k];	           		//volume fraction of inclusion 
+		copymatr(S0[k],S,6,6);
+		inverse(S,invS[k],&errortmp,6);
+		if(errortmp!=0){
+			printf("Problem while inversing Eshelby's tensor in equationsNR, S=\n");
+			printmatr(S,6,6);
+                        error=errortmp;
+			return error;
+		}
+		contraction44(C,invS[k],CinvS[k]);							//C*S^{-1}
+		contraction44(S,invC,PI);				 //Hill's polarization tensor: P=SC^{-1}
+
+    		//UPDATE INCLUSION STATE
+                errortmp=(icl_mat[k])->constbox(DeI[k], &(statev_n[idsdv_i[k] + (icl_mat[k])->get_pos_strs()]),  &(statev[idsdv_i[k] + (icl_mat[k])->get_pos_strs()]), &(statev_n[idsdv_i[k]]), &(statev[idsdv_i[k]]), CI, dCIdde, dtauI, ddtauIdde, CalgoI[k], alpha1, vec1, vec2, Sp_bar, cg_temp, dFd_d_bar, dstrs_dFd_bar, dFd_dE, c_gF,&tmp1,&tmp2, kinc, kstep, dt);
+                if(errortmp!=0) 
+                  error=1;
+
+		//printf("inclusion %d\n",k+1);
+		//printf("C ref: \n"); printmatr(CI,6,6);
+		//printf("C algo: \n"); printmatr(CalgoI[k],6,6);
 	
-	return 0;
+		addtens2(1./V,DeI[k],-1./V,DE,vec1);
+		contraction42(invS[k],vec1,vec2);
+    		addtens2(1.,DeI[k],-1.,vec2,a);
+    		contraction42(C,a,Ca);
+    		contraction42(CI,DeI[k],CIEI);
+	
+		for(i=0;i<6;i++){
+			for(j=0;j<6;j++){
+				mat1[i][j]=0.;
+				for(l=0;l<6;l++){
+					mat1[i][j] += dCIdde[i][l][j]*DeI[k][l];
+				}
+			}
+		}
+
+		for(i=0;i<6;i++){
+			F[i+(k*6)] = Ca[i] -CIEI[i] - (dtauI[i]-dtauM[i]);      //FI
+			for(j=0;j<6;j++){
+				J[i+(k*6)][j+(k*6)] = C[i][j] - CinvS[k][i][j] - CI[i][j] - mat1[i][j] - ddtauIdde[i][j];  //dFI/dEI
+			}
+		}
+
+		//compute AI (SC) or BI (MT)
+		addtens4(1.,CI, -1., C, diffC);				//diffC=(CI-C)
+		contraction44(PI,diffC,mat1);					//mat1=P::(CI-C)
+		addtens4(1.,I,1.,mat1,mat2);					//A^-1 = I + P::(CI-C)
+		inverse(mat2,AI,&errortmp,6);						//A = (I + P::(CI-C))^{-1} 
+		if(errortmp!=0){
+			printf("Problem while inversing invBI in equationsNR, invBI=\n");
+			error=errortmp;
+                        return error;
+		}
+		contraction44(CI,AI,CIAI);
+		contraction44(AI,PI,AIPI);
+		for(i=0;i<6;i++){
+			for(j=0;j<6;j++){
+				dFdE[(6*k)+i][j] = (CinvS[k][i][j])/V;	
+			}
+                                dFdp[(6*k)+i] = -Ca[i]*dDdp_bar/(1.0-D_m);    //ling wu 2011/10/18  avec endomagement
+		}
+		//MT only:
+		if(sch==MT){
+			 
+			for(i=0;i<6;i++){
+				for(j=0;j<6;j++){
+					mat1[i][j]=0.;
+					for(l=0;l<6;l++){
+						mat1[i][j] += dCMdde[i][l][j]*a[l];
+					}
+				}
+			}
+			for(i=0;i<6;i++){
+				for(j=0;j<6;j++){
+					dFdE[(6*k)+i][j] += (mat1[i][j] + ddtauMdde[i][j])/V;		
+				}
+			}
+			for(i=0;i<6;i++){
+				for(j=0;j<6;j++){   
+					J[i][j] = J[i][j] - VI*dFdE[i][j];  
+				}
+			}
+			//Compute Mori-Tanaka macro tangent operator
+			addtens4(VI,CIAI,V,C,mat1);
+			addtens4(VI,AI,V,I,mat2);
+			inverse(mat2,mat3,&errortmp,6);
+			if(errortmp!=0){
+				printf("Problem in matrix inversion while computing Mori-Tanaka tangent operator\n");
+				error=errortmp;
+                                return error;
+			}
+			contraction44(mat1,mat3,C);
+		}//end if sch==MT
+
+		//SC only
+		if(sch==SC){
+		   
+			//compute N=sum VI*AI
+			addtens4(1.,sumVIAI,VI,AI,sumVIAI);
+
+			//change diffC if composite
+			if(mtx==1){
+				addtens4(1.,CI,-1.,CM,diffC);
+			}
+
+			//compute dAIdC
+			contraction44(invC,CIAI,mat1);					//mat1=C^{-1}:CI:AI
+			contraction44(diffC,AIPI,mat3);				//mat3=(CI-C):AIPI       
+			addtens4(1.,I,-1.,mat3,mat2);
+
+			for(i=0;i<6;i++){
+				for(j=0;j<6;j++){
+					for(l=0;l<6;l++){
+						cub[i][j][l]=0.;
+						for(m=0;m<6;m++){
+							cub[i][j][l] += dCIdde[i][m][l]*AI[m][j];
+						}
+					}
+				}
+			}
+			for(i=0;i<6;i++){
+				for(j=0;j<6;j++){
+					for(l=0;l<6;l++){
+						for(m=0;m<6;m++){
+							dAIdEI[k][i][j][l] += AIPI[i][m]*cub[m][j][l];
+						}
+					}
+				}
+			}
+
+			for(i=0;i<6;i++){
+				for(j=0;j<6;j++){
+					for(l=0;l<6;l++){
+						for(n=0;n<6;n++){
+							cub2[i][j][l]+=vfI[k]*dCMdde[i][n][l]*AI[n][j];
+						}
+					}
+				}
+			}
+
+			for(i=0;i<6;i++){
+				for(j=0;j<6;j++){
+
+				    J[(6*k) + i][(6*Nicl) + (i*6) +j] = a[j];			//dFIdC (1st part)
+					F[(6*Nicl)+(i*6)+j] += VI*CIAI[i][j];			//FC (1st part)
+					for(m=0;m<6;m++){
+						for(n=0;n<6;n++){
+
+							J[(6*Nicl)+(i*6)+j][(6*k)+m] += VI*diffC[i][n]*dAIdEI[k][n][j][m];
+							J[(6*Nicl)+(i*6)+j][(6*Nicl)+(m*6)+n] += VI*(mat3[i][m]*mat1[n][j]); //dFCdC (1st part)
+							  
+							if(mtx==0){
+								J[(6*Nicl)+(i*6)+j][(6*Nicl)+(m*6)+n] -= VI*(I[i][m]*AI[n][j]);	  //dFCdC (1st part)
+							}							     
+							sumVIdAIdC[i][j][m][n] += VI*AIPI[i][m]*mat1[n][j];
+						}
+					}
+				}
+			}
+		}//if SC 
+	}//end 1st loop over inclusions 
+
+	//COMPLETE CONSTRUCTION OF RESIDUAL VECTOR AND JACOBIAN MATRIX
+	if(sch==SC){
+
+		//CASE1: COMPOSITE
+		if(mtx==1){
+			contraction44(CM,sumVIAI,mat1);		//mat1=sum VI*CM:AI = CM:sum VI*AI
+			addtens4(1.,CM,-1.,C,mat2);				//mat2 = CM-C
+			addtens4(1.,mat2,-1.,mat1,mat3);		//mat3 = CM - sum VI*CM*AI - C
+	
+			addtens4(1.,sumVIAI,-1.,I,mat1);  //mat1 = N-I
+			 
+			for(i=0;i<6;i++){
+				for(j=0;j<6;j++){
+					for(m=0;m<6;m++){
+						cub[i][j][m]=0.;
+						for(n=0;n<6;n++){
+							cub[i][j][m] += dCMdde[i][n][m]*mat1[n][j];
+						}
+					}
+				}
+			}
+
+			for(i=0;i<6;i++){
+				for(j=0;j<6;j++){
+					for(k=0;k<6;k++){
+						dFdE[(Nicl*6)+(i*6)+j][k] = (dCMdde[i][j][k] - cub2[i][j][k])/vfM; 
+					}
+				}
+			}
+
+			for(i=0;i<6;i++){
+				for(j=0;j<6;j++){
+					F[(6*Nicl)+(i*6)+j] += mat3[i][j];	 	//FC end
+					for(m=0;m<Nicl;m++){
+						for(n=0;n<6;n++){
+							J[(6*Nicl)+(i*6)+j][(6*m) + n] += (vfI[m]/vfM)*cub[i][j][n];								//dFCdEI (end)
+						}
+					}
+					for(m=0;m<6;m++){
+						for(n=0;n<6;n++){
+							J[(6*Nicl)+(i*6)+j][(6*Nicl)+(m*6)+n] -= I[i][m]*I[j][n];								//dFCdC (end)
+						}
+					}
+				}
+			}
+		}//end if composite
+	
+		//CASE2: POLYCRYSTAL
+		else{					
+			//compute N^{-1}
+			inverse(sumVIAI,invN,&errortmp,6);
+			if(errortmp!=0){
+				printf("Problem while inversing sumVIAI in equationsNR, sumVIAI=\n");
+				printmatr(sumVIAI,6,6);
+				error=errortmp;
+                                return error;
+			}
+    
+			contraction42(invN,DE,vec1);					//vec1=N^{-1}:DE
+			addtens2(1.,vec1, -1.,DE,vec4);				//vec4=(N^{-1} -I):DE
+ 	
+			contraction44(C,sumVIAI,mat2);				//mat2 = C:N
+			for(i=0;i<6;i++){
+				for(j=0;j<6;j++){
+					F[(6*Nicl)+(i*6)+j] -= mat2[i][j];			//FC (end)
+				}
+			}
+
+			//second loop over inclusions
+			for(k=0;k<Nicl;k++){
+		
+				contraction44(CinvS[k],invN,mat1);		//mat1=C:S^{-1}:N^{-1}
+				for(i=0;i<6;i++){
+					for(j=0;j<6;j++){
+						dFdE[i+(k*6)][j] = mat1[i][j]; 
+					}	
+				}
+
+				for(m=0;m<Nicl;m++){
+					for(i=0;i<6;i++){
+						for(j=0;j<6;j++){
+							mat3[i][j]=0.;
+							for(l=0;l<6;l++){
+								mat3[i][j] += dAIdEI[m][i][l][j]*vec1[l];   //mat3 = AI:PI:dCdEI:AI:N^{-1}:DE
+							}
+						}
+					}
+					contraction44(mat1,mat3,mat4);					//mat4 = C:S^{-1}:N^{-1}:mat3
+	
+			 		for(i=0;i<6;i++){
+						for(j=0;j<6;j++){
+							J[(k*6)+i][(m*6)+j] += vfI[m]*mat4[i][j];					//dFIdEJ
+						}
+					}
+				}
+		
+				contraction42(CinvS[k],vec4,vec2);			//vec2=C:S^{-1}:(N^{-1}-I):DE
+				contraction42(invS[k],vec4,vec5);			//vec5=S^{-1}:(N^{-1}-I):DE
+			 
+				for(i=0;i<6;i++){
+					F[i+(k*6)] += vec2[i];							//FI
+					for(j=0;j<6;j++){
+						for(l=0;l<6;l++){
+							for(m=0;m<6;m++){
+								for(n=0;n<6;n++){
+									J[(k*6)+i][(6*Nicl)+(j*6)+l] += I[i][j]*I[m][l]*vec5[m] - mat1[i][m]*sumVIdAIdC[m][n][j][l]*vec1[n];				//dFIdC
+								}
+							}
+						}
+					}
+				}
+   	
+			}//end 2nd loop over inclusions
+		}//end if polycrystal
+
+	}//end if self-consistent
+	
+	//COMPUTE MACRO TANGENT OPERATORS, CONTINUUM AND ALGORITHMIC
+	if(last){
+
+
+		inverse(J,invJ,&errortmp,neq);
+		if(errortmp!=0){
+			printf("Problem in inversing Jacobian matrix in equationsNR\n");
+			error=errortmp;
+                        return error;
+		}
+		for(i=0;i<neq;i++){
+			for(j=0;j<6;j++){
+				dVdE[i][j]=0.;
+				for(m=0;m<neq;m++){
+					dVdE[i][j]+= invJ[i][m]*dFdE[m][j];		//warning: absolute value
+				}
+				dVdE[i][j]=-dVdE[i][j];
+			}
+		}
+                
+                for(i=0;i<neq;i++){
+			dEIdp[i]=0.0;
+			for(m=0;m<neq;m++){
+			        dEIdp[i] += invJ[i][m]*dFdp[m];		   // dEI/dp_bar=-J^-1 dF/dp
+			}
+				dEIdp[i]=-dEIdp[i];
+		} 
+
+
+
+		if(sch==MT){
+
+			//Compute derivatives of Mori-Tanaka tangent operator
+			contraction44(invC,CIAI,mat4);
+
+             		for(i=0;i<6;i++){
+				for(j=0;j<6;j++){
+					for(k=0;k<6;k++){
+						cub[i][j][k]=0.;
+						cub3[i][j][k]=0.;
+						for(l=0;l<6;l++){
+							cub[i][j][k] +=  dCIdde[i][l][k]*AI[l][j];
+							cub3[i][j][k] +=  dCMdde[i][l][k]*mat4[l][j];
+						}
+					}
+				}
+			}
+			for(i=0;i<6;i++){
+				for(j=0;j<6;j++){
+					for(k=0;k<6;k++){
+						cub[i][j][k] = cub[i][j][k] + (VI/V)*cub3[i][j][k];
+					}
+				}
+			}
+			for(i=0;i<6;i++){
+				for(j=0;j<6;j++){
+					for(k=0;k<6;k++){
+						cub2[i][j][k]=0.;
+						for(l=0;l<6;l++){
+							cub2[i][j][k] += AIPI[i][l]*cub[l][j][k];
+						}	
+					}
+				}
+			}
+			for(i=0;i<6;i++){
+				for(j=0;j<6;j++){
+					for(k=0;k<6;k++){
+						dBIdE[i][j][k]=0.;
+						for(l=0;l<6;l++){
+							dBIdE[i][j][k] += cub2[i][j][l]*dVdE[l][k];
+						}
+					}
+				}
+			}
+			for(i=0;i<6;i++){
+				for(j=0;j<6;j++){
+					for(k=0;k<6;k++){
+						cub2[i][j][k]=0.;
+						for(l=0;l<6;l++){
+							cub2[i][j][k] += AIPI[i][l]*cub3[l][j][k];
+						}
+					}
+				}
+			}
+
+			for(i=0;i<6;i++){
+				for(j=0;j<6;j++){
+					for(k=0;k<6;k++){
+						dBIdE[i][j][k] += cub2[i][j][k]/V;
+					}
+				}
+			}
+
+			//compute dCIdE and dCMdE
+			for(i=0;i<6;i++){
+				for(j=0;j<6;j++){
+					for(k=0;k<6;k++){
+						dCIdE[i][j][k]=0.;
+						dCMdE[i][j][k]=0.;
+						cub2[i][j][k]=0.;
+						for(l=0;l<6;l++){
+							dCIdE[i][j][k] -= dCIdde[i][j][l]*dVdE[l][k];
+							dCMdE[i][j][k] += dCMdde[i][j][l]*(I[l][k]- VI*dVdE[l][k]);
+							cub2[i][j][k] += CI[i][l]*dBIdE[l][j][k];
+						}
+					}
+				}
+			}
+
+			for(i=0;i<6;i++){
+				for(j=0;j<6;j++){
+					for(k=0;k<6;k++){
+						cub[i][j][k]=0.;
+						for(l=0;l<6;l++){
+							cub[i][j][k] += dCIdE[i][l][k]*AI[l][j];
+						}
+					}
+				}
+			}
+			for(i=0;i<6;i++){
+				for(j=0;j<6;j++){
+					for(k=0;k<6;k++){
+						cub3[i][j][k] = VI*(cub[i][j][k]+cub2[i][j][k]) + dCMdE[i][j][k];
+					}
+				}
+			}
+    
+			for(i=0;i<6;i++){
+				for(j=0;j<6;j++){
+					for(k=0;k<6;k++){
+						cub[i][j][k]=0.;
+						for(l=0;l<6;l++){
+							cub[i][j][k] += C[i][l]*dBIdE[l][j][k];
+						}
+					}
+				}
+			}
+			for(i=0;i<6;i++){
+				for(j=0;j<6;j++){
+					for(k=0;k<6;k++){
+						cub2[i][j][k] = cub3[i][j][k] - (VI*cub[i][j][k]);
+					}
+				}	
+			}
+
+			for(i=0;i<6;i++){
+				for(j=0;j<6;j++){
+					for(k=0;k<6;k++){
+						dC[i][j][k]=0.;
+						for(l=0;l<6;l++){
+							dC[i][j][k] += cub2[i][l][k]*mat3[l][j]; 
+						}
+					}
+				}
+			}
+
+		}//end case Mori-Tanaka
+
+		//COMPUTE ALGORITHMIC TANGENT OPERATOR
+		for(i=0;i<6;i++){
+			for(j=0;j<6;j++){
+				Calgo[i][j]=0.;
+			}
+                        //D_strs_eff[i]=0.;      // add by wu ling
+                        Cp_bar[i]=0.0;
+		}
+		for(k=0;k<Nicl;k++){
+			for(i=0;i<6;i++){
+				for(j=0;j<6;j++){
+					dSIdE[i][j]=0.;
+				}
+				for(j=0;j<neq;j++){
+					dSIdV[i][j]=0.;
+				}
+                                dSIdp[i]=0.0;     // add by wu ling
+			}
+			for(i=0;i<6;i++){
+				for(j=0;j<6;j++){
+					dSIdV[i][(k*6)+j]=CalgoI[k][i][j];
+				}
+			}
+			for(i=0;i<6;i++){
+				for(j=0;j<6;j++){
+					for(m=0;m<neq;m++){
+						dSIdE[i][j] += dSIdV[i][m]*dVdE[m][j];
+					}
+				}
+			}
+// by Ling Wu 2011/10/18*****************************
+                        for(i=0;i<6;i++){
+				for(m=0;m<neq;m++){
+					dSIdp[i] += dSIdV[i][m]*dEIdp[m];
+				}
+			}
+//****************************************************
+
+			for(i=0;i<6;i++){
+				for(j=0;j<6;j++){	
+					Calgo[i][j]+=vfI[k]*dSIdE[i][j];
+				}
+                               Cp_bar[i] += vfI[k]*dSIdp[i];            //  by ling wu
+			}
+// add by wu ling comput D* effective stress
+                       // for (i=0;i<6;i++){
+                                //D_strs_eff[i]+=vfI[k]*ID_strs_eff[k][i];
+                        //}
+// end add bu wu ling
+		}
+		if(mtx==1){
+ 
+			for(k=0;k<Nicl;k++){
+				for(i=0;i<6;i++){
+					for(j=0;j<6;j++){
+						dSMdV[i][(k*6)+j]=-(vfI[k]/vfM)*CalgoM[i][j];
+					}
+				}
+			}
+			for(i=0;i<6;i++){
+				for(j=0;j<6;j++){
+					dSMdE[i][j]=CalgoM[i][j]/vfM;
+				}
+			}
+			for(i=0;i<6;i++){
+				for(j=0;j<6;j++){
+					for(m=0;m<neq;m++){
+						dSMdE[i][j] += dSMdV[i][m]*dVdE[m][j]; 
+					}
+				}
+			}
+//****by ling wu **********************
+                        for(i=0;i<6;i++){
+                                dSMdp[i]=0.0;
+				for(m=0;m<neq;m++){
+					dSMdp[i] += dSMdV[i][m]*dEIdp[m]; 
+				}
+			}
+//**************************************
+			for(i=0;i<6;i++){
+				for(j=0;j<6;j++){
+					Calgo[i][j]+= vfM*dSMdE[i][j];
+				}
+                                Cp_bar[i] += vfM*dSMdp[i];
+			}
+  //add by wu ling 13.04.2011 compute dpdE and strs_dDdp_bar for composite   
+
+                        if (sch==MT){
+                                    for(i=0;i<6;i++){
+					     vec1[i]=-((1.-vfM)/vfM)*dpdEM[i];
+				    }
+                                    for(i=0;i<6;i++){
+					     dpdE[i]=dpdEM[i]/vfM;
+				    }
+
+                                    *Sp_bar=0.0;
+                                    for(i=0;i<6;i++){
+					for(j=0;j<6;j++){
+						dpdE[i] += vec1[j]*dVdE[j][i]; 
+					}
+                                         *Sp_bar += vec1[i]*dEIdp[i];
+				    }
+
+                                    addtens2(vfM, strs_dDdp_bar, 1.0, Cp_bar, strs_dDdp_bar);
+
+                        }
+                       // end add bu wu ling     
+		}
+	}
+	
+	return error;
 
 }
 /************************************************
@@ -80,6 +1420,28 @@ int equationsNR(double* DE, double* DeM, double** DeI, Material* mtx_mat, Materi
 void updateNR(double* DE, double** De1, double* DeM1, double* vf, double vfM, double** C, double* corrNR, int sch, int mtx, int Nicl)
 {
 
+	int i,j;
+	double* sumDe1=NULL;
+	mallocvector(&sumDe1,6);
+        
+	//correct strain increments
+	for(i=0;i<Nicl;i++){
+		addtens2(1.,De1[i],-1.,&(corrNR[i*6]),De1[i]);
+		addtens2(1.,sumDe1,vf[i],De1[i],sumDe1);
+	}
+	if(mtx==1){
+		addtens2(1./vfM,DE,-1/vfM,sumDe1,DeM1);			//compute matrix strain increment, if any
+	} 
+	//correct macro tangent operator
+	if(sch==SC){
+		for(i=0;i<6;i++){
+			for(j=0;j<6;j++){
+				C[i][j] = C[i][j] - corrNR[(6*Nicl) + (i*6) + j];
+			}
+		}
+	}
+ 
+	free(sumDe1);
 }
 
 
@@ -94,7 +1456,34 @@ void updateNR(double* DE, double** De1, double* DeM1, double* vf, double vfM, do
 double scalar_res(double* vec, int sch, int Nicl, double NORM){
 
 
-	return 0.;
+	int i,j,pos,neq;
+	double tmp;
+	double n=0.;
+	pos=0;
+	tmp=0.;
+
+	for(i=0;i<Nicl;i++){
+		for(j=0;j<6;j++){
+			tmp += vec[pos+j]*vec[pos+j];
+		}
+		tmp=sqrt(tmp/6)/NORM;
+		n += tmp;
+		tmp=0.;
+		pos+=6;
+	}
+	if(sch==SC){
+		neq = (6*Nicl) + 36;
+		for(i=0;i<6;i++){
+			for(j=0;j<6;j++){
+				tmp += vec[pos + (i*6) + j]*vec[pos + (i*6) + j];
+			}
+		}
+		tmp = sqrt(tmp/36)/NORM;
+		n += tmp;
+	}
+	else neq = 6;
+	n /= float(neq);
+	return n;
 
 }
 
@@ -106,6 +1495,85 @@ double scalar_res(double* vec, int sch, int Nicl, double NORM){
 //   OUTPUT: Esh:           Eshelby's tensor            	       
 void eshelby(double** dSdE, double ar1, double ar2, double**Esh)
 {
+	double C [6][6];
+	double S [6][6];
+	long int MP=50;
+	long int NP=50;
+	double A1;
+	double A2;
+	double A3;
+	short int I6[3][3];
+	int i,j;
+	int isotr;
+	const double sq2 = sqrt(2.);
+
+	isotr = isisotropic(dSdE);
+
+	//if dSdE is isotropic AND the inclusion is a spheroid, compute eshelby's tensor analytically
+	if(isotr && (fabs(ar1-ar2)/ar1<1.0e-6)){
+		//printf("Esh isotrope\n");
+		eshelby_iso(dSdE,ar1,Esh);
+		return;
+	}
+        else if(isotr){
+                eshelby_aniso(dSdE,ar1,ar2,Esh);
+   		return;
+        }
+	A1=1.;
+	A3=ar1;
+	A2=A3/ar2;
+	//printf("A1: %lf\t, A2: %lf\t, A3: %lf\n",A1,A2,A3);
+
+	for(i=0;i<6;i++){
+		for(j=0;j<6;j++){
+			Esh[i][j]=0.;									//reset Eshelby's tensor to zero
+			C[i][j]=dSdE[j][i];						//copy the tangent operator in a static table - fortran convention
+		}
+	}
+
+	for(i=0;i<3;i++){
+		for(j=3;j<6;j++){
+			C[i][j]=C[i][j]/(sqrt(2));
+			C[j][i]=C[j][i]/(sqrt(2));				//adapt storage convention
+			C[i+3][j] = C[i+3][j]/2;
+		}
+	}
+	//conversion table
+	I6[0][0]= 1;
+	I6[1][1]= 2;
+	I6[2][2]= 3;
+	I6[1][0]= 4;
+	I6[0][1]= 4;
+	I6[2][0]= 5;
+	I6[0][2]= 5;
+	I6[1][2]= 6;
+	I6[2][1]= 6;
+ 
+	//call fortran routines
+#ifdef NONLOCALGMSH
+        printf("Eshelby with anisotropic code not implemented:\n");
+//	points_((integer*)&MP,(integer*)&NP);
+//	eshani_((doublereal*)*C,(integer*)&MP,(integer*)&NP,(doublereal*)&A1,(doublereal*)&A2,(doublereal*)&A3,(doublereal*)*S,(shortint*)*I6);
+#else
+	points_(&MP,&NP);
+	eshani_(*C,&MP,&NP,&A1,&A2,&A3,*S,*I6);
+#endif
+	//store result in output table	
+   
+	for(i=0;i<6;i++){
+		for(j=0;j<6;j++){
+			Esh[i][j]=S[j][i];
+		}
+	}
+	
+	for(i=0;i<3;i++){
+		for(j=0;j<3;j++){
+			Esh[i][j+3] = Esh[i][j+3]*sq2;
+			Esh[i+3][j] = Esh[i+3][j]/sq2;
+		}
+	}
+
+	//printf("Eshelby with anisotropic code:\n"); printmatr(Esh,6,6);
    
 	return;
 }
@@ -124,6 +1592,93 @@ void eshelby(double** dSdE, double ar1, double ar2, double**Esh)
 void eshelby_iso(double **C0, double ar, double **Esh)
 
 {
+  double lambda, mu, nu;
+  int i,j;
+  double g;
+
+  lambda = C0[0][1];
+  mu = C0[3][3]/2.0;
+  nu = lambda/(2.0*(lambda+mu));
+ 
+  if(nu > 0.485){
+      nu=0.5;
+  }
+
+  /*reinitialisation of Eshelby's tensor*/
+   for(i=0;i<6;i++){
+      for(j=0;j<6;j++){
+            Esh[i][j]=0.;
+         }
+   }
+
+  /* Case ar = 1 */
+
+  if (ar==1) {
+    for (i=0;i<3;i++) {
+      for(j=0;j<3;j++) {
+        if (i!=j)
+	         Esh[i][j] = (5.*nu - 1.)/(15.*(1.-nu));
+        else
+	         Esh[i][i] = (7.-5.*nu)/(15.*(1.-nu));
+      }
+    }
+    for (i=3;i<6;i++) {
+      Esh[i][i] = 2.*(4.-5.*nu)/(15.*(1.-nu));  /*Doghri's convention: bottom right corner terms are premultiplied by 2*/
+    }
+  }
+  
+  /* General case - idem formules Christophe->ok */    
+  
+  if(ar!=1.0) {
+    if ((ar>0) && (ar<1))
+      g = (ar/(pow(ar,2.)-1.))*(ar-((acos(ar))/(sqrt(1.-pow(ar,2.)))));
+    else
+      g=(ar/(pow(ar,2.)-1.))*(ar-(log(ar+sqrt(pow(ar,2.)-1.))/(sqrt(pow(ar,2.)-1.))));
+    Esh[0][0] = (1./(4.*(1.-nu)))*(2.*(2.-nu)*g-0.5-(pow(ar,2.)-0.25)*(3.*g-2.)/(pow(ar,2.)-1.));
+    Esh[1][1] = Esh[0][0];
+    Esh[2][2] = (1./(2.*(1.-nu)))*(2.*(1.-nu)*(1.-g)+g-pow(ar,2.)*(3.*g-2.)/(pow(ar,2.)-1.));
+   
+	  Esh[0][1] = (1./(4.*(1.-nu)))*(-(1.-2.*nu)*g+0.5-0.25*(3.*g-2.)/(pow(ar,2.)-1.));
+    Esh[1][0] = Esh[0][1];
+
+    Esh[0][2] = (1./(4.*(1.-nu)))*(-(1.-2.*nu)*g+pow(ar,2.)*(3.*g-2.)/(pow(ar,2.)-1.));
+    Esh[1][2] = Esh[0][2];
+
+    Esh[2][0] = (1./(4.*(1.-nu)))*(4.*nu*(1.-g)-g+pow(ar,2.)*(3.*g-2.)/(pow(ar,2.)-1.));
+    Esh[2][1] = Esh[2][0];
+
+    Esh[3][3] = (1./(4.*(1.-nu)))*((1.-2.*nu)*g+0.5-0.25*(3.*g-2.)/(pow(ar,2.)-1.));
+    Esh[3][3] = 2.*Esh[3][3];
+
+    Esh[4][4] = (1./(4.*(1.-nu)))*((1.-nu)*(2.-g)-g+pow(ar,2.)*(3.*g-2.)/(pow(ar,2.)-1.));
+    Esh[4][4] = 2.*Esh[4][4];
+
+    Esh[5][5] = Esh[4][4];
+  }
+ 
+ /* version d'olivier pierard: fibre alignée selon e1 */ 
+ /* if(ar!=1) {
+    if ((ar>0) && (ar<1))
+      g = (ar/(pow(ar,2)-1))*(ar-((acos(ar))/(sqrt(1-pow(ar,2)))));
+    else
+      g=(ar/(pow(ar,2)-1))*(ar-(log(ar+sqrt(pow(ar,2)-1))/(sqrt(pow(ar,2)-1))));
+    Esh[1][1] = (1/(4*(1-nu)))*(2*(2-nu)*g-0.5-(pow(ar,2)-0.25)*(3*g-2)/(pow(ar,2)-1));
+    Esh[2][2] = Esh[1][1];
+    Esh[0][0] = (1/(2*(1-nu)))*(2*(1-nu)*(1-g)+g-pow(ar,2)*(3*g-2)/(pow(ar,2)-1));
+    Esh[1][2] = (1/(4*(1-nu)))*(-(1-2*nu)*g+0.5-0.25*(3*g-2)/(pow(ar,2)-1));
+    Esh[2][1] = Esh[1][2];
+    Esh[1][0] = (1/(4*(1-nu)))*(-(1-2*nu)*g+pow(ar,2)*(3*g-2)/(pow(ar,2)-1));
+    Esh[2][0] = Esh[1][0];
+    Esh[0][1] = (1/(4*(1-nu)))*(4*nu*(1-g)-g+pow(ar,2)*(3*g-2)/(pow(ar,2)-1));
+    Esh[0][2] = Esh[0][1];
+    Esh[4][4] = (1/(4*(1-nu)))*((1-2*nu)*g+0.5-0.25*(3*g-2)/(pow(ar,2)-1));
+    Esh[4][4] = 2*Esh[4][4];
+    Esh[5][5] = (1/(4*(1-nu)))*((1-nu)*(2-g)-g+pow(ar,2)*(3*g-2)/(pow(ar,2)-1));
+    Esh[5][5] = 2*Esh[5][5];
+    Esh[3][3] = Esh[5][5];
+  }
+
+	*/
 }
 
 
@@ -145,14 +1700,230 @@ void eshelby_iso(double **C0, double ar, double **Esh)
 void eshelby_iso(double **C0, double ar, double **S, double **dS, double ** ddS, double *dnu)
 
 {
+  double lambda, mu, nu, kappa;
+  int i,j;
+  double g;
+
+  double tmp;
+
+	
+  lambda = C0[0][1];
+  mu = C0[3][3]/2;
+  nu = lambda/(2.*(lambda+mu));
+  if (nu>0.485){
+  nu=0.5;
+  }
+
+
+  kappa = C0[0][1] + C0[3][3]/3.;
+
+  /*reinitialisation of Eshelby's tensor*/
+   for(i=0;i<6;i++){
+      for(j=0;j<6;j++){
+            S[i][j]=0.;
+         }
+   }
+
+  /* Case ar = 1 */
+
+  if (ar==1.0) {
+  	tmp = 15.*(1.-nu)*(1.-nu);
+  
+    for (i=0;i<3;i++) {
+      for(j=0;j<3;j++) {
+        if (i!=j){
+	         S[i][j] = (5.*nu - 1.)/(15.*(1.-nu));
+	         dS[i][j] = 4./tmp;
+        }
+        else{
+	         S[i][i] = (7.-5.*nu)/(15.*(1.-nu));
+	         dS[i][i] = 2./tmp;
+      	}
+      }
+    }
+    for (i=3;i<6;i++) {
+      S[i][i] = 2.*(4.-5.*nu)/(15.*(1.-nu)); 
+    	dS[i][i] = -2./tmp;
+    }
+    
+    //printf("dS: \n"); printmatr(dS,6,6);
+    
+    //second and third derivatives
+    tmp = 1./(1.-nu);
+    for(i=0;i<3;i++){
+    	for(j=0;j<3;j++){
+    		ddS[i][j] = dS[i][j]*2.*tmp;
+    	
+    	}
+    }
+    for(i=3;i<6;i++){
+			ddS[i][i] = dS[i][i]*2.*tmp;
+			
+    }
+  }
+  
+  /* General case - idem formules Christophe->ok */    
+  
+  if(ar!=1.0) {
+  	if(ar <= 0){
+  		printf("wrong aspect ratio: %lf \n", ar);
+  		return;
+  	}
+  	else{
+    	if (ar<1)	//oblate ellipsoids
+      g = (ar/(pow(ar,2.)-1.))*(ar-((acos(ar))/(sqrt(1.-pow(ar,2.)))));
+    	else		//prolate ellipsoids
+      g=(ar/(pow(ar,2.)-1.))*(ar-(log(ar+sqrt(pow(ar,2.)-1.))/(sqrt(pow(ar,2.)-1.))));
+		}
+      
+    S[0][0] = (1./(4.*(1.-nu)))*(2.*(2.-nu)*g-0.5-(pow(ar,2.)-0.25)*(3.*g-2.)/(pow(ar,2.)-1.));
+    S[1][1] = S[0][0];
+    S[2][2] = (1./(2.*(1.-nu)))*(2.*(1.-nu)*(1.-g)+g-pow(ar,2.)*(3.*g-2.)/(pow(ar,2.)-1.));
+   
+	  S[0][1] = (1./(4.*(1.-nu)))*(-(1.-2.*nu)*g+0.5-0.25*(3.*g-2.)/(pow(ar,2.)-1.));
+    S[1][0] = S[0][1];
+
+    S[0][2] = (1./(4.*(1.-nu)))*(-(1.-2.*nu)*g+pow(ar,2.)*(3.*g-2.)/(pow(ar,2.)-1.));
+    S[1][2] = S[0][2];
+
+    S[2][0] = (1./(4.*(1.-nu)))*(4.*nu*(1.-g)-g+pow(ar,2.)*(3.*g-2.)/(pow(ar,2.)-1.));
+    S[2][1] = S[2][0];
+
+    S[3][3] = (1./(4.*(1.-nu)))*((1.-2.*nu)*g+0.5-0.25*(3.*g-2.)/(pow(ar,2.)-1.));
+    S[3][3] = 2.*S[3][3];	//multiplied by 2: Doghri's convention
+
+    S[4][4] = (1./(4.*(1.-nu)))*((1.-nu)*(2.-g)-g+pow(ar,2.)*(3.*g-2.)/(pow(ar,2.)-1.));
+    S[4][4] = 2.*S[4][4];	//multiplied by 2: Doghri's convention
+
+    S[5][5] = S[4][4];
+  
+ 
+		//derivatives of Eshelby's tensor w.r.t nu
+		//first derivatives
+		tmp = (-1.+nu)*(-1.+nu)*(-1.+ar*ar);
+		dS[0][0] = (6.*ar*ar - g*(5.+4*ar*ar))/(16.*tmp);
+		dS[1][1] = dS[0][0];
+		dS[2][2] = (2.*ar*ar - g*(1.+2.*ar*ar))/(2.*tmp);
+ 
+		dS[2][0] = (-4. + 5.*g + 2.*ar*ar - 2.*g*ar*ar)/(4.*tmp);
+		dS[2][1] = dS[2][0];
+ 
+		dS[0][2] = (-2.*ar*ar + g*(-1.+4.*ar*ar))/(4.*tmp);
+		dS[1][2] = dS[0][2];
+ 
+		dS[0][1] = (2.*ar*ar + g*(-7.+4.*ar*ar))/(16.*tmp);
+		dS[1][0] = dS[0][1];
+ 
+		dS[4][4] = 2.*(g - 2.*ar*ar + 2.*g*ar*ar)/(4.*tmp); //multiplied by 2: Doghri's convention
+		dS[5][5] = dS[4][4];
+ 
+		dS[3][3] = (dS[0][0] - dS[0][1]);  //multiplied by 2: Doghri's convention
+ 
+		//second and third derivatives
+		tmp = -2./(-1.+nu);
+		for(i=0;i<3;i++){
+			for(j=0;j<3;j++){
+				ddS[i][j] = dS[i][j]*tmp;
+				
+			}
+		}
+		for(i=3;i<6;i++){
+			ddS[i][i] = dS[i][i]*tmp;
+			
+		}
+	}
+	
+	 
+	//derivatives of nu w.r.t. mu and kappa 
+	tmp = (3.*kappa + mu);
+	dnu[0] = -9.*kappa/(2.*tmp*tmp);
+        dnu[1] = - 2.*dnu[0]/tmp;
+        
+        dnu[2] = 9.*mu/(2.*tmp*tmp);
+        dnu[3] = -6.*dnu[2]/tmp;
+
+        dnu[4]= (27.*kappa-9.*mu)/(2.*tmp*tmp*tmp);
+	
+
+  if (nu==0.5){
+    for (i=0;i<6;i++) {
+      for(j=0;j<6;j++) {
+        dS[i][j] = 0.0;
+        ddS[i][j] = 0.0;
+        }
+    }
+    
+
+	 
+	//derivatives of nu w.r.t. mu and kappa 
+	
+	dnu[0] = 0.0;
+        dnu[1] = 0.0;
+        
+        dnu[2] = 0.0;
+        dnu[3] = 0.0;
+
+        dnu[4]= 0.0;	
+
+  }
+  
 }
 
 
 void Eshelby(double **C0, double* ar, double *euler, double **S, double **dS, double ** ddS, double *dnu){
 
+	static double **C0_loc=NULL;
+        static double **R66=NULL;
+	static double **mat1=NULL;
+        static double **mat2=NULL;
+        static double **mat3=NULL;
+
+	//memory allocation
+        static bool initialized = false;
+	if(!initialized)
+        {
+          initialized=true;
+          mallocmatrix(&C0_loc,6,6);
+          mallocmatrix(&R66,6,6);
+          mallocmatrix(&mat1,6,6);
+          mallocmatrix(&mat2,6,6);
+          mallocmatrix(&mat3,6,6);
+        }
+        cleartens4(C0_loc);
+        cleartens4(R66);
+        cleartens4(mat1);
+        cleartens4(mat2);
+        cleartens4(mat3);
 
+	//if fibers not oriented with e3:
+        if ( ar[0] == 1.0 && ar[1] == 1.0){
+            eshelby_iso(C0, ar[0], S, dS, ddS, dnu); 
+        } 
+        else if (fabs(euler[0]) > 1.e-3 || fabs(euler[1]) > 1.e-3){
+	    eul_mat(euler, R66);
+	    rot4(R66,C0,C0_loc);
+            if(fabs(ar[0]-ar[1])/ar[0] < 1.0e-6){
+		eshelby_iso(C0_loc, ar[0], mat1, mat2, mat3, dnu);  //compute Eshelby's tensor in local frame
+            }
+            else{
+                eshelby_aniso(C0_loc, ar[0], ar[1],mat1, mat2, mat3, dnu);  //compute Eshelby's tensor in local frame
+            }
+	    transpose(R66,R66,6,6);
+	    rot4(R66,mat1,S);
+	    rot4(R66,mat2,dS);
+	    rot4(R66,mat3,ddS);
+	}
+	else{
+	    if(fabs(ar[0]-ar[1])/ar[0] < 1.0e-6){
+		eshelby_iso(C0, ar[0], S, dS, ddS, dnu);  //compute Eshelby's tensor in local frame
+            }
+            else{
+                eshelby_aniso(C0, ar[0], ar[1], S, dS, ddS, dnu);  //compute Eshelby's tensor in local frame
+            } 
+	}
 }
 
+
 //*************Eshelby tensor for elliptic cilinder**************
 //****** x->ar1, y->ar2, z-> infinite ***************
 //**********  Sept.2017,   Ling Wu*******************
@@ -167,14 +1938,180 @@ void Eshelby(double **C0, double* ar, double *euler, double **S, double **dS, do
 //***************************************************************
 void eshelby_aniso(double **C0, double ar1, double ar2, double **S)
 {
+  double lambda, mu, nu, kappa;
+  int i,j;
+  double g, k;
+  double dg;
+
+  double tmp;
+	
+  lambda = C0[0][1];
+  mu = C0[3][3]/2;
+  nu = lambda/(2.*(lambda+mu));
+  if (nu>0.485){
+  nu=0.5;
+  }
 
+  kappa = C0[0][1] + C0[3][3]/3.0;
+
+  /*reinitialisation of Eshelby's tensor*/
+   for(i=0;i<6;i++){
+      for(j=0;j<6;j++){
+            S[i][j]=0.;
+         }
+   }
+
+  g = 1.0/(2.0*(1.0-nu));
+  tmp = 1.0/(1.0-nu);
+  dg = g*tmp;
+  k = pow((ar1+ar2),2.0);
+
+  // Eshelby tensor     
+  S[0][0] = g*ar1*ar2/k +ar2/(ar1+ar2);
+  S[1][1] = g*ar1*ar2/k +ar1/(ar1+ar2);
+  S[2][2] = 1.0e-6;
+   
+  S[0][1] = g*(2.0*ar2*ar2+ar1*ar2)/k -ar2/(ar1+ar2);
+  S[1][0] = g*(2.0*ar1*ar1+ar1*ar2)/k -ar1/(ar1+ar2);
+
+  S[0][2] = g*2.0*ar2/(ar1+ar2)-ar2/(ar1+ar2);
+  S[1][2] = g*2.0*ar1/(ar1+ar2)-ar1/(ar1+ar2);
+
+  S[2][0] = 0.0;
+  S[2][1] = 0.0;
+
+  S[3][3] = -g*ar1*ar2/k +0.5;
+  S[3][3] = 2.*S[3][3];	//multiplied by 2: Doghri's convention
+
+  S[4][4] = ar2/(2.0*(ar1+ar2));
+  S[4][4] = 2.*S[4][4];	//multiplied by 2: Doghri's convention
+
+  S[5][5] = ar1/(2.0*(ar1+ar2));
+  S[5][5] = 2.*S[5][5]; 
+  
 }
 
+
+
+
 void eshelby_aniso(double **C0, double ar1, double ar2, double **S, double **dS, double ** ddS, double *dnu)
 
 {
+  double lambda, mu, nu, kappa;
+  int i,j;
+  double g, k;
+  double dg;
+
+  double tmp;
+	
+  lambda = C0[0][1];
+  mu = C0[3][3]/2;
+  nu = lambda/(2.*(lambda+mu));
+  if (nu>0.485){
+  nu=0.5;
+  }
+
+  kappa = C0[0][1] + C0[3][3]/3.0;
+
+  /*reinitialisation of Eshelby's tensor*/
+   for(i=0;i<6;i++){
+      for(j=0;j<6;j++){
+            S[i][j]=0.;
+         }
+   }
+
+  g = 1.0/(2.0*(1.0-nu));
+  tmp = 1.0/(1.0-nu);
+  dg = g*tmp;
+  k = pow((ar1+ar2),2.0);
+
+  // Eshelby tensor     
+  S[0][0] = g*ar1*ar2/k +ar2/(ar1+ar2);
+  S[1][1] = g*ar1*ar2/k +ar1/(ar1+ar2);
+  S[2][2] = 1.0e-6;
+   
+  S[0][1] = g*(2.0*ar2*ar2+ar1*ar2)/k -ar2/(ar1+ar2);
+  S[1][0] = g*(2.0*ar1*ar1+ar1*ar2)/k -ar1/(ar1+ar2);
+
+  S[0][2] = g*2.0*ar2/(ar1+ar2)-ar2/(ar1+ar2);
+  S[1][2] = g*2.0*ar1/(ar1+ar2)-ar1/(ar1+ar2);
+
+  S[2][0] = 0.0;
+  S[2][1] = 0.0;
+
+  S[3][3] = -g*ar1*ar2/k +0.5;
+  S[3][3] = 2.*S[3][3];	//multiplied by 2: Doghri's convention
+
+  S[4][4] = ar2/(2.0*(ar1+ar2));
+  S[4][4] = 2.*S[4][4];	//multiplied by 2: Doghri's convention
+
+  S[5][5] = ar1/(2.0*(ar1+ar2));
+  S[5][5] = 2.*S[5][5]; 
+  
+  if(nu!= 0.5) {
+    //derivatives of Eshelby's tensor w.r.t nu
+    //first derivatives
+	dS[0][0] = dg*ar1*ar2/k;
+        dS[1][1] = dg*ar1*ar2/k;
+        dS[2][2] = 0.0;
+   
+        dS[0][1] = dg*(2.0*ar2*ar2+ar1*ar2)/k;
+        dS[1][0] = dg*(2.0*ar1*ar1+ar1*ar2)/k;
+
+        dS[0][2] = dg*2.0*ar2/(ar1+ar2);
+        dS[1][2] = dg*2.0*ar1/(ar1+ar2);
+
+        dS[2][0] = 0.0;
+        dS[2][1] = 0.0;
+
+        dS[3][3] = -dg*2.0*ar1*ar2/k; //multiplied by 2: Doghri's convention
+
+        dS[4][4] = 0.0;
+        dS[5][5] = 0.0; 
+
+     //second and third derivatives
+	tmp = 2./(1.-nu);
+        for(i=0;i<3;i++){
+	    for(j=0;j<3;j++){
+		ddS[i][j] = dS[i][j]*tmp;	
+	    }
+	}
+	for(i=3;i<6;i++){
+	    ddS[i][i] = dS[i][i]*tmp;
+	}
+    }
+	
+	 
+	//derivatives of nu w.r.t. mu and kappa 
+	tmp = (3.*kappa + mu);
+	dnu[0] = -9.*kappa/(2.*tmp*tmp);
+        dnu[1] = - 2.*dnu[0]/tmp;
+        
+        dnu[2] = 9.*mu/(2.*tmp*tmp);
+        dnu[3] = -6.*dnu[2]/tmp;
+
+        dnu[4]= (27.*kappa-9.*mu)/(2.*tmp*tmp*tmp);
+	
 
+    if (nu==0.5){
+       for (i=0;i<6;i++) {
+         for(j=0;j<6;j++) {
+           dS[i][j] = 0.0;
+           ddS[i][j] = 0.0;
+         }
+       }
+    //derivatives of nu w.r.t. mu and kappa 
+      dnu[0] = 0.0;
+      dnu[1] = 0.0;
+        
+      dnu[2] = 0.0;
+      dnu[3] = 0.0;
+      dnu[4]= 0.0;	
+    }
+  
 }
+
+
 /*******************************************************************************************************
 //Resolution of the localization problem on the equivalent inclusion system
 // INPUT:	DE: macro strain increment (given)
@@ -189,9 +2126,234 @@ void eshelby_aniso(double **C0, double ar1, double ar2, double **S, double **dS,
 **********************************************************************************************************/
 //***************new tensor added by wu ling: double* dpdE, double* strs_dDdp_bar
 int impl_SecLocal(int sch, double* DE, Material* mtx_mat, Material** icl_mat, ELcc *LCC, double vfM, double* vfI, double** ar, double** angles, double**  _R66,
-                  double* statev_n, double* statev, int nsdv, int idsdv_m, int* idsdv_i, int mtx, int Nicl, double** C, double*** dC, double** Calgo, double* dpdE, double* dstrsdp_bar,double *Sp_bar, double* dFd_d_bar, double* dstrs_dFd_bar, double *dFd_dE, double** c_gF, double* dpdFd, double* dFddp, int kinc, int kstep, double dt){
+	double* statev_n, double* statev, int nsdv, int idsdv_m, int* idsdv_i, int mtx, int Nicl, double** C, double*** dC, double** Calgo, double* dpdE, double* dstrsdp_bar,double *Sp_bar, double* dFd_d_bar, double* dstrs_dFd_bar, double *dFd_dE, double** c_gF, double* dpdFd, double* dFddp, int kinc, int kstep, double dt){
+
+	int i,it,pos,j;
+	int iso_all;
+	int last;
+	int error,errortmp;
+	int neq;
+	double res, res_r, res_rr; 
+	int corr;
+	double NORM;
+	double TOL_NR = 1e-6;
+
+	static double** C_n=NULL;		//macro (SC) or matrix (MT) tangent operator at tn from which Eshelby's tensor is computed
+
+	static double** mat1=NULL;		//tmporary matrix
+	static double* F=NULL; 		//residual vector;
+	static double** J=NULL;		//jacobian matrix
+	static double* DeM=NULL;		//matrix strain increment
+	static double** DeI=NULL;		//inclusion strain increments (unknowns of the NR system)
+	static double* DeM_r=NULL;		//phase strain increment of the previous iteration
+	static double** DeI_r=NULL;
+	static double* F_r=NULL;		//residual vector of at the previous iteration
+
+	static int* indx=NULL;	  //permutation vector for LU decomposition
+	double odd;		//also used for LU decomposition		
+
+	double alpha1=1.0; 		//for Secant method in each phase (default value)
+        error=0;
+	//memory allocation
+        static bool initialized = false;
+	if(!initialized)
+        {
+          initialized=true;
+          mallocmatrix(&C_n,6,6);
+  	  mallocmatrix(&mat1,6,6);
+	  mallocmatrix(&DeI,Nicl,6);
+	  mallocmatrix(&DeI_r,Nicl,6);
+          mallocvector(&DeM,6);
+          mallocvector(&DeM_r,6);
+        }
+        cleartens4(C_n);
+        cleartens4(mat1);
+        cleartens2(DeM);
+        cleartens2(DeM_r);
+        for(i=0;i<Nicl;i++)
+        {
+          cleartens2(DeI[i]);
+          cleartens2(DeI_r[i]);
+        }
+	if(sch==MT){
+		neq=6;
+		mtx_mat->get_elOD(&(statev_n[idsdv_m]), C_n);  //reference operator to compute NORM
+	}
+	else if(sch==MTSecNtr){
+		neq=6;
+		mtx_mat->get_elOD(&(statev_n[idsdv_m]), C_n);  //reference operator to compute NORM
+	}
+	else if(sch==MTSecF_LargeDeform){
+ 		neq=6;
+		mtx_mat->get_elOD(&(statev_n[idsdv_m]), C_n);  //reference operator to compute NORM
+	}
+	else if(sch==SC){
+		neq = 6*Nicl + 36;
+		copymatr(C,C_n,6,6);
+		
+	}
+	else{
+		printf("bad scheme in localization: %d\n",sch);
+	}
+
+      
+	NORM = C_n[3][3]/100; 
+
+        static int neqInitialized=0;
+        if(neq!=neqInitialized)
+        {
+          if(F!=NULL) free(F);		
+	  if(F_r!=NULL) free(F_r);
+	  if(J!=NULL) freematrix(J,neqInitialized);
+	  if(indx!=NULL) free(indx);
+	  mallocvector(&F,neq);		
+	  mallocvector(&F_r,neq);
+	  mallocmatrix(&J,neq,neq);
+	  indx = (int*)malloc(neq*sizeof(int));
+          neqInitialized=neq;
+        }
+        for(i=0;i<neq;i++)
+        {
+          F[i]=0.;
+          F_r[i]=0.;
+          for(j=0;j<3;j++)
+           J[i][j]=0.;
+        }
+ //***********  first guess for DeM, DeI and C  ***************************
+	 //first increment of a step: use macro strain increment and elastic macro operator
+	
+		if(mtx) copyvect(DE,DeM,6);
+		for(i=0;i<Nicl;i++){		
+			copyvect(DE,DeI[i],6);
+		}
+		
+		if(sch==SC){
+			if(mtx) mtx_mat->get_elOD(&(statev_n[idsdv_m]),C);	
+			else icl_mat[0]->get_elOD(&(statev_n[idsdv_i[0]]),C);
+		}
+		
+	last=0;
+	it=0;
+
+	copymatr(C_n,C,6,6);
+
+	//compute first residual 
+
+	errortmp=equationsNR_Sec(sch, DE, DeM, DeI, mtx_mat, icl_mat, LCC, vfM, vfI, statev_n, statev, idsdv_m, idsdv_i, mtx, Nicl, ar, angles, _R66, kinc, kstep, dt, last, neq, F, J, C, dC, Calgo, dpdE, dstrsdp_bar, Sp_bar, dFd_d_bar, dstrs_dFd_bar, dFd_dE, c_gF, dpdFd, dFddp, alpha1);
+        if(errortmp!=0) 
+          error=1;
+
+        res = scalar_res(F,sch,Nicl,NORM);
+#ifdef NONLOCALGMSH
+#else
+	printf("1st Misf: %.10e\n",res);
+#endif
+
+		
+	if(res<TOL_NR){
+		last=1;
+	}
+	res_r=res;
+
+	//NEWTON-RAPHSON LOOP
+	while(res>TOL_NR || last == 1){
+
+		it++;
+		corr=0;
+		ludcmp(J,neq,indx,&odd,&errortmp);									//compute LU decomposition of jacobian matrix
+		if(errortmp!=0){
+			printf("problem in LU decomposition of Jacobian matrix, iteration: %d\n",it);
+			error=errortmp;
+                        break;
+		}
+		//solve NR system -> F contains now the NR correction
+		lubksb(J,neq,indx,F);  
+		
+		//store the solution at the previous iteration
+		copymatr(DeI,DeI_r,Nicl,6);
+		if(mtx) copyvect(DeM,DeM_r,6);
+		copymatr(C,mat1,6,6);
+		copyvect(F,F_r,neq);
+		res_r=res;		
+
+		//update strain increments
+		updateNR(DE, DeI, DeM, vfI, vfM, C, F,sch,mtx,Nicl);
+			
+		//compute new residual
+	        errortmp=equationsNR_Sec(sch, DE, DeM, DeI, mtx_mat, icl_mat, LCC, vfM, vfI, statev_n, statev, idsdv_m, idsdv_i, mtx, Nicl, ar, angles, _R66, kinc, kstep, dt, last, neq, F, J, C, dC, Calgo, dpdE, dstrsdp_bar, Sp_bar, dFd_d_bar, dstrs_dFd_bar, dFd_dE, c_gF, dpdFd, dFddp, alpha1);
+                if(errortmp!=0) 
+                  error=1;
+
+		res = scalar_res(F,sch,Nicl,NORM);
+
+		if((res<TOL_NR) && (last==0)){
+			last=1;
+		}else{
+			last=0;
+		}
+		//check if residual decreases
+			
+		while((res>res_r) && (error==0) && (res>TOL_NR) && (it>1) ){	
+			res_rr = res;
+			corr++;
+			//printf("Residual increases: %.10e -> reduce NR correction \n", res);
+			//reduce proposed correction
+			for(i=0;i<neq;i++){
+				F[i] = 0.5*F_r[i];
+			}
+
+			copyvect(F,F_r,neq);
+			//get back to the result of previous iteration
+			copymatr(DeI_r,DeI,Nicl,6);
+			if(mtx) copyvect(DeM_r,DeM,6);
+			copymatr(mat1,C,6,6);
+
+			updateNR(DE, DeI, DeM, vfI, vfM, C, F,sch,mtx,Nicl);
+          
+			//compute residual with the reduced correction
+			errortmp=equationsNR_Sec(sch, DE, DeM, DeI, mtx_mat, icl_mat, LCC, vfM, vfI, statev_n, statev, idsdv_m, idsdv_i, mtx, Nicl, ar, angles, _R66, kinc, kstep, dt, last, neq, F, J, C, dC, Calgo, dpdE, dstrsdp_bar, Sp_bar, dFd_d_bar, dstrs_dFd_bar, dFd_dE, c_gF, dpdFd, dFddp, alpha1);
+                        if(errortmp!=0) 
+                          error=1;
+			res = scalar_res(F,sch,Nicl,NORM);
+					 
+			//if corrections are inefficient
+			if((corr > 5) && (fabs(res-res_rr) < 1e-6)){
+				//printf("corrections are inefficient\n");
+                                //error=1;
+				break;
+			}
+
+		}//end while residual > previous residual
+#ifdef NONLOCALGMSH	
+#else
+		printf("iteration %d, Misf: %.10e\n",it,res);
+#endif
+		if (it>500){
+			//printf("WARNING: too many iterations in Newton-Raphson loop\n");
+			
+			if(res<1e-4){	//not too bad - exit anyway
+				res=0;
+			}
+			else{
+				printf("No conv in NR loop, residual: %.10e\n",res);
+				error=1;
+                                res=0;
+			}
+			//compute algo tangent anyway...
+			last=1;
+			errortmp=equationsNR_Sec(sch, DE, DeM, DeI, mtx_mat, icl_mat, LCC, vfM, vfI, statev_n, statev, idsdv_m, idsdv_i, mtx, Nicl, ar, angles, _R66, kinc, kstep, dt, last, neq, F, J, C, dC, Calgo, dpdE, dstrsdp_bar, Sp_bar, dFd_d_bar, dstrs_dFd_bar, dFd_dE, c_gF, dpdFd,  dFddp, alpha1);
+                        if(errortmp!=0) 
+                          error=1;
+			last=0; //to exit the loop
+		}
+
+	}  //end NR loop
+
+	//if(res > TOL_NR){
+	//	printf("Warning: tolerance not achieved in NR loops. last residual: %.10e\n",res);
+	//}
 
-	return 0;
+	return error;
 
 }
 //********************************for secant MT scheme by Ling Wu June 2012********************************************************************
@@ -199,9 +2361,1690 @@ int impl_SecLocal(int sch, double* DE, Material* mtx_mat, Material** icl_mat, EL
 
 int equationsNR_Sec(int sch, double* DE, double* DeM, double** DeI, Material* mtx_mat, Material** icl_mat, ELcc *LCC, double vfM, double* vfI, 
 	double* statev_n, double* statev, int idsdv_m, int* idsdv_i, int mtx, int Nicl, double** ar, double** angles, double **_R66, int kinc, int kstep, double dt, int last, 
-                    int neq, double* F, double** J, double** C, double*** dC, double** Calgo,double* dpdE, double* dstrsdp_bar, double *Sp_bar, double* dFd_d_bar, double* dstrs_dFd_bar, double *dFd_dE, double** c_gF, double* dpdFd, double* dFddp, double alpha1){
+	int neq, double* F, double** J, double** C, double*** dC, double** Calgo, double* dpdE, double* dstrsdp_bar, double *Sp_bar, double* dFd_d_bar, double* dstrs_dFd_bar, double *dFd_dE, double** c_gF, double* dpdFd, double* dFddp, double alpha1){
+
+	int i,j,k,m,n,l,errortmp;
+	double V, VI;
+        double num1;
+
+	int error=0;
+
+	if(sch != MT && sch != MTSecNtr && sch != MTSecF_LargeDeform){
+		printf("This secheme is only implemented for MT, C=\n");
+		return 0;
+	}
+
+	static double** I=NULL;			                	//identity tensor
+
+	static double*** CalgoI=NULL, **CalgoM=NULL;		       		//algorithmic tangent operators of inclusions and matrix
+	static double** CI=NULL,**CM=NULL; 			              		//Secant operators of inclusions and matrix ...
+	static double*** dCMdde=NULL, ***dCIdde=NULL;					// ... and derivatives
+        static double** dCMdp_bar=NULL, ** dCIdFd_bar=NULL;
+        static double*  dnuM=NULL;                                                  // derivatives of possion ration
+
+        static double* dstrsMdp_bar=NULL;  
+
+        double   dnuMdp_bar;
+        double   dFddissip_dFd_bar;                                         //  derivatives of dissipation term to Fd_bar
+
+			
+	static double** invC=NULL;							//inverse of macro tangent operator
+	static double** invJ=NULL;							//inverse of jacobian matrix
+	static double**S=NULL, ***invS=NULL;						//eshelby's tensor and its inverse
+        static double   ***dS=NULL, ***dinvS=NULL;
+        static double  **dSdp_bar=NULL,**dinvSdp_bar=NULL;
+	
+
+	static double*** S_n=NULL, ***dS_n=NULL;		                        //array of Eshelby's tensor for each phase, and dS/dnu
+	static double** S_n_loc=NULL;	                                        //Eshelby's tensor in the local frame of the current inclusion
+	static double** R66=NULL;		                                        //rotation matrix
+        static double **dS_n_loc=NULL;                                             // ds/dnu
+        static double ** ddS=NULL;                                                 // ddS/ddnu 
+        static double *dnu=NULL; 	                                                // dnu[0]= dnudmu, dnu[1]=ddnuddmu, dnu[2]=dnudk , dnu[3]=ddnuddk, dnu[4]=ddnudmudk
+
+	static double**AI=NULL;							//strain concentration tensor
+	static double** PI=NULL;							//Hill's polarization tensor
+
+       
+	//some additional tensors...
+	static double** CIAI=NULL, **AIPI=NULL;
+	static double *** CinvS=NULL;						//C*S^{-1} 
+	static double **mat1=NULL, **mat2=NULL, **mat3=NULL, **mat4=NULL, **depdEM=NULL, **diffC=NULL;                //temporary matrices
+	static double* CIEI=NULL;							//CI*EI
+	static double* a=NULL;
+	static double *Ca=NULL, *vec1=NULL, *vec2=NULL, *vec3=NULL, *vec4=NULL;			//temporary vectors
+	static double*** cub=NULL, ***cub2=NULL, ***cub3=NULL;
+
+	static double* strnM=NULL, *ep=NULL,  *strn=NULL;
+        static double** strnI=NULL;
+
+
+	//for MT scheme
+	static double*** dBIdE=NULL;
+	static double*** dCIdE=NULL;
+	static double*** dCMdE=NULL;
+
+	//for algorithmic tangent operator	
+	static double**dFdE=NULL;							//derivative of residual w.r.t. macro strain increment
+	static double** dVdE=NULL;
+	static double** dSIdE=NULL, **dSMdE=NULL;
+	static double** dSIdV=NULL, **dSMdV=NULL;
+
+        static double* dpdEM=NULL;       // add by wu ling for damage
+        static double* dFdp=NULL;        // Ling wu 2011/10/18
+        static double* dFdFd_bar=NULL;        // Ling wu 2011/10/18
+	static double *dstrsIdFd_bar=NULL;
+
+        static double** cg_temp=NULL;
+
+        static double* dEIdp=NULL;
+        static double* dEIdFd=NULL;
+        static double* dSIdp=NULL;
+        static double* dSMdp=NULL;
+        static double* Cp_bar=NULL;
+        static double* CFd_bar=NULL;
+
+        static double* dFd_dEI=NULL;
+
+	//Memory allocation
+        static bool initialized=false;
+        if(!initialized)
+        {
+          initialized=true;
+  	  mallocmatrix(&I,6,6);
+
+	  malloctens3(&dCMdde,6,6,6);
+	  malloctens3(&dCIdde,6,6,6);
+	  mallocmatrix(&dCMdp_bar,6,6);
+	  mallocmatrix(&dCIdFd_bar,6,6);
+          mallocvector(&dnuM,6); 
+	  mallocvector(&dstrsIdFd_bar,6);
+	  mallocvector(&dFdFd_bar,6);
+        
+	  mallocvector(&a,6); 
+	  mallocvector(&Ca,6); 
+	  mallocvector(&vec1,6);
+	  mallocvector(&vec2,6);
+	  mallocvector(&vec3,6);
+	  mallocvector(&vec4,6);
+
+	  mallocvector(&CIEI,6);
+
+	  mallocmatrix(&S,6,6);
+	  mallocmatrix(&CalgoM,6,6);
+	  mallocmatrix(&CI,6,6);
+	  mallocmatrix(&CM,6,6);
+	  mallocmatrix(&invC,6,6);
+	  mallocmatrix(&AI,6,6);
+	  mallocmatrix(&PI,6,6);
+	  mallocmatrix(&mat1,6,6);
+	  mallocmatrix(&mat2,6,6);
+	  mallocmatrix(&mat3,6,6);
+	  mallocmatrix(&mat4,6,6);
+	  mallocmatrix(&depdEM,6,6);
+	  mallocmatrix(&diffC,6,6);
+	  mallocmatrix(&CIAI,6,6);
+	  mallocmatrix(&AIPI,6,6);
+	  malloctens3(&cub,6,6,6);
+	  mallocmatrix(&dSIdE,6,6);
+	  mallocmatrix(&dSMdE,6,6);
+	  malloctens3(&cub2,6,6,6);
+
+	  mallocvector(&strnM,6);
+	  mallocvector(&ep,6);
+	  mallocvector(&strn,6);
+
+          mallocvector(&dpdEM,6);                    // add by wu ling for damage
+          mallocvector(&dstrsMdp_bar,6);  
+
+          mallocmatrix(&cg_temp,3,3);
+          mallocvector(&dSIdp,6);
+          mallocvector(&dSMdp,6);
+          mallocvector(&Cp_bar,6);
+          mallocvector(&CFd_bar,6);
+
+          mallocmatrix(&S_n_loc,6,6);
+	  mallocmatrix(&R66,6,6);
+          mallocmatrix(&dS_n_loc,6,6);
+          mallocmatrix(&ddS,6,6);		         
+          mallocvector(&dnu,5);   
+
+          malloctens3(&dS,6,6,6);
+          malloctens3(&dinvS,6,6,6);
+          mallocmatrix(&dSdp_bar,6,6);
+          mallocmatrix(&dinvSdp_bar,6,6);      
+	  malloctens3(&dBIdE,6,6,6);
+	  malloctens3(&dCIdE,6,6,6);
+	  malloctens3(&dCMdE,6,6,6);
+	  malloctens3(&cub3,6,6,6);
+        }
+
+  	  cleartens4(I);
+
+	  cleartens6(dCMdde);
+	  cleartens6(dCIdde);
+	  cleartens4(dCMdp_bar);
+	  cleartens4(dCIdFd_bar);
+          cleartens2(dnuM); 
+	  cleartens2(dstrsIdFd_bar);
+	  cleartens2(dFdFd_bar);
+        
+	  cleartens2(a); 
+	  cleartens2(Ca); 
+	  cleartens2(vec1);
+	  cleartens2(vec2);
+	  cleartens2(vec3);
+	  cleartens2(vec4);
+
+	  cleartens2(CIEI);
+
+	  cleartens4(S);
+	  cleartens4(CalgoM);
+	  cleartens4(CI);
+	  cleartens4(CM);
+	  cleartens4(invC);
+	  cleartens4(AI);
+	  cleartens4(PI);
+	  cleartens4(mat1);
+	  cleartens4(mat2);
+	  cleartens4(mat3);
+	  cleartens4(mat4);
+	  cleartens4(depdEM);
+	  cleartens4(diffC);
+	  cleartens4(CIAI);
+	  cleartens4(AIPI);
+	  cleartens6(cub);
+	  cleartens4(dSIdE);
+	  cleartens4(dSMdE);
+	  cleartens6(cub2);
+
+	  cleartens2(strnM);
+	  cleartens2(ep);
+	  cleartens2(strn);
+
+          cleartens2(dpdEM);                    // add by wu ling for damage
+          cleartens2(dstrsMdp_bar);  
+
+          cleartens2(dSIdp);
+          cleartens2(dSMdp);
+          cleartens2(Cp_bar);
+          cleartens2(CFd_bar);
+
+          cleartens4(S_n_loc);
+	  cleartens4(R66);
+          cleartens4(dS_n_loc);
+          cleartens4(ddS);		         
+          
+          for(i=0;i<5;i++) dnu[i]=0.;   
+          for(i=0;i<3;i++)
+          {
+             for(j=0;j<3;j++) cg_temp[i][j];
+          }
+ 
+
+          cleartens6(dS);
+          cleartens6(dinvS);
+          cleartens4(dSdp_bar);
+          cleartens4(dinvSdp_bar);      
+	  cleartens6(dBIdE);
+	  cleartens6(dCIdE);
+	  cleartens6(dCMdE);
+	  cleartens6(cub3);
+
+
+        static int NiclInitialized=0;
+        if(Nicl!=NiclInitialized)
+        {
+	  if(invS!=NULL) freetens3(invS,NiclInitialized,6);
+	  if(CalgoI!=NULL) freetens3(CalgoI,NiclInitialized,6);
+	  if(CinvS!=NULL) freetens3(CinvS,NiclInitialized,6);
+	  if(S_n!=NULL) freetens3(S_n,NiclInitialized,6);
+	  if(dS_n!=NULL) freetens3(dS_n,NiclInitialized,6);
+
+	  if(strnI!=NULL) freematrix(strnI,NiclInitialized);
+
+	  malloctens3(&S_n,Nicl,6,6);
+	  malloctens3(&dS_n,Nicl,6,6);
+	  malloctens3(&invS,Nicl,6,6);
+  	  malloctens3(&CalgoI,Nicl,6,6);
+	  malloctens3(&CinvS,Nicl,6,6);
+
+	  mallocmatrix(&strnI,Nicl,6);
+
+          NiclInitialized=Nicl;
+        }
+        for(i=0;i<Nicl;i++)
+        {
+            cleartens4(S_n[i]);
+            cleartens4(dS_n[i]);
+            cleartens4(invS[i]);
+            cleartens4(CalgoI[i]);
+            cleartens4(CinvS[i]);
+            cleartens2(strnI[i]);
+        }
+
+        static int neqInitialized=0;
+        if(neq!=neqInitialized)
+        {
+	  if(invJ!=NULL) freematrix(invJ,neqInitialized);
+	  if(dFdE!=NULL) freematrix(dFdE,neqInitialized);
+	  if(dVdE!=NULL) freematrix(dVdE,neqInitialized);
+	  if(dSIdV!=NULL) freematrix(dSIdV,6);
+	  if(dSMdV!=NULL) freematrix(dSMdV,6);
+          if(dFdp!=NULL) free(dFdp);    // add by wu ling for damage
+          if(dEIdp!=NULL) free(dEIdp);
+          if(dEIdFd!=NULL) free(dEIdFd);
+          if(dFd_dEI!=NULL) free(dFd_dEI);
+
+  	  mallocmatrix(&invJ,neq,neq); 
+	  mallocmatrix(&dFdE,neq,6);
+	  mallocmatrix(&dVdE,neq,6);
+	  mallocmatrix(&dSIdV,6,neq);
+	  mallocmatrix(&dSMdV,6,neq);
+	  mallocvector(&dFdp,neq);                   // add by wu ling for damage
+          mallocvector(&dEIdp,neq);
+          mallocvector(&dEIdFd,neq);
+          mallocvector(&dFd_dEI,neq);
+
+
+          neqInitialized=neq;                           
+        }
+        for(i=0;i<neq;i++)
+        {
+          for(j=0;j<neq;j++)
+          {
+            invJ[i][j]=0.;
+          }
+          cleartens2(dFdE[i]);
+          cleartens2(dVdE[i]);
+          dFdp[i]=0.;
+          dEIdp[i]=0.;
+          dEIdFd[i]=0.;
+          dFd_dEI[i]=0.;
+        }
+        for(i=0;i<6;i++)
+        {
+          for(j=0;j<neq;j++)
+          {
+            dSIdV[i][j]=0.;
+            dSMdV[i][j]=0.;
+          }
+        }
+
+	for(i=0;i<6;i++){
+		I[i][i]=1.;
+	}
+		V=vfM;
+	
+	//RESET TO ZERO...
+	for(i=0;i<neq;i++){
+		for(j=0;j<neq;j++){
+			J[i][j]=0.;
+		}
+		F[i]=0.;	
+	}
+
+
+//************* Begining of computation**************************************
+//************       1. First moment secant method  *************************
+//***************************************************************************
+// UPDATE MATRIX VARIABLES  (IF ANY)
+      if(sch == MT){
+          if(mtx==1){
+#if Crmatrix_1st==1
+//           errortmp=mtx_mat->constboxSecant(DeM, &(statev_n[idsdv_m + mtx_mat->get_pos_strs()]),  &(statev[idsdv_m + mtx_mat->get_pos_strs()]), &(statev_n[idsdv_m]), &(statev[idsdv_m]), CalgoM, CM, dCMdde, dCMdp_bar, dnuM, dnuMdp_bar, alpha1, dpdEM, dstrsMdp_bar, cg_temp, kinc, kstep, dt);
+           errortmp=mtx_mat->constboxSecantMixte(DeM, &(statev_n[idsdv_m + mtx_mat->get_pos_strs()]),  &(statev[idsdv_m + mtx_mat->get_pos_strs()]), &(statev_n[idsdv_m]), &(statev[idsdv_m]), CalgoM, CM, dCMdde, dCMdp_bar, dnuM, dnuMdp_bar, alpha1, dpdEM, dstrsMdp_bar, cg_temp, kinc, kstep,dt,false,true);
+#elif Crmatrix_1st==0
+//           errortmp=mtx_mat->constboxSecantZero(DeM, &(statev_n[idsdv_m + mtx_mat->get_pos_strs()]),  &(statev[idsdv_m + mtx_mat->get_pos_strs()]), &(statev_n[idsdv_m]), &(statev[idsdv_m]), CalgoM, CM, dCMdde, dCMdp_bar, dnuM, dnuMdp_bar, alpha1, dpdEM, dstrsMdp_bar, cg_temp, kinc, kstep,dt);
+           errortmp=mtx_mat->constboxSecantMixte(DeM, &(statev_n[idsdv_m + mtx_mat->get_pos_strs()]),  &(statev[idsdv_m + mtx_mat->get_pos_strs()]), &(statev_n[idsdv_m]), &(statev[idsdv_m]), CalgoM, CM, dCMdde, dCMdp_bar, dnuM, dnuMdp_bar, alpha1, dpdEM, dstrsMdp_bar, cg_temp, kinc, kstep,dt,true,false);
+#else
+           errortmp=mtx_mat->constboxSecantMixte(DeM, &(statev_n[idsdv_m + mtx_mat->get_pos_strs()]),  &(statev[idsdv_m + mtx_mat->get_pos_strs()]), &(statev_n[idsdv_m]), &(statev[idsdv_m]), CalgoM, CM, dCMdde, dCMdp_bar, dnuM, dnuMdp_bar, alpha1, dpdEM, dstrsMdp_bar, cg_temp, kinc, kstep,dt,false,false);
+#endif
+           if(errortmp!=0) 
+             error=1;
+	//     
+           
+//compute Eshelby's tensor for each inclusion phase
+
+	   for(i=0;i<Nicl;i++){
+        	eul_mat(angles[i],R66);
+		rot4(R66,CM,mat1); 				                   //express (fictitious) matrix tangent operator in local axes   
+                if(fabs(ar[i][0]-ar[i][1])/ar[i][0] < 1.0e-6){
+                      eshelby_iso(mat1, ar[i][0], S_n_loc, dS_n_loc, ddS, dnu);         //(re-)compute Eshelby's tensor 
+                }
+                else{
+                      eshelby_aniso(mat1, ar[i][0], ar[i][1], S_n_loc, dS_n_loc, ddS, dnu);  //(re-)compute Eshelby's tensor         
+                }		
+		transpose(R66,R66,6,6);  			//transpose rotation matrix for inverse transformation
+		rot4(R66,S_n_loc,S_n[i]); 			//express eshelby's tensor in global axes
+                rot4(R66,dS_n_loc,dS_n[i]); 			//express derivative of eshelby's tensor in global axes
+	   }
+
+		copymatr(CM,C,6,6);					// set C equal to CM	 
+			
+        }
+// COMPUTE INVERSE OF MACRO/MATRIX TANGENT OPERATOR
+	inverse(C,invC,&errortmp,6);
+	if(errortmp!=0){
+		printf("Problem while inversing macro tangent operator in equationsNR, C=\n");
+		printmatr(C,6,6);
+		error=errortmp;
+                return error;
+	}
+
+	// LOOP OVER INCLUSION PHASES 
+	for(k=0;k<Nicl;k++){
+                VI=vfI[k];							//volume fraction of inclusion 
+		copymatr(S_n[k],S,6,6);
+		inverse(S,invS[k],&errortmp,6);
+		if(errortmp!=0){
+			printf("Problem while inversing Eshelby's tensor in equationsNR, S=\n");
+			printmatr(S,6,6);
+			error=errortmp;
+                        return error;
+		}
+
+        // derivatives of S to dEM and dp_bar **************** by Ling Wu June, 2012
+                for(i=0;i<6;i++){
+                            for(j=0;j<6;j++){
+                                     for(m=0; m<6; m++){
+                                               dS[i][j][m] = dS_n[k][i][j]*dnuM[m];
+                                     }
+                                     dSdp_bar[i][j] = dS_n[k][i][j]* dnuMdp_bar;
+                             }
+                }
+
+        // derivatives of invS to dEM and dp_bar **************** by Ling Wu June, 2012  
+
+	        contraction44(invS[k], dSdp_bar, mat1);
+	        contraction44(mat1, invS[k], dinvSdp_bar);                  
+
+
+                for(m=0; m<6; m++){ 
+                         for(n=0; n<6; n++){
+                                  for(l=0; l<6; l++){
+                                            dinvS[m][n][l]=0.0;
+                                            for(i=0;i<6;i++){
+                                                     for(j=0;j<6;j++){
+                                                             dinvS[m][n][l] -= invS[k][m][i]*dS[i][j][l]*invS[k][j][n];
+                                                     }
+                                            }
+                                   }
+                                   dinvSdp_bar[m][n] = -1.0*dinvSdp_bar[m][n];
+                          }
+                }
+
+      //******************************************************                                
+
+	        contraction44(C,invS[k],CinvS[k]);							//C*S^{-1}
+		contraction44(S,invC,PI);							  		    //Hill's polarization tensor: P=SC^{-1}
+
+           //UPDATE INCLUSION STATE
+             dFddissip_dFd_bar=0.;
+#if Crinclusion==1
+	    errortmp=(icl_mat[k])->constboxSecantMixte(DeI[k], &(statev_n[idsdv_i[k] + (icl_mat[k])->get_pos_strs()]),  &(statev[idsdv_i[k] + (icl_mat[k])->get_pos_strs()]), &(statev_n[idsdv_i[k]]), &(statev[idsdv_i[k]]), CalgoI[k], CI, dCIdde, dCIdFd_bar, vec1,  dFddissip_dFd_bar, alpha1, vec2, dstrsIdFd_bar, c_gF, kinc, kstep, dt,false,true);
+#elif Crinclusion==0
+            errortmp=(icl_mat[k])->constboxSecantZeroMixte(DeI[k], &(statev_n[idsdv_i[k] + (icl_mat[k])->get_pos_strs()]),  &(statev[idsdv_i[k] + (icl_mat[k])->get_pos_strs()]), &(statev_n[idsdv_i[k]]), &(statev[idsdv_i[k]]), CalgoI[k], CI, dCIdde, dCIdFd_bar, vec1,  dFddissip_dFd_bar, alpha1, vec2, dstrsIdFd_bar, c_gF, kinc, kstep, dt,true,false);   		
+#else
+            errortmp=(icl_mat[k])->constboxSecantMixte(DeI[k], &(statev_n[idsdv_i[k] + (icl_mat[k])->get_pos_strs()]),  &(statev[idsdv_i[k] + (icl_mat[k])->get_pos_strs()]), &(statev_n[idsdv_i[k]]), &(statev[idsdv_i[k]]), CalgoI[k], CI, dCIdde, dCIdFd_bar, vec1,  dFddissip_dFd_bar, alpha1, vec2, dstrsIdFd_bar, c_gF, kinc, kstep, dt,false,false);   		
+
+#endif
+                if(errortmp!=0) 
+                  error=1;
+                for(i=0;i<6;i++){ 
+                  //if(vec2[i]!=vec2[i]) printf("vec2 is nanHOM\n");
+                  dFd_dEI[i+k*6] = vec2[i];
+                }
+
+		addtens2(1./V,DeI[k],-1./V,DE,vec1);
+		contraction42(invS[k],vec1,vec2);
+    		addtens2(1.,DeI[k],-1.,vec2,a);
+    		contraction42(C,a,Ca);
+    		contraction42(CI,DeI[k],CIEI);
+
+	
+		for(i=0;i<6;i++){
+			for(j=0;j<6;j++){
+				mat1[i][j]=0.;
+				for(l=0;l<6;l++){
+					mat1[i][j] += dCIdde[i][l][j]*DeI[k][l];
+				}
+			}
+		}
+
+
+                for(i=0;i<6;i++){
+
+			F[i+(k*6)] = Ca[i] -CIEI[i] ;     				//FI
+
+			for(j=0;j<6;j++){
+				J[i+(k*6)][j+(k*6)] = C[i][j] - CinvS[k][i][j] - CI[i][j] - mat1[i][j];	//dFI/dEI
+			}
+		}
+
+
+		//compute AI (SC) or BI (MT)
+		addtens4(1.,CI, -1., C, diffC);				//diffC=(CI-C)
+		contraction44(PI,diffC,mat1);					//mat1=P::(CI-C)
+		addtens4(1.,I,1.,mat1,mat2);					//A^-1 = I + P::(CI-C)
+		inverse(mat2,AI,&errortmp,6);						//A = (I + P::(CI-C))^{-1} 
+		if(errortmp!=0){
+			printf("Problem while inversing invBI in equationsNR, invBI=\n");
+			error=errortmp;
+                        return error;
+		}
+		contraction44(CI,AI,CIAI);
+		contraction44(AI,PI,AIPI);
+
+//***********dF/dE, dF/dp_bar**********************************
+
+
+		contraction42(dinvSdp_bar,vec1,vec3);
+
+		for(i=0;i<6;i++){
+                        dFdp[(6*k)+i] = 0.0;
+                        dFdFd_bar[(6*k)+i] =0.0;
+			for(j=0;j<6;j++){
+				dFdE[(6*k)+i][j] = (CinvS[k][i][j])/V;				
+                                dFdp[(6*k)+i] += dCMdp_bar[i][j]*a[j]-C[i][j]*vec3[j]/V;       //ling wu 2012/06/28
+                                dFdFd_bar[(6*k)+i] -= dCIdFd_bar[i][j]*DeI[k][j];
+                        }
+                 }
+ 
+		
+			for(i=0;i<6;i++){
+				for(j=0;j<6;j++){
+					mat1[i][j]=0.;
+                                        mat2[i][j]=0.0;
+					for(l=0;l<6;l++){
+						mat1[i][j] += dCMdde[i][l][j]*a[l];
+                                                mat2[i][j] += dinvS[i][l][j]*vec1[l];
+					}
+				}
+			}
+
+		        contraction44(C,mat2,mat3);
+
+			for(i=0;i<6;i++){
+				for(j=0;j<6;j++){
+					dFdE[(6*k)+i][j] += mat1[i][j]/V - mat3[i][j]/(V);		
+				}
+			}
+			for(i=0;i<6;i++){
+				for(j=0;j<6;j++){   
+					J[i][j] = J[i][j] - VI*dFdE[i][j];  
+				}
+			}
+
+			//Compute Mori-Tanaka macro tangent operator
+			addtens4(VI,CIAI,V,C,mat1);
+			addtens4(VI,AI,V,I,mat2);
+			inverse(mat2,mat3,&errortmp,6);
+			if(errortmp!=0){
+				printf("Problem in matrix inversion while computing Mori-Tanaka tangent operator\n");
+				error=errortmp;
+                                return error;
+			}
+			contraction44(mat1,mat3,C);
+		
+	}//end 1st loop over inclusions 
+
+				
+	
+	//COMPUTE MACRO TANGENT OPERATORS, CONTINUUM AND ALGORITHMIC
+	if(last){
+
+		inverse(J,invJ,&errortmp,neq);
+		if(errortmp!=0){
+			printf("Problem in inversing Jacobian matrix in equationsNR\n");
+                        error=errortmp;
+			return error;
+		}
+		for(i=0;i<neq;i++){
+			for(j=0;j<6;j++){
+				dVdE[i][j]=0.;
+				for(m=0;m<neq;m++){
+					dVdE[i][j]+= invJ[i][m]*dFdE[m][j];		//warning: absolute value
+				}
+				dVdE[i][j]=-dVdE[i][j];
+			}
+		}
+                
+                for(i=0;i<neq;i++){
+			dEIdp[i]=0.0;
+			dEIdFd[i]=0.0;
+			for(m=0;m<neq;m++){
+			        dEIdp[i] += invJ[i][m]*dFdp[m];		   // dEI/dp_bar=-J^-1 dF/dp
+                                dEIdFd[i] += invJ[i][m]*dFdFd_bar[m];
+			}
+				dEIdp[i]=-dEIdp[i];
+                                dEIdFd[i] = -dEIdFd[i];
+		} 
+
+
+         // It is not used in two - phases M-T formular, we comment the following code for effciency. 
+		/*	//Compute derivatives of Mori-Tanaka tangent operator
+
+			contraction44(invC,CIAI,mat4);
+
+             		for(i=0;i<6;i++){
+				for(j=0;j<6;j++){
+					for(k=0;k<6;k++){
+						cub[i][j][k]=0.;
+						cub3[i][j][k]=0.;
+						for(l=0;l<6;l++){
+							cub[i][j][k] +=  dCIdde[i][l][k]*AI[l][j];
+							cub3[i][j][k] +=  dCMdde[i][l][k]*mat4[l][j];
+						}
+					}
+				}
+			}
+			for(i=0;i<6;i++){
+				for(j=0;j<6;j++){
+					for(k=0;k<6;k++){
+						cub[i][j][k] = cub[i][j][k] + (VI/V)*cub3[i][j][k];
+					}
+				}
+			}
+			for(i=0;i<6;i++){
+				for(j=0;j<6;j++){
+					for(k=0;k<6;k++){
+						cub2[i][j][k]=0.;
+						for(l=0;l<6;l++){
+							cub2[i][j][k] += AIPI[i][l]*cub[l][j][k];
+						}	
+					}
+				}
+			}
+			for(i=0;i<6;i++){
+				for(j=0;j<6;j++){
+					for(k=0;k<6;k++){
+						dBIdE[i][j][k]=0.;
+						for(l=0;l<6;l++){
+							dBIdE[i][j][k] += cub2[i][j][l]*dVdE[l][k];
+						}
+					}
+				}
+			}
+			for(i=0;i<6;i++){
+				for(j=0;j<6;j++){
+					for(k=0;k<6;k++){
+						cub2[i][j][k]=0.;
+						for(l=0;l<6;l++){
+							cub2[i][j][k] += AIPI[i][l]*cub3[l][j][k];
+						}
+					}
+				}
+			}
+
+			for(i=0;i<6;i++){
+				for(j=0;j<6;j++){
+					for(k=0;k<6;k++){
+						dBIdE[i][j][k] += cub2[i][j][k]/V;
+					}
+				}
+			}
+
+			//compute dCIdE and dCMdE
+			for(i=0;i<6;i++){
+				for(j=0;j<6;j++){
+					for(k=0;k<6;k++){
+						dCIdE[i][j][k]=0.;
+						dCMdE[i][j][k]=0.;
+						cub2[i][j][k]=0.;
+						for(l=0;l<6;l++){
+							dCIdE[i][j][k] -= dCIdde[i][j][l]*dVdE[l][k];
+							dCMdE[i][j][k] += dCMdde[i][j][l]*(I[l][k]- VI*dVdE[l][k]);
+							cub2[i][j][k] += CI[i][l]*dBIdE[l][j][k];
+						}
+					}
+				}
+			}
+
+			for(i=0;i<6;i++){
+				for(j=0;j<6;j++){
+					for(k=0;k<6;k++){
+						cub[i][j][k]=0.;
+						for(l=0;l<6;l++){
+							cub[i][j][k] += dCIdE[i][l][k]*AI[l][j];
+						}
+					}
+				}
+			}
+			for(i=0;i<6;i++){
+				for(j=0;j<6;j++){
+					for(k=0;k<6;k++){
+						cub3[i][j][k] = VI*(cub[i][j][k]+cub2[i][j][k]) + dCMdE[i][j][k];
+					}
+				}
+			}
+    
+			for(i=0;i<6;i++){
+				for(j=0;j<6;j++){
+					for(k=0;k<6;k++){
+						cub[i][j][k]=0.;
+						for(l=0;l<6;l++){
+							cub[i][j][k] += C[i][l]*dBIdE[l][j][k];
+						}
+					}
+				}
+			}
+			for(i=0;i<6;i++){
+				for(j=0;j<6;j++){
+					for(k=0;k<6;k++){
+						cub2[i][j][k] = cub3[i][j][k] - (VI*cub[i][j][k]);
+					}
+				}	
+			}
+
+			for(i=0;i<6;i++){
+				for(j=0;j<6;j++){
+					for(k=0;k<6;k++){
+						dC[i][j][k]=0.;
+						for(l=0;l<6;l++){
+							dC[i][j][k] += cub2[i][l][k]*mat3[l][j]; 
+						}
+					}
+				}
+			}                     */
+
+
+// **********  compute stress of composite***************************
+
+               for(i=0;i<6;i++){
+               statev[i+6]= VI*(statev[idsdv_i[0] + (icl_mat[0])->get_pos_strs()+i]) + V*(statev[idsdv_m + mtx_mat->get_pos_strs()+i]);
+               }
+//************************************************ at the end : out put for FE ***********************
+   //1. COMPUTE ALGORITHMIC TANGENT OPERATOR dstrsI/dE---- dstrsI/dp------dstrsI/dFd-------------------
+		cleartens4(Calgo);
+		cleartens2(Cp_bar);
+                cleartens2(CFd_bar);
+
+		for(k=0;k<Nicl;k++){
+			for(i=0;i<6;i++){
+				for(j=0;j<6;j++){
+					dSIdE[i][j]=0.;
+				}
+				for(j=0;j<neq;j++){
+					dSIdV[i][j]=0.;
+				}
+			}
+			for(i=0;i<6;i++){
+				for(j=0;j<6;j++){
+					dSIdV[i][(k*6)+j]=CalgoI[k][i][j];
+				}
+			}
+			for(i=0;i<6;i++){
+				for(j=0;j<6;j++){
+					for(m=0;m<neq;m++){
+						dSIdE[i][j] += dSIdV[i][m]*dVdE[m][j];
+					}
+				}
+			}
+
+			for(i=0;i<6;i++){
+				for(j=0;j<6;j++){	
+					Calgo[i][j]+=vfI[k]*dSIdE[i][j];    //  dstrsI/dE
+				}
+			}
+
+
+                        for(i=0;i<6;i++){
+				for(m=0;m<neq;m++){
+					Cp_bar[i] += vfI[k]* dSIdV[i][m]*dEIdp[m];          //  dstrsI/dp
+					CFd_bar[i] += vfI[k]* dSIdV[i][m]*dEIdFd[m] ;       //  dstrsI/dFd
+				}     
+			}
+                        //for(i=0;i<6;i++){
+                       //         CFd_bar[i] -= vfI[k]*dFdFd_bar[6*k+i];                  
+                      //  }
+		}
+
+ //***********************************************************************************************************
+		if(mtx==1){
+                      
+			for(k=0;k<Nicl;k++){
+				for(i=0;i<6;i++){
+					for(j=0;j<6;j++){
+						dSMdV[i][(k*6)+j]=-(vfI[k]/vfM)*CalgoM[i][j];
+					}
+				}
+			}
+			for(i=0;i<6;i++){
+				for(j=0;j<6;j++){
+					dSMdE[i][j]=CalgoM[i][j]/vfM;
+				}
+			}
+			for(i=0;i<6;i++){
+				for(j=0;j<6;j++){
+					for(m=0;m<neq;m++){
+						dSMdE[i][j] += dSMdV[i][m]*dVdE[m][j];      //  dstrsM/dE-					
+                                        }
+				}
+			}
+
+			for(i=0;i<6;i++){
+				for(j=0;j<6;j++){  
+					Calgo[i][j]+= vfM*dSMdE[i][j];                      // ###########   Final 1. Calgo    ###############
+				}
+			}
+
+
+                        for(i=0;i<6;i++){
+                                dSMdp[i]=0.0;
+				for(m=0;m<neq;m++){
+					dSMdp[i] += dSMdV[i][m]*dEIdp[m]; 
+				}
+			}
+			for(i=0;i<6;i++){
+				
+                                Cp_bar[i] += vfM*dSMdp[i];
+			}
+                        addtens2(vfM, dstrsMdp_bar, 1.0, Cp_bar, dstrsdp_bar);           // ###########   Final 2. dstrsdp_bar    ###############
+
+
+                        for(i=0;i<6;i++){
+                                dSMdp[i]=0.0;
+				for(m=0;m<neq;m++){
+					dSMdp[i] += dSMdV[i][m]*dEIdFd[m]; 
+				}
+			}
+			for(i=0;i<6;i++){
+				
+                                dstrs_dFd_bar[i]= CFd_bar[i] + vfM*dSMdp[i] + VI*dstrsIdFd_bar[i];        // ###########   Final 3. dstrsdFd_bar ###############
+                                                                  
+                        }
+
+                               
+
+                    //################################ works for one phase inclusion reinforced matrix only #################################### 
+                                     
+
+                        for(i=0;i<6;i++){
+			     vec1[i]=-((1.-vfM)/vfM)*dpdEM[i];
+			}
+                        for(i=0;i<6;i++){
+			     dpdE[i]=dpdEM[i]/vfM;
+			}
+
+                        *Sp_bar =0.0;
+                        *dpdFd =0.0;
+                        for(i=0;i<6;i++){
+			    for(j=0;j<6;j++){
+				dpdE[i] += vec1[j]*dVdE[j][i];                             //   ###############   Final 4. dpdE    ################
+			    }
+                        *Sp_bar += vec1[i]*dEIdp[i];                                       //   ###############   Final 5. dpdp_bar   #######################
+                        *dpdFd += vec1[i]*dEIdFd[i];                                       //   ###############   Final 6. dpdFd   #######################
+			}
+
+                     //####################################   works for one phase inclusion reinforced matrix only   #############################################           
+                        
+                        for(i=0;i<6;i++){
+                            dFd_dE[i]=0.;
+			    for(j=0;j<6;j++){
+                             //if(dFd_dEI[i]!=dFd_dEI[i]) printf("dFd_dEI PREM is nanHOM\n");
+                             //if(dVdE[i]!=dVdE[i]) printf("dVdE PREM is nanHOM\n");
+
+			     dFd_dE[i]+= dFd_dEI[j]*dVdE[j][i];                              //   ###############   Final 7. dFd_dE    ################
+                            }
+			}
+
+                        *dFddp = 0.0;
+                        *dFd_d_bar = 0.0; 
+                        for(i=0;i<6;i++){
+                          //if(dFd_dEI[i]!=dFd_dEI[i]) printf("dFd_dEI is nanHOM\n");
+                          //if(dEIdp[i]!=dEIdp[i]) printf("dEIdp is nanHOM\n");
+
+                          *dFddp += dFd_dEI[i]*dEIdp[i];                    //   ###############   Final 8. dFd/dp_bar   #######################
+			}
+
+                        for(i=0;i<6;i++) *dFd_d_bar += dFd_dEI[i]*dEIdFd[i];    
+                        *dFd_d_bar += dFddissip_dFd_bar;                             //   ###############   Final 9. dFd_dFd   #######################
+			                        
+		}
+	 }
+      }
+//*****************************************************************************
+// 2. second moment secant method in Ntr***************************************
+//*****************************************************************************
+// UPDATE MATRIX VARIABLES  (IF ANY)
+       if(sch == MTSecNtr){
+
+            EPR  Mresult;     // structure for calling matix constitutive box
+            malloc_Epresult(&Mresult);
+
+            if(mtx==1){
+                     errortmp=mtx_mat->constbox_2ndNtr(DE, DeM, &(statev_n[idsdv_m + mtx_mat->get_pos_strs()]),  &(statev[idsdv_m + mtx_mat->get_pos_strs()]), &(statev_n[idsdv_m]), &(statev[idsdv_m]), LCC, &Mresult, alpha1, cg_temp, kinc, kstep, dt);
+                    if(errortmp!=0) 
+                      error=1;
+   
+                copymatr(Mresult.Csd, C,6,6);            // set C equal to Mresult.Csd of matrix	
+         //compute Eshelby's tensor for each inclusion phase
+
+	    for(i=0;i<Nicl;i++){
+        	eul_mat(angles[i],R66);
+		rot4(R66,C,mat1); 				                   //express (fictitious) matrix tangent operator in local axes
+                if(fabs(ar[i][0]-ar[i][1])/ar[i][0] < 1.0e-6){
+                      eshelby_iso(mat1, ar[i][0], S_n_loc, dS_n_loc, ddS, dnu);         //(re-)compute Eshelby's tensor 
+                }
+                else{
+                      eshelby_aniso(mat1, ar[i][0], ar[i][1], S_n_loc, dS_n_loc, ddS, dnu);  //(re-)compute Eshelby's tensor         
+                }
+		transpose(R66,R66,6,6);  			//transpose rotation matrix for inverse transformation
+		rot4(R66,S_n_loc,S_n[i]); 			//express eshelby's tensor in global axes
+                rot4(R66,dS_n_loc,dS_n[i]); 			//express derivative of eshelby's tensor in global axes
+	    }
+       }
+// COMPUTE INVERSE OF MACRO/MATRIX scant OPERATOR
+	inverse(C,invC,&errortmp,6);
+	if(errortmp!=0){
+		printf("Problem while inversing macro tangent operator in equationsNR, C=\n");
+		printmatr(C,6,6);
+		error=errortmp;
+                return error;
+	}
+
+	// LOOP OVER INCLUSION PHASES 
+	for(k=0;k<Nicl;k++){
+                VI=vfI[k];							//volume fraction of inclusion 
+		copymatr(S_n[k],S,6,6);
+		inverse(S,invS[k],&errortmp,6);
+		if(errortmp!=0){
+			printf("Problem while inversing Eshelby's tensor in equationsNR, S=\n");
+			printmatr(S,6,6);
+			error=errortmp;
+                        return error;
+		}
+
+        // derivatives of S to dEM and dp_bar **************** by Ling Wu June, 2012
+                for(i=0;i<6;i++){
+                            for(j=0;j<6;j++){
+                                     for(m=0; m<6; m++){
+                                               dS[i][j][m] = dS_n[k][i][j]* Mresult.dnu[m];
+                                     }
+                                     dSdp_bar[i][j] = dS_n[k][i][j]* Mresult.dnudp_bar[0];
+                             }
+                }
+
+        // derivatives of invS to dEM and dp_bar **************** by Ling Wu June, 2012  
+
+	        contraction44(invS[k], dSdp_bar, mat1);
+	        contraction44(mat1, invS[k], dinvSdp_bar);                  
+
+
+                for(m=0; m<6; m++){ 
+                         for(n=0; n<6; n++){
+                                  for(l=0; l<6; l++){
+                                            dinvS[m][n][l]=0.0;
+                                            for(i=0;i<6;i++){
+                                                     for(j=0;j<6;j++){
+                                                             dinvS[m][n][l] -= invS[k][m][i]*dS[i][j][l]*invS[k][j][n];
+                                                     }
+                                            }
+                                   }
+                                   dinvSdp_bar[m][n] = -1.0*dinvSdp_bar[m][n];
+                          }
+                }
+
+      //******************************************************                                
+
+	        contraction44(C,invS[k],CinvS[k]);							//C*S^{-1}
+		contraction44(S,invC,PI);							  		    //Hill's polarization tensor: P=SC^{-1}
+
+    	//UPDATE INCLUSION STATE
+#if Crinclusion==1
+        errortmp=(icl_mat[k])->constboxSecantMixte(DeI[k], &(statev_n[idsdv_i[k] + (icl_mat[k])->get_pos_strs()]),  &(statev[idsdv_i[k] + (icl_mat[k])->get_pos_strs()]), &(statev_n[idsdv_i[k]]), &(statev[idsdv_i[k]]), CalgoI[k], CI, dCIdde, dCIdFd_bar, vec1, num1, alpha1, vec2, vec3, c_gF, kinc, kstep, dt,false,true);
+#elif Crinclusion==0
+        errortmp=(icl_mat[k])->constboxSecantMixte(DeI[k], &(statev_n[idsdv_i[k] + (icl_mat[k])->get_pos_strs()]),  &(statev[idsdv_i[k] + (icl_mat[k])->get_pos_strs()]), &(statev_n[idsdv_i[k]]), &(statev[idsdv_i[k]]), CalgoI[k], CI, dCIdde, dCIdFd_bar, vec1, num1, alpha1, vec2, vec3, c_gF, kinc, kstep, dt,true,false);
+#else
+        errortmp=(icl_mat[k])->constboxSecantMixte(DeI[k], &(statev_n[idsdv_i[k] + (icl_mat[k])->get_pos_strs()]),  &(statev[idsdv_i[k] + (icl_mat[k])->get_pos_strs()]), &(statev_n[idsdv_i[k]]), &(statev[idsdv_i[k]]), CalgoI[k], CI, dCIdde, dCIdFd_bar, vec1, num1, alpha1, vec2, vec3, c_gF, kinc, kstep, dt,false,false);
+
+#endif
+                if(errortmp!=0) 
+                  error=1;
+		addtens2(1./V,DeI[k],-1./V,DE,vec1);
+		contraction42(invS[k],vec1,vec2);
+    		addtens2(1.,DeI[k],-1.,vec2,a);
+    		contraction42(C,a,Ca);
+    		contraction42(CI,DeI[k],CIEI);
+
+	
+		for(i=0;i<6;i++){
+			for(j=0;j<6;j++){
+				mat1[i][j]=0.;
+				for(l=0;l<6;l++){
+					mat1[i][j] += dCIdde[i][l][j]*DeI[k][l];
+				}
+			}
+		}
+
+
+                for(i=0;i<6;i++){
+
+			F[i+(k*6)] = Ca[i] -CIEI[i] ;     				//FI
+
+			for(j=0;j<6;j++){
+				J[i+(k*6)][j+(k*6)] = C[i][j] - CinvS[k][i][j] - CI[i][j] - mat1[i][j];	//dFI/dEI
+			}
+		}
+
+
+		//compute AI (SC) or BI (MT)
+		addtens4(1.,CI, -1., C, diffC);				//diffC=(CI-C)
+		contraction44(PI,diffC,mat1);					//mat1=P::(CI-C)
+		addtens4(1.,I,1.,mat1,mat2);					//A^-1 = I + P::(CI-C)
+		inverse(mat2,AI,&errortmp,6);						//A = (I + P::(CI-C))^{-1} 
+		if(errortmp!=0){
+			printf("Problem while inversing invBI in equationsNR, invBI=\n");
+			error=errortmp;
+                        return error;
+		}
+		contraction44(CI,AI,CIAI);
+		contraction44(AI,PI,AIPI);
+
+//***********dF/dE, dF/dp_bar**********************************
+
+
+		contraction42(dinvSdp_bar,vec1,vec3);
+
+		for(i=0;i<6;i++){
+			 dFdp[(6*k)+i] = 0.;
+			for(j=0;j<6;j++){
+				dFdE[(6*k)+i][j] = (CinvS[k][i][j])/V;	
+                                dFdp[(6*k)+i] += Mresult.dCsdp_bar[i][j]*a[j]-C[i][j]*vec3[j]/V;       //ling wu 2012/06/28
+			}
+                }
+ 
+			for(i=0;i<6;i++){
+				for(j=0;j<6;j++){
+					mat1[i][j]=0.;
+                                        mat2[i][j]=0.0;
+					for(l=0;l<6;l++){
+						mat1[i][j] += Mresult.dCsd[i][l][j]*a[l];
+                                                mat2[i][j] += dinvS[i][l][j]*vec1[l];
+					}
+				}
+			}
+
+		        contraction44(C,mat2,mat3);
+
+			for(i=0;i<6;i++){
+				for(j=0;j<6;j++){                                               //correction: /v^2 to/v,
+					dFdE[(6*k)+i][j] += mat1[i][j]/V - mat3[i][j]/(V);     // because a '/v' is included in vec1 		
+				}
+			}
+			for(i=0;i<6;i++){
+				for(j=0;j<6;j++){   
+					J[i][j] = J[i][j] - VI*dFdE[i][j];  
+				}
+			}
+
+			//Compute Mori-Tanaka macro tangent operator
+			addtens4(VI,CIAI,V,C,mat1);
+			addtens4(VI,AI,V,I,mat2);
+			inverse(mat2,mat3,&errortmp,6);
+			if(errortmp!=0){
+				printf("Problem in matrix inversion while computing Mori-Tanaka tangent operator\n");
+				error=errortmp;
+                                return error;
+			}
+			contraction44(mat1,mat3,C);
+		
+	}//end 1st loop over inclusions 
+
+				
+	
+	//COMPUTE MACRO TANGENT OPERATORS, CONTINUUM AND ALGORITHMIC
+	if(last){
+
+		inverse(J,invJ,&errortmp,neq);
+		if(errortmp!=0){
+			printf("Problem in inversing Jacobian matrix in equationsNR\n");
+			error=errortmp;
+                        return error;
+		}
+            // dFdE here is only a part of derivative of F w.r.t DE, in this scheme more items are needed
+            //************  extra iterms for derivative of F w.r.t DE  **********************************
+
+            // derivatives of S to dDE  **************** by Ling Wu FEB, 2014   
+	    for(k=0;k<Nicl;k++){
+                     addtens2(1./V,DeI[k],-1./V,DE,vec1);
+		     contraction42(invS[k],vec1,vec2);
+    		     addtens2(1.,DeI[k],-1.,vec2,a);
+
+                     for(i=0;i<6;i++){
+                            for(j=0;j<6;j++){
+                                     for(m=0; m<6; m++){
+                                               dS[i][j][m] = dS_n[k][i][j]* Mresult.dnudE[m];
+                                     }
+                             }
+                     }
+
+           // derivatives of invS to dDE **************** by Ling Wu FEB, 2014  
+
+                    for(m=0; m<6; m++){ 
+                         for(n=0; n<6; n++){
+                                  for(l=0; l<6; l++){
+                                            dinvS[m][n][l]=0.0;
+                                            for(i=0;i<6;i++){
+                                                     for(j=0;j<6;j++){
+                                                             dinvS[m][n][l] -= invS[k][m][i]*dS[i][j][l]*invS[k][j][n];
+                                                     }
+                                            }
+                                   }                                 
+                          }
+                     }    // caution!!!  we use the same variable as for dEM
+
+           
+                    for(i=0;i<6;i++){
+			  for(j=0;j<6;j++){
+                                mat1[i][j]=0.0;
+                                mat2[i][j]=0.0;
+				for(l=0;l<6;l++){
+					mat1[i][j] += Mresult.dCsddE[i][l][j]*a[l];
+                                        mat2[i][j] += dinvS[i][l][j]*vec1[l];
+				}
+		  	  }
+                    }
+
+                   contraction44(C,mat2,mat3);
+		   for(i=0;i<6;i++){
+			for(j=0;j<6;j++){
+			       dFdE[(6*k)+i][j] += mat1[i][j] - mat3[i][j];		
+			}
+		   }
+              } //end of loop on inclusion
+              //***** end of the extra iterms for dFdE*********************************/
+
+   		for(i=0;i<neq;i++){
+			for(j=0;j<6;j++){
+				dVdE[i][j]=0.;                             // dVdE= dEIdDE
+				for(m=0;m<neq;m++){
+					dVdE[i][j]+= invJ[i][m]*dFdE[m][j];		//warning: absolute value
+				}
+				dVdE[i][j]=-dVdE[i][j];
+			}
+		}
+                
+                for(i=0;i<neq;i++){
+			dEIdp[i]=0.0;
+			for(m=0;m<neq;m++){
+			        dEIdp[i] += invJ[i][m]*dFdp[m];		   // dEI/dp_bar=-J^-1 dF/dp
+			}
+				dEIdp[i]=-dEIdp[i];
+		} 
+
+			
+// **********  compute stress of composite***************************
+
+               for(i=0;i<6;i++){
+               statev[i+6]= VI*(statev[idsdv_i[0] + (icl_mat[0])->get_pos_strs()+i]) + V*(statev[idsdv_m + mtx_mat->get_pos_strs()+i]);
+               }
+//************************************************ at the end : out put for FE ***********************
+		//COMPUTE ALGORITHMIC TANGENT OPERATOR
+		for(i=0;i<6;i++){
+			for(j=0;j<6;j++){
+				Calgo[i][j]=0.;
+			}
+                        Cp_bar[i]=0.0;
+		}
+		for(k=0;k<Nicl;k++){
+			for(i=0;i<6;i++){
+				for(j=0;j<6;j++){
+					dSIdE[i][j]=0.;
+				}
+				for(j=0;j<neq;j++){
+					dSIdV[i][j]=0.;
+				}
+                                dSIdp[i]=0.0;     // add by wu ling
+			}
+			for(i=0;i<6;i++){
+				for(j=0;j<6;j++){
+					dSIdV[i][(k*6)+j]=CalgoI[k][i][j];
+				}
+			}
+			for(i=0;i<6;i++){
+				for(j=0;j<6;j++){
+					for(m=0;m<neq;m++){
+						dSIdE[i][j] += dSIdV[i][m]*dVdE[m][j];
+					}
+				}
+			}
+// by Ling Wu 2011/10/18*****************************
+                        for(i=0;i<6;i++){
+				for(m=0;m<neq;m++){
+					dSIdp[i] += dSIdV[i][m]*dEIdp[m];
+				}
+			}
+//****************************************************
+
+			for(i=0;i<6;i++){
+				for(j=0;j<6;j++){	
+					Calgo[i][j]+=vfI[k]*dSIdE[i][j];
+				}
+                               Cp_bar[i] += vfI[k]*dSIdp[i];            //  by ling wu
+			}
+		}
+
+
+		if(mtx==1){
+ 
+			for(k=0;k<Nicl;k++){
+				for(i=0;i<6;i++){
+					for(j=0;j<6;j++){
+						dSMdV[i][(k*6)+j]=-(vfI[k]/vfM)*Mresult.Calgo[i][j];
+					}
+				}
+			}
+			for(i=0;i<6;i++){
+				for(j=0;j<6;j++){
+					dSMdE[i][j]=Mresult.Calgo[i][j]/vfM;
+				}
+			}
+			for(i=0;i<6;i++){
+				for(j=0;j<6;j++){
+					for(m=0;m<neq;m++){
+						dSMdE[i][j] += dSMdV[i][m]*dVdE[m][j]; 
+					}
+				}
+			}
+//****by ling wu **********************
+                        for(i=0;i<6;i++){
+                                dSMdp[i]=0.0;
+				for(m=0;m<neq;m++){
+					dSMdp[i] += dSMdV[i][m]*dEIdp[m]; 
+				}
+			}
+//**************************************
+			for(i=0;i<6;i++){
+				for(j=0;j<6;j++){
+					Calgo[i][j]+= vfM*dSMdE[i][j];
+				}
+                                Cp_bar[i] += vfM*dSMdp[i];
+			}
+                  
+                        addtens2(vfM, Mresult.dstrsdp_bar, 1.0, Cp_bar, dstrsdp_bar);
+
+//**** extra trems for dSMdDE
+			for(i=0;i<6;i++){
+				for(j=0;j<6;j++){
+                                        mat1[i][j] = 0.0;
+                                        for(l=0;l<6;l++){
+                                                mat1[i][j] += Mresult.dCsddE[l][i][j]*DeM[l];
+                                        }
+					Calgo[i][j]+= vfM*mat1[i][j];
+				}
+			}
+
+  //add by wu ling 28.06.2012 compute dpdE and dstrsDdp_bar for composite 
+
+                         for(i=0;i<6;i++){
+			         vec1[i]=-((1.-vfM)/vfM)*Mresult.dp[i];
+			 }
+                         for(i=0;i<6;i++){
+				 dpdE[i]= Mresult.dp[i]/vfM;
+			 }
+
+                         *Sp_bar=0.0;
+                         for(i=0;i<6;i++){
+				for(j=0;j<6;j++){
+					dpdE[i] += vec1[j]*dVdE[j][i]; 
+				}
+                                dpdE[i] += Mresult.dpdE[i];
+                                *Sp_bar += vec1[i]*dEIdp[i];
+			 }
+                 }  // end of if(matrix)
+	    }  // end of if(last)
+
+            free_Epresult(&Mresult);
+       }
+//************* Begining of computation**************************************
+//**********  3. First moment secant method for Large deformation  **********
+//***************************************************************************
+// UPDATE MATRIX VARIABLES  (IF ANY)
+      if(sch == MTSecF_LargeDeform){
+          if(mtx==1){
+           errortmp=mtx_mat->constboxLargD(DeM, &(statev_n[idsdv_m + mtx_mat->get_pos_strs()]),  &(statev[idsdv_m + mtx_mat->get_pos_strs()]), &(statev_n[idsdv_m]), &(statev[idsdv_m]), CalgoM, CM, dCMdde, dCMdp_bar, dnuM, dnuMdp_bar, alpha1, dpdEM, dstrsMdp_bar, cg_temp, kinc, kstep,dt);
+           if(errortmp!=0) 
+             error=1;
+
+//compute Eshelby's tensor for each inclusion phase
+
+	   for(i=0;i<Nicl;i++){
+        	rot4(_R66,CM,mat1); 				                   //express (fictitious) matrix tangent operator in local axes
+                if(fabs(ar[i][0]-ar[i][1])/ar[i][0] < 1.0e-6){
+                      eshelby_iso(mat1, ar[i][0], S_n_loc, dS_n_loc, ddS, dnu);         //(re-)compute Eshelby's tensor 
+                }
+                else{
+                      eshelby_aniso(mat1, ar[i][0], ar[i][1], S_n_loc, dS_n_loc, ddS, dnu);  //(re-)compute Eshelby's tensor         
+                }		
+		transpose(_R66,R66,6,6);  			//transpose rotation matrix for inverse transformation
+		rot4(R66,S_n_loc,S_n[i]); 			//express eshelby's tensor in global axes
+                rot4(R66,dS_n_loc,dS_n[i]); 			//express derivative of eshelby's tensor in global axes
+	   }
+
+		copymatr(CM,C,6,6);					// set C equal to CM	 
+			
+        }
+// COMPUTE INVERSE OF MACRO/MATRIX TANGENT OPERATOR
+	inverse(C,invC,&errortmp,6);
+	if(errortmp!=0){
+		printf("Problem while inversing macro tangent operator in equationsNR, C=\n");
+		printmatr(C,6,6);
+		error=errortmp;
+                return error;
+	}
+
+	// LOOP OVER INCLUSION PHASES 
+	for(k=0;k<Nicl;k++){
+                VI=vfI[k];							//volume fraction of inclusion 
+		copymatr(S_n[k],S,6,6);
+		inverse(S,invS[k],&errortmp,6);
+		if(errortmp!=0){
+			printf("Problem while inversing Eshelby's tensor in equationsNR, S=\n");
+			printmatr(S,6,6);
+			error=errortmp;
+                        return error;
+		}
+
+        // derivatives of S to dEM and dp_bar **************** by Ling Wu June, 2012
+                for(i=0;i<6;i++){
+                            for(j=0;j<6;j++){
+                                     for(m=0; m<6; m++){
+                                               dS[i][j][m] = dS_n[k][i][j]*dnuM[m];
+                                     }
+                                     dSdp_bar[i][j] = dS_n[k][i][j]* dnuMdp_bar;
+                             }
+                }
+
+        // derivatives of invS to dEM and dp_bar **************** by Ling Wu June, 2012  
+
+	        contraction44(invS[k], dSdp_bar, mat1);
+	        contraction44(mat1, invS[k], dinvSdp_bar);                  
+
+
+                for(m=0; m<6; m++){ 
+                         for(n=0; n<6; n++){
+                                  for(l=0; l<6; l++){
+                                            dinvS[m][n][l]=0.0;
+                                            for(i=0;i<6;i++){
+                                                     for(j=0;j<6;j++){
+                                                             dinvS[m][n][l] -= invS[k][m][i]*dS[i][j][l]*invS[k][j][n];
+                                                     }
+                                            }
+                                   }
+                                   dinvSdp_bar[m][n] = -1.0*dinvSdp_bar[m][n];
+                          }
+                }
+
+      //******************************************************                                
+
+	        contraction44(C,invS[k],CinvS[k]);							//C*S^{-1}
+		contraction44(S,invC,PI);							  		    //Hill's polarization tensor: P=SC^{-1}
+
+           //UPDATE INCLUSION STATE
+                errortmp=(icl_mat[k])->constboxLargD(DeI[k], &(statev_n[idsdv_i[k] + (icl_mat[k])->get_pos_strs()]),  &(statev[idsdv_i[k] + (icl_mat[k])->get_pos_strs()]), &(statev_n[idsdv_i[k]]), &(statev[idsdv_i[k]]), CalgoI[k], CI, dCIdde, dCIdFd_bar, vec1, num1, alpha1, vec2, vec3, c_gF, kinc, kstep, dt);
+                if(errortmp!=0) 
+                  error=1;
+
+		addtens2(1./V,DeI[k],-1./V,DE,vec1);
+		contraction42(invS[k],vec1,vec2);
+    		addtens2(1.,DeI[k],-1.,vec2,a);
+    		contraction42(C,a,Ca);
+    		contraction42(CI,DeI[k],CIEI);
+
+	
+		for(i=0;i<6;i++){
+			for(j=0;j<6;j++){
+				mat1[i][j]=0.;
+				for(l=0;l<6;l++){
+					mat1[i][j] += dCIdde[i][l][j]*DeI[k][l];
+				}
+			}
+		}
+
+
+                for(i=0;i<6;i++){
+
+			F[i+(k*6)] = Ca[i] -CIEI[i] ;     				//FI
+
+			for(j=0;j<6;j++){
+				J[i+(k*6)][j+(k*6)] = C[i][j] - CinvS[k][i][j] - CI[i][j] - mat1[i][j];	//dFI/dEI
+			}
+		}
+
+
+		//compute AI (SC) or BI (MT)
+		addtens4(1.,CI, -1., C, diffC);				//diffC=(CI-C)
+		contraction44(PI,diffC,mat1);					//mat1=P::(CI-C)
+		addtens4(1.,I,1.,mat1,mat2);					//A^-1 = I + P::(CI-C)
+		inverse(mat2,AI,&errortmp,6);						//A = (I + P::(CI-C))^{-1} 
+		if(errortmp!=0){
+			printf("Problem while inversing invBI in equationsNR, invBI=\n");
+			error=errortmp;
+                        return error;
+		}
+		contraction44(CI,AI,CIAI);
+		contraction44(AI,PI,AIPI);
+
+//***********dF/dE, dF/dp_bar**********************************
+
+
+		contraction42(dinvSdp_bar,vec1,vec3);
+
+		for(i=0;i<6;i++){
+			for(j=0;j<6;j++){
+				dFdE[(6*k)+i][j] = (CinvS[k][i][j])/V;	
+			}
+                                dFdp[(6*k)+i] = dCMdp_bar[i][j]*a[j]-C[i][j]*vec3[j]/V;       //ling wu 2012/06/28
+                }
+ 
+		
+			for(i=0;i<6;i++){
+				for(j=0;j<6;j++){
+					mat1[i][j]=0.;
+                                        mat2[i][j]=0.0;
+					for(l=0;l<6;l++){
+						mat1[i][j] += dCMdde[i][l][j]*a[l];
+                                                mat2[i][j] += dinvS[i][l][j]*vec1[l];
+					}
+				}
+			}
+
+		        contraction44(C,mat2,mat3);
+
+			for(i=0;i<6;i++){
+				for(j=0;j<6;j++){
+					dFdE[(6*k)+i][j] += mat1[i][j]/V - mat3[i][j]/(V);		
+				}
+			}
+			for(i=0;i<6;i++){
+				for(j=0;j<6;j++){   
+					J[i][j] = J[i][j] - VI*dFdE[i][j];  
+				}
+			}
+
+			//Compute Mori-Tanaka macro tangent operator
+			addtens4(VI,CIAI,V,C,mat1);
+			addtens4(VI,AI,V,I,mat2);
+			inverse(mat2,mat3,&errortmp,6);
+			if(errortmp!=0){
+				printf("Problem in matrix inversion while computing Mori-Tanaka tangent operator\n");
+				error=errortmp;
+                                return error;
+			}
+			contraction44(mat1,mat3,C);
+		
+	}//end 1st loop over inclusions 
+
+				
+	
+	//COMPUTE MACRO TANGENT OPERATORS, CONTINUUM AND ALGORITHMIC
+	if(last){
+
+		inverse(J,invJ,&errortmp,neq);
+		if(errortmp!=0){
+			printf("Problem in inversing Jacobian matrix in equationsNR\n");
+			error=errortmp;
+                        return error;
+		}
+		for(i=0;i<neq;i++){
+			for(j=0;j<6;j++){
+				dVdE[i][j]=0.;
+				for(m=0;m<neq;m++){
+					dVdE[i][j]+= invJ[i][m]*dFdE[m][j];		//warning: absolute value
+				}
+				dVdE[i][j]=-dVdE[i][j];
+			}
+		}
+                
+                for(i=0;i<neq;i++){
+			dEIdp[i]=0.0;
+			for(m=0;m<neq;m++){
+			        dEIdp[i] += invJ[i][m]*dFdp[m];		   // dEI/dp_bar=-J^-1 dF/dp
+			}
+				dEIdp[i]=-dEIdp[i];
+		} 
+
+
+
+			//Compute derivatives of Mori-Tanaka tangent operator
+			contraction44(invC,CIAI,mat4);
+
+             		for(i=0;i<6;i++){
+				for(j=0;j<6;j++){
+					for(k=0;k<6;k++){
+						cub[i][j][k]=0.;
+						cub3[i][j][k]=0.;
+						for(l=0;l<6;l++){
+							cub[i][j][k] +=  dCIdde[i][l][k]*AI[l][j];
+							cub3[i][j][k] +=  dCMdde[i][l][k]*mat4[l][j];
+						}
+					}
+				}
+			}
+			for(i=0;i<6;i++){
+				for(j=0;j<6;j++){
+					for(k=0;k<6;k++){
+						cub[i][j][k] = cub[i][j][k] + (VI/V)*cub3[i][j][k];
+					}
+				}
+			}
+			for(i=0;i<6;i++){
+				for(j=0;j<6;j++){
+					for(k=0;k<6;k++){
+						cub2[i][j][k]=0.;
+						for(l=0;l<6;l++){
+							cub2[i][j][k] += AIPI[i][l]*cub[l][j][k];
+						}	
+					}
+				}
+			}
+			for(i=0;i<6;i++){
+				for(j=0;j<6;j++){
+					for(k=0;k<6;k++){
+						dBIdE[i][j][k]=0.;
+						for(l=0;l<6;l++){
+							dBIdE[i][j][k] += cub2[i][j][l]*dVdE[l][k];
+						}
+					}
+				}
+			}
+			for(i=0;i<6;i++){
+				for(j=0;j<6;j++){
+					for(k=0;k<6;k++){
+						cub2[i][j][k]=0.;
+						for(l=0;l<6;l++){
+							cub2[i][j][k] += AIPI[i][l]*cub3[l][j][k];
+						}
+					}
+				}
+			}
+
+			for(i=0;i<6;i++){
+				for(j=0;j<6;j++){
+					for(k=0;k<6;k++){
+						dBIdE[i][j][k] += cub2[i][j][k]/V;
+					}
+				}
+			}
+
+			//compute dCIdE and dCMdE
+			for(i=0;i<6;i++){
+				for(j=0;j<6;j++){
+					for(k=0;k<6;k++){
+						dCIdE[i][j][k]=0.;
+						dCMdE[i][j][k]=0.;
+						cub2[i][j][k]=0.;
+						for(l=0;l<6;l++){
+							dCIdE[i][j][k] -= dCIdde[i][j][l]*dVdE[l][k];
+							dCMdE[i][j][k] += dCMdde[i][j][l]*(I[l][k]- VI*dVdE[l][k]);
+							cub2[i][j][k] += CI[i][l]*dBIdE[l][j][k];
+						}
+					}
+				}
+			}
+
+			for(i=0;i<6;i++){
+				for(j=0;j<6;j++){
+					for(k=0;k<6;k++){
+						cub[i][j][k]=0.;
+						for(l=0;l<6;l++){
+							cub[i][j][k] += dCIdE[i][l][k]*AI[l][j];
+						}
+					}
+				}
+			}
+			for(i=0;i<6;i++){
+				for(j=0;j<6;j++){
+					for(k=0;k<6;k++){
+						cub3[i][j][k] = VI*(cub[i][j][k]+cub2[i][j][k]) + dCMdE[i][j][k];
+					}
+				}
+			}
+    
+			for(i=0;i<6;i++){
+				for(j=0;j<6;j++){
+					for(k=0;k<6;k++){
+						cub[i][j][k]=0.;
+						for(l=0;l<6;l++){
+							cub[i][j][k] += C[i][l]*dBIdE[l][j][k];
+						}
+					}
+				}
+			}
+			for(i=0;i<6;i++){
+				for(j=0;j<6;j++){
+					for(k=0;k<6;k++){
+						cub2[i][j][k] = cub3[i][j][k] - (VI*cub[i][j][k]);
+					}
+				}	
+			}
+
+			for(i=0;i<6;i++){
+				for(j=0;j<6;j++){
+					for(k=0;k<6;k++){
+						dC[i][j][k]=0.;
+						for(l=0;l<6;l++){
+							dC[i][j][k] += cub2[i][l][k]*mat3[l][j]; 
+						}
+					}
+				}
+			}
+
+
+// **********  compute stress of composite***************************
+          //  in material box 
+  
+//************************************************ at the end : out put for FE ***********************
+		//COMPUTE ALGORITHMIC TANGENT OPERATOR
+		for(i=0;i<6;i++){
+			for(j=0;j<6;j++){
+				Calgo[i][j]=0.;
+			}
+
+                        Cp_bar[i]=0.0;
+		}
+		for(k=0;k<Nicl;k++){
+			for(i=0;i<6;i++){
+				for(j=0;j<6;j++){
+					dSIdE[i][j]=0.;
+				}
+				for(j=0;j<neq;j++){
+					dSIdV[i][j]=0.;
+				}
+                                dSIdp[i]=0.0;     // add by wu ling
+			}
+			for(i=0;i<6;i++){
+				for(j=0;j<6;j++){
+					dSIdV[i][(k*6)+j]=CalgoI[k][i][j];
+				}
+			}
+			for(i=0;i<6;i++){
+				for(j=0;j<6;j++){
+					for(m=0;m<neq;m++){
+						dSIdE[i][j] += dSIdV[i][m]*dVdE[m][j];
+					}
+				}
+			}
+// by Ling Wu 2011/10/18*****************************
+                        for(i=0;i<6;i++){
+				for(m=0;m<neq;m++){
+					dSIdp[i] += dSIdV[i][m]*dEIdp[m];
+				}
+			}
+//****************************************************
+
+			for(i=0;i<6;i++){
+				for(j=0;j<6;j++){	
+					Calgo[i][j]+=vfI[k]*dSIdE[i][j];
+				}
+                               Cp_bar[i] += vfI[k]*dSIdp[i];            //  by ling wu
+			}
+		}
+
+
+		if(mtx==1){
+ 
+			for(k=0;k<Nicl;k++){
+				for(i=0;i<6;i++){
+					for(j=0;j<6;j++){
+						dSMdV[i][(k*6)+j]=-(vfI[k]/vfM)*CalgoM[i][j];
+					}
+				}
+			}
+			for(i=0;i<6;i++){
+				for(j=0;j<6;j++){
+					dSMdE[i][j]=CalgoM[i][j]/vfM;
+				}
+			}
+			for(i=0;i<6;i++){
+				for(j=0;j<6;j++){
+					for(m=0;m<neq;m++){
+						dSMdE[i][j] += dSMdV[i][m]*dVdE[m][j]; 
+					}
+				}
+			}
+//****by ling wu **********************
+                        for(i=0;i<6;i++){
+                                dSMdp[i]=0.0;
+				for(m=0;m<neq;m++){
+					dSMdp[i] += dSMdV[i][m]*dEIdp[m]; 
+				}
+			}
+//**************************************
+			for(i=0;i<6;i++){
+				for(j=0;j<6;j++){
+					Calgo[i][j]+= vfM*dSMdE[i][j];
+				}
+                                Cp_bar[i] += vfM*dSMdp[i];
+			}
+  //add by wu ling 28.06.2012 compute dpdE and dstrsDdp_bar for composite   
+
+                        
+                                     addtens2(vfM, dstrsMdp_bar, 1.0, Cp_bar, dstrsdp_bar);
+
+                                    for(i=0;i<6;i++){
+					     vec1[i]=-((1.-vfM)/vfM)*dpdEM[i];
+				    }
+                                    for(i=0;i<6;i++){
+					     dpdE[i]=dpdEM[i]/vfM;
+				    }
+
+                                    *Sp_bar=0.0;
+                                    for(i=0;i<6;i++){
+					for(j=0;j<6;j++){
+						dpdE[i] += vec1[j]*dVdE[j][i]; 
+					}
+                                         *Sp_bar += vec1[i]*dEIdp[i];
+				    }
+
+                       // end add bu wu ling     
+		}
+	 }
+      }
 
-       return 0;
+       return error;
 }
 
 
diff --git a/NonLinearSolver/materialLaw/homogenization_2rd.cpp b/NonLinearSolver/materialLaw/homogenization_2rd.cpp
index 5af45f184f9a85c4a5de7dcfdce9b5dc3e6ab56e..ed855293b426992554a0653129a61170b547dbd2 100644
--- a/NonLinearSolver/materialLaw/homogenization_2rd.cpp
+++ b/NonLinearSolver/materialLaw/homogenization_2rd.cpp
@@ -23,8 +23,140 @@ using namespace MFH;
 int homogenize_2rd(int sch, double* DE, Material* mtx_mat, Material* icl_mat, double vfM, double vfI, double* ar, double* angles, double* statev_n, double* statev, int nsdv, int idsdv_m, int idsdv_i, Lcc* LCC, double** Calgo, double* dpdE, double* strs_dDdp_bar,double *Sp_bar, int kinc, int kstep, double dt)
 {
 
+	int i,j,error,errortmp;
+	
+//	double *pstrn; 		//macro plastic strain
+//	double *tr_strn; 		//macro trial strain
+//	double *MACRO; 			//macro strain applied to the LCC
 		
-	return 0;
+	double tol = 1e-12;			//NR tolerance
+	int it=0;				//NR current iteration 
+	double res=0.0;
+        double res_n=0.0;			//NR residual
+	int last=0;				//last iteration or not
+	int neq=0;			//number of NR equations
+	int solver=NR;
+	double factor;
+	double norm;
+
+	double* mu0=NULL;		//vector of effective shear moduli (the unknowns)
+	double* Dmu0=NULL;	        //correction vector for the unknowns
+	double* F;					//residual vector
+	double** J;					//jacobian matrix
+	double** invJ;			//inverse of jacobian matrix
+	int* indx=NULL;			//indices of phases which plastify
+	
+        int Nph = LCC->Nph;
+        error=0;
+
+	//Memory allocation
+	mallocvector(&mu0,Nph);
+	mallocvector(&Dmu0,Nph);
+	mallocvector(&F,Nph);
+	mallocmatrix(&J,Nph,Nph);
+	mallocmatrix(&invJ,Nph,Nph);
+	indx=(int*)malloc(Nph*sizeof(int));
+
+	
+ 	//initialize bulk mudulus in the LCC and unknown shear moduli
+        // is done in unload step before enter homogenization
+	//LCC with the same microstructure as the nonlinear one
+
+	norm=LCC->mu[0];
+        for (i=0; i <Nph;i++) mu0[i] = LCC->mu[i];
+
+
+	//compute first residual vector and jacobian matrix	
+	errortmp=preNR(DE, mu0, mtx_mat, icl_mat, vfI, ar, angles, statev_n, statev, idsdv_m, idsdv_i, LCC, last, F, J, 
+              indx, &neq, solver, Calgo, dpdE, strs_dDdp_bar, Sp_bar, kinc, kstep, dt);
+        if(errortmp==1) error=1;
+	
+	//compute scalar residual normalized by the elastic shear modulus of the 1st phase
+	res=scalar_res(F,neq,norm);		
+
+	printf("first residual: %.8e \n", res);
+	it=1;
+	while (res > tol ){
+	
+		//Newton-Raphson	
+		if(solver==NR){
+
+			factor=1.0;
+			solveNR(F,J,invJ,Dmu0,indx, Nph, neq);	
+			updateNR(mu0,Dmu0,Nph,factor);
+
+                    
+                        for(i=0;i<Nph;i++){
+			        if (mu0[i] > LCC->mu[i]){
+				        mu0[i] = LCC->mu[i];
+			        }
+                        }
+                }
+		
+		//Fixed-point
+		else{
+			
+			for(j=0;j<neq;j++){	
+				mu0[indx[j]] += J[j][0];
+			}
+		}
+		
+		errortmp=preNR(DE, mu0, mtx_mat, icl_mat, vfI, ar, angles, statev_n, statev, idsdv_m, idsdv_i, LCC, last, F, J, 
+                      indx, &neq, solver, Calgo, dpdE, strs_dDdp_bar, Sp_bar, kinc, kstep, dt);
+                if(errortmp==1) error=1;
+
+	        res=scalar_res(F,neq,norm);	
+		//printf("iteration %d, residual: %.10e\n",it,res);
+
+		if(it>100){
+		
+			if(res<1e-4){
+				//printf("Warning: prescribed convergence not achieved. Actual residual: %.10e\n",res);
+				res=0;
+			}
+			else{
+				printf("CONVERGENCE PROBLEM, residual: %.10e\n",res);		
+				error=1;
+				res=0;
+			}
+		}
+			
+		it++;
+	}
+	printf("%d iterations, residual: %.10e\n",it-1,res);
+	
+	//one extra correction to compute the algo tangent operator:
+
+       	res_n=res;
+	last = 1; 
+
+	solveNR(F,J,invJ,Dmu0,indx, Nph, neq);
+	updateNR(mu0,Dmu0,Nph,1.);
+
+
+	errortmp=preNR(DE, mu0, mtx_mat, icl_mat, vfI, ar, angles, statev_n, statev, idsdv_m, idsdv_i, LCC, last, F, J, 
+             indx, &neq, solver, Calgo, dpdE, strs_dDdp_bar, Sp_bar, kinc, kstep, dt);
+        if(errortmp==1) error=1;
+
+	res= scalar_res(F,neq,0.001*norm);
+	if(res>res_n){
+		//printf("Problem: last residual increases: %.10e \t %.10e \n",res_n,res);
+		if(res > tol){
+			printf("Last residual above tolerance!!\n");
+                        error=1;
+		}	
+	}
+
+        
+	//free memory
+	free(indx);
+	free(F);
+	freematrix(J,Nph);
+	freematrix(invJ,Nph);
+	free(mu0);
+	free(Dmu0);
+		
+	return error;
 
 } //end homogenize
 //*****************************************************
@@ -33,8 +165,234 @@ int homogenize_2rd(int sch, double* DE, Material* mtx_mat, Material* icl_mat, do
 
 int preNR(double* DE, double* mu0, Material* mtx_mat, Material* icl_mat, double vfI, double* ar, double* angles, double* statev_n, double* statev, int idsdv_m, int idsdv_i, Lcc* LCC, int last, double* F, double** J, int* indx, int* neq, int solver, double** Calgo, double* dpdE, double* strs_dDdp_bar, double *Sp_bar, int kinc, int kstep, double dt){
 
+        int mtx=1;
+        int icl=0;
+	int i,j,k,ph1,ph2;
+	int Nph=LCC->Nph;
+	int Npl;
+	int error,errortmp;
+	double trial;
+
+        double *kappa0;
+        double **S, **dS, **ddS;
+        double *dnu;
+        double *dstrn_m, *dstrn_i;
+
+        double **CalgoI, **CalgoM;
+        double **cg_temp;
+
+        YieldF YFM, YFI, *YFP1, *YFP2;
+
+
+	//estimate of second-order moment of the trial strain and derivatives
+
+	double* vec1;
+	double** dSdV, **dFde, **dVde;
+	double** invJ;
+        error=0;
+        mallocvector(&kappa0,2);
+	mallocmatrix(&S,6,6);
+	mallocmatrix(&dS,6,6);
+	mallocmatrix(&ddS,6,6);
+        mallocvector(&dnu,5);
+
+        mallocvector(&dstrn_m,6);
+        mallocvector(&dstrn_i,6);
+
+        malloc_YF(&YFM);
+        malloc_YF(&YFI);
+
+	mallocvector(&vec1,6);
+
+        mallocmatrix(&CalgoI,6,6);
+        mallocmatrix(&CalgoM,6,6);
+        mallocmatrix(&cg_temp,3,3);
+
+	
+	//reset residual vector and jacobian matrix
+         for(i=0;i<Nph;i++){
+                 F[i] = 0.0;
+                 for(j=0;j<Nph;j++){
+                         J[i][j] = 0.0;
+                 }
+         }
+
+	//initialize some vectors...
+	mtx_mat->get_elOD(&(statev_n[idsdv_m]), LCC->C0);
+	icl_mat->get_elOD(&(statev_n[idsdv_i]), LCC->C1);
+
+        //
+        kappa0[0] = LCC->C0[0][1] + LCC->C0[3][3]/3.0;
+        kappa0[1] = LCC->C1[0][1] + LCC->C1[3][3]/3.0;
+
+    // 1. set properties of the LCC with current mu
+	      set_elprops(LCC,mu0,kappa0);
+
+	      //CONVENTION: phase0 -> matrix, phase1 -> inclusion
+	      //linear_scheme==MT
+
+              //complete LCC with given Kappa,mu
+               Eshelby(LCC->C0, ar, angles, S, dS, ddS, dnu);
+               CA_2ndCdA_MT(LCC, vfI, S, dS, ddS, dnu);
+
+
+
+              //LCC subjected to macro trial strain
+               contraction42(LCC->A, DE, dstrn_i);              //incremental strain of inclusion
+               addtens2 (1./(1.0-vfI), DE, -1.*vfI/(1.0-vfI), dstrn_i, dstrn_m);
+
+               
+    // 2. loop on each phases, material->conbox_2order()
+               errortmp=mtx_mat->constbox_2order(mtx, DE, dstrn_m, &(statev[idsdv_m + mtx_mat->get_pos_strs()]), &(statev_n[idsdv_m]), &(statev[idsdv_m]), CalgoM, LCC, &YFM, cg_temp, kinc, kstep, dt);
+               if(errortmp==1) error=1;
+
+               errortmp=icl_mat->constbox_2order(icl, DE, dstrn_i, &(statev[idsdv_i + icl_mat->get_pos_strs()]), &(statev_n[idsdv_i]), &(statev[idsdv_i]), CalgoI, LCC, &YFI, cg_temp, kinc, kstep, dt);
+               if(errortmp==1) error=1;
+
+	      //end of MT
+
+    // 3. check plastic yielding in each phase
+
+	      Npl=0;
+              // matrix
+                if(YFM.trial > 0.){    //plastic yielding	
+				indx[Npl]= 0;
+			        Npl++;
+                               }
+             // inclusion
+                if(YFI.trial > 0.){    //plastic yielding	
+				indx[Npl]= 1;
+			        Npl++;	
+			       }
+                              
+   //  4.1 if the load is elastic:
+	     if(Npl==0){
+		   *neq=0;
+		   copymatr(LCC->C,Calgo,6,6); 
+	     }
+   //  4.2 else, build residual vector and jacobian matrix
+	     else{ 
+		   for(i=0;i<Npl;i++){
+                        ph1=indx[i]; 
+                        if(indx[i] == 0){ 
+                                  YFP1= &YFM;
+                        }
+                        if(indx[i] == 1){ 
+                                  YFP1= &YFI;
+                        }
+                          
+		       //RESIDUAL
+			F[i] = YFP1->f;
+
+		       //NR: COMPUTE JACOBIAN MATRIX
+		        if (solver==NR){
+                                  J[i][i] = YFP1->dfdmu[ph1];
+
+  				  for(j=i+1;j<Npl;j++){
+					ph2=indx[j];
+                                        if(indx[j] == 0){ 
+                                              YFP2= &YFM;
+                                        }
+                                        if(indx[j] == 1){ 
+                                              YFP2= &YFI;
+                                        }
+             
+                                        J[i][j] = YFP1->dfdmu[ph2];
+                                        J[j][i] = YFP2->dfdmu[ph1];
+				  }
+			}
+                        else{
+			         printf("wrong solver: %d\n",solver);
+		        }
+                   }
+             
+		//update the number of equations
+		*neq=Npl;		
+
+		//if last iteration: compute algorithmic tangent operator
+		if(last==1){
+			
+			//reset algo tangent operator
+			cleartens4(Calgo);      //maybe not necessary
+
+			mallocmatrix(&dSdV,6,Npl);
+			mallocmatrix(&dFde,Npl,6);
+			mallocmatrix(&dVde,Npl,6);
+			mallocmatrix(&invJ,Npl,Npl);
+
+			inverse(J,invJ,&error,Npl);
+
+			for(i=0;i<Npl;i++){
+				ph1=indx[i];
+				if(ph1==0){
+					contraction42(LCC->dCdmu0,DE,vec1);	
+				}
+				else{
+					contraction42(LCC->dCdmu1,DE,vec1);
+				}
+				for(j=0;j<6;j++){
+					dSdV[j][i] = vec1[j];
+				}
+			}
+
+			for(i=0;i<Npl;i++){
+				if(indx[i] == 0){ 
+                                         YFP1= &YFM;
+                                }
+                                if(indx[i] == 1){ 
+                                         YFP1= &YFI;
+                                }
+ 				for(j=0;j<6;j++){
+					dFde[i][j] = YFP1->dfdstrn[j];
+				}
+			}
+
+			for(i=0;i<Npl;i++){
+				for(j=0;j<6;j++){
+					for(k=0;k<Npl;k++){
+						dVde[i][j] += invJ[i][k]*dFde[k][j];	// dVde---dmude
+					}
+				}
+			}	
+			for(i=0;i<6;i++){
+				for(j=0;j<6;j++){
+					for(k=0;k<Npl;k++){
+						Calgo[i][j] += dSdV[i][k]*dVde[k][j];
+					}
+				}
+			}
+			addtens4(1.,LCC->C, -1.,Calgo,Calgo);
+
+			freematrix(dSdV,6);
+			freematrix(dFde,Npl);
+			freematrix(dVde,Npl);
+			freematrix(invJ,Npl);
+
+		}//end if last
+	}//end if plastic yield
+
+	//update statev
+          	
+	free(vec1);
+        free(kappa0);
+
+ 
+	freematrix(S,6);
+	freematrix(dS,6);
+	freematrix(ddS,6);
+	free(dnu);
+	free(dstrn_m);
+	free(dstrn_i);
+
+        free_YF(&YFM);
+        free_YF(&YFI);
+
+
+        freematrix(CalgoI,6);
+        freematrix(CalgoM,6);    
+        freematrix(cg_temp,3);  
  
-	return 0; 
+	return error; 
 
 }	//end function
 
diff --git a/NonLinearSolver/materialLaw/j2plast.cpp b/NonLinearSolver/materialLaw/j2plast.cpp
index f90f26297cdc36f280906d9745058da8f76f9312..1714213b921cd7b7b13083bd1896287ae5339e5a 100644
--- a/NonLinearSolver/materialLaw/j2plast.cpp
+++ b/NonLinearSolver/materialLaw/j2plast.cpp
@@ -1,9 +1,9 @@
 #ifndef J2PLAST_C
 #define J2PLAST_C 1
 
-#ifndef max
-#define max(a,b) ( ((a) > (b)) ? (a) : (b) )
-#endif
+//#ifndef max
+//#define max(a,b) ( ((a) > (b)) ? (a) : (b) )
+//#endif
 
 #include <math.h>
 #include <stdlib.h>
@@ -25,27 +25,1071 @@ using namespace MFH;
 //ELASTO-PLASTIC CONSTITUTIVE BOX
 int constbox_ep(double E, double nu, double sy0, int htype, double hmod1, double hmod2, double hp0,
 	double hexp, double *dstrn, double *strs_n, double *strs, double* pstrn_n, double* pstrn,
-	double p_n, double *p, double *twomu_iso, double* dtwomu_iso,  double** Calgo, double*** dCalgo, double* dpdE, bool residual)
+	double p_n, double *p, double *twomu_iso, double* dtwomu_iso, double** Calgo, double*** dCalgo, double* dpdE, bool residual)
 
 {
+	int i,j,k,it,error;
+	double strseqtr, trstrstr,strseqtrNor0;       	//Variables for the elastic prediction 
+	double R, dR, ddR, strseq, G;    //Variables for the correction phase 
+	double kp;
+	double Dp;  
+	double h, tmp1, tmp2;
+	double cp=0.;
+	double tol = 1.e-12;    //tolerance on the residual 
+	double res, res0;    		 //residual 
+	double mu_iso, k_iso;
+	double G3, h3;
+        double sq2;
+
+        sq2 = sqrt(2.);
+	R=0.;
+	dR=0.;
+	ddR=0.;
+
+	G = E/(2.*(1.+nu));  
+	k_iso = E/(3.*(1.-(2.*nu)));
+	G3 = G*G*G;
+
+        static bool initialized=false;
+        // initialize only once!
+	static double **Cel=NULL;
+	static double **NoN=NULL;
+	static double **Idev=NULL;
+	static double **mat1=NULL;
+	static double *strstr=NULL;
+	static double *Str=NULL;              //used to compute the modified normal
+	static double *Ntr=NULL;              //used to compute the modified normal
+	static double *Stau=NULL;
+	static double *dstrs=NULL;
+        static double *strstrNor0=NULL;      //used to compute the modified normal
+        bool stay=true;
+        if(!initialized)
+        {
+          mallocmatrix(&Cel, 6, 6);
+	  mallocmatrix(&NoN,6,6);
+	  mallocmatrix(&Idev,6,6);
+	  mallocmatrix(&mat1,6,6);
+          mallocvector(&strstr,6);
+          mallocvector(&Str,6);
+          mallocvector(&Ntr,6);
+          mallocvector(&Stau,6);
+          mallocvector(&dstrs,6);
+          mallocvector(&strstrNor0,6);
+          initialized = true;
+        }
+        cleartens4(Cel);
+        cleartens4(NoN);
+	cleartens4(Idev);
+	cleartens4(mat1);
+        cleartens2(strstr);
+        cleartens2(Str);
+        cleartens2(Ntr);
+        cleartens2(Stau);
+        cleartens2(dstrs);
+        cleartens2(strstrNor0);
+	//deviatoric operator
+	for(i=0;i<3;i++){
+	  for(j=0;j<3;j++){
+	    Idev[i][j]=-1./3.;
+          }
+	  Idev[i][i]+=1.;
+	  Idev[i+3][i+3]=1.;
+	}
+	//reset tangent operators to zero
+	for(i=0;i<6;i++){
+		for(j=0;j<6;j++){
+			Calgo[i][j]=0.;
+		}
+	}
+
+	//elastic predictor
+	compute_Hooke(E,nu,Cel);
+
+	//compute trial stress
+	contraction42(Cel, dstrn, dstrs);
+
+	addtens2(1., strs_n, 1., dstrs, strstr);
+	strseqtr = vonmises(strstr);
+        strseqtrNor0 = vonmises(dstrs);  
+	//normal to the yield surface
+        if(!residual)
+        {
+  	  dev(strstr, Str);
+  	  if(strseqtr > 0){
+		addtens2(1.5/strseqtr, Str, 0, Str, Ntr);
+		produit_tensoriel(Ntr,Ntr,NoN);
+	  }
+        }
+        else
+        {
+          dev(dstrs, Str);
+          if(strseqtrNor0 > 0){
+                addtens2(1.5/strseqtrNor0, Str, 0, Str, Ntr);
+		produit_tensoriel(Ntr,Ntr,NoN);
+          }
+        }
+	//elastic increment
+	Dp=DP_MIN;
+	j2hard (p_n+Dp, sy0, htype, hmod1, hmod2, hp0, hexp, &R, &dR,&ddR);
+	strseq= sy0 + R;
+	h = (3.*G) + dR;
+	kp = strseq + 3.*G*Dp - strseqtr;
+
+	if(kp>=0.){
+		//printf("elastic: !");
+		copyvect(strstr, strs, 6);
+		copyvect(pstrn_n, pstrn,6);
+    		*p = p_n;
+		Dp=0.;
+		copymatr(Cel,Calgo,6,6);
+		for(i=0;i<6;i++){
+			for(j=0;j<6;j++){
+				for(k=0;k<6;k++){
+					dCalgo[i][j][k]=0.;
+				}
+			}
+		}
+      //***** By Wu Ling 06/04/2011************************************************************************************
+       //compute dpdE  accumulate plastice strain p derivative w.r.t. strain increment
+
+       cleartens2(dpdE);
+
+
+       //******* By Wu Ling 06/04/2011**********************************************************************************
+
+	}
+	//Plastic correction: return mapping algorithm 
+	else{
+		Dp = fmax(DP_MIN,-kp/h);  //correction must be such that Dp >= DP_MIN
+
+		it=0;
+		res=1.;
+		res0=res;
+		while(res>tol && stay){
+		
+			it++;
+			if(it>20){
+				printf("no convergence in return mapping algorithm, p: %lf\n",*p);
+				stay=false;
+                                Dp=1.;
+				//return(1);
+			}
+
+			*p=p_n+Dp;
+			j2hard (*p, sy0, htype, hmod1, hmod2, hp0, hexp, &R, &dR,&ddR);
+			kp = 3.*G*Dp + R + sy0 - strseqtr;
+      
+			res = fabs(kp)/G;
+
+			if(it==1||res<res0){
+				res0=res;
+				cp =  - kp/(3.*G+dR);
+				tmp1 = 0.99*(DP_MIN-Dp);
+				if(cp<tmp1) {
+					//printf("new Dp below Dpmin : correction!\n");
+					cp=tmp1;
+				}
+				Dp+=cp;
+			}
+			else{
+				//printf("residual is not decreasing: correction!\n");
+				cp=cp/2.;
+				Dp=Dp-cp;
+				res0=res;
+			}
+
+			//printf("j2plast iteration: %d, res: %.10e, p: %.10e\n",it,res,*p);
+		}
+		//printf("Number of iterations in radial return algorithm: %d\n",it); 
+		strseq = sy0 + R;
+
+		addtens2(1., strstr,-2.*G*(Dp), Ntr, strs);
+		h=(3.*G) + dR;
+		
+		addtens2(1.,pstrn_n, Dp, Ntr, pstrn);
+
+		h3 = h*h*h;
+		tmp1 = 4.*G*G/h;
+		tmp2 = 4.*G*G*(*p-p_n)/strseqtr;
+
+		addtens4(1.,Cel,(-tmp1+tmp2),NoN, Calgo);
+		addtens4(1.,Calgo,-1.5*tmp2,Idev,Calgo);
+
+		addtens4(1.5,Idev,-1.,NoN,mat1);
+		for(i=0;i<6;i++){
+			for(j=0;j<6;j++){
+				for(k=0;k<6;k++){
+					dCalgo[i][j][k] = (8.*G3*ddR/h3)*NoN[i][j]*Ntr[k] - (16.*G3/(h*strseqtr))*Ntr[i]*mat1[j][k] - mat1[i][j]*8.*G3*Ntr[k]*((1./(h*strseqtr))-(Dp/(strseqtr*strseqtr))) + (16.*G3*Dp/(strseqtr*strseqtr))*Ntr[i]*mat1[j][k];
+				}
+			}
+		}
+
+       //***** By Wu Ling 06/04/2011************************************************************************************
+       //compute dpdE  accumulate plastice strain p derivative w.r.t. strain increment
+
+       addtens2((2.*G/h), Ntr, 0, Ntr, dpdE);
+
+
+       //******* By Wu Ling 06/04/2011**********************************************************************************
+
+
+	} //end case plastic correction
+
+
+	//compute isoJ2 tangent operator and its derivative w.r.t. strain increment
+	if(Dp<DP_MIN){		//that is, Dp=0 	
+		mu_iso=G;
+		for(i=0;i<6;i++){
+			dtwomu_iso[i]=0.;
+		}
+	}
+		
+	else {
+		mu_iso = G*(1.-(3.*G/h));
+		for(i=0;i<6;i++){
+			dtwomu_iso[i] = 12.*pow(G/h,3)*ddR*Ntr[i];
+		}
+	}
+  
+	*twomu_iso = 2.*mu_iso;
+
+//      no free as initialized once        
+//     	freematrix(Cel, 6);
+//	freematrix(Idev,6);
+//	freematrix(NoN,6);
+//	freematrix(mat1,6);
+        if(!stay) return(1); //no convergence
 	return(0);
 }
 
-//****************************************************
-/**********J2 plasticity for large deformation***/
-//******************************************************
-int constbox_ep(double E, double nu, double sy0, int htype, double hmod1, double hmod2, double hp0, double hexp, double *strstr, double *strs, double* pstrn_n, double* pstrn, double p_n, double *p,  double** Calgo, double*** dCalgo, double* dpdE, bool residual)
+
+int constbox_ep_res(double E, double nu, double sy0, int htype, double hmod1, double hmod2, double hp0,
+	double hexp, double *dstrn, double *strs_n, double *strs, double* pstrn_n, double* pstrn,
+	double p_n, double *p, double *twomu_iso, double* dtwomu_iso,  double** Calgo, double*** dCalgo, double* dpdE, bool residual)
 
 {
+	int i,j,k,it,error;
+	double strseqtr, strseqtrNor0, trstrstr;       	//Variables for the elastic prediction 
+	double R, dR, ddR, strseq, G;    //Variables for the correction phase 
+	double kp;
+	double Dp;  
+	double h, tmp1, tmp2;
+	double cp=0.;
+	double tol = 1.e-12;    //tolerance on the residual 
+	double res, res0;    		 //residual 
+	double mu_iso, k_iso;
+	double G3, h3;
+        double sq2;
+
+        sq2 = sqrt(2.);
+	R=0.;
+	dR=0.;
+	ddR=0.;
+
+	G = E/(2.*(1.+nu));  
+	k_iso = E/(3.*(1.-(2.*nu)));
+	G3 = G*G*G;
+
+        static bool initialized=false;
+        // initialize only once!
+	static double **Cel=NULL;
+	static double **NoN=NULL;
+	static double **Idev=NULL;
+	static double **mat1=NULL;
+	static double *strstr=NULL;
+	static double *strstrNor0=NULL;              //used to compute the modified normal
+	static double *Str=NULL;              //used to compute the modified normal
+	static double *Ntr=NULL;              //used to compute the modified normal
+	static double *Stau=NULL;
+	static double *dstrs=NULL;
+        bool stay=true;
+
+        if(!initialized)
+        {
+          mallocmatrix(&Cel, 6, 6);
+	  mallocmatrix(&NoN,6,6);
+	  mallocmatrix(&Idev,6,6);
+	  mallocmatrix(&mat1,6,6);
+          mallocvector(&strstr,6);
+          mallocvector(&strstrNor0,6);
+          mallocvector(&Str,6);
+          mallocvector(&Ntr,6);
+          mallocvector(&Stau,6);
+          mallocvector(&dstrs,6);
+          initialized = true;
+        }
+        cleartens4(Cel);
+        cleartens4(NoN);
+	cleartens4(Idev);
+	cleartens4(mat1);
+        cleartens2(strstr);
+        cleartens2(strstrNor0);
+        cleartens2(Str);
+        cleartens2(Ntr);
+        cleartens2(Stau);
+        cleartens2(dstrs);
+
+	//deviatoric operator
+	for(i=0;i<3;i++){
+	  for(j=0;j<3;j++){
+	    Idev[i][j]=-1./3.;
+          }
+	  Idev[i][i]+=1.;
+	  Idev[i+3][i+3]=1.;
+	}
+	//reset tangent operators to zero
+	for(i=0;i<6;i++){
+		for(j=0;j<6;j++){
+			Calgo[i][j]=0.;
+		}
+	}
+
+	//elastic predictor
+	compute_Hooke(E,nu,Cel);
+
+	//compute trial stress
+	contraction42(Cel, dstrn, dstrs);
 
+	addtens2(1.0, strs_n, 1.0, dstrs, strstr);
+        strseqtrNor0 = vonmises(dstrs);
+	strseqtr = vonmises(strstr);
+  
+	//normal to the yield surface
+	dev(dstrs, Str);
+  
+	if(strseqtrNor0 > 0){
+		addtens2(1.5/strseqtrNor0, Str, 0, Str, Ntr);
+		produit_tensoriel(Ntr,Ntr,NoN);
+	}
+
+
+	//elastic increment
+	Dp=DP_MIN;
+	j2hard (p_n+Dp, sy0, htype, hmod1, hmod2, hp0, hexp, &R, &dR,&ddR);
+	strseq= sy0 + R;
+	h = (3.*G) + dR;
+	kp = strseq + 3.*G*Dp - strseqtr;
+
+	if(kp>=0.){
+		//printf("elastic: !");
+		copyvect(strstr, strs, 6);
+		copyvect(pstrn_n, pstrn,6);
+    		*p = p_n;
+		Dp=0.;
+		copymatr(Cel,Calgo,6,6);
+		for(i=0;i<6;i++){
+			for(j=0;j<6;j++){
+				for(k=0;k<6;k++){
+					dCalgo[i][j][k]=0.;
+				}
+			}
+		}
+      //***** By Wu Ling 06/04/2011************************************************************************************
+       //compute dpdE  accumulate plastice strain p derivative w.r.t. strain increment
+
+       cleartens2(dpdE);
+
+
+       //******* By Wu Ling 06/04/2011**********************************************************************************
+
+	}
+	//Plastic correction: return mapping algorithm 
+	else{
+		Dp = fmax(DP_MIN,-kp/h);  //correction must be such that Dp >= DP_MIN
+
+		it=0;
+		res=1.;
+		res0=res;
+		while(res>tol && stay){
+		
+			it++;
+			if(it>20){
+				printf("no convergence in return mapping algorithm, p: %lf\n",*p);
+				
+				//return(1);
+                                stay=false;
+                                Dp=1.;
+
+			}
+
+			*p=p_n+Dp;
+			j2hard (*p, sy0, htype, hmod1, hmod2, hp0, hexp, &R, &dR,&ddR);
+			kp = 3.*G*Dp + R + sy0 - strseqtr;
+      
+			res = fabs(kp)/G;
+
+			if(it==1||res<res0){
+				res0=res;
+				cp =  - kp/(3.*G+dR);
+				tmp1 = 0.99*(DP_MIN-Dp);
+				if(cp<tmp1) {
+					//printf("new Dp below Dpmin : correction!\n");
+					cp=tmp1;
+				}
+				Dp+=cp;
+			}
+			else{
+				//printf("residual is not decreasing: correction!\n");
+				cp=cp/2.;
+				Dp=Dp-cp;
+				res0=res;
+			}
+
+			//printf("j2plast iteration: %d, res: %.10e, p: %.10e\n",it,res,*p);
+		}
+		//printf("Number of iterations in radial return algorithm: %d\n",it); 
+		strseq = sy0 + R;
+
+		addtens2(1., strstr,-2.*G*(Dp), Ntr, strs);
+		h=(3.*G) + dR;
+		
+		addtens2(1.,pstrn_n, Dp, Ntr, pstrn);
+
+		h3 = h*h*h;
+		tmp1 = 4.*G*G/h;
+		tmp2 = 4.*G*G*(*p-p_n)/strseqtr;
+
+		addtens4(1.,Cel,(-tmp1+tmp2),NoN, Calgo);
+		addtens4(1.,Calgo,-1.5*tmp2,Idev,Calgo);
+
+		addtens4(1.5,Idev,-1.,NoN,mat1);
+		for(i=0;i<6;i++){
+			for(j=0;j<6;j++){
+				for(k=0;k<6;k++){
+					dCalgo[i][j][k] = (8.*G3*ddR/h3)*NoN[i][j]*Ntr[k] - (16.*G3/(h*strseqtr))*Ntr[i]*mat1[j][k] - mat1[i][j]*8.*G3*Ntr[k]*((1./(h*strseqtr))-(Dp/(strseqtr*strseqtr))) + (16.*G3*Dp/(strseqtr*strseqtr))*Ntr[i]*mat1[j][k];
+				}
+			}
+		}
+
+       //***** By Wu Ling 06/04/2011************************************************************************************
+       //compute dpdE  accumulate plastice strain p derivative w.r.t. strain increment
+
+       addtens2((2.*G/h), Ntr, 0, Ntr, dpdE);
+
+
+       //******* By Wu Ling 06/04/2011**********************************************************************************
+
+
+	} //end case plastic correction
+
+
+	//compute isoJ2 tangent operator and its derivative w.r.t. strain increment
+	if(Dp<DP_MIN){		//that is, Dp=0 	
+		mu_iso=G;
+		for(i=0;i<6;i++){
+			dtwomu_iso[i]=0.;
+		}
+	}
+		
+	else {
+		mu_iso = G*(1.-(3.*G/h));
+		for(i=0;i<6;i++){
+			dtwomu_iso[i] = 12.*pow(G/h,3)*ddR*Ntr[i];
+		}
+	}
+  
+	*twomu_iso = 2.*mu_iso;
+
+//      no free as initialized once        
+//     	freematrix(Cel, 6);
+//	freematrix(Idev,6);
+//	freematrix(NoN,6);
+//	freematrix(mat1,6);
+        if(!stay) return(1); //no convergence
 	return(0);
 }
 
+
+
+
+
 //PRESSURE SENSITIVE ELASTO-PLASTIC CONSTITUTIVE BOX
 int constbox_ep(double E, double nu, double sy0, int htype, double hmod1, double hmod2, double hp0, double alpha_DP, double m_DP, double nup, double hexp, double *dstrn, double *strs_n, double *strs, double* pstrn_n, double* pstrn, double p_n, double *p, double *twomu_iso, double* dtwomu_iso, double *twok_iso, double* dtwok_iso, double** Calgo, double*** dCalgo, double* dpdE, bool residual)
 {
-  return (0);
+	int i,j,k,it,error;
+	double strseqtr, trstrstr,strseqtrNor0;       	//Variables for the elastic prediction 
+	double R, dR, ddR, strseq, G, kappa_el, dkp_dDp, dDp_dGamma, dkp_dGamma, Deriv_kp;    //Variables for the correction phase 
+	double kp;
+	double beta;
+	double Dp, DGAMMA_MIN, Gamma, phitr, phires;           
+	double h, tmp1, tmp2, ka, NR1_prime_eq, NR2_prime, NR1_eq, NR2;
+	double cGamma=0.;
+	double tol = 1.e-8;    //tolerance on the residual 
+	double res, res0;    		 //residual
+	double mu_iso, k_iso;
+	double G3, h3;
+        double sq2;
+	
+        sq2 = sqrt(2.);
+	R=0.;
+	dR=0.;
+	ddR=0.;
+
+	G = E/(2.*(1.+nu));  
+	kappa_el = E/(3.*(1.-(2.*nu)));
+        ka = 1./sqrt(1.+2.*pow(nup,2));
+	G3 = G*G*G;
+        beta = (9.-18.*nup)/(2.*nup+2.);
+        static bool initialized=false;
+        // initialize only once
+	static double **Cel=NULL;
+	static double **tmp_tens4=NULL;
+	static double **tmp_tens42=NULL;
+	static double **NoN=NULL;
+	static double **Idev=NULL;
+	static double **Ivol=NULL;
+	static double **mat1=NULL;
+	static double *Identity=NULL;
+	static double *tmp_tens2=NULL;
+	static double *tmp_tens22=NULL;
+	static double *dkp_dE=NULL;
+	static double *dGamma_dEr=NULL;
+	static double *NR1_prime=NULL;
+	static double *NR1=NULL;
+	static double *NR1_dev=NULL;
+	static double *NR1_prime_dev=NULL;
+	static double *strstr=NULL;
+	static double *StrVol=NULL;
+	static double *Str=NULL;              
+	static double *StrVoltmp=NULL;
+	static double *Strtmp=NULL;              
+	static double *Ntr=NULL;              
+	static double *Stau=NULL;
+	static double *dstrs=NULL;
+        static double *strstrNor0=NULL;      
+        bool stay=true;
+        if(!initialized)
+        {
+          mallocmatrix(&Cel, 6, 6);
+          mallocmatrix(&tmp_tens4, 6, 6);
+          mallocmatrix(&tmp_tens42, 6, 6);
+	  mallocmatrix(&NoN,6,6);
+	  mallocmatrix(&Idev,6,6);
+	  mallocmatrix(&Ivol,6,6);
+	  mallocmatrix(&mat1,6,6);
+          mallocvector(&Identity,6);
+          mallocvector(&tmp_tens2,6);
+          mallocvector(&tmp_tens22,6);
+          mallocvector(&dkp_dE,6);
+          mallocvector(&dGamma_dEr,6);
+          mallocvector(&NR1_prime,6);
+          mallocvector(&NR1,6);
+          mallocvector(&NR1_dev,6);
+          mallocvector(&NR1_prime_dev,6);
+          mallocvector(&strstr,6);
+          mallocvector(&StrVol,6);
+          mallocvector(&Str,6);
+          mallocvector(&StrVoltmp,6);
+          mallocvector(&Strtmp,6);
+          mallocvector(&Ntr,6);
+          mallocvector(&Stau,6);
+          mallocvector(&dstrs,6);
+          mallocvector(&strstrNor0,6);
+          initialized = true;
+        }
+        cleartens4(Cel);
+        cleartens4(tmp_tens4);
+        cleartens4(tmp_tens42);
+        cleartens4(NoN);
+	cleartens4(Idev);
+	cleartens4(Ivol);
+	cleartens4(mat1);
+        cleartens2(Identity);
+        cleartens2(tmp_tens2);
+        cleartens2(tmp_tens22);
+        cleartens2(dkp_dE);
+        cleartens2(dGamma_dEr);
+        cleartens2(NR1_prime);
+        cleartens2(NR1);
+        cleartens2(NR1_dev);
+        cleartens2(NR1_prime_dev);
+        cleartens2(strstr);
+        cleartens2(StrVol);
+        cleartens2(Str);
+        cleartens2(Ntr);
+        cleartens2(Stau);
+        cleartens2(dstrs);
+        cleartens2(strstrNor0);
+	//deviatoric operator and Identity
+	for(i=0;i<3;i++){
+	  for(j=0;j<3;j++){
+	    Idev[i][j]=-1./3.;
+            Ivol[i][j]=1./3.;
+          }
+	  Idev[i][i]+=1.;
+	  Idev[i+3][i+3]=1.;
+          Identity[i]=1.;
+	}
+	//reset tangent operators to zero
+	for(i=0;i<6;i++){
+		for(j=0;j<6;j++){
+			Calgo[i][j]=0.;
+		}
+	}
+
+	//elastic predictor
+	compute_Hooke(E,nu,Cel);
+
+	//compute trial stress
+	contraction42(Cel, dstrn, dstrs);
+
+	addtens2(1., strs_n, 1., dstrs, strstr);
+	strseqtr = vonmises(strstr);
+        strseqtrNor0 = vonmises(dstrs);  
+	//normal to the yield surface
+        if(!residual)
+        {
+  	  dev(strstr, Str); 
+          addtens2(1./3.*trace(strstr),Identity,0.,Identity,StrVol);
+  	  if(strseqtr > 0){
+		addtens2(3., Str, 2.*beta/3., StrVol, Ntr); 
+		produit_tensoriel(Ntr,Ntr,NoN); 
+
+	  }
+        }
+        else
+        {
+          dev(dstrs, Str);
+          addtens2(1./3.*trace(dstrs),Identity,0.,Identity,StrVol);
+          if(strseqtrNor0 > 0){
+                addtens2(3., Str, 2.*beta/3., StrVol, Ntr);
+		produit_tensoriel(Ntr,Ntr,NoN);
+          }
+        }
+	//elastic increment
+	Dp=DP_MIN;
+        DGAMMA_MIN = DP_MIN/100.;
+	j2hard (p_n+Dp, sy0, htype, hmod1, hmod2, hp0, hexp, &R, &dR,&ddR);
+	strseq= sy0 + R;
+        phitr = 1./3.*trace(strstr);
+
+        kp = pow(strseqtr,alpha_DP)/pow(strseq,alpha_DP)-3.*(pow(m_DP,alpha_DP)-1.)/((m_DP+1.)*strseq)*phitr - (pow(m_DP,alpha_DP)+m_DP)/(m_DP+1.);
+
+
+	if(kp<=0.){
+		//printf("elastic: !");
+		copyvect(strstr, strs, 6);
+		copyvect(pstrn_n, pstrn,6);
+    		*p = p_n;
+		Dp=0.;
+		copymatr(Cel,Calgo,6,6);
+		for(i=0;i<6;i++){
+			for(j=0;j<6;j++){
+				for(k=0;k<6;k++){
+					dCalgo[i][j][k]=0.;
+				}
+			}
+		}
+       //***** By Juan Manuel Calleja 12/2020************************************************************************************
+       //compute dpdE  accumulate plastic strain p derivative w.r.t. strain increment
+
+       cleartens2(dpdE);
+
+
+
 
+       //******* By Juan Manuel Calleja 12/2020**********************************************************************************
+
+	}
+	//Plastic correction: return mapping algorithm 
+	else{
+	  Gamma = DGAMMA_MIN; 
+
+		it=0;
+		res=1.;
+		res0=res;
+		*p=p_n;
+		while(res>tol && stay){
+		  if(it>20)
+  		          printf("Return mapping algorithm, p: %.10e, Gamma: %.10e, res: %.10e\n",*p, Gamma, res);
+			it++;
+			if(it>200){
+				printf("no convergence in return mapping algorithm, p: %lf\n",*p);
+				stay=false;
+                                //Gamma +=0.5 ;
+				//return(1);
+			}
+
+			if(!residual)
+			{
+                                phires = 0.;
+				addtens2(1./(1.+6.*G*(Gamma)),strstr,0.,strs_n,NR1_prime);
+				//dev(NR1_prime, NR1_prime_dev);
+				dev(strstr, NR1_prime_dev);
+				addtens2(1./(1.+6.*G*(Gamma)),NR1_prime_dev,0.,strs_n,NR1_prime_dev);
+                               	NR1_prime_eq = vonmises(NR1_prime);
+                                NR2_prime = phitr/(1.+2.*kappa_el*(Gamma)*beta);
+			}
+			else
+			{
+                                phires = 1./3.*trace(strs_n);
+				addtens2(1./(1.+6.*G*(Gamma)),dstrs,0.,strs_n,NR1_prime);
+                                //dev(NR1_prime, NR1_prime_dev);
+                                dev(dstrs, NR1_prime_dev);
+				addtens2(1./(1.+6.*G*(Gamma)),NR1_prime_dev,0.,strs_n,NR1_prime_dev);
+                               	NR1_prime_eq = vonmises(NR1_prime);
+                                NR2_prime = (phitr-phires)/(1.+2.*kappa_el*(Gamma)*beta);     
+			}
+
+		        Dp = ka*(Gamma)*sqrt(6.*pow(NR1_prime_eq,2.)+4.*pow(beta,2.)/3.*pow(NR2_prime,2.));
+
+                        *p = p_n+Dp;
+
+			j2hard (*p, sy0, htype, hmod1, hmod2, hp0, hexp, &R, &dR,&ddR);
+                        strseq = sy0 + R;
+      
+
+
+			if(!residual)
+			{
+				addtens2(1./(1.+6.*G*(Gamma)),strstr,0.,strstr,NR1);
+                                NR1_eq = vonmises(NR1);
+				NR2 = phitr/(1.+2.*kappa_el*(Gamma)*beta);
+			}
+			else
+			{
+				addtens2(1./(1.+6.*G*(Gamma)),dstrs,1.,strs_n,NR1);
+                                NR1_eq = vonmises(NR1);
+				NR2 = (phitr-phires)/(1.+2.*kappa_el*(Gamma)*beta)+phires;
+			}
+
+                        tmp1 = pow(NR1_eq,alpha_DP)/pow(strseq,alpha_DP)-3.*NR2*(pow(m_DP,alpha_DP)-1.)/((m_DP+1.)*strseq);
+		        kp = tmp1 - (pow(m_DP,alpha_DP)+m_DP)/(m_DP+1.);
+
+			res = fabs(kp); 
+                        
+			
+			if(it==1 || res<res0){
+				res0=res;
+
+                                dkp_dDp = -pow(NR1_eq,alpha_DP)*alpha_DP/pow(strseq,alpha_DP+1.)*dR+3.*(pow(m_DP,alpha_DP)-1.)/((m_DP+1.)*pow(strseq,2.))*dR*NR2;
+
+				if(!residual)
+				{
+                                	tmp1 = 72.*G*pow(strseqtr,2.)/pow(1.+6.*G*(Gamma),3.)+16.*pow(beta,3.)*kappa_el/3.*pow(phitr,2.)/pow(1.+2.*kappa_el*(Gamma)*beta,3.);
+				}
+				else
+				{
+                                      	tmp1 = 72.*G*pow(strseqtrNor0,2.)/pow(1.+6.*G*(Gamma),3.)+16.*pow(beta,3.)*kappa_el/3.*pow(phitr-phires,2.)/pow(1.+2.*kappa_el*(Gamma)*beta,3.);
+				}
+                                dDp_dGamma = ka*sqrt(6.*pow(NR1_prime_eq,2.)+4.*pow(beta,2.)/3.*pow(NR2_prime,2.))-ka*(Gamma)/(2.*sqrt(6.*pow(NR1_prime_eq,2.)+4.*pow(beta,2.)/3.*pow(NR2_prime,2.)))*tmp1;
+                                dev(NR1,NR1_dev);
+                                dkp_dGamma = -alpha_DP*pow(NR1_eq/strseq,alpha_DP-1.)*(9.*G*contraction22(Str,NR1_dev))/(strseq*pow(1.+6.*G*(Gamma),2.)*NR1_eq)+3.*(pow(m_DP,alpha_DP)-1.)/((m_DP+1.)*strseq)*(1./3.*trace(StrVol)/pow(1.+2.*kappa_el*(Gamma)*beta,2.)*2.*kappa_el*beta);
+				
+				Deriv_kp = dkp_dDp*dDp_dGamma+dkp_dGamma;
+				cGamma =  - kp/Deriv_kp; // -kp / derivative of kp w.r.t. dp. Newton-Raphson correction.
+
+				tmp1 = 0.99*(DGAMMA_MIN-Gamma);
+				if(cGamma<tmp1) {
+					printf("new Dp below DGAMMA_MIN : correction!\n");
+					cGamma=tmp1;
+				}
+				Gamma+=cGamma;
+			}
+			else{
+			  res0=res;
+			  printf("residual is not decreasing: correction!\n");
+ 	     	          cGamma=0.5*cGamma;
+			  Gamma-=cGamma; 
+			}
+
+			//printf("j2plast iteration: %d, res: %.10e, p: %.10e\n",it,res,*p);
+		}
+		//printf("Number of iterations in radial return algorithm: %d\n",it); 
+		strseq = sy0 + R;
+
+                addtens2(1./(1.+6.*G*Gamma),Str, 0., Str, Strtmp);
+                addtens2(1./(1.+(2.*kappa_el*Gamma*beta)),StrVol, 0., StrVol, StrVoltmp);
+
+
+                addtens2(1.,Strtmp, 1., StrVoltmp, strs);
+                if(residual)
+		{
+                        addtens2(1.,strs, 1., strs_n, strs);       
+		}
+
+		//addtens2(1.,pstrn_n, 3.*Gamma, NR1_prime, pstrn);
+                addtens2(1.,pstrn_n, 3.*Gamma, NR1_prime_dev, pstrn);
+		addtens2(1.,pstrn, 2.*beta/3.*Gamma*NR2_prime, Identity, pstrn);
+
+
+		
+                //Computation of Calgo
+
+                contraction44(Idev,Cel,tmp_tens4); //ORDER 4
+                addtens4(1./(1.+6.*G*(Gamma)),tmp_tens4,0.,tmp_tens4,tmp_tens4); //ORDER 4
+                contraction42(tmp_tens4,NR1_dev,tmp_tens2); //ORDER 2
+                addtens2(3./2.*alpha_DP * (pow(NR1_eq,alpha_DP-1.)/NR1_eq),tmp_tens2,0.,tmp_tens2,tmp_tens2); //ORDER 2 58.1
+              
+                addtens2(kappa_el/(1.+2.*kappa_el*(Gamma)*beta),Identity,0.,Identity,tmp_tens22);  //ORDER 2 58.2
+
+                addtens2(1/pow(strseq,alpha_DP),tmp_tens2,-3.*(pow(m_DP,alpha_DP)-1.)/((m_DP+1.)*strseq),tmp_tens22, dkp_dE); //ORDER 2 57
+
+                addtens2(-1./Deriv_kp,dkp_dE,0.,dkp_dE,dGamma_dEr); //ORDER 2 56
+  
+
+
+                //*************************************************************
+                addtens2(1.+6.*G*(Gamma),dGamma_dEr,-6.*G*(Gamma),dGamma_dEr,tmp_tens2); //ORDER 2
+                addtens2(1./pow(1.+6.*G*(Gamma),2.),tmp_tens2,0.,tmp_tens2,tmp_tens2); //ORDER 2
+                produit_tensoriel(Str,tmp_tens2,tmp_tens4); //ORDER 4
+
+                addtens2(1.+2.*kappa_el*beta*(Gamma),dGamma_dEr,-2.*kappa_el*beta*(Gamma),dGamma_dEr,tmp_tens2); //ORDER 2
+                addtens2(1./pow(1.+2.*kappa_el*beta*(Gamma),2.),tmp_tens2,0.,tmp_tens2,tmp_tens2); //ORDER 2
+                produit_tensoriel(StrVol,tmp_tens2,tmp_tens42); //ORDER 4
+ 
+                addtens4(2.*G*(Gamma)/(1.+6.*G*(Gamma)),Idev,1.,tmp_tens4,tmp_tens4); //ORDER 4
+                addtens4(3.*kappa_el*(Gamma)/(1.+2.*beta*kappa_el*(Gamma)),Ivol,1.,tmp_tens42,tmp_tens42); //ORDER 4
+                //************************************************************
+                addtens4(1.,Cel,-6.*G,tmp_tens4,Calgo);
+                addtens4(1.,Calgo,-2.*kappa_el*beta,tmp_tens42,Calgo);
+
+       //*****************************************************************************************
+       //compute dpdE  accumulate plastice strain p derivative w.r.t. strain increment
+
+       addtens2(dDp_dGamma,dGamma_dEr, 0., dGamma_dEr, dpdE); //ORDER 2 
+       
+
+       //*****************************************************************************************
+
+
+	} //end case plastic correction
+
+
+	//compute isoJ2 tangent operator and its derivative w.r.t. strain increment
+	if(Dp<DP_MIN){		//that is, Dp=0 	
+		mu_iso=G;
+                k_iso=kappa_el;
+		for(i=0;i<6;i++){
+			dtwomu_iso[i]=0.;
+                        dtwok_iso[i]=0.;
+		}
+	}
+		
+	else {
+		mu_iso = G*(1-(6.*G*Gamma)/(1.+6.*G*Gamma));
+                k_iso= kappa_el*(1.-(2.*beta*kappa_el*Gamma)/(1.+2.*beta*kappa_el*Gamma));
+                addtens2(-6.*pow(G,2.)/pow(1.+6.*G*Gamma,2.),dGamma_dEr,0.,dGamma_dEr,dtwok_iso);
+                addtens2(-2.*beta*pow(kappa_el,2.)/pow(1.+2.*kappa_el*Gamma*beta,2.),dGamma_dEr,0.,dGamma_dEr,dtwok_iso);
+	}
+  
+	*twomu_iso = 2.*mu_iso;
+        *twok_iso = 2.*k_iso;
+
+//      no free as initialized once        
+//     	freematrix(Cel, 6);
+//	freematrix(Idev,6);
+//	freematrix(NoN,6);
+//	freematrix(mat1,6);
+        if(!stay) return(1); //no convergence
+	return(0);
+}
+
+
+//****************************************************
+/**********J2 plasticity for large deformation***/
+//******************************************************
+int constbox_ep(double E, double nu, double sy0, int htype, double hmod1, double hmod2, double hp0, double hexp, double *strstr, double *Rstrs_n, double *strs, double* pstrn_n, double* pstrn, double p_n, double *p,  double** Calgo, double*** dCalgo, double* dpdE, bool residual)
+
+{
+	int i,j,k,it,error;
+	double strseqtr,strseqtr0, trstrstr;       	//Variables for the elastic prediction 
+	double R, dR, ddR, strseq, G;    //Variables for the correction phase 
+	double kp;
+	double Dp;  
+	double h, tmp1, tmp2;
+	double cp=0.;
+	double tol = 1.e-12;    //tolerance on the residual 
+	double res, res0;    		 //residual 
+	double mu_iso, k_iso;
+	double G3, h3;
+        double sq2;
+
+        sq2 = sqrt(2.);
+	R=0.;
+	dR=0.;
+	ddR=0.;
+
+	G = E/(2.*(1.+nu));  
+	k_iso = E/(3.*(1.-(2.*nu)));
+	G3 = G*G*G;
+
+        static bool initialized=false;
+        // initialize only once!
+	static double **Cel;
+	static double **NoN;
+	static double **Idev;
+	static double **mat1;
+	static double *strstrNor0=NULL;              //used to compute the modified normal
+	static double *Str=NULL;              //used to compute the modified normal
+	static double *Ntr=NULL;              //used to compute the modified normal
+	static double *Stau=NULL;
+	static double *dstrs=NULL;
+        bool stay=true;
+
+        if(!initialized)
+        {
+          mallocmatrix(&Cel, 6, 6);
+	  mallocmatrix(&NoN,6,6);
+	  mallocmatrix(&Idev,6,6);
+	  mallocmatrix(&mat1,6,6);
+          mallocvector(&strstrNor0,6);
+          mallocvector(&Str,6);
+          mallocvector(&Ntr,6);
+          mallocvector(&Stau,6);
+          mallocvector(&dstrs,6);
+          initialized = true;
+        }
+        cleartens4(Cel);
+        cleartens4(NoN);
+	cleartens4(Idev);
+	cleartens4(mat1);
+        cleartens2(strstrNor0);
+        cleartens2(Str);
+        cleartens2(Ntr);
+        cleartens2(Stau);
+        cleartens2(dstrs);
+	//deviatoric operator
+	for(i=0;i<3;i++){
+	  for(j=0;j<3;j++){
+	    Idev[i][j]=-1./3.;
+          }
+	  Idev[i][i]+=1.;
+	  Idev[i+3][i+3]=1.;
+	}
+	//reset tangent operators to zero
+	for(i=0;i<6;i++){
+		for(j=0;j<6;j++){
+			Calgo[i][j]=0.;
+		}
+	}
+
+	
+	strseqtr = vonmises(strstr);
+  
+	//normal to the yield surface
+        //dev(strstr, Str);
+  
+        //normal to the residual stress
+        addtens2(1.0, strstr, -1.0, Rstrs_n, strstrNor0);
+	dev(strstrNor0, Str);
+	strseqtr0 = vonmises(strstrNor0);
+
+	if(strseqtr > 0.){
+		addtens2(1.5/strseqtr0, Str, 0., Str, Ntr);
+		produit_tensoriel(Ntr,Ntr,NoN);
+	}
+
+
+	//elastic increment
+	Dp=DP_MIN;
+	j2hard (p_n+Dp, sy0, htype, hmod1, hmod2, hp0, hexp, &R, &dR,&ddR);
+	strseq= sy0 + R;
+	h = (3.*G) + dR;
+	kp = strseq + 3.*G*Dp - strseqtr;
+
+	if(kp>=0.){
+		//printf("elastic: !");
+		copyvect(strstr, strs, 6);
+		copyvect(pstrn_n, pstrn,6);
+    		*p = p_n;
+		Dp=0.;
+		copymatr(Cel,Calgo,6,6);
+		for(i=0;i<6;i++){
+			for(j=0;j<6;j++){
+				for(k=0;k<6;k++){
+					dCalgo[i][j][k]=0.;
+				}
+			}
+		}
+      //***** By Wu Ling 06/04/2011************************************************************************************
+       //compute dpdE  accumulate plastice strain p derivative w.r.t. strain increment
+
+       cleartens2(dpdE);
+
+
+       //******* By Wu Ling 06/04/2011**********************************************************************************
+
+	}
+	//Plastic correction: return mapping algorithm 
+	else{
+		Dp = fmax(DP_MIN,-kp/h);  //correction must be such that Dp >= DP_MIN
+
+		it=0;
+		res=1.;
+		res0=res;
+		while(res>tol && stay){
+		
+			it++;
+			if(it>20){
+				printf("no convergence in return mapping algorithm, p: %lf\n",*p);
+				stay=false;
+                                Dp=1.;
+
+				//return(1);
+			}
+
+			*p=p_n+Dp;
+			j2hard (*p, sy0, htype, hmod1, hmod2, hp0, hexp, &R, &dR,&ddR);
+			kp = 3.*G*Dp + R + sy0 - strseqtr;
+      
+			res = fabs(kp)/G;
+
+			if(it==1||res<res0){
+				res0=res;
+				cp =  - kp/(3.*G+dR);
+				tmp1 = 0.99*(DP_MIN-Dp);
+				if(cp<tmp1) {
+					//printf("new Dp below Dpmin : correction!\n");
+					cp=tmp1;
+				}
+				Dp+=cp;
+			}
+			else{
+				//printf("residual is not decreasing: correction!\n");
+				cp=cp/2.;
+				Dp=Dp-cp;
+				res0=res;
+			    
+			}
+
+			//printf("j2plast iteration: %d, res: %.10e, p: %.10e\n",it,res,*p);
+		}
+		//printf("Number of iterations in radial return algorithm: %d\n",it); 
+		strseq = sy0 + R;
+
+		addtens2(1., strstr,-2.*G*(Dp), Ntr, strs);
+		h=(3.*G) + dR;
+		
+		addtens2(1.,pstrn_n, Dp, Ntr, pstrn);
+
+		h3 = h*h*h;
+		tmp1 = 4.*G*G/h;
+		tmp2 = 4.*G*G*(*p-p_n)/strseqtr0;
+
+		addtens4(1.,Cel,(-tmp1+tmp2),NoN, Calgo);
+		addtens4(1.,Calgo,-1.5*tmp2,Idev,Calgo);
+
+		addtens4(1.5,Idev,-1.,NoN,mat1);
+		for(i=0;i<6;i++){
+			for(j=0;j<6;j++){
+				for(k=0;k<6;k++){
+					dCalgo[i][j][k] = (8.*G3*ddR/h3)*NoN[i][j]*Ntr[k] - (16.*G3/(h*strseqtr0))*Ntr[i]*mat1[j][k] - mat1[i][j]*8.*G3*Ntr[k]*((1./(h*strseqtr0))-(Dp/(strseqtr*strseqtr0))) + (16.*G3*Dp/(strseqtr0*strseqtr0))*Ntr[i]*mat1[j][k];
+				}
+			}
+		}
+
+       //***** By Wu Ling 06/04/2011************************************************************************************
+       //compute dpdE  accumulate plastice strain p derivative w.r.t. strain increment
+
+       addtens2((2.*G/h), Ntr, 0., Ntr, dpdE);
+
+
+	} //end case plastic correction
+
+
+        if(!stay) return(1); //no convergence
+	return(0);
 }
 
 //end elastoPlastic for large deformation
@@ -54,6 +1098,287 @@ int constbox_ep(double E, double nu, double sy0, int htype, double hmod1, double
 // EVALUATION OF THE HARDENING FUNCTION 
 void j2hard (double p, double sy0, int htype, double hmod1, double hmod2, double hp0, double hexp, double* R, double* dR, double* ddR){
 
+	double tmp;
+
+	//Perfect plasticity
+	if(hmod1 == 0){
+		
+		*R = 0.;
+		*dR = 0.;
+		*ddR = 0.;
+		return;
+
+	}
+
+	switch(htype) {
+	
+	//POWER LAW HARDENING
+	case H_POW:
+		if(p<DP_MIN){
+			printf("Should not be here: p: %.10e\n",p);
+			*R=0.;
+			if(hexp<1.0){
+				*dR = 1e20;
+				*ddR = -1e20;
+			}
+			else{
+				*dR = hmod1;
+				*ddR = 0.;
+			}		
+		}	
+		else{
+			*R=hmod1*pow(p,hexp);
+			*dR = (*R)*hexp/p;
+			*ddR = (*dR)*(hexp-1.)/p;
+		}
+
+		break;	
+	//POWER LAW HARDENING FOR DRUCKER PRAGER
+	case H_POW_DP:
+		if(p<DP_MIN){
+			printf("Should not be here: p: %.10e\n",p);
+			*R=0.;
+			if(hexp<1.0){
+				*dR = 1e20;
+				*ddR = -1e20;
+			}
+			else{
+				*dR = hmod1;
+				*ddR = 0.;
+			}		
+		}	
+		else{
+			*R=hmod1*pow(p,hexp);
+			*dR = (*R)*hexp/p;
+			*ddR = (*dR)*(hexp-1.)/p;
+		}
+
+		break;	
+			
+	//EXPONENTIAL HARDENING
+	case H_EXP:
+	
+		if(p<DP_MIN){
+			printf("Should not be here: p: %.10e\n",p);
+			*R=0.;
+			*dR = hmod1*hexp;
+			*ddR = -hexp*(*dR);
+		} 
+		else{
+			tmp = exp(-hexp*p);
+			*R = hmod1*(1.-tmp);
+			*dR = hmod1*hexp*tmp;
+			*ddR = -hexp*(*dR);
+		}
+		break;
+
+
+
+	//EXPONENTIAL HARDENING FOR DRUCKER PRAGER
+	case H_EXP_DP:
+	
+		if(p<DP_MIN){
+			printf("Should not be here: p: %.10e\n",p);
+			*R=0.;
+			*dR = hmod1*hexp;
+			*ddR = -hexp*(*dR);
+		} 
+		else{
+			tmp = exp(-hexp*p);
+			*R = hmod1*(1.-tmp);
+			*dR = hmod1*hexp*tmp;
+			*ddR = -hexp*(*dR);
+		}
+		break;
+
+	
+	//SWIFT LAW
+	case H_SWIFT:
+		if(p<DP_MIN){
+			printf("Should not be here: p: %.10e\n",p);
+			*R=0.;
+			*dR = sy0*hmod1*hexp;
+			*ddR = (*dR)*(hexp-1.)*hmod1;
+		}
+		else{
+			tmp = 1.+hmod1*p;
+			*R = sy0*pow(tmp,hexp) - sy0;
+			tmp = hmod1/tmp;
+			*dR = (*R)*hexp*tmp;
+			*ddR = (*dR)*(hexp-1.)*tmp;
+		}
+		break;
+
+	//SWIFT LAW FOR DRUCKER PRAGER
+	case H_SWIFT_DP:
+		if(p<DP_MIN){
+			printf("Should not be here: p: %.10e\n",p);
+			*R=0.;
+			*dR = sy0*hmod1*hexp;
+			*ddR = (*dR)*(hexp-1.)*hmod1;
+		}
+		else{
+			tmp = 1.+hmod1*p;
+			*R = sy0*pow(tmp,hexp) - sy0;
+			tmp = hmod1/tmp;
+			*dR = (*R)*hexp*tmp;
+			*ddR = (*dR)*(hexp-1.)*tmp;
+		}
+		break;
+
+	//LINEAR-EXPONENTIAL HARDENING
+	case H_LINEXP:
+	
+		if(p<DP_MIN){
+			printf("Should not be here: p: %.10e\n",p);
+			*R = 0;
+			*dR = hmod1 + hmod2*hexp;
+			*ddR = -hmod2*hexp*hexp;
+		}
+		else{
+			tmp = exp(-hexp*p);
+			*R = hmod1*p + hmod2*(1.-tmp);
+			*dR = hmod1 + hmod2*hexp*tmp;
+			*ddR = - hmod2*hexp*hexp*tmp; 
+		}
+		break;
+
+	//LINEAR-EXPONENTIAL HARDENING FOR DRUCKER PRAGER
+	case H_LINEXP_DP:
+	
+		if(p<DP_MIN){
+			printf("Should not be here: p: %.10e\n",p);
+			*R = 0;
+			*dR = hmod1 + hmod2*hexp;
+			*ddR = -hmod2*hexp*hexp;
+		}
+		else{
+			tmp = exp(-hexp*p);
+			*R = hmod1*p + hmod2*(1.-tmp);
+			*dR = hmod1 + hmod2*hexp*tmp;
+			*ddR = - hmod2*hexp*hexp*tmp; 
+		}
+		break;
+
+	//POWER LAW HARDENING EXTRAPOLATED AFTER 16% DEFO TO MIMIC DIGIMAT TO ABAQUS
+	case H_POW_EXTRAPOL:
+		if(p<DP_MIN){
+			printf("Should not be here: p: %.10e\n",p);
+			*R=0.;
+			if(hmod1<1){
+				*dR = 1e20;
+				*ddR = -1e20;
+			}
+			else{
+				*dR = hmod1;
+				*ddR = 0.;
+			}		
+		}	
+		else if(p<hp0)
+                {
+			*R=hmod1*pow(p,hexp);
+			*dR = (*R)*hexp/p;
+			*ddR = (*dR)*(hexp-1.)/p;
+		}
+		else if(p<10.*hp0)
+                {
+			*R=hmod1*pow(hp0,hexp)+hmod2*(p-hp0);
+			*dR = hmod2;
+			*ddR = 0.;
+		}
+		else
+		{
+                       *R=hmod1*pow(hp0,hexp)+hmod2*(10.*hp0-hp0)+hmod2*(p-10.*hp0)/1000.;
+                       *dR = hmod2/1000.;
+                       *ddR = 0.;
+ 
+		}
+
+		break;	
+
+	//POWER LAW HARDENING EXTRAPOLATED AFTER 16% DEFO TO MIMIC DIGIMAT TO ABAQUS DRUCKER PRAGER
+	case H_POW_EXTRAPOL_DP:
+		if(p<DP_MIN){
+			printf("Should not be here: p: %.10e\n",p);
+			*R=0.;
+			if(hmod1<1){
+				*dR = 1e20;
+				*ddR = -1e20;
+			}
+			else{
+				*dR = hmod1;
+				*ddR = 0.;
+			}		
+		}	
+		else if(p<hp0)
+                {
+			*R=hmod1*pow(p,hexp);
+			*dR = (*R)*hexp/p;
+			*ddR = (*dR)*(hexp-1.)/p;
+		}
+		else if(p<10.*hp0)
+                {
+			*R=hmod1*pow(hp0,hexp)+hmod2*(p-hp0);
+			*dR = hmod2;
+			*ddR = 0.;
+		}
+		else
+		{
+                       *R=hmod1*pow(hp0,hexp)+hmod2*(10.*hp0-hp0)+hmod2*(p-10.*hp0)/1000.;
+                       *dR = hmod2/1000.;
+                       *ddR = 0.;
+ 
+		}
+
+		break;	
+      
+        //POWER EXPONENTIAL HARDENING
+	case H_POW_EXP:	
+		if(p<DP_MIN){
+                        *R = 0.0;
+                        *dR = 0.0;
+			if(hmod2<1.0){
+				*ddR = 1e20;
+			}
+			else{
+				*ddR = 0.;
+			}
+		}
+		else{
+			tmp = exp(-hexp*p);
+			*R = hmod1*pow(p,hmod2)*(1.-tmp);
+			*dR = hmod2*hmod1*pow(p,hmod2-1.)*(1.-tmp) + hexp*hmod1*pow(p,hmod2)*tmp;
+			*ddR = hmod2*(hmod2-1.0)*hmod1*pow(p,hmod2-2.)*(1.-tmp) + 2.0*hmod2*hexp*hmod1*pow(p,hmod2-1.0)*tmp - hexp*hexp*hmod1*pow(p,hmod2)*tmp; 
+		}
+		break;
+
+        //POWER EXPONENTIAL HARDENING FOR DRUCKER PRAGAER
+	case H_POW_EXP_DP:	
+		if(p<DP_MIN){
+                        *R = 0.0;
+                        *dR = 0.0;
+			if(hmod2<1.0){
+				*ddR = 1e20;
+			}
+			else{
+				*ddR = 0.;
+			}
+		}
+		else{
+			tmp = exp(-hexp*p);
+			*R = hmod1*pow(p,hmod2)*(1.-tmp);
+			*dR = hmod2*hmod1*pow(p,hmod2-1.)*(1.-tmp) + hexp*hmod1*pow(p,hmod2)*tmp;
+			*ddR = hmod2*(hmod2-1.0)*hmod1*pow(p,hmod2-2.)*(1.-tmp) + 2.0*hmod2*hexp*hmod1*pow(p,hmod2-1.0)*tmp - hexp*hexp*hmod1*pow(p,hmod2)*tmp; 
+		}
+		break;
+	
+	default:
+		printf("Bad choice of hardening law in j2hard: %d\n",htype);
+		break;
+		
+	}
+
+	//printf("p: %lf\t, R: %.10e, \t dR: %.10e \t, ddR: %.10e \n",p, *R,*dRdp,*ddRdp);
  
 }
 
@@ -61,9 +1386,79 @@ void j2hard (double p, double sy0, int htype, double hmod1, double hmod2, double
  * COMPUTATION OF ALGORITHMIC TANGENT OPERATOR
  * FROM STATE VARIABLES 
  * ********************************************/
-void algoJ2(double E, double nu, double sy0, int htype, double hmod1, double hmod2,  double hp0, double hexp, 
+void algoJ2(double E, double nu, double sy0, int htype, double hmod1, double hmod2, double hp0, double hexp, 
 	double* strs, double p, double dp, double** Calgo){
 
+	int i,j;
+	double seqtr;
+	double R,dR,ddR;
+	double mu;
+	static double *N=NULL;
+        static double *devstrs=NULL;
+        static double **Cel=NULL;
+        static double **mat1=NULL;
+        static double **mat2=NULL;
+        static double ** NoN=NULL;
+        static double ** Idev=NULL;
+	double h, tmp1, tmp2;
+
+        if(N==NULL)
+        {
+ 	  mallocvector(&devstrs,6);
+	  mallocvector(&N,6);
+	  mallocmatrix(&Cel,6,6);
+	  mallocmatrix(&NoN,6,6);
+	  mallocmatrix(&mat1,6,6);
+	  mallocmatrix(&mat2,6,6);
+	  mallocmatrix(&Idev,6,6);
+        }
+        cleartens2(devstrs);
+	cleartens2(N);
+	cleartens4(Cel);
+	cleartens4(NoN);
+	cleartens4(mat1);
+	cleartens4(mat2);
+	cleartens4(Idev);
+
+        //deviatoric operator
+        for(i=0;i<3;i++){
+		for(j=0;j<3;j++){
+		  Idev[i][j]=-1./3.;
+
+		}
+		Idev[i][i]+=1.;
+		Idev[i+3][i+3]=1.;
+	}
+  //reset tangent operators to zero
+	mu = E/(2.*(1.+nu));
+
+	compute_Hooke(E,nu,Cel);
+
+	dev(strs,devstrs);
+	
+	j2hard (p, sy0, htype, hmod1, hmod2, hp0, hexp, &R, &dR, &ddR);
+
+	addtens2(1.5/(sy0+R),devstrs,0.,devstrs,N);
+	seqtr = 3*mu*dp + sy0 + R;
+	produit_tensoriel(N,N,NoN);
+	
+	h = 3.*mu + dR;
+	tmp1 = 4.*mu*mu/h;
+	tmp2 = 4.*mu*mu*dp/seqtr;
+
+	addtens4(tmp1,NoN,0,NoN,mat1);
+	addtens4(3.*tmp2/2.,Idev,-tmp2,NoN,mat2);
+
+	addtens4(1.,Cel,-1.,mat1,Calgo);
+	addtens4(1.,Calgo,-1.,mat2,Calgo);
+
+	//free(devstrs);
+	//free(N);
+	//freematrix(Cel,6);
+	//freematrix(mat1,6);
+	//freematrix(mat2,6);
+	//freematrix(Idev,6);
+	//freematrix(NoN,6);
 
 
 }
@@ -72,7 +1467,206 @@ void algoJ2(double E, double nu, double sy0, int htype, double hmod1, double hmo
 
 //ELASTO-PLASTIC CONSTITUTIVE BOX for second moment mehtod
 int constbox_ep(double E, double nu, double sy0, int htype, double hmod1, double hmod2, double hp0, double hexp, double *DE, double *dstrn, double *strs_n, double eq2strs_n, double *eq2strs, double dstrseq_tr, double *dstrseq_trdDE, double *strs, double* pstrn_n, double* pstrn, double p_n, double *p, FY2nd *FY2){
-return 0;
+
+	int i,j,it;
+	double strseqtr2;       	//Variables for the elastic prediction 
+	double R, dR, ddR, strseq2, mu_el;    //Variables for the correction phase 
+	double Dp, temp1, temp2;
+	double cp=0.0;
+	double tol = 1e-12;    //tolerance on the residual 
+	double res, res0;    		 //residual 
+
+	R=0.;
+	dR=0.;
+	ddR=0.;
+
+	mu_el = E/(2.*(1.+nu));  
+	
+        static bool initialized=false;
+        // initialize only once!
+	static double **Cel=NULL;
+	static double **Idev=NULL;
+	static double *dstrstr=NULL;
+	static double *dstrstr_dev=NULL;
+	static double *Str=NULL;
+	static double *Ntr=NULL;
+	static double *strs_ndev=NULL;
+	static double *mat1=NULL;
+        bool stay=true;
+
+	
+        if(!initialized)
+        {
+          mallocmatrix(&Cel, 6, 6);
+	  mallocmatrix(&Idev,6,6);
+          mallocvector(&dstrstr,6);
+          mallocvector(&dstrstr_dev,6);
+          mallocvector(&Str,6);
+          mallocvector(&Ntr,6);
+          mallocvector(&strs_ndev,6);
+          mallocvector(&mat1,6);
+          initialized = true;
+        }
+        cleartens4(Cel);
+	cleartens4(Idev);
+        cleartens2(dstrstr);
+        cleartens2(dstrstr_dev);
+        cleartens2(Str);
+        cleartens2(Ntr);
+        cleartens2(strs_ndev);
+        cleartens2(mat1);
+        
+
+	//deviatoric operator
+	for(i=0;i<3;i++){
+	  for(j=0;j<3;j++){
+	    Idev[i][j]=-1./3.;
+          }
+	  Idev[i][i]+=1.;
+	  Idev[i+3][i+3]=1.;
+	}
+
+	//elastic predictor
+	compute_Hooke(E,nu,Cel);
+
+	//compute trial incremental stress
+	contraction42(Cel, dstrn, dstrstr);
+	contraction42(Idev, dstrstr, dstrstr_dev);
+        contraction42(Idev, strs_n, strs_ndev);
+
+	if(dstrseq_tr > 0.){
+		addtens2(1.5/dstrseq_tr, dstrstr_dev, 0., dstrstr_dev, Ntr);
+	}
+                addtens2(1.0, strs_n, 1.0, dstrstr, Str);
+       //1. elastic increment
+            Dp=DP_MIN;
+	    j2hard (p_n+Dp, sy0, htype, hmod1, hmod2, hp0, hexp, &R, &dR,&ddR);
+	    strseq2= (sy0 + R)*(sy0 + R);
+
+           //1.1 trial (eq_stress)^2 
+             addtens2(1.0, dstrstr_dev, -2.0*mu_el*Dp, Ntr, mat1);
+
+             int scheme = 1;
+             //if(contraction22(strs_ndev,Str)<=0.0){
+             //     scheme = 1;
+             //}
+             if(scheme==1){
+                   strseqtr2 =  (dstrseq_tr-3.0*mu_el*Dp)*(dstrseq_tr-3.0*mu_el*Dp);
+             }
+             else if(scheme==2){
+                    strseqtr2 = (dstrseq_tr-3.0*mu_el*Dp)*(dstrseq_tr-3.0*mu_el*Dp) + 3.0*contraction22(strs_ndev,mat1);
+             }
+             else{
+                    strseqtr2 = eq2strs_n + (dstrseq_tr-3.0*mu_el*Dp)*(dstrseq_tr-3.0*mu_el*Dp) + 3.0*contraction22(strs_ndev,mat1);
+             }
+             FY2->f = strseqtr2 - strseq2; 
+
+          //1.2 check yielding condition 
+
+       	if(FY2->f<=0.){
+
+                *eq2strs = strseqtr2;
+		copyvect(Str, strs,6);
+                copyvect(pstrn_n, pstrn,6);
+    		*p = p_n;
+		Dp=0.;
+
+                // clean structure FY2
+                FY2->f=0.0;
+                FY2->dfdp=0.0;	
+	        for(i=0;i<6;i++){
+	                FY2->dfdstrn_m[i]=0.0;
+                        FY2->dfdstrn_c[i]=0.0;
+	                FY2->dpdstrn_m[i]=0.0;
+                        FY2->dpdstrn_c[i]=0.0; 
+                }		
+	}
+	//2. Plastic correction: return mapping algorithm 
+	else{
+             it=0;
+	     res=1.0;
+	     res0=res; 
+	     while(res>tol && stay){
+		  it++;
+		  if(it>20){
+			 printf(":( no convergence in return mapping algorithm, p: %lf\n",*p);
+			 stay=false;
+                         Dp=1.;
+			//return(1);
+		  }
+
+		  *p=p_n+Dp;
+		  j2hard (*p, sy0, htype, hmod1, hmod2, hp0, hexp, &R, &dR,&ddR);
+                  strseq2= (sy0 + R)*(sy0 + R);
+                  addtens2(1.0, dstrstr_dev, -2.0*mu_el*Dp, Ntr, mat1);
+
+             	  if(scheme==1){
+                     strseqtr2 =  (dstrseq_tr-3.0*mu_el*Dp)*(dstrseq_tr-3.0*mu_el*Dp);
+                  }
+                  else if(scheme==2){
+                     strseqtr2 = (dstrseq_tr-3.0*mu_el*Dp)*(dstrseq_tr-3.0*mu_el*Dp) +  3.0*contraction22(strs_ndev,mat1);
+                  }
+                  else{
+                    strseqtr2 = eq2strs_n + (dstrseq_tr-3.0*mu_el*Dp)*(dstrseq_tr-3.0*mu_el*Dp) + 3.0*contraction22(strs_ndev,mat1);
+                  }
+
+
+                  FY2->f = strseqtr2 - strseq2; 
+  
+		  res = fabs(FY2->f)/strseq2; //mu_el;
+         	  if(it==1||res<res0){
+		     res0=res;
+                 // 2.1 newton-raphson iteration , compute Dp
+ 
+                     if(scheme==1 ){
+                         FY2->dfdp = -6.0*mu_el*((dstrseq_tr-3.0*mu_el*Dp))-2.0*(sy0 + R)*dR; 
+                     }
+                     else{
+                         FY2->dfdp = -6.0*mu_el*((dstrseq_tr-3.0*mu_el*Dp) + contraction22(strs_ndev, Ntr))-2.0*(sy0 + R)*dR;
+                     }
+                     cp = -FY2->f/FY2->dfdp;          
+
+                     temp1 = 0.99*(DP_MIN-Dp);
+		     if(cp<temp1) {
+			//printf("new Dp below Dpmin : correction!\n");
+			cp=temp1;
+		     }
+		     Dp+=cp;
+		   }
+		   else{
+			//printf("residual is not decreasing: correction!\n");
+			cp=cp/2.;
+			Dp=Dp-cp;
+			res0=res;
+		   }
+			//printf("j2plast iteration: %d, res: %.10e, p: %.10e\n",it,res,*p);
+	     }
+             // 2.2 After obtainning the value of Dp, compute the out put variables 
+		*eq2strs = (sy0 + R)*(sy0 + R);
+		addtens2(1., Str,-2.*mu_el*Dp, Ntr, strs);
+		addtens2(1.,pstrn_n, Dp, Ntr, pstrn);
+
+             //2.3 compute the derivatives of f and p
+                if(scheme==1){
+                temp1 = 0.0;
+                temp2 = 2.0*(dstrseq_tr-3.0*mu_el*Dp);
+                }
+                else{
+                temp1 = 6.0*mu_el*(1.0-3.0*mu_el*Dp/dstrseq_tr); 
+                temp2 = 2.0*(dstrseq_tr-3.0*mu_el*Dp)+ 9.0*mu_el*Dp*contraction22(strs_ndev, dstrstr_dev)/dstrseq_tr/dstrseq_tr;
+                }
+                for(i=0;i<6;i++){
+                      FY2->dfdstrn_m[i] = temp1*strs_ndev[i];
+                      FY2->dpdstrn_m[i] = -FY2->dfdstrn_m[i]/FY2->dfdp;
+
+                      FY2->dfdstrn_c[i] = temp2*dstrseq_trdDE[i];
+                      FY2->dpdstrn_c[i] = -FY2->dfdstrn_c[i]/FY2->dfdp;
+                }
+    
+  	} //end case plastic correction
+        if(!stay) return(1); //no convergence
+
+	return(0);
 }
 
 
@@ -88,13 +1682,465 @@ int constbox_evp(double E, double nu, double sy0, int htype, double hmod1, doubl
         double* dpdE, bool residual, double dt)
 
 {
-  return (0);
+	int i,j,k,it,error;
+	double strseqtr, strseqtrNor0, trstrstr;       	//Variables for the elastic prediction 
+	double R, dR, ddR, strseq, G;    //Variables for the correction phase 
+        double gv, hv, dgdf, dhvdSeq, dhvdp;
+	double kp;
+	double Dp;  
+	double h, tmp1, tmp2;
+	double cp=0.;
+	double tol = 1.e-12;    //tolerance on the residual 
+	double res, res0;    		 //residual 
+	double mu_iso, k_iso;
+	double G3, h3;
+        double sq2;
+
+        double eq2strs_n;
+
+        sq2 = sqrt(2.);
+	R=0.;
+	dR=0.;
+	ddR=0.;
+
+	G = E/(2.*(1.+nu));  
+//	k_iso = E/(3.*(1.-(2.*nu)));
+	G3 = G*G*G;
+
+        static bool initialized=false;
+        // initialize only once!
+	static double **Cel=NULL;
+	static double **NoN=NULL;
+	static double **Idev=NULL;
+	static double **mat1=NULL;
+	static double *strstr=NULL;
+	static double *strstrNor0=NULL;
+	static double *Str=NULL;
+	static double *Ntr=NULL;
+	static double *dstrs=NULL;
+        bool stay=true;
+
+        if(!initialized)
+        {
+          mallocmatrix(&Cel, 6, 6);
+	  mallocmatrix(&NoN,6,6);
+	  mallocmatrix(&Idev,6,6);
+	  mallocmatrix(&mat1,6,6);
+          mallocvector(&strstr,6);
+          mallocvector(&strstrNor0,6);
+          mallocvector(&Str,6);
+          mallocvector(&Ntr,6);
+          mallocvector(&dstrs,6);
+
+          initialized = true;
+        }
+        cleartens4(Cel);
+	cleartens4(NoN);
+	cleartens4(Idev);
+	cleartens4(mat1);
+        cleartens2(strstr);
+        cleartens2(strstrNor0);
+        cleartens2(Str);
+        cleartens2(Ntr);
+        cleartens2(dstrs);
+
+	//deviatoric operator
+	for(i=0;i<3;i++){
+	  for(j=0;j<3;j++){
+	    Idev[i][j]=-1./3.;
+          }
+	  Idev[i][i]+=1.;
+	  Idev[i+3][i+3]=1.;
+	}
+	//reset tangent operators to zero
+	for(i=0;i<6;i++){
+		for(j=0;j<6;j++){
+			Calgo[i][j]=0.;
+		}
+	}
+
+	//elastic predictor
+	compute_Hooke(E,nu,Cel);
+
+	//compute trial stress
+	contraction42(Cel, dstrn, dstrs);
+
+        addtens2(1., strs_n,   1., dstrs, strstrNor0);
+
+	addtens2(1., strs_n, 1., dstrs, strstr);
+        strseqtrNor0 = vonmises(strstrNor0);
+       // strseqtrNor0 = vonmises(dstrs);
+	strseqtr = vonmises(strstr);
+  
+	//normal to the yield surface
+	dev(strstrNor0, Str);
+        //  dev(dstrs, Str);
+
+  
+	if(strseqtrNor0 > 0.){
+		addtens2(1.5/strseqtrNor0, Str, 0., Str, Ntr);
+		produit_tensoriel(Ntr,Ntr,NoN);
+	}
+
+         
+	//elastic increment
+	Dp=DP_MIN;
+	j2hard (p_n+Dp, sy0, htype, hmod1, hmod2, hp0, hexp, &R, &dR,&ddR);
+	strseq= sy0 + R;
+	kp = strseq + 3.*G*Dp - strseqtr;
+
+	if(kp>=0.){
+		//printf("elastic: !");
+		copyvect(strstr, strs, 6);
+		copyvect(pstrn_n, pstrn,6);
+    		*p = p_n;
+		Dp=0.;
+		copymatr(Cel,Calgo,6,6);
+		for(i=0;i<6;i++){
+			for(j=0;j<6;j++){
+				for(k=0;k<6;k++){
+					dCalgo[i][j][k]=0.;
+				}
+			}
+		}
+      //compute dpdE  accumulate plastice strain p derivative w.r.t. strain increment
+
+       cleartens2(dpdE);
+     
+	}
+	//ViscoPlastic correction: return mapping algorithm 
+	else{
+                Dp = DP_MIN;  //correction must be such that Dp >= DP_MIN
+
+		it=0;
+		res=1.;
+		res0=res;
+		while(res>tol && stay){
+			it++;
+			if(it>20){
+				printf("no convergence in return mapping algorithm, p: %lf\n",*p);				
+				//return(1);
+                               	stay=false;
+                                Dp=1.;
+
+			}
+
+			*p=p_n+Dp;
+			j2hard (*p, sy0, htype, hmod1, hmod2, hp0, hexp, &R, &dR,&ddR);
+
+		        strseq = strseqtr-3.*G*Dp;
+
+                        solve_gv(viscmodel, vmod, vstressy, vexp, G, strseq, sy0, dt, R, dR, ddR, &gv, &hv, &dgdf, &dhvdSeq, &dhvdp,eq2strs_n);
+
+			kp = Dp - gv*dt;                           
+			res = fabs(kp);
+                        h=hv;
+
+			if(it==1||res<res0){
+				res0=res;
+				cp =  - kp/(h*dgdf*dt);
+				tmp1 = 0.99*(DP_MIN-Dp);
+				if(cp<tmp1) {
+					//printf("new Dp below Dpmin : correction!\n");
+					cp=tmp1;
+				}
+				Dp+=cp;
+			}
+			else{
+				//printf("residual is not decreasing: correction!\n");
+				cp=cp/2.;
+				Dp=Dp-cp;
+				res0=res;
+			}
+
+			//printf("j2plast iteration: %d, res: %.10e, p: %.10e\n",it,res,*p);
+		}
+		//printf("Number of iterations in radial return algorithm: %d\n",it); 
+
+     	        addtens2(1., strstr,-2.*G*(Dp), Ntr, strs);
+	        addtens2(1.,pstrn_n, Dp, Ntr, pstrn);
+             
+	        h3 = h*h*h;
+		tmp1 = 4.*G*G/h;
+		tmp2 = 4.*G*G*(*p-p_n)/strseqtr;
+
+		addtens4(1.,Cel,(-tmp1+tmp2),NoN, Calgo);
+		addtens4(1.,Calgo,-1.5*tmp2,Idev,Calgo);  
+
+		addtens4(1.5,Idev,-1.,NoN,mat1);
+		for(i=0;i<6;i++){
+			for(j=0;j<6;j++){
+				for(k=0;k<6;k++){
+					dCalgo[i][j][k] = (8.*G3/(h*h))*(dhvdSeq*(1.0-3.0*G/h) + dhvdp/h)*NoN[i][j]*Ntr[k] - (16.*G3/(h*strseqtr))*Ntr[i]*mat1[j][k] - mat1[i][j]*8.*G3*Ntr[k]*((1./(h*strseqtr))-(Dp/(strseqtr*strseqtr))) + (16.*G3*Dp/(strseqtr*strseqtr))*Ntr[i]*mat1[j][k];
+				}
+			}
+		}
+
+       //compute dpdE  accumulate plastice strain p derivative w.r.t. strain increment
+
+       addtens2((2.*G/h), Ntr, 0, Ntr, dpdE);
+
+
+	} //end case plastic correction
+
+
+      
+
+
+	//compute isoJ2 tangent operator and its derivative w.r.t. strain increment
+	if(Dp<DP_MIN){		//that is, Dp=0 	
+		mu_iso=G;
+		for(i=0;i<6;i++){
+			dtwomu_iso[i]=0.;
+		}
+	}
+		
+	else {
+		mu_iso = G*(1.-(3.*G/h));
+		for(i=0;i<6;i++){
+			dtwomu_iso[i] = 12.*pow(G/h,3.)*ddR*Ntr[i];
+		}
+	}
+  
+	*twomu_iso = 2.*mu_iso;
+
+//      no free as initialized once        
+//     	freematrix(Cel, 6);
+//	freematrix(Idev,6);
+//	freematrix(NoN,6);
+//	freematrix(mat1,6);
+        if(!stay) return(1); //no convergence
+	return(0);
 }
 
 
 //ELASTO-VISCOPLASTIC CONSTITUTIVE BOX for second moment mehtod
 int constbox_evp(double E, double nu, double sy0, int htype, double hmod1, double hmod2, double hp0, double hexp, int viscmodel, double vmod, double vstressy, double vexp, double *DE, double *dstrn, double *strs_n, double eq2strs_n, double *eq2strs, double dstrseq_tr, double *dstrseq_trdDE, double *strs, double* pstrn_n, double* pstrn, double p_n, double *p, FY2nd *FY2, double dt, ELcc *LCC){
 
+	int i,j,it;
+	double strseqtr;       	//Variables for the elastic prediction 
+        double gv, hv, dgdf, dhvdSeq, dhvdp;
+	double R, dR, ddR, strseq, mu_el;    //Variables for the correction phase 
+        double kp;
+	double Dp, temp0, temp1, temp2;
+	double cp=0.0;
+	double tol = 1e-12;    //tolerance on the residual 
+	double res, res0;    		 //residual 
+
+	R=0.;
+	dR=0.;
+	ddR=0.;
+
+	mu_el = E/(2.*(1.+nu));  
+	
+        static bool initialized=false;
+        // initialize only once!
+	static double **Cel=NULL;
+	static double **Idev=NULL;
+	static double **I=NULL;
+	//static double **ImA=NULL;
+	static double *dstrstr=NULL;
+	static double *dstrstr_dev=NULL;
+	static double *Str=NULL;
+	static double *Ntr=NULL;
+	static double *strs_ndev=NULL;
+	//static double *Edstrn_i=NULL;
+	//static double *Edstrn_m=NULL;
+	static double *mat1=NULL;
+	//static double *Edstrstr=NULL;
+	//static double *Edstrstr_dev=NULL;
+	//static double *P;
+        bool stay=true;
+		
+        if(!initialized)
+        {
+          mallocmatrix(&Cel, 6, 6);
+	  mallocmatrix(&Idev,6,6);
+	  mallocmatrix(&I,6,6);
+	  //mallocmatrix(&ImA,6,6);
+	  mallocvector(&dstrstr,6);
+	  mallocvector(&dstrstr_dev,6);
+	  mallocvector(&Str,6);
+	  mallocvector(&Ntr,6);
+	  mallocvector(&strs_ndev,6);
+	  //mallocvector(&Edstrn_i,6);
+	  //mallocvector(&Edstrn_m,6);
+	  mallocvector(&mat1,6);
+	  //mallocvector(&Edstrstr,6);
+	  //mallocvector(&Edstrstr_dev,6);
+	  //mallocvector(&P,6);
+
+          initialized = true;
+        }
+        cleartens4(Cel);
+        cleartens4(Idev);
+	cleartens4(I);
+	//cleartens4(ImA);
+	cleartens2(dstrstr);
+	cleartens2(dstrstr_dev);
+	cleartens2(Str);
+	cleartens2(Ntr);
+	cleartens2(strs_ndev);
+	//cleartens2(Edstrn_i);
+	//cleartens2(Edstrn_m);
+	cleartens2(mat1);
+	//cleartens2(Edstrstr);
+	//cleartens2(Edstrstr_dev);
+	//cleartens2(P);
+
+	//deviatoric operator
+	for(i=0;i<3;i++){
+	  for(j=0;j<3;j++){
+	    Idev[i][j]=-1./3.;
+          }
+	  Idev[i][i]+=1.;
+	  Idev[i+3][i+3]=1.;
+	}
+
+	for(i=0;i<6;i++){
+		I[i][i] = 1.;
+	}
+
+
+	//elastic predictor
+	compute_Hooke(E,nu,Cel);
+
+	//compute trial incremental stress
+	contraction42(Cel, dstrn, dstrstr);
+	contraction42(Idev, dstrstr, dstrstr_dev);
+        contraction42(Idev, strs_n, strs_ndev);
+
+
+        //double v1= LCC->v1;
+        //double v0 = 1.0 - v1;		
+	//contraction42(LCC->A, DE, Edstrn_i);              //unloading strain of inclusion at tn
+        //addtens2 (1./v0, DE, -1.*v1/v0, Edstrn_i, Edstrn_m); //unloading strain of matrix at tn
+
+        //addtens4(1.0/v0, I, -1.0*v1/v0, LCC->A, ImA);
+
+
+	//compute trial incremental stress
+   	//contraction42(Cel, dstrn, Edstrstr);
+
+	
+	//contraction42(Idev, Edstrstr, Edstrstr_dev);
+        //contraction42(Idev, strs_n, strs_ndev);
+
+	//contraction42(ImA, strs_ndev,P);
+        //addtens2(1.0, strs_n, 1.0, Edstrstr, Str);
+        addtens2(1.0, strs_n, 1.0, dstrstr, Str);
+
+
+       //1. elastic increment
+            Dp=DP_MIN;
+	    j2hard (p_n+Dp, sy0, htype, hmod1, hmod2, hp0, hexp, &R, &dR,&ddR);
+
+           //1.1 trial (eq_stress)^2 
+             strseqtr =  dstrseq_tr;
+             int soft_inclusions=0;
+             if(soft_inclusions==1)
+             {
+                // for soft inclusion, a modification is applied-----------
+                temp0 = (dstrseq_tr*dstrseq_tr)+6.0*mu_el*contraction22(strs_ndev, dstrn)+ 1.5*contraction22(strs_ndev,strs_ndev);
+                strseqtr =  fabs(pow(temp0,0.5)-3.0*mu_el*Dp);     
+             }
+             if(dstrseq_tr > 0.){
+               addtens2(1.5/dstrseq_tr, dstrstr_dev, 0., strs_ndev, Ntr);
+               //old version
+               //addtens2(1.5/dstrseq_tr, dstrstr_dev, 1.5, strs_ndev, Ntr);
+              //addtens2(1.5/strseqtr, dstrstr_dev, 1.5/strseqtr, strs_ndev, Ntr);
+                 //addtens2(1.5/strseqtr, dstrstr_dev, 1.5/strseqtr, strs_ndev, Ntr);
+              //----------------------------------------------------------------------
+	    }           
+
+             FY2->f = strseqtr - (sy0 + R);
+
+          //1.2 check yielding condition 
+
+       	if(FY2->f<=0.){
+
+                *eq2strs = strseqtr*strseqtr;
+		copyvect(Str, strs,6);
+                copyvect(pstrn_n, pstrn,6);
+    		*p = p_n;
+		Dp=0.;
+
+                // clean structure FY2
+                FY2->f=0.0;
+                FY2->dfdp=0.0;	
+	        for(i=0;i<6;i++){
+	                FY2->dfdstrn_m[i]=0.0;
+                        FY2->dfdstrn_c[i]=0.0;
+	                FY2->dpdstrn_m[i]=0.0;
+                        FY2->dpdstrn_c[i]=0.0; 
+                }		
+	}
+	//2. Plastic correction: return mapping algorithm 
+	else{
+             it=0;
+	     res=1.0;
+	     res0=res;
+	     while(res>tol && stay){
+		  it++;
+		  if(it>20){
+			printf("no convergence in return mapping algorithm, p: %lf\n",*p);
+			stay=false;
+                        Dp=1.;
+			//return(1);
+		  }
+
+		  *p=p_n+Dp;
+                  j2hard (*p, sy0, htype, hmod1, hmod2, hp0, hexp, &R, &dR,&ddR);
+
+               	  strseq =  strseqtr-3.0*mu_el*Dp;
+                  solve_gv(viscmodel, vmod, vstressy, vexp, mu_el, strseq, sy0, dt, R, dR, ddR, &gv, &hv, &dgdf, &dhvdSeq, &dhvdp,eq2strs_n);
+
+                  kp = Dp - gv*dt;                           
+		  res = fabs(kp);
+                 
+                  if(it==1||res<res0){
+			res0=res;
+			cp = - kp/(hv*dgdf*dt);
+			temp1 = 0.99*(DP_MIN-Dp);
+			if(cp<temp1) {
+			   //printf("new Dp below Dpmin : correction!\n");
+			    cp=temp1;
+			}
+			Dp+=cp;
+		  }
+		  else{
+			 //printf("residual is not decreasing: correction!\n");
+			cp=cp/2.;
+			Dp=Dp-cp;
+			res0=res;
+		  }
+
+			//printf("j2plast iteration: %d, res: %.10e, p: %.10e\n",it,res,*p);
+	     }
+
+             // 2.2 After obtainning the value of Dp, compute the out put variables 
+
+		*eq2strs = strseq*strseq;
+		addtens2(1., Str,-2.*mu_el*Dp, Ntr, strs);
+		addtens2(1.,pstrn_n, Dp, Ntr, pstrn);
+
+             //2.3 compute the derivatives of f and p
+                for(i=0;i<6;i++){
+                      FY2->dpdstrn_m[i] = 0.0;                    
+
+                     if(soft_inclusions==1)
+                     {
+                       // for soft inclusion, a modification is applied-----------
+
+                       FY2->dpdstrn_m[i] = strs_ndev[i]*3.0*mu_el/(strseqtr)/hv;
+                       //---------------------
+                     }
+                     FY2->dpdstrn_c[i] = dstrseq_trdDE[i]/hv;
+                }
+    
+  	} //end case plastic correction
+        if(!stay) return(1); //no convergence
+
 	return(0);
 }
 
@@ -102,10 +2148,204 @@ int constbox_evp(double E, double nu, double sy0, int htype, double hmod1, doubl
 /**********J2 viscoplasticity for large deformation***/
 //******************************************************
 int constbox_evp(double E, double nu, double sy0, int htype, double hmod1, double hmod2, double hp0,
-	double hexp, int viscmodel, double vmod, double vstressy, double vexp, double *strs_tr, double *strs, double* pstrn_n, 
+	double hexp, int viscmodel, double vmod, double vstressy, double vexp, double *strs_tr, double *Rstrs_n, double *strs, double* pstrn_n, 
         double* pstrn, double p_n, double *p, double** Calgo, double*** dCalgo, double* dpdE, bool residual, double dt)
 
 {
+	int i,j,k,it,error;
+	double strseqtr,strseqtr0;       	//Variables for the elastic prediction 
+	double R, dR, ddR, strseq, G;    //Variables for the correction phase 
+        double gv, hv, dgdf, dhvdSeq, dhvdp;
+	double kp;
+	double Dp;  
+	double h, tmp1, tmp2;
+	double cp=0.0;
+	double tol = 1.e-12;    //tolerance on the residual 
+	double res, res0;    		 //residual 
+	double G3, h3;
+        double sq2;
+
+        double eq2strs_n;
+        bool stay=true;
+
+        sq2 = sqrt(2.);
+	R=0.;
+	dR=0.;
+	ddR=0.;
+
+	G = E/(2.*(1.+nu));  
+//	k_iso = E/(3.*(1.-(2.*nu)));
+	G3 = G*G*G;
+
+        static bool initialized=false;
+        // initialize only once!
+	static double **Cel;
+	static double **NoN;
+	static double **Idev;
+	static double **mat1;
+	static double *Str;
+        static double *Ntr;
+        static double *strstrNor0;
+
+        if(!initialized)
+        {
+          mallocmatrix(&Cel, 6, 6);
+	  mallocmatrix(&NoN,6,6);
+	  mallocmatrix(&Idev,6,6);
+	  mallocmatrix(&mat1,6,6);
+          mallocvector(&Str,6);
+          mallocvector(&Ntr,6); 
+          mallocvector(&strstrNor0,6);
+          initialized = true;
+        }
+        cleartens4(Cel);
+        cleartens4(NoN);
+	cleartens4(Idev);
+	cleartens4(mat1);
+	cleartens2(Str);
+	cleartens2(Ntr);
+        cleartens2(strstrNor0);
+	//deviatoric operator
+	for(i=0;i<3;i++){
+	  for(j=0;j<3;j++){
+	    Idev[i][j]=-1./3.;
+          }
+	  Idev[i][i]+=1.;
+	  Idev[i+3][i+3]=1.;
+	}
+	//reset tangent operators to zero
+	for(i=0;i<6;i++){
+		for(j=0;j<6;j++){
+			Calgo[i][j]=0.;
+		}
+	}
+
+	//elastic predictor
+	compute_Hooke(E,nu,Cel);
+
+	strseqtr = vonmises(strs_tr);
+  
+	//normal to the yield surface
+        //dev(strs_tr, Str);
+  
+        //normal to the residual stress
+        addtens2(1.0, strs_tr, -1.0, Rstrs_n, strstrNor0);
+	dev(strstrNor0, Str);
+	strseqtr0 = vonmises(strstrNor0);
+
+	if(strseqtr > 0.){
+		addtens2(1.5/strseqtr0, Str, 0., Str, Ntr);
+		produit_tensoriel(Ntr,Ntr,NoN);
+	}
+         
+	//elastic increment
+	Dp=DP_MIN;
+	j2hard (p_n+Dp, sy0, htype, hmod1, hmod2, hp0, hexp, &R, &dR,&ddR);
+	strseq= sy0 + R;
+	kp = strseq + 3.*G*Dp - strseqtr;
+
+	if(kp>=0.){
+		//printf("elastic: !");
+		copyvect(strs_tr, strs, 6);
+		copyvect(pstrn_n, pstrn,6);
+    		*p = p_n;
+		Dp=0.;
+		copymatr(Cel,Calgo,6,6);
+		for(i=0;i<6;i++){
+			for(j=0;j<6;j++){
+				for(k=0;k<6;k++){
+					dCalgo[i][j][k]=0.;
+				}
+			}
+		}
+      //compute dpdE  accumulate plastice strain p derivative w.r.t. strain increment
+
+        cleartens2(dpdE);
+     
+	}
+	//ViscoPlastic correction: return mapping algorithm 
+	else{
+                Dp = DP_MIN;  //correction must be such that Dp >= DP_MIN
+
+		it=0;
+		res=1.;
+		res0=res;
+		while(res>tol && stay){
+			it++;
+			if(it>20){
+				printf("no convergence in return mapping algorithm, p: %lf\n",*p);			
+                                stay=false;
+                                Dp=1.;
+	
+				//return(1);
+			}
+
+			*p=p_n+Dp;
+			j2hard (*p, sy0, htype, hmod1, hmod2, hp0, hexp, &R, &dR,&ddR);
+
+		        strseq = strseqtr-3.*G*Dp;
+
+                        solve_gv(viscmodel, vmod, vstressy, vexp, G, strseq, sy0, dt, R, dR, ddR, &gv, &hv, &dgdf, &dhvdSeq, &dhvdp,eq2strs_n);
+
+			kp = Dp - gv*dt;                           
+			res = fabs(kp);
+                        h=hv;
+
+			if(it==1||res<res0){
+				res0=res;
+				cp =  - kp/(h*dgdf*dt);
+				tmp1 = 0.99*(DP_MIN-Dp);
+				if(cp<tmp1) {
+					//printf("new Dp below Dpmin : correction!\n");
+					cp=tmp1;
+				}
+				Dp+=cp;
+			}
+			else{
+				//printf("residual is not decreasing: correction!\n");
+				cp=cp/2.;
+				Dp=Dp-cp;
+				res0=res;
+			}
+
+			//printf("j2plast iteration: %d, res: %.10e, p: %.10e\n",it,res,*p);
+		}
+		//printf("Number of iterations in radial return algorithm: %d\n",it); 
+
+     	        addtens2(1., strs_tr,-2.*G*(Dp), Ntr, strs);
+	        addtens2(1.,pstrn_n, Dp, Ntr, pstrn);
+             
+	        h3 = h*h*h;
+		tmp1 = 4.*G*G/h;
+		tmp2 = 4.*G*G*(*p-p_n)/strseqtr;
+
+		addtens4(1.,Cel,(-tmp1+tmp2),NoN, Calgo);
+		addtens4(1.,Calgo,-1.5*tmp2,Idev,Calgo);  
+
+		addtens4(1.5,Idev,-1.,NoN,mat1);
+		for(i=0;i<6;i++){
+			for(j=0;j<6;j++){
+				for(k=0;k<6;k++){
+					dCalgo[i][j][k] = (8.*G3/(h*h))*(dhvdSeq*(1.0-3.0*G/h) + dhvdp/h)*NoN[i][j]*Ntr[k] - (16.*G3/(h*strseqtr))*Ntr[i]*mat1[j][k] - mat1[i][j]*8.*G3*Ntr[k]*((1./(h*strseqtr))-(Dp/(strseqtr*strseqtr))) + (16.*G3*Dp/(strseqtr*strseqtr))*Ntr[i]*mat1[j][k];
+				}
+			}
+		}
+
+       //compute dpdE  accumulate plastice strain p derivative w.r.t. strain increment
+
+       addtens2((2.*G/h), Ntr, 0, Ntr, dpdE);
+
+
+	} //end case plastic correction
+
+
+
+//      no free as initialized once        
+//     	freematrix(Cel, 6);
+//	freematrix(Idev,6);
+//	freematrix(NoN,6);
+//	freematrix(mat1,6);
+        if(!stay) return(1); //no convergence
 	return(0);
 }
 
@@ -116,6 +2356,107 @@ int constbox_evp(double E, double nu, double sy0, int htype, double hmod1, doubl
 
 void solve_gv(int viscmodel, double vmod, double vstressy, double vexp, double mu, double strseq, double yldstrs, double dt, double R, double dR, double ddR, double *gv, double *hv, double *dgdf, double *dhvdSeq, double *dhvdp, double eq2strs_n){
 
+	double f;
+        double tmp1,tmp2, dgdR;
+        double ddgdSdR, ddgdR;
+     	
+        f = strseq - yldstrs - R;
+
+	if(f < 0.0){
+		printf("f < 0 Should be elastic, f = %.10e\n",f);
+		return;
+	}
+        
+	switch(viscmodel){
+		case V_NORTON:
+                        *gv = vmod*pow(f/yldstrs,vexp);
+                        tmp1 = vmod*vexp/yldstrs*pow(f/yldstrs,vexp-1.0);
+                        *dgdf = tmp1;
+                
+                        *hv = 1.0/(tmp1*dt)+3.0*mu + dR;
+
+                        tmp2 = vmod*vexp*(vexp-1.0)/(yldstrs*yldstrs)*pow(f/yldstrs,vexp-2.0); //ddgvdSeq
+                        *dhvdSeq = -1.0/(tmp1*tmp1*dt)*tmp2;
+                        *dhvdp = 1.0/(tmp1*tmp1*dt)*tmp2*dR + ddR;
+
+			break;
+		
+		//PERZYNA law with drag stress implemented in Abaqus 
+		case V_PERZYNA:
+			*gv = vmod*pow(f/(yldstrs+R),vexp);
+                        tmp1 = vmod*vexp/(yldstrs+R)*pow(f/(yldstrs+R),vexp-1.0);
+                        *dgdf = tmp1;
+
+                        dgdR = -tmp1-vmod*vexp/(yldstrs+R)*pow(f/(yldstrs+R),vexp);
+                        *hv = 1.0/(tmp1*dt) + 3.0*mu - dgdR/tmp1*dR ;
+
+                        tmp2 = vmod*vexp*(vexp-1.0)/((yldstrs+R)*(yldstrs+R))*pow(f/(yldstrs+R),vexp-2.0); //ddgvdSeq
+                        ddgdSdR = -tmp2*(1.0 + vexp*f/(yldstrs+R)/(vexp-1.0));
+                        ddgdR = tmp2*(1.0 + 2.0*vexp*f/(yldstrs+R)/(vexp-1.0) + (vexp+1.0)*f/(yldstrs+R)*f/(yldstrs+R)/(vexp-1.0));
+
+                        *dhvdSeq = 1.0/(tmp1*tmp1)*tmp2*(-1.0/dt + dgdR*dR) - ddgdSdR*dR/tmp1;
+                        *dhvdp = (-1.0/dt + dgdR*dR)/(tmp1*tmp1)*ddgdSdR*dR - (ddgdR*dR*dR+ dgdR*ddR)/tmp1; 
+
+			break;
+				
+		//Power law 
+		case V_POWER:
+			*gv = vmod*pow(strseq/(yldstrs+R),vexp);
+                        tmp1 = vmod*vexp/(yldstrs+R)*pow(strseq/(yldstrs+R),vexp-1.0);
+                        *dgdf = tmp1;
+
+                        dgdR = -vmod*vexp/(yldstrs+R)*pow(strseq/(yldstrs+R),vexp);
+                        *hv = 1.0/(tmp1*dt) + 3.0*mu - dgdR/tmp1*dR ;
+
+                        tmp2 = vmod*vexp*(vexp-1.0)/((yldstrs+R)*(yldstrs+R))*pow(strseq/(yldstrs+R),vexp-2.0); //ddgvdSeq
+                        ddgdSdR = -tmp1*vexp/(yldstrs+R);
+                        ddgdR = vmod*vexp*(vexp+1.0)/(yldstrs+R)/(yldstrs+R)*pow(strseq/(yldstrs+R),vexp);
+
+                        *dhvdSeq = 1.0/(tmp1*tmp1)*tmp2*(-1.0/dt + dgdR*dR) - ddgdSdR*dR/tmp1;
+                        *dhvdp = (-1.0/dt + dgdR*dR)/(tmp1*tmp1)*ddgdSdR*dR - (ddgdR*dR*dR+ dgdR*ddR)/tmp1; 
+
+			break;	
+
+		case V_PRANDTL:
+                        double Beta;
+                        Beta = 10.0;
+
+                        *gv = vmod*pow(sinh(f/Beta),vexp);
+                        tmp1 = vmod*vexp/Beta*pow(sinh(f/Beta),vexp-1.0)*cosh(f/Beta);
+                        *dgdf = tmp1;
+                
+                        *hv = 1.0/(tmp1*dt)+3.0*mu + dR;
+
+                        tmp2 = vmod*vexp/Beta/Beta*((vexp-1.0)*pow(sinh(f/Beta),vexp-2.0)*cosh(f/Beta)*cosh(f/Beta)+
+                               pow(sinh(f/Beta),vexp)); //ddgvdSeq
+                        *dhvdSeq = -1.0/(tmp1*tmp1*dt)*tmp2;
+                        *dhvdp = 1.0/(tmp1*tmp1*dt)*tmp2*dR + ddR;
+
+			break;
+		//Power law with hardening: vmod is actually dot eps0/sy0^n
+		case V_POWER_NO_HARDENING:
+                  	*gv = vmod*pow(strseq/vstressy,vexp);
+                        tmp1 = vmod/vstressy*vexp*pow(strseq/vstressy,vexp-1.0);
+                        *dgdf = tmp1;
+                        dgdR = 0.;
+                        *hv = 1.0/(tmp1*dt) + 3.0*mu  ;
+
+                        tmp2 = vmod*vexp*(vexp-1.0)/vstressy/vstressy*pow(strseq/vstressy,vexp-2.0); //ddgvdSeq
+                        ddgdSdR = 0.0;
+                        ddgdR = 0.0;
+                        if(vexp == 1.0){
+                            *dhvdSeq = 0.0;
+                            *dhvdp =0.0; 
+                        }
+                        else{
+                            *dhvdSeq = -1.0/(dt*tmp1*tmp1)*tmp2;
+                            *dhvdp =  0.0; 
+                        } 
+			break;	
+		default:
+			printf("Invalid viscosity law: %d\n", viscmodel);
+			break;
+	}
 
 	return;
 }
diff --git a/NonLinearSolver/materialLaw/material.cpp b/NonLinearSolver/materialLaw/material.cpp
index 282a1971cc4d211516715d3df8ea0015df99691b..04e14b515395cb9feee247ccd509cfff5b7a6f7d 100644
--- a/NonLinearSolver/materialLaw/material.cpp
+++ b/NonLinearSolver/materialLaw/material.cpp
@@ -17,6 +17,7 @@
 #include "j2plast.h"
 #include "mlawNonLocalDamage.h"
 #include "homogenization.h"
+#include "Lamhomogenization.h"
 #include "homogenization_2rd.h"
 using std::max;
 using namespace MFH;
@@ -28,6 +29,17 @@ using namespace MFH;
 //*******c_g the characteristic length tensor, the value is returned by Clength_creat function***********
 
 
+/*int Material::constboxSecant(double* dstrn, double* strs_n,  double* strs, double* statev_n, double* statev, double **Calgo, double** Csd, double*** dCsd, double** dCsdp_bar, double* dnu, double& dnudp_bar, double alpha, double* dpdE, double* dstrsdp_bar, double** c_g, int kinc, int kstep, double dt)
+{
+  printf("Function constBoxSecant is not defined for this material\n");
+  return (1);
+}
+
+int Material::constboxSecantZero(double* dstrn, double* strs_n,  double* strs, double* statev_n, double* statev, double **Calgo, double** Csd, double*** dCsd, double** dCsdp_bar, double* dnu, double& dnudp_bar, double alpha, double* dpdE, double* dstrsdp_bar, double** c_g, int kinc, int kstep, double dt)
+{
+  return constboxSecant(dstrn, strs_n,  strs, statev_n, statev, Calgo, Csd, dCsd, dCsdp_bar, dnu, dnudp_bar, alpha, dpdE, dstrsdp_bar,c_g, kinc, kstep, dt);
+}*/
+
 int Material::constboxSecantMixte(double* dstrn, double* strs_n,  double* strs, double* statev_n, double* statev, double **Calgo, double** Csd, double*** dCsd, double** dCsdp_bar, double* dnu, double& dnudp_bar, double alpha, double* dpdE, double* dstrsdp_bar, double** c_g, int kinc, int kstep, double dt, bool forceZero, bool forceRes)
 {
   printf("Function constBoxSecant is not defined for this material\n");
@@ -41,6 +53,7 @@ int Material::constboxSecantMixte(double* dstrn, double* strs_n,  double* strs,
 //    return constboxSecant(dstrn, strs_n,  strs, statev_n, statev, Calgo, Csd, dCsd, dCsdp_bar, dnu, dnudp_bar, alpha, dpdE, dstrsdp_bar,c_g, kinc, kstep, dt);  
 }
 
+
 int Material::constboxLargD(double* dstrn, double* strs_n,  double* strs, double* statev_n, double* statev, double **Calgo, double** Csd, double*** dCsd, double** dCsdp_bar, double* dnu, double& dnudp_bar, double alpha, double* dpdE, double* dstrsdp_bar, double** c_g, int kinc, int kstep, double dt)
 {
   printf("Function constBoxLargD is not defined for this material\n");
@@ -86,17 +99,478 @@ bool Material::eqstrs_exist() const
 {
     return false;
 }
-int Material::constboxSecantMixteGeneric(double* dstrn, double* strs_n,  double* strs, double* statev_n, double* statev, double **Calgo, double** Csd, double*** dCsd, double** dCsdp_bar, double* dnu, double& dnudp_bar, double alpha, double* dpdE, double* dstrsdp_bar, double** c_g, int kinc, int kstep, double dt, bool forceZero, bool forceRes,
-double E, double nu, int htype, double sy0, double hexp, double hmod1, double hmod2, double hp0, double alpha_DP, double m_DP, double nup, int viscmodel, double vmod, double vstressy, double vexp, bool evp)
+          
+int Material::constboxSecantMixteGeneric(double* dstrn, double* strs_n,  double* strs, double* statev_n, double* statev, double **Calgo, double** Csd, double*** dCsd, double** dCsdp_bar, double* dnu, double& dnudp_bar, double alpha, double* dpdE, double* dstrsdp_bar, double** c_g, int kinc, int kstep, double dt, bool forceZero, bool forceRes,double E, double nu, int htype, double sy0, double hexp, double hmod1, double hmod2, double hp0, double alpha_DP, double m_DP, double nup, int viscmodel, double vmod, double vstressy, double vexp, bool evp)
 {
-  return (1);
-}     
+	int i,j,k,error;
+	double p_n,p;
+        double kappa,tmp;
+        double mu;
+	double twomu, twok;
+        bool zeroMethod;
+	
+	static double** Cel = NULL;
+	static double* dtwomu = NULL;
+	static double* dtwok = NULL;
+	static double** Idev = NULL, **Ivol = NULL;
+	static double* pstrn = NULL;
+	static double* pstrn_n = NULL;
+        static double* strs_nef = NULL;             // effective stress at tn (residual stress) 
+        static double* strs_ef = NULL;              // effective stress at tn+1 (updated stress) 
+
+        static double* dstrs = NULL, *dstrs_ef = NULL;                // increment of stress 
+
+        static double* dstrs_efdev = NULL;            // dev of increment of stress
+        static double* strs_efdev = NULL;            // dev of increment of stress
+        static double* strs_nefdev = NULL;            // dev of increment of stress at tn
+        static double* dstrn_dev = NULL;            // dev of increment of strain
+
+        static double* dDdE = NULL;                 //*********add by wu ling 
+        static double* mat1 = NULL, *mat2 = NULL;
+        static double* dkappa = NULL, *dmu = NULL;
+
+        double strs_tra;
+        double dstrs_eff_tra;             // trace of increment of effective stress
+        double strs_eff_tra;             // trace of effective stress
+        double dstrn_tra;
+        double strs_eq;
+        double dstrs_eq;
+        double dstrs_efeq;
+        double dstrn_eq;
+        double dDdp_bar;                 //*********add by wu ling 
+        double D;                    //*********add by wu ling 
+// variables for operation
+        double dkappadp_bar, dmudp_bar, dkappadD, dmudD, num1, num2, num3;
+
+        static double **strs_dDdE=NULL;
+
+        static bool initialized = false;
+        double toleranceDiv=1.e-20;
+	//allocate memory
+        if(!initialized)
+        {
+          initialized = true;
+  	  mallocvector(&dtwomu,6);
+  	  mallocvector(&dtwok,6);
+	  mallocmatrix(&Idev,6,6);
+	  mallocmatrix(&Ivol,6,6);
+	  mallocmatrix(&Cel,6,6);
+	  mallocvector(&pstrn,6);
+	  mallocvector(&pstrn_n,6);
+          mallocvector(&strs_nef,6);
+          mallocvector(&strs_ef,6);
+          mallocvector(&dstrs,6);
+          mallocvector(&dstrs_ef,6);
+          mallocvector(&dstrs_efdev,6);
+          mallocvector(&strs_efdev,6);
+          mallocvector(&strs_nefdev,6);
+          mallocvector(&dstrn_dev,6);
+          mallocvector(&dDdE,6);         //*********add by wu ling 
+          mallocvector(&dkappa,6);       
+          mallocvector(&dmu,6);          
+          mallocvector(&mat1,6);  
+          mallocvector(&mat2,6); 
+
+          mallocmatrix(&strs_dDdE,6,6); 
+        }
+        cleartens2(dtwomu);
+        cleartens2(dtwok);
+	cleartens4(Idev);
+	cleartens4(Cel);
+	cleartens4(Ivol);
+	cleartens2(pstrn);
+	cleartens2(pstrn_n);
+        cleartens2(strs_nef);
+        cleartens2(strs_ef);
+        cleartens2(dstrs);
+        cleartens2(dstrs_ef);
+        cleartens2(dstrs_efdev);
+        cleartens2(strs_efdev);
+        cleartens2(strs_nefdev);
+        cleartens2(dstrn_dev);
+        cleartens2(dDdE);         //*********add by wu ling 
+        cleartens2(dkappa);       
+        cleartens2(dmu);          
+        cleartens2(mat1);  
+        cleartens2(mat2);  
+        cleartens4(strs_dDdE);
+        
+
+	//fill Idev and Ivol
+
+	for(i=0;i<3;i++){
+		Idev[i][i]=1.;
+		Idev[i+3][i+3]=1.;
+		for(j=0;j<3;j++){
+			Ivol[i][j]=1./3.;
+			Idev[i][j]=Idev[i][j]-1./3.;
+		}
+	}
+	
+
+	p_n = statev_n[get_pos_p()];
+	copyvect(&(statev_n[get_pos_pstrn()]),pstrn_n,6);
+	p=0.;
+
+       
+       //convert stress into effective stress at tn, the return mapping will not be changed then
+       D=0.0;
+       if(dam){
+               D = statev_n[pos_dam+2];
+       }
+
+       for(i=0;i<6;i++){
+               strs_nef[i]=strs_n[i]/(1.0-D);
+       }
+
+        //check if residual has to be removed or not
+        //elastic predictor
+	compute_Hooke(E,nu,Cel);
+
+	//compute trial stress to decide to use of not residual method
+	contraction42(Cel, dstrn, dstrs_ef);
+
+	addtens2(1., strs_nef, 1., dstrs_ef, strs_ef);
+
+        zeroMethod=false;
+               
+	if(vonmises(dstrs_ef)> vonmises(strs_ef))
+        {
+          zeroMethod=true;
+        }
+        if(forceZero) zeroMethod=true;
+        if(forceRes) zeroMethod=false;
+        cleartens2(strs_ef);
+        cleartens2(dstrs_ef);
+        if(!evp)
+          if(htype>10)
+            error=constbox_ep(E, nu, sy0, htype, hmod1, hmod2, hp0, alpha_DP, m_DP, nup, hexp, dstrn, strs_nef, strs_ef, pstrn_n, pstrn, p_n, &p, &twomu, dtwomu, &twok, dtwok, Calgo, dCsd,dpdE,!zeroMethod);
+          else
+            error=constbox_ep(E, nu, sy0, htype, hmod1, hmod2, hp0, hexp, dstrn, strs_nef, strs_ef, pstrn_n, pstrn, p_n, &p, &twomu, dtwomu, Calgo, dCsd,dpdE,!zeroMethod);
+        else
+          error=constbox_evp(E, nu, sy0, htype, hmod1, hmod2, hp0, hexp, viscmodel, vmod, vstressy, vexp, dstrn, strs_nef, strs_ef, pstrn_n, pstrn, p_n, &p, &twomu, dtwomu, Calgo, dCsd, dpdE, !zeroMethod, dt);
+       
+       // update state variable, and keep the effective stress in state variable for the compuation of damage
+
+	addtens2(1., statev_n, 1., dstrn, statev); 
+	copyvect(strs_ef, &(statev[pos_strs]),6);
+	copyvect(dstrn, &(statev[pos_dstrn]),6);
+	copyvect(pstrn, &(statev[get_pos_pstrn()]),6);
+	statev[get_pos_p()]=p;
+	statev[get_pos_dp()]=p-p_n;
+	statev[get_pos_twomu()]=twomu;  
+	statev[get_pos_eqstrs()]= vonmises(strs_ef); 
+#ifdef NONLOCALGMSH
+	//statev_n[get_pos_dp()]=p-p_n;
+#else
+        statev_n[get_pos_dp()]=p-p_n;
+#endif
+	copyvect(strs_nef, &(statev_n[pos_strs]),6);
+
+
+       //*****************************************
+#ifdef NONLOCALGMSH
+            if(dam && localDamage)
+            {
+              statev_n[pos_dam]= statev_n[get_pos_p()];
+  	      statev_n[pos_dam+1]= statev_n[get_pos_dp()];
+            }
+#else
+// add by wu ling try nonlocal mehod without finite element cacilation
+            if(dam)
+            {
+              statev_n[pos_dam]= statev_n[get_pos_p()];
+  	      statev_n[pos_dam+1]= statev_n[get_pos_dp()];
+            }
+#endif
+
+            if(dam){
+               // get damage parameters
+                dDdp_bar=0.0;
+		dam->damagebox(statev_n, statev, pos_strn, pos_strs, pos_dam, Calgo, dDdE, &dDdp_bar, 1., kinc, kstep);
+
+              // update state variable, and convert the effective stress in state variable back
+          
+               for(i=0;i<6;i++){
+                 statev_n[6+i]=strs_nef[i]*(1.0-D);
+               } 
+
+               D = statev[pos_dam+2];
+               for(i=0;i<6;i++){
+                 statev[6+i]=strs_ef[i]*(1.0-D);
+               }
+             }
+               
+              // make Csd, secant operator*****************************************************************************************************************************
+
+                for(i=0;i<6;i++){
+                 strs[i]=statev[6+i];
+                 dstrs[i]=statev[6+i]-statev_n[6+i];
+                 dstrs_ef[i]=strs_ef[i]-strs_nef[i];
+               }
+                
+      //check
+      //        printf(" vomin residusl stress of matrix is %e\n", vonmises(strs_nef)); 
+
+               // Compute the trace of a second order tensor-dstrn amd dstrs 
+               strs_tra = trace(strs);
+               strs_eff_tra = trace(strs_ef);
+               dstrs_eff_tra = trace(dstrs_ef);
+               dstrn_tra = trace(dstrn);
+
+               // Extract the deviatoric part of a second order tensor -dstrn amd dstrs 
+               dev(dstrs_ef, dstrs_efdev);  
+               dev(strs_ef, strs_efdev);  
+               dev(strs_nef, strs_nefdev);  
+               dev(dstrn,dstrn_dev);
+
+               // Compute the von Mises equivalent stress 
+               strs_eq = vonmises(strs_ef);
+               dstrs_eq = vonmises(dstrs_ef);
+
+               // Compute the equivalent strain scalar 
+               dstrn_eq = eqstrn(dstrn);
+
+
+               // make Csd
+               if(fabs(dstrn_tra)>toleranceDiv and p-p_n >0.){
+                 if(!zeroMethod)
+                 {  
+                    kappa = E/3./(1.-2.*nu);
+                    num1=0; //for dkappa
+                 }
+                 else
+                 {
+                    kappa = strs_eff_tra/(3.*dstrn_tra);
+                    num1=trace(strs_nef)/3.0; //here only if use strs_eff in kappa
+                    kappa = dstrs_eff_tra/(3.*dstrn_tra);
+                    num1=0.;
+                 }
+                 if(htype>10)
+                 {
+                    kappa = 0.5*twok;
+                 }
+                 if(dam)
+                 {
+                    kappa = kappa*(1.-D);
+                 }
+               } 
+               else{
+                  kappa = E/3./(1.-2.*nu);
+                  if(htype>10)
+                  {
+                     kappa = 0.5*twok;
+                  }
+                  if(dam)
+                  {
+                    kappa=kappa*(1.-D);
+                  }
+               }
+
+               if(!zeroMethod)
+               {  
+                 if(fabs(dstrn_eq) >toleranceDiv and p-p_n >0.){
+                    mu = dstrs_eq/(3.*dstrn_eq);
+                    if(dam){
+                      mu = mu*(1.-D);
+                    }
+                 }
+                 else{                 
+                   mu = E/2./(1.+nu);
+                   if(dam)
+                   {
+                     mu=mu*(1.-D);
+                   }
+                 }
+               }
+               else
+               {
+                 if(fabs(dstrn_eq) >toleranceDiv and p-p_n >0.){
+                    mu = strs_eq/(3.*dstrn_eq);
+                    if(htype>10)
+                    {
+                       mu = 0.5*twomu;
+                    }
+                    if(dam)
+                    {
+                       mu = mu*(1.-D);
+                   }
+                 }
+                 else{                 
+                   mu = E/2./(1.+nu);
+                  if(htype>10)
+                  {
+                     mu = 0.5*twomu;
+                  }
+                   if(dam)
+                   {
+                     mu=mu*(1.-D);
+                   }
+                 }
+               }
+
+	       makeiso(kappa, mu, Csd);
+
+       // dCsd/dstrain  and dCsd/dp_bar*****************
+
+ 
+          //1. dkappa/dstrain, /dp_bar
+               if(!zeroMethod)
+               {  
+                 for(i=0;i<6;i++){
+                   dkappa[i] = 0.0;
+                 }
+               }
+               else
+               {
+                 for(i=0;i<6;i++){
+                   dkappa[i] = 0.0;
+                 }
+                 for(i=0;i<3;i++){
+                    if(fabs(dstrn_tra)>toleranceDiv and p-p_n >0.)
+                      dkappa[i] = -(1.0-D)*num1/(dstrn_tra*dstrn_tra);
+                    else
+                      dkappa[i] = 0.;
+                 }
+               }
+               if(htype>10)
+               {
+                  dkappa = dtwok;
+               }
+               if(dam){
+                  
+                 dkappadD =  -kappa/(1.-D);
+                 for(i=0;i<6;i++){
+                   dkappa[i] = dkappa[i]+ dkappadD*dDdE[i];
+                 }  
+                 dkappadp_bar = dkappadD*dDdp_bar;
+               }
+
+          //2. dmu/dstrain, /dp_bar
+
+            for (i=0; i<6; i++) {
+                     mat1[i] = 0.;
+                }
+                if(!zeroMethod)
+                {
+                   for(i=0;i<6;i++){
+                     for (j=0; j<6; j++) {
+                           mat1[i] = mat1[i] + dstrs_efdev[j]*Calgo[j][i];
+                     }
+                   }
+                }
+                else
+                {
+                   for(i=0;i<6;i++){
+                     for (j=0; j<6; j++) {
+                           mat1[i] = mat1[i] + strs_efdev[j]*Calgo[j][i];
+                     }
+                   }
+
+                }
+                for(i=0;i<6;i++){
+                  if(fabs(dstrn_eq)>toleranceDiv and p-p_n >0.)
+                    dmu[i] = ((1.-D)*(1.-D)*mat1[i])/(6.*mu*dstrn_eq *dstrn_eq);  //mu is actually muD
+		  else
+	            dmu[i] = 0.;
+                }
+
+
+                dev(dstrn, mat1);  
+                for(i=0;i<6;i++){
+                  if(fabs(dstrn_eq)>toleranceDiv and p-p_n >0.)
+                    dmu[i] = dmu[i]-2.0*mu*mat1[i]/(3.0*dstrn_eq *dstrn_eq);
+                }
+                if(htype>10)
+                {
+                   dmu = dtwomu;
+                }
+                if(dam){
+                      
+                       if(fabs(dstrn_eq)>toleranceDiv)
+                         dmudD = -mu/(1.-D); 
+                       else
+                         dmudD = -E/2./(1.+nu); 
+
+                       for(i=0;i<6;i++){
+                            dmu[i] = dmu[i]+ dmudD*dDdE[i]; 
+                       }
+                      dmudp_bar= dmudD*dDdp_bar;
+                }
+
+           //3. dCsd/dstrain, /dp_bar
+
+                for(i=0;i<6;i++){
+                        for(j=0;j<6;j++){
+                                 for(k=0;k<6;k++){   
+            
+                                         dCsd[i][j][k] = 3.0*Ivol[i][j]*dkappa[k]+ 2.0*Idev[i][j]*dmu[k]; 
+                                  }
+                                 dCsdp_bar[i][j]= 3.0*Ivol[i][j]*dkappadp_bar+ 2.0*Idev[i][j]*dmudp_bar;
+                         }
+                } 
+          //4. dnu/dstrain, /dp_bar
+             
+                tmp = (3.*kappa + mu);
+                if(fabs(tmp)>toleranceDiv)
+                {
+                  for(i=0;i<6;i++){
+                   dnu[i] = 9.*mu/(2.*tmp*tmp)*dkappa[i]-9.*kappa/(2.*tmp*tmp)*dmu[i];
+                  }  
+                  dnudp_bar = 9.*mu/(2.*tmp*tmp)*dkappadp_bar-9.*kappa/(2.*tmp*tmp)*dmudp_bar;
+                }
+                else
+                {
+                  for(i=0;i<6;i++){
+                   dnu[i] = 0.;
+                  }  
+                  dnudp_bar = 0.;
+                }
+
+           // up date  Calgo and dstrsdp_bar 
+                     
+                 for(i=0;i<6;i++){
+                     dstrsdp_bar[i]= -1.*strs_ef[i]*dDdp_bar;
+	            for(j=0;j<6;j++){
+		           
+                    //  get stress*dDdE,
+                            strs_dDdE[i][j]=strs_ef[i]*dDdE[j]; 
+	            }        
+                 }
+
+           
+                 // add extra item on Calgo to conside the damage ( stress*dDdE)
+                 addtens4 ((1.-D), Calgo, -1.0, strs_dDdE, Calgo);
+                 //printf("j2plast iteration:  p: %.10e\n", statev[pos_p]);
+
+#ifdef NONLOCALGMSH
+            if(dam && localDamage)
+            {
+              statev[pos_dam]= statev[get_pos_p()];
+  	      statev[pos_dam+1]= statev[get_pos_dp()];
+            }
+#else
+// add by wu ling try nonlocal mehod without finite element cacilation
+            if(dam)
+            {
+              statev[pos_dam]= statev[get_pos_p()];
+  	      statev[pos_dam+1]= statev[get_pos_dp()];
+            }
+#endif
+
+        clength->creat_cg(statev_n, get_pos_p(), c_g);        //*********add by wu ling 
+
+        return error;               
+
+
+
+}
 
 void Material::setEuler(double e1, double e2, double e3)
 {
   printf("Function setEuler is not defined for this material\n");
-  //int a = 1;
-}     
+}
+
 
 #ifdef NONLOCALGMSH
 int Material::get_pos_mtx_stress () const
@@ -155,7 +629,7 @@ void Material::get_elOp_icl(double** Cel)
 double Material::get_vfI()
 {
   printf("Function get_vfI is not defined for this material\n");
-  return 0.;
+
 }
 
 #endif
@@ -203,6 +677,10 @@ EL_Material::EL_Material(double* props, int idmat):Material(props, idmat){
 	}
 
         clength = init_clength(props,idclength);
+
+#ifdef NONLOCALGMSH
+	if(idclength==0) this->setLocalDamage();
+#endif
 }
 
 #ifdef NONLOCALGMSH
@@ -287,18 +765,424 @@ void EL_Material::print(){
 
 //constbox
 int EL_Material::constbox(double* dstrn, double* strs_n,  double* strs, double* statev_n, double* statev, double** Cref, double*** dCref, double* tau, double** dtau, double** Calgo, double alpha, double* dpdE, double* strs_dDdp_bar,double *Sp_bar, double** c_g, double* dFd_d_bar, double* dstrs_dFd_bar, double *dFd_dE, double** c_gF, double* dpdFd, double* dFddp, int kinc, int kstep, double dt){
-  return (1);
+
+        int i,j,k; 
+	static double* strn_n = NULL;
+	static double* strn = NULL;
+
+        double  dDdp_bar;                 //*********add by wu ling 
+        double  D;  
+
+        if(strn_n == NULL)
+        {
+	  mallocvector(&strn_n,6);
+	  mallocvector(&strn,6);
+        }
+        cleartens2(strn_n);
+        cleartens2(strn);
+
+	copyvect(&(statev_n[pos_strn]), strn_n,6);
+
+	//compute reference and algorithmic operators (=Hooke's operator)
+	compute_Hooke(E,nu,Calgo);
+	copymatr(Calgo,Cref,6,6);
+
+	addtens2(1.,strn_n,1.,dstrn,strn);
+	//compute new stress
+	contraction42(Calgo,strn,strs);
+
+	//update state variables
+	addtens2(1., statev_n, 1., dstrn, statev); 
+	copyvect(dstrn, &(statev[pos_dstrn]),6);
+
+
+
+#ifdef NONLOCALGMSH
+        if(dam && localDamage)
+        {
+          statev[pos_dam]= statev[pos_p];
+	  statev[pos_dam+1]= statev[pos_p]-statev_n[pos_p];
+        }
+#else
+// add by wu ling try nonlocal mehod without finite element cacilation
+        if(dam)
+        {
+          statev[pos_dam]= statev[pos_p];
+	  statev[pos_dam+1]= statev[pos_p]-statev_n[pos_p];
+        }
+#endif
+
+
+
+        //Note: damage evolution doesn't depend on stress, it depends on local/nonlocal strain.
+        //dDdE in damage box is replaced, and sends back dpdE
+        if(dam){
+                dDdp_bar=0.0;
+		dam->damagebox(statev_n, statev, pos_strn, pos_strs, pos_dam, Calgo, dpdE, &dDdp_bar, alpha, kinc, kstep);
+
+               // up date reference operator Cref, Calgo and dCref dCalgo according to damage
+                 D = statev[pos_dam+2];
+
+                 for(i=0;i<6;i++){
+		         for(j=0;j<6;j++){
+                                 Cref[i][j] = (1.-D)*Cref[i][j];
+                                 Calgo[i][j] = (1.-D)*Calgo[i][j];			         
+		         }
+                          //  get stress*dDdp_bar
+                         strs_dDdp_bar[i]= -1.*strs[i]*dDdp_bar;
+                          //   apparent stress
+                         strs[i]= (1.-D)*strs[i];
+	         }
+
+        }
+
+
+#ifdef NONLOCALGMSH
+        if(dam && localDamage)
+        {
+          for(i=0;i<6;i++){
+		         for(j=0;j<6;j++){
+                                  for(k=0;k<6;k++){
+                                         dCref[i][j][k] = -Cref[i][j]*dDdp_bar*dpdE[k];
+                                  }
+                         }
+         }
+        }
+#else
+// add by wu ling try nonlocal mehod without finite element caculation
+        if(dam)
+        {
+          for(i=0;i<6;i++){
+		         for(j=0;j<6;j++){
+                                  for(k=0;k<6;k++){
+                                         dCref[i][j][k] = -Cref[i][j]*dDdp_bar*dpdE[k];
+                                  }
+                         }
+         }
+        }
+#endif
+
+
+
+        // update state variable
+	copyvect(strs, &(statev[6]),6);
+
+	//TO DO: call damage box, if dam!=NULL
+        clength->creat_cg(statev_n, pos_p, c_g);
+  return (0);
 }
 
 //costboxSecant
 int EL_Material::constboxSecantMixte(double* dstrn, double* strs_n,  double* strs, double* statev_n, double* statev, double **Calgo, double** Csd, double*** dCsd, double** dCsdp_bar, double* dnu, double& dnudp_bar, double alpha, double* dpdE, double* dstrsdp_bar, double** c_g, int kinc, int kstep, double dt, bool forceZero, bool forceRes){
 
-  return (1);
+        int i,j,k; 
+	static double* strn_n = NULL;
+	static double* strn = NULL;
+
+        double  dDdp_bar;                 //*********add by wu ling 
+        double  D;  
+
+        if(strn_n == NULL)
+        {
+	  mallocvector(&strn_n,6);
+	  mallocvector(&strn,6);
+        }
+        cleartens2(strn_n);
+        cleartens2(strn);
+
+	copyvect(&(statev_n[pos_strn]), strn_n,6);
+
+	//compute reference and algorithmic operators (=Hooke's operator)
+	compute_Hooke(E,nu,Calgo);
+	copymatr(Calgo,Csd,6,6);
+
+	addtens2(1.,strn_n,1.,dstrn,strn);
+	//compute new stress
+       
+	contraction42(Calgo,strn,strs); 
+
+
+
+	//update state variables
+	addtens2(1., statev_n, 1., dstrn, statev); 
+	copyvect(dstrn, &(statev[pos_dstrn]),6);
+
+#ifdef NONLOCALGMSH
+        if(dam && localDamage)
+        {
+          statev[pos_dam]= statev[pos_p];
+	  statev[pos_dam+1]= statev[pos_p]-statev_n[pos_p];
+        }
+#else
+// add by wu ling try nonlocal mehod without finite element cacilation
+        if(dam)
+        {
+          statev[pos_dam]= statev[pos_p];
+	  statev[pos_dam+1]= statev[pos_p]-statev_n[pos_p];
+        }
+#endif
+
+
+        //Note: damage evolution doesn't depend on stress, it depends on local/nonlocal strain.
+        //dDdE in damage box is replaced, and sends back dpdE
+        if(dam){
+                dDdp_bar=0.0;
+		dam->damagebox(statev_n, statev, pos_strn, pos_strs, pos_dam, Calgo, dpdE, &dDdp_bar, alpha, kinc, kstep);
+
+               // up date reference operator Cref, Calgo and dCref dCalgo according to damage
+                 D = statev[pos_dam+2];
+
+                 for(i=0;i<6;i++){
+		         for(j=0;j<6;j++){
+                                 Csd[i][j] = (1.-D)*Csd[i][j];
+                                 Calgo[i][j] = (1.-D)*Calgo[i][j];			         
+		         }
+                          //  get stress*dDdp_bar
+                         dstrsdp_bar[i]= -1.*strs[i]*dDdp_bar;
+                          //   apparent stress
+                         strs[i]= (1.-D)*strs[i];
+	         }
+#ifdef NONLOCALGMSH
+        if(dam && localDamage)
+        {
+          for(i=0;i<6;i++){
+		         for(j=0;j<6;j++){
+                                  for(k=0;k<6;k++){
+                                         dCsd[i][j][k] = -Csd[i][j]*dDdp_bar*dpdE[k];
+                                  }
+                         }
+         }
+        }
+#else
+// add by wu ling try nonlocal mehod without finite element cacilation
+        if(dam)
+        {
+          for(i=0;i<6;i++){
+		         for(j=0;j<6;j++){
+                                  for(k=0;k<6;k++){
+                                         dCsd[i][j][k] = -Csd[i][j]*dDdp_bar*dpdE[k];
+                                  }
+                         }
+         }
+        }
+#endif
+
+        }
+
+
+        // update state variable
+	copyvect(strs, &(statev[6]),6);
+
+	//TO DO: call damage box, if dam!=NULL
+         clength->creat_cg(statev_n, pos_p, c_g);
+
+  return (0);
 }
 
 
 int EL_Material::constboxLargD(double* dstrn, double* strs_n,  double* strs, double* statev_n, double* statev, double **Calgo, double** Csd, double*** dCsd, double** dCsdp_bar, double* dnu, double& dnudp_bar, double alpha, double* dpdE, double* dstrsdp_bar, double** c_g, int kinc, int kstep, double dt){
- return (1);
+ 
+      int i,j,k, error; 
+
+      double  dDdp_bar;                 //*********add by wu ling 
+      double  D; 
+
+      static double** Basen = NULL;
+      static double** Basenp1 = NULL;
+      static double** Fn = NULL;
+      static double** Fnp1 = NULL;
+      static double** Rn = NULL;
+      static double** Rnp1 = NULL;
+      static double** dR = NULL;
+      static double** Vr = NULL;
+      static double *elasstrn=NULL;
+      static double** invCel = NULL;
+      static double* Rstrs_n=NULL;
+      static double* RVect = NULL;
+
+      if(Fn == NULL)
+        {
+	  mallocmatrix(&Basen,3,3);
+	  mallocmatrix(&Basenp1,3,3);
+	  mallocmatrix(&Fn,3,3);
+	  mallocmatrix(&Fnp1,3,3);
+	  mallocmatrix(&Rn,3,3);
+	  mallocmatrix(&Rnp1,3,3);
+	  mallocmatrix(&dR,3,3);
+	  mallocmatrix(&Vr,3,3);
+          mallocvector(&elasstrn,6);
+          mallocvector(&Rstrs_n,6);
+          mallocvector(&RVect,9);
+	  mallocmatrix(&invCel,6,6);
+	}
+
+      for (i=0; i<3; i++){
+         for (j=0; j<3; j++){
+           Vr[i][j] = 0.0;
+           Fnp1[i][j] = 0.0;
+           Fn[i][j] = 0.0;
+           Rnp1[i][j] = 0.0;
+           Rn[i][j] = 0.0;
+           dR[i][j] = 0.0;
+           Basen[i][j] = 0.0;
+           Basenp1[i][j] = 0.0;
+           RVect[i+3*j] = 0.;
+         }
+      } 
+      cleartens2(elasstrn);
+      cleartens2(Rstrs_n);
+      cleartens4(invCel);
+
+     if( kinc==1 and kstep==1){
+         for (i=0; i<3; i++){
+             for (j=0; j<3; j++){
+                 dR[i][j] = 0.0;
+                 Rnp1[i][j] = 0.0;
+                 Rn[i][j] = 0.0;
+                 Fnp1[i][j] = 0.0;
+                 Fn[i][j] = 0.0;
+                 Vr[i][j] = 0.0;
+                 //Basen[i][j] = 0.0;
+                 //Basenp1[i][j] = 0.0;
+             }
+             dR[i][i] = 1.0;
+             Rnp1[i][i] = 1.0;
+             Rn[i][i] = 1.0;
+             Fnp1[i][i] = 1.0;
+             Fn[i][i] = 1.0;
+             Vr[i][i] = 1.0;
+             //Basen[i][i] = 1.0;
+             //Basenp1[i][i] = 1.0;
+         }
+     }   
+     else{
+             vect_to_matrix (3, &(statev[pos_Ri]), Rnp1);
+             vect_to_matrix (3, &(statev_n[pos_Ri]), Rn);
+             vect_to_matrix (3, &(statev[pos_F]), Fnp1);
+             vect_to_matrix (3, &(statev_n[pos_F]), Fn);
+     }
+     vect_to_matrix (3, &(statev[pos_Base]), Basenp1);
+     vect_to_matrix (3, &(statev_n[pos_Base]), Basen);
+     GetdR(Basen, dstrn, dR, Basenp1,sqrt(2.));
+     //printf("Basen: %f %f %f %f %f %f %f %f %f: \n ", Basen[0][0], Basen[0][1], Basen[0][2], Basen[1][0], Basen[1][1], Basen[1][2], Basen[2][0], Basen[2][1], Basen[2][2]);
+     //printf("Basenp1: %f %f %f %f %f %f %f %f %f: \n ", Basenp1[0][0], Basenp1[0][1], Basenp1[0][2], Basenp1[1][0], Basenp1[1][1], Basenp1[1][2], Basenp1[2][0], Basenp1[2][1], Basenp1[2][2]);
+     //printf("dR: %f %f %f %f %f %f %f %f %f: \n ", dR[0][0], dR[0][1], dR[0][2], dR[1][0], dR[1][1], dR[1][2], dR[2][0], dR[2][1], dR[2][2]);
+     //printf("Rn: %f %f %f %f %f %f %f %f %f: \n ", Rn[0][0], Rn[0][1], Rn[0][2], Rn[1][0], Rn[1][1], Rn[1][2], Rn[2][0], Rn[2][1], Rn[2][2]);
+     //printf("Fn: %f %f %f %f %f %f %f %f %f: \n ", Fn[0][0], Fn[0][1], Fn[0][2], Fn[1][0], Fn[1][1], Fn[1][2], Fn[2][0], Fn[2][1], Fn[2][2]);
+
+     UpdateFandR(Fn, Rn, dstrn, dR, Fnp1, Rnp1,sqrt(2.)); //Fn should be unloaded state
+     //printf("Rn+1: %f %f %f %f %f %f %f %f %f: \n ", Rnp1[0][0], Rnp1[0][1], Rnp1[0][2], Rnp1[1][0], Rnp1[1][1], Rnp1[1][2], Rnp1[2][0], Rnp1[2][1], Rnp1[2][2]);
+     //printf("Fn+1: %f %f %f %f %f %f %f %f %f: \n ", Fnp1[0][0], Fnp1[0][1], Fnp1[0][2], Fnp1[1][0], Fnp1[1][1], Fnp1[1][2], Fnp1[2][0], Fnp1[2][1], Fnp1[2][2]);
+
+     //for(i=0;i<6;i++){
+     //  strs_nef[i]=strs_n[i]/(1.0-D);
+     //}
+     //rotate residual stress
+     matrix_to_vect(3, dR, RVect);
+     for(i=0;i<6;i++)
+     {
+       Rstrs_n[i]=strs_n[i];
+     }
+     Rot_vect(RVect, Rstrs_n);       
+
+       // printf(" Rstrs : %f, %f, %f, %f, %f, %f\n", Rstrs_n[0],Rstrs_n[1],Rstrs_n[2],Rstrs_n[3],Rstrs_n[4],Rstrs_n[5]);
+       // GetTau(dR, &(statev_n[pos_strn]), E, nu, Rstrs_n, Basenp1,sqrt(2.),sqrt(2.));
+       // GetTau(dR, dstrn, E, nu, strs, Basenp1,sqrt(2.),sqrt(2.));
+       // printf(" TauEl : %f, %f, %f, %f, %f, %f\n", strs[0],strs[1],strs[2],strs[3],strs[4],strs[5]);
+  
+     GetTauRes(dR, &(statev_n[pos_strn]), dstrn, E, nu, strs, Basenp1,sqrt(2.),sqrt(2.));
+#if RESIDUAL_FROM_STRAIN_LD==0
+     for(i=0;i<6;i++){
+       strs[i]=strs[i]+Rstrs_n[i];
+     }
+#endif
+
+     //compute reference and algorithmic operators (=Hooke's operator)
+     compute_Hooke(E,nu,Calgo);
+
+     copymatr(Calgo,Csd,6,6);
+     inverse(Calgo,invCel,&error,6);
+     contraction42(invCel, strs, elasstrn);          //unloading strain of composite at tn
+     copyvect(elasstrn, &(statev[pos_strn]),6);
+
+	//update state variables
+     copyvect(dstrn, &(statev[pos_dstrn]),6);
+
+
+     // update state variable
+     copyvect(strs, &(statev[pos_strs]),6);
+     matrix_to_vect(3, Rnp1, &(statev[pos_Ri]));
+     matrix_to_vect(3, Basenp1, &(statev[pos_Base]));
+     matrix_to_vect(3, Fnp1, &(statev[pos_F]));
+
+#ifdef NONLOCALGMSH
+        if(dam && localDamage)
+        {
+          statev[pos_dam]= statev[pos_p];
+	  statev[pos_dam+1]= statev[pos_p]-statev_n[pos_p];
+        }
+#else
+// add by wu ling try nonlocal mehod without finite element cacilation
+        if(dam)
+        {
+          statev[pos_dam]= statev[pos_p];
+	  statev[pos_dam+1]= statev[pos_p]-statev_n[pos_p];
+        }
+#endif
+
+
+        //Note: damage evolution doesn't depend on stress, it depends on local/nonlocal strain.
+        //dDdE in damage box is replaced, and sends back dpdE
+        if(dam){
+                dDdp_bar=0.0;
+		dam->damagebox(statev_n, statev, pos_strn, pos_strs, pos_dam, Calgo, dpdE, &dDdp_bar, alpha, kinc, kstep);
+
+               // up date reference operator Cref, Calgo and dCref dCalgo according to damage
+                 D = statev[pos_dam+2];
+
+                 for(i=0;i<6;i++){
+		         for(j=0;j<6;j++){
+                                 Csd[i][j] = (1.-D)*Csd[i][j];
+                                 Calgo[i][j] = (1.-D)*Calgo[i][j];			         
+		         }
+                          //  get stress*dDdp_bar
+                         dstrsdp_bar[i]= -1.*strs[i]*dDdp_bar;
+                          //   apparent stress
+                         strs[i]= (1.-D)*strs[i];
+	         }
+#ifdef NONLOCALGMSH
+        if(dam && localDamage)
+        {
+          for(i=0;i<6;i++){
+		         for(j=0;j<6;j++){
+                                  for(k=0;k<6;k++){
+                                         dCsd[i][j][k] = -Csd[i][j]*dDdp_bar*dpdE[k];
+                                  }
+                         }
+         }
+        }
+#else
+// add by wu ling try nonlocal mehod without finite element cacilation
+        if(dam)
+        {
+          for(i=0;i<6;i++){
+		         for(j=0;j<6;j++){
+                                  for(k=0;k<6;k++){
+                                         dCsd[i][j][k] = -Csd[i][j]*dDdp_bar*dpdE[k];
+                                  }
+                         }
+         }
+        }
+#endif
+
+        }
+
+	//TO DO: call damage box, if dam!=NULL
+        clength->creat_cg(statev_n, pos_p, c_g);
+
+        statev[pos_Ja] = Determinant(Fnp1, 3);
+  return (0);
+
 }
 
 //constitutive box called by 2rd order method*******************
@@ -307,7 +1191,78 @@ int EL_Material::constboxLargD(double* dstrn, double* strs_n,  double* strs, dou
 int EL_Material::constbox_2order( int mtx, double *DE, double* dstrn, double* strs, double* statev_n, double* statev, 
 double **Calgo, Lcc* LCC, YieldF* YF, double** c_g, int kinc, int kstep, double dt){
 
-  return (1);
+        int i,j,k; 
+	static double* strn_n = NULL;
+	static double* strn = NULL;
+
+        double  D;  
+
+        if(strn_n == NULL)
+        {
+	  mallocvector(&strn_n,6);
+	  mallocvector(&strn,6);
+	}
+        cleartens2(strn_n);
+        cleartens2(strn);
+	//compute reference and algorithmic operators (=Hooke's operator)
+	compute_Hooke(E,nu,Calgo);
+
+        if(dam){ //need to be implemented****************************
+  
+#ifdef NONLOCALGMSH
+               if(dam && localDamage)
+               {
+                     statev[pos_dam]= statev[pos_p];
+	             statev[pos_dam+1]= statev[pos_p]-statev_n[pos_p];
+               }
+#else
+   // add by wu ling try nonlocal mehod without finite element caculation
+               if(dam)
+               {
+                     statev[pos_dam]= statev[pos_p];
+	             statev[pos_dam+1]= statev[pos_p]-statev_n[pos_p];
+               }
+#endif
+
+
+        }   //end of damage,
+
+      
+        // compute LCC to get strain concentration tensor A, where dstrn=A:dstrn_c
+        
+	copyvect(&(statev_n[pos_strn]), strn_n,6);
+
+
+	addtens2(1.,strn_n,1.,dstrn,strn);
+	//compute new stress
+       
+	contraction42(Calgo,strn,strs); 
+
+
+	//update state variables
+	addtens2(1., statev_n, 1., dstrn, statev); 
+	copyvect(dstrn, &(statev[pos_dstrn]),6);
+
+
+       //clean structure YielF YF before update its values.
+       // for elastic material YF->f...=0, If there is damage in the material YF->dp...will be update
+          YF->trial=0.0;          // no plasticity
+          YF->f=0.0;		  // value of yielding function
+	  YF->dfdmu[0] = YF->dfdmu[1] = YF->dfdp_bar= 0.0;	
+          for(i=0;i<6;i++){
+                     YF->dfdstrn[i]=0.0;            //  derivatives w.r. incremental strain of composite
+                     YF->dpdstrn[i]=0.0;     
+          }
+	  YF->dpdmu[0] = YF->dpdmu[1] = YF->dpdp_bar= 0.0;    //if there is damage	these values will be updated
+
+
+        // update state variable
+	copyvect(strs, &(statev[pos_strs]),6);
+
+	//TO DO: call damage box, if dam!=NULL
+         clength->creat_cg(statev_n, pos_p, c_g);
+  return (0);
+
 }
 
 
@@ -373,25 +1328,76 @@ EP_Material::EP_Material(double* props, int idmat):Material(props, idmat){
                 hmod2 = props[k++];
                 hp0 = 0.;
         }      
+
         else if(htype==H_POW_EXTRAPOL){
 		hmod2 = props[k++];
                 hp0   = props[k++];
 	}
-	else{
+
+	//hardening models for Drucker-Prager
+        else if(htype==H_POW_DP){
+		alpha_DP = props[k++];
+                m_DP = props[k++];
+                nup = props[k++];
 		hmod2 = 0.;
                 hp0   = 0.;
 	}
-	hexp = props[k];
-
-	nsdv = 28;
-	pos_strn=0;
-	pos_strs=6;
-	pos_dstrn=12;
-	pos_pstrn=18;
+        else if(htype==H_EXP_DP){
+		alpha_DP = props[k++];
+                m_DP = props[k++];
+                nup = props[k++];
+		hmod2 = 0.;
+                hp0   = 0.;
+	}
+        else if(htype==H_SWIFT_DP){
+		alpha_DP = props[k++];
+                m_DP = props[k++];
+                nup = props[k++];
+		hmod2 = 0.;
+                hp0   = 0.;
+	}
+	else if(htype==H_LINEXP_DP){
+		hmod2 = props[k++];
+                hp0 = 0.;
+		alpha_DP = props[k++];
+                m_DP = props[k++];
+                nup = props[k++];
+        }
+        else if(htype==H_POW_EXP_DP){
+                hmod2 = props[k++];
+                hp0 = 0.;
+		alpha_DP = props[k++];
+                m_DP = props[k++];
+                nup = props[k++];
+        } 
+        else if(htype==H_POW_EXTRAPOL_DP){
+		hmod2 = props[k++];
+                hp0   = props[k++];
+		alpha_DP = props[k++];
+                m_DP = props[k++];
+                nup = props[k++];
+	}
+	else{
+		hmod2 = 0.;
+                hp0   = 0.;
+	}
+
+	hexp = props[k++];
+
+	nsdv = 28;
+	pos_strn=0;
+	pos_strs=6;
+	pos_dstrn=12;
+	pos_pstrn=18;
 	pos_p = 24;
 	pos_dp = 25;
 	pos_twomu = 26;
 	pos_eqstrs = 27;
+	if(htype>10){
+		pos_twok = 27;
+	        pos_eqstrs = 28;
+                nsdv += 1;
+        }
         pos_F = nsdv;
         nsdv += 9;
         pos_Base = nsdv;
@@ -409,14 +1415,19 @@ EP_Material::EP_Material(double* props, int idmat):Material(props, idmat){
 
         clength = init_clength(props,idclength);
 
+#ifdef NONLOCALGMSH
+	if(idclength==0) this->setLocalDamage();
+#endif
 }
 
-
 #ifdef NONLOCALGMSH
 int EP_Material::get_pos_currentplasticstrainfornonlocal() const 
 {
 	return pos_p;
 }
+
+
+
 int EP_Material::get_pos_effectiveplasticstrainfornonlocal() const
 {
 	if(dam)
@@ -463,6 +1474,8 @@ double EP_Material::getPlasticEnergy (double* statev)
 {
   double eP = 0.;
   double p  = statev[get_pos_currentplasticstrainfornonlocal()];
+
+  int nstepI=1000;
   eP = sy0*p;
   switch(htype) {
     //POWER LAW HARDENING
@@ -470,21 +1483,43 @@ double EP_Material::getPlasticEnergy (double* statev)
       if(fabs(hexp+1.)!=0) 
          eP+=hmod1*pow(p,hexp+1.)/(hexp+1.);
       break;
+    //POWER LAW HARDENING  FOR DRUCKER PRAGER
+    case H_POW_DP:
+      if(fabs(hexp+1.)!=0) 
+         eP+=hmod1*pow(p,hexp+1.)/(hexp+1.);
+      break;
     //EXPONENTIAL HARDENING
     case H_EXP:
       eP+=hmod1*p;
       if(fabs(hexp)!=0) eP+=hmod1*(exp(-hexp*p)-exp(0))/(hexp);
       break;
+
+    //EXPONENTIAL HARDENING FOR DRUCKER PRAGER
+    case H_EXP_DP:
+      eP+=hmod1*p;
+      if(fabs(hexp)!=0) eP+=hmod1*(exp(-hexp*p)-exp(0))/(hexp);
+      break;
+
     //SWIFT LAW
     case H_SWIFT:
       eP-=sy0*p;
       if(fabs(hexp+1.)!=0 && fabs(hmod1)!=0.) eP+=sy0*pow(1.+hmod1*p,hexp+1.)/(hexp+1.)/hmod1;
       break;
+    //SWIFT LAW FOR DRUCKER PRAGER
+    case H_SWIFT_DP:
+      eP-=sy0*p;
+      if(fabs(hexp+1.)!=0 && fabs(hmod1)!=0.) eP+=sy0*pow(1.+hmod1*p,hexp+1.)/(hexp+1.)/hmod1;
+      break;
     //LINEAR-EXPONENTIAL HARDENING
     case H_LINEXP:
       eP+=hmod1*p*p/2.+hmod2*p;
       if(fabs(hexp)!=0) eP+=hmod2*(exp(-hexp*p)-exp(0))/(hexp);
       break;
+    //LINEAR-EXPONENTIAL HARDENING FOR DRUCKER PRAGER
+    case H_LINEXP_DP:
+      eP+=hmod1*p*p/2.+hmod2*p;
+      if(fabs(hexp)!=0) eP+=hmod2*(exp(-hexp*p)-exp(0))/(hexp);
+      break;
     //POWER LAW HARDENING EXTRAPOLATED AFTER 16% DEFO TO MIMIC DIGIMAT TO ABAQUS
     case H_POW_EXTRAPOL:
       if(p<hp0)
@@ -506,8 +1541,45 @@ double EP_Material::getPlasticEnergy (double* statev)
         eP+=(hmod1*pow(hp0,hexp+1.)+hmod2*(10.*hp0-hp0))*(p-10.*hp0)+hmod2*(p-10.*hp0)*(p-10.*hp0)/2000.;
       }
       break;
+    //POWER LAW HARDENING EXTRAPOLATED AFTER 16% DEFO TO MIMIC DIGIMAT TO ABAQUS FOR DRUCKER PRAGER
+    case H_POW_EXTRAPOL_DP:
+      if(p<hp0)
+      {
+        if(fabs(hexp+1.)!=0)
+          eP+=hmod1*pow(p,hexp+1.)/(hexp+1.);
+      }
+      else if(p<10.*hp0)
+      {
+        if(fabs(hexp+1.)!=0)
+          eP+=hmod1*pow(hp0,hexp+1.)/(hexp+1.);
+        eP+=hmod1*pow(hp0,hexp+1.)*(p-hp0)+hmod2*(p-hp0)*(p-hp0)/2.;
+      }
+      else
+      {
+        if(fabs(hexp+1.)!=0)
+          eP+=hmod1*pow(hp0,hexp+1.)/(hexp+1.);
+        eP+=hmod1*pow(hp0,hexp+1.)*(10.*hp0-hp0)+hmod2*(10.*hp0-hp0)*(10.*hp0-hp0)/2.;
+        eP+=(hmod1*pow(hp0,hexp+1.)+hmod2*(10.*hp0-hp0))*(p-10.*hp0)+hmod2*(p-10.*hp0)*(p-10.*hp0)/2000.;
+      }
+      break;
+    //POWER EXPONENTIAL HARDENING
+    case H_POW_EXP:
+        for(int i=0; i<nstepI; i++)
+        {
+          double ptmp=((double)(i+1)-0.5)*p/((double)(nstepI));
+          eP+=(hmod1*pow(ptmp,hmod2)*(1.- exp(-hexp*ptmp)))*p/((double)(nstepI));
+        }
+	break;
+    //POWER EXPONENTIAL HARDENING FOR DRUCKER PRAGER
+    case H_POW_EXP_DP:
+        for(int i=0; i<nstepI; i++)
+        {
+          double ptmp=((double)(i+1)-0.5)*p/((double)(nstepI));
+          eP+=(hmod1*pow(ptmp,hmod2)*(1.- exp(-hexp*ptmp)))*p/((double)(nstepI));
+        }
+	break;
     default:
-      printf("Bad choice of hardening law in j2hard: %d\n",htype);
+      printf("Bad choice of hardening law in plasticEnergy: %d\n",htype);
       break;
   }
   return eP;
@@ -533,341 +1605,4653 @@ void EP_Material::print(){
 //constbox      //*****************New tenor added by wu ling: double* dpdE, double* strs_dDdp_bar ****************
 int EP_Material::constbox(double* dstrn, double* strs_n,  double* strs, double* statev_n, double* statev, double** Cref, double*** dCref, double* tau, double** dtau, double** Calgo, double alpha, double* dpdE, double* strs_dDdp_bar,double *Sp_bar, double** c_g, double* dFd_d_bar, double* dstrs_dFd_bar, double *dFd_dE, double** c_gF, double* dpdFd, double* dFddp, int kinc, int kstep, double dt){
 
- return (1);
-}
-//******************************************************
-//costboxSecant
-//****************************************************
-int EP_Material::constboxSecantMixte(double* dstrn, double* strs_n,  double* strs, double* statev_n, double* statev, double **Calgo, double** Csd, double*** dCsd, double** dCsdp_bar, double* dnu, double& dnudp_bar, double alpha, double* dpdE, double* dstrsdp_bar, double** c_g, int kinc, int kstep, double dt, bool forceZero, bool forceRes){
-  return (1);
-}
+	int i,j,k,error;
+	double p_n,p, Gamma;
+	double twomu;
+        double twok;
+ 
+	static double* dtwomu;
+        static double* dtwok;
+	static double*** dCalgo;
+	static double** Idev;
+	static double* pstrn;
+	static double* pstrn_n;
+	static double** Cn;
+        static double* dDdE;                 //*********add by wu ling 
+        double  dDdp_bar;                 //*********add by wu ling 
+        double  D;                    //*********add by wu ling 
+        static double** strs_dDdE;           //*********add by wu ling 
 
-//end of costboxSecant
 
-//**************************************************************
-// EP_Material::constbox for large deformation 
-//*************************************************************************************************************
-int EP_Material::constboxLargD(double* dstrn, double* strs_n,  double* strs, double* statev_n, double* statev, double **Calgo, double** Csd, double*** dCsd, double** dCsdp_bar, 
-double* dnu, double &dnudp_bar, double alpha, double* dpdE, double* dstrsdp_bar, double** c_g, int kinc, int kstep, double dt){
+ 
+	//allocate memory (only once!)
+        static bool initialized=false;
+	static bool initCn=false; 
+        if(!initialized)
+        {
+	  mallocvector(&dtwomu,6);
+          mallocvector(&dtwok,6);
+	  malloctens3(&dCalgo,6,6,6);
+	  mallocmatrix(&Idev,6,6);
+	  mallocvector(&pstrn,6);
+	  mallocvector(&pstrn_n,6);
 
-  return (1);
-}
-//end of constbox large deformation
+          mallocvector(&dDdE,6);         //*********add by wu ling 
+          mallocmatrix(&strs_dDdE,6,6); //*********add by wu ling 
+	  initialized = true;
+        }
+        cleartens2(dtwomu);
+        cleartens2(dtwok);
+        cleartens6(dCalgo);
+        cleartens4(Idev);
+        cleartens2(pstrn);
+        cleartens2(pstrn_n);
+        cleartens2(dDdE);
+        cleartens4(strs_dDdE);
+
+
+	//fill Idev 
+	for(i=0;i<3;i++){
+	  for(j=0;j<3;j++){
+	    Idev[i][j] = -1./3.;
+	  }
+	  Idev[i][i]+=1.;
+	  Idev[i+3][i+3] = 1.;
+	}
 
-//****************************************************
-// consbox called by MTSecNtr 2rd order method
-//****************************************************
+	p_n = statev_n[pos_p];
+	copyvect(&(statev_n[pos_pstrn]),pstrn_n,6);
+	p=0.;
+        
+        if(dam)
+        {
+          // put in effective space
+          D = statev_n[pos_dam+2];
+          for(i=0;i<6;i++)
+          {
+            if( D<1.)
+            {
+              strs_n[i] = strs_n[i]/(1.-D);
+	      strs[i]   = strs[i]/(1.-D);
+            }
+          }
+        }
 
-int EP_Material::constbox_2ndNtr(double *DE, double* dstrn, double* strs_n,  double* strs, double* statev_n, double* statev,  ELcc* LCC, EPR* epresult, double alpha, double** c_g, int kinc, int kstep, double dt){
 
+	if(htype>10){
+            error=constbox_ep(E, nu, sy0, htype, hmod1, hmod2, hp0, alpha_DP, m_DP, nup, hexp, dstrn, strs_n, strs, pstrn_n, pstrn, p_n, &p, &twomu, dtwomu, &twok, dtwok, Calgo, dCalgo,dpdE,0);
+        }
+        else 
+        {
+            error=constbox_ep(E, nu, sy0, htype, hmod1, hmod2, hp0, hexp, dstrn, strs_n, strs, pstrn_n, pstrn, p_n, &p, &twomu, dtwomu, Calgo, dCalgo,dpdE,0);
+        }      
 
- return (1);           
-}
-// end of constbox_2ndNtr()
 
+	if(dam)
+        {
+				                 // put back old stress in apparent space
+	   D = statev_n[pos_dam+2];
+	   for(i=0;i<6;i++)
+	   {
+	     if( D<1.)
+	     {
+		strs_n[i] = strs_n[i]*(1.-D);
+	     }
+	     else
+	     {
+		 strs_n[i] = 0.;
+	     }
+	    }
+        }
 
-//****************************************************
-// consbox called by 2rd order method
-//****************************************************
+	//update state variables
+	addtens2(1., statev_n, 1., dstrn, statev); 
+	copyvect(strs, &(statev[pos_strs]),6);
+	copyvect(dstrn, &(statev[pos_dstrn]),6);
+	copyvect(pstrn, &(statev[pos_pstrn]),6);
+	statev[pos_p]=p;
+	statev[pos_dp]=p-p_n;
+	statev[pos_twomu]=twomu;  
+	if(htype>10){
+		 statev[pos_twok] =twok;
+        }
 
-int EP_Material::constbox_2order(int mtx, double *DE, double* dstrn, double* strs, double* statev_n, double* statev,  double **Calgo, Lcc* LCC, YieldF* YF, double** c_g, int kinc, int kstep, double dt){
+	statev[pos_eqstrs]= vonmises(strs); 
 
+       // prepare for damage box which need effective stress.
+	//copyvect(strs_n, &(statev_n[6]),6);
 
-  return (1);
-}
+#ifdef NONLOCALGMSH
+        if(dam && localDamage)
+        {
+          statev[pos_dam]= statev[pos_p];
+	  statev[pos_dam+1]= statev[pos_dp];
+        }
+#else
+// add by wu ling try nonlocal mehod without finite element cacilation
+        if(dam)
+        {
+          statev[pos_dam]= statev[pos_p];
+	  statev[pos_dam+1]= statev[pos_dp];
+        }
+#endif
 
-//end of consbox_2order
 
-//****************************************************
-//****************************************************
+	tau=NULL;
+	dtau=NULL;
 
-void EP_Material::get_refOp(double* statev, double** C, int kinc, int kstep){
 
+    
 	
-	double twomu, threekappa, D;
-
-	if(kinc<2 && kstep==1){
-	   get_elOp(C);
+	makeiso(E/(3.*(1.-2.*nu)), 0.5*twomu, Cref);
+		
+	for(i=0;i<6;i++){
+		for(j=0;j<6;j++){
+			for(k=0;k<6;k++){
+				dCref[i][j][k] = Idev[i][j]*dtwomu[k];
+			}
+		}
 	}
-	//if(kinc<2 ){
-                //get_elOD(statev,C);
-	//}
-	else{
-                twomu = statev[pos_twomu];
-		threekappa = E/(1.-2.*nu); 
 
 
-                if(dam){                                           //*********add by wu ling 
-                        D = statev[pos_dam+2];                     //***********13.04.2011********
-		        twomu = twomu*(1-D);
-		        threekappa = threekappa*(1-D);
-                 }
-		makeiso(threekappa/3.,twomu/2.,C);
-	}
+ //***** By Wu Ling 06/04/2011************************************************************************************
+        
+       cleartens2(strs_dDdp_bar);    //stress*dDdp_bar
+       cleartens4(strs_dDdE);        //  stress*dDdE
 
-}
+     //TO DO: CALL DAMAGE BOX, IF DAM != NULL
 
-void EP_Material::get_elOD(double* statev, double** Cel)
-{
-     get_elOp(Cel);
-     if(dam)
-     {
-       double damage = statev[pos_dam+2];
-       for(int i=0; i < 6; i++)
-         for(int j=0; j < 6; j++)
-           Cel[i][j]*=1.-damage;
-    }
-}
+       if(dam){
+               // get damage parameters
+                dDdp_bar=0.0;
+		dam->damagebox(statev_n, statev, pos_strn, pos_strs, pos_dam, Calgo, dDdE, &dDdp_bar, alpha, kinc, kstep);
 
+               // up date reference operator Cref, Calgo and dCref dCalgo according to damage
+                 D = statev[pos_dam+2];
 
-void EP_Material::get_elOp(double** Cel){
+	        //define tensor from effective stress
 
-	compute_Hooke(E,nu,Cel);
-}
+                 //addtens2( D, strs , 0.0, strs, D_strs_eff); // D*strs_efficvtiv add by wu ling
 
-void EP_Material::unload_step(double* dstrn,double* strs_n, double* statev_n, int kinc, int kstep){
+//*****
 
-       if(kinc == 1 && kstep==1){
-		return;
-	}
+                 for(i=0;i<6;i++){
+		         for(j=0;j<6;j++){
+			         for(k=0;k<6;k++){
+				            dCref[i][j][k] = (1.0-D)*dCref[i][j][k];
+                                            dCalgo[i][j][k] = (1.0-D)*dCalgo[i][j][k];
+			         }
+		         }
+                          //  get stress*dDdp_bar
+                         strs_dDdp_bar[i]= -1.*strs[i]*dDdp_bar;
+	         }
 
-	int i,error;
-	static double **C0=NULL;
-        static double **invC0=NULL;
-	static double *strs=NULL;
-        static double *udstrn=NULL;
-        if(C0==NULL)
-        {
-  	  mallocmatrix(&C0,6,6);
-	  mallocmatrix(&invC0,6,6);	
-          mallocvector(&strs,6);
-          mallocvector(&udstrn,6);
-        }
-        cleartens4(C0);
-        cleartens4(invC0);
-        cleartens2(strs);
-        cleartens2(udstrn);
 
 
+                 for(i=0;i<6;i++){
+	            for(j=0;j<6;j++){
+		            for(k=0;k<6;k++){
+			               dCref[i][j][k] = dCref[i][j][k]-Cref[i][j]*dDdE[k];
+                                       dCalgo[i][j][k] = dCalgo[i][j][k]-Calgo[i][j]*dDdE[k];
 
-	get_elOD(statev_n, C0);
-	inverse(C0,invC0,&error,6);
-	if(error!=0) printf("problem while inversing C0 in unload_step of MTSecF\n");
+		            }
+                    //  get stress*dDdE,
 
-	copyvect(&statev_n[pos_strs], strs, 6);        //stress in at tn
-        contraction42(invC0, strs, udstrn);          //unloading strain of composite at tn
-       
- // update statev_n to keep the imformation for residual condition 
+                            strs_dDdE[i][j]=strs[i]*dDdE[j]; 
+	            }        
+                    
+                 }
 
-        for(i=0;i<6;i++){
-	strs_n[i]=0.0;	
-        statev_n[pos_strs +i]=0.0;                                   //residual stress is 0
-        statev_n[pos_strn +i]= statev_n[pos_strn +i]- udstrn[i];      //residual strain 
-        statev_n[pos_dstrn +i]= dstrn[i]+ udstrn[i];    // strain increment in composte
+                 addtens4((1.-D),Cref,0.0,Idev,Cref);
+                 addtens4((1.-D),Calgo,0.0,Idev,Calgo);
 
-        dstrn[i]= statev_n[pos_dstrn +i];
-      	}
+                 // add extra item on Calgo to conside the damage ( stress*dDdE)
+                 addtens4 (1.0, Calgo, -1.0, strs_dDdE, Calgo);
+                 
+		 //after computing Jacobian tensor put stress in apparent space
+                 for(i=0;i<6;i++)
+                 {
+	            if( D<1.)
+            	    {
+                      strs[i] = strs[i]*(1.-D);
+            	    }
+            	    else
+	            {
+              	      strs[i] = 0.;
+	            }            
+          	 }
+                 copyvect(strs, &(statev[pos_strs]),6);
+
+                 // put back old stress in apparent space
+                 //   D = statev_n[pos_dam+2];
+                    //for(i=0;i<6;i++)
+                    //{
+                       //if( D<1.)
+                       //{
+                        //strs_n[i] = strs_n[i]*(1.-D);
+                       //}
+                       //else
+                       //{
+                        //strs_n[i] = 0.;
+                       //}
+                    //}
+                  //copyvect(strs_n, &(statev_n[6]),6);
+       }
+
+       //***** end of By Wu Ling 13/04/2011**********************************************************************************
+
+
+
+	//Elastic-plastic transition: use explicit estimate (may improve convergence during elastic-plastic transitions)
+	/*		
+	if( (statev[25] > 0 && statev_n[25] == 0) || (statev[25]==0 && statev_n[25] > 0)){
+		alpha = 0.;
+	}
+	*/
 
-}
+	//generalized mid-point rule
+	if(alpha < 1.){
 
+		//get reference operator of the previous time step
+                if(!initCn)
+                {
+                  mallocmatrix(&Cn,6,6);
+		  initCn=true;
+                }
+                cleartens4(Cn);
 
+                get_refOp(statev_n, Cn, kinc, kstep);
+		
+		if(alpha==0){
+			copymatr(Cn,Cref,6,6);
+			cleartens6(dCref);
+		}
+		else{
 
-//*******************  Stochastic  EP  *************************
-//Stochastic RATE-INDEPENDENT ELASTO-PLASTICITY
-//PROPS: MODEL, iddam, E, nu, sy0, htype, hmod1, (hmod2, hp0), hexp 
-//STATEV: strn, strs, dstrn, pstrn, p, dp, 2*mu_iso
-//**************************************************************
-//constructor
-EP_Stoch_Material::EP_Stoch_Material(double* props, int idmat):Material(props, idmat){
-	int k;
-	int iddam, idclength, Flag_stoch ;	
+			addtens4((1.-alpha),Cn,alpha,Cref,Cref);
 
-	iddam = (int)props[idmat+1];
-        idclength = (int)props[idmat+2];
+			for(i=0;i<6;i++){
+				for(j=0;j<6;j++){
+					for(k=0;k<6;k++){
+						dCref[i][j][k] *= alpha;
+					}
+				}
+			}
+		}
+		//freematrix(Cn,6); // not anymore as now static
+	}
 
-	k=idmat+3;          
-	_E = props[k++];
-	_nu = props[k++];
-	_sy0 = props[k++];
-	htype = (int) props[k++];
-	_hmod1 = props[k++];
+	
 
-	//hardening models with two hardening moduli
-	if(htype==H_LINEXP)
+	//free memory not anymore as now static
+//	free(dtwomu);
+//	freetens3(dCalgo,6,6);
+//	freematrix(Idev,6);	
+//	free(pstrn);
+//	free(pstrn_n);
+
+//        free(dDdE);                     //*********add by wu ling 
+//        freematrix(strs_dDdE,6);       //*********add by wu ling 
+
+        clength->creat_cg(statev_n, pos_p, c_g);       //*********add by wu ling 
+ 
+        return (error);
+
+}
+//******************************************************
+//costboxSecant
+//****************************************************
+/*int EP_Material::constboxSecant(double* dstrn, double* strs_n,  double* strs, double* statev_n, double* statev, double **Calgo, double** Csd, double*** dCsd, double** dCsdp_bar, 
+double* dnu, double &dnudp_bar, double alpha, double* dpdE, double* dstrsdp_bar, double** c_g, int kinc, int kstep, double dt){
+
+	int i,j,k,error;
+	double p_n,p;
+        double kappa,tmp;
+        double mu;
+	double twomu;
+	
+	static double* dtwomu = NULL;
+	static double** Idev = NULL, **Ivol = NULL;
+	static double* pstrn = NULL;
+	static double* pstrn_n = NULL;
+        static double* strs_nef = NULL;             // effective stress at tn (residual stress) 
+        static double* strs_ef = NULL;              // effective stress at tn+1 (updated stress) 
+
+        static double* dstrs = NULL, *dstrs_ef = NULL;                // increment of stress 
+
+        static double* dstrs_efdev = NULL;            // dev of increment of stress
+        static double* strs_nefdev = NULL;            // dev of increment of stress at tn
+
+        static double* dDdE = NULL;                 //*********add by wu ling 
+        static double* mat1 = NULL, *mat2 = NULL;
+        static double* dkappa = NULL, *dmu = NULL;
+
+        double dstrs_tra;             // trace of increment of stress
+        double dstrn_tra;
+        double dstrs_eq;
+        double dstrs_efeq;
+        double dstrn_eq;
+        double dDdp_bar;                 //*********add by wu ling 
+        double D;                    //*********add by wu ling 
+// variables for operation
+        double dD;                  // increment of D
+        double dkappadp_bar, dmudp_bar, dkappadD, dmudD, num1, num2, num3;
+
+        static double **strs_dDdE=NULL;
+
+        static bool initialized = false;
+        double toleranceDiv=1.e-20;
+	//allocate memory
+        if(!initialized)
         {
-		_hmod2 = props[k++];
-                _hp0 = 0.;
+          initialized = true;
+  	  mallocvector(&dtwomu,6);
+	  mallocmatrix(&Idev,6,6);
+	  mallocmatrix(&Ivol,6,6);
+	  mallocvector(&pstrn,6);
+	  mallocvector(&pstrn_n,6);
+          mallocvector(&strs_nef,6);
+          mallocvector(&strs_ef,6);
+          mallocvector(&dstrs,6);
+          mallocvector(&dstrs_ef,6);
+          mallocvector(&dstrs_efdev,6);
+          mallocvector(&strs_nefdev,6);
+          mallocvector(&dDdE,6);         //*********add by wu ling 
+          mallocvector(&dkappa,6);       
+          mallocvector(&dmu,6);          
+          mallocvector(&mat1,6);  
+          mallocvector(&mat2,6); 
+
+          mallocmatrix(&strs_dDdE,6,6); 
         }
-        else if(htype==H_POW_EXTRAPOL){
-		_hmod2 = props[k++];
-                _hp0   = props[k++];
-	}
-	else{
-		_hmod2 = 0.;
-                _hp0   = 0.;
+        cleartens2(dtwomu);
+	cleartens4(Idev);
+	cleartens4(Ivol);
+	cleartens2(pstrn);
+	cleartens2(pstrn_n);
+        cleartens2(strs_nef);
+        cleartens2(strs_ef);
+        cleartens2(dstrs);
+        cleartens2(dstrs_ef);
+        cleartens2(dstrs_efdev);
+        cleartens2(strs_nefdev);
+        cleartens2(dDdE);         //*********add by wu ling 
+        cleartens2(dkappa);       
+        cleartens2(dmu);          
+        cleartens2(mat1);  
+        cleartens2(mat2);  
+        cleartens4(strs_dDdE);
+        
+
+	//fill Idev and Ivol
+
+	for(i=0;i<3;i++){
+		Idev[i][i]=1.;
+		Idev[i+3][i+3]=1.;
+		for(j=0;j<3;j++){
+			Ivol[i][j]=1./3.;
+			Idev[i][j]=Idev[i][j]-1./3.;
+		}
 	}
-	_hexp = props[k];
+	
 
-	nsdv = 28;
-	pos_strn=0;
-	pos_strs=6;
-	pos_dstrn=12;
-	pos_pstrn=18;
-	pos_p = 24;
-	pos_dp = 25;
-	pos_twomu = 26;
-	pos_eqstrs = 27;
-        
-        if(_E < 1.0e-6){
-            pos_E = nsdv;
-            nsdv += 1;}
-        else{ pos_E = 0; }
+	p_n = statev_n[pos_p];
+	copyvect(&(statev_n[pos_pstrn]),pstrn_n,6);
+	p=0.;
 
-        if(_nu < 1.0e-6){
-            pos_nu = nsdv;
-            nsdv += 1;}
-        else{ pos_nu = 0; }
+       
+       //convert stress into effective stress at tn, the return mapping will not be changed then
+       D=0.0;
+       if(dam){
+               D = statev_n[pos_dam+2];
+       }
 
-        if(_sy0 < 1.0e-6){
-            pos_sy0 = nsdv;
-            nsdv += 1;}
-        else{ pos_sy0 = 0; }
+       for(i=0;i<6;i++){
+               strs_nef[i]=strs_n[i]/(1.0-D);
+       }
+
+	error=constbox_ep(E, nu, sy0, htype, hmod1, hmod2, hp0, hexp, dstrn, strs_nef, strs_ef, pstrn_n, pstrn, p_n, &p, &twomu, dtwomu, Calgo, dCsd,dpdE,1);
+       
+       // update state variable, and keep the effective stress in state variable for the compuation of damage
+
+	addtens2(1., statev_n, 1., dstrn, statev); 
+	copyvect(strs_ef, &(statev[pos_strs]),6);
+	copyvect(dstrn, &(statev[pos_dstrn]),6);
+	copyvect(pstrn, &(statev[pos_pstrn]),6);
+	statev[pos_p]=p;
+	statev[pos_dp]=p-p_n;
+	statev[pos_twomu]=twomu;  
+	statev[pos_eqstrs]= vonmises(strs_ef); 
+#ifdef NONLOCALGMSH
+#else
+        statev_n[pos_dp]=p-p_n;
+#endif
+	copyvect(strs_nef, &(statev_n[pos_strs]),6);
+
+
+       //*****************************************
+       dD=0.0;
+#ifdef NONLOCALGMSH
+#else
+// add by wu ling try nonlocal mehod without finite element cacilation
+            if(dam)
+            {
+              statev_n[pos_dam]= statev_n[pos_p];
+  	      statev_n[pos_dam+1]= statev_n[pos_dp]; 
+            }
+#endif
+
+       if(dam){
+               // get damage parameters
+                dDdp_bar=0.0;
+		dam->damagebox(statev_n, statev, pos_strn, pos_strs, pos_dam, Calgo, dDdE, &dDdp_bar, 1., kinc, kstep);
+
+              // update state variable, and convert the effective stress in state variable back
+          
+               for(i=0;i<6;i++){
+               statev_n[6+i]=strs_nef[i]*(1.0-D);
+               } 
+
+               D = statev[pos_dam+2];
+               for(i=0;i<6;i++){
+               statev[6+i]=strs_ef[i]*(1.0-D);
+               }
+               dD = D-statev_n[pos_dam+2];
+       }
+               
+              // make Csd, secant operator*****************************************************************************************************************************
+
+                for(i=0;i<6;i++){
+                 strs[i]=statev[6+i];
+                 dstrs[i]=statev[6+i]-statev_n[6+i];
+                 dstrs_ef[i]=strs_ef[i]-strs_nef[i];
+               }
+                
+      //check
+      //        printf(" vomin residusl stress of matrix is %e\n", vonmises(strs_nef)); 
+
+               // Compute the trace of a second order tensor-dstrn amd dstrs 
+               dstrs_tra = trace(dstrs_ef);
+               dstrn_tra = trace(dstrn);
+
+               // Extract the deviatoric part of a second order tensor -dstrn amd dstrs 
+               dev(dstrs_ef, dstrs_efdev);  
+               dev(strs_nef, strs_nefdev);  
    
-        if(_hmod1 < 1.0e-6){
-            pos_hmod1 = nsdv;
-            nsdv += 1; }
-        else{ pos_hmod1 = 0;}
 
-        if((htype==H_LINEXP || htype==H_POW_EXTRAPOL) && (_hmod2 < 1.0e-6)){
-            pos_hmod2 = nsdv;
-            nsdv += 1; 
-        }
-        else{ pos_hmod2 = 0;}
+               // Compute the von Mises equivalent stress 
+               dstrs_eq = vonmises(dstrs_ef);
 
-        if((htype==H_POW_EXTRAPOL) && (_hp0 < 1.0e-6)){
-            pos_hp0 = nsdv;
-            nsdv += 1; 
-        }
-        else{ pos_hp0 = 0;}
+               // Compute the equivalent strain scalar 
+               dstrn_eq = eqstrn(dstrn);
 
+               // make Csd
+               if(fabs(dstrn_tra)>toleranceDiv and p-p_n >0.){
+                  kappa = dstrs_tra/(3.*dstrn_tra);
+                  if(dam){
+                       kappa = kappa*(1.-D);
+                  }
+               } 
+               else{
+                  kappa = E/3./(1.-2.*nu)*(1.-D);
+               }
 
-        if(_hexp < 1.0e-6){
-            pos_hexp = nsdv;
-            nsdv += 1; }
-        else{ pos_hexp = 0;}
 
-	dam = init_damage(props,iddam);
-	if(dam){
-  	        pos_dam = nsdv;
-		nsdv += dam->get_nsdv();
-                Flag_stoch = dam->get_pos_DamParm1();
+               if(fabs(dstrn_eq) >toleranceDiv and p-p_n >0.){
+                  mu = dstrs_eq/(3.*dstrn_eq);
+                  if(dam){
+                     mu = mu*(1.-D);
+                 }
+               }
+               else{                 
+                  mu = E/2./(1.+nu)*(1.-D);
+               }
+	       makeiso(kappa, mu, Csd);
 
-                if(Flag_stoch > 0){
-                    pos_DamParm1 = pos_dam + dam->get_pos_DamParm1();
-                    pos_DamParm2 = pos_dam + dam->get_pos_DamParm2();
+       // dCsd/dstrain  and dCsd/dp_bar*****************
+
+               for(i=0;i<6;i++){
+                    dkappa[i] = 0.0;
+               }
+
+          //1. dkappa/dstrain, /dp_bar
+
+            if(dam){
+                  
+               dkappadD =  -E/(3.*(1.-2.*nu));
+               for(i=0;i<6;i++){
+                 dkappa[i] = dkappa[i]+ dkappadD*dDdE[i];
+               }  
+               dkappadp_bar = dkappadD*dDdp_bar;
+             }
+
+          //2. dmu/dstrain, /dp_bar
+
+            for (i=0; i<6; i++) {
+                     mat1[i] = 0.;
                 }
-                else{
-                    pos_DamParm1 = 0;
-                    pos_DamParm2 = 0;
+                for(i=0;i<6;i++){
+                     for (j=0; j<6; j++) {
+                           mat1[i] = mat1[i] + dstrs_efdev[j]*Calgo[j][i];
+                     }
                 }
-	}
-        else{
-            pos_DamParm1 = 0;
-            pos_DamParm2 = 0;
-        }
 
-        clength = init_clength(props,idclength);
+                for(i=0;i<6;i++){
+		  if(fabs(dstrn_eq)>toleranceDiv and p-p_n >0.)
+                    dmu[i] = ((1.-D)*(1.-D)*mat1[i])/(6.*mu*dstrn_eq *dstrn_eq); 
+		  else
+	            dmu[i] = 0.;
+                }
+               
+                dev(dstrn, mat1);  
+                for(i=0;i<6;i++){
+                  if(fabs(dstrn_eq)>toleranceDiv and p-p_n >0.)
+                    dmu[i] = dmu[i]-2.0*mu*mat1[i]/(3.0*dstrn_eq *dstrn_eq); 
+                }
 
-}
+                if(dam){
+                
+                       num1 = vonmises(dstrs_ef);
+                      
+                       if(fabs(dstrn_eq)>toleranceDiv)
+                         dmudD = -mu/(1.-D); 
+                       else
+                         dmudD = -E/2./(1.+nu); 
+
+                       for(i=0;i<6;i++){
+                            dmu[i] = dmu[i]+ dmudD*dDdE[i]; 
+                       }
+                      dmudp_bar= dmudD*dDdp_bar;
+                }
 
+           //3. dCsd/dstrain, /dp_bar
 
-bool EP_Stoch_Material::eqstrs_exist() const
-{
-        return true;
-}
+                for(i=0;i<6;i++){
+                        for(j=0;j<6;j++){
+                                 for(k=0;k<6;k++){   
+            
+                                         dCsd[i][j][k] = 3.0*Ivol[i][j]*dkappa[k]+ 2.0*Idev[i][j]*dmu[k]; 
+                                  }
+                                 dCsdp_bar[i][j]= 3.0*Ivol[i][j]*dkappadp_bar+ 2.0*Idev[i][j]*dmudp_bar;
+                         }
+                } 
+          //4. dnu/dstrain, /dp_bar
+             
+                tmp = (3.*kappa + mu);
+                for(i=0;i<6;i++){
+                   dnu[i] = 9.*mu/(2.*tmp*tmp)*dkappa[i]-9.*kappa/(2.*tmp*tmp)*dmu[i];
+                  
+                }
+                dnudp_bar = 9.*mu/(2.*tmp*tmp)*dkappadp_bar-9.*kappa/(2.*tmp*tmp)*dmudp_bar;
+
+
+           // up date  Calgo and dstrsdp_bar 
+                     
+                 for(i=0;i<6;i++){
+                     dstrsdp_bar[i]= -1.*strs_ef[i]*dDdp_bar;
+	            for(j=0;j<6;j++){
+		           
+                    //  get stress*dDdE,
+                            strs_dDdE[i][j]=strs_ef[i]*dDdE[j]; 
+	            }        
+                 }
 
+           
+                 // add extra item on Calgo to conside the damage ( stress*dDdE)
+                 addtens4 ((1.-D), Calgo, -1.0, strs_dDdE, Calgo);
+                 //printf("j2plast iteration:  p: %.10e\n", statev[pos_p]);
 
 #ifdef NONLOCALGMSH
-int EP_Stoch_Material::get_pos_currentplasticstrainfornonlocal() const 
-{
-	return pos_p;
+#else
+// add by wu ling try nonlocal mehod without finite element cacilation
+            if(dam)
+            {
+              statev[pos_dam]= statev[pos_p];
+  	      statev[pos_dam+1]= statev[pos_dp]; 
+            }
+#endif
+
+        clength->creat_cg(statev_n, pos_p, c_g);        //*********add by wu ling 
+
+        return error;               
 }
-int EP_Stoch_Material::get_pos_effectiveplasticstrainfornonlocal() const
-{
-	if(dam)
-	{
-		return pos_dam;
+//end of costboxSecant
+
+// constboxSecant with Cs computed from Zero stress
+int EP_Material::constboxSecantZero(double* dstrn, double* strs_n,  double* strs, double* statev_n, double* statev, double **Calgo, double** Csd, double*** dCsd, double** dCsdp_bar, 
+double* dnu, double &dnudp_bar, double alpha, double* dpdE, double* dstrsdp_bar, double** c_g, int kinc, int kstep, double dt){
+
+
+	int i,j,k,error;
+	double p_n,p;
+        double kappa,tmp;
+        double mu;
+	double twomu;
+
+
+	static double* dtwomu=NULL;
+	static double** Idev=NULL, **Ivol=NULL;
+	static double* pstrn=NULL;
+	static double* pstrn_n=NULL;
+        static double* strs_nef=NULL;             // effective stress at tn (residual stress) 
+        static double* strs_ef=NULL;              // effective stress at tn+1 (updated stress) 
+        static double* strs_efdev=NULL;            // dev of increment of stress
+        static double* dDdE=NULL;                 //*********add by wu ling 
+        static double* mat1=NULL;
+        static double* dkappa=NULL, *dmu=NULL;
+
+        static double** strs_dDdE=NULL;
+
+        double strs_tra;             // trace of increment of stress
+        double dstrn_tra;
+        double strs_eq;
+        double dstrn_eq;
+
+        double  dDdp_bar;                 //*********add by wu ling 
+        double  D;                    //*********add by wu ling 
+
+
+// variables for operation
+        double dkappadp_bar, dmudp_bar, dkappadD, dmudD, num1;
+
+	//allocate memory
+        static bool initialized = false;
+        double toleranceDiv=1.e-20;
+
+        if(!initialized)
+        {
+          initialized = true;
+	  mallocvector(&dtwomu,6);
+	  mallocmatrix(&Idev,6,6);
+	  mallocmatrix(&Ivol,6,6);
+	  mallocvector(&pstrn,6);
+	  mallocvector(&pstrn_n,6);
+          mallocvector(&strs_nef,6);
+          mallocvector(&strs_ef,6);
+          mallocvector(&strs_efdev,6);
+          mallocvector(&dDdE,6);         //*********add by wu ling 
+          mallocvector(&dkappa,6);       
+          mallocvector(&dmu,6); 
+          mallocvector(&mat1,6);  
+          mallocmatrix(&strs_dDdE,6,6); 
+         }
+//printf("dstrn in matrix is %e\n", dstrn[0]);
+	//fill Idev and Ivol
+	 cleartens2(dtwomu);
+	 cleartens4(Idev);
+	 cleartens4(Ivol);
+	 cleartens2(pstrn);
+	 cleartens2(pstrn_n);
+         cleartens2(strs_nef);
+         cleartens2(strs_ef);
+         cleartens2(strs_efdev);
+         cleartens2(dDdE);         //*********add by wu ling 
+         cleartens2(dkappa);       
+         cleartens2(dmu); 
+         cleartens2(mat1);  
+         cleartens4(strs_dDdE);
+
+
+
+	for(i=0;i<3;i++){
+		Idev[i][i]=1.;
+		Idev[i+3][i+3]=1.;
+		for(j=0;j<3;j++){
+			Ivol[i][j]=1./3.;
+			Idev[i][j]=Idev[i][j]-1./3.;
+		}
 	}
-	return -1;
-}
+	
 
-int EP_Stoch_Material::get_pos_damagefornonlocal() const
-{
-	if(dam) return pos_dam+2;
-        return -1;
-}
-double EP_Stoch_Material::getElasticEnergy (double* statev)
-{
-  double eE = 0.;
-  int i;
-  static double* strn = NULL;
-  static double* pstrn = NULL;
-  static double* strs = NULL;
-  //static double**CelD = NULL;
-  if(strn == NULL)
-  {
-    mallocvector(&strn,6);
-    mallocvector(&pstrn,6);
-    mallocvector(&strs,6);
-  }
-  cleartens2(strn);
-  cleartens2(pstrn);
-  cleartens2(strs);
+	p_n = statev_n[pos_p];
 
-  copyvect(&(statev[pos_strn]), strn,6);
-  copyvect(&(statev[pos_pstrn]),pstrn,6);
-  copyvect(&statev[pos_strs], strs, 6);
-  //enegry due to damage has been removed
-  for (i =0; i< 6; i++) eE+=0.5*(strs[i]*(strn[i]-pstrn[i]));
+        copyvect(&(statev_n[pos_pstrn]),pstrn_n,6);
+	p=0.;
 
-  return eE;
+       
+       //convert stress into effective stress at tn, the return mapping will not be changed then
+       D=0.0;
+       if(dam){
+               D = statev_n[pos_dam+2];
+       }
+
+       for(i=0;i<6;i++){
+               strs_nef[i]=strs_n[i]/(1.0-D);
+        }
+   // printf("the trace of residual stress in matrix is %e\n",trace(strs_n));
+	error=constbox_ep(E, nu, sy0, htype, hmod1, hmod2, hp0, hexp, dstrn, strs_nef, strs_ef, pstrn_n, pstrn, p_n, &p, &twomu, dtwomu, Calgo, dCsd,dpdE,0);
+       
+       // update state variable, and keep the effective stress in state variable for the compuation of damage
+
+	addtens2(1., statev_n, 1., dstrn, statev); 
+	copyvect(strs_ef, &(statev[pos_strs]),6);
+	copyvect(dstrn, &(statev[pos_dstrn]),6);
+	copyvect(pstrn, &(statev[pos_pstrn]),6);
+	statev[pos_p]=p;
+	statev[pos_dp]=p-p_n;
+	statev[pos_twomu]=twomu; 
+	statev[pos_eqstrs]= vonmises(strs);  
+ 
+	copyvect(strs_nef, &(statev_n[pos_strs]),6);
+
+       //*****************************************
+       if(dam){
+               // get damage parameters
+                dDdp_bar=0.0;
+		dam->damagebox(statev_n, statev, pos_strn, pos_strs, pos_dam, Calgo, dDdE, &dDdp_bar, 1., kinc, kstep);
+
+              // update state variable, and convert the effective stress in state variable back
+
+               for(i=0;i<6;i++){
+               statev_n[6+i]=strs_nef[i]*(1.0-D);
+               } 
+
+               D = statev[pos_dam+2];
+               for(i=0;i<6;i++){
+               statev[6+i]=strs_ef[i]*(1.0-D);
+               }
+       }
+               
+
+        // make Csd, secant operator **********************************************************************************
+//check
+
+//if(p-p_n>1.e-8){
+              for(i=0;i<6;i++){
+                 strs[i]=statev[6+i];
+               }
+                
+               // Compute the trace of a second order tensor-dstrn amd strs 
+
+               strs_tra = trace(strs);
+               dstrn_tra = trace(dstrn); //trace(&statev[0]);//trace(dstrn);
+
+               // Extract the deviatoric part of a second order tensor strs_ef 
+               dev(strs_ef, strs_efdev);  
+   
+
+               // Compute the von Mises equivalent stress 
+               strs_eq = vonmises(strs);
+
+
+               // Compute the equivalent strain scalar 
+               dstrn_eq = eqstrn(dstrn);
+
+
+               // make Csd
+               if(fabs(dstrn_tra)>toleranceDiv and p-p_n >0.){
+                 kappa = strs_tra/(3.*dstrn_tra);
+               }
+               else{
+                 kappa = E/3./(1.-2.*nu)*(1.-D);
+               }
+               if(fabs(dstrn_eq) >toleranceDiv and p-p_n >0.){
+                 mu = strs_eq/(3.*dstrn_eq);
+               }
+               else{
+                 mu = E/2./(1.+nu)*(1.-D);
+               }
+
+	       makeiso(kappa, mu, Csd);
+
+       // dCsd/dstrain  and dCsd/dp_bar*****************
+
+            for(i=0;i<6;i++){
+                    dkappa[i] = 0.0;
+               }
+
+          //1. dkappa/dstrain, /dp_bar
+
+               num1=trace(strs_nef)/3.0;
+
+               for(i=0;i<3;i++){
+                    if(fabs(dstrn_tra)>toleranceDiv and p-p_n >0.)
+                      dkappa[i] = -(1.0-D)*num1/(dstrn_tra*dstrn_tra);
+                    else
+                      dkappa[i] = 0.;
+               }
+               
+               dkappadp_bar = 0.0;
+
+              if(dam){
+               
+                      num1=trace(strs_ef)/3.0;
+    
+                      if(fabs(dstrn_tra)>toleranceDiv and p-p_n >0.)
+                            dkappadD =  -num1/(dstrn_tra);
+                      else
+                            dkappadD =  -E/(3.*(1.-2.*nu));
+                      
+
+                      for(i=0;i<6;i++){
+                           dkappa[i] = dkappa[i]+ dkappadD*dDdE[i];
+                      }  
+                      dkappadp_bar = dkappadD*dDdp_bar;
+              }
+
+          //2. dmu/dstrain, /dp_bar
+
+                for(i=0;i<6;i++){
+                     mat1[i] = 0.;
+                     for (j=0; j<6; j++) {
+                           mat1[i] = mat1[i] + strs_efdev[j]*Calgo[j][i];
+                     }
+                }
+
+
+                for(i=0;i<6;i++){
+		  if(fabs(dstrn_eq)>toleranceDiv and p-p_n >0.)
+                    dmu[i] = (1.-D)*(1.-D)*mat1[i]/(6.*mu*dstrn_eq *dstrn_eq); 
+		  else
+	            dmu[i] = 0.;
+                   
+                }
+               
+                dev(dstrn, mat1);  
+                for(i=0;i<6;i++){
+                  if(fabs(dstrn_eq)>toleranceDiv and p-p_n >0.)
+                    dmu[i] = dmu[i]-2.0*mu*mat1[i]/(3.0*dstrn_eq *dstrn_eq); 
+                }
+                     
+                dmudp_bar= 0.0;
+
+                if(dam){
+                
+                       num1 = vonmises(strs_ef);
+
+                       if(fabs(dstrn_eq)>toleranceDiv and p-p_n >0.)
+                         dmudD = -num1/(3.*dstrn_eq); 
+                       else
+                         dmudD = -E/2./(1.+nu); 
+
+                       for(i=0;i<6;i++){
+                            dmu[i] = dmu[i]+ dmudD*dDdE[i]; 
+                       }
+                      dmudp_bar= dmudD*dDdp_bar;
+                }
+
+           //3. dCsd/dstrain, /dp_bar
+
+                for(i=0;i<6;i++){
+                        for(j=0;j<6;j++){
+                                 for(k=0;k<6;k++){   
+            
+                                         dCsd[i][j][k] = 3.0*Ivol[i][j]*dkappa[k]+ 2.0*Idev[i][j]*dmu[k]; 
+                                  }
+                                 dCsdp_bar[i][j]= 3.0*Ivol[i][j]*dkappadp_bar+ 2.0*Idev[i][j]*dmudp_bar;
+                         }
+                } 
+          //4. dnu/dstrain, /dp_bar
+             
+                tmp = (3.*kappa + mu);
+                for(i=0;i<6;i++){
+                   dnu[i] = 9.*mu/(2.*tmp*tmp)*dkappa[i]-9.*kappa/(2.*tmp*tmp)*dmu[i];
+                  
+                }
+                dnudp_bar = 9.*mu/(2.*tmp*tmp)*dkappadp_bar-9.*kappa/(2.*tmp*tmp)*dmudp_bar;
+
+
+           // up date  Calgo and dstrsdp_bar 
+
+                for(i=0;i<6;i++){
+                     dstrsdp_bar[i]= -1.*strs_ef[i]*dDdp_bar;
+	            for(j=0;j<6;j++){
+		           
+                    //  get stress*dDdE,
+                            strs_dDdE[i][j]=strs_ef[i]*dDdE[j]; 
+	            }        
+                 }
+
+             
+                 // add extra item on Calgo to conside the damage ( stress*dDdE)
+                 addtens4 ((1.-D), Calgo, -1.0, strs_dDdE, Calgo);
+                 //printf("j2plast iteration:  p: %.10e\n", statev[pos_p]);
+
+#ifdef NONLOCALGMSH
+#else
+// add by wu ling try nonlocal mehod without finite element cacilation
+        if(dam)
+        {
+          statev[pos_dam]= statev[pos_p];
+  	  statev[pos_dam+1]= statev[pos_dp]; 
+        }
+#endif
+
+        clength->creat_cg(statev_n, pos_p, c_g);      //*********add by wu ling 
+        return error;
+}*/
+//end of costboxSecant
+
+//******************************************************
+//costboxSecant
+//****************************************************
+int EP_Material::constboxSecantMixte(double* dstrn, double* strs_n,  double* strs, double* statev_n, double* statev, double **Calgo, double** Csd, double*** dCsd, double** dCsdp_bar, 
+double* dnu, double &dnudp_bar, double alpha, double* dpdE, double* dstrsdp_bar, double** c_g, int kinc, int kstep, double dt, bool forceZero, bool forceRes){
+
+        int error;
+        int viscmodel=0;
+        double vmod=0., vstressy =0., vexp=0.; 
+	
+        error=constboxSecantMixteGeneric(dstrn, strs_n,  strs, statev_n, statev, Calgo, Csd, dCsd, dCsdp_bar, dnu,  dnudp_bar, alpha, dpdE, dstrsdp_bar, c_g, kinc, kstep, dt, forceZero, forceRes, E, nu, htype, sy0, hexp, hmod1, hmod2, hp0, alpha_DP, m_DP, nup, viscmodel, vmod, vstressy, vexp, false);
+
+        return error;               
 }
+//end of costboxSecant
 
-double EP_Stoch_Material::getPlasticEnergy (double* statev) 
-{
-  double eP = 0.;
-  double p = statev[get_pos_currentplasticstrainfornonlocal()];
-  double sy0, hexp, hmod1, hmod2, hp0;
-  if(pos_sy0 != 0) sy0 = statev[pos_sy0];
-  else sy0 = _sy0;
 
-  if(pos_hexp != 0) hexp = statev[pos_hexp];
-  else hexp = _hexp;
+//**************************************************************
+// EP_Material::constbox for large deformation 
+//*************************************************************************************************************
+int EP_Material::constboxLargD(double* dstrn, double* strs_n,  double* strs, double* statev_n, double* statev, double **Calgo, double** Csd, double*** dCsd, double** dCsdp_bar, 
+double* dnu, double &dnudp_bar, double alpha, double* dpdE, double* dstrsdp_bar, double** c_g, int kinc, int kstep, double dt){
 
-  if(pos_hmod1 != 0) hmod1 = statev[pos_hmod1];
-  else hmod1 = _hmod1;
+
+	int i,j,k,error1,error;
+	double p_n,p;
+        double kappa,tmp;
+        double mu;
+	double twomu;
+
+
+	static double* dtwomu=NULL;
+	static double** Idev=NULL, **Ivol=NULL;
+	static double* pstrn=NULL;
+	static double* pstrn_n=NULL;
+        static double* dstrs=NULL;
+        static double* strs_nef=NULL;             // effective stress at tn (residual stress) 
+        static double* strs_ef=NULL;              // effective stress at tn+1 (updated stress) 
+        static double* dstrs_ef=NULL;              // effective stress at tn+1 (updated stress) 
+        static double* dstrs_efdev=NULL;            // dev of increment of stress
+        static double* strs_nefdev=NULL;            // dev of increment of stress
+        static double* dDdE=NULL;                 //*********add by wu ling 
+        static double* mat1=NULL;
+        static double* dkappa=NULL, *dmu=NULL;
+        static double* Rstrs_n = NULL;
+        static double* Rstrs_nef = NULL;
  
-  if(pos_hmod2 != 0) hmod2 = statev[pos_hmod2];
-  else hmod2 = _hmod2;
+        static double** Fn = NULL;
+        static double** Fnp1 = NULL;
+        static double** Basen = NULL;
+        static double** Basenp1 = NULL;
+        //static double** mtr = NULL;
+        static double** Rnp1 = NULL;
+        static double** Rn = NULL;
+        static double** dR = NULL;
+        static double* RVect = NULL;
 
-  if(pos_hp0 != 0) hp0 = statev[pos_hp0];
-  else hp0 = _hp0;
+        static double** Cel = NULL;
+        static double** invCel = NULL;
+        static double* strs_tr = NULL;  
+        static double* elasstrn=NULL;
 
-  eP = sy0*p;
-  switch(htype) {
-    //POWER LAW HARDENING
-    case H_POW:
-      if(fabs(hexp+1.)!=0) 
-         eP+= hmod1*pow(p,hexp+1.)/(hexp+1.);
-      break;
-    //EXPONENTIAL HARDENING
-    case H_EXP:
-      eP+=hmod1*p;
-      if(fabs(hexp)!=0) eP+=hmod1*(exp(-hexp*p)-exp(0))/(hexp);
-      break;
-    //SWIFT LAW
-    case H_SWIFT:
-      eP-=sy0*p;
+        static double** strs_dDdE=NULL;
+
+        double dstrs_tra;             // trace of increment of stress
+        double dstrn_tra;
+        double dstrs_eq;
+        double dstrn_eq;
+
+        double  dDdp_bar;                 //*********add by wu ling 
+        double  D;                    //*********add by wu ling 
+
+
+// variables for operation
+        double dkappadp_bar, dmudp_bar, dkappadD, dmudD, num1;
+
+	//allocate memory
+        static bool initialized = false;
+        double toleranceDiv=1.e-20;
+        if(!initialized)
+        {
+          initialized = true;
+	  mallocvector(&dtwomu,6);
+	  mallocmatrix(&Idev,6,6);
+	  mallocmatrix(&Ivol,6,6);
+	  mallocvector(&pstrn,6);
+	  mallocvector(&pstrn_n,6);
+          mallocvector(&dstrs,6);
+          mallocvector(&strs_nef,6);
+          mallocvector(&strs_ef,6);
+          mallocvector(&dstrs_ef,6);
+          mallocvector(&dstrs_efdev,6);
+          mallocvector(&strs_nefdev,6);
+          mallocvector(&Rstrs_n,6);
+          mallocvector(&Rstrs_nef,6);
+          mallocvector(&dDdE,6);         //*********add by wu ling 
+          mallocvector(&dkappa,6);       
+          mallocvector(&dmu,6); 
+          mallocvector(&mat1,6);  
+          mallocvector(&strs_tr,6); 
+	  mallocvector(&elasstrn,6);
+	  mallocmatrix(&Cel,6,6);
+	  mallocmatrix(&invCel,6,6);
+
+	  mallocmatrix(&Fn,3,3);
+	  mallocmatrix(&Fnp1,3,3);
+	  mallocmatrix(&Basen,3,3);
+	  mallocmatrix(&Basenp1,3,3);
+//	  mallocmatrix(&mtr,3,3);
+	  mallocmatrix(&Rnp1,3,3);
+	  mallocmatrix(&Rn,3,3);
+	  mallocmatrix(&dR,3,3);
+          mallocvector(&RVect,9);
+
+          mallocmatrix(&strs_dDdE,6,6); 
+         }
+//printf("dstrn in matrix is %e\n", dstrn[0]);
+	//fill Idev and Ivol
+	 cleartens2(dtwomu);
+	 cleartens4(Idev);
+	 cleartens4(Ivol);
+	 cleartens2(pstrn);
+	 cleartens2(pstrn_n);
+         cleartens2(dstrs);
+         cleartens2(strs_nef);
+         cleartens2(dstrs_ef);
+         cleartens2(strs_ef);
+         cleartens2(Rstrs_nef);
+         cleartens2(dstrs_efdev);
+         cleartens2(strs_nefdev);
+         cleartens2(dDdE);         //*********add by wu ling 
+         cleartens2(dkappa);       
+         cleartens2(dmu); 
+         cleartens2(mat1);  
+         cleartens2(strs_tr);
+	 cleartens2(elasstrn);
+         cleartens2(Rstrs_n);
+	 cleartens4(Cel);
+	 cleartens4(invCel);
+         cleartens4(strs_dDdE);
+
+        for (i=0; i<3; i++){
+            for (j=0; j<3; j++){
+             Fn[i][j] = 0.0;
+             Fnp1[i][j] = 0.0;
+             Rnp1[i][j] = 0.0;
+             Rn[i][j] = 0.0;
+             dR[i][j] = 0.0;
+             Basen[i][j] = 0.0;
+             Basenp1[i][j] = 0.0;
+ //            mtr[i][j] = 0.0;
+             RVect[3*i+j]=0.;
+            }
+        } 
+
+        if( kinc==1 and kstep==1){
+               for (i=0; i<3; i++){
+                   for (j=0; j<3; j++){
+                       Rnp1[i][j] = 0.0;
+                       Rn[i][j] = 0.0;
+                       dR[i][j] = 0.0;
+                       Fn[i][j] = 0.0;
+                       Fnp1[i][j] = 0.0;
+                       //Basen[i][j] = 0.0;
+                       //Basenp1[i][j] = 0.0;
+                   }
+                   Rnp1[i][i] = 1.0;
+                   Rn[i][i] = 1.0;
+                   dR[i][i] = 1.0;
+                   Fn[i][i] = 1.0;
+                   Fnp1[i][i] = 1.0;
+                   //Basen[i][i] = 1.0;
+                   //Basenp1[i][i] = 1.0;
+               }
+        }
+        else{
+             vect_to_matrix (3, &(statev[pos_Ri]), Rnp1);
+             vect_to_matrix (3, &(statev_n[pos_Ri]), Rn);
+             vect_to_matrix (3, &(statev[pos_F]), Fnp1);
+             vect_to_matrix (3, &(statev_n[pos_F]), Fn);
+        }
+        vect_to_matrix (3, &(statev[pos_Base]), Basenp1);
+        vect_to_matrix (3, &(statev_n[pos_Base]), Basen);
+
+	for(i=0;i<3;i++){
+		Idev[i][i]=1.;
+		Idev[i+3][i+3]=1.;
+		for(j=0;j<3;j++){
+			Ivol[i][j]=1./3.;
+			Idev[i][j]=Idev[i][j]-1./3.;
+		}
+	}
+	
+	p_n = statev_n[pos_p];
+
+        copyvect(&(statev_n[pos_pstrn]),pstrn_n,6);
+	p=0.;
+
+       //convert stress into effective stress at tn, the return mapping will not be changed then
+       D=0.0;
+       if(dam){
+               D = statev_n[pos_dam+2];
+       }
+
+
+        //get strain at n+1
+        GetdR(Basen, dstrn, dR, Basenp1,sqrt(2.));
+        UpdateFandR(Fn, Rn, dstrn, dR, Fnp1, Rnp1,sqrt(2.)); //Fn should be unloaded state
+        
+        //rotate residual stress
+        matrix_to_vect(3, dR, RVect);
+        for(i=0;i<6;i++)
+        {
+          Rstrs_n[i]=strs_n[i];
+          strs_nef[i]=strs_n[i]/(1.0-D);
+        }
+        Rot_vect(RVect, Rstrs_n);         
+        for(i=0;i<6;i++){
+               Rstrs_nef[i]=Rstrs_n[i]/(1.0-D);
+        }
+//        GetTau(dR, &(statev_n[pos_strn]), E, nu, strs_tr, Basenp1,sqrt(2.),sqrt(2.));
+//        printf(" Rstrs : %f, %f, %f, %f, %f, %f\n", Rstrs_nef[0],Rstrs_nef[1],Rstrs_nef[2],Rstrs_nef[3],Rstrs_nef[4],Rstrs_nef[5]);
+//        printf(" TauEl : %f, %f, %f, %f, %f, %f\n", strs_tr[0],strs_tr[1],strs_tr[2],strs_tr[3],strs_tr[4],strs_tr[5]);
+
+
+        GetTauRes(dR, &(statev_n[pos_strn]), dstrn, E, nu, strs_tr, Basenp1,sqrt(2.),sqrt(2.));
+        statev[pos_Ja] = Determinant(Fnp1, 3);
+#if RESIDUAL_FROM_STRAIN_LD==0
+        for(i=0;i<6;i++){
+            strs_tr[i]=strs_tr[i]+Rstrs_n[i];
+        }
+#endif
+        //printf(" strain of matrix is %e,%e,%e,%e,%e,%e\n", statev[0],statev[1],statev[2],statev[3],statev[4],statev[5]); 
+        //printf(" stress of matrix is %e,%e,%e,%e,%e,%e\n", Rstrs_n[0],Rstrs_n[1],Rstrs_n[2],Rstrs_n[3],Rstrs_n[4],Rstrs_n[5]); 
+        //check return mapping dir
+        if(htype>10)
+        {
+          printf("you need to complete the large deformation law with Drucker Prager hardening");
+          error =1;
+        }
+        else
+          error=constbox_ep(E, nu, sy0, htype, hmod1, hmod2, hp0, hexp, strs_tr, Rstrs_n, strs_ef, pstrn_n, pstrn, p_n, &p, Calgo, dCsd, dpdE,1);
+
+	compute_Hooke(E,nu,Cel);
+        inverse(Cel, invCel, &error1, 6);
+        contraction42(invCel, strs_ef, elasstrn);
+
+       
+       // update state variable, and keep the effective stress in state variable for the compuation of damage
+
+	//addtens2(1., statev_n, 1., dstrn, statev); //here we could store elastic one
+	copyvect(elasstrn, &(statev[pos_strn]),6);
+	copyvect(strs_ef, &(statev[pos_strs]),6);
+	copyvect(dstrn, &(statev[pos_dstrn]),6);
+	copyvect(pstrn, &(statev[pos_pstrn]),6);
+	statev[pos_p]=p;
+	statev[pos_dp]=p-p_n;
+	statev[pos_twomu]=twomu;  
+	statev[pos_eqstrs]= vonmises(strs_ef); 
+ 
+
+
+	copyvect(strs_nef, &(statev_n[pos_strs]),6);
+
+        matrix_to_vect(3, Rnp1, &(statev[pos_Ri]));
+        matrix_to_vect(3, Basenp1, &(statev[pos_Base]));
+        matrix_to_vect(3, Fnp1, &(statev[pos_F]));
+
+       //*****************************************
+       if(dam){
+               // get damage parameters
+                dDdp_bar=0.0;
+		dam->damagebox(statev_n, statev, pos_strn, pos_strs, pos_dam, Calgo, dDdE, &dDdp_bar, 1., kinc, kstep);
+
+              // update state variable, and convert the effective stress in state variable back
+
+               for(i=0;i<6;i++){
+               statev_n[pos_strs+i]=strs_nef[i]*(1.0-D);
+               } 
+
+               D = statev[pos_dam+2];
+               for(i=0;i<6;i++){
+               statev[pos_strs+i]=strs_ef[i]*(1.0-D);
+               }
+       }
+               
+
+        // make Csd, secant operator **********************************************************************************
+              //printf("Rstref %f %f %f %f %f %f\n",Rstrs_nef[0],Rstrs_nef[1],Rstrs_nef[2],Rstrs_nef[3],Rstrs_nef[4],Rstrs_nef[5]);
+              for(i=0;i<6;i++){
+                 strs[i]=statev[pos_strs+i];
+                 dstrs[i]=statev[pos_strs+i]-Rstrs_n[i];
+                 dstrs_ef[i]=strs_ef[i]-Rstrs_nef[i];
+               }
+  
+               // Compute the trace of a second order tensor-dstrn amd dstrs 
+               dstrs_tra = trace(dstrs_ef);
+               dstrn_tra = trace(dstrn);
+
+               // Extract the deviatoric part of a second order tensor -dstrn amd dstrs 
+               dev(dstrs_ef, dstrs_efdev);  
+               dev(strs_nef, strs_nefdev);  
+
+               // Compute the von Mises equivalent stress 
+               dstrs_eq = vonmises(dstrs_ef);
+
+               // Compute the equivalent strain scalar 
+               dstrn_eq = eqstrn(dstrn);
+              
+
+               // make Csd
+               if(fabs(dstrn_tra)>toleranceDiv and p-p_n >0.){
+                 kappa = dstrs_tra/(3.*dstrn_tra);
+               }
+               else{
+                 kappa = E/3./(1.-2.*nu)*(1.-D);
+               }
+#if RESIDUAL_FROM_STRAIN_LD==0
+               kappa = E/3./(1.-2.*nu)*(1.-D); //here we cannot use dstrs_tra/dstrn_tra becasue we do not cancel residual but change the secant operator
+#endif
+
+               if(fabs(dstrn_eq) >toleranceDiv and p-p_n >0.){
+                  mu = dstrs_eq/(3.*dstrn_eq);
+                  if(dam){
+                     mu = mu*(1.-D);
+                 }
+               }
+               else{                 
+                  mu = E/2./(1.+nu)*(1.-D);
+               }
+	       makeiso(kappa, mu, Csd);
+
+       // dCsd/dstrain  and dCsd/dp_bar*****************
+
+               for(i=0;i<6;i++){
+                    dkappa[i] = 0.0;
+               }
+
+          //1. dkappa/dstrain, /dp_bar
+ 
+               num1=dstrs_tra/3.0;
+
+               for(i=0;i<3;i++){
+                    if(fabs(dstrn_tra)>toleranceDiv and p-p_n >0.)
+                      dkappa[i] = -(1.0-D)*num1/(dstrn_tra*dstrn_tra)+E/3./(1.-2.*nu)*(1.-D)/dstrn_tra;
+                    else
+                      dkappa[i] = 0.;
+#if RESIDUAL_FROM_STRAIN_LD==0
+                 dkappa[i] = 0.;
+#endif
+               }
+               dkappadp_bar = 0.0;
+
+              if(dam){
+               
+                      num1=trace(dstrs_ef)/3.0;
+    
+                      if(fabs(dstrn_tra)>toleranceDiv and p-p_n >0.)
+                            dkappadD =  -num1/(dstrn_tra);
+                      else
+                            dkappadD =  -E/(3.*(1.-2.*nu));
+                      
+
+                      for(i=0;i<6;i++){
+                           dkappa[i] = dkappa[i]+ dkappadD*dDdE[i];
+                      }  
+                      dkappadp_bar = dkappadD*dDdp_bar;
+              }
+
+          //2. dmu/dstrain, /dp_bar
+
+            for (i=0; i<6; i++) {
+                     mat1[i] = 0.;
+                }
+                for(i=0;i<6;i++){
+                     for (j=0; j<6; j++) {
+                           mat1[i] = mat1[i] + dstrs_efdev[j]*Calgo[j][i];
+                     }
+                }
+
+                for(i=0;i<6;i++){
+		  if(fabs(dstrn_eq)>toleranceDiv and p-p_n >0.)
+                    dmu[i] = ((1.-D)*(1.-D)*mat1[i])/(6.*mu*dstrn_eq *dstrn_eq); 
+		  else
+	            dmu[i] = 0.;
+                }
+               
+                dev(dstrn, mat1);  
+                for(i=0;i<6;i++){
+                  if(fabs(dstrn_eq)>toleranceDiv and p-p_n >0.)
+                    dmu[i] = dmu[i]-2.0*mu*mat1[i]/(3.0*dstrn_eq *dstrn_eq); 
+                }
+
+                if(dam){
+                
+                       num1 = vonmises(dstrs_ef);
+                      
+                       if(fabs(dstrn_eq)>toleranceDiv)
+                         dmudD = -mu/(1.-D); 
+                       else
+                         dmudD = -E/2./(1.+nu); 
+
+                       for(i=0;i<6;i++){
+                            dmu[i] = dmu[i]+ dmudD*dDdE[i]; 
+                       }
+                      dmudp_bar= dmudD*dDdp_bar;
+                }
+
+           //3. dCsd/dstrain, /dp_bar
+
+                for(i=0;i<6;i++){
+                        for(j=0;j<6;j++){
+                                 for(k=0;k<6;k++){   
+            
+                                         dCsd[i][j][k] = 3.0*Ivol[i][j]*dkappa[k]+ 2.0*Idev[i][j]*dmu[k]; 
+                                  }
+                                 dCsdp_bar[i][j]= 3.0*Ivol[i][j]*dkappadp_bar+ 2.0*Idev[i][j]*dmudp_bar;
+                         }
+                } 
+          //4. dnu/dstrain, /dp_bar
+             
+                tmp = (3.*kappa + mu);
+                for(i=0;i<6;i++){
+                   dnu[i] = 9.*mu/(2.*tmp*tmp)*dkappa[i]-9.*kappa/(2.*tmp*tmp)*dmu[i];
+                  
+                }
+                dnudp_bar = 9.*mu/(2.*tmp*tmp)*dkappadp_bar-9.*kappa/(2.*tmp*tmp)*dmudp_bar;
+
+
+           // up date  Calgo and dstrsdp_bar 
+                     
+                 for(i=0;i<6;i++){
+                     dstrsdp_bar[i]= -1.*strs_ef[i]*dDdp_bar;
+	            for(j=0;j<6;j++){
+		           
+                    //  get stress*dDdE,
+                            strs_dDdE[i][j]=strs_ef[i]*dDdE[j]; 
+	            }        
+                 }
+
+           
+                 // add extra item on Calgo to conside the damage ( stress*dDdE)
+                 addtens4 ((1.-D), Calgo, -1.0, strs_dDdE, Calgo);
+                 //printf("j2plast iteration:  p: %.10e\n", statev[pos_p]);
+
+          // updat internal variables for large deformation***************************
+          //**************** R, Cp, Ja ****************
+          //       matrix_to_vect(3, R, &(statev[pos_Ri]));
+          //       GetCp(elasstrn, mtr, F, Cp);
+          //       for (i=0; i<3; i++){statev[pos_Cp+i] = Cp[i][i];}
+          //       statev[pos_Cp+3] = Cp[0][1];
+          //       statev[pos_Cp+4] = Cp[0][2];
+          //       statev[pos_Cp+5] = Cp[1][2];             
+        
+#ifdef NONLOCALGMSH
+        if(dam && localDamage)
+        {
+          statev[pos_dam]= statev[pos_p];
+  	  statev[pos_dam+1]= statev[pos_dp];
+        }
+#else
+// add by wu ling try nonlocal mehod without finite element cacilation
+        if(dam)
+        {
+          statev[pos_dam]= statev[pos_p];
+  	  statev[pos_dam+1]= statev[pos_dp];
+        }
+#endif
+
+        clength->creat_cg(statev_n, pos_p, c_g);        //*********add by wu ling 
+        return error;
+}
+//end of constbox large deformation
+
+//****************************************************
+// consbox called by MTSecNtr 2rd order method
+//****************************************************
+
+int EP_Material::constbox_2ndNtr(double *DE, double* dstrn, double* strs_n,  double* strs, double* statev_n, double* statev,  ELcc* LCC, EPR* epresult, double alpha, double** c_g, int kinc, int kstep, double dt){
+
+	int i,j,k,error;
+	double p_n,p;
+        double kappa,temp;
+        double temp1, temp2;
+        double mu;
+	double v0;
+        double mu_el = 0.5*E/(1.+nu); 
+        double eq2strs_n, eq2strs;
+       
+	
+	static double* dstrseq_trdDE = NULL;
+	static double** Idev = NULL, **Ivol = NULL;
+	static double* pstrn = NULL;
+	static double* pstrn_n = NULL;
+        static double* strs_nef = NULL;             // effective stress at tn (residual stress) 
+        static double* strs_ef = NULL;              // effective stress at tn+1 (updated stress) 
+
+        static double* dstrs = NULL, *dstrs_ef = NULL;                // increment of stress 
+
+        static double* dstrs_efdev = NULL;            // dev of increment of stress
+        static double* strs_nefdev = NULL;            // dev of increment of stress at tn
+
+        static double* dDdE = NULL;                 //*********add by wu ling 
+        static double* mat1 = NULL, *mat2 = NULL;
+        static double* dkappa = NULL, *dmu = NULL, *dmudE = NULL;
+
+        static double* mat3 = NULL, *mat4 = NULL;
+   
+        FY2nd  FY2;
+        double dstrs_tra;             // trace of increment of stress
+        double dstrn_tra;
+        double dstrseq_tr;
+        double dstrs_efeq;
+        double dstrn_eq;
+        double dDdp_bar;                 //*********add by wu ling 
+        double D;                    //*********add by wu ling 
+// variables for operation
+        double dD;                  // increment of D
+        double dkappadp_bar, dmudp_bar, dkappadD, dmudD, num1, num2, num3;
+
+        static double **strs_dDdE=NULL;
+
+        static bool initialized = false;
+        double toleranceDiv=1.e-20;
+	//allocate memory
+        if(!initialized)
+        {
+          initialized = true;
+  	  mallocvector(&dstrseq_trdDE,6);
+	  mallocmatrix(&Idev,6,6);
+	  mallocmatrix(&Ivol,6,6);
+	  mallocvector(&pstrn,6);
+	  mallocvector(&pstrn_n,6);
+          mallocvector(&strs_nef,6);
+          mallocvector(&strs_ef,6);
+          mallocvector(&dstrs,6);
+          mallocvector(&dstrs_ef,6);
+          mallocvector(&dstrs_efdev,6);
+          mallocvector(&strs_nefdev,6);
+          mallocvector(&dDdE,6);         //*********add by wu ling 
+          mallocvector(&dkappa,6);       
+          mallocvector(&dmu,6);      
+          mallocvector(&dmudE,6);       
+          mallocvector(&mat1,6);  
+          mallocvector(&mat2,6); 
+          mallocvector(&mat3,6);  
+          mallocvector(&mat4,6); 
+          mallocmatrix(&strs_dDdE,6,6); 
+        }
+         malloc_YF(&FY2);
+
+	cleartens2(dstrseq_trdDE);
+      	cleartens4(Idev);
+	cleartens4(Ivol);
+	cleartens2(pstrn);
+	cleartens2(pstrn_n);
+        cleartens2(strs_nef);
+        cleartens2(strs_ef);
+        cleartens2(dstrs);
+        cleartens2(dstrs_ef);
+        cleartens2(dstrs_efdev);
+        cleartens2(strs_nefdev);
+        cleartens2(dDdE);         //*********add by wu ling 
+        cleartens2(dkappa);       
+        cleartens2(dmu);          
+        cleartens2(dmudE);  
+        cleartens2(mat1);  
+        cleartens2(mat2);  
+        cleartens2(mat3);  
+        cleartens2(mat4);  
+        cleartens4(strs_dDdE);
+
+	//fill Idev and Ivol
+
+	for(i=0;i<3;i++){
+		Idev[i][i]=1.;
+		Idev[i+3][i+3]=1.;
+		for(j=0;j<3;j++){
+			Ivol[i][j]=1./3.;
+			Idev[i][j]=Idev[i][j]-1./3.;
+		}
+	}
+	
+
+	p_n = statev_n[pos_p];
+	copyvect(&(statev_n[pos_pstrn]),pstrn_n,6);
+	p=0.;
+
+        eq2strs_n = statev_n[pos_eqstrs];
+       //convert stress into effective stress at tn, the return mapping will not be changed then
+        D=0.0;
+        if(dam){
+               D = statev_n[pos_dam+2];
+        }
+
+        for(i=0;i<6;i++){
+                strs_nef[i]=strs_n[i]/(1.0-D);
+        }
+        eq2strs_n = eq2strs_n/(1.0-D);
+
+       // compute the trial increment second-moment of von-mises stress
+        v0 = 1.0 - LCC->v1;		
+	contraction42(LCC->dCdmu0,DE,mat1);
+	dstrseq_tr = 3.0*mu_el*sqrt((contraction22(DE,mat1))/(3.*v0));
+	temp = 3.*mu_el;
+	if(fabs(dstrseq_tr) >toleranceDiv) 
+          temp = 3.0*mu_el*mu_el/v0/dstrseq_tr;
+        for (i=0;i<6;i++){
+             dstrseq_trdDE[i] = temp*mat1[i];
+        }
+       // elasto-plastic material return mapping
+        if(htype>10)
+        {
+          printf("you need to complete the second order moment law with Drucker Prager hardening");
+          error =1;
+        }
+        else
+          error=constbox_ep(E, nu, sy0, htype, hmod1, hmod2, hp0, hexp, DE, dstrn, strs_nef, eq2strs_n, &eq2strs, dstrseq_tr, dstrseq_trdDE, strs_ef, pstrn_n, pstrn, p_n, &p, &FY2);
+
+
+
+   /*     v0 = 1.0 - LCC->v1;		
+	contraction42(LCC->dCdmu0,LCC->dstrnf,mat1);
+	dstrseq_tr = 3.0*mu_el*sqrt((contraction22(LCC->dstrnf,mat1))/(3.*v0));
+        temp = 3.0*mu_el*mu_el/v0/dstrseq_tr;
+        for (i=0;i<6;i++){
+             dstrseq_trdDE[i] = temp*mat1[i];
+        }
+       
+       // elasto-plastic material return mapping
+	copyvect(LCC->dstrnf,mat3,6);
+        addtens2(1.,statev_n, 1., dstrn, statev);
+        addtens2(1.,statev, -1., LCC->dstrn_m, mat4);
+	copyvect(LCC->strs_n,mat2,6);
+
+        
+        error=constbox_ep(E, nu, sy0, htype, hmod1, hmod2, hp0, hexp, mat3, mat4, mat2, eq2strs_n, &eq2strs, dstrseq_tr, dstrseq_trdDE, strs_ef, pstrn_n, pstrn, p_n, &p, &FY2);*/
+       
+       // update state variable, and keep the effective stress in state variable for the compuation of damage
+
+	addtens2(1., statev_n, 1., dstrn, statev); 
+	copyvect(strs_ef, &(statev[pos_strs]),6);
+	copyvect(dstrn, &(statev[pos_dstrn]),6);
+	copyvect(pstrn, &(statev[pos_pstrn]),6);
+	statev[pos_p]=p;
+	statev[pos_dp]=p-p_n;
+ 
+	copyvect(strs_nef, &(statev_n[pos_strs]),6);
+        statev[pos_eqstrs]=eq2strs;
+
+       // 1. make Csd, secant operator without damage D   *************************************************************************
+            kappa = E/(3.*(1.-(2.*nu)));
+
+          //when it is elastic 
+        if((statev[pos_dp]) <= 0.0){
+          // 1.1 kappa, mu and Csd
+              makeiso(kappa, mu_el, epresult->Csd);
+    
+              for(i=0;i<6;i++){
+                      for(j=0;j<6;j++){
+                                for(k=0;k<6;k++){   
+                                      epresult->dCsd[i][j][k] = 0.0; 
+                                      epresult->dCsddE[i][j][k] = 0.0;                                 
+                                 }
+                         }
+                         dmu[i] = 0.0; 
+                         dmudE[i] = 0.0;
+                } 
+          //1.2  Calgo
+               for(i=0;i<6;i++){
+                        for(j=0;j<6;j++){
+                                epresult->Calgo[i][j] = epresult->Csd[i][j];
+                         }
+                }
+          //1.3 dnu and dnudE , dp and dpdE
+                temp = (3.*kappa + mu);
+                for(i=0;i<6;i++){   
+                         epresult->dnu[i] = 0.0; 
+                         epresult->dnudE[i] = 0.0; 
+
+                         epresult->dp[i] = 0.0;
+                         epresult->dpdE[i] = 0.0;                         
+                }
+          }
+          else{
+          // 1.1 kappa, mu and Csd
+
+               kappa = E/(3.*(1.-(2.*nu)));
+	       mu = mu_el;
+	       if(fabs(dstrseq_tr) >toleranceDiv and p-p_n >0.)
+                 mu = mu_el*(1.0 - 3.0*mu_el*(p-p_n)/dstrseq_tr);
+	       makeiso(kappa, mu, epresult->Csd);
+    
+          //1.2  dCsd and dCsddE
+	       temp = 0.;
+	       temp1= 0.;
+	       temp2= 0.;
+	       if(fabs(dstrseq_tr) >toleranceDiv and p-p_n >0.)
+	       {
+                 temp = -6.0*mu_el*mu_el/dstrseq_tr;
+                 temp1 = 18.0*(mu_el*mu_el*mu_el*mu_el)*(p-p_n)/(v0*dstrseq_tr*dstrseq_tr*dstrseq_tr);
+                 temp2 = -6.0*mu_el*mu_el/dstrseq_tr;
+	       }
+  
+               for(i=0;i<6;i++){
+                        for(j=0;j<6;j++){
+                                 for(k=0;k<6;k++){   
+                                      epresult->dCsd[i][j][k] = temp*Idev[i][j]*FY2.dpdstrn_m[k]; 
+                                      epresult->dCsddE[i][j][k] = Idev[i][j]*(temp1*mat1[k] + temp2*FY2.dpdstrn_c[k]);                                 
+                                 }
+                         }
+                         dmu[i] = temp*FY2.dpdstrn_m[i]/2.0; 
+                         dmudE[i] = (temp1*mat1[i] + temp2*FY2.dpdstrn_c[i])/2.0;
+                } 
+          //1.3  Calgo
+               for(i=0;i<6;i++){
+                        for(j=0;j<6;j++){
+                                 epresult->Calgo[i][j]=0.0;
+                                 for(k=0;k<6;k++){   
+                                      epresult->Calgo[i][j] += dstrn[k]*epresult->dCsd[k][i][j];
+                                 }
+                                 epresult->Calgo[i][j] += epresult->Csd[i][j];
+                         }
+                }
+          //1.4 dnu and dnudE , dp and dpdE
+                temp = (3.*kappa + mu);
+                for(i=0;i<6;i++){   
+                         epresult->dnu[i] = -9.*kappa/(2.*temp*temp)*dmu[i]; 
+                         epresult->dnudE[i] = -9.*kappa/(2.*temp*temp)*dmudE[i]; 
+
+                         epresult->dp[i] = FY2.dpdstrn_m[i];
+                         epresult->dpdE[i] = FY2.dpdstrn_c[i];                         
+                }
+
+           }
+          //1.5 when there is no damage, the following tensors are set zero.
+                for(i=0;i<6;i++){
+                        for(j=0;j<6;j++){   
+                                epresult->dCsdp_bar[i][j] = 0.0;                     
+                        }
+                        epresult->dnudp_bar[i] = 0.0;
+                        epresult->dstrsdp_bar[i] = 0.0;
+                } 
+       
+       // 2. if there is a damage defined, Mofify Csd, secant operator *******************************************************
+               
+/*
+
+                for(i=0;i<6;i++){
+                 strs[i]=statev[6+i];
+                 dstrs[i]=statev[6+i]-statev_n[6+i];
+                 dstrs_ef[i]=strs_ef[i]-strs_nef[i];
+               }
+                
+      //check
+      //        printf(" vomin residusl stress of matrix is %e\n", vonmises(strs_nef)); 
+
+               // Compute the trace of a second order tensor-dstrn amd dstrs 
+               dstrs_tra = trace(dstrs_ef);
+               dstrn_tra = trace(dstrn);
+
+               // Extract the deviatoric part of a second order tensor -dstrn amd dstrs 
+               dev(dstrs_ef, dstrs_efdev);  
+               dev(strs_nef, strs_nefdev);  
+   
+
+               // Compute the von Mises equivalent stress 
+               dstrs_eq = vonmises(dstrs_ef);
+
+               // Compute the equivalent strain scalar 
+               dstrn_eq = eqstrn(dstrn);
+
+               // make Csd
+               if(fabs(dstrn_tra)>0. and fabs(dstrn_eq) >0.)
+               {
+                 kappa = dstrs_tra/(3.*dstrn_tra);
+                 mu = dstrs_eq/(3.*dstrn_eq);
+                 if(dam){
+                       kappa = kappa*(1.-D);
+                       mu = mu*(1.-D);
+                 }
+               }
+               else
+               {
+                 kappa = E/3./(1.-2.*nu)*(1.-D);
+                 mu = E/2./(1.+nu)*(1.-D);
+               }
+	       makeiso(kappa, mu, Csd);
+
+       // dCsd/dstrain  and dCsd/dp_bar*****************
+
+               for(i=0;i<6;i++){
+                    dkappa[i] = 0.0;
+               }
+
+          //1. dkappa/dstrain, /dp_bar
+
+            if(dam){
+                  
+               dkappadD =  -E/(3.*(1.-2.*nu));
+               for(i=0;i<6;i++){
+                 dkappa[i] = dkappa[i]+ dkappadD*dDdE[i];
+               }  
+               dkappadp_bar = dkappadD*dDdp_bar;
+             }
+
+          //2. dmu/dstrain, /dp_bar
+
+            for (i=0; i<6; i++) {
+                     mat1[i] = 0.;
+                }
+                for(i=0;i<6;i++){
+                     for (j=0; j<6; j++) {
+                           mat1[i] = mat1[i] + dstrs_efdev[j]*Calgo[j][i];
+                     }
+                }
+
+                for(i=0;i<6;i++){
+		  if(fabs(dstrn_eq)>0.  && p-p_n >0.)
+                    dmu[i] = ((1.-D)*(1.-D)*mat1[i])/(6.*mu*dstrn_eq *dstrn_eq); 
+		  else
+	            dmu[i] = 0.;
+                }
+               
+                dev(dstrn, mat1);  
+                for(i=0;i<6;i++){
+                  if(fabs(dstrn_eq)>0)
+                    dmu[i] = dmu[i]-2.0*mu*mat1[i]/(3.0*dstrn_eq *dstrn_eq); 
+                }
+
+                if(dam){
+                
+                       num1 = vonmises(dstrs_ef);
+                      
+                       if(fabs(dstrn_eq)>0.)
+                         dmudD = -mu/(1.-D); 
+                       else
+                         dmudD = -E/2./(1.+nu); 
+
+                       for(i=0;i<6;i++){
+                            dmu[i] = dmu[i]+ dmudD*dDdE[i]; 
+                       }
+                      dmudp_bar= dmudD*dDdp_bar;
+                }
+
+           //3. dCsd/dstrain, /dp_bar
+
+                for(i=0;i<6;i++){
+                        for(j=0;j<6;j++){
+                                 for(k=0;k<6;k++){   
+            
+                                         dCsd[i][j][k] = 3.0*Ivol[i][j]*dkappa[k]+ 2.0*Idev[i][j]*dmu[k]; 
+                                  }
+                                 dCsdp_bar[i][j]= 3.0*Ivol[i][j]*dkappadp_bar+ 2.0*Idev[i][j]*dmudp_bar;
+                         }
+                } 
+          //4. dnu/dstrain, /dp_bar
+             
+                tmp = (3.*kappa + mu);
+                for(i=0;i<6;i++){
+                   dnu[i] = 9.*mu/(2.*tmp*tmp)*dkappa[i]-9.*kappa/(2.*tmp*tmp)*dmu[i];
+                  
+                }
+                dnudp_bar = 9.*mu/(2.*tmp*tmp)*dkappadp_bar-9.*kappa/(2.*tmp*tmp)*dmudp_bar;
+
+
+           // up date  Calgo and dstrsdp_bar 
+                     
+                 for(i=0;i<6;i++){
+                     dstrsdp_bar[i]= -1.*strs_ef[i]*dDdp_bar;
+	            for(j=0;j<6;j++){
+		           
+                    //  get stress*dDdE,
+                            strs_dDdE[i][j]=strs_ef[i]*dDdE[j]; 
+	            }        
+                 }
+
+           
+                 // add extra item on Calgo to conside the damage ( stress*dDdE)
+                 addtens4 ((1.-D), Calgo, -1.0, strs_dDdE, Calgo);
+
+
+
+       //*****************************************
+       dD=0.0;
+       if(dam){
+               // get damage parameters
+                dDdp_bar=0.0;
+		dam->damagebox(statev_n, statev, pos_strn, pos_strs, pos_dam, Calgo, dDdE, &dDdp_bar, 1., kinc, kstep);
+// need to change derivatives of D , dDdDE need to be derived  
+              // update state variable, and convert the effective stress in state variable back
+
+               for(i=0;i<6;i++){
+               statev_n[6+i]=strs_nef[i]*(1.0-D);
+               } 
+
+               D = statev[pos_dam+2];
+               for(i=0;i<6;i++){
+               statev[6+i]=strs_ef[i]*(1.0-D);
+               }
+               dD = D-statev_n[pos_dam+2];
+       }
+
+*/
+
+
+
+#ifdef NONLOCALGMSH
+        if(dam && localDamage)
+        {
+          statev[pos_dam]= statev[pos_p];
+  	  statev[pos_dam+1]= statev[pos_dp];
+        }
+#else
+// add by wu ling try nonlocal mehod without finite element cacilation
+        if(dam)
+        {
+          statev[pos_dam]= statev[pos_p];
+  	  statev[pos_dam+1]= statev[pos_dp];
+        }
+#endif
+
+        clength->creat_cg(statev_n, pos_p, c_g);        //*********add by wu ling 
+
+        free_YF(&FY2);
+        return error;
+}
+// end of constbox_2ndNtr()
+
+
+//****************************************************
+// consbox called by 2rd order method
+//****************************************************
+
+int EP_Material::constbox_2order(int mtx, double *DE, double* dstrn, double* strs, double* statev_n, double* statev,  double **Calgo, Lcc* LCC, YieldF* YF, double** c_g, int kinc, int kstep, double dt){
+
+        int i,j,k,m,n;
+        int error1,error;
+	double dp,p;
+	double R, dR, ddR;
+        double tiny_p =1.0e-14;
+        double eqstrs_n, temp, temp_trial, temp1,temp2;
+        double mu_el = 0.5*E/(1.+nu);           // elastic shear modulus
+	double mu, v0, v1;
+	
+	static double** I = NULL, **Idev = NULL;
+        static double* strs_n = NULL;             // effective stress at tn (residual stress) 
+
+        static double* dstrn_dmu0 = NULL;   
+        static double* dstrn_dmu1 = NULL; 
+        static double** dstrn_dDE =NULL;              
+
+        static double* dstrs = NULL;               // increment of stress 
+
+        static double* strn_el = NULL;              //elastic strain
+        static double* dstrn_dev = NULL;            // dev of increment of stress
+        static double* strn_dev = NULL; 
+        static double* strs_dev = NULL;            // dev of increment of stress at tn
+        static double* strs_ndev = NULL;
+        static double* dstrs_devtrial =NULL;            // trial increment stress
+
+        static double* dstrs_eqtrialdDE = NULL;                 //*********add by wu ling 
+        static double* dstrs_eqdDE = NULL;
+        static double* mat1 = NULL, *mat2 = NULL, *mat3=NULL;
+        static double* Ntr = NULL;
+        static double* pstrn = NULL;
+        static double* dpdDE = NULL;
+        static double *dstrn_eq2dDE = NULL;
+        static double **A_m = NULL;
+        static double **invA_m = NULL;
+
+       static double *DE_e = NULL;
+
+
+        double strs_eq2trial;             // square of trial equivalent stress
+        double strs_eq2;                 // square of equivalent stress
+
+        double dstrn_eq2;
+        double dstrn_eq2dmu0;
+        double dstrn_eq2dmu1;
+
+        double dstrs_eqdmu0, dstrs_eqdmu1;
+        double dstrs_eqtrialdmu0, dstrs_eqtrialdmu1;
+
+        double dpdmu0, dpdmu1;                 //*********add by wu ling 
+ 
+        static bool initialized = false;
+        double toleranceDiv=1.e-20;
+	//allocate memory
+        if(!initialized)
+        {
+          initialized = true;
+	  mallocmatrix(&Idev,6,6);
+	  mallocmatrix(&I,6,6);
+	  mallocvector(&pstrn,6);
+          mallocvector(&strs_n,6);
+          mallocvector(&dstrs,6);
+          mallocvector(&dstrs_devtrial,6);
+          mallocvector(&strn_el,6);
+          mallocvector(&dstrn_dev,6);
+          mallocvector(&strn_dev,6);
+          mallocvector(&strs_dev,6);
+          mallocvector(&strs_ndev,6);
+          mallocvector(&dstrs_eqdDE,6);   
+          mallocvector(&dstrs_eqtrialdDE,6);              
+          mallocvector(&mat1,6);  
+          mallocvector(&mat2,6); 
+          mallocvector(&mat3,6); 
+          mallocvector(&Ntr,6); 
+          mallocvector(&dpdDE,6); 
+          mallocvector(&dstrn_eq2dDE,6); 
+          mallocmatrix(&dstrn_dDE,6,6);
+          mallocvector(&dstrn_dmu0,6);
+          mallocvector(&dstrn_dmu1,6);
+          mallocvector(&DE_e,6);
+	  mallocmatrix(&A_m,6,6);
+	  mallocmatrix(&invA_m,6,6);
+
+        }
+	cleartens4(Idev);
+	cleartens4(I);
+	cleartens2(pstrn);
+        cleartens2(strs_n);
+        cleartens2(dstrs);
+        cleartens2(dstrs_devtrial);
+        cleartens2(strn_el);
+        cleartens2(strs_dev);
+        cleartens2(strs_ndev);
+        cleartens2(dstrs_eqdDE);        
+        cleartens2(dstrs_eqtrialdDE);       
+        cleartens2(mat1);  
+        cleartens2(mat2);  
+        cleartens2(mat3);  
+        cleartens2(Ntr);  
+        cleartens2(dpdDE);            
+        cleartens2(dstrn_eq2dDE); 
+        cleartens4(dstrn_dDE);
+        cleartens2(dstrn_dmu0);
+        cleartens2(dstrn_dmu0);
+        cleartens2(DE_e);
+        cleartens4(A_m);
+        cleartens4(invA_m);
+
+        v1 = LCC->v1;
+        v0 = 1.- v1; 
+        error=0;
+
+	//fill Idev and Ivol
+
+	for(i=0;i<3;i++){
+		Idev[i][i]=1.;
+		Idev[i+3][i+3]=1.;
+		I[i][i]=1.;
+		I[i+3][i+3]=1.;
+		for(j=0;j<3;j++){
+			Idev[i][j]=Idev[i][j]-1./3.;
+		}
+	}	
+	
+
+       //1.1 Compute residual stress  
+	 copyvect(&(statev_n[pos_strs]),strs_n,6);
+         eqstrs_n = statev_n[pos_eqstrs];   
+   
+	 addtens2(1., statev_n, 1., dstrn, statev); 
+	 copyvect(dstrn, &(statev[pos_dstrn]),6);
+
+        
+       //1.2 Compute current stress and stress increment and derivatives of incremental strn to mu and macro strain DE
+         if(mtx){
+
+            //  addtens2(1., statev, -1., &statev_n[pos_pstrn], strn_el);
+            //  contraction42(LCC->C0, strn_el, strs);
+               contraction42(LCC->C0, dstrn, dstrs);
+               
+              addtens2(1., statev_n, -1., &statev_n[pos_pstrn], mat1);
+
+              contraction42(LCC->C0, mat1, strs_n);
+              addtens2(1., strs_n, 1., dstrs, strs); 
+
+              mu=LCC->mu[0];
+
+              contraction42(LCC->dAdmu0, DE, mat1);
+              addtens2(-v1/v0, mat1, 0., mat2, dstrn_dmu0); 
+
+              contraction42(LCC->dAdmu1, DE, mat1);
+              addtens2(-v1/v0, mat1, 0., mat2, dstrn_dmu1);    
+
+              addtens4(1./v0, I, -v1/v0, LCC->A, dstrn_dDE);
+
+           //   printf("p in matrix is: %.5e\n", statev_n[pos_p]);
+
+
+              copyvect(strs, &(statev[pos_strs]),6);
+              dev(dstrn, dstrn_dev);
+         dev(strs, strs_dev);
+         dev(statev, strn_dev);
+         contraction42(Idev, strn_el, mat1);
+         contraction42(Idev, strs_n, strs_ndev);
+
+//addtens2(1., statev_n, -1., &statev_n[pos_pstrn], mat2);
+
+              addtens4(1.0/v0, I, -v1/v0, LCC->A, A_m);
+              inverse (A_m, invA_m, &error1, 6);
+              contraction42(invA_m, strn_el, DE_e);
+
+
+             eqstrn2_order2(mtx, DE, LCC, &dstrn_eq2, dstrn_eq2dDE, &dstrn_eq2dmu0, &dstrn_eq2dmu1);
+
+
+        /*      strs_eq2 = 9.0*mu*mu*(dstrn_eq2)+3.0*contraction22(dstrs,strs_ndev)+eqstrs_n;
+                
+       // 2.1 apply J2 plasticity for YF->trial, and f
+       	  dp = tiny_p;
+          p= statev_n[pos_p]+ dp;
+          j2hard(p, sy0, htype, hmod1, hmod2, hp0, hexp, &R, &dR,&ddR);
+
+          temp = sqrt(strs_eq2) - (sy0+R);   //check plasticity      
+
+          YF->trial= 0.0;
+          YF->f = 0.0;
+          if( (temp >0.0) || (mu < mu_el))  YF->trial=1.0;
+          
+          if(YF->trial > 0.0){
+             dp = sqrt(dstrn_eq2)*(1.0-mu/mu_el);
+           
+             temp = 2.0*sqrt(strs_eq2);
+      // 2.2 the derivatives of strs_eqtrial and strs_eq
+      
+               dstrs_eqdmu0 = (9.0*mu*mu*dstrn_eq2dmu0+18.0*mu*dstrn_eq2 + 6.0*mu*contraction22(strs_ndev, dstrn_dmu0) 
+                               + 6.0*contraction22(strs_ndev, dstrn))/temp;
+
+               dstrs_eqdmu1 = (9.0*mu*mu*dstrn_eq2dmu1 + 6.0*mu*contraction22(strs_ndev, dstrn_dmu1))/temp;
+
+               for(i=0;i<6;i++){
+                       mat1[i] = 0.0;
+                       for(j=0;j<6;j++){
+                               mat1[i] += dstrn_dDE[j][i]*strs_ndev[j];
+                       }
+               }
+ 
+               addtens2(9.0*mu*mu/temp, dstrn_eq2dDE, 6.0*mu/temp, mat1, dstrs_eqdDE); */
+
+
+
+          strs_eq2 = 9.0*mu*mu*(dstrn_eq2);
+                
+       // 2.1 apply J2 plasticity for YF->trial, and f
+       	  dp = tiny_p;
+          p= statev_n[pos_p]+ dp;
+          j2hard(p, sy0, htype, hmod1, hmod2, hp0, hexp, &R, &dR,&ddR);
+
+          temp = sqrt(strs_eq2) - (sy0+R);   //check plasticity      
+
+          YF->trial= 0.0;
+          YF->f = 0.0;
+          if( (temp >0.0) || (mu < mu_el))  YF->trial=1.0;
+          
+          if(YF->trial > 0.0){
+             dp = sqrt(dstrn_eq2)*(1.0-mu/mu_el);
+           
+             temp = 2.0*sqrt(strs_eq2);
+      // 2.2 the derivatives of strs_eqtrial and strs_eq
+      
+               dstrs_eqdmu0 = (9.0*mu*mu*dstrn_eq2dmu0+18.0*mu*dstrn_eq2 )/temp;
+
+               dstrs_eqdmu1 = (9.0*mu*mu*dstrn_eq2dmu1)/temp;
+
+               
+               addtens2(9.0*mu*mu/temp, dstrn_eq2dDE, 0.0, mat1, dstrs_eqdDE); 
+
+        // 2.3 the derivatives of dp
+               temp = 2.0*sqrt(dstrn_eq2);                    
+                     dpdmu0 = dstrn_eq2dmu0*(1.0-mu/mu_el)/temp - sqrt(strs_eq2)/mu_el;
+                     dpdmu1 = dstrs_eqdmu1*(1.0-mu/mu_el)/temp;
+
+                     addtens2((1.0-mu/mu_el)/(temp), dstrn_eq2dDE, 0.0, mat1, dpdDE);  
+                  
+
+             dp = max(dp,tiny_p);
+             p = statev_n[pos_p]+ dp;
+             j2hard(p, sy0, htype, hmod1, hmod2, hp0, hexp, &R, &dR,&ddR);
+             YF->f = sqrt(strs_eq2) - (sy0+R);      //check yielding function is satisfied or not.
+      
+     //  3.1 the derivatives of
+
+	     YF->dfdmu[0] = dstrs_eqdmu0 - dR*dpdmu0;
+
+	     YF->dfdmu[1] = dstrs_eqdmu1 - dR*dpdmu1;
+ 
+             addtens2(1.0, dstrs_eqdDE, -(dR), dpdDE, YF->dfdstrn);
+            }
+
+         }
+         else{
+              //*************
+               contraction42(LCC->C1, dstrn, dstrs);
+               addtens2(1., strs_n, 1., dstrs, strs); 
+
+               mu=LCC->mu[1];
+
+               contraction42(LCC->dAdmu0, DE, dstrn_dmu0); 
+               contraction42(LCC->dAdmu1, DE, dstrn_dmu1);    
+               addtens4(1., LCC->A, 0., I, dstrn_dDE);
+             
+              //**************
+              copyvect(strs, &(statev[pos_strs]),6);
+              dev(strs, strs_dev);
+              dev(dstrn, dstrn_dev);
+             
+       // 2.1 apply J2 plasticity for YF->trial, and f
+              strs_eq2 = 1.5*contraction22(strs_dev, strs_dev);
+       	      dp = tiny_p;
+              p= statev_n[pos_p]+ dp;
+              j2hard(p, sy0, htype, hmod1, hmod2, hp0, hexp, &R, &dR,&ddR);
+
+              temp = sqrt(strs_eq2) - (sy0+R);   //check plasticity
+              YF->trial= 0.0;
+              YF->f = 0.0;
+              if( (temp >0.0) || (mu < mu_el)) {
+                   YF->trial=1.0;
+
+                   dstrn_eq2 = 2.0*contraction22(dstrn_dev, dstrn_dev)/3.0;
+                   dp = sqrt(dstrn_eq2)*(1.0-mu/mu_el);
+
+                   temp = 2.0*sqrt(strs_eq2);
+       // 2.2 the derivatives of strs_eq2
+                   dstrs_eqdmu0 = 6.0*mu*contraction22(strs_dev, dstrn_dmu0)/temp;
+                   dstrs_eqdmu1 = (6.0*mu*contraction22(strs_dev, dstrn_dmu1)+6.0*contraction22(strs_dev, dstrn_dev))/temp;
+
+                   for(i=0;i<6;i++){
+                           mat1[i] = 0.0;
+                           mat2[i] = 0.0;
+                           for(j=0;j<6;j++){ 
+                               mat1[i] = mat1[i] + strs_dev[j]*dstrn_dDE[j][i];
+                               mat2[i] = mat2[i] + dstrn_dev[j]*dstrn_dDE[j][i];
+                           }
+                   }
+                   addtens2(6.0*mu/temp, mat1, 0.0, mat1, dstrs_eqdDE); 
+
+       // 2.3 the derivatives of dp
+
+                   temp = 2.0/(3.0*sqrt(dstrn_eq2));
+                   dpdmu0 = temp*contraction22(dstrn_dev, dstrn_dmu0)*(1.0-mu/mu_el);
+                   dpdmu1 = temp*contraction22(dstrn_dev, dstrn_dmu1)*(1.0-mu/mu_el)-sqrt(dstrn_eq2)/mu_el;
+
+                   addtens2((1.0-mu/mu_el)*temp, mat2, 0.0, mat1, dpdDE);
+       // 2.4  update YF->f
+                   dp = max(dp,tiny_p);
+                   p = statev_n[pos_p]+ dp;
+                   j2hard(p, sy0, htype, hmod1, hmod2, hp0, hexp, &R, &dR,&ddR);
+                   YF->f = sqrt(strs_eq2) - (sy0+R);       //check yielding function is satisfied or not.
+      
+      //  3.1 the derivatives of
+
+	           YF->dfdmu[0] = dstrs_eqdmu0 - dR*dpdmu0;
+	           YF->dfdmu[1] = dstrs_eqdmu1 - dR*dpdmu1; 
+                   addtens2(1.0, dstrs_eqdDE, -(dR), dpdDE, YF->dfdstrn);
+                }
+              }   
+
+                  
+               
+
+
+ /* if(mtx){
+
+               addtens2(1., statev, -1., &statev_n[pos_pstrn], strn_el);
+               contraction42(LCC->C0, strn_el, strs);
+            //   contraction42(LCC->C0, dstrn, dstrs);
+          //     addtens2(1., strs_n, 1., dstrs, strs); 
+
+               mu=LCC->mu[0];
+
+               contraction42(LCC->dAdmu0, DE, mat1);
+               addtens2(-v1/v0, mat1, 0., mat2, dstrn_dmu0); 
+
+               contraction42(LCC->dAdmu1, DE, mat1);
+               addtens2(-v1/v0, mat1, 0., mat2, dstrn_dmu1);    
+
+               addtens4(1./v0, I, -v1/v0, LCC->A, dstrn_dDE);
+
+              printf("p in matrix is: %.5e\n", statev_n[pos_p]);
+
+         }
+         else{
+       
+               contraction42(LCC->C1, dstrn, dstrs);
+               addtens2(1., strs_n, 1., dstrs, strs); 
+
+               mu=LCC->mu[1];
+
+               contraction42(LCC->dAdmu0, DE, dstrn_dmu0); 
+               contraction42(LCC->dAdmu1, DE, dstrn_dmu1);    
+               addtens4(1., LCC->A, 0., I, dstrn_dDE);
+         }
+
+
+         copyvect(strs, &(statev[pos_strs]),6);
+         dev(dstrn, dstrn_dev);
+         dev(strs, strs_dev);
+
+         contraction42(Idev, strn_el, mat1);
+         contraction42(Idev, strs_n, strs_ndev);
+
+       //1.3 Compute second moment of equivalent strain and trial stress 
+       if(mtx){
+                 eqstrn2_order2(mtx, DE, LCC, &dstrn_eq2, dstrn_eq2dDE, &dstrn_eq2dmu0, &dstrn_eq2dmu1);
+               //  temp1 = sqrt(9.0*mu*mu*dstrn_eq2-6.0*mu*mu*contraction22(dstrn_dev,dstrn_dev)); 
+                 strs_eq2 = 9.0*mu*mu*dstrn_eq2+eqstrs_n;//1.5*contraction22(strs_dev,strs_ndev)+3.0*mu*contraction22(dstrn_dev,strs_n);
+// 1.5*contraction22(strs_dev,strs_dev)+(eqstrs_n+temp1)*(eqstrs_n+temp1);
+
+
+ //+3.0*contraction22(strs_ndev,strs_ndev);
+       //           strs_eq2trial = 9.0*mu_el*mu_el*dstrn_eq2+eqstrs_n+6.0*mu_el*contraction22(dstrn_dev,strs_n);//+3.0*contraction22(strs_ndev,strs_ndev);
+       // 2.1 apply J2 plasticity for YF->trial, and f
+       	  dp = tiny_p;
+          p= statev_n[pos_p]+ dp;
+          j2hard(p, sy0, htype, hmod1, hmod2, hp0, hexp, &R, &dR,&ddR);
+
+          temp = sqrt(strs_eq2) - (sy0+R);   //check plasticity      
+
+          YF->trial= 0.0;
+          YF->f = 0.0;
+          if( (temp >0.0) || (mu < mu_el))  YF->trial=1.0;
+          
+          if(YF->trial > 0.0){
+               dp = sqrt(dstrn_eq2)*(1.0-mu/mu_el);
+
+               temp = 2.0*sqrt(strs_eq2);
+      // 2.2 the derivatives of strs_eqtrial and strs_eq
+      
+               dstrs_eqdmu0 = (9.0*mu*mu*dstrn_eq2dmu0+18.0*mu*dstrn_eq2)/temp;/*(6.0*mu*contraction22(strs_dev, dstrn_dmu0)+6.0*contraction22(strs_dev, dstrn)
+                               + (eqstrs_n+temp1)/temp1*(9.0*mu*mu*dstrn_eq2dmu0+18.0*mu*dstrn_eq2-
+                                 12.0*mu*mu*contraction22(dstrn_dev, dstrn_dmu0)-12.0*mu*contraction22(dstrn_dev, dstrn)))/temp;*/
+
+/*               dstrs_eqdmu1 = 9.0*mu*mu*dstrn_eq2dmu1/temp;/*(6.0*mu*contraction22(strs_dev, dstrn_dmu1)+
+                               + (eqstrs_n+temp1)/temp1*(9.0*mu*mu*dstrn_eq2dmu1-12.0*mu*mu*contraction22(dstrn_dev, dstrn_dmu1)))/temp;*/
+
+             /*  contraction42(dstrn_dDE, strs_dev, mat1); 
+               contraction42(dstrn_dDE, dstrn_dev, mat2); 
+ 
+               addtens2(9.0*mu*mu, dstrn_eq2dDE, -12.0*mu*mu, mat2, mat2); 
+               addtens2(6.0*mu/temp, mat1, (eqstrs_n+temp1)/temp1/temp, mat2, dstrs_eqdDE); */
+
+            
+
+/*                     addtens2(9.0*mu*mu/temp, dstrn_eq2dDE, 0.0, mat1, dstrs_eqdDE); 
+
+                 /*    dstrs_eqdmu1 = 6.0*mu*contraction22(strs_dev, dstrn_dmu1)/temp;
+                     dstrs_eqdmu0 = (6.0*mu*contraction22(strs_dev, dstrn_dmu0)+6.0*contraction22(strs_dev, dstrn))/temp;
+
+                     contraction42(Idev, strn_el, mat1);
+                     dstrs_eqtrialdmu0 = 12.0*mu_el*mu_el*contraction22(mat1, dstrn_dmu0)/temp_trial;
+                     dstrs_eqtrialdmu1 = 12.0*mu_el*mu_el*contraction22(mat1, dstrn_dmu1)/temp_trial;
+
+                     contraction42(dstrn_dDE, strs_dev, mat2); 
+                     addtens2(6.0*mu/temp, mat2, 0.0, mat1, dstrs_eqdDE); 
+
+                     contraction42(dstrn_dDE, mat1, mat2);  
+                     addtens2(12.0*mu_el*mu_el/temp_trial, mat2, 0.0, mat1, dstrs_eqtrialdDE); */
+
+                     
+           // 2.3 the derivatives of dp
+
+/*                     temp = sqrt(dstrn_eq2);
+                     dpdmu0 = dstrn_eq2dmu0/(2.0*temp)*(1.0-mu/mu_el)-temp/mu_el;
+                     dpdmu1 = dstrn_eq2dmu1/(2.0*temp)*(1.0-mu/mu_el);
+
+                     addtens2((1.0-mu/mu_el)/(2.0*temp), dstrn_eq2dDE, 0.0, mat1, dpdDE);  
+                   /*  dpdmu0 = (dstrs_eqtrialdmu0-dstrs_eqtrialdmu0)/(3.0*mu_el);
+                     dpdmu1 = (dstrs_eqtrialdmu1-dstrs_eqtrialdmu1)/(3.0*mu_el);
+                     addtens2(1.0/(3.0*mu_el), dstrs_eqtrialdDE, -1.0/(3.0*mu_el), dstrs_eqdDE, dpdDE);  */
+
+/*             dp = max(dp,tiny_p);
+             p = statev_n[pos_p]+ dp;
+             j2hard(p, sy0, htype, hmod1, hmod2, hp0, hexp, &R, &dR,&ddR);
+             YF->f = sqrt(strs_eq2) - (sy0+R); //sqrt(strs_eq2trial) - (sy0+R + 3.0*mu_el*dp);       //check yielding function is satisfied or not.
+      
+     //  3.1 the derivatives of
+
+	     YF->dfdmu[0] = dstrs_eqdmu0 - dR*dpdmu0;
+
+	     YF->dfdmu[1] = dstrs_eqdmu1 - dR*dpdmu1;
+ 
+             addtens2(1.0, dstrs_eqdDE, -(dR), dpdDE, YF->dfdstrn);
+            }
+
+         }
+  else{
+                  strs_eq2 = 1.5*contraction22(strs_dev, strs_dev);
+                  dstrn_eq2 = 2.0/3.0*contraction22(dstrn_dev, dstrn_dev);
+               //   strs_eq2trial = 6.0*mu_el*mu_el*contraction22(dstrn_dev, dstrn_dev)+ 1.5*contraction22(strs_ndev, strs_ndev)  
+               //                    +6.0*mu_el*contraction22(dstrn_dev,strs_n);
+ 
+        
+       // 2.1 apply J2 plasticity for YF->trial, and f
+       	  dp = tiny_p;
+          p= statev_n[pos_p]+ dp;
+          j2hard(p, sy0, htype, hmod1, hmod2, hp0, hexp, &R, &dR,&ddR);
+
+          temp = sqrt(strs_eq2) - (sy0+R);   //check plasticity
+        
+          YF->trial= 0.0;
+          YF->f = 0.0;
+          if( (temp >0.0) || (mu < mu_el))  YF->trial=1.0;
+          
+          if(YF->trial > 0.0){
+               dp = sqrt(dstrn_eq2)*(1.0-mu/mu_el);
+
+               temp = 2.0*sqrt(strs_eq2);
+     
+            //   temp_trial = 2.0*sqrt(strs_eq2trial);
+              
+                    //  dp = sqrt(strs_eq2)*(mu_el-mu)/(3.0*mu*mu_el); 
+                 //    dp = (sqrt(strs_eq2trial) - sqrt(strs_eq2))/(3.0*mu_el);
+
+               //   dstrs_eqdmu0 = (9.0*mu*mu*dstrn_eq2dmu0+6.0*mu*contraction22(dstrn_dmu0, strs_ndev))/temp; 
+               //   dstrs_eqdmu1 = (9.0*mu*mu*dstrn_eq2dmu1+18.0*mu*dstrn_eq2+
+                //               6.0*mu*contraction22(dstrn_dmu1, strs_ndev)+6.0*contraction22(dstrn, strs_ndev))/temp;  
+              //    dstrs_eqdmu0 = (9.0*mu*mu*dstrn_eq2dmu0)/temp; 
+             //     dstrs_eqdmu1 = (9.0*mu*mu*dstrn_eq2dmu1+18.0*mu*dstrn_eq2)/temp;
+
+                  /*   contraction42(Idev, dstrn_dmu0, mat1);
+                     dstrs_eqtrialdmu0 = 6.0*mu*contraction22(strs,mat1)/temp;
+
+                      contraction42(Idev, dstrn_dmu1, mat1);
+                      dev(strs, mat2);
+                      dstrs_eqtrialdmu1 = 6.0*(contraction22(mat2, dstrn)+contraction22(mat2, statev_n)-contraction22(mat2, &statev_n[pos_pstrn])+mu*contraction22(strs,mat1))/temp;
+
+                     dev(strs, mat1);
+                     contraction42(dstrn_dDE,mat1, mat2);
+                     addtens2(6.0*mu/temp, mat2, 0.0, mat1, dstrs_eqtrialdDE);*/
+
+
+/*                    dstrs_eqdmu0 = 6.0*mu*contraction22(strs_dev, dstrn_dmu0)/temp;
+                     dstrs_eqdmu1 = (6.0*mu*contraction22(strs_dev, dstrn_dmu1)+6.0*contraction22(strs_dev, dstrn))/temp;
+
+                     
+                  //   dstrs_eqtrialdmu0 = (12.0*mu_el*mu_el*contraction22(dstrn_dev, dstrn_dmu0)+6.0*mu_el*contraction22(dstrn_dmu0,strs_ndev))/temp_trial;
+                  //   dstrs_eqtrialdmu1 = (12.0*mu_el*mu_el*contraction22(dstrn_dev, dstrn_dmu1)+6.0*mu_el*contraction22(dstrn_dmu1,strs_ndev))/temp_trial;
+
+                     contraction42(dstrn_dDE, strs_dev, mat2); 
+                     addtens2(6.0*mu/temp, mat2, 0.0, mat1, dstrs_eqdDE); 
+
+                //     contraction42(dstrn_dDE, dstrn_dev, mat2);  
+                 //    addtens2(12.0*mu_el*mu_el/temp_trial, mat2, 0.0, mat1, dstrs_eqtrialdDE); 
+
+           // 2.3 the derivatives of dp
+                   dpdmu0 = 2.0/3.0*contraction22(dstrn_dev,dstrn_dmu0)/sqrt(dstrn_eq2)*(1.0-mu/mu_el);
+                   dpdmu1 = 2.0/3.0*contraction22(dstrn_dev,dstrn_dmu1)/sqrt(dstrn_eq2)*(1.0-mu/mu_el);
+                   dpdmu1 = dpdmu1 - sqrt(dstrn_eq2)/mu_el;
+                   dp = sqrt(dstrn_eq2)*(1.0-mu/mu_el);
+
+                   contraction42(dstrn_dDE,dstrn_dev, mat1);
+                   addtens2(2.0/3.0*(1.0-mu/mu_el)/sqrt(dstrn_eq2), mat1, 0.0, mat1, dpdDE);
+                  /*   dpdmu0 = (dstrs_eqtrialdmu0-dstrs_eqtrialdmu0)/(3.0*mu_el);
+                     dpdmu1 = (dstrs_eqtrialdmu1-dstrs_eqtrialdmu1)/(3.0*mu_el);
+                     addtens2(1.0/(3.0*mu_el), dstrs_eqtrialdDE, -1.0/(3.0*mu_el), dstrs_eqdDE, dpdDE);  
+                     dpdmu0 = (dstrs_eqdmu0/mu - sqrt(strs_eq2)/mu/mu-dstrs_eqdmu0/mu_el)/3.0;
+                     dpdmu1 = dstrs_eqdmu1*(mu_el-mu)/(3.0*mu_el*mu);
+                     addtens2((mu_el-mu)/(3.0*mu_el*mu), dstrs_eqdDE, 0.0, mat1, dpdDE);  */
+/*             dp = max(dp,tiny_p);
+             p = statev_n[pos_p]+ dp;
+             j2hard(p, sy0, htype, hmod1, hmod2, hp0, hexp, &R, &dR,&ddR);
+             YF->f = sqrt(strs_eq2) - (sy0+R); //sqrt(strs_eq2trial) - (sy0+R + 3.0*mu_el*dp);       //check yielding function is satisfied or not.
+      
+     //  3.1 the derivatives of
+
+	     YF->dfdmu[0] = dstrs_eqdmu0 - dR*dpdmu0;
+
+	     YF->dfdmu[1] = dstrs_eqdmu1 - dR*dpdmu1;
+ 
+             addtens2(1.0, dstrs_eqdDE, -(dR), dpdDE, YF->dfdstrn);
+
+
+              }
+             }*/
+                  
+
+      // 3.2 as damage is not applied: 
+             YF->dpdmu[0] = 0.0;    
+             YF->dpdmu[1] = 0.0;  	
+             cleartens2(YF->dpdstrn); 
+             YF->dfdp_bar = 0.0; 
+             YF->dpdp_bar = 0.0;
+
+         
+       // 4. update state variable
+
+
+        contraction42(Idev, dstrs, mat1);
+        addtens2(0.5/sqrt(dstrn_eq2)/mu, mat1, 0.0, mat1, Ntr);
+
+        copyvect(&(statev_n[pos_pstrn]), pstrn, 6);
+        addtens2(dp, Ntr, 1.0, pstrn, pstrn);
+	copyvect(pstrn, &(statev[pos_pstrn]),6);
+	statev[pos_p]=p;
+	statev[pos_dp]=dp;
+
+        statev[pos_eqstrs] = strs_eq2; 
+                 
+ 
+ 
+#ifdef NONLOCALGMSH
+        if(dam && localDamage)
+        {
+          statev[pos_dam]= statev[pos_p];
+  	  statev[pos_dam+1]= statev[pos_dp];
+        }
+#else
+// add by wu ling try nonlocal mehod without finite element cacilation
+        if(dam)
+        {
+          statev[pos_dam]= statev[pos_p];
+  	  statev[pos_dam+1]= statev[pos_dp];
+        }
+#endif
+
+        clength->creat_cg(statev_n, pos_p, c_g);        //*********add by wu ling 
+        return error;
+}
+
+//end of consbox_2order
+
+//****************************************************
+//****************************************************
+
+void EP_Material::get_refOp(double* statev, double** C, int kinc, int kstep){
+
+	
+	double twomu, threekappa, D;
+
+	if(kinc<2 && kstep==1){
+	   get_elOp(C);
+	}
+	//if(kinc<2 ){
+                //get_elOD(statev,C);
+	//}
+	else{
+                twomu = statev[pos_twomu];
+		threekappa = E/(1.-2.*nu); 
+
+
+                if(dam){                                           //*********add by wu ling 
+                        D = statev[pos_dam+2];                     //***********13.04.2011********
+		        twomu = twomu*(1-D);
+		        threekappa = threekappa*(1-D);
+                 }
+		makeiso(threekappa/3.,twomu/2.,C);
+	}
+
+}
+
+void EP_Material::get_elOD(double* statev, double** Cel)
+{
+     get_elOp(Cel);
+     if(dam)
+     {
+       double damage = statev[pos_dam+2];
+       for(int i=0; i < 6; i++)
+         for(int j=0; j < 6; j++)
+           Cel[i][j]*=1.-damage;
+    }
+}
+
+
+void EP_Material::get_elOp(double** Cel){
+
+	compute_Hooke(E,nu,Cel);
+}
+
+void EP_Material::unload_step(double* dstrn,double* strs_n, double* statev_n, int kinc, int kstep){
+
+       if(kinc == 1 && kstep==1){
+		return;
+	}
+
+	int i,error;
+	static double **C0=NULL;
+        static double **invC0=NULL;
+	static double *strs=NULL;
+        static double *udstrn=NULL;
+        if(C0==NULL)
+        {
+  	  mallocmatrix(&C0,6,6);
+	  mallocmatrix(&invC0,6,6);	
+          mallocvector(&strs,6);
+          mallocvector(&udstrn,6);
+        }
+        cleartens4(C0);
+        cleartens4(invC0);
+        cleartens2(strs);
+        cleartens2(udstrn);
+
+
+
+	get_elOD(statev_n, C0);
+	inverse(C0,invC0,&error,6);
+	if(error!=0) printf("problem while inversing C0 in unload_step of MTSecF\n");
+
+	copyvect(&statev_n[pos_strs], strs, 6);        //stress in at tn
+        contraction42(invC0, strs, udstrn);          //unloading strain of composite at tn
+       
+ // update statev_n to keep the imformation for residual condition 
+
+        for(i=0;i<6;i++){
+	strs_n[i]=0.0;	
+        statev_n[pos_strs +i]=0.0;                                   //residual stress is 0
+        statev_n[pos_strn +i]= statev_n[pos_strn +i]- udstrn[i];      //residual strain 
+        statev_n[pos_dstrn +i]= dstrn[i]+ udstrn[i];    // strain increment in composte
+
+        dstrn[i]= statev_n[pos_dstrn +i];
+      	}
+
+}
+
+
+
+//*******************  Stochastic  EP  *************************
+//Stochastic RATE-INDEPENDENT ELASTO-PLASTICITY
+//PROPS: MODEL, iddam, E, nu, sy0, htype, hmod1, (hmod2, hp0), hexp 
+//STATEV: strn, strs, dstrn, pstrn, p, dp, 2*mu_iso
+//**************************************************************
+//constructor
+EP_Stoch_Material::EP_Stoch_Material(double* props, int idmat):Material(props, idmat){
+	int k;
+	int iddam, idclength, Flag_stoch ;	
+
+	iddam = (int)props[idmat+1];
+        idclength = (int)props[idmat+2];
+
+	k=idmat+3;          
+	_E = props[k++];
+	_nu = props[k++];
+	_sy0 = props[k++];
+	htype = (int) props[k++];
+	_hmod1 = props[k++];
+
+	//hardening models with two hardening moduli
+		//hardening models with two hardening moduli
+	if(htype==H_LINEXP){
+		_hmod2 = props[k++];
+                _hp0 = 0.;
+        }
+        else if(htype==H_POW_EXP){
+                _hmod2 = props[k++];
+                _hp0 = 0.;
+        }      
+
+        else if(htype==H_POW_EXTRAPOL){
+		_hmod2 = props[k++];
+                _hp0   = props[k++];
+	}
+
+	//hardening models for Drucker-Prager
+        else if(htype==H_POW_DP){
+		_alpha_DP = props[k++];
+                _m_DP = props[k++];
+                _nup = props[k++];
+		_hmod2 = 0.;
+                _hp0   = 0.;
+	}
+        else if(htype==H_EXP_DP){
+		_alpha_DP = props[k++];
+                _m_DP = props[k++];
+                _nup = props[k++];
+		_hmod2 = 0.;
+                _hp0   = 0.;
+	}
+        else if(htype==H_SWIFT_DP){
+		_alpha_DP = props[k++];
+                _m_DP = props[k++];
+                _nup = props[k++];
+		_hmod2 = 0.;
+                _hp0   = 0.;
+	}
+	else if(htype==H_LINEXP_DP){
+		_hmod2 = props[k++];
+                _hp0 = 0.;
+		_alpha_DP = props[k++];
+                _m_DP = props[k++];
+                _nup = props[k++];
+        }
+        else if(htype==H_POW_EXP_DP){
+                _hmod2 = props[k++];
+                _hp0 = 0.;
+		_alpha_DP = props[k++];
+                _m_DP = props[k++];
+                _nup = props[k++];
+        } 
+        else if(htype==H_POW_EXTRAPOL_DP){
+		_hmod2 = props[k++];
+                _hp0   = props[k++];
+		_alpha_DP = props[k++];
+                _m_DP = props[k++];
+                _nup = props[k++];
+	}
+	else{
+		_hmod2 = 0.;
+                _hp0   = 0.;
+	}
+
+	_hexp = props[k++];
+
+	nsdv = 28;
+	pos_strn=0;
+	pos_strs=6;
+	pos_dstrn=12;
+	pos_pstrn=18;
+	pos_p = 24;
+	pos_dp = 25;
+	pos_twomu = 26;
+	pos_eqstrs = 27;
+        
+        if(_E < 1.0e-6){
+            pos_E = nsdv;
+            nsdv += 1;}
+        else{ pos_E = 0; }
+
+        if(_nu < 1.0e-6){
+            pos_nu = nsdv;
+            nsdv += 1;}
+        else{ pos_nu = 0; }
+
+        if(_sy0 < 1.0e-6){
+            pos_sy0 = nsdv;
+            nsdv += 1;}
+        else{ pos_sy0 = 0; }
+   
+        if(_hmod1 < 1.0e-6){
+            pos_hmod1 = nsdv;
+            nsdv += 1; }
+        else{ pos_hmod1 = 0;}
+
+        if((htype==H_LINEXP || htype==H_POW_EXTRAPOL || htype==H_POW_EXP || htype==H_LINEXP_DP || htype==H_POW_EXTRAPOL_DP || htype==H_POW_EXP_DP) && (_hmod2 < 1.0e-6)){
+            pos_hmod2 = nsdv;
+            nsdv += 1; 
+        }
+        else{ pos_hmod2 = 0;}
+
+        if((htype==H_POW_EXTRAPOL || htype==H_POW_EXTRAPOL_DP) && (_hp0 < 1.0e-6)){
+            pos_hp0 = nsdv;
+            nsdv += 1; 
+        }
+        else{ pos_hp0 = 0;}
+
+        if(htype>10)
+          printf("COnstructor of Stoch law has to be updated to account for stochastic values of _DP coef");
+
+        if(_hexp < 1.0e-6){
+            pos_hexp = nsdv;
+            nsdv += 1; }
+        else{ pos_hexp = 0;}
+
+	dam = init_damage(props,iddam);
+	if(dam){
+  	        pos_dam = nsdv;
+		nsdv += dam->get_nsdv();
+                Flag_stoch = dam->get_pos_DamParm1();
+
+                if(Flag_stoch > 0){
+                    pos_DamParm1 = pos_dam + dam->get_pos_DamParm1();
+                    pos_DamParm2 = pos_dam + dam->get_pos_DamParm2();
+                    pos_DamParm3 = pos_dam + dam->get_pos_DamParm3();
+
+                }
+                else{
+                    pos_DamParm1 = 0;
+                    pos_DamParm2 = 0;
+                    pos_DamParm3 = 0;
+
+                }
+	}
+        else{
+            pos_DamParm1 = 0;
+            pos_DamParm2 = 0;
+            pos_DamParm3 = 0;
+        }
+
+        clength = init_clength(props,idclength);
+
+#ifdef NONLOCALGMSH
+        if(idclength==0) this->setLocalDamage();
+#endif
+}
+
+
+bool EP_Stoch_Material::eqstrs_exist() const
+{
+        return true;
+}
+
+
+#ifdef NONLOCALGMSH
+int EP_Stoch_Material::get_pos_currentplasticstrainfornonlocal() const 
+{
+	return pos_p;
+}
+int EP_Stoch_Material::get_pos_effectiveplasticstrainfornonlocal() const
+{
+	if(dam)
+	{
+		return pos_dam;
+	}
+	return -1;
+}
+
+int EP_Stoch_Material::get_pos_damagefornonlocal() const
+{
+	if(dam) return pos_dam+2;
+        return -1;
+}
+double EP_Stoch_Material::getElasticEnergy (double* statev)
+{
+  double eE = 0.;
+  int i;
+  static double* strn = NULL;
+  static double* pstrn = NULL;
+  static double* strs = NULL;
+  //static double**CelD = NULL;
+  if(strn == NULL)
+  {
+    mallocvector(&strn,6);
+    mallocvector(&pstrn,6);
+    mallocvector(&strs,6);
+  }
+  cleartens2(strn);
+  cleartens2(pstrn);
+  cleartens2(strs);
+
+  copyvect(&(statev[pos_strn]), strn,6);
+  copyvect(&(statev[pos_pstrn]),pstrn,6);
+  copyvect(&statev[pos_strs], strs, 6);
+  //enegry due to damage has been removed
+  for (i =0; i< 6; i++) eE+=0.5*(strs[i]*(strn[i]-pstrn[i]));
+
+  return eE;
+}
+
+double EP_Stoch_Material::getPlasticEnergy (double* statev) 
+{
+  double eP = 0.;
+  double p = statev[get_pos_currentplasticstrainfornonlocal()];
+  int nstepI=1000;
+  double sy0, hexp, hmod1, hmod2, hp0;
+  if(pos_sy0 != 0) sy0 = statev[pos_sy0];
+  else sy0 = _sy0;
+
+  if(pos_hexp != 0) hexp = statev[pos_hexp];
+  else hexp = _hexp;
+
+  if(pos_hmod1 != 0) hmod1 = statev[pos_hmod1];
+  else hmod1 = _hmod1;
+ 
+  if(pos_hmod2 != 0) hmod2 = statev[pos_hmod2];
+  else hmod2 = _hmod2;
+
+  if(pos_hp0 != 0) hp0 = statev[pos_hp0];
+  else hp0 = _hp0;
+
+  eP = sy0*p;
+  switch(htype) {
+    //POWER LAW HARDENING
+    case H_POW:
+      if(fabs(hexp+1.)!=0) 
+         eP+= hmod1*pow(p,hexp+1.)/(hexp+1.);
+      break;
+    //EXPONENTIAL HARDENING
+    case H_EXP:
+      eP+=hmod1*p;
+      if(fabs(hexp)!=0) eP+=hmod1*(exp(-hexp*p)-exp(0))/(hexp);
+      break;
+    //SWIFT LAW
+    case H_SWIFT:
+      eP-=sy0*p;
+      if(fabs(hexp+1.)!=0 && fabs(hmod1)!=0.) eP+=sy0*pow(1.+hmod1*p,hexp+1.)/(hexp+1.)/hmod1;
+      break;
+    //LINEAR-EXPONENTIAL HARDENING
+    case H_LINEXP:
+      eP+=hmod1*p*p/2.+hmod2*p;
+      if(fabs(hexp)!=0) eP+=hmod2*(exp(-hexp*p)-exp(0))/(hexp);
+      break;
+    //POWER LAW HARDENING EXTRAPOLATED AFTER 16% DEFO TO MIMIC DIGIMAT TO ABAQUS
+    case H_POW_EXTRAPOL:
+      if(p<hp0)
+      {
+        if(fabs(hexp+1.)!=0)
+          eP+=hmod1*pow(p,hexp+1.)/(hexp+1.);
+      }
+      else if(p<10.*hp0)
+      {
+        if(fabs(hexp+1.)!=0)
+          eP+=hmod1*pow(hp0,hexp+1.)/(hexp+1.);
+        eP+=hmod1*pow(hp0,hexp+1.)*(p-hp0)+hmod2*(p-hp0)*(p-hp0)/2.;
+      }
+      else
+      {
+        if(fabs(hexp+1.)!=0)
+          eP+=hmod1*pow(hp0,hexp+1.)/(hexp+1.);
+        eP+=hmod1*pow(hp0,hexp+1.)*(10.*hp0-hp0)+hmod2*(10.*hp0-hp0)*(10.*hp0-hp0)/2.;
+        eP+=(hmod1*pow(hp0,hexp+1.)+hmod2*(10.*hp0-hp0))*(p-10.*hp0)+hmod2*(p-10.*hp0)*(p-10.*hp0)/2000.;
+      }
+      break;
+    case H_POW_EXP:
+        for(int i=0; i<nstepI; i++)
+        {
+          double ptmp=((double)(i+1)-0.5)*p/((double)(nstepI));
+          eP+=(hmod1*pow(ptmp,hmod2)*(1.- exp(-hexp*ptmp)))*p/((double)(nstepI));
+        }
+	break;
+    default:
+      printf("Bad choice of hardening law in plasticEnergy: %d\n",htype);
+      break;
+  }
+  return eP;
+}
+#endif
+
+//destructor
+EP_Stoch_Material::~EP_Stoch_Material(){
+	if(dam) delete dam;
+        if(clength) delete clength;
+}
+
+//print
+void EP_Stoch_Material::print(){
+
+	printf("Stochastic J2 elasto-plasticity\n");
+	printf("Young modulus: %lf, Poisson ratio: %lf\n", _E, _nu);
+	printf("Intial yield stress: %lf, hardening law: %d, hardening coefficients: %lf\t%lf\t%lf\t%lf\n", _sy0,
+                                                                               htype,_hmod1,_hmod2,_hp0,_hexp);
+	if(dam){ dam->print();}
+        if(clength){clength->print();}
+}
+
+//constbox      //*****************New tenor added by wu ling: double* dpdE, double* strs_dDdp_bar ****************
+int EP_Stoch_Material::constbox(double* dstrn, double* strs_n,  double* strs, double* statev_n, double* statev, double** Cref, double*** dCref, double* tau, double** dtau, double** Calgo, double alpha, double* dpdE, double* strs_dDdp_bar,double *Sp_bar, double** c_g, double* dFd_d_bar, double* dstrs_dFd_bar, double *dFd_dE, double** c_gF, double* dpdFd, double* dFddp, int kinc, int kstep, double dt){
+
+	int i,j,k,error;
+	double p_n,p;
+	double twomu;
+        double E, nu , sy0, hexp, hmod1, hmod2, hp0;
+
+        if(pos_E != 0) E = statev[pos_E];
+        else E = _E;
+
+        if(pos_nu != 0) nu = statev[pos_nu];
+        else nu = _nu;
+
+        if(pos_sy0 != 0) sy0 = statev[pos_sy0];
+        else sy0 = _sy0;
+
+        if(pos_hexp != 0) hexp = statev[pos_hexp];
+        else hexp = _hexp;
+
+        if(pos_hmod1 != 0) hmod1 = statev[pos_hmod1];
+        else hmod1 = _hmod1;
+ 
+        if(pos_hmod2 != 0) hmod2 = statev[pos_hmod2];
+        else hmod2 = _hmod2;
+
+        if(pos_hp0 != 0) hp0 = statev[pos_hp0];
+        else hp0 = _hp0;
+ 
+	static double* dtwomu;
+	static double*** dCalgo;
+	static double** Idev;
+	static double* pstrn;
+	static double* pstrn_n;
+	static double** Cn;
+        static double* dDdE;                 //*********add by wu ling 
+        double  dDdp_bar;                 //*********add by wu ling 
+        double  D;                    //*********add by wu ling 
+        static double** strs_dDdE;           //*********add by wu ling 
+
+
+ 
+	//allocate memory (only once!)
+        static bool initialized=false;
+	static bool initCn=false; 
+        if(!initialized)
+        {
+	  mallocvector(&dtwomu,6);
+	  malloctens3(&dCalgo,6,6,6);
+	  mallocmatrix(&Idev,6,6);
+	  mallocvector(&pstrn,6);
+	  mallocvector(&pstrn_n,6);
+
+          mallocvector(&dDdE,6);         //*********add by wu ling 
+          mallocmatrix(&strs_dDdE,6,6); //*********add by wu ling 
+	  initialized = true;
+        }
+        cleartens2(dtwomu);
+        cleartens6(dCalgo);
+        cleartens4(Idev);
+        cleartens2(pstrn);
+        cleartens2(pstrn_n);
+        cleartens2(dDdE);
+        cleartens4(strs_dDdE);
+
+
+	//fill Idev 
+	for(i=0;i<3;i++){
+	  for(j=0;j<3;j++){
+	    Idev[i][j] = -1./3.;
+	  }
+	  Idev[i][i]+=1.;
+	  Idev[i+3][i+3] = 1.;
+	}
+
+	p_n = statev_n[pos_p];
+	copyvect(&(statev_n[pos_pstrn]),pstrn_n,6);
+	p=0.;
+        
+        if(dam)
+        {
+          // put in effective space
+          D = statev_n[pos_dam+2];
+          for(i=0;i<6;i++)
+          {
+            if( D<1.)
+            {
+              strs_n[i] = strs_n[i]/(1.-D);
+	      strs[i]   = strs[i]/(1.-D);
+            }
+          }
+        }
+        if(htype>10)
+        {
+          printf("you need to complete the stochastic law with Drucker Prager hardening");
+          error =1;
+        }
+        else
+          error=constbox_ep(E, nu, sy0, htype, hmod1, hmod2, hp0, hexp, dstrn, strs_n, strs, pstrn_n, pstrn, p_n, &p, &twomu, dtwomu, Calgo, dCalgo,dpdE,0);
+
+	if(dam)
+        {
+				                 // put back old stress in apparent space
+	   D = statev_n[pos_dam+2];
+	   for(i=0;i<6;i++)
+	   {
+	     if( D<1.)
+	     {
+		strs_n[i] = strs_n[i]*(1.-D);
+	     }
+	     else
+	     {
+		 strs_n[i] = 0.;
+	     }
+	    }
+        }
+
+	//update state variables
+	addtens2(1., statev_n, 1., dstrn, statev); 
+	copyvect(strs, &(statev[pos_strs]),6);
+	copyvect(dstrn, &(statev[pos_dstrn]),6);
+	copyvect(pstrn, &(statev[pos_pstrn]),6);
+	statev[pos_p]=p;
+	statev[pos_dp]=p-p_n;
+	statev[pos_twomu]=twomu;  
+	statev[pos_eqstrs]= vonmises(strs); 
+
+       // prepare for damage box which need effective stress.
+	//copyvect(strs_n, &(statev_n[6]),6);
+
+#ifdef NONLOCALGMSH
+        if(dam && localDamage)
+        {
+          statev[pos_dam]= statev[pos_p];
+	  statev[pos_dam+1]= statev[pos_dp];
+        }
+#else
+// add by wu ling try nonlocal mehod without finite element cacilation
+        if(dam)
+        {
+          statev[pos_dam]= statev[pos_p];
+	  statev[pos_dam+1]= statev[pos_dp];
+        }
+#endif
+
+
+	tau=NULL;
+	dtau=NULL;
+
+
+    
+	
+	makeiso(E/(3.*(1.-2.*nu)), 0.5*twomu, Cref);
+		
+	for(i=0;i<6;i++){
+		for(j=0;j<6;j++){
+			for(k=0;k<6;k++){
+				dCref[i][j][k] = Idev[i][j]*dtwomu[k];
+			}
+		}
+	}
+
+
+ //***** By Wu Ling 06/04/2011************************************************************************************
+        
+       cleartens2(strs_dDdp_bar);    //stress*dDdp_bar
+       cleartens4(strs_dDdE);        //  stress*dDdE
+
+     //TO DO: CALL DAMAGE BOX, IF DAM != NULL
+
+       if(dam){
+               // get damage parameters
+                dDdp_bar=0.0;
+		dam->damagebox(statev_n, statev, pos_strn, pos_strs, pos_dam, Calgo, dDdE, &dDdp_bar, alpha, kinc, kstep);
+
+               // up date reference operator Cref, Calgo and dCref dCalgo according to damage
+                 D = statev[pos_dam+2];
+
+	        //define tensor from effective stress
+
+                 //addtens2( D, strs , 0.0, strs, D_strs_eff); // D*strs_efficvtiv add by wu ling
+
+//*****
+
+                 for(i=0;i<6;i++){
+		         for(j=0;j<6;j++){
+			         for(k=0;k<6;k++){
+				            dCref[i][j][k] = (1.0-D)*dCref[i][j][k];
+                                            dCalgo[i][j][k] = (1.0-D)*dCalgo[i][j][k];
+			         }
+		         }
+                          //  get stress*dDdp_bar
+                         strs_dDdp_bar[i]= -1.*strs[i]*dDdp_bar;
+	         }
+
+
+
+                 for(i=0;i<6;i++){
+	            for(j=0;j<6;j++){
+		            for(k=0;k<6;k++){
+			               dCref[i][j][k] = dCref[i][j][k]-Cref[i][j]*dDdE[k];
+                                       dCalgo[i][j][k] = dCalgo[i][j][k]-Calgo[i][j]*dDdE[k];
+
+		            }
+                    //  get stress*dDdE,
+
+                            strs_dDdE[i][j]=strs[i]*dDdE[j]; 
+	            }        
+                    
+                 }
+
+                 addtens4((1.-D),Cref,0.0,Idev,Cref);
+                 addtens4((1.-D),Calgo,0.0,Idev,Calgo);
+
+                 // add extra item on Calgo to conside the damage ( stress*dDdE)
+                 addtens4 (1.0, Calgo, -1.0, strs_dDdE, Calgo);
+                 
+		 //after computing Jacobian tensor put stress in apparent space
+                 for(i=0;i<6;i++)
+                 {
+	            if( D<1.)
+            	    {
+                      strs[i] = strs[i]*(1.-D);
+            	    }
+            	    else
+	            {
+              	      strs[i] = 0.;
+	            }            
+          	 }
+                 copyvect(strs, &(statev[pos_strs]),6);
+
+                 // put back old stress in apparent space
+                 //   D = statev_n[pos_dam+2];
+                    //for(i=0;i<6;i++)
+                    //{
+                       //if( D<1.)
+                       //{
+                        //strs_n[i] = strs_n[i]*(1.-D);
+                       //}
+                       //else
+                       //{
+                        //strs_n[i] = 0.;
+                       //}
+                    //}
+                  //copyvect(strs_n, &(statev_n[6]),6);
+       }
+
+       //***** end of By Wu Ling 13/04/2011**********************************************************************************
+
+
+
+	//Elastic-plastic transition: use explicit estimate (may improve convergence during elastic-plastic transitions)
+	/*		
+	if( (statev[25] > 0 && statev_n[25] == 0) || (statev[25]==0 && statev_n[25] > 0)){
+		alpha = 0.;
+	}
+	*/
+
+	//generalized mid-point rule
+	if(alpha < 1.){
+
+		//get reference operator of the previous time step
+                if(!initCn)
+                {
+                  mallocmatrix(&Cn,6,6);
+		  initCn=true;
+                }
+                cleartens4(Cn);
+
+                get_refOp(statev_n, Cn, kinc, kstep);
+		
+		if(alpha==0){
+			copymatr(Cn,Cref,6,6);
+			cleartens6(dCref);
+		}
+		else{
+
+			addtens4((1.-alpha),Cn,alpha,Cref,Cref);
+
+			for(i=0;i<6;i++){
+				for(j=0;j<6;j++){
+					for(k=0;k<6;k++){
+						dCref[i][j][k] *= alpha;
+					}
+				}
+			}
+		}
+		//freematrix(Cn,6); // not anymore as now static
+	}
+
+	
+
+	//free memory not anymore as now static
+//	free(dtwomu);
+//	freetens3(dCalgo,6,6);
+//	freematrix(Idev,6);	
+//	free(pstrn);
+//	free(pstrn_n);
+
+//        free(dDdE);                     //*********add by wu ling 
+//        freematrix(strs_dDdE,6);       //*********add by wu ling 
+
+        clength->creat_cg(statev_n, pos_p, c_g);       //*********add by wu ling 
+        return error;
+}
+//******************************************************
+//costboxSecant
+//****************************************************
+/*int EP_Stoch_Material::constboxSecant(double* dstrn, double* strs_n,  double* strs, double* statev_n, double* statev, double **Calgo, double** Csd, double*** dCsd, double** dCsdp_bar, 
+double* dnu, double &dnudp_bar, double alpha, double* dpdE, double* dstrsdp_bar, double** c_g, int kinc, int kstep, double dt){
+
+	int i,j,k,error;
+	double p_n,p;
+        double kappa,tmp;
+        double mu;
+	double twomu;
+        double E, nu, sy0, hexp, hmod1, hmod2, hp0;
+
+        if(pos_E != 0) E = statev[pos_E];
+        else E = _E;
+
+        if(pos_nu != 0) nu = statev[pos_nu];
+        else nu = _nu;
+
+        if(pos_sy0 != 0) sy0 = statev[pos_sy0];
+        else sy0 = _sy0;
+
+        if(pos_hexp != 0) hexp = statev[pos_hexp];
+        else hexp = _hexp;
+
+        if(pos_hmod1 != 0) hmod1 = statev[pos_hmod1];
+        else hmod1 = _hmod1;
+ 
+        if(pos_hmod2 != 0) hmod2 = statev[pos_hmod2];
+        else hmod2 = _hmod2;
+	
+        if(pos_hp0 != 0) hp0 = statev[pos_hp0];
+        else hp0 = _hp0;
+
+	static double* dtwomu = NULL;
+	static double** Idev = NULL, **Ivol = NULL;
+	static double* pstrn = NULL;
+	static double* pstrn_n = NULL;
+        static double* strs_nef = NULL;             // effective stress at tn (residual stress) 
+        static double* strs_ef = NULL;              // effective stress at tn+1 (updated stress) 
+
+        static double* dstrs = NULL, *dstrs_ef = NULL;                // increment of stress 
+
+        static double* dstrs_efdev = NULL;            // dev of increment of stress
+        static double* strs_nefdev = NULL;            // dev of increment of stress at tn
+
+        static double* dDdE = NULL;                 //*********add by wu ling 
+        static double* mat1 = NULL, *mat2 = NULL;
+        static double* dkappa = NULL, *dmu = NULL;
+
+        double dstrs_tra;             // trace of increment of stress
+        double dstrn_tra;
+        double dstrs_eq;
+        double dstrs_efeq;
+        double dstrn_eq;
+        double dDdp_bar;                 //*********add by wu ling 
+        double D;                    //*********add by wu ling 
+// variables for operation
+        double dD;                  // increment of D
+        double dkappadp_bar, dmudp_bar, dkappadD, dmudD, num1, num2, num3;
+
+        static double **strs_dDdE=NULL;
+
+        static bool initialized = false;
+        double toleranceDiv=1.e-20;
+	//allocate memory
+        if(!initialized)
+        {
+          initialized = true;
+  	  mallocvector(&dtwomu,6);
+	  mallocmatrix(&Idev,6,6);
+	  mallocmatrix(&Ivol,6,6);
+	  mallocvector(&pstrn,6);
+	  mallocvector(&pstrn_n,6);
+          mallocvector(&strs_nef,6);
+          mallocvector(&strs_ef,6);
+          mallocvector(&dstrs,6);
+          mallocvector(&dstrs_ef,6);
+          mallocvector(&dstrs_efdev,6);
+          mallocvector(&strs_nefdev,6);
+          mallocvector(&dDdE,6);         //*********add by wu ling 
+          mallocvector(&dkappa,6);       
+          mallocvector(&dmu,6);          
+          mallocvector(&mat1,6);  
+          mallocvector(&mat2,6); 
+
+          mallocmatrix(&strs_dDdE,6,6); 
+        }
+        cleartens2(dtwomu);
+	cleartens4(Idev);
+	cleartens4(Ivol);
+	cleartens2(pstrn);
+	cleartens2(pstrn_n);
+        cleartens2(strs_nef);
+        cleartens2(strs_ef);
+        cleartens2(dstrs);
+        cleartens2(dstrs_ef);
+        cleartens2(dstrs_efdev);
+        cleartens2(strs_nefdev);
+        cleartens2(dDdE);         //*********add by wu ling 
+        cleartens2(dkappa);       
+        cleartens2(dmu);          
+        cleartens2(mat1);  
+        cleartens2(mat2);  
+        cleartens4(strs_dDdE);
+        
+
+	//fill Idev and Ivol
+
+	for(i=0;i<3;i++){
+		Idev[i][i]=1.;
+		Idev[i+3][i+3]=1.;
+		for(j=0;j<3;j++){
+			Ivol[i][j]=1./3.;
+			Idev[i][j]=Idev[i][j]-1./3.;
+		}
+	}
+	
+
+	p_n = statev_n[pos_p];
+	copyvect(&(statev_n[pos_pstrn]),pstrn_n,6);
+	p=0.;
+
+       
+       //convert stress into effective stress at tn, the return mapping will not be changed then
+       D=0.0;
+       if(dam){
+               D = statev_n[pos_dam+2];
+       }
+
+       for(i=0;i<6;i++){
+               strs_nef[i]=strs_n[i]/(1.0-D);
+       }
+
+	error=constbox_ep(E, nu, sy0, htype, hmod1, hmod2, hp0, hexp, dstrn, strs_nef, strs_ef, pstrn_n, pstrn, p_n, &p, &twomu, dtwomu, Calgo, dCsd,dpdE,1);
+       
+       // update state variable, and keep the effective stress in state variable for the compuation of damage
+
+	addtens2(1., statev_n, 1., dstrn, statev); 
+	copyvect(strs_ef, &(statev[pos_strs]),6);
+	copyvect(dstrn, &(statev[pos_dstrn]),6);
+	copyvect(pstrn, &(statev[pos_pstrn]),6);
+	statev[pos_p]=p;
+	statev[pos_dp]=p-p_n;
+	statev[pos_twomu]=twomu;  
+	statev[pos_eqstrs]= vonmises(strs); 
+ 
+	copyvect(strs_nef, &(statev_n[pos_strs]),6);
+
+       //*****************************************
+       dD=0.0;
+       if(dam){
+               // get damage parameters
+                dDdp_bar=0.0;
+		dam->damagebox(statev_n, statev, pos_strn, pos_strs, pos_dam, Calgo, dDdE, &dDdp_bar, 1., kinc, kstep);
+
+              // update state variable, and convert the effective stress in state variable back
+
+               for(i=0;i<6;i++){
+               statev_n[6+i]=strs_nef[i]*(1.0-D);
+               } 
+
+               D = statev[pos_dam+2];
+               for(i=0;i<6;i++){
+               statev[6+i]=strs_ef[i]*(1.0-D);
+               }
+               dD = D-statev_n[pos_dam+2];
+       }
+               
+
+       // make Csd, secant operator*****************************************************************************************************************************
+
+                for(i=0;i<6;i++){
+                 strs[i]=statev[6+i];
+                 dstrs[i]=statev[6+i]-statev_n[6+i];
+                 dstrs_ef[i]=strs_ef[i]-strs_nef[i];
+               }
+                
+      //check
+      //        printf(" vomin residusl stress of matrix is %e\n", vonmises(strs_nef)); 
+
+               // Compute the trace of a second order tensor-dstrn amd dstrs 
+               dstrs_tra = trace(dstrs_ef);
+               dstrn_tra = trace(dstrn);
+
+               // Extract the deviatoric part of a second order tensor -dstrn amd dstrs 
+               dev(dstrs_ef, dstrs_efdev);  
+               dev(strs_nef, strs_nefdev);  
+   
+
+               // Compute the von Mises equivalent stress 
+               dstrs_eq = vonmises(dstrs_ef);
+
+               // Compute the equivalent strain scalar 
+               dstrn_eq = eqstrn(dstrn);
+
+               // make Csd
+               if(fabs(dstrn_tra)>toleranceDiv and p-p_n >0.){
+                  kappa = dstrs_tra/(3.*dstrn_tra);
+                  if(dam){
+                       kappa = kappa*(1.-D);
+                  }
+               } 
+               else{
+                  kappa = E/3./(1.-2.*nu)*(1.-D);
+               }
+
+
+               if(fabs(dstrn_eq) > toleranceDiv and p-p_n >0.){
+                  mu = dstrs_eq/(3.*dstrn_eq);
+                  if(dam){
+                     mu = mu*(1.-D);
+                 }
+               }
+               else{                 
+                  mu = E/2./(1.+nu)*(1.-D);
+               }
+	       makeiso(kappa, mu, Csd);
+
+       // dCsd/dstrain  and dCsd/dp_bar*****************
+
+               for(i=0;i<6;i++){
+                    dkappa[i] = 0.0;
+               }
+
+          //1. dkappa/dstrain, /dp_bar
+
+            if(dam){
+                  
+               dkappadD =  -E/(3.*(1.-2.*nu));
+               for(i=0;i<6;i++){
+                 dkappa[i] = dkappa[i]+ dkappadD*dDdE[i];
+               }  
+               dkappadp_bar = dkappadD*dDdp_bar;
+             }
+
+          //2. dmu/dstrain, /dp_bar
+
+            for (i=0; i<6; i++) {
+                     mat1[i] = 0.;
+                }
+                for(i=0;i<6;i++){
+                     for (j=0; j<6; j++) {
+                           mat1[i] = mat1[i] + dstrs_efdev[j]*Calgo[j][i];
+                     }
+                }
+
+                for(i=0;i<6;i++){
+		  if(fabs(dstrn_eq)>toleranceDiv  and p-p_n >0.)
+                    dmu[i] = ((1.-D)*(1.-D)*mat1[i])/(6.*mu*dstrn_eq *dstrn_eq); 
+		  else
+	            dmu[i] = 0.;
+                }
+               
+                dev(dstrn, mat1);  
+                for(i=0;i<6;i++){
+                  if(fabs(dstrn_eq)>toleranceDiv  and p-p_n >0.)
+                    dmu[i] = dmu[i]-2.0*mu*mat1[i]/(3.0*dstrn_eq *dstrn_eq); 
+                }
+
+                if(dam){
+                
+                       num1 = vonmises(dstrs_ef);
+                      
+                       if(fabs(dstrn_eq)>0.)
+                         dmudD = -mu/(1.-D); 
+                       else
+                         dmudD = -E/2./(1.+nu); 
+
+                       for(i=0;i<6;i++){
+                            dmu[i] = dmu[i]+ dmudD*dDdE[i]; 
+                       }
+                      dmudp_bar= dmudD*dDdp_bar;
+                }
+
+           //3. dCsd/dstrain, /dp_bar
+
+                for(i=0;i<6;i++){
+                        for(j=0;j<6;j++){
+                                 for(k=0;k<6;k++){   
+            
+                                         dCsd[i][j][k] = 3.0*Ivol[i][j]*dkappa[k]+ 2.0*Idev[i][j]*dmu[k]; 
+                                  }
+                                 dCsdp_bar[i][j]= 3.0*Ivol[i][j]*dkappadp_bar+ 2.0*Idev[i][j]*dmudp_bar;
+                         }
+                } 
+          //4. dnu/dstrain, /dp_bar
+             
+                tmp = (3.*kappa + mu);
+                for(i=0;i<6;i++){
+                   dnu[i] = 9.*mu/(2.*tmp*tmp)*dkappa[i]-9.*kappa/(2.*tmp*tmp)*dmu[i];
+                  
+                }
+                dnudp_bar = 9.*mu/(2.*tmp*tmp)*dkappadp_bar-9.*kappa/(2.*tmp*tmp)*dmudp_bar;
+
+
+           // up date  Calgo and dstrsdp_bar 
+                     
+                 for(i=0;i<6;i++){
+                     dstrsdp_bar[i]= -1.*strs_ef[i]*dDdp_bar;
+	            for(j=0;j<6;j++){
+		           
+                    //  get stress*dDdE,
+                            strs_dDdE[i][j]=strs_ef[i]*dDdE[j]; 
+	            }        
+                 }
+
+           
+                 // add extra item on Calgo to conside the damage ( stress*dDdE)
+                 addtens4 ((1.-D), Calgo, -1.0, strs_dDdE, Calgo);
+                 //printf("j2plast iteration:  p: %.10e\n", statev[pos_p]);
+
+#ifdef NONLOCALGMSH
+#else
+// add by wu ling try nonlocal mehod without finite element cacilation
+        if(dam)
+        {
+          statev[pos_dam]= statev[pos_p];
+  	  statev[pos_dam+1]= statev[pos_dp]; 
+        }
+#endif
+
+        clength->creat_cg(statev_n, pos_p, c_g);        //*********add by wu ling 
+
+         return error;      
+}
+//end of costboxSecant
+
+// constboxSecant with Cs computed from Zero stress
+int EP_Stoch_Material::constboxSecantZero(double* dstrn, double* strs_n,  double* strs, double* statev_n, double* statev, double **Calgo, double** Csd, double*** dCsd, double** dCsdp_bar, 
+double* dnu, double &dnudp_bar, double alpha, double* dpdE, double* dstrsdp_bar, double** c_g, int kinc, int kstep, double dt){
+
+
+
+	int i,j,k,error;
+	double p_n,p;
+        double kappa,tmp;
+        double mu;
+	double twomu;
+        double E, nu, sy0, hexp, hmod1, hmod2, hp0;
+
+        if(pos_E != 0) E = statev[pos_E];
+        else E = _E;
+
+        if(pos_nu != 0) nu = statev[pos_nu];
+        else nu = _nu;
+
+        if(pos_sy0 != 0) sy0 = statev[pos_sy0];
+        else sy0 = _sy0;
+
+        if(pos_hexp != 0) hexp = statev[pos_hexp];
+        else hexp = _hexp;
+
+        if(pos_hmod1 != 0) hmod1 = statev[pos_hmod1];
+        else hmod1 = _hmod1;
+ 
+        if(pos_hmod2 != 0) hmod2 = statev[pos_hmod2];
+        else hmod2 = _hmod2;
+
+        if(pos_hp0 != 0) hp0 = statev[pos_hp0];
+        else hp0 = _hp0;
+
+	static double* dtwomu=NULL;
+	static double** Idev=NULL, **Ivol=NULL;
+	static double* pstrn=NULL;
+	static double* pstrn_n=NULL;
+        static double* strs_nef=NULL;             // effective stress at tn (residual stress) 
+        static double* strs_ef=NULL;              // effective stress at tn+1 (updated stress) 
+        static double* strs_efdev=NULL;            // dev of increment of stress
+        static double* dDdE=NULL;                 //*********add by wu ling 
+        static double* mat1=NULL;
+        static double* dkappa=NULL, *dmu=NULL;
+
+        static double** strs_dDdE=NULL;
+
+        double strs_tra;             // trace of increment of stress
+        double dstrn_tra;
+        double strs_eq;
+        double dstrn_eq;
+
+        double  dDdp_bar;                 //*********add by wu ling 
+        double  D;                    //*********add by wu ling 
+
+
+// variables for operation
+        double dkappadp_bar, dmudp_bar, dkappadD, dmudD, num1;
+
+	//allocate memory
+        static bool initialized = false;
+        double toleranceDiv=1.e-20;
+        if(!initialized)
+        {
+          initialized = true;
+	  mallocvector(&dtwomu,6);
+	  mallocmatrix(&Idev,6,6);
+	  mallocmatrix(&Ivol,6,6);
+	  mallocvector(&pstrn,6);
+	  mallocvector(&pstrn_n,6);
+          mallocvector(&strs_nef,6);
+          mallocvector(&strs_ef,6);
+          mallocvector(&strs_efdev,6);
+          mallocvector(&dDdE,6);         //*********add by wu ling 
+          mallocvector(&dkappa,6);       
+          mallocvector(&dmu,6); 
+          mallocvector(&mat1,6);  
+          mallocmatrix(&strs_dDdE,6,6); 
+         }
+//printf("dstrn in matrix is %e\n", dstrn[0]);
+	//fill Idev and Ivol
+	 cleartens2(dtwomu);
+	 cleartens4(Idev);
+	 cleartens4(Ivol);
+	 cleartens2(pstrn);
+	 cleartens2(pstrn_n);
+         cleartens2(strs_nef);
+         cleartens2(strs_ef);
+         cleartens2(strs_efdev);
+         cleartens2(dDdE);         //*********add by wu ling 
+         cleartens2(dkappa);       
+         cleartens2(dmu); 
+         cleartens2(mat1);  
+         cleartens4(strs_dDdE);
+
+
+
+	for(i=0;i<3;i++){
+		Idev[i][i]=1.;
+		Idev[i+3][i+3]=1.;
+		for(j=0;j<3;j++){
+			Ivol[i][j]=1./3.;
+			Idev[i][j]=Idev[i][j]-1./3.;
+		}
+	}
+	
+
+	p_n = statev_n[pos_p];
+
+        copyvect(&(statev_n[pos_pstrn]),pstrn_n,6);
+	p=0.;
+
+       
+       //convert stress into effective stress at tn, the return mapping will not be changed then
+       D=0.0;
+       if(dam){
+               D = statev_n[pos_dam+2];
+       }
+
+       for(i=0;i<6;i++){
+               strs_nef[i]=strs_n[i]/(1.0-D);
+        }
+   // printf("the trace of residual stress in matrix is %e\n",trace(strs_n));
+	error=constbox_ep(E, nu, sy0, htype, hmod1, hmod2, hp0, hexp, dstrn, strs_nef, strs_ef, pstrn_n, pstrn, p_n, &p, &twomu, dtwomu, Calgo, dCsd,dpdE,0);
+       
+       // update state variable, and keep the effective stress in state variable for the compuation of damage
+
+	addtens2(1., statev_n, 1., dstrn, statev); 
+	copyvect(strs_ef, &(statev[pos_strs]),6);
+	copyvect(dstrn, &(statev[pos_dstrn]),6);
+	copyvect(pstrn, &(statev[pos_pstrn]),6);
+	statev[pos_p]=p;
+	statev[pos_dp]=p-p_n;
+	statev[pos_twomu]=twomu; 
+	statev[pos_eqstrs]= vonmises(strs);  
+ 
+	copyvect(strs_nef, &(statev_n[pos_strs]),6);
+
+       //*****************************************
+       if(dam){
+               // get damage parameters
+                dDdp_bar=0.0;
+		dam->damagebox(statev_n, statev, pos_strn, pos_strs, pos_dam, Calgo, dDdE, &dDdp_bar, 1., kinc, kstep);
+
+              // update state variable, and convert the effective stress in state variable back
+
+               for(i=0;i<6;i++){
+               statev_n[6+i]=strs_nef[i]*(1.0-D);
+               } 
+
+               D = statev[pos_dam+2];
+               for(i=0;i<6;i++){
+               statev[6+i]=strs_ef[i]*(1.0-D);
+               }
+       }
+               
+
+        // make Csd, secant operator **********************************************************************************
+//check
+
+//if(p-p_n>1.e-8){
+              for(i=0;i<6;i++){
+                 strs[i]=statev[6+i];
+               }
+                
+               // Compute the trace of a second order tensor-dstrn amd strs 
+
+               strs_tra = trace(strs);
+               dstrn_tra = trace(dstrn); //trace(&statev[0]);//trace(dstrn);
+
+               // Extract the deviatoric part of a second order tensor strs_ef 
+               dev(strs_ef, strs_efdev);  
+   
+
+               // Compute the von Mises equivalent stress 
+               strs_eq = vonmises(strs);
+
+
+               // Compute the equivalent strain scalar 
+               dstrn_eq = eqstrn(dstrn);
+
+
+               // make Csd
+               if(fabs(dstrn_tra)>toleranceDiv and p-p_n >0.){
+                 kappa = strs_tra/(3.*dstrn_tra);
+               }
+               else{
+                 kappa = E/3./(1.-2.*nu)*(1.-D);
+               }
+               if(fabs(dstrn_eq) >toleranceDiv and p-p_n >0.){
+                 mu = strs_eq/(3.*dstrn_eq);
+               }
+               else{
+                 mu = E/2./(1.+nu)*(1.-D);
+               }
+
+	       makeiso(kappa, mu, Csd);
+
+       // dCsd/dstrain  and dCsd/dp_bar*****************
+
+            for(i=0;i<6;i++){
+                    dkappa[i] = 0.0;
+               }
+
+          //1. dkappa/dstrain, /dp_bar
+
+               num1=trace(strs_nef)/3.0;
+
+               for(i=0;i<3;i++){
+                    if(fabs(dstrn_tra)>toleranceDiv and p-p_n >0.)
+                      dkappa[i] = -(1.0-D)*num1/(dstrn_tra*dstrn_tra);
+                    else
+                      dkappa[i] = 0.;
+               }
+               
+               dkappadp_bar = 0.0;
+
+              if(dam){
+               
+                      num1=trace(strs_ef)/3.0;
+    
+                      if(fabs(dstrn_tra)>toleranceDiv and p-p_n >0.)
+                            dkappadD =  -num1/(dstrn_tra);
+                      else
+                            dkappadD =  -E/(3.*(1.-2.*nu));
+                      
+
+                      for(i=0;i<6;i++){
+                           dkappa[i] = dkappa[i]+ dkappadD*dDdE[i];
+                      }  
+                      dkappadp_bar = dkappadD*dDdp_bar;
+              }
+
+          //2. dmu/dstrain, /dp_bar
+
+                for(i=0;i<6;i++){
+                     mat1[i] = 0.;
+                     for (j=0; j<6; j++) {
+                           mat1[i] = mat1[i] + strs_efdev[j]*Calgo[j][i];
+                     }
+                }
+
+
+                for(i=0;i<6;i++){
+		  if(fabs(dstrn_eq)>toleranceDiv and p-p_n >0.)
+                    dmu[i] = (1.-D)*(1.-D)*mat1[i]/(6.*mu*dstrn_eq *dstrn_eq); 
+		  else
+	            dmu[i] = 0.;
+                   
+                }
+               
+                dev(dstrn, mat1);  
+                for(i=0;i<6;i++){
+                  if(fabs(dstrn_eq)>toleranceDiv and p-p_n >0.)
+                    dmu[i] = dmu[i]-2.0*mu*mat1[i]/(3.0*dstrn_eq *dstrn_eq); 
+                }
+                     
+                dmudp_bar= 0.0;
+
+                if(dam){
+                
+                       num1 = vonmises(strs_ef);
+
+                       if(fabs(dstrn_eq)>toleranceDiv and p-p_n >0.)
+                         dmudD = -num1/(3.*dstrn_eq); 
+                       else
+                         dmudD = -E/2./(1.+nu); 
+
+                       for(i=0;i<6;i++){
+                            dmu[i] = dmu[i]+ dmudD*dDdE[i]; 
+                       }
+                      dmudp_bar= dmudD*dDdp_bar;
+                }
+
+           //3. dCsd/dstrain, /dp_bar
+
+                for(i=0;i<6;i++){
+                        for(j=0;j<6;j++){
+                                 for(k=0;k<6;k++){   
+            
+                                         dCsd[i][j][k] = 3.0*Ivol[i][j]*dkappa[k]+ 2.0*Idev[i][j]*dmu[k]; 
+                                  }
+                                 dCsdp_bar[i][j]= 3.0*Ivol[i][j]*dkappadp_bar+ 2.0*Idev[i][j]*dmudp_bar;
+                         }
+                } 
+          //4. dnu/dstrain, /dp_bar
+             
+                tmp = (3.*kappa + mu);
+                for(i=0;i<6;i++){
+                   dnu[i] = 9.*mu/(2.*tmp*tmp)*dkappa[i]-9.*kappa/(2.*tmp*tmp)*dmu[i];
+                  
+                }
+                dnudp_bar = 9.*mu/(2.*tmp*tmp)*dkappadp_bar-9.*kappa/(2.*tmp*tmp)*dmudp_bar;
+
+
+           // up date  Calgo and dstrsdp_bar 
+
+                for(i=0;i<6;i++){
+                     dstrsdp_bar[i]= -1.*strs_ef[i]*dDdp_bar;
+	            for(j=0;j<6;j++){
+		           
+                    //  get stress*dDdE,
+                            strs_dDdE[i][j]=strs_ef[i]*dDdE[j]; 
+	            }        
+                 }
+
+             
+                 // add extra item on Calgo to conside the damage ( stress*dDdE)
+                 addtens4 ((1.-D), Calgo, -1.0, strs_dDdE, Calgo);
+                 //printf("j2plast iteration:  p: %.10e\n", statev[pos_p]);
+
+#ifdef NONLOCALGMSH
+#else
+// add by wu ling try nonlocal mehod without finite element cacilation
+        if(dam)
+        {
+          statev[pos_dam]= statev[pos_p];
+  	  statev[pos_dam+1]= statev[pos_dp]; 
+        }
+#endif
+
+        clength->creat_cg(statev_n, pos_p, c_g);      //*********add by wu ling 
+        return error;
+}*/
+//end of costboxSecant
+
+int EP_Stoch_Material::constboxSecantMixte(double* dstrn, double* strs_n,  double* strs, double* statev_n, double* statev, double **Calgo, double** Csd, double*** dCsd, double** dCsdp_bar, double* dnu, double &dnudp_bar, double alpha, double* dpdE, double* dstrsdp_bar, double** c_g, int kinc, int kstep, double dt, bool forceZero, bool forceRes)
+{
+        int error;
+        double E, nu, sy0, hexp, hmod1, hmod2, hp0, alpha_DP, m_DP, nup;
+        int viscmodel=0.;
+        double vmod=0., vstressy=0., vexp=0.; 
+
+        if(pos_E != 0) E = statev[pos_E];
+        else E = _E;
+
+        if(pos_nu != 0) nu = statev[pos_nu];
+        else nu = _nu;
+
+        if(pos_sy0 != 0) sy0 = statev[pos_sy0];
+        else sy0 = _sy0;
+
+        if(pos_hexp != 0) hexp = statev[pos_hexp];
+        else hexp = _hexp;
+
+        if(pos_hmod1 != 0) hmod1 = statev[pos_hmod1];
+        else hmod1 = _hmod1;
+ 
+        if(pos_hmod2 != 0) hmod2 = statev[pos_hmod2];
+        else hmod2 = _hmod2;
+	
+        if(pos_hp0 != 0) hp0 = statev[pos_hp0];
+        else hp0 = _hp0;
+        
+        if(htype>10)
+        {
+          printf("EP_Stoch_Material::constboxSecantMixte needs to be updated to account for Drucker Prager parameters");
+        }
+        else
+        {
+          alpha_DP=0.; 
+          m_DP=0.;
+          nup-=0.;
+        }
+	
+        error=constboxSecantMixteGeneric(dstrn, strs_n,  strs, statev_n, statev, Calgo, Csd, dCsd, dCsdp_bar, dnu,  dnudp_bar, alpha, dpdE, dstrsdp_bar, c_g, kinc, kstep, dt, forceZero, forceRes, E, nu, htype, sy0, hexp, hmod1, hmod2, hp0, alpha_DP, m_DP, nup, viscmodel, vmod, vstressy, vexp, false);
+
+        return error;               
+
+}
+//****************************************************
+// consbox called by MTSecNtr 2rd order method
+//****************************************************
+
+int EP_Stoch_Material::constbox_2ndNtr(double *DE, double* dstrn, double* strs_n,  double* strs, double* statev_n, double* statev,  ELcc* LCC, EPR* epresult, double alpha, double** c_g, int kinc, int kstep, double dt){
+
+	int i,j,k,error;
+        double E, nu, sy0, hexp, hmod1, hmod2, hp0;
+
+        if(pos_E != 0) E = statev[pos_E];
+        else E = _E;
+
+        if(pos_nu != 0) nu = statev[pos_nu];
+        else nu = _nu;
+
+        if(pos_sy0 != 0) sy0 = statev[pos_sy0];
+        else sy0 = _sy0;
+
+        if(pos_hexp != 0) hexp = statev[pos_hexp];
+        else hexp = _hexp;
+
+        if(pos_hmod1 != 0) hmod1 = statev[pos_hmod1];
+        else hmod1 = _hmod1;
+ 
+        if(pos_hmod2 != 0) hmod2 = statev[pos_hmod2];
+        else hmod2 = _hmod2;
+
+        if(pos_hp0 != 0) hp0 = statev[pos_hp0];
+        else hp0 = _hp0;
+
+	double p_n,p;
+        double kappa,temp;
+        double temp1, temp2;
+        double mu;
+	double v0;
+        double mu_el = 0.5*E/(1.+nu); 
+        double eq2strs_n, eq2strs;
+       
+	
+	static double* dstrseq_trdDE = NULL;
+	static double** Idev = NULL, **Ivol = NULL;
+	static double* pstrn = NULL;
+	static double* pstrn_n = NULL;
+        static double* strs_nef = NULL;             // effective stress at tn (residual stress) 
+        static double* strs_ef = NULL;              // effective stress at tn+1 (updated stress) 
+
+        static double* dstrs = NULL, *dstrs_ef = NULL;                // increment of stress 
+
+        static double* dstrs_efdev = NULL;            // dev of increment of stress
+        static double* strs_nefdev = NULL;            // dev of increment of stress at tn
+
+        static double* dDdE = NULL;                 //*********add by wu ling 
+        static double* mat1 = NULL, *mat2 = NULL;
+        static double* dkappa = NULL, *dmu = NULL, *dmudE = NULL;
+
+        static double* mat3 = NULL, *mat4 = NULL;
+   
+        FY2nd  FY2;
+        double dstrs_tra;             // trace of increment of stress
+        double dstrn_tra;
+        double dstrseq_tr;
+        double dstrs_efeq;
+        double dstrn_eq;
+        double dDdp_bar;                 //*********add by wu ling 
+        double D;                    //*********add by wu ling 
+// variables for operation
+        double dD;                  // increment of D
+        double dkappadp_bar, dmudp_bar, dkappadD, dmudD, num1, num2, num3;
+
+        static double **strs_dDdE=NULL;
+
+        static bool initialized = false;
+        double toleranceDiv=1.e-20;
+	//allocate memory
+        if(!initialized)
+        {
+          initialized = true;
+  	  mallocvector(&dstrseq_trdDE,6);
+	  mallocmatrix(&Idev,6,6);
+	  mallocmatrix(&Ivol,6,6);
+	  mallocvector(&pstrn,6);
+	  mallocvector(&pstrn_n,6);
+          mallocvector(&strs_nef,6);
+          mallocvector(&strs_ef,6);
+          mallocvector(&dstrs,6);
+          mallocvector(&dstrs_ef,6);
+          mallocvector(&dstrs_efdev,6);
+          mallocvector(&strs_nefdev,6);
+          mallocvector(&dDdE,6);         //*********add by wu ling 
+          mallocvector(&dkappa,6);       
+          mallocvector(&dmu,6);      
+          mallocvector(&dmudE,6);       
+          mallocvector(&mat1,6);  
+          mallocvector(&mat2,6); 
+          mallocvector(&mat3,6);  
+          mallocvector(&mat4,6); 
+          mallocmatrix(&strs_dDdE,6,6); 
+        }
+         malloc_YF(&FY2);
+
+	cleartens2(dstrseq_trdDE);
+      	cleartens4(Idev);
+	cleartens4(Ivol);
+	cleartens2(pstrn);
+	cleartens2(pstrn_n);
+        cleartens2(strs_nef);
+        cleartens2(strs_ef);
+        cleartens2(dstrs);
+        cleartens2(dstrs_ef);
+        cleartens2(dstrs_efdev);
+        cleartens2(strs_nefdev);
+        cleartens2(dDdE);         //*********add by wu ling 
+        cleartens2(dkappa);       
+        cleartens2(dmu);          
+        cleartens2(dmudE);  
+        cleartens2(mat1);  
+        cleartens2(mat2);  
+        cleartens2(mat3);  
+        cleartens2(mat4);  
+        cleartens4(strs_dDdE);
+
+	//fill Idev and Ivol
+
+	for(i=0;i<3;i++){
+		Idev[i][i]=1.;
+		Idev[i+3][i+3]=1.;
+		for(j=0;j<3;j++){
+			Ivol[i][j]=1./3.;
+			Idev[i][j]=Idev[i][j]-1./3.;
+		}
+	}
+	
+
+	p_n = statev_n[pos_p];
+	copyvect(&(statev_n[pos_pstrn]),pstrn_n,6);
+	p=0.;
+
+        eq2strs_n = statev_n[pos_eqstrs];
+       //convert stress into effective stress at tn, the return mapping will not be changed then
+        D=0.0;
+        if(dam){
+               D = statev_n[pos_dam+2];
+        }
+
+        for(i=0;i<6;i++){
+                strs_nef[i]=strs_n[i]/(1.0-D);
+        }
+        eq2strs_n = eq2strs_n/(1.0-D);
+
+       // compute the trial increment second-moment of von-mises stress
+        v0 = 1.0 - LCC->v1;		
+	contraction42(LCC->dCdmu0,DE,mat1);
+	dstrseq_tr = 3.0*mu_el*sqrt((contraction22(DE,mat1))/(3.*v0));
+	temp = 3.*mu_el;
+	if(fabs(dstrseq_tr) >toleranceDiv) 
+          temp = 3.0*mu_el*mu_el/v0/dstrseq_tr;
+        for (i=0;i<6;i++){
+             dstrseq_trdDE[i] = temp*mat1[i];
+        }
+       // elasto-plastic material return mapping
+        if(htype>10)
+        {
+          printf("you need to complete the stochastic second moment law with Drucker Prager hardening");
+          error =1;
+        }
+        else
+          error=constbox_ep(E, nu, sy0, htype, hmod1, hmod2, hp0, hexp, DE, dstrn, strs_nef, eq2strs_n, &eq2strs, dstrseq_tr, dstrseq_trdDE, strs_ef, pstrn_n, pstrn, p_n, &p, &FY2);
+
+
+
+   /*     v0 = 1.0 - LCC->v1;		
+	contraction42(LCC->dCdmu0,LCC->dstrnf,mat1);
+	dstrseq_tr = 3.0*mu_el*sqrt((contraction22(LCC->dstrnf,mat1))/(3.*v0));
+        temp = 3.0*mu_el*mu_el/v0/dstrseq_tr;
+        for (i=0;i<6;i++){
+             dstrseq_trdDE[i] = temp*mat1[i];
+        }
+       
+       // elasto-plastic material return mapping
+	copyvect(LCC->dstrnf,mat3,6);
+        addtens2(1.,statev_n, 1., dstrn, statev);
+        addtens2(1.,statev, -1., LCC->dstrn_m, mat4);
+	copyvect(LCC->strs_n,mat2,6);
+
+        
+        constbox_ep(E, nu, sy0, htype, hmod1, hmod2, hp0, hexp, mat3, mat4, mat2, eq2strs_n, &eq2strs, dstrseq_tr, dstrseq_trdDE, strs_ef, pstrn_n, pstrn, p_n, &p, &FY2);*/
+       
+       // update state variable, and keep the effective stress in state variable for the compuation of damage
+
+	addtens2(1., statev_n, 1., dstrn, statev); 
+	copyvect(strs_ef, &(statev[pos_strs]),6);
+	copyvect(dstrn, &(statev[pos_dstrn]),6);
+	copyvect(pstrn, &(statev[pos_pstrn]),6);
+	statev[pos_p]=p;
+	statev[pos_dp]=p-p_n;
+ 
+	copyvect(strs_nef, &(statev_n[pos_strs]),6);
+        statev[pos_eqstrs]=eq2strs;
+
+       // 1. make Csd, secant operator without damage D   *************************************************************************
+            kappa = E/(3.*(1.-(2.*nu)));
+
+          //when it is elastic 
+        if((statev[pos_dp]) <= 0.0){
+          // 1.1 kappa, mu and Csd
+              makeiso(kappa, mu_el, epresult->Csd);
+    
+              for(i=0;i<6;i++){
+                      for(j=0;j<6;j++){
+                                for(k=0;k<6;k++){   
+                                      epresult->dCsd[i][j][k] = 0.0; 
+                                      epresult->dCsddE[i][j][k] = 0.0;                                 
+                                 }
+                         }
+                         dmu[i] = 0.0; 
+                         dmudE[i] = 0.0;
+                } 
+          //1.2  Calgo
+               for(i=0;i<6;i++){
+                        for(j=0;j<6;j++){
+                                epresult->Calgo[i][j] = epresult->Csd[i][j];
+                         }
+                }
+          //1.3 dnu and dnudE , dp and dpdE
+                temp = (3.*kappa + mu);
+                for(i=0;i<6;i++){   
+                         epresult->dnu[i] = 0.0; 
+                         epresult->dnudE[i] = 0.0; 
+
+                         epresult->dp[i] = 0.0;
+                         epresult->dpdE[i] = 0.0;                         
+                }
+          }
+          else{
+          // 1.1 kappa, mu and Csd
+
+               kappa = E/(3.*(1.-(2.*nu)));
+	       mu = mu_el;
+	       if(fabs(dstrseq_tr) >toleranceDiv)
+                 mu = mu_el*(1.0 - 3.0*mu_el*(p-p_n)/dstrseq_tr);
+	       makeiso(kappa, mu, epresult->Csd);
+    
+          //1.2  dCsd and dCsddE
+	       temp = 0.;
+	       temp1= 0.;
+	       temp2= 0.;
+	       if(fabs(dstrseq_tr) >toleranceDiv and p-p_n >0.)
+	       {
+                 temp = -6.0*mu_el*mu_el/dstrseq_tr;
+                 temp1 = 18.0*(mu_el*mu_el*mu_el*mu_el)*(p-p_n)/(v0*dstrseq_tr*dstrseq_tr*dstrseq_tr);
+                 temp2 = -6.0*mu_el*mu_el/dstrseq_tr;
+	       }
+  
+               for(i=0;i<6;i++){
+                        for(j=0;j<6;j++){
+                                 for(k=0;k<6;k++){   
+                                      epresult->dCsd[i][j][k] = temp*Idev[i][j]*FY2.dpdstrn_m[k]; 
+                                      epresult->dCsddE[i][j][k] = Idev[i][j]*(temp1*mat1[k] + temp2*FY2.dpdstrn_c[k]);                                 
+                                 }
+                         }
+                         dmu[i] = temp*FY2.dpdstrn_m[i]/2.0; 
+                         dmudE[i] = (temp1*mat1[i] + temp2*FY2.dpdstrn_c[i])/2.0;
+                } 
+          //1.3  Calgo
+               for(i=0;i<6;i++){
+                        for(j=0;j<6;j++){
+                                 epresult->Calgo[i][j]=0.0;
+                                 for(k=0;k<6;k++){   
+                                      epresult->Calgo[i][j] += dstrn[k]*epresult->dCsd[k][i][j];
+                                 }
+                                 epresult->Calgo[i][j] += epresult->Csd[i][j];
+                         }
+                }
+          //1.4 dnu and dnudE , dp and dpdE
+                temp = (3.*kappa + mu);
+                for(i=0;i<6;i++){   
+                         epresult->dnu[i] = -9.*kappa/(2.*temp*temp)*dmu[i]; 
+                         epresult->dnudE[i] = -9.*kappa/(2.*temp*temp)*dmudE[i]; 
+
+                         epresult->dp[i] = FY2.dpdstrn_m[i];
+                         epresult->dpdE[i] = FY2.dpdstrn_c[i];                         
+                }
+
+           }
+          //1.5 when there is no damage, the following tensors are set zero.
+                for(i=0;i<6;i++){
+                        for(j=0;j<6;j++){   
+                                epresult->dCsdp_bar[i][j] = 0.0;                     
+                        }
+                        epresult->dnudp_bar[i] = 0.0;
+                        epresult->dstrsdp_bar[i] = 0.0;
+                } 
+       
+       // 2. if there is a damage defined, Mofify Csd, secant operator *******************************************************
+               
+/*
+
+                for(i=0;i<6;i++){
+                 strs[i]=statev[6+i];
+                 dstrs[i]=statev[6+i]-statev_n[6+i];
+                 dstrs_ef[i]=strs_ef[i]-strs_nef[i];
+               }
+                
+      //check
+      //        printf(" vomin residusl stress of matrix is %e\n", vonmises(strs_nef)); 
+
+               // Compute the trace of a second order tensor-dstrn amd dstrs 
+               dstrs_tra = trace(dstrs_ef);
+               dstrn_tra = trace(dstrn);
+
+               // Extract the deviatoric part of a second order tensor -dstrn amd dstrs 
+               dev(dstrs_ef, dstrs_efdev);  
+               dev(strs_nef, strs_nefdev);  
+   
+
+               // Compute the von Mises equivalent stress 
+               dstrs_eq = vonmises(dstrs_ef);
+
+               // Compute the equivalent strain scalar 
+               dstrn_eq = eqstrn(dstrn);
+
+               // make Csd
+               if(fabs(dstrn_tra)>0. and fabs(dstrn_eq) >0.)
+               {
+                 kappa = dstrs_tra/(3.*dstrn_tra);
+                 mu = dstrs_eq/(3.*dstrn_eq);
+                 if(dam){
+                       kappa = kappa*(1.-D);
+                       mu = mu*(1.-D);
+                 }
+               }
+               else
+               {
+                 kappa = E/3./(1.-2.*nu)*(1.-D);
+                 mu = E/2./(1.+nu)*(1.-D);
+               }
+	       makeiso(kappa, mu, Csd);
+
+       // dCsd/dstrain  and dCsd/dp_bar*****************
+
+               for(i=0;i<6;i++){
+                    dkappa[i] = 0.0;
+               }
+
+          //1. dkappa/dstrain, /dp_bar
+
+            if(dam){
+                  
+               dkappadD =  -E/(3.*(1.-2.*nu));
+               for(i=0;i<6;i++){
+                 dkappa[i] = dkappa[i]+ dkappadD*dDdE[i];
+               }  
+               dkappadp_bar = dkappadD*dDdp_bar;
+             }
+
+          //2. dmu/dstrain, /dp_bar
+
+            for (i=0; i<6; i++) {
+                     mat1[i] = 0.;
+                }
+                for(i=0;i<6;i++){
+                     for (j=0; j<6; j++) {
+                           mat1[i] = mat1[i] + dstrs_efdev[j]*Calgo[j][i];
+                     }
+                }
+
+                for(i=0;i<6;i++){
+		  if(fabs(dstrn_eq)>0.  && p-p_n >0.)
+                    dmu[i] = ((1.-D)*(1.-D)*mat1[i])/(6.*mu*dstrn_eq *dstrn_eq); 
+		  else
+	            dmu[i] = 0.;
+                }
+               
+                dev(dstrn, mat1);  
+                for(i=0;i<6;i++){
+                  if(fabs(dstrn_eq)>0  && p-p_n >0.)
+                    dmu[i] = dmu[i]-2.0*mu*mat1[i]/(3.0*dstrn_eq *dstrn_eq); 
+                }
+
+                if(dam){
+                
+                       num1 = vonmises(dstrs_ef);
+                      
+                       if(fabs(dstrn_eq)>0.)
+                         dmudD = -mu/(1.-D); 
+                       else
+                         dmudD = -E/2./(1.+nu); 
+
+                       for(i=0;i<6;i++){
+                            dmu[i] = dmu[i]+ dmudD*dDdE[i]; 
+                       }
+                      dmudp_bar= dmudD*dDdp_bar;
+                }
+
+           //3. dCsd/dstrain, /dp_bar
+
+                for(i=0;i<6;i++){
+                        for(j=0;j<6;j++){
+                                 for(k=0;k<6;k++){   
+            
+                                         dCsd[i][j][k] = 3.0*Ivol[i][j]*dkappa[k]+ 2.0*Idev[i][j]*dmu[k]; 
+                                  }
+                                 dCsdp_bar[i][j]= 3.0*Ivol[i][j]*dkappadp_bar+ 2.0*Idev[i][j]*dmudp_bar;
+                         }
+                } 
+          //4. dnu/dstrain, /dp_bar
+             
+                tmp = (3.*kappa + mu);
+                for(i=0;i<6;i++){
+                   dnu[i] = 9.*mu/(2.*tmp*tmp)*dkappa[i]-9.*kappa/(2.*tmp*tmp)*dmu[i];
+                  
+                }
+                dnudp_bar = 9.*mu/(2.*tmp*tmp)*dkappadp_bar-9.*kappa/(2.*tmp*tmp)*dmudp_bar;
+
+
+           // up date  Calgo and dstrsdp_bar 
+                     
+                 for(i=0;i<6;i++){
+                     dstrsdp_bar[i]= -1.*strs_ef[i]*dDdp_bar;
+	            for(j=0;j<6;j++){
+		           
+                    //  get stress*dDdE,
+                            strs_dDdE[i][j]=strs_ef[i]*dDdE[j]; 
+	            }        
+                 }
+
+           
+                 // add extra item on Calgo to conside the damage ( stress*dDdE)
+                 addtens4 ((1.-D), Calgo, -1.0, strs_dDdE, Calgo);
+
+
+
+       //*****************************************
+       dD=0.0;
+       if(dam){
+               // get damage parameters
+                dDdp_bar=0.0;
+		dam->damagebox(statev_n, statev, pos_strn, pos_strs, pos_dam, Calgo, dDdE, &dDdp_bar, 1., kinc, kstep);
+// need to change derivatives of D , dDdDE need to be derived  
+              // update state variable, and convert the effective stress in state variable back
+
+               for(i=0;i<6;i++){
+               statev_n[6+i]=strs_nef[i]*(1.0-D);
+               } 
+
+               D = statev[pos_dam+2];
+               for(i=0;i<6;i++){
+               statev[6+i]=strs_ef[i]*(1.0-D);
+               }
+               dD = D-statev_n[pos_dam+2];
+       }
+
+*/
+
+
+
+#ifdef NONLOCALGMSH
+        if(dam && localDamage)
+        {
+          statev[pos_dam]= statev[pos_p];
+  	  statev[pos_dam+1]= statev[pos_dp];
+        }
+#else
+// add by wu ling try nonlocal mehod without finite element cacilation
+        if(dam)
+        {
+          statev[pos_dam]= statev[pos_p];
+  	  statev[pos_dam+1]= statev[pos_dp];
+        }
+#endif
+
+        clength->creat_cg(statev_n, pos_p, c_g);        //*********add by wu ling 
+
+        free_YF(&FY2);
+        return error;
+}
+// end of constbox_2ndNtr()
+
+
+
+//****************************************************
+//****************************************************
+
+void EP_Stoch_Material::get_refOp(double* statev, double** C, int kinc, int kstep){
+	
+	double twomu, threekappa, D;
+        double E, nu;
+
+        if(pos_E != 0) E = statev[pos_E];
+        else E = _E;
+
+        if(pos_nu != 0) nu = statev[pos_nu];
+        else nu = _nu;
+
+	if(kinc<2 && kstep==1){
+	   get_elOp(statev, C);
+	}
+	//if(kinc<2 ){
+                //get_elOD(statev,C);
+	//}
+	else{
+                twomu = statev[pos_twomu];
+		threekappa = E/(1.-2.*nu); 
+
+
+                if(dam){                                           //*********add by wu ling 
+                        D = statev[pos_dam+2];                     //***********13.04.2011********
+		        twomu = twomu*(1-D);
+		        threekappa = threekappa*(1-D);
+                 }
+		makeiso(threekappa/3.,twomu/2.,C);
+	}
+
+}
+
+void EP_Stoch_Material::get_elOD(double* statev, double** Cel)
+{
+     get_elOp(statev, Cel);
+     if(dam)
+     {
+       double damage = statev[pos_dam+2];
+       for(int i=0; i < 6; i++)
+         for(int j=0; j < 6; j++)
+           Cel[i][j]*=1.-damage;
+    }
+}
+
+
+void EP_Stoch_Material::get_elOp(double* statev, double** Cel){
+
+        double E, nu;
+        if(pos_E != 0) E = statev[pos_E];
+        else E = _E;
+
+        if(pos_nu != 0) nu = statev[pos_nu];
+        else nu = _nu;
+
+	compute_Hooke(E,nu,Cel);
+}
+
+void  EP_Stoch_Material::get_elOp(double** Cel) {
+	compute_Hooke(_E,_nu,Cel);
+}
+
+void EP_Stoch_Material::unload_step(double* dstrn,double* strs_n, double* statev_n, int kinc, int kstep){
+
+       if(kinc == 1 && kstep==1){
+		return;
+	}
+
+	int i,error;
+	static double **C0=NULL;
+        static double **invC0=NULL;
+	static double *strs=NULL;
+        static double *udstrn=NULL;
+        if(C0==NULL)
+        {
+  	  mallocmatrix(&C0,6,6);
+	  mallocmatrix(&invC0,6,6);	
+          mallocvector(&strs,6);
+          mallocvector(&udstrn,6);
+        }
+        cleartens4(C0);
+        cleartens4(invC0);
+        cleartens2(strs);
+        cleartens2(udstrn);
+
+
+
+	get_elOD(statev_n, C0);
+	inverse(C0,invC0,&error,6);
+	if(error!=0) printf("problem while inversing C0 in unload_step of MTSecF\n");
+
+	copyvect(&statev_n[pos_strs], strs, 6);        //stress in at tn
+        contraction42(invC0, strs, udstrn);          //unloading strain of composite at tn
+       
+ // update statev_n to keep the imformation for residual condition 
+
+        for(i=0;i<6;i++){
+	strs_n[i]=0.0;	
+        statev_n[pos_strs +i]=0.0;                                   //residual stress is 0
+        statev_n[pos_strn +i]= statev_n[pos_strn +i]- udstrn[i];      //residual strain 
+        statev_n[pos_dstrn +i]= dstrn[i]+ udstrn[i];    // strain increment in composte
+
+        dstrn[i]= statev_n[pos_dstrn +i];
+      	}
+
+
+}
+
+
+//****************************************************************************************
+//**** RATE-DEPENDENT elasto-viscoplastic material ************************************
+//PROPS: MODEL, iddam, E, nu, sy0, htype, hmod1, (hmod2, hp0), hexp, viscmodel, vmod, vexp 
+//STATEV: strn, strs, dstrn, pstrn, p, dp, 2*mu_iso
+//****************************************************************************************
+//constructor
+EVP_Material::EVP_Material(double* props, int idmat):Material(props, idmat){
+	int k;
+	int iddam, idclength;
+	
+
+	iddam = (int)props[idmat+1];
+        idclength = (int)props[idmat+2];
+
+	k=idmat+3;          
+	E = props[k++];
+	nu = props[k++];
+	sy0 = props[k++];
+	htype = (int) props[k++];
+	hmod1 = props[k++];
+
+	//hardening models with two hardening moduli
+	if(htype==H_LINEXP){
+		hmod2 = props[k++];
+                hp0 = 0.;
+        }
+        else if(htype==H_POW_EXP){
+                hmod2 = props[k++];
+                hp0 = 0.;
+        }      
+
+        else if(htype==H_POW_EXTRAPOL){
+		hmod2 = props[k++];
+                hp0   = props[k++];
+	}
+
+	//hardening models for Drucker-Prager
+        else if(htype==H_POW_DP){
+		alpha_DP = props[k++];
+                m_DP = props[k++];
+                nup = props[k++];
+		hmod2 = 0.;
+                hp0   = 0.;
+	}
+        else if(htype==H_EXP_DP){
+		alpha_DP = props[k++];
+                m_DP = props[k++];
+                nup = props[k++];
+		hmod2 = 0.;
+                hp0   = 0.;
+	}
+        else if(htype==H_SWIFT_DP){
+		alpha_DP = props[k++];
+                m_DP = props[k++];
+                nup = props[k++];
+		hmod2 = 0.;
+                hp0   = 0.;
+	}
+	else if(htype==H_LINEXP_DP){
+		hmod2 = props[k++];
+                hp0 = 0.;
+		alpha_DP = props[k++];
+                m_DP = props[k++];
+                nup = props[k++];
+        }
+        else if(htype==H_POW_EXP_DP){
+                hmod2 = props[k++];
+                hp0 = 0.;
+		alpha_DP = props[k++];
+                m_DP = props[k++];
+                nup = props[k++];
+        } 
+        else if(htype==H_POW_EXTRAPOL_DP){
+		hmod2 = props[k++];
+                hp0   = props[k++];
+		alpha_DP = props[k++];
+                m_DP = props[k++];
+                nup = props[k++];
+	}
+	else{
+		hmod2 = 0.;
+                hp0   = 0.;
+	}
+
+	hexp = props[k++];
+
+        viscmodel = (int) props[k++];
+        vmod = props[k++];
+        vexp = props[k++];
+        if(viscmodel == V_POWER_NO_HARDENING){
+                vstressy = props[k];
+        }
+        else{
+                vstressy = 0.0;
+        }
+      
+	nsdv = 28;
+	pos_strn=0;
+	pos_strs=6;
+	pos_dstrn=12;
+	pos_pstrn=18;
+	pos_p = 24;
+	pos_dp = 25;
+	pos_twomu = 26;
+	pos_eqstrs = 27;
+        pos_F = nsdv;
+        nsdv += 9;
+        pos_Base = nsdv;
+        nsdv += 9;
+        pos_Ja=nsdv;
+        nsdv += 1;
+        pos_Ri = nsdv;
+        nsdv += 9; 
+
+	dam = init_damage(props,iddam);
+	if(dam){
+		pos_dam = nsdv;
+		nsdv += dam->get_nsdv();
+	}
+
+        clength = init_clength(props,idclength);
+
+#ifdef NONLOCALGMSH
+	if(idclength==0) this->setLocalDamage();
+#endif
+}
+
+bool EVP_Material::eqstrs_exist() const
+{
+        return true;
+}
+
+
+#ifdef NONLOCALGMSH
+int EVP_Material::get_pos_currentplasticstrainfornonlocal() const 
+{
+	return pos_p;
+}
+int EVP_Material::get_pos_effectiveplasticstrainfornonlocal() const
+{
+	if(dam)
+	{
+		return pos_dam;
+	}
+	return -1;
+}
+
+int EVP_Material::get_pos_damagefornonlocal() const
+{
+	if(dam) return pos_dam+2;
+        return -1;
+}
+double EVP_Material::getElasticEnergy (double* statev)
+{
+  double eE = 0.;
+  int i;
+  static double* strn = NULL;
+  static double* pstrn = NULL;
+  static double* strs = NULL;
+  //static double**CelD = NULL;
+  if(strn == NULL)
+  {
+    mallocvector(&strn,6);
+    mallocvector(&pstrn,6);
+    mallocvector(&strs,6);
+   // mallocmatrix(&CelD,6,6);
+  }
+  cleartens2(strn);
+  cleartens2(pstrn);
+  cleartens2(strs);
+
+  copyvect(&(statev[pos_strn]), strn,6);
+  copyvect(&(statev[pos_pstrn]),pstrn,6);
+  copyvect(&statev[pos_strs], strs, 6);
+  //enegry due to damage has been removed
+  for (i =0; i< 6; i++) eE+=0.5*(strs[i]*(strn[i]-pstrn[i]));
+
+  return eE;
+}
+
+double EVP_Material::getPlasticEnergy (double* statev) 
+{
+  double eP = 0.;
+  double p  = statev[get_pos_currentplasticstrainfornonlocal()];
+  int nstepI=1000;
+  eP = sy0*p;
+  switch(htype) {
+    //POWER LAW HARDENING
+    case H_POW:
+      if(fabs(hexp+1.)!=0) 
+         eP+=hmod1*pow(p,hexp+1.)/(hexp+1.);
+      break;
+    //EXPONENTIAL HARDENING
+    case H_EXP:
+      eP+=hmod1*p;
+      if(fabs(hexp)!=0) eP+=hmod1*(exp(-hexp*p)-exp(0))/(hexp);
+      break;
+    //SWIFT LAW
+    case H_SWIFT:
+      eP-=sy0*p;
       if(fabs(hexp+1.)!=0 && fabs(hmod1)!=0.) eP+=sy0*pow(1.+hmod1*p,hexp+1.)/(hexp+1.)/hmod1;
       break;
     //LINEAR-EXPONENTIAL HARDENING
@@ -896,418 +6280,2465 @@ double EP_Stoch_Material::getPlasticEnergy (double* statev)
         eP+=(hmod1*pow(hp0,hexp+1.)+hmod2*(10.*hp0-hp0))*(p-10.*hp0)+hmod2*(p-10.*hp0)*(p-10.*hp0)/2000.;
       }
       break;
+    case H_POW_EXP:
+        for(int i=0; i<nstepI; i++)
+        {
+          double ptmp=((double)(i+1)-0.5)*p/((double)(nstepI));
+          eP+=(hmod1*pow(ptmp,hmod2)*(1.- exp(-hexp*ptmp)))*p/((double)(nstepI));
+        }
+	break;
     default:
-      printf("Bad choice of hardening law in j2hard: %d\n",htype);
+      printf("Bad choice of hardening law in plasticEnergy: %d\n",htype);
       break;
   }
   return eP;
 }
 #endif
 
-//destructor
-EP_Stoch_Material::~EP_Stoch_Material(){
-	if(dam) delete dam;
-        if(clength) delete clength;
-}
+//destructor
+EVP_Material::~EVP_Material(){
+	if(dam) delete dam;
+        if(clength) delete clength;
+}
+
+//print
+void EVP_Material::print(){
+
+	printf("J2 elasto-ViscoPlasticity\n");
+	printf("Young modulus: %lf, Poisson ratio: %lf\n", E, nu);
+	printf("Intial yield stress: %lf, hardening law: %d, hardening coefficients: %lf\t%lf\t%lf\t%lf\t%lf\n", sy0, htype,hmod1,hmod2,hp0, hp0,hexp);
+	printf("ViscoPlastic function: %d, ViscoPlastic coefficients: %lf\t%lf\n", viscmodel, vmod, vexp);
+        if(dam){ dam->print();}
+        if(clength){clength->print();}
+}
+
+//constbox      //*****************New tenor added by wu ling: double* dpdE, double* strs_dDdp_bar ****************
+int EVP_Material::constbox(double* dstrn, double* strs_n,  double* strs, double* statev_n, double* statev, double** Cref, double*** dCref, double* tau, double** dtau, double** Calgo, double alpha, double* dpdE, double* strs_dDdp_bar,double *Sp_bar, double** c_g, double* dFd_d_bar, double* dstrs_dFd_bar, double *dFd_dE, double** c_gF, double* dpdFd, double* dFddp, int kinc, int kstep, double dt){
+
+	int i,j,k,error;
+	double p_n,p;
+	double twomu;
+ 
+	static double* dtwomu;
+	static double*** dCalgo;
+	static double** Idev;
+	static double* pstrn;
+	static double* pstrn_n;
+	static double** Cn;
+        static double* dDdE;                 //*********add by wu ling 
+        double  dDdp_bar;                 //*********add by wu ling 
+        double  D;                    //*********add by wu ling 
+        static double** strs_dDdE;           //*********add by wu ling 
+
+
+ 
+	//allocate memory (only once!)
+        static bool initialized=false;
+        double toleranceDiv=1.e-20;
+	static bool initCn=false; 
+        if(!initialized)
+        {
+	  mallocvector(&dtwomu,6);
+	  malloctens3(&dCalgo,6,6,6);
+	  mallocmatrix(&Idev,6,6);
+	  mallocvector(&pstrn,6);
+	  mallocvector(&pstrn_n,6);
+
+          mallocvector(&dDdE,6);         //*********add by wu ling 
+          mallocmatrix(&strs_dDdE,6,6); //*********add by wu ling 
+	  initialized = true;
+        }
+        cleartens2(dtwomu);
+        cleartens6(dCalgo);
+        cleartens4(Idev);
+        cleartens2(pstrn);
+        cleartens2(pstrn_n);
+        cleartens2(dDdE);
+        cleartens4(strs_dDdE);
+
+	//fill Idev 
+	for(i=0;i<3;i++){
+	  for(j=0;j<3;j++){
+	    Idev[i][j] = -1./3.;
+	  }
+	  Idev[i][i]+=1.;
+	  Idev[i+3][i+3] = 1.;
+	}
+
+	p_n = statev_n[pos_p];
+	copyvect(&(statev_n[pos_pstrn]),pstrn_n,6);
+	p=0.;
+        
+        if(dam)
+        {
+          // put in effective space
+          D = statev_n[pos_dam+2];
+          for(i=0;i<6;i++)
+          {
+            if( D<1.)
+            {
+              strs_n[i] = strs_n[i]/(1.-D);
+	      strs[i]   = strs[i]/(1.-D);
+            }
+          }
+        }
+        if(htype>10)
+        {
+          printf("you need to complete the evp law with Drucker Prager hardening");
+          error =1;
+        }
+        else
+          error=constbox_evp(E, nu, sy0, htype, hmod1, hmod2, hp0, hexp, viscmodel, vmod, vstressy, vexp, dstrn, strs_n, strs, pstrn_n, pstrn, p_n,  
+                     &p, &twomu, dtwomu, Calgo, dCalgo, dpdE,0, dt);
+
+	if(dam)
+        {
+				                 // put back old stress in apparent space
+	   D = statev_n[pos_dam+2];
+	   for(i=0;i<6;i++)
+	   {
+	     if( D<1.)
+	     {
+		strs_n[i] = strs_n[i]*(1.-D);
+	     }
+	     else
+	     {
+		 strs_n[i] = 0.;
+	     }
+	    }
+        }
+
+	//update state variables
+	addtens2(1., statev_n, 1., dstrn, statev); 
+	copyvect(strs, &(statev[pos_strs]),6);
+	copyvect(dstrn, &(statev[pos_dstrn]),6);
+	copyvect(pstrn, &(statev[pos_pstrn]),6);
+	statev[pos_p]=p;
+	statev[pos_dp]=p-p_n;
+	statev[pos_twomu]=twomu;  
+	statev[pos_eqstrs]= vonmises(strs); 
+
+       // prepare for damage box which need effective stress.
+	//copyvect(strs_n, &(statev_n[6]),6);
+
+#ifdef NONLOCALGMSH
+        if(dam && localDamage)
+        {
+          statev[pos_dam]= statev[pos_p];
+	  statev[pos_dam+1]= statev[pos_dp];
+        }
+#else
+// add by wu ling try nonlocal mehod without finite element cacilation
+        if(dam)
+        {
+          statev[pos_dam]= statev[pos_p];
+	  statev[pos_dam+1]= statev[pos_dp];
+        }
+#endif
+
+
+	tau=NULL;
+	dtau=NULL;
+
+
+    
+	
+	makeiso(E/(3.*(1.-2.*nu)), 0.5*twomu, Cref);
+		
+	for(i=0;i<6;i++){
+		for(j=0;j<6;j++){
+			for(k=0;k<6;k++){
+				dCref[i][j][k] = Idev[i][j]*dtwomu[k];
+			}
+		}
+	}
+
+
+ //***** By Wu Ling 06/04/2011************************************************************************************
+        
+       cleartens2(strs_dDdp_bar);    //stress*dDdp_bar
+       cleartens4(strs_dDdE);        //  stress*dDdE
+
+     //TO DO: CALL DAMAGE BOX, IF DAM != NULL
+
+       if(dam){
+               // get damage parameters
+                dDdp_bar=0.0;
+		dam->damagebox(statev_n, statev, pos_strn, pos_strs, pos_dam, Calgo, dDdE, &dDdp_bar, alpha, kinc, kstep);
+
+               // up date reference operator Cref, Calgo and dCref dCalgo according to damage
+                 D = statev[pos_dam+2];
+
+	        //define tensor from effective stress
+
+                 //addtens2( D, strs , 0.0, strs, D_strs_eff); // D*strs_efficvtiv add by wu ling
+
+//*****
+
+                 for(i=0;i<6;i++){
+		         for(j=0;j<6;j++){
+			         for(k=0;k<6;k++){
+				            dCref[i][j][k] = (1.0-D)*dCref[i][j][k];
+                                            dCalgo[i][j][k] = (1.0-D)*dCalgo[i][j][k];
+			         }
+		         }
+                          //  get stress*dDdp_bar
+                         strs_dDdp_bar[i]= -1.*strs[i]*dDdp_bar;
+	         }
+
+
+
+                 for(i=0;i<6;i++){
+	            for(j=0;j<6;j++){
+		            for(k=0;k<6;k++){
+			               dCref[i][j][k] = dCref[i][j][k]-Cref[i][j]*dDdE[k];
+                                       dCalgo[i][j][k] = dCalgo[i][j][k]-Calgo[i][j]*dDdE[k];
+
+		            }
+                    //  get stress*dDdE,
+
+                            strs_dDdE[i][j]=strs[i]*dDdE[j]; 
+	            }        
+                    
+                 }
+
+                 addtens4((1.-D),Cref,0.0,Idev,Cref);
+                 addtens4((1.-D),Calgo,0.0,Idev,Calgo);
+
+                 // add extra item on Calgo to conside the damage ( stress*dDdE)
+                 addtens4 (1.0, Calgo, -1.0, strs_dDdE, Calgo);
+                 
+		 //after computing Jacobian tensor put stress in apparent space
+                 for(i=0;i<6;i++)
+                 {
+	            if( D<1.)
+            	    {
+                      strs[i] = strs[i]*(1.-D);
+            	    }
+            	    else
+	            {
+              	      strs[i] = 0.;
+	            }            
+          	 }
+                 copyvect(strs, &(statev[pos_strs]),6);
+
+                 // put back old stress in apparent space
+                 //   D = statev_n[pos_dam+2];
+                    //for(i=0;i<6;i++)
+                    //{
+                       //if( D<1.)
+                       //{
+                        //strs_n[i] = strs_n[i]*(1.-D);
+                       //}
+                       //else
+                       //{
+                        //strs_n[i] = 0.;
+                       //}
+                    //}
+                  //copyvect(strs_n, &(statev_n[6]),6);
+       }
+
+       //***** end of By Wu Ling 13/04/2011**********************************************************************************
+
+
+
+	//Elastic-plastic transition: use explicit estimate (may improve convergence during elastic-plastic transitions)
+	/*		
+	if( (statev[25] > 0 && statev_n[25] == 0) || (statev[25]==0 && statev_n[25] > 0)){
+		alpha = 0.;
+	}
+	*/
+
+	//generalized mid-point rule
+	if(alpha < 1.){
+
+		//get reference operator of the previous time step
+                if(!initCn)
+                {
+                  mallocmatrix(&Cn,6,6);
+		  initCn=true;
+                }
+                cleartens4(Cn);
+                get_refOp(statev_n, Cn, kinc, kstep);
+		
+		if(alpha==0){
+			copymatr(Cn,Cref,6,6);
+			cleartens6(dCref);
+		}
+		else{
+
+			addtens4((1.-alpha),Cn,alpha,Cref,Cref);
+
+			for(i=0;i<6;i++){
+				for(j=0;j<6;j++){
+					for(k=0;k<6;k++){
+						dCref[i][j][k] *= alpha;
+					}
+				}
+			}
+		}
+		//freematrix(Cn,6); // not anymore as now static
+	}
+
+	
+
+	//free memory not anymore as now static
+//	free(dtwomu);
+//	freetens3(dCalgo,6,6);
+//	freematrix(Idev,6);	
+//	free(pstrn);
+//	free(pstrn_n);
+
+//        free(dDdE);                     //*********add by wu ling 
+//        freematrix(strs_dDdE,6);       //*********add by wu ling 
+
+        clength->creat_cg(statev_n, pos_p, c_g);       //*********add by wu ling 
+        return error;
+}
+//******************************************************
+//costboxSecant
+//****************************************************
+/*int EVP_Material::constboxSecant(double* dstrn, double* strs_n,  double* strs, double* statev_n, double* statev, double **Calgo, double** Csd, double*** dCsd, double** dCsdp_bar, 
+double* dnu, double &dnudp_bar, double alpha, double* dpdE, double* dstrsdp_bar, double** c_g, int kinc, int kstep, double dt){
+
+	int i,j,k,error;
+	double p_n,p;
+        double kappa,tmp;
+        double mu;
+	double twomu;
+	
+	static double* dtwomu = NULL;
+	static double** Idev = NULL, **Ivol = NULL;
+	static double* pstrn = NULL;
+	static double* pstrn_n = NULL;
+        static double* strs_nef = NULL;             // effective stress at tn (residual stress) 
+        static double* strs_ef = NULL;              // effective stress at tn+1 (updated stress) 
+
+        static double* dstrs = NULL, *dstrs_ef = NULL;                // increment of stress 
+
+        static double* dstrs_efdev = NULL;            // dev of increment of stress
+        static double* strs_nefdev = NULL;            // dev of increment of stress at tn
+
+        static double* dDdE = NULL;                 //*********add by wu ling 
+        static double* mat1 = NULL, *mat2 = NULL;
+        static double* dkappa = NULL, *dmu = NULL;
+
+        double dstrs_tra;             // trace of increment of stress
+        double dstrn_tra;
+        double dstrs_eq;
+        double dstrs_efeq;
+        double dstrn_eq;
+        double dDdp_bar;                 //*********add by wu ling 
+        double D;                    //*********add by wu ling 
+// variables for operation
+        double dD;                  // increment of D
+        double dkappadp_bar, dmudp_bar, dkappadD, dmudD, num1, num2, num3;
+
+        static double **strs_dDdE=NULL;
+
+        static bool initialized = false;
+        double toleranceDiv=1.e-20;
+	//allocate memory
+        if(!initialized)
+        {
+          initialized = true;
+  	  mallocvector(&dtwomu,6);
+	  mallocmatrix(&Idev,6,6);
+	  mallocmatrix(&Ivol,6,6);
+	  mallocvector(&pstrn,6);
+	  mallocvector(&pstrn_n,6);
+          mallocvector(&strs_nef,6);
+          mallocvector(&strs_ef,6);
+          mallocvector(&dstrs,6);
+          mallocvector(&dstrs_ef,6);
+          mallocvector(&dstrs_efdev,6);
+          mallocvector(&strs_nefdev,6);
+          mallocvector(&dDdE,6);         //*********add by wu ling 
+          mallocvector(&dkappa,6);       
+          mallocvector(&dmu,6);          
+          mallocvector(&mat1,6);  
+          mallocvector(&mat2,6); 
+
+          mallocmatrix(&strs_dDdE,6,6); 
+        }
+        cleartens2(dtwomu);
+	cleartens4(Idev);
+	cleartens4(Ivol);
+	cleartens2(pstrn);
+	cleartens2(pstrn_n);
+        cleartens2(strs_nef);
+        cleartens2(strs_ef);
+        cleartens2(dstrs);
+        cleartens2(dstrs_ef);
+        cleartens2(dstrs_efdev);
+        cleartens2(strs_nefdev);
+        cleartens2(dDdE);         //*********add by wu ling 
+        cleartens2(dkappa);       
+        cleartens2(dmu);          
+        cleartens2(mat1);  
+        cleartens2(mat2);  
+
+        cleartens4(strs_dDdE);
+        
+
+	//fill Idev and Ivol
+
+	for(i=0;i<3;i++){
+		Idev[i][i]=1.;
+		Idev[i+3][i+3]=1.;
+		for(j=0;j<3;j++){
+			Ivol[i][j]=1./3.;
+			Idev[i][j]=Idev[i][j]-1./3.;
+		}
+	}
+	
+
+	p_n = statev_n[pos_p];
+	copyvect(&(statev_n[pos_pstrn]),pstrn_n,6);
+	p=0.;
+
+       
+       //convert stress into effective stress at tn, the return mapping will not be changed then
+       D=0.0;
+       if(dam){
+               D = statev_n[pos_dam+2];
+       }
+
+       for(i=0;i<6;i++){
+               strs_nef[i]=strs_n[i]/(1.0-D);
+       }
+
+        error=constbox_evp(E, nu, sy0, htype, hmod1, hmod2, hp0, hexp, viscmodel, vmod, vstressy, vexp, dstrn, strs_nef, strs_ef, pstrn_n, pstrn, p_n,  
+                     &p, &twomu, dtwomu, Calgo, dCsd, dpdE, 1, dt);
+
+       // update state variable, and keep the effective stress in state variable for the compuation of damage
+
+	addtens2(1., statev_n, 1., dstrn, statev); 
+	copyvect(strs_ef, &(statev[pos_strs]),6);
+	copyvect(dstrn, &(statev[pos_dstrn]),6);
+	copyvect(pstrn, &(statev[pos_pstrn]),6);
+	statev[pos_p]=p;
+	statev[pos_dp]=p-p_n;
+	statev[pos_twomu]=twomu;
+	statev[pos_eqstrs]= vonmises(strs);   
+ 
+	copyvect(strs_nef, &(statev_n[pos_strs]),6);
+
+       //*****************************************
+       dD=0.0;
+       if(dam){
+               // get damage parameters
+                dDdp_bar=0.0;
+		dam->damagebox(statev_n, statev, pos_strn, pos_strs, pos_dam, Calgo, dDdE, &dDdp_bar, 1., kinc, kstep);
+
+              // update state variable, and convert the effective stress in state variable back
+
+               for(i=0;i<6;i++){
+               statev_n[6+i]=strs_nef[i]*(1.0-D);
+               } 
+
+               D = statev[pos_dam+2];
+               for(i=0;i<6;i++){
+               statev[6+i]=strs_ef[i]*(1.0-D);
+               }
+               dD = D-statev_n[pos_dam+2];
+       }
+               
+
+       // make Csd, secant operator*****************************************************************************************************************************
+
+                for(i=0;i<6;i++){
+                 strs[i]=statev[6+i];
+                 dstrs[i]=statev[6+i]-statev_n[6+i];
+                 dstrs_ef[i]=strs_ef[i]-strs_nef[i];
+               }
+                
+      //check
+      //        printf(" vomin residusl stress of matrix is %e\n", vonmises(strs_nef)); 
+
+               // Compute the trace of a second order tensor-dstrn amd dstrs 
+               dstrs_tra = trace(dstrs_ef);
+               dstrn_tra = trace(dstrn);
+
+               // Extract the deviatoric part of a second order tensor -dstrn amd dstrs 
+               dev(dstrs_ef, dstrs_efdev);  
+               dev(strs_nef, strs_nefdev);  
+   
+
+               // Compute the von Mises equivalent stress 
+               dstrs_eq = vonmises(dstrs_ef);
+
+               // Compute the equivalent strain scalar 
+               dstrn_eq = eqstrn(dstrn);
+
+               // make Csd
+               if(fabs(dstrn_tra)>toleranceDiv and p-p_n >0.){
+                  kappa = dstrs_tra/(3.*dstrn_tra);
+                  if(dam){
+                       kappa = kappa*(1.-D);
+                  }
+               } 
+               else{
+                  kappa = E/3./(1.-2.*nu)*(1.-D);
+               }
+
+
+               if(fabs(dstrn_eq) >toleranceDiv and p-p_n >0.){
+                  mu = dstrs_eq/(3.*dstrn_eq);
+                  if(dam){
+                     mu = mu*(1.-D);
+                 }
+               }
+               else{                 
+                  mu = E/2./(1.+nu)*(1.-D);
+               }
+	       makeiso(kappa, mu, Csd);
+
+       // dCsd/dstrain  and dCsd/dp_bar*****************
+
+               for(i=0;i<6;i++){
+                    dkappa[i] = 0.0;
+               }
+
+          //1. dkappa/dstrain, /dp_bar
+
+            if(dam){
+                  
+               dkappadD =  -E/(3.*(1.-2.*nu));
+               for(i=0;i<6;i++){
+                 dkappa[i] = dkappa[i]+ dkappadD*dDdE[i];
+               }  
+               dkappadp_bar = dkappadD*dDdp_bar;
+             }
+
+          //2. dmu/dstrain, /dp_bar
+
+            for (i=0; i<6; i++) {
+                     mat1[i] = 0.;
+                }
+                for(i=0;i<6;i++){
+                     for (j=0; j<6; j++) {
+                           mat1[i] = mat1[i] + dstrs_efdev[j]*Calgo[j][i];
+                     }
+                }
+
+                for(i=0;i<6;i++){
+		  if(fabs(dstrn_eq)>toleranceDiv and p-p_n >0.)
+                    dmu[i] = ((1.-D)*(1.-D)*mat1[i])/(6.*mu*dstrn_eq *dstrn_eq); 
+		  else
+	            dmu[i] = 0.;
+                }
+               
+                dev(dstrn, mat1);  
+                for(i=0;i<6;i++){
+                  if(fabs(dstrn_eq)>toleranceDiv and p-p_n >0.)
+                    dmu[i] = dmu[i]-2.0*mu*mat1[i]/(3.0*dstrn_eq *dstrn_eq); 
+                }
+
+                if(dam){
+                
+                       num1 = vonmises(dstrs_ef);
+                      
+                       if(fabs(dstrn_eq)>toleranceDiv)
+                         dmudD = -mu/(1.-D); 
+                       else
+                         dmudD = -E/2./(1.+nu); 
+
+                       for(i=0;i<6;i++){
+                            dmu[i] = dmu[i]+ dmudD*dDdE[i]; 
+                       }
+                      dmudp_bar= dmudD*dDdp_bar;
+                }
+
+           //3. dCsd/dstrain, /dp_bar
+
+                for(i=0;i<6;i++){
+                        for(j=0;j<6;j++){
+                                 for(k=0;k<6;k++){   
+            
+                                         dCsd[i][j][k] = 3.0*Ivol[i][j]*dkappa[k]+ 2.0*Idev[i][j]*dmu[k]; 
+                                  }
+                                 dCsdp_bar[i][j]= 3.0*Ivol[i][j]*dkappadp_bar+ 2.0*Idev[i][j]*dmudp_bar;
+                         }
+                } 
+          //4. dnu/dstrain, /dp_bar
+             
+                tmp = (3.*kappa + mu);
+                for(i=0;i<6;i++){
+                   dnu[i] = 9.*mu/(2.*tmp*tmp)*dkappa[i]-9.*kappa/(2.*tmp*tmp)*dmu[i];
+                  
+                }
+                dnudp_bar = 9.*mu/(2.*tmp*tmp)*dkappadp_bar-9.*kappa/(2.*tmp*tmp)*dmudp_bar;
+
+
+           // up date  Calgo and dstrsdp_bar 
+                     
+                 for(i=0;i<6;i++){
+                     dstrsdp_bar[i]= -1.*strs_ef[i]*dDdp_bar;
+	            for(j=0;j<6;j++){
+		           
+                    //  get stress*dDdE,
+                            strs_dDdE[i][j]=strs_ef[i]*dDdE[j]; 
+	            }        
+                 }
+
+           
+                 // add extra item on Calgo to conside the damage ( stress*dDdE)
+                 addtens4 ((1.-D), Calgo, -1.0, strs_dDdE, Calgo);
+                 //printf("j2plast iteration:  p: %.10e\n", statev[pos_p]);
+
+#ifdef NONLOCALGMSH
+#else
+// add by wu ling try nonlocal mehod without finite element cacilation
+        if(dam)
+        {
+          statev[pos_dam]= statev[pos_p];
+  	  statev[pos_dam+1]= statev[pos_dp]; 
+        }
+#endif
+
+        clength->creat_cg(statev_n, pos_p, c_g);        //*********add by wu ling 
+        return error;
+                
+}
+//end of costboxSecant
+
+// constboxSecant with Cs computed from Zero stress
+int EVP_Material::constboxSecantZero(double* dstrn, double* strs_n,  double* strs, double* statev_n, double* statev, double **Calgo, double** Csd, double*** dCsd, double** dCsdp_bar, 
+double* dnu, double &dnudp_bar, double alpha, double* dpdE, double* dstrsdp_bar, double** c_g, int kinc, int kstep, double dt){
+
+
+	int i,j,k,error;
+	double p_n,p;
+        double kappa,tmp;
+        double mu;
+	double twomu;
+
+
+	static double* dtwomu=NULL;
+	static double** Idev=NULL, **Ivol=NULL;
+	static double* pstrn=NULL;
+	static double* pstrn_n=NULL;
+        static double* strs_nef=NULL;             // effective stress at tn (residual stress) 
+        static double* strs_ef=NULL;              // effective stress at tn+1 (updated stress) 
+        static double* strs_efdev=NULL;            // dev of increment of stress
+        static double* dDdE=NULL;                 //*********add by wu ling 
+        static double* mat1=NULL;
+        static double* dkappa=NULL, *dmu=NULL;
+
+        static double** strs_dDdE=NULL;
+
+        double strs_tra;             // trace of increment of stress
+        double dstrn_tra;
+        double strs_eq;
+        double dstrn_eq;
+
+        double  dDdp_bar;                 //*********add by wu ling 
+        double  D;                    //*********add by wu ling 
+
+
+// variables for operation
+        double dkappadp_bar, dmudp_bar, dkappadD, dmudD, num1;
+
+	//allocate memory
+        static bool initialized = false;
+        double toleranceDiv=1.e-20;
+        if(!initialized)
+        {
+          initialized = true;
+	  mallocvector(&dtwomu,6);
+	  mallocmatrix(&Idev,6,6);
+	  mallocmatrix(&Ivol,6,6);
+	  mallocvector(&pstrn,6);
+	  mallocvector(&pstrn_n,6);
+          mallocvector(&strs_nef,6);
+          mallocvector(&strs_ef,6);
+          mallocvector(&strs_efdev,6);
+          mallocvector(&dDdE,6);         //*********add by wu ling 
+          mallocvector(&dkappa,6);       
+          mallocvector(&dmu,6); 
+          mallocvector(&mat1,6);  
+
+         mallocmatrix(&strs_dDdE,6,6); 
+         }
+//printf("dstrn in matrix is %e\n", dstrn[0]);
+	//fill Idev and Ivol
+	 cleartens2(dtwomu);
+	 cleartens4(Idev);
+	 cleartens4(Ivol);
+	 cleartens2(pstrn);
+	 cleartens2(pstrn_n);
+         cleartens2(strs_nef);
+         cleartens2(strs_ef);
+         cleartens2(strs_efdev);
+         cleartens2(dDdE);         //*********add by wu ling 
+         cleartens2(dkappa);       
+         cleartens2(dmu); 
+         cleartens2(mat1);  
+
+         cleartens4(strs_dDdE);
+
+
+
+	for(i=0;i<3;i++){
+		Idev[i][i]=1.;
+		Idev[i+3][i+3]=1.;
+		for(j=0;j<3;j++){
+			Ivol[i][j]=1./3.;
+			Idev[i][j]=Idev[i][j]-1./3.;
+		}
+	}
+	
+
+	p_n = statev_n[pos_p];
+
+        copyvect(&(statev_n[pos_pstrn]),pstrn_n,6);
+	p=0.;
+
+       
+       //convert stress into effective stress at tn, the return mapping will not be changed then
+       D=0.0;
+       if(dam){
+               D = statev_n[pos_dam+2];
+       }
+
+       for(i=0;i<6;i++){
+               strs_nef[i]=strs_n[i]/(1.0-D);
+        }
+   // printf("the trace of residual stress in matrix is %e\n",trace(strs_n));
+        error=constbox_evp(E, nu, sy0, htype, hmod1, hmod2, hp0, hexp, viscmodel, vmod, vstressy, vexp, dstrn, strs_nef, strs_ef, pstrn_n, pstrn, p_n,  
+                     &p, &twomu, dtwomu, Calgo, dCsd, dpdE, 0, dt);
+    
+       // update state variable, and keep the effective stress in state variable for the compuation of damage
+
+	addtens2(1., statev_n, 1., dstrn, statev); 
+	copyvect(strs_ef, &(statev[pos_strs]),6);
+	copyvect(dstrn, &(statev[pos_dstrn]),6);
+	copyvect(pstrn, &(statev[pos_pstrn]),6);
+	statev[pos_p]=p;
+	statev[pos_dp]=p-p_n;
+	statev[pos_twomu]=twomu;  
+	statev[pos_eqstrs]= vonmises(strs); 
+ 
+	copyvect(strs_nef, &(statev_n[pos_strs]),6);
+
+       //*****************************************
+       if(dam){
+               // get damage parameters
+                dDdp_bar=0.0;
+		dam->damagebox(statev_n, statev, pos_strn, pos_strs, pos_dam, Calgo, dDdE, &dDdp_bar, 1., kinc, kstep);
+
+              // update state variable, and convert the effective stress in state variable back
+
+               for(i=0;i<6;i++){
+               statev_n[6+i]=strs_nef[i]*(1.0-D);
+               } 
+
+               D = statev[pos_dam+2];
+               for(i=0;i<6;i++){
+               statev[6+i]=strs_ef[i]*(1.0-D);
+               }
+       }
+               
+
+        // make Csd, secant operator **********************************************************************************
+//check
+
+//if(p-p_n>1.e-8){
+              for(i=0;i<6;i++){
+                 strs[i]=statev[6+i];
+               }
+                
+               // Compute the trace of a second order tensor-dstrn amd strs 
+
+               strs_tra = trace(strs);
+               dstrn_tra = trace(dstrn); //trace(&statev[0]);//trace(dstrn);
+
+               // Extract the deviatoric part of a second order tensor strs_ef 
+               dev(strs_ef, strs_efdev);  
+   
+
+               // Compute the von Mises equivalent stress 
+               strs_eq = vonmises(strs);
+
+
+               // Compute the equivalent strain scalar 
+               dstrn_eq = eqstrn(dstrn);
+
+
+               // make Csd
+               if(fabs(dstrn_tra)>toleranceDiv and p-p_n >0.){
+                 kappa = strs_tra/(3.*dstrn_tra);
+               }
+               else{
+                 kappa = E/3./(1.-2.*nu)*(1.-D);
+               }
+               if(fabs(dstrn_eq) >toleranceDiv and p-p_n >0.){
+                 mu = strs_eq/(3.*dstrn_eq);
+               }
+               else{
+                 mu = E/2./(1.+nu)*(1.-D);
+               }
+
+	       makeiso(kappa, mu, Csd);
+
+       // dCsd/dstrain  and dCsd/dp_bar*****************
+
+            for(i=0;i<6;i++){
+                    dkappa[i] = 0.0;
+               }
+
+          //1. dkappa/dstrain, /dp_bar
+
+              // num1=trace(strs_nef)/3.0;
+
+               for(i=0;i<3;i++){
+                    if(fabs(dstrn_tra)>toleranceDiv and p-p_n >0.)
+                      dkappa[i] = -(1.0-D)*num1/(dstrn_tra*dstrn_tra);
+                    else
+                      dkappa[i] = 0.;
+               }
+               
+               dkappadp_bar = 0.0;
+
+              if(dam){
+               
+                      num1=trace(strs_ef)/3.0;
+    
+                      if(fabs(dstrn_tra)>toleranceDiv and p-p_n >0.)
+                            dkappadD =  -num1/(dstrn_tra);
+                      else
+                            dkappadD =  -E/(3.*(1.-2.*nu));
+                      
+
+                      for(i=0;i<6;i++){
+                           dkappa[i] = dkappa[i]+ dkappadD*dDdE[i];
+                      }  
+                      dkappadp_bar = dkappadD*dDdp_bar;
+              }
+
+          //2. dmu/dstrain, /dp_bar
+
+                for(i=0;i<6;i++){
+                     mat1[i] = 0.;
+                     for (j=0; j<6; j++) {
+                           mat1[i] = mat1[i] + strs_efdev[j]*Calgo[j][i];
+                     }
+                }
+
+
+                for(i=0;i<6;i++){
+		  if(fabs(dstrn_eq)>toleranceDiv and p-p_n >0.)
+                    dmu[i] = (1.-D)*(1.-D)*mat1[i]/(6.*mu*dstrn_eq *dstrn_eq); 
+		  else
+	            dmu[i] = 0.;
+                   
+                }
+               
+                dev(dstrn, mat1);  
+                for(i=0;i<6;i++){
+                  if(fabs(dstrn_eq)>toleranceDiv and p-p_n >0.)
+                    dmu[i] = dmu[i]-2.0*mu*mat1[i]/(3.0*dstrn_eq *dstrn_eq); 
+                }
+                     
+                dmudp_bar= 0.0;
+
+                if(dam){
+                
+                       num1 = vonmises(strs_ef);
+
+                       if(fabs(dstrn_eq)>toleranceDiv and p-p_n >0.)
+                         dmudD = -num1/(3.*dstrn_eq); 
+                       else
+                         dmudD = -E/2./(1.+nu); 
+
+                       for(i=0;i<6;i++){
+                            dmu[i] = dmu[i]+ dmudD*dDdE[i]; 
+                       }
+                      dmudp_bar= dmudD*dDdp_bar;
+                }
+
+           //3. dCsd/dstrain, /dp_bar
+
+                for(i=0;i<6;i++){
+                        for(j=0;j<6;j++){
+                                 for(k=0;k<6;k++){   
+            
+                                         dCsd[i][j][k] = 3.0*Ivol[i][j]*dkappa[k]+ 2.0*Idev[i][j]*dmu[k]; 
+                                  }
+                                 dCsdp_bar[i][j]= 3.0*Ivol[i][j]*dkappadp_bar+ 2.0*Idev[i][j]*dmudp_bar;
+                         }
+                } 
+          //4. dnu/dstrain, /dp_bar
+             
+                tmp = (3.*kappa + mu);
+                for(i=0;i<6;i++){
+                   dnu[i] = 9.*mu/(2.*tmp*tmp)*dkappa[i]-9.*kappa/(2.*tmp*tmp)*dmu[i];
+                  
+                }
+                dnudp_bar = 9.*mu/(2.*tmp*tmp)*dkappadp_bar-9.*kappa/(2.*tmp*tmp)*dmudp_bar;
+
+
+           // up date  Calgo and dstrsdp_bar 
+
+                for(i=0;i<6;i++){
+                     dstrsdp_bar[i]= -1.*strs_ef[i]*dDdp_bar;
+	            for(j=0;j<6;j++){
+		           
+                    //  get stress*dDdE,
+                            strs_dDdE[i][j]=strs_ef[i]*dDdE[j]; 
+	            }        
+                 }
+
+             
+                 // add extra item on Calgo to conside the damage ( stress*dDdE)
+                 addtens4 ((1.-D), Calgo, -1.0, strs_dDdE, Calgo);
+                 //printf("j2plast iteration:  p: %.10e\n", statev[pos_p]);
+
+#ifdef NONLOCALGMSH
+#else
+// add by wu ling try nonlocal mehod without finite element cacilation
+        if(dam)
+        {
+          statev[pos_dam]= statev[pos_p];
+  	  statev[pos_dam+1]= statev[pos_dp]; 
+        }
+#endif
+
+        clength->creat_cg(statev_n, pos_p, c_g);      //*********add by wu ling 
+        return error;
+}*/
+//end of costboxSecant
+
+int EVP_Material::constboxSecantMixte(double* dstrn, double* strs_n,  double* strs, double* statev_n, double* statev, double **Calgo, double** Csd, double*** dCsd, double** dCsdp_bar, 
+double* dnu, double &dnudp_bar, double alpha, double* dpdE, double* dstrsdp_bar, double** c_g, int kinc, int kstep, double dt, bool forceZero, bool forceRes){
+
+        int error;
+	
+        error=constboxSecantMixteGeneric(dstrn, strs_n,  strs, statev_n, statev, Calgo, Csd, dCsd, dCsdp_bar, dnu,  dnudp_bar, alpha, dpdE, dstrsdp_bar, c_g, kinc, kstep, dt, forceZero, forceRes, E, nu, htype, sy0, hexp, hmod1, hmod2, hp0, alpha_DP, m_DP, nup,  viscmodel, vmod, vstressy, vexp, true);
+
+        return error;               
+
+}
+//****************************************************
+// consbox called by MTSecNtr 2rd order method
+//****************************************************
+
+int EVP_Material::constbox_2ndNtr(double *DE, double* dstrn, double* strs_n,  double* strs, double* statev_n, double* statev,  ELcc* LCC, EPR* epresult, double alpha, double** c_g, int kinc, int kstep, double dt){
+
+	int i,j,k,error;
+	double p_n,p;
+        double kappa,temp;
+        double temp1, temp2;
+        double mu;
+	double v0;
+        double mu_el = 0.5*E/(1.+nu); 
+        double eq2strs_n, eq2strs;
+       
+	
+	static double* dstrseq_trdDE = NULL;
+	static double** Idev = NULL, **Ivol = NULL;
+	static double* pstrn = NULL;
+	static double* pstrn_n = NULL;
+        static double* strs_nef = NULL;             // effective stress at tn (residual stress) 
+        static double* strs_ef = NULL;              // effective stress at tn+1 (updated stress) 
+
+        static double* dstrs = NULL, *dstrs_ef = NULL;                // increment of stress 
+
+        static double* dstrs_efdev = NULL;            // dev of increment of stress
+        static double* strs_nefdev = NULL;            // dev of increment of stress at tn
+
+        static double* dDdE = NULL;                 //*********add by wu ling 
+        static double* mat1 = NULL, *mat2 = NULL;
+        static double* dkappa = NULL, *dmu = NULL, *dmudE = NULL;
+
+        static double* mat3 = NULL, *mat4 = NULL;
+   
+        FY2nd  FY2;
+        double dstrs_tra;             // trace of increment of stress
+        double dstrn_tra;
+        double dstrseq_tr;
+        double dstrs_efeq;
+        double dstrn_eq;
+        double dDdp_bar;                 //*********add by wu ling 
+        double D;                    //*********add by wu ling 
+// variables for operation
+        double dD;                  // increment of D
+        double dkappadp_bar, dmudp_bar, dkappadD, dmudD, num1, num2, num3;
+
+        static double **strs_dDdE=NULL;
+
+        static bool initialized = false;
+        double toleranceDiv=1.e-20;
+	//allocate memory
+        if(!initialized)
+        {
+          initialized = true;
+  	  mallocvector(&dstrseq_trdDE,6);
+	  mallocmatrix(&Idev,6,6);
+	  mallocmatrix(&Ivol,6,6);
+	  mallocvector(&pstrn,6);
+	  mallocvector(&pstrn_n,6);
+          mallocvector(&strs_nef,6);
+          mallocvector(&strs_ef,6);
+          mallocvector(&dstrs,6);
+          mallocvector(&dstrs_ef,6);
+          mallocvector(&dstrs_efdev,6);
+          mallocvector(&strs_nefdev,6);
+          mallocvector(&dDdE,6);         //*********add by wu ling 
+          mallocvector(&dkappa,6);       
+          mallocvector(&dmu,6);      
+          mallocvector(&dmudE,6);       
+          mallocvector(&mat1,6);  
+          mallocvector(&mat2,6); 
+
+          mallocvector(&mat3,6);  
+          mallocvector(&mat4,6); 
+
+          mallocmatrix(&strs_dDdE,6,6); 
+        }
+         malloc_YF(&FY2);
+
+      	cleartens2(dstrseq_trdDE);
+        cleartens4(Idev);
+	cleartens4(Ivol);
+	cleartens2(pstrn);
+	cleartens2(pstrn_n);
+        cleartens2(strs_nef);
+        cleartens2(strs_ef);
+        cleartens2(dstrs);
+        cleartens2(dstrs_ef);
+        cleartens2(dstrs_efdev);
+        cleartens2(strs_nefdev);
+        cleartens2(dDdE);         //*********add by wu ling 
+        cleartens2(dkappa);       
+        cleartens2(dmu);          
+        cleartens2(mat1);  
+        cleartens2(mat2);  
+        cleartens2(mat3);  
+        cleartens2(mat4);  
+
+        cleartens4(strs_dDdE);
+
+	//fill Idev and Ivol
+
+	for(i=0;i<3;i++){
+		Idev[i][i]=1.;
+		Idev[i+3][i+3]=1.;
+		for(j=0;j<3;j++){
+			Ivol[i][j]=1./3.;
+			Idev[i][j]=Idev[i][j]-1./3.;
+		}
+	}
+	
+
+	p_n = statev_n[pos_p];
+	copyvect(&(statev_n[pos_pstrn]),pstrn_n,6);
+	p=0.;
+
+        eq2strs_n = statev_n[pos_eqstrs];
+       //convert stress into effective stress at tn, the return mapping will not be changed then
+        D=0.0;
+        if(dam){
+               D = statev_n[pos_dam+2];
+        }
+
+        for(i=0;i<6;i++){
+                strs_nef[i]=strs_n[i]/(1.0-D);
+        }
+        eq2strs_n = eq2strs_n/(1.0-D);
+
+       // compute the trial increment second-moment of von-mises stress
+        v0 = 1.0 - LCC->v1;		
+	contraction42(LCC->dCdmu0,DE,mat1);
+	dstrseq_tr = 3.0*mu_el*sqrt((contraction22(DE,mat1))/(3.*v0));
+	temp = 3.*mu_el;
+	if(fabs(dstrseq_tr) >toleranceDiv) 
+          temp = 3.0*mu_el*mu_el/v0/dstrseq_tr;
+        for (i=0;i<6;i++){
+             dstrseq_trdDE[i] = temp*mat1[i];
+        }
+       // elasto-viscoplastic material return mapping
+        
+        error=constbox_evp(E, nu, sy0, htype, hmod1, hmod2, hp0, hexp, viscmodel, vmod, vstressy, vexp, DE, dstrn, strs_nef, eq2strs_n, &eq2strs, dstrseq_tr, dstrseq_trdDE, strs_ef, pstrn_n, pstrn, p_n, &p, &FY2, dt, LCC);
+       
+       // update state variable, and keep the effective stress in state variable for the compuation of damage
+
+	addtens2(1., statev_n, 1., dstrn, statev); 
+	copyvect(strs_ef, &(statev[pos_strs]),6);
+	copyvect(dstrn, &(statev[pos_dstrn]),6);
+	copyvect(pstrn, &(statev[pos_pstrn]),6);
+	statev[pos_p]=p;
+	statev[pos_dp]=p-p_n;
+ 
+	copyvect(strs_nef, &(statev_n[pos_strs]),6);
+        statev[pos_eqstrs]=eq2strs;
+
+       // 1. make Csd, secant operator without damage D   *************************************************************************
+            kappa = E/(3.*(1.-(2.*nu)));
+
+          //when it is elastic 
+        if((statev[pos_dp]) <= 0.0){
+          // 1.1 kappa, mu and Csd
+              makeiso(kappa, mu_el, epresult->Csd);
+    
+              for(i=0;i<6;i++){
+                      for(j=0;j<6;j++){
+                                for(k=0;k<6;k++){   
+                                      epresult->dCsd[i][j][k] = 0.0; 
+                                      epresult->dCsddE[i][j][k] = 0.0;                                 
+                                 }
+                         }
+                         dmu[i] = 0.0; 
+                         dmudE[i] = 0.0;
+                } 
+          //1.2  Calgo
+               for(i=0;i<6;i++){
+                        for(j=0;j<6;j++){
+                                epresult->Calgo[i][j] = epresult->Csd[i][j];
+                         }
+                }
+          //1.3 dnu and dnudE , dp and dpdE
+                temp = (3.*kappa + mu);
+                for(i=0;i<6;i++){   
+                         epresult->dnu[i] = 0.0; 
+                         epresult->dnudE[i] = 0.0; 
+
+                         epresult->dp[i] = 0.0;
+                         epresult->dpdE[i] = 0.0;                         
+                }
+          }
+          else{
+          // 1.1 kappa, mu and Csd
+
+               kappa = E/(3.*(1.-(2.*nu)));
+	       mu = mu_el;
+	       if(fabs(dstrseq_tr) >toleranceDiv)
+                 mu = mu_el*(1.0 - 3.0*mu_el*(p-p_n)/dstrseq_tr);
+	       makeiso(kappa, mu, epresult->Csd);
+    
+          //1.2  dCsd and dCsddE
+	       temp = 0.;
+	       temp1= 0.;
+	       temp2= 0.;
+	       if(fabs(dstrseq_tr) >toleranceDiv and p-p_n >0.)
+	       {
+                 temp = -6.0*mu_el*mu_el/dstrseq_tr;
+                 temp1 = 18.0*(mu_el*mu_el*mu_el*mu_el)*(p-p_n)/(v0*dstrseq_tr*dstrseq_tr*dstrseq_tr);
+                 temp2 = -6.0*mu_el*mu_el/dstrseq_tr;
+	       }
+  
+               for(i=0;i<6;i++){
+                        for(j=0;j<6;j++){
+                                 for(k=0;k<6;k++){   
+                                      epresult->dCsd[i][j][k] = temp*Idev[i][j]*FY2.dpdstrn_m[k]; 
+                                      epresult->dCsddE[i][j][k] = Idev[i][j]*(temp1*mat1[k] + temp2*FY2.dpdstrn_c[k]);                                 
+                                 }
+                         }
+                         dmu[i] = temp*FY2.dpdstrn_m[i]/2.0; 
+                         dmudE[i] = (temp1*mat1[i] + temp2*FY2.dpdstrn_c[i])/2.0;
+                } 
+          //1.3  Calgo
+               for(i=0;i<6;i++){
+                        for(j=0;j<6;j++){
+                                 epresult->Calgo[i][j]=0.0;
+                                 for(k=0;k<6;k++){   
+                                      epresult->Calgo[i][j] += dstrn[k]*epresult->dCsd[k][i][j];
+                                 }
+                                 epresult->Calgo[i][j] += epresult->Csd[i][j];
+                         }
+                }
+          //1.4 dnu and dnudE , dp and dpdE
+                temp = (3.*kappa + mu);
+                for(i=0;i<6;i++){   
+                         epresult->dnu[i] = -9.*kappa/(2.*temp*temp)*dmu[i]; 
+                         epresult->dnudE[i] = -9.*kappa/(2.*temp*temp)*dmudE[i]; 
+
+                         epresult->dp[i] = FY2.dpdstrn_m[i];
+                         epresult->dpdE[i] = FY2.dpdstrn_c[i];                         
+                }
+
+           }
+          //1.5 when there is no damage, the following tensors are set zero.
+                for(i=0;i<6;i++){
+                        for(j=0;j<6;j++){   
+                                epresult->dCsdp_bar[i][j] = 0.0;                     
+                        }
+                        epresult->dnudp_bar[i] = 0.0;
+                        epresult->dstrsdp_bar[i] = 0.0;
+                } 
+       
+       // 2. if there is a damage defined, Mofify Csd, secant operator *******************************************************
+               
+/*
+
+                for(i=0;i<6;i++){
+                 strs[i]=statev[6+i];
+                 dstrs[i]=statev[6+i]-statev_n[6+i];
+                 dstrs_ef[i]=strs_ef[i]-strs_nef[i];
+               }
+                
+      //check
+      //        printf(" vomin residusl stress of matrix is %e\n", vonmises(strs_nef)); 
+
+               // Compute the trace of a second order tensor-dstrn amd dstrs 
+               dstrs_tra = trace(dstrs_ef);
+               dstrn_tra = trace(dstrn);
+
+               // Extract the deviatoric part of a second order tensor -dstrn amd dstrs 
+               dev(dstrs_ef, dstrs_efdev);  
+               dev(strs_nef, strs_nefdev);  
+   
+
+               // Compute the von Mises equivalent stress 
+               dstrs_eq = vonmises(dstrs_ef);
+
+               // Compute the equivalent strain scalar 
+               dstrn_eq = eqstrn(dstrn);
+
+               // make Csd
+               if(fabs(dstrn_tra)>0. and fabs(dstrn_eq) >0.)
+               {
+                 kappa = dstrs_tra/(3.*dstrn_tra);
+                 mu = dstrs_eq/(3.*dstrn_eq);
+                 if(dam){
+                       kappa = kappa*(1.-D);
+                       mu = mu*(1.-D);
+                 }
+               }
+               else
+               {
+                 kappa = E/3./(1.-2.*nu)*(1.-D);
+                 mu = E/2./(1.+nu)*(1.-D);
+               }
+	       makeiso(kappa, mu, Csd);
+
+       // dCsd/dstrain  and dCsd/dp_bar*****************
+
+               for(i=0;i<6;i++){
+                    dkappa[i] = 0.0;
+               }
+
+          //1. dkappa/dstrain, /dp_bar
+
+            if(dam){
+                  
+               dkappadD =  -E/(3.*(1.-2.*nu));
+               for(i=0;i<6;i++){
+                 dkappa[i] = dkappa[i]+ dkappadD*dDdE[i];
+               }  
+               dkappadp_bar = dkappadD*dDdp_bar;
+             }
+
+          //2. dmu/dstrain, /dp_bar
+
+            for (i=0; i<6; i++) {
+                     mat1[i] = 0.;
+                }
+                for(i=0;i<6;i++){
+                     for (j=0; j<6; j++) {
+                           mat1[i] = mat1[i] + dstrs_efdev[j]*Calgo[j][i];
+                     }
+                }
+
+                for(i=0;i<6;i++){
+		  if(fabs(dstrn_eq)>0. && p-p_n >0.)
+                    dmu[i] = ((1.-D)*(1.-D)*mat1[i])/(6.*mu*dstrn_eq *dstrn_eq); 
+		  else
+	            dmu[i] = 0.;
+                }
+               
+                dev(dstrn, mat1);  
+                for(i=0;i<6;i++){
+                  if(fabs(dstrn_eq)>0.  && p-p_n >0.)
+                    dmu[i] = dmu[i]-2.0*mu*mat1[i]/(3.0*dstrn_eq *dstrn_eq); 
+                }
+
+                if(dam){
+                
+                       num1 = vonmises(dstrs_ef);
+                      
+                       if(fabs(dstrn_eq)>0.)
+                         dmudD = -mu/(1.-D); 
+                       else
+                         dmudD = -E/2./(1.+nu); 
+
+                       for(i=0;i<6;i++){
+                            dmu[i] = dmu[i]+ dmudD*dDdE[i]; 
+                       }
+                      dmudp_bar= dmudD*dDdp_bar;
+                }
+
+           //3. dCsd/dstrain, /dp_bar
+
+                for(i=0;i<6;i++){
+                        for(j=0;j<6;j++){
+                                 for(k=0;k<6;k++){   
+            
+                                         dCsd[i][j][k] = 3.0*Ivol[i][j]*dkappa[k]+ 2.0*Idev[i][j]*dmu[k]; 
+                                  }
+                                 dCsdp_bar[i][j]= 3.0*Ivol[i][j]*dkappadp_bar+ 2.0*Idev[i][j]*dmudp_bar;
+                         }
+                } 
+          //4. dnu/dstrain, /dp_bar
+             
+                tmp = (3.*kappa + mu);
+                for(i=0;i<6;i++){
+                   dnu[i] = 9.*mu/(2.*tmp*tmp)*dkappa[i]-9.*kappa/(2.*tmp*tmp)*dmu[i];
+                  
+                }
+                dnudp_bar = 9.*mu/(2.*tmp*tmp)*dkappadp_bar-9.*kappa/(2.*tmp*tmp)*dmudp_bar;
+
+
+           // up date  Calgo and dstrsdp_bar 
+                     
+                 for(i=0;i<6;i++){
+                     dstrsdp_bar[i]= -1.*strs_ef[i]*dDdp_bar;
+	            for(j=0;j<6;j++){
+		           
+                    //  get stress*dDdE,
+                            strs_dDdE[i][j]=strs_ef[i]*dDdE[j]; 
+	            }        
+                 }
+
+           
+                 // add extra item on Calgo to conside the damage ( stress*dDdE)
+                 addtens4 ((1.-D), Calgo, -1.0, strs_dDdE, Calgo);
+
+
+
+       //*****************************************
+       dD=0.0;
+       if(dam){
+               // get damage parameters
+                dDdp_bar=0.0;
+		dam->damagebox(statev_n, statev, pos_strn, pos_strs, pos_dam, Calgo, dDdE, &dDdp_bar, 1., kinc, kstep);
+// need to change derivatives of D , dDdDE need to be derived  
+              // update state variable, and convert the effective stress in state variable back
+
+               for(i=0;i<6;i++){
+               statev_n[6+i]=strs_nef[i]*(1.0-D);
+               } 
+
+               D = statev[pos_dam+2];
+               for(i=0;i<6;i++){
+               statev[6+i]=strs_ef[i]*(1.0-D);
+               }
+               dD = D-statev_n[pos_dam+2];
+       }
+
+*/
+
+
+
+#ifdef NONLOCALGMSH
+        if(dam && localDamage)
+        {
+          statev[pos_dam]= statev[pos_p];
+  	  statev[pos_dam+1]= statev[pos_dp];
+        }
+#else
+// add by wu ling try nonlocal mehod without finite element cacilation
+        if(dam)
+        {
+          statev[pos_dam]= statev[pos_p];
+  	  statev[pos_dam+1]= statev[pos_dp];
+        }
+#endif
+
+        clength->creat_cg(statev_n, pos_p, c_g);        //*********add by wu ling 
+
+        free_YF(&FY2);
+        return error;
+}
+// end of constbox_2ndNtr()
+
+
+//****************************************************
+//    For large deformation
+// consbox called by MTSecF 1rd order method
+//****************************************************
+
+int EVP_Material::constboxLargD(double* dstrn, double* strs_n,  double* strs, double* statev_n, double* statev, double **Calgo, double** Csd, double*** dCsd, double** dCsdp_bar, 
+double* dnu, double &dnudp_bar, double alpha, double* dpdE, double* dstrsdp_bar, double** c_g, int kinc, int kstep, double dt){
+
+	int i,j,k,error1,error;
+	double p_n,p;
+        double kappa,tmp;
+        double mu;
+	double twomu;
+	
+	static double* dtwomu = NULL;
+	static double** Idev = NULL, **Ivol = NULL;
+	static double* pstrn = NULL;
+	static double* pstrn_n = NULL;
+        static double* strs_nef = NULL;             // effective stress at tn (residual stress) 
+        static double* strs_ef = NULL;              // effective stress at tn+1 (updated stress) 
+        static double* elasstrn = NULL;
+        static double* Rstrs_n = NULL;
+        static double* Rstrs_nef = NULL;
+
+        static double* dstrs = NULL, *dstrs_ef = NULL;                // increment of stress 
+
+        static double* dstrs_efdev = NULL;            // dev of increment of stress
+        static double* strs_nefdev = NULL;            // dev of increment of stress at tn
+
+        static double* dDdE = NULL;                 //*********add by wu ling 
+        static double* mat1 = NULL, *mat2 = NULL;
+        static double* dkappa = NULL, *dmu = NULL;
+
+        static double** Fn = NULL;
+        static double** Fnp1 = NULL;
+        static double** Basen = NULL;
+        static double** Basenp1 = NULL;
+        //static double** mtr = NULL;
+        static double** Rnp1 = NULL;
+        static double** Rn = NULL;
+        static double** dR = NULL;
+        static double* RVect = NULL;
+
+        static double** Cel = NULL;
+        static double** invCel = NULL;
+        static double* strs_tr = NULL;
+        double dstrs_tra;             // trace of increment of stress
+        double dstrn_tra;
+        double dstrs_eq;
+        double dstrs_efeq;
+        double dstrn_eq;
+        double dDdp_bar;                 //*********add by wu ling 
+        double D;                    //*********add by wu ling 
+// variables for operation
+        double dD;                  // increment of D
+        double dkappadp_bar, dmudp_bar, dkappadD, dmudD, num1, num2, num3;
+
+        static double **strs_dDdE=NULL;
+
+        static bool initialized = false;
+        double toleranceDiv=1.e-20;
+	//allocate memory
+        if(!initialized)
+        {
+          initialized = true;
+  	  mallocvector(&dtwomu,6);
+	  mallocmatrix(&Idev,6,6);
+	  mallocmatrix(&Ivol,6,6);
+	  mallocvector(&pstrn,6);
+	  mallocvector(&pstrn_n,6);
+          mallocvector(&strs_nef,6);
+          mallocvector(&strs_ef,6);
+          mallocvector(&dstrs,6);
+          mallocvector(&dstrs_ef,6);
+          mallocvector(&dstrs_efdev,6);
+          mallocvector(&strs_nefdev,6);
+          mallocvector(&Rstrs_n,6);
+          mallocvector(&Rstrs_nef,6);
+          mallocvector(&dDdE,6);         //*********add by wu ling 
+          mallocvector(&dkappa,6);       
+          mallocvector(&dmu,6);          
+          mallocvector(&mat1,6);  
+          mallocvector(&mat2,6); 
+          mallocvector(&strs_tr,6); 
+	  mallocvector(&elasstrn,6);
+	  mallocmatrix(&Cel,6,6);
+	  mallocmatrix(&invCel,6,6);
+          mallocmatrix(&strs_dDdE,6,6); 
+          mallocmatrix(&Fn,3,3);
+          mallocmatrix(&Fnp1,3,3);
+          mallocmatrix(&Basen,3,3);
+          mallocmatrix(&Basenp1,3,3);
+//        mallocmatrix(&mtr,3,3);
+          mallocmatrix(&Rnp1,3,3);
+          mallocmatrix(&Rn,3,3);
+          mallocmatrix(&dR,3,3);
+          mallocvector(&RVect,9);
+        }
+        cleartens2(dtwomu);
+	cleartens4(Idev);
+	cleartens4(Ivol);
+	cleartens2(pstrn);
+	cleartens2(pstrn_n);
+        cleartens2(strs_nef);
+        cleartens2(strs_ef);
+        cleartens2(Rstrs_n);
+        cleartens2(Rstrs_nef);
+        cleartens2(dstrs);
+        cleartens2(dstrs_ef);
+        cleartens2(dstrs_efdev);
+        cleartens2(strs_nefdev);
+        cleartens2(dDdE);         //*********add by wu ling 
+        cleartens2(dkappa);       
+        cleartens2(dmu);          
+        cleartens2(mat1);  
+        cleartens2(mat2);  
+        cleartens2(strs_tr);
+	cleartens2(elasstrn);
+	cleartens4(Cel);
+	cleartens4(invCel);
+        cleartens4(strs_dDdE);
+
+        for (i=0; i<3; i++){
+            for (j=0; j<3; j++){
+             Fn[i][j] = 0.0;
+             Fnp1[i][j] = 0.0;
+             Rnp1[i][j] = 0.0;
+             Rn[i][j] = 0.0;
+             dR[i][j] = 0.0;
+             Basen[i][j] = 0.0;
+             Basenp1[i][j] = 0.0;
+ //            mtr[i][j] = 0.0;
+             RVect[3*i+j]=0.;
+            }
+        } 
+
+        if( kinc==1 and kstep==1){
+               for (i=0; i<3; i++){
+                   for (j=0; j<3; j++){
+                      Rnp1[i][j] = 0.0;
+                       Rn[i][j] = 0.0;
+                       dR[i][j] = 0.0;
+                       Fn[i][j] = 0.0;
+                       Fnp1[i][j] = 0.0;
+                      // Basen[i][j] = 0.0;
+                      // Basenp1[i][j] = 0.0;
+                   }
+                   Rnp1[i][i] = 1.0;
+                   Rn[i][i] = 1.0;
+                   dR[i][i] = 1.0;
+                   Fn[i][i] = 1.0;
+                   Fnp1[i][i] = 1.0;
+                  // Basen[i][i] = 1.0;
+                  // Basenp1[i][i] = 1.0;
+               }
+        }
+        else{
+            vect_to_matrix (3, &(statev[pos_Ri]), Rnp1);
+             vect_to_matrix (3, &(statev_n[pos_Ri]), Rn);
+             vect_to_matrix (3, &(statev[pos_F]), Fnp1);
+             vect_to_matrix (3, &(statev_n[pos_F]), Fn);
+        }
+        vect_to_matrix (3, &(statev[pos_Base]), Basenp1);
+        vect_to_matrix (3, &(statev_n[pos_Base]), Basen);
+            
+
+	//fill Idev and Ivol
+
+	for(i=0;i<3;i++){
+		Idev[i][i]=1.;
+		Idev[i+3][i+3]=1.;
+		for(j=0;j<3;j++){
+			Ivol[i][j]=1./3.;
+			Idev[i][j]=Idev[i][j]-1./3.;
+		}
+	}
+	
+	p_n = statev_n[pos_p];
+	copyvect(&(statev_n[pos_pstrn]),pstrn_n,6);
+	p=0.;
+
+        D=0.0;
+        if(dam){
+                D = statev_n[pos_dam+2];
+        }
+        //get strain at n+1
+        GetdR(Basen, dstrn, dR, Basenp1,sqrt(2.));
+        UpdateFandR(Fn, Rn, dstrn, dR, Fnp1, Rnp1,sqrt(2.)); //Fn should be unloaded state
+
+
+        //rotate residual stress
+        matrix_to_vect(3, dR, RVect);
+        for(i=0;i<6;i++)
+        {
+          Rstrs_n[i]=strs_n[i];
+          strs_nef[i]=strs_n[i]/(1.0-D);
+        }
+        Rot_vect(RVect, Rstrs_n);         
+        for(i=0;i<6;i++){
+               Rstrs_nef[i]=Rstrs_n[i]/(1.0-D);
+        }
+        GetTauRes(dR, &(statev_n[pos_strn]), dstrn, E, nu, strs_tr, Basenp1,sqrt(2.),sqrt(2.));
+
+        //compute deformation gradient F, in order to convert stress into effective stress at tn, the return mapping will not be changed 
+        //GetdR(statev_n, dstrn, statev, dR);  //strn=dstrn+ dR*strn_n*dR^T
+        //GetFr(R, dR, statev, F);                          //get F at n+1
+        //GetTauRes(F, Cp, E, nu, strs_tr, mtr);         //get stress tau_tr at n+1   
+        statev[pos_Ja] = Determinant(Fnp1, 3);
+#if RESIDUAL_FROM_STRAIN_LD==0
+        for(i=0;i<6;i++){
+           strs_tr[i]=strs_tr[i]+Rstrs_n[i];
+        }
+#endif
+         //here check return mapping dir
+        error=constbox_evp(E, nu, sy0, htype, hmod1, hmod2, hp0, hexp, viscmodel, vmod, vstressy, vexp, strs_tr, Rstrs_n, strs_ef, pstrn_n, 
+        pstrn, p_n, &p, Calgo, dCsd, dpdE, 1, dt);
+
+	compute_Hooke(E,nu,Cel);
+        inverse(Cel, invCel, &error1, 6);
+        contraction42(invCel, strs_ef, elasstrn);
+
+       // update state variable, and keep the effective stress in state variable for the compuation of damage
+        //addtens2(1., statev_n, 1., dstrn, statev); //here we could store elastic one
+        copyvect(elasstrn, &(statev[pos_strn]),6);
+ 
+	copyvect(strs_ef, &(statev[pos_strs]),6);
+	copyvect(dstrn, &(statev[pos_dstrn]),6);
+	copyvect(pstrn, &(statev[pos_pstrn]),6);
+	statev[pos_p]=p;
+	statev[pos_dp]=p-p_n;
+	statev[pos_twomu]=twomu;
+	statev[pos_eqstrs]= vonmises(strs_ef);   
+ 
+	copyvect(strs_nef, &(statev_n[pos_strs]),6);
+
+        matrix_to_vect(3, Rnp1, &(statev[pos_Ri]));
+        matrix_to_vect(3, Basenp1, &(statev[pos_Base]));
+        matrix_to_vect(3, Fnp1, &(statev[pos_F]));
+
+       //*****************************************
+       dD=0.0;
+       if(dam){
+               // get damage parameters
+                dDdp_bar=0.0;
+		dam->damagebox(statev_n, statev, pos_strn, pos_strs, pos_dam, Calgo, dDdE, &dDdp_bar, 1., kinc, kstep);
+
+              // update state variable, and convert the effective stress in state variable back
+
+               for(i=0;i<6;i++){
+                 statev_n[pos_strs+i]=strs_nef[i]*(1.0-D);
+               } 
+               D = statev[pos_dam+2];
+               for(i=0;i<6;i++){
+               statev[pos_strs+i]=strs_ef[i]*(1.0-D);
+               }
+               dD = D-statev_n[pos_dam+2];
+       }
+               
+
+       // make Csd, secant operator*****************************************************************************************************************************
+
+                for(i=0;i<6;i++){
+                 strs[i]=statev[pos_strs+i];
+                 dstrs[i]=statev[pos_strs+i]-Rstrs_n[i];
+                 dstrs_ef[i]=strs_ef[i]-Rstrs_nef[i];
+               }
+                
+      //check
+      //        printf(" vomin residusl stress of matrix is %e\n", vonmises(strs_nef)); 
+
+               // Compute the trace of a second order tensor-dstrn amd dstrs 
+               dstrs_tra = trace(dstrs_ef);
+               dstrn_tra = trace(dstrn);
+
+               // Extract the deviatoric part of a second order tensor -dstrn amd dstrs 
+               dev(dstrs_ef, dstrs_efdev);  
+               dev(strs_nef, strs_nefdev);  
+   
+
+               // Compute the von Mises equivalent stress 
+               dstrs_eq = vonmises(dstrs_ef);
+
+               // Compute the equivalent strain scalar 
+               dstrn_eq = eqstrn(dstrn);
+
+               // make Csd
+               if(fabs(dstrn_tra)>toleranceDiv and p-p_n >0.){
+                 kappa = dstrs_tra/(3.*dstrn_tra);
+               }
+               else{
+                 kappa = E/3./(1.-2.*nu)*(1.-D);
+               }
+#if RESIDUAL_FROM_STRAIN_LD==0
+               kappa = E/3./(1.-2.*nu)*(1.-D); //here we cannot use dstrs_tra/dstrn_tra becasue we do not cancel residual but change the secant operator
+#endif
+ 
+               if(fabs(dstrn_eq) >toleranceDiv and p-p_n >0.){
+                  mu = dstrs_eq/(3.*dstrn_eq);
+                  if(dam){
+                     mu = mu*(1.-D);
+                 }
+               }
+               else{                 
+                  mu = E/2./(1.+nu)*(1.-D);
+               }
+	       makeiso(kappa, mu, Csd);
+
+       // dCsd/dstrain  and dCsd/dp_bar*****************
+
+               for(i=0;i<6;i++){
+                    dkappa[i] = 0.0;
+               }
+
+          //1. dkappa/dstrain, /dp_bar
+ 
+               num1=dstrs_tra/3.0;
+
+               for(i=0;i<3;i++){
+                    if(fabs(dstrn_tra)>toleranceDiv and p-p_n >0.)
+                      dkappa[i] = -(1.0-D)*num1/(dstrn_tra*dstrn_tra)+E/3./(1.-2.*nu)*(1.-D)/dstrn_tra;
+                    else
+                      dkappa[i] = 0.;
+#if RESIDUAL_FROM_STRAIN_LD==0
+                 dkappa[i]=0.;
+#endif
+               }
+              
+               dkappadp_bar = 0.0;
+
+              if(dam){
+               
+                      num1=trace(dstrs_ef)/3.0;
+    
+                      if(fabs(dstrn_tra)>toleranceDiv and p-p_n >0.)
+                            dkappadD =  -num1/(dstrn_tra);
+                      else
+                            dkappadD =  -E/(3.*(1.-2.*nu));
+                      
+
+                      for(i=0;i<6;i++){
+                           dkappa[i] = dkappa[i]+ dkappadD*dDdE[i];
+                      }  
+                      dkappadp_bar = dkappadD*dDdp_bar;
+              }
+
+          //2. dmu/dstrain, /dp_bar
+
+            for (i=0; i<6; i++) {
+                     mat1[i] = 0.;
+                }
+                for(i=0;i<6;i++){
+                     for (j=0; j<6; j++) {
+                           mat1[i] = mat1[i] + dstrs_efdev[j]*Calgo[j][i];
+                     }
+                }
+
+                for(i=0;i<6;i++){
+		  if(fabs(dstrn_eq)>toleranceDiv and p-p_n >0.)
+                    dmu[i] = ((1.-D)*(1.-D)*mat1[i])/(6.*mu*dstrn_eq *dstrn_eq); 
+		  else
+	            dmu[i] = 0.;
+                }
+               
+                dev(dstrn, mat1);  
+                for(i=0;i<6;i++){
+                  if(fabs(dstrn_eq)>toleranceDiv and p-p_n >0.)
+                    dmu[i] = dmu[i]-2.0*mu*mat1[i]/(3.0*dstrn_eq *dstrn_eq); 
+                }
+
+                if(dam){
+                
+                       num1 = vonmises(dstrs_ef);
+                      
+                       if(fabs(dstrn_eq)>toleranceDiv)
+                         dmudD = -mu/(1.-D); 
+                       else
+                         dmudD = -E/2./(1.+nu); 
+
+                       for(i=0;i<6;i++){
+                            dmu[i] = dmu[i]+ dmudD*dDdE[i]; 
+                       }
+                      dmudp_bar= dmudD*dDdp_bar;
+                }
+
+           //3. dCsd/dstrain, /dp_bar
+
+                for(i=0;i<6;i++){
+                        for(j=0;j<6;j++){
+                                 for(k=0;k<6;k++){   
+            
+                                         dCsd[i][j][k] = 3.0*Ivol[i][j]*dkappa[k]+ 2.0*Idev[i][j]*dmu[k]; 
+                                  }
+                                 dCsdp_bar[i][j]= 3.0*Ivol[i][j]*dkappadp_bar+ 2.0*Idev[i][j]*dmudp_bar;
+                         }
+                } 
+          //4. dnu/dstrain, /dp_bar
+             
+                tmp = (3.*kappa + mu);
+                for(i=0;i<6;i++){
+                   dnu[i] = 9.*mu/(2.*tmp*tmp)*dkappa[i]-9.*kappa/(2.*tmp*tmp)*dmu[i];
+                  
+                }
+                dnudp_bar = 9.*mu/(2.*tmp*tmp)*dkappadp_bar-9.*kappa/(2.*tmp*tmp)*dmudp_bar;
+
+
+           // up date  Calgo and dstrsdp_bar 
+                     
+                 for(i=0;i<6;i++){
+                     dstrsdp_bar[i]= -1.*strs_ef[i]*dDdp_bar;
+	            for(j=0;j<6;j++){
+		           
+                    //  get stress*dDdE,
+                            strs_dDdE[i][j]=strs_ef[i]*dDdE[j]; 
+	            }        
+                 }
+
+           
+                 // add extra item on Calgo to conside the damage ( stress*dDdE)
+                 addtens4 ((1.-D), Calgo, -1.0, strs_dDdE, Calgo);
+                 //printf("j2plast iteration:  p: %.10e\n", statev[pos_p]);
+
+          // updat internal variables for large deformation***************************
+          //**************** R, Cp, Ja ****************
+          //       matrix_to_vect(3, R, &(statev[pos_Ri]));
+          //       GetCp(elasstrn, mtr, F, Cp);
+          //       for (i=0; i<3; i++){statev[pos_Cp+i] = Cp[i][i];}
+          //       statev[pos_Cp+3] = Cp[0][1];
+          //       statev[pos_Cp+4] = Cp[0][2];
+          //       statev[pos_Cp+5] = Cp[1][2];             
+        
+#ifdef NONLOCALGMSH
+        if(dam && localDamage)
+        {
+          statev[pos_dam]= statev[pos_p];
+  	  statev[pos_dam+1]= statev[pos_dp];
+        }
+#else
+// add by wu ling try nonlocal mehod without finite element cacilation
+        if(dam)
+        {
+          statev[pos_dam]= statev[pos_p];
+  	  statev[pos_dam+1]= statev[pos_dp];
+        }
+#endif
+
+        clength->creat_cg(statev_n, pos_p, c_g);        //*********add by wu ling 
+        return error;
+                
+}
+// end of constbox_LargD()
+
+//****************************************************
+// consbox called by 2rd order method
+//****************************************************
+
+int EVP_Material::constbox_2order(int mtx, double *DE, double* dstrn, double* strs, double* statev_n, double* statev,  double **Calgo, Lcc* LCC, YieldF* YF, double** c_g, int kinc, int kstep, double dt){
+
+        int i,j,k,m,n;
+        int error,error1;
+	double dp,p;
+	double R, dR, ddR;
+        double tiny_p =1.0e-6;
+        double eqstrs_n, temp, temp_trial, temp1,temp2;
+        double mu_el = 0.5*E/(1.+nu);           // elastic shear modulus
+	double mu, v0, v1;
+	
+	static double** I = NULL, **Idev = NULL;
+        static double* strs_n = NULL;             // effective stress at tn (residual stress) 
+
+        static double* dstrn_dmu0 = NULL;   
+        static double* dstrn_dmu1 = NULL; 
+        static double** dstrn_dDE =NULL;              
+
+        static double* dstrs = NULL;               // increment of stress 
+
+        static double* strn_el = NULL;              //elastic strain
+        static double* dstrn_dev = NULL;            // dev of increment of stress
+        static double* strn_dev = NULL; 
+        static double* strs_dev = NULL;            // dev of increment of stress at tn
+        static double* strs_ndev = NULL;
+        static double* dstrs_devtrial =NULL;            // trial increment stress
+
+        static double* dstrs_eqtrialdDE = NULL;                 //*********add by wu ling 
+        static double* dstrs_eqdDE = NULL;
+        static double* mat1 = NULL, *mat2 = NULL, *mat3=NULL;
+        static double* Ntr = NULL;
+        static double* pstrn = NULL;
+        static double* dpdDE = NULL;
+        static double *dstrn_eq2dDE = NULL;
+        static double **A_m = NULL;
+        static double **invA_m = NULL;
+
+       static double *DE_e = NULL;
+
+
+        double strs_eq2trial;             // square of trial equivalent stress
+        double strs_eq2;                 // square of equivalent stress
+
+        double dstrn_eq2;
+        double dstrn_eq2dmu0;
+        double dstrn_eq2dmu1;
+
+        double dstrs_eqdmu0, dstrs_eqdmu1;
+        double dstrs_eqtrialdmu0, dstrs_eqtrialdmu1;
+
+        double dpdmu0, dpdmu1;                 //*********add by wu ling 
+ 
+        static bool initialized = false;
+        double toleranceDiv=1.e-20;
+	//allocate memory
+        if(!initialized)
+        {
+          initialized = true;
+	  mallocmatrix(&Idev,6,6);
+	  mallocmatrix(&I,6,6);
+	  mallocvector(&pstrn,6);
+          mallocvector(&strs_n,6);
+          mallocvector(&dstrs,6);
+          mallocvector(&dstrs_devtrial,6);
+          mallocvector(&strn_el,6);
+          mallocvector(&dstrn_dev,6);
+          mallocvector(&strn_dev,6);
+          mallocvector(&strs_dev,6);
+          mallocvector(&strs_ndev,6);
+          mallocvector(&dstrs_eqdDE,6);   
+          mallocvector(&dstrs_eqtrialdDE,6);              
+          mallocvector(&mat1,6);  
+          mallocvector(&mat2,6); 
+          mallocvector(&mat3,6); 
+          mallocvector(&Ntr,6); 
+          mallocvector(&dpdDE,6); 
+          mallocvector(&dstrn_eq2dDE,6); 
+          mallocmatrix(&dstrn_dDE,6,6);
+
+          mallocvector(&dstrn_dmu0,6);
+          mallocvector(&dstrn_dmu1,6);
+          mallocvector(&DE_e,6);
+	  mallocmatrix(&A_m,6,6);
+	  mallocmatrix(&invA_m,6,6);
+
+        }
+	cleartens4(Idev);
+	cleartens4(I);
+	cleartens2(pstrn);
+        cleartens2(strs_n);
+        cleartens2(dstrs);
+        cleartens2(dstrs_devtrial);
+        cleartens2(strn_el);
+        cleartens2(strs_dev);
+        cleartens2(strs_ndev);
+        cleartens2(dstrs_eqdDE);        
+        cleartens2(dstrs_eqtrialdDE);       
+        cleartens2(mat1);  
+        cleartens2(mat2);  
+        cleartens2(mat3);  
+        cleartens2(Ntr);  
+        cleartens2(dpdDE);            
+        cleartens2(dstrn_eq2dDE); 
+        cleartens4(dstrn_dDE);
+
+        cleartens2(dstrn_dmu0);
+        cleartens2(dstrn_dmu1);
+        cleartens2(DE_e);            
+        cleartens4(A_m);            
+        cleartens4(invA_m);            
+
+        v1 = LCC->v1;
+        v0 = 1.- v1; 
+        error=0;
+
+	//fill Idev and Ivol
+
+	for(i=0;i<3;i++){
+		Idev[i][i]=1.;
+		Idev[i+3][i+3]=1.;
+		I[i][i]=1.;
+		I[i+3][i+3]=1.;
+		for(j=0;j<3;j++){
+			Idev[i][j]=Idev[i][j]-1./3.;
+		}
+	}	
+	
+
+       //1.1 Compute residual stress  
+	 copyvect(&(statev_n[pos_strs]),strs_n,6);
+         eqstrs_n = statev_n[pos_eqstrs];   
+   
+	 addtens2(1., statev_n, 1., dstrn, statev); 
+	 copyvect(dstrn, &(statev[pos_dstrn]),6);
 
-//print
-void EP_Stoch_Material::print(){
+        
+       //1.2 Compute current stress and stress increment and derivatives of incremental strn to mu and macro strain DE
+         if(mtx){
 
-	printf("Stochastic J2 elasto-plasticity\n");
-	printf("Young modulus: %lf, Poisson ratio: %lf\n", _E, _nu);
-	printf("Intial yield stress: %lf, hardening law: %d, hardening coefficients: %lf\t%lf\t%lf\t%lf\n", _sy0,
-                                                                               htype,_hmod1,_hmod2,_hp0,_hexp);
-	if(dam){ dam->print();}
-        if(clength){clength->print();}
-}
+            //  addtens2(1., statev, -1., &statev_n[pos_pstrn], strn_el);
+            //  contraction42(LCC->C0, strn_el, strs);
+               contraction42(LCC->C0, dstrn, dstrs);
+               
+              addtens2(1., statev_n, -1., &statev_n[pos_pstrn], mat1);
 
-//constbox      //*****************New tenor added by wu ling: double* dpdE, double* strs_dDdp_bar ****************
-int EP_Stoch_Material::constbox(double* dstrn, double* strs_n,  double* strs, double* statev_n, double* statev, double** Cref, double*** dCref, double* tau, double** dtau, double** Calgo, double alpha, double* dpdE, double* strs_dDdp_bar,double *Sp_bar, double** c_g, double* dFd_d_bar, double* dstrs_dFd_bar, double *dFd_dE, double** c_gF, double* dpdFd, double* dFddp, int kinc, int kstep, double dt){
+              contraction42(LCC->C0, mat1, strs_n);
+              addtens2(1., strs_n, 1., dstrs, strs); 
 
-  return (1);
-}
-//******************************************************
-//costboxSecant
-//****************************************************
-int EP_Stoch_Material::constboxSecantMixte(double* dstrn, double* strs_n,  double* strs, double* statev_n, double*
-statev, double **Calgo, double** Csd, double*** dCsd, double** dCsdp_bar, double* dnu, double& dnudp_bar, double alpha, double* dpdE, double* dstrsdp_bar, double** c_g, int kinc, int kstep, double dt, bool forceZero, bool forceRes)
-{
-  return (1);
+              mu=LCC->mu[0];
 
-}
-//end of costboxSecant
+              contraction42(LCC->dAdmu0, DE, mat1);
+              addtens2(-v1/v0, mat1, 0., mat2, dstrn_dmu0); 
 
+              contraction42(LCC->dAdmu1, DE, mat1);
+              addtens2(-v1/v0, mat1, 0., mat2, dstrn_dmu1);    
 
-//****************************************************
-// consbox called by MTSecNtr 2rd order method
-//****************************************************
+              addtens4(1./v0, I, -v1/v0, LCC->A, dstrn_dDE);
 
-int EP_Stoch_Material::constbox_2ndNtr(double *DE, double* dstrn, double* strs_n,  double* strs, double* statev_n, double* statev,  ELcc* LCC, EPR* epresult, double alpha, double** c_g, int kinc, int kstep, double dt){
+           //   printf("p in matrix is: %.5e\n", statev_n[pos_p]);
 
 
- return (1);          
-}
-// end of constbox_2ndNtr()
+              copyvect(strs, &(statev[pos_strs]),6);
+              dev(dstrn, dstrn_dev);
+         dev(strs, strs_dev);
+         dev(statev, strn_dev);
+         contraction42(Idev, strn_el, mat1);
+         contraction42(Idev, strs_n, strs_ndev);
 
+//addtens2(1., statev_n, -1., &statev_n[pos_pstrn], mat2);
 
+              addtens4(1.0/v0, I, -v1/v0, LCC->A, A_m);
+              inverse (A_m, invA_m, &error1, 6);
+              contraction42(invA_m, strn_el, DE_e);
 
-//****************************************************
-//****************************************************
 
-void EP_Stoch_Material::get_refOp(double* statev, double** C, int kinc, int kstep){
-	
-	double twomu, threekappa, D;
-        double E, nu;
+              eqstrn2_order2(mtx, DE, LCC, &dstrn_eq2, dstrn_eq2dDE, &dstrn_eq2dmu0, &dstrn_eq2dmu1);
 
-        if(pos_E != 0) E = statev[pos_E];
-        else E = _E;
 
-        if(pos_nu != 0) nu = statev[pos_nu];
-        else nu = _nu;
+        /*      strs_eq2 = 9.0*mu*mu*(dstrn_eq2)+3.0*contraction22(dstrs,strs_ndev)+eqstrs_n;
+                
+       // 2.1 apply J2 plasticity for YF->trial, and f
+       	  dp = tiny_p;
+          p= statev_n[pos_p]+ dp;
+          j2hard(p, sy0, htype, hmod1, hmod2, hp0, hexp, &R, &dR,&ddR);
 
-	if(kinc<2 && kstep==1){
-	   get_elOp(statev, C);
-	}
-	//if(kinc<2 ){
-                //get_elOD(statev,C);
-	//}
-	else{
-                twomu = statev[pos_twomu];
-		threekappa = E/(1.-2.*nu); 
+          temp = sqrt(strs_eq2) - (sy0+R);   //check plasticity      
 
+          YF->trial= 0.0;
+          YF->f = 0.0;
+          if( (temp >0.0) || (mu < mu_el))  YF->trial=1.0;
+          
+          if(YF->trial > 0.0){
+             dp = sqrt(dstrn_eq2)*(1.0-mu/mu_el);
+           
+             temp = 2.0*sqrt(strs_eq2);
+      // 2.2 the derivatives of strs_eqtrial and strs_eq
+      
+               dstrs_eqdmu0 = (9.0*mu*mu*dstrn_eq2dmu0+18.0*mu*dstrn_eq2 + 6.0*mu*contraction22(strs_ndev, dstrn_dmu0) 
+                               + 6.0*contraction22(strs_ndev, dstrn))/temp;
 
-                if(dam){                                           //*********add by wu ling 
-                        D = statev[pos_dam+2];                     //***********13.04.2011********
-		        twomu = twomu*(1-D);
-		        threekappa = threekappa*(1-D);
-                 }
-		makeiso(threekappa/3.,twomu/2.,C);
-	}
+               dstrs_eqdmu1 = (9.0*mu*mu*dstrn_eq2dmu1 + 6.0*mu*contraction22(strs_ndev, dstrn_dmu1))/temp;
 
-}
+               for(i=0;i<6;i++){
+                       mat1[i] = 0.0;
+                       for(j=0;j<6;j++){
+                               mat1[i] += dstrn_dDE[j][i]*strs_ndev[j];
+                       }
+               }
+ 
+               addtens2(9.0*mu*mu/temp, dstrn_eq2dDE, 6.0*mu/temp, mat1, dstrs_eqdDE); */
 
-void EP_Stoch_Material::get_elOD(double* statev, double** Cel)
-{
-     get_elOp(statev, Cel);
-     if(dam)
-     {
-       double damage = statev[pos_dam+2];
-       for(int i=0; i < 6; i++)
-         for(int j=0; j < 6; j++)
-           Cel[i][j]*=1.-damage;
-    }
+
+
+          strs_eq2 = 9.0*mu*mu*(dstrn_eq2);
+                
+       // 2.1 apply J2 plasticity for YF->trial, and f
+       	  dp = tiny_p;
+          p= statev_n[pos_p]+ dp;
+          j2hard(p, sy0, htype, hmod1, hmod2, hp0, hexp, &R, &dR,&ddR);
+//////////////////////add temperataly for EVP
+dp=1.e-5*pow(sqrt(strs_eq2),5.0)*dt;
+if(dp>tiny_p){         
+R=pow(dp/dt*1.e5,0.2);  //for evp 
+dR=pow(1.e5/dt,0.2)*0.2*pow(dp,-0.8);
+temp = sqrt(strs_eq2) - (sy0+R);   //check plasticity  
 }
+else{
+temp = 0.0; 
+}
+///////////////////////////////////////////end
 
+        //  temp = sqrt(strs_eq2) - (sy0+R);   //check plasticity  
+printf("2st R, dR= %f,%f,%f\n",R,dR,temp);    
 
-void EP_Stoch_Material::get_elOp(double* statev, double** Cel){
+          YF->trial= 0.0;
+          YF->f = 0.0;
+          if( (temp >0.0) || (mu < mu_el))  YF->trial=1.0;
+          
+          if(YF->trial > 0.0){
+             dp = sqrt(dstrn_eq2)*(1.0-mu/mu_el);
+           
+             temp = 2.0*sqrt(strs_eq2);
+      // 2.2 the derivatives of strs_eqtrial and strs_eq
+      
+               dstrs_eqdmu0 = (9.0*mu*mu*dstrn_eq2dmu0+18.0*mu*dstrn_eq2 )/temp;
 
-        double E, nu;
-        if(pos_E != 0) E = statev[pos_E];
-        else E = _E;
+               dstrs_eqdmu1 = (9.0*mu*mu*dstrn_eq2dmu1)/temp;
 
-        if(pos_nu != 0) nu = statev[pos_nu];
-        else nu = _nu;
+               
+               addtens2(9.0*mu*mu/temp, dstrn_eq2dDE, 0.0, mat1, dstrs_eqdDE); 
 
-	compute_Hooke(E,nu,Cel);
-}
+        // 2.3 the derivatives of dp
+               temp = 2.0*sqrt(dstrn_eq2);                    
+                     dpdmu0 = dstrn_eq2dmu0*(1.0-mu/mu_el)/temp - sqrt(strs_eq2)/mu_el;
+                     dpdmu1 = dstrs_eqdmu1*(1.0-mu/mu_el)/temp;
 
-void  EP_Stoch_Material::get_elOp(double** Cel) {
-	compute_Hooke(_E,_nu,Cel);
-}
+                     addtens2((1.0-mu/mu_el)/(temp), dstrn_eq2dDE, 0.0, mat1, dpdDE);  
+                  
 
-void EP_Stoch_Material::unload_step(double* dstrn,double* strs_n, double* statev_n, int kinc, int kstep){
+             dp = max(dp,tiny_p);
+             p = statev_n[pos_p]+ dp;
+             j2hard(p, sy0, htype, hmod1, hmod2, hp0, hexp, &R, &dR,&ddR);
+             R=pow(dp/dt*1.e5,0.2);  //for evp 
+             dR=pow(1.e5/dt,0.2)*0.2*pow(dp,-0.8);
 
-       if(kinc == 1 && kstep==1){
-		return;
-	}
 
-	int i,error;
-	static double **C0=NULL;
-        static double **invC0=NULL;
-	static double *strs=NULL;
-        static double *udstrn=NULL;
-        if(C0==NULL)
-        {
-  	  mallocmatrix(&C0,6,6);
-	  mallocmatrix(&invC0,6,6);	
-          mallocvector(&strs,6);
-          mallocvector(&udstrn,6);
-        }
-        cleartens4(C0);
-        cleartens4(invC0);
-        cleartens2(strs);
-        cleartens2(udstrn);
+             YF->f = sqrt(strs_eq2) - (sy0+R);      //check yielding function is satisfied or not.
+      
+     //  3.1 the derivatives of
 
+	     YF->dfdmu[0] = dstrs_eqdmu0 - dR*dpdmu0;
 
+	     YF->dfdmu[1] = dstrs_eqdmu1 - dR*dpdmu1;
+ 
+             addtens2(1.0, dstrs_eqdDE, -(dR), dpdDE, YF->dfdstrn);
+            }
 
-	get_elOD(statev_n, C0);
-	inverse(C0,invC0,&error,6);
-	if(error!=0) printf("problem while inversing C0 in unload_step of MTSecF\n");
+         }
+         else{
+              //*************
+               contraction42(LCC->C1, dstrn, dstrs);
+               addtens2(1., strs_n, 1., dstrs, strs); 
+
+               mu=LCC->mu[1];
+
+               contraction42(LCC->dAdmu0, DE, dstrn_dmu0); 
+               contraction42(LCC->dAdmu1, DE, dstrn_dmu1);    
+               addtens4(1., LCC->A, 0., I, dstrn_dDE);
+             
+              //**************
+              copyvect(strs, &(statev[pos_strs]),6);
+              dev(strs, strs_dev);
+              dev(dstrn, dstrn_dev);
+             
+       // 2.1 apply J2 plasticity for YF->trial, and f
+              strs_eq2 = 1.5*contraction22(strs_dev, strs_dev);
+       	      dp = tiny_p;
+              p= statev_n[pos_p]+ dp;
+              j2hard(p, sy0, htype, hmod1, hmod2, hp0, hexp, &R, &dR,&ddR);
+//////////////////////add temperataly for EVP
+dp=1.e-5*pow(sqrt(strs_eq2),5.0)*dt;
+if(dp>tiny_p){         
+R=pow(dp/dt*1.e5,0.2);  //for evp 
+dR=pow(1.e5/dt,0.2)*0.2*pow(dp,-0.8);
+temp = sqrt(strs_eq2) - (sy0+R);   //check plasticity  
+}
+else{
+temp = 0.0; 
+}
+///////////////////////////////////////////end
+
+        //  temp = sqrt(strs_eq2) - (sy0+R);   //check plasticity 
+              YF->trial= 0.0;
+              YF->f = 0.0;
+              if( (temp >0.0) || (mu < mu_el)) {
+                   YF->trial=1.0;
+
+                   dstrn_eq2 = 2.0*contraction22(dstrn_dev, dstrn_dev)/3.0;
+                   dp = sqrt(dstrn_eq2)*(1.0-mu/mu_el);
+
+                   temp = 2.0*sqrt(strs_eq2);
+       // 2.2 the derivatives of strs_eq2
+                   dstrs_eqdmu0 = 6.0*mu*contraction22(strs_dev, dstrn_dmu0)/temp;
+                   dstrs_eqdmu1 = (6.0*mu*contraction22(strs_dev, dstrn_dmu1)+6.0*contraction22(strs_dev, dstrn_dev))/temp;
+
+                   for(i=0;i<6;i++){
+                           mat1[i] = 0.0;
+                           mat2[i] = 0.0;
+                           for(j=0;j<6;j++){ 
+                               mat1[i] = mat1[i] + strs_dev[j]*dstrn_dDE[j][i];
+                               mat2[i] = mat2[i] + dstrn_dev[j]*dstrn_dDE[j][i];
+                           }
+                   }
+                   addtens2(6.0*mu/temp, mat1, 0.0, mat1, dstrs_eqdDE); 
+
+       // 2.3 the derivatives of dp
+
+                   temp = 2.0/(3.0*sqrt(dstrn_eq2));
+                   dpdmu0 = temp*contraction22(dstrn_dev, dstrn_dmu0)*(1.0-mu/mu_el);
+                   dpdmu1 = temp*contraction22(dstrn_dev, dstrn_dmu1)*(1.0-mu/mu_el)-sqrt(dstrn_eq2)/mu_el;
+
+                   addtens2((1.0-mu/mu_el)*temp, mat2, 0.0, mat1, dpdDE);
+       // 2.4  update YF->f
+                   dp = max(dp,tiny_p);
+                   p = statev_n[pos_p]+ dp;
+                   j2hard(p, sy0, htype, hmod1, hmod2, hp0, hexp, &R, &dR,&ddR);
+
+//////////////////////add temperataly for EVP
+dp=1.e-5*pow(sqrt(strs_eq2),5.0)*dt;
+if(dp>tiny_p){         
+R=pow(dp/dt*1.e5,0.2);  //for evp 
+dR=pow(1.e5/dt,0.2)*0.2*pow(dp,-0.8);
+temp = sqrt(strs_eq2) - (sy0+R);   //check plasticity  
+}
+else{
+temp = 0.0; 
+}
+///////////////////////////////////////////end
+
+        //  temp = sqrt(strs_eq2) - (sy0+R);   //check plasticity 
+                   YF->f = sqrt(strs_eq2) - (sy0+R);       //check yielding function is satisfied or not.
+      
+      //  3.1 the derivatives of
 
-	copyvect(&statev_n[pos_strs], strs, 6);        //stress in at tn
-        contraction42(invC0, strs, udstrn);          //unloading strain of composite at tn
-       
- // update statev_n to keep the imformation for residual condition 
+	           YF->dfdmu[0] = dstrs_eqdmu0 - dR*dpdmu0;
+	           YF->dfdmu[1] = dstrs_eqdmu1 - dR*dpdmu1; 
+                   addtens2(1.0, dstrs_eqdDE, -(dR), dpdDE, YF->dfdstrn);
+                }
+              }   
 
-        for(i=0;i<6;i++){
-	strs_n[i]=0.0;	
-        statev_n[pos_strs +i]=0.0;                                   //residual stress is 0
-        statev_n[pos_strn +i]= statev_n[pos_strn +i]- udstrn[i];      //residual strain 
-        statev_n[pos_dstrn +i]= dstrn[i]+ udstrn[i];    // strain increment in composte
+                  
+               
 
-        dstrn[i]= statev_n[pos_dstrn +i];
-      	}
 
+ /* if(mtx){
 
-}
+               addtens2(1., statev, -1., &statev_n[pos_pstrn], strn_el);
+               contraction42(LCC->C0, strn_el, strs);
+            //   contraction42(LCC->C0, dstrn, dstrs);
+          //     addtens2(1., strs_n, 1., dstrs, strs); 
 
+               mu=LCC->mu[0];
 
-//****************************************************************************************
-//**** RATE-DEPENDENT elasto-viscoplastic material ************************************
-//PROPS: MODEL, iddam, E, nu, sy0, htype, hmod1, (hmod2, hp0), hexp, viscmodel, vmod, vexp 
-//STATEV: strn, strs, dstrn, pstrn, p, dp, 2*mu_iso
-//****************************************************************************************
-//constructor
-EVP_Material::EVP_Material(double* props, int idmat):Material(props, idmat){
-	int k;
-	int iddam, idclength;
-	
+               contraction42(LCC->dAdmu0, DE, mat1);
+               addtens2(-v1/v0, mat1, 0., mat2, dstrn_dmu0); 
 
-	iddam = (int)props[idmat+1];
-        idclength = (int)props[idmat+2];
+               contraction42(LCC->dAdmu1, DE, mat1);
+               addtens2(-v1/v0, mat1, 0., mat2, dstrn_dmu1);    
 
-	k=idmat+3;          
-	E = props[k++];
-	nu = props[k++];
-	sy0 = props[k++];
-	htype = (int) props[k++];
-	hmod1 = props[k++];
+               addtens4(1./v0, I, -v1/v0, LCC->A, dstrn_dDE);
 
-	//hardening models with two hardening moduli
-	if(htype==H_LINEXP) {
-		hmod2 = props[k++];
-                hp0 = 0.;
-        }
-        else if(htype==H_POW_EXTRAPOL){
-		hmod2 = props[k++];
-                hp0   = props[k++];
-	}
-	else{
-		hmod2 = 0.;
-                hp0   = 0.;
-	}
-	hexp = props[k++];
+              printf("p in matrix is: %.5e\n", statev_n[pos_p]);
 
-        viscmodel = (int) props[k++];
-        vmod = props[k++];
-        vexp = props[k++];
-        if(viscmodel == V_POWER_NO_HARDENING){
-                vstressy = props[k];
-        }
-        else{
-                vstressy = 0.0;
-        }
-      
-	nsdv = 28;
-	pos_strn=0;
-	pos_strs=6;
-	pos_dstrn=12;
-	pos_pstrn=18;
-	pos_p = 24;
-	pos_dp = 25;
-	pos_twomu = 26;
-	pos_eqstrs = 27;
-        pos_F = nsdv;
-        nsdv += 9;
-        pos_Base = nsdv;
-        nsdv += 9;
-        pos_Ja=nsdv;
-        nsdv += 1;
-        pos_Ri = nsdv;
-        nsdv += 9; 
+         }
+         else{
+       
+               contraction42(LCC->C1, dstrn, dstrs);
+               addtens2(1., strs_n, 1., dstrs, strs); 
 
-	dam = init_damage(props,iddam);
-	if(dam){
-		pos_dam = nsdv;
-		nsdv += dam->get_nsdv();
-	}
+               mu=LCC->mu[1];
 
-        clength = init_clength(props,idclength);
+               contraction42(LCC->dAdmu0, DE, dstrn_dmu0); 
+               contraction42(LCC->dAdmu1, DE, dstrn_dmu1);    
+               addtens4(1., LCC->A, 0., I, dstrn_dDE);
+         }
 
-}
 
+         copyvect(strs, &(statev[pos_strs]),6);
+         dev(dstrn, dstrn_dev);
+         dev(strs, strs_dev);
 
-bool EVP_Material::eqstrs_exist() const
-{
-        return true;
-}
+         contraction42(Idev, strn_el, mat1);
+         contraction42(Idev, strs_n, strs_ndev);
 
+       //1.3 Compute second moment of equivalent strain and trial stress 
+       if(mtx){
+                 eqstrn2_order2(mtx, DE, LCC, &dstrn_eq2, dstrn_eq2dDE, &dstrn_eq2dmu0, &dstrn_eq2dmu1);
+               //  temp1 = sqrt(9.0*mu*mu*dstrn_eq2-6.0*mu*mu*contraction22(dstrn_dev,dstrn_dev)); 
+                 strs_eq2 = 9.0*mu*mu*dstrn_eq2+eqstrs_n;//1.5*contraction22(strs_dev,strs_ndev)+3.0*mu*contraction22(dstrn_dev,strs_n);
+// 1.5*contraction22(strs_dev,strs_dev)+(eqstrs_n+temp1)*(eqstrs_n+temp1);
 
-#ifdef NONLOCALGMSH
-int EVP_Material::get_pos_currentplasticstrainfornonlocal() const 
-{
-	return pos_p;
-}
-int EVP_Material::get_pos_effectiveplasticstrainfornonlocal() const
-{
-	if(dam)
-	{
-		return pos_dam;
-	}
-	return -1;
-}
 
-int EVP_Material::get_pos_damagefornonlocal() const
-{
-	if(dam) return pos_dam+2;
-        return -1;
-}
-double EVP_Material::getElasticEnergy (double* statev)
-{
-  double eE = 0.;
-  int i;
-  static double* strn = NULL;
-  static double* pstrn = NULL;
-  static double* strs = NULL;
-  //static double**CelD = NULL;
-  if(strn == NULL)
-  {
-    mallocvector(&strn,6);
-    mallocvector(&pstrn,6);
-    mallocvector(&strs,6);
-   // mallocmatrix(&CelD,6,6);
-  }
-  cleartens2(strn);
-  cleartens2(pstrn);
-  cleartens2(strs);
+ //+3.0*contraction22(strs_ndev,strs_ndev);
+       //           strs_eq2trial = 9.0*mu_el*mu_el*dstrn_eq2+eqstrs_n+6.0*mu_el*contraction22(dstrn_dev,strs_n);//+3.0*contraction22(strs_ndev,strs_ndev);
+       // 2.1 apply J2 plasticity for YF->trial, and f
+       	  dp = tiny_p;
+          p= statev_n[pos_p]+ dp;
+          j2hard(p, sy0, htype, hmod1, hmod2, hp0, hexp, &R, &dR,&ddR);
+
+          temp = sqrt(strs_eq2) - (sy0+R);   //check plasticity      
+
+          YF->trial= 0.0;
+          YF->f = 0.0;
+          if( (temp >0.0) || (mu < mu_el))  YF->trial=1.0;
+          
+          if(YF->trial > 0.0){
+               dp = sqrt(dstrn_eq2)*(1.0-mu/mu_el);
+
+               temp = 2.0*sqrt(strs_eq2);
+      // 2.2 the derivatives of strs_eqtrial and strs_eq
+      
+               dstrs_eqdmu0 = (9.0*mu*mu*dstrn_eq2dmu0+18.0*mu*dstrn_eq2)/temp;/*(6.0*mu*contraction22(strs_dev, dstrn_dmu0)+6.0*contraction22(strs_dev, dstrn)
+                               + (eqstrs_n+temp1)/temp1*(9.0*mu*mu*dstrn_eq2dmu0+18.0*mu*dstrn_eq2-
+                                 12.0*mu*mu*contraction22(dstrn_dev, dstrn_dmu0)-12.0*mu*contraction22(dstrn_dev, dstrn)))/temp;*/
+
+/*               dstrs_eqdmu1 = 9.0*mu*mu*dstrn_eq2dmu1/temp;/*(6.0*mu*contraction22(strs_dev, dstrn_dmu1)+
+                               + (eqstrs_n+temp1)/temp1*(9.0*mu*mu*dstrn_eq2dmu1-12.0*mu*mu*contraction22(dstrn_dev, dstrn_dmu1)))/temp;*/
+
+             /*  contraction42(dstrn_dDE, strs_dev, mat1); 
+               contraction42(dstrn_dDE, dstrn_dev, mat2); 
+ 
+               addtens2(9.0*mu*mu, dstrn_eq2dDE, -12.0*mu*mu, mat2, mat2); 
+               addtens2(6.0*mu/temp, mat1, (eqstrs_n+temp1)/temp1/temp, mat2, dstrs_eqdDE); */
+
+            
+
+/*                     addtens2(9.0*mu*mu/temp, dstrn_eq2dDE, 0.0, mat1, dstrs_eqdDE); 
+
+                 /*    dstrs_eqdmu1 = 6.0*mu*contraction22(strs_dev, dstrn_dmu1)/temp;
+                     dstrs_eqdmu0 = (6.0*mu*contraction22(strs_dev, dstrn_dmu0)+6.0*contraction22(strs_dev, dstrn))/temp;
 
-  copyvect(&(statev[pos_strn]), strn,6);
-  copyvect(&(statev[pos_pstrn]),pstrn,6);
-  copyvect(&statev[pos_strs], strs, 6);
-  //enegry due to damage has been removed
-  for (i =0; i< 6; i++) eE+=0.5*(strs[i]*(strn[i]-pstrn[i]));
+                     contraction42(Idev, strn_el, mat1);
+                     dstrs_eqtrialdmu0 = 12.0*mu_el*mu_el*contraction22(mat1, dstrn_dmu0)/temp_trial;
+                     dstrs_eqtrialdmu1 = 12.0*mu_el*mu_el*contraction22(mat1, dstrn_dmu1)/temp_trial;
 
-  return eE;
-}
+                     contraction42(dstrn_dDE, strs_dev, mat2); 
+                     addtens2(6.0*mu/temp, mat2, 0.0, mat1, dstrs_eqdDE); 
 
-double EVP_Material::getPlasticEnergy (double* statev) 
-{
-  double eP = 0.;
-  double p  = statev[get_pos_currentplasticstrainfornonlocal()];
-  eP = sy0*p;
-  switch(htype) {
-    //POWER LAW HARDENING
-    case H_POW:
-      if(fabs(hexp+1.)!=0) 
-         eP+=hmod1*pow(p,hexp+1.)/(hexp+1.);
-      break;
-    //EXPONENTIAL HARDENING
-    case H_EXP:
-      eP+=hmod1*p;
-      if(fabs(hexp)!=0) eP+=hmod1*(exp(-hexp*p)-exp(0))/(hexp);
-      break;
-    //SWIFT LAW
-    case H_SWIFT:
-      eP-=sy0*p;
-      if(fabs(hexp+1.)!=0 && fabs(hmod1)!=0.) eP+=sy0*pow(1.+hmod1*p,hexp+1.)/(hexp+1.)/hmod1;
-      break;
-    //LINEAR-EXPONENTIAL HARDENING
-    case H_LINEXP:
-      eP+=hmod1*p*p/2.+hmod2*p;
-      if(fabs(hexp)!=0) eP+=hmod2*(exp(-hexp*p)-exp(0))/(hexp);
-      break;
-    //POWER LAW HARDENING EXTRAPOLATED AFTER 16% DEFO TO MIMIC DIGIMAT TO ABAQUS
-    case H_POW_EXTRAPOL:
-      if(p<hp0)
-      {
-        if(fabs(hexp+1.)!=0)
-          eP+=hmod1*pow(p,hexp+1.)/(hexp+1.);
-      }
-      else if(p<10.*hp0)
-      {
-        if(fabs(hexp+1.)!=0)
-          eP+=hmod1*pow(hp0,hexp+1.)/(hexp+1.);
-        eP+=hmod1*pow(hp0,hexp+1.)*(p-hp0)+hmod2*(p-hp0)*(p-hp0)/2.;
-      }
-      else
-      {
-        if(fabs(hexp+1.)!=0)
-          eP+=hmod1*pow(hp0,hexp+1.)/(hexp+1.);
-        eP+=hmod1*pow(hp0,hexp+1.)*(10.*hp0-hp0)+hmod2*(10.*hp0-hp0)*(10.*hp0-hp0)/2.;
-        eP+=(hmod1*pow(hp0,hexp+1.)+hmod2*(10.*hp0-hp0))*(p-10.*hp0)+hmod2*(p-10.*hp0)*(p-10.*hp0)/2000.;
-      }
-      break;
-    default:
-      printf("Bad choice of hardening law in j2hard: %d\n",htype);
-      break;
-  }
-  return eP;
-}
-#endif
+                     contraction42(dstrn_dDE, mat1, mat2);  
+                     addtens2(12.0*mu_el*mu_el/temp_trial, mat2, 0.0, mat1, dstrs_eqtrialdDE); */
 
-//destructor
-EVP_Material::~EVP_Material(){
-	if(dam) delete dam;
-        if(clength) delete clength;
-}
+                     
+           // 2.3 the derivatives of dp
 
-//print
-void EVP_Material::print(){
+/*                     temp = sqrt(dstrn_eq2);
+                     dpdmu0 = dstrn_eq2dmu0/(2.0*temp)*(1.0-mu/mu_el)-temp/mu_el;
+                     dpdmu1 = dstrn_eq2dmu1/(2.0*temp)*(1.0-mu/mu_el);
 
-	printf("J2 elasto-ViscoPlasticity\n");
-	printf("Young modulus: %lf, Poisson ratio: %lf\n", E, nu);
-	printf("Intial yield stress: %lf, hardening law: %d, hardening coefficients: %lf\t%lf\t%lf\t%lf\t%lf\n", sy0, htype,hmod1,hmod2,hp0, hp0,hexp);
-	printf("ViscoPlastic function: %d, ViscoPlastic coefficients: %lf\t%lf\n", viscmodel, vmod, vexp);
-        if(dam){ dam->print();}
-        if(clength){clength->print();}
-}
+                     addtens2((1.0-mu/mu_el)/(2.0*temp), dstrn_eq2dDE, 0.0, mat1, dpdDE);  
+                   /*  dpdmu0 = (dstrs_eqtrialdmu0-dstrs_eqtrialdmu0)/(3.0*mu_el);
+                     dpdmu1 = (dstrs_eqtrialdmu1-dstrs_eqtrialdmu1)/(3.0*mu_el);
+                     addtens2(1.0/(3.0*mu_el), dstrs_eqtrialdDE, -1.0/(3.0*mu_el), dstrs_eqdDE, dpdDE);  */
 
-//constbox      //*****************New tenor added by wu ling: double* dpdE, double* strs_dDdp_bar ****************
-int EVP_Material::constbox(double* dstrn, double* strs_n,  double* strs, double* statev_n, double* statev, double** Cref, double*** dCref, double* tau, double** dtau, double** Calgo, double alpha, double* dpdE, double* strs_dDdp_bar,double *Sp_bar, double** c_g, double* dFd_d_bar, double* dstrs_dFd_bar, double *dFd_dE, double** c_gF, double* dpdFd, double* dFddp, int kinc, int kstep, double dt){
+/*             dp = max(dp,tiny_p);
+             p = statev_n[pos_p]+ dp;
+             j2hard(p, sy0, htype, hmod1, hmod2, hp0, hexp, &R, &dR,&ddR);
+             YF->f = sqrt(strs_eq2) - (sy0+R); //sqrt(strs_eq2trial) - (sy0+R + 3.0*mu_el*dp);       //check yielding function is satisfied or not.
+      
+     //  3.1 the derivatives of
 
-  return (1);
-}
-//******************************************************
-//costboxSecant
-//****************************************************
-int EVP_Material::constboxSecantMixte(double* dstrn, double* strs_n,  double* strs, double* statev_n, double*
-statev, double **Calgo, double** Csd, double*** dCsd, double** dCsdp_bar, double* dnu, double& dnudp_bar, double alpha, double* dpdE, double* dstrsdp_bar, double** c_g, int kinc, int kstep, double dt, bool forceZero, bool forceRes)
-{
-  return (1);
-}
-//end of costboxSecant
+	     YF->dfdmu[0] = dstrs_eqdmu0 - dR*dpdmu0;
 
-//****************************************************
-// consbox called by MTSecNtr 2rd order method
-//****************************************************
+	     YF->dfdmu[1] = dstrs_eqdmu1 - dR*dpdmu1;
+ 
+             addtens2(1.0, dstrs_eqdDE, -(dR), dpdDE, YF->dfdstrn);
+            }
 
-int EVP_Material::constbox_2ndNtr(double *DE, double* dstrn, double* strs_n,  double* strs, double* statev_n, double* statev,  ELcc* LCC, EPR* epresult, double alpha, double** c_g, int kinc, int kstep, double dt){
+         }
+  else{
+                  strs_eq2 = 1.5*contraction22(strs_dev, strs_dev);
+                  dstrn_eq2 = 2.0/3.0*contraction22(dstrn_dev, dstrn_dev);
+               //   strs_eq2trial = 6.0*mu_el*mu_el*contraction22(dstrn_dev, dstrn_dev)+ 1.5*contraction22(strs_ndev, strs_ndev)  
+               //                    +6.0*mu_el*contraction22(dstrn_dev,strs_n);
+ 
+        
+       // 2.1 apply J2 plasticity for YF->trial, and f
+       	  dp = tiny_p;
+          p= statev_n[pos_p]+ dp;
+          j2hard(p, sy0, htype, hmod1, hmod2, hp0, hexp, &R, &dR,&ddR);
+
+          temp = sqrt(strs_eq2) - (sy0+R);   //check plasticity
+        
+          YF->trial= 0.0;
+          YF->f = 0.0;
+          if( (temp >0.0) || (mu < mu_el))  YF->trial=1.0;
+          
+          if(YF->trial > 0.0){
+               dp = sqrt(dstrn_eq2)*(1.0-mu/mu_el);
 
+               temp = 2.0*sqrt(strs_eq2);
+     
+            //   temp_trial = 2.0*sqrt(strs_eq2trial);
+              
+                    //  dp = sqrt(strs_eq2)*(mu_el-mu)/(3.0*mu*mu_el); 
+                 //    dp = (sqrt(strs_eq2trial) - sqrt(strs_eq2))/(3.0*mu_el);
+
+               //   dstrs_eqdmu0 = (9.0*mu*mu*dstrn_eq2dmu0+6.0*mu*contraction22(dstrn_dmu0, strs_ndev))/temp; 
+               //   dstrs_eqdmu1 = (9.0*mu*mu*dstrn_eq2dmu1+18.0*mu*dstrn_eq2+
+                //               6.0*mu*contraction22(dstrn_dmu1, strs_ndev)+6.0*contraction22(dstrn, strs_ndev))/temp;  
+              //    dstrs_eqdmu0 = (9.0*mu*mu*dstrn_eq2dmu0)/temp; 
+             //     dstrs_eqdmu1 = (9.0*mu*mu*dstrn_eq2dmu1+18.0*mu*dstrn_eq2)/temp;
+
+                  /*   contraction42(Idev, dstrn_dmu0, mat1);
+                     dstrs_eqtrialdmu0 = 6.0*mu*contraction22(strs,mat1)/temp;
+
+                      contraction42(Idev, dstrn_dmu1, mat1);
+                      dev(strs, mat2);
+                      dstrs_eqtrialdmu1 = 6.0*(contraction22(mat2, dstrn)+contraction22(mat2, statev_n)-contraction22(mat2, &statev_n[pos_pstrn])+mu*contraction22(strs,mat1))/temp;
+
+                     dev(strs, mat1);
+                     contraction42(dstrn_dDE,mat1, mat2);
+                     addtens2(6.0*mu/temp, mat2, 0.0, mat1, dstrs_eqtrialdDE);*/
+
+
+/*                    dstrs_eqdmu0 = 6.0*mu*contraction22(strs_dev, dstrn_dmu0)/temp;
+                     dstrs_eqdmu1 = (6.0*mu*contraction22(strs_dev, dstrn_dmu1)+6.0*contraction22(strs_dev, dstrn))/temp;
+
+                     
+                  //   dstrs_eqtrialdmu0 = (12.0*mu_el*mu_el*contraction22(dstrn_dev, dstrn_dmu0)+6.0*mu_el*contraction22(dstrn_dmu0,strs_ndev))/temp_trial;
+                  //   dstrs_eqtrialdmu1 = (12.0*mu_el*mu_el*contraction22(dstrn_dev, dstrn_dmu1)+6.0*mu_el*contraction22(dstrn_dmu1,strs_ndev))/temp_trial;
+
+                     contraction42(dstrn_dDE, strs_dev, mat2); 
+                     addtens2(6.0*mu/temp, mat2, 0.0, mat1, dstrs_eqdDE); 
+
+                //     contraction42(dstrn_dDE, dstrn_dev, mat2);  
+                 //    addtens2(12.0*mu_el*mu_el/temp_trial, mat2, 0.0, mat1, dstrs_eqtrialdDE); 
+
+           // 2.3 the derivatives of dp
+                   dpdmu0 = 2.0/3.0*contraction22(dstrn_dev,dstrn_dmu0)/sqrt(dstrn_eq2)*(1.0-mu/mu_el);
+                   dpdmu1 = 2.0/3.0*contraction22(dstrn_dev,dstrn_dmu1)/sqrt(dstrn_eq2)*(1.0-mu/mu_el);
+                   dpdmu1 = dpdmu1 - sqrt(dstrn_eq2)/mu_el;
+                   dp = sqrt(dstrn_eq2)*(1.0-mu/mu_el);
+
+                   contraction42(dstrn_dDE,dstrn_dev, mat1);
+                   addtens2(2.0/3.0*(1.0-mu/mu_el)/sqrt(dstrn_eq2), mat1, 0.0, mat1, dpdDE);
+                  /*   dpdmu0 = (dstrs_eqtrialdmu0-dstrs_eqtrialdmu0)/(3.0*mu_el);
+                     dpdmu1 = (dstrs_eqtrialdmu1-dstrs_eqtrialdmu1)/(3.0*mu_el);
+                     addtens2(1.0/(3.0*mu_el), dstrs_eqtrialdDE, -1.0/(3.0*mu_el), dstrs_eqdDE, dpdDE);  
+                     dpdmu0 = (dstrs_eqdmu0/mu - sqrt(strs_eq2)/mu/mu-dstrs_eqdmu0/mu_el)/3.0;
+                     dpdmu1 = dstrs_eqdmu1*(mu_el-mu)/(3.0*mu_el*mu);
+                     addtens2((mu_el-mu)/(3.0*mu_el*mu), dstrs_eqdDE, 0.0, mat1, dpdDE);  */
+/*             dp = max(dp,tiny_p);
+             p = statev_n[pos_p]+ dp;
+             j2hard(p, sy0, htype, hmod1, hmod2, hp0, hexp, &R, &dR,&ddR);
+             YF->f = sqrt(strs_eq2) - (sy0+R); //sqrt(strs_eq2trial) - (sy0+R + 3.0*mu_el*dp);       //check yielding function is satisfied or not.
+      
+     //  3.1 the derivatives of
 
-  return (1);            
-}
-// end of constbox_2ndNtr()
+	     YF->dfdmu[0] = dstrs_eqdmu0 - dR*dpdmu0;
 
+	     YF->dfdmu[1] = dstrs_eqdmu1 - dR*dpdmu1;
+ 
+             addtens2(1.0, dstrs_eqdDE, -(dR), dpdDE, YF->dfdstrn);
 
-//****************************************************
-//    For large deformation
-// consbox called by MTSecF 1rd order method
-//****************************************************
 
-int EVP_Material::constboxLargD(double* dstrn, double* strs_n,  double* strs, double* statev_n, double* statev, double **Calgo, double** Csd, double*** dCsd, double** dCsdp_bar, 
-double* dnu, double &dnudp_bar, double alpha, double* dpdE, double* dstrsdp_bar, double** c_g, int kinc, int kstep, double dt){
+              }
+             }*/
+                  
 
-  return (1);              
-}
-// end of constbox_LargD()
+      // 3.2 as damage is not applied: 
+             YF->dpdmu[0] = 0.0;    
+             YF->dpdmu[1] = 0.0;  	
+             cleartens2(YF->dpdstrn); 
+             YF->dfdp_bar = 0.0; 
+             YF->dpdp_bar = 0.0;
 
-//****************************************************
-// consbox called by 2rd order method
-//****************************************************
+         
+       // 4. update state variable
 
-int EVP_Material::constbox_2order(int mtx, double *DE, double* dstrn, double* strs, double* statev_n, double* statev,  double **Calgo, Lcc* LCC, YieldF* YF, double** c_g, int kinc, int kstep, double dt){
 
- return (1);
+        contraction42(Idev, dstrs, mat1);
+        addtens2(0.5/sqrt(dstrn_eq2)/mu, mat1, 0.0, mat1, Ntr);
+
+        copyvect(&(statev_n[pos_pstrn]), pstrn, 6);
+        addtens2(dp, Ntr, 1.0, pstrn, pstrn);
+	copyvect(pstrn, &(statev[pos_pstrn]),6);
+	statev[pos_p]=p;
+	statev[pos_dp]=dp;
+
+        statev[pos_eqstrs] = strs_eq2; 
+                 
+ 
+ 
+#ifdef NONLOCALGMSH
+        if(dam && localDamage)
+        {
+          statev[pos_dam]= statev[pos_p];
+  	  statev[pos_dam+1]= statev[pos_dp];
+        }
+#else
+// add by wu ling try nonlocal mehod without finite element cacilation
+        if(dam)
+        {
+          statev[pos_dam]= statev[pos_p];
+  	  statev[pos_dam+1]= statev[pos_dp];
+        }
+#endif
+
+        clength->creat_cg(statev_n, pos_p, c_g);        //*********add by wu ling 
+        return error;
 }
 
 //end of consbox_2order
@@ -1416,7 +8847,7 @@ void EVP_Material::unload_step(double* dstrn,double* strs_n, double* statev_n, i
 
 //********************************************************************************************
 // COMPOSITE - VOIGT  
-//PROPS: MODEL, IDDAM, Nph, IDMAT phase 1, IDTOP phase 1, ... , 
+//PROPS: MODEL, IDDAM, NGrain, IDMAT phase 1, IDTOP phase 1, ... ,
 //	 	...	IDMAT phase N, IDTOP phase N
 //  (material properties of each phase), (volume fraction of each phase)
 //STATEV: strn, strs, dstrn, (statev of each phase)   
@@ -1426,22 +8857,156 @@ VT_Material::VT_Material(double* props, int idmat):Material(props, idmat){
 
 	int i,idmat_i,idtop_i,k;
 	int iddam, idclength;
+	std::vector<double> euler_lam;
 
 	nsdv=18;
 	iddam = (int) props[idmat+1];
         idclength = (int)props[idmat+2];
-	Nph = (int) props[idmat+3];
-	mat = (Material**) malloc(Nph*sizeof(Material*));	
-	mallocvector(&vf,Nph);
-        
+	NGrain = (int) props[idmat+3];
+	mat = (Material**) malloc(NGrain*sizeof(Material*));
+	mallocvector(&vf,NGrain);
+
 	k=idmat+4;
 
-	for(i=0;i<Nph;i++){
+#ifdef NONLOCALGMSH
+	euler_vt_lam.clear();
+	pos_strn_vt_m0.clear();
+	pos_strn_vt_mt.clear();
+	pos_strn_vt_lam.clear();
+	pos_strs_vt_m0.clear();
+	pos_strs_vt_mt.clear();
+	pos_strs_vt_lam.clear();
+	pos_dam_vt_m0.clear();
+	pos_strn_vt_lam_m0.clear();
+	pos_strn_vt_lam_mt.clear();
+	pos_strs_vt_lam_m0.clear();
+	pos_strs_vt_lam_mt.clear();
+	pos_dam_vt_lam_m0.clear();
+	pos_strn_vt_mt_mtx.clear();
+	pos_strn_vt_mt_inc.clear();
+	pos_strn_vt_lam_mt_mtx.clear();
+	pos_strn_vt_lam_mt_inc.clear();
+	pos_strs_vt_mt_mtx.clear();
+	pos_strs_vt_mt_inc.clear();
+	pos_strs_vt_lam_mt_mtx.clear();
+	pos_strs_vt_lam_mt_inc.clear();
+	pos_dam_vt_mt_mtx.clear();
+	pos_dam_vt_mt_inc.clear();
+	pos_dam_vt_lam_mt_mtx.clear();
+	pos_dam_vt_lam_mt_inc.clear();
+#endif	
+
+
+	for(i=0;i<NGrain;i++){
 		idmat_i = (int)props[k++];
-		idtop_i = (int)props[k++];
-		
-		mat[i] = init_material(props,idmat_i);
-		vf[i] = props[idtop_i];
+                vf[i] = props[k++];
+		mat[i] = init_material(&(props[idmat_i]),0);      // modified by Ling Wu in June 2020 to simplify the input file (e.g. proper.i01)		
+
+#ifdef NONLOCALGMSH
+                // for each VT grain
+                switch(mat[i]->get_constmodel()){
+                	case EP:  // for pure matrix grain
+                		// strain
+                		pos_strn_vt_m0.emplace_back(nsdv + mat[i]->get_pos_strn());
+                		// stress
+                		pos_strs_vt_m0.emplace_back(nsdv + mat[i]->get_pos_strs());
+                		// damage
+                		if(mat[i]->get_pos_damagefornonlocal() > -1){
+                			pos_dam_vt_m0.emplace_back(nsdv + mat[i]->get_pos_damagefornonlocal());
+                		}
+                		else{
+                			pos_dam_vt_m0.emplace_back(-1);
+                		}
+                		break;
+                		
+                	case MTSecF:  // for MT(Mtx+Inc) grain
+                		// strain
+                		pos_strn_vt_mt.emplace_back(nsdv + mat[i]->get_pos_strn());
+                		// stress
+                		pos_strs_vt_mt.emplace_back(nsdv + mat[i]->get_pos_strs());
+                		// for each material phase
+                		// strain
+                		pos_strn_vt_mt_mtx.emplace_back(nsdv + mat[i]->get_pos_mtx_strain());
+                		pos_strn_vt_mt_inc.emplace_back(nsdv + mat[i]->get_pos_inc_strain());
+                		// stress
+                		pos_strs_vt_mt_mtx.emplace_back(nsdv + mat[i]->get_pos_mtx_stress());
+                		pos_strs_vt_mt_inc.emplace_back(nsdv + mat[i]->get_pos_inc_stress());
+                		// damage
+                		if(mat[i]->get_pos_mtx_Dam() > -1){
+                			pos_dam_vt_mt_mtx.emplace_back(nsdv + mat[i]->get_pos_mtx_Dam());
+                		}
+                		else{
+                			pos_dam_vt_mt_mtx.emplace_back(-1);
+                		}
+                		if(mat[i]->get_pos_inc_Dam() > -1){
+                			pos_dam_vt_mt_inc.emplace_back(nsdv + mat[i]->get_pos_inc_Dam());
+                		}
+                		else{
+                			pos_dam_vt_mt_inc.emplace_back(-1);
+                		}               		
+                		break;
+                		
+                	case LAM_2PLY:  // for laminate
+                		// laminate euler angles
+                		euler_lam = mat[i]->getEuler(euler_lam);
+                		euler_vt_lam.insert(euler_vt_lam.end(), euler_lam.begin(), euler_lam.end());
+                		// strain
+                		pos_strn_vt_lam.emplace_back(nsdv + mat[i]->get_pos_strn());
+                		// stress
+                		pos_strs_vt_lam.emplace_back(nsdv + mat[i]->get_pos_strs());               		
+                		// for each laminate ply
+                		for(int iLam=0;iLam<mat[i]->getNPatch();iLam++){
+                			switch(mat[i]->get_mat_constmodel(iLam)){
+                				case EP:  // pure matrix
+                					// for EP laminate ply
+                					// strain
+                					pos_strn_vt_lam_m0.emplace_back(nsdv + mat[i]->get_pos_mat_strain(iLam));
+                					// stress
+                					pos_strs_vt_lam_m0.emplace_back(nsdv + mat[i]->get_pos_mat_stress(iLam));
+                					// damage
+                					if(mat[i]->get_pos_mat_Dam(iLam) > -1){
+                						pos_dam_vt_lam_m0.emplace_back(nsdv + mat[i]->get_pos_mat_Dam(iLam));
+                					}
+                					else{
+                						pos_dam_vt_lam_m0.emplace_back(-1);
+                					}
+                					break;
+                			
+                				case MTSecF:  // MFH Fisrst order secant
+                					// for MT laminate ply
+                					// strain
+                					pos_strn_vt_lam_mt.emplace_back(nsdv + mat[i]->get_pos_mat_strain(iLam));
+                					// stress
+                					pos_strs_vt_lam_mt.emplace_back(nsdv + mat[i]->get_pos_mat_stress(iLam));
+                					// for each material phase
+                					// strain
+                					pos_strn_vt_lam_mt_mtx.emplace_back(nsdv + mat[i]->get_pos_mat_mtx_strain(iLam));
+                					pos_strn_vt_lam_mt_inc.emplace_back(nsdv + mat[i]->get_pos_mat_inc_strain(iLam));
+                					// stress
+                					pos_strs_vt_lam_mt_mtx.emplace_back(nsdv + mat[i]->get_pos_mat_mtx_stress(iLam));
+                					pos_strs_vt_lam_mt_inc.emplace_back(nsdv + mat[i]->get_pos_mat_inc_stress(iLam));
+                					// damage
+                					if(mat[i]->get_pos_mat_mtx_Dam(iLam) > -1){
+                						pos_dam_vt_lam_mt_mtx.emplace_back(nsdv + mat[i]->get_pos_mat_mtx_Dam(iLam));
+                					}
+                					else{
+                						pos_dam_vt_lam_mt_mtx.emplace_back(-1);
+                					}
+                					if(mat[i]->get_pos_mat_inc_Dam(iLam) > -1){
+                						pos_dam_vt_lam_mt_inc.emplace_back(nsdv + mat[i]->get_pos_mat_inc_Dam(iLam));
+                					}
+                					else{
+                						pos_dam_vt_lam_mt_inc.emplace_back(-1);
+                					}
+                					break;
+                				
+                			}
+                		}                		
+                		break;
+                		
+                }
+#endif
+
 		nsdv += mat[i]->get_nsdv();
 	}
 
@@ -1458,11 +9023,14 @@ VT_Material::VT_Material(double* props, int idmat):Material(props, idmat){
 		nsdv += dam->get_nsdv();
 	}
 
-        
         clength = init_clength(props,idclength);
 
- 
+#ifdef NONLOCALGMSH
+	if(idclength==0) this->setLocalDamage();
+#endif
 }
+
+
 #ifdef NONLOCALGMSH
 int VT_Material::get_pos_currentplasticstrainfornonlocal() const
 {
@@ -1516,13 +9084,14 @@ double VT_Material::getPlasticEnergy (double* statev)
 VT_Material::~VT_Material(){
 
 	int i;
-	for (i=0;i<Nph;i++){
+	for (i=0;i<NGrain;i++){
 		if(mat[i]){
 			delete mat[i];
 		}
 	}
 	free(mat);
 	free(vf);
+	
 	if(dam) delete(dam);
         if(clength) delete clength;
 	
@@ -1535,10 +9104,10 @@ void VT_Material::print(){
 	printf("Voigt\n");
 	if(dam){ dam->print();}
 
-	printf("Number of phases: %d\n", Nph);
+	printf("Number of grains: %d\n", NGrain);
 	
-	for(i=0;i<Nph;i++){
-		printf("phase %d, volume fraction: %lf\n",i+1,vf[i]);
+	for(i=0;i<NGrain;i++){
+		printf("grain %d, volume fraction: %lf\n",i+1,vf[i]);
 		mat[i]->print();
 	}
 }
@@ -1546,20 +9115,117 @@ void VT_Material::print(){
 //constbox
 int VT_Material::constbox(double* dstrn, double* strs_n,  double* strs, double* statev_n, double* statev, double** Cref, double*** dCref, double* tau, double** dtau, double** Calgo, double alpha, double* dpdE, double* strs_dDdp_bar, double *Sp_bar, double** c_g, double* dFd_d_bar, double* dstrs_dFd_bar, double *dFd_dE, double** c_gF, double* dpdFd, double* dFddp, int kinc, int kstep, double dt){
 
-  return (1);
+	int i,j,idsdv,error,errortmp;
+	int pos_strs_i, pos_dstrn_i;
+	static double** Cref_i=NULL;
+        static double **Calgo_i=NULL;
+	static double*** dCref_i=NULL;
+	static double* tau_i=NULL;
+	static double** dtau_i=NULL;
+        static double** cg_temp=NULL; 
+
+	int iso_loc;
+	double alpha1 = 1.0; //mid point integration law in each phase
+        error=0;
+        if(Cref_i==NULL)
+        {  
+           mallocmatrix(&Cref_i,6,6);
+           mallocmatrix(&Calgo_i,6,6);
+           malloctens3(&dCref_i,6,6,6);
+           mallocvector(&tau_i,6);
+           mallocmatrix(&dtau_i,6,6);
+           mallocmatrix(&cg_temp,3,3);
+        }
+
+	//reset stress and tangent operators to zero
+	cleartens2(strs);
+	cleartens4(Calgo);
+	cleartens4(Cref);
+	cleartens6(dCref);
+	cleartens2(tau);
+	cleartens4(dtau);
+        for(i=1;i<3;i++)
+        {
+          for(j=1;j<3;j++)
+          {
+            cg_temp[i][j]=0.;
+          }
+        }
+
+	idsdv=18; //position in statev where the statev of the first phase start
+
+/*#ifdef NONLOCALGMSH
+	if (kstep==1) this->populateMaxD(statev);  // do once for createIPVariable
+#endif*/
+
+	for(i=0;i<NGrain;i++){
+		//get positions of strs and dstrn in statev for each phase
+		pos_strs_i = mat[i]->get_pos_strs();
+		pos_dstrn_i = mat[i]->get_pos_dstrn();
+		
+		//call constitutive box of each phase
+		errortmp=mat[i]->constbox(dstrn, &(statev_n[idsdv+pos_strs_i]), &(statev[idsdv+pos_strs_i]), &(statev_n[idsdv]), &(statev[idsdv]), Cref_i, dCref_i, tau_i, dtau_i, Calgo_i, alpha1, dpdE,  strs_dDdp_bar,Sp_bar, cg_temp, dFd_d_bar, dstrs_dFd_bar, dFd_dE, c_gF,  dpdFd,  dFddp, kinc, kstep, dt );
+                if(errortmp!=0) error=1;
+		//macro stress, tangent operators and polarization tensor computed as phase averages
+		addtens2(1.,strs, vf[i], &(statev[idsdv+pos_strs_i]), strs);   
+		addtens4(1.,Calgo, vf[i], Calgo_i, Calgo);
+		addtens4(1.,Cref, vf[i], Cref_i, Cref);
+		addtens6(1.,dCref,vf[i], dCref_i, dCref);
+
+		addtens2(1.,tau,vf[i],tau_i,tau);
+		addtens4(1.,dtau,vf[i],dtau_i,dtau);
+
+		idsdv += mat[i]->get_nsdv();	//position of the statev of the next phase
+	
+	}
+
+	addtens2(1., statev_n, 1., dstrn, statev); 
+	copyvect(strs, &(statev[6]),6);
+	copyvect(dstrn, &(statev[12]),6);
+
+	//TO DO: call damage box of material if iddam!=0
+
+        pos_p=0;
+        clength->creat_cg(statev_n, pos_p, c_g);       //*********add by wu ling 
+	
+	//freematrix(Cref_i,6);
+	//freematrix(Calgo_i,6);
+	//freetens3(dCref_i,6,6);
+	//free(tau_i);
+	//freematrix(dtau_i,6);
+        
+        //freematrix(cg_temp,3);
+        return error;
 }
 
 //reference operator from statev
 void VT_Material::get_refOp(double* statev, double** C, int kinc, int kstep){
 
-	printf("get_refOp not implemented for Voigt material\n");
+    int i;
+    int idsdv=18;
+    static double** Cref_i=NULL;
+    if(Cref_i==NULL) mallocmatrix(&Cref_i,6,6);
+
+    cleartens4(C);
+    for(i=0;i<NGrain;i++){
+        mat[i]->get_refOp(&(statev[idsdv]), Cref_i, kinc, kstep);
+        addtens4(1.,C, vf[i], Cref_i, C);
+        idsdv += mat[i]->get_nsdv();
+    }
 
 }
 
 void VT_Material::get_elOp(double** Cel){
 
-	printf("get_elOp not implemented for Voigt material\n");
+    int i;
+    static double** Cel_i=NULL;
+    if(Cel_i==NULL) mallocmatrix(&Cel_i,6,6);
 
+    cleartens4(Cel);
+    for(i=0;i<NGrain;i++){
+        mat[i]->get_elOp(Cel_i);
+        addtens4(1.,Cel, vf[i], Cel_i, Cel);
+    }
 }
 
 void VT_Material::unload_step(double* dstrn, double* strs_n, double* statev_n, int kinc, int kstep){
@@ -1569,16 +9235,20 @@ void VT_Material::unload_step(double* dstrn, double* strs_n, double* statev_n, i
 
 void VT_Material::get_elOD(double* statev, double** Cel)
 {
-     get_elOp(Cel);
-     if(dam)
-     {
-       double damage = statev[get_pos_dam()];
-       for(int i=0; i < 6; i++)
-         for(int j=0; j < 6; j++)
-           Cel[i][j]*=1.-damage;
+    int i;
+    int idsdv=18;
+    static double** Cref_i=NULL;
+    if(Cref_i==NULL) mallocmatrix(&Cref_i,6,6);
+
+    cleartens4(Cel);
+    for(i=0;i<NGrain;i++){
+        mat[i]->get_elOD(&(statev[idsdv]), Cref_i);
+        addtens4(1.,Cel, vf[i], Cref_i, Cel);
+        idsdv += mat[i]->get_nsdv();
     }
 }
 
+
 //********************************************************************************************************************
 //  Laminate of two plies  
 //PROPS: MODEL, IDDAM,  ... , 
@@ -1589,8 +9259,133 @@ void VT_Material::get_elOD(double* statev, double** Cel)
 //constructor
 LAM2Ply_Material::LAM2Ply_Material(double* props, int idmat):Material(props, idmat){
 
- 
+	int i,idmat_i,idtop_i,k,l;
+	int iddam, idclength, ideuler;
+
+	mallocvector(&euler,3);
+
+	nsdv=39;
+	iddam = (int) props[idmat+1];
+        idclength = (int)props[idmat+2];
+        ideuler = (int)props[idmat+3];
+
+        l=ideuler;	
+	euler[0] = props[l++];
+	euler[1] = props[l++];
+	euler[2] = props[l++];
+
+	mat = (Material**) malloc(NPly*sizeof(Material*));
+	mallocvector(&vf,NPly);
+        
+	k=idmat+4;
+        idsdv_A = nsdv;
+        
+#ifdef NONLOCALGMSH
+	pos_strn_lam_m0.clear();
+	pos_strn_lam_vt.clear();
+	pos_strs_lam_m0.clear();
+	pos_strs_lam_vt.clear();
+	pos_dam_lam_m0.clear();
+	pos_strn_lam_vt_mt.clear();
+	pos_strs_lam_vt_mt.clear();
+	pos_strn_lam_vt_mt_mtx.clear();
+	pos_strn_lam_vt_mt_inc.clear();
+	pos_strs_lam_vt_mt_mtx.clear();
+	pos_strs_lam_vt_mt_inc.clear();
+	pos_dam_lam_vt_mt_mtx.clear();
+	pos_dam_lam_vt_mt_inc.clear();
+#endif
+	
+
+	for(i=0;i<NPly;i++){
+		idmat_i = (int)props[k++];
+                vf[i] = props[k++];
+		mat[i] = init_material(&(props[idmat_i]),0);     // modified by Ling Wu in June 2020 to simplify the input file (e.g. proper.i01)
+		
+#ifdef NONLOCALGMSH
+		// for each laminate ply
+                switch(mat[i]->get_constmodel()){
+			case EP:  // for pure matrix ply
+				// strain
+				pos_strn_lam_m0.emplace_back(nsdv + mat[i]->get_pos_strn());
+				// stress
+				pos_strs_lam_m0.emplace_back(nsdv + mat[i]->get_pos_strs());
+				// damage
+                		if(mat[i]->get_pos_damagefornonlocal() > -1){
+                		    pos_dam_lam_m0.emplace_back(nsdv + mat[i]->get_pos_damagefornonlocal());
+                		}
+                		else{
+                		    pos_dam_lam_m0.emplace_back(-1);
+                		}
+				break;
+                			
+                	case VT:  // for VT ply
+                		// strain
+                		pos_strn_lam_vt.emplace_back(nsdv + mat[i]->get_pos_strn());
+                		// stress
+                		pos_strs_lam_vt.emplace_back(nsdv + mat[i]->get_pos_strs());
+                		// for each MT grain of VT ply
+                		for(int iVT=0;iVT<mat[i]->getNPatch();iVT++){
+                			switch(mat[i]->get_mat_constmodel(iVT)){
+                				case MTSecF:  // MFH Fisrst order secant
+                					// strain
+                					pos_strn_lam_vt_mt.emplace_back(nsdv + mat[i]->get_pos_mat_strain(iVT));
+                					// stress
+                					pos_strs_lam_vt_mt.emplace_back(nsdv + mat[i]->get_pos_mat_stress(iVT));
+                					// for each material phase
+                					// strain
+                					pos_strn_lam_vt_mt_mtx.emplace_back(nsdv + mat[i]->get_pos_mat_mtx_strain(iVT));
+                					pos_strn_lam_vt_mt_inc.emplace_back(nsdv + mat[i]->get_pos_mat_inc_strain(iVT));
+                					// stress
+                					pos_strs_lam_vt_mt_mtx.emplace_back(nsdv + mat[i]->get_pos_mat_mtx_stress(iVT));
+                					pos_strs_lam_vt_mt_inc.emplace_back(nsdv + mat[i]->get_pos_mat_inc_stress(iVT));
+                					// damage
+                					if(mat[i]->get_pos_mat_mtx_Dam(iVT) > -1){
+                						pos_dam_lam_vt_mt_mtx.emplace_back(nsdv + mat[i]->get_pos_mat_mtx_Dam(iVT));
+                					}
+                					else{
+                						pos_dam_lam_vt_mt_mtx.emplace_back(-1);
+                					}
+							if(mat[i]->get_pos_mat_inc_Dam(iVT) > -1){
+                						pos_dam_lam_vt_mt_inc.emplace_back(nsdv + mat[i]->get_pos_mat_inc_Dam(iVT));
+                					}
+                					else{
+                						pos_dam_lam_vt_mt_inc.emplace_back(-1);
+                					}
+                					break;
+                					
+                			}
+                		}	
+				break;
+				
+		}
+#endif
+
+		nsdv += mat[i]->get_nsdv();
+	}
+        idsdv_B = idsdv_A + mat[0]->get_nsdv();
+	pos_strn=0;
+	pos_strs=6;
+	pos_dstrn=12;
+        pos_C=18;
+
+        pos_p = 0; // defined by Ling Wu for the input of clength->creat_cg, which is not implemented for this material
+
+
+	dam = init_damage(props,iddam);
+	if(dam){
+		pos_dam=nsdv;
+		nsdv += dam->get_nsdv();
+	}
+        
+        clength = init_clength(props,idclength);
+
+#ifdef NONLOCALGMSH
+	if(idclength==0) this->setLocalDamage();
+#endif
 }
+
+
 #ifdef NONLOCALGMSH
 int LAM2Ply_Material::get_pos_currentplasticstrainfornonlocal() const
 {
@@ -1644,13 +9439,14 @@ double LAM2Ply_Material::getPlasticEnergy (double* statev)
 LAM2Ply_Material::~LAM2Ply_Material(){
 
 	int i;
-	for (i=0;i<Nph;i++){
+	for (i=0;i<NPly;i++){
 		if(mat[i]){
 			delete mat[i];
 		}
 	}
 	free(mat);
 	free(vf);
+	
 	if(dam) delete(dam);
         if(clength) delete clength;
 	
@@ -1663,10 +9459,10 @@ void LAM2Ply_Material::print(){
 	printf("LAM2Ply\n");
 	if(dam){ dam->print();}
 
-	printf("Number of phases: %d\n", Nph);
+	printf("Number of plies: %d\n", NPly);
 	
-	for(i=0;i<Nph;i++){
-		printf("phase %d, volume fraction: %lf\n",i+1,vf[i]);
+	for(i=0;i<NPly;i++){
+		printf("ply %d, volume fraction: %lf\n",i+1,vf[i]);
 		mat[i]->print();
 	}
 }
@@ -1674,20 +9470,167 @@ void LAM2Ply_Material::print(){
 //constbox
 int LAM2Ply_Material::constbox(double* dstrn, double* strs_n,  double* strs, double* statev_n, double* statev, double** Cref, double*** dCref, double* tau, double** dtau, double** Calgo, double alpha, double* dpdE, double* strs_dDdp_bar, double *Sp_bar, double** c_g, double* dFd_d_bar, double* dstrs_dFd_bar, double *dFd_dE, double** c_gF, double* dpdFd, double* dFddp, int kinc, int kstep, double dt){
 
+	int i,j,error,errortmp;
+	int k;
+        double VA = vf[0];
+	double** Cel;
+        double **Calgo_i;
+	double*** dCref_i;
+	double* tau_i;
+	double** dtau_i;
+        static double** cg_temp=NULL; 
+
+	int iso_loc;
+	double alpha1 = 1; //mid point integration law in each phase
+        error=0;
+     
+        mallocmatrix(&Cel,6,6);
+        mallocmatrix(&Calgo_i,6,6);
+        malloctens3(&dCref_i,6,6,6);
+        mallocvector(&tau_i,6);
+        mallocmatrix(&dtau_i,6,6);
+        if(cg_temp==NULL)
+        {
+           mallocmatrix(&cg_temp,3,3);
+        }
+
+	//reset stress and tangent operators to zero
+	cleartens2(strs);
+	cleartens4(Calgo);
+	cleartens4(Cref);
+	cleartens6(dCref);
+	cleartens2(tau);
+	cleartens4(dtau);
+        for(i=1;i<3;i++)
+        {
+          for(j=1;j<3;j++)
+          {
+            cg_temp[i][j]=0.;
+          }
+        }
+
+/*#ifdef NONLOCALGMSH
+	if (kstep==1) this->populateMaxD(statev);  // do once for createIPVariable
+#endif*/
+
+
+        errortmp = Laminate_2ply(dstrn, mat[0], mat[1], VA, statev_n, statev, nsdv, idsdv_A, idsdv_B, euler, Cref, dCref, Calgo, kinc, kstep, dt);
+        if(errortmp!=0) error=1;
+
+	copyvect(dstrn, &(statev[12]),6);
+        addtens2(1., statev_n, 1., dstrn, statev); 	
+        copyvect(&(statev[pos_strs]), strs,6);
+
+	k=pos_C;
+	for(i=0;i<6;i++){
+		for(j=i;j<6;j++){
+			statev[k++] = Cref[i][j];
+		}
+	}
+
+	//TO DO: call damage box of material if iddam!=0
 
+        pos_p=0;
+        clength->creat_cg(statev_n, pos_p, c_g);       //*********add by wu ling
+
+	freematrix(Cel,6);
+        freematrix(Calgo_i,6);
+	freetens3(dCref_i,6,6);
+	free(tau_i);
+	freematrix(dtau_i,6);  
 	
-        return 1;
+        return error;
 }
 
 //reference operator from statev
 void LAM2Ply_Material::get_refOp(double* statev, double** C, int kinc, int kstep){
 
+        int error=0;
+        double VA = vf[0];
+        static bool initialized=false;
+	static double** CA=NULL;
+	static double** CB=NULL;
+	static double** PA=NULL;
+	static double** R66=NULL;		//rotation matrix
+	static double** C_loc=NULL;
+	static double** mat1=NULL;
+	static double** mat2=NULL;
+	
+        if(!initialized)
+        {
+          initialized=true;
+ 	  //memory allocation
+	  mallocmatrix(&CA,6,6);
+	  mallocmatrix(&CB,6,6);
+	  mallocmatrix(&PA,6,6);
+	  mallocmatrix(&R66,6,6);
+	  mallocmatrix(&C_loc,6,6);
+	  mallocmatrix(&mat1,6,6);
+	  mallocmatrix(&mat2,6,6);
+        }
+	cleartens4(R66);
+	cleartens4(CA);
+	cleartens4(CB);
+	cleartens4(PA);
+        cleartens4(C_loc);
+        cleartens4(mat1);
+        cleartens4(mat2);
+
+        eul_mat(euler,R66);
+        transpose(R66,R66,6,6);
+        mat[0]->get_refOp(&(statev[idsdv_A]), CA, kinc, kstep);
+        mat[1]->get_refOp(&(statev[idsdv_B]), CB, kinc, kstep);
+        error = TensPA(VA, CA, CB, PA);
 
+        addtens4(1.0, CA, -1.0, CB, mat1);             
+        contraction44(mat1, PA, mat2); 
+        addtens4(VA, mat2, 1.0, CB, C_loc);  
+	rot4(R66,C_loc,C); 
 
 }
 
-void LAM2Ply_Material::get_elOp(double** Cel){	
+void LAM2Ply_Material::get_elOp(double** Cel){	
+        int error=0;
+        double VA = vf[0];
+        static bool initialized=false;
+	static double** CA=NULL;
+	static double** CB=NULL;
+	static double** PA=NULL;
+	static double** R66=NULL;		//rotation matrix
+	static double** C_loc=NULL;
+	static double** mat1=NULL;
+	static double** mat2=NULL;
+	
+        if(!initialized)
+        {
+          initialized=true;
+ 	  //memory allocation
+	  mallocmatrix(&CA,6,6);
+	  mallocmatrix(&CB,6,6);
+	  mallocmatrix(&PA,6,6);
+	  mallocmatrix(&R66,6,6);
+	  mallocmatrix(&C_loc,6,6);
+	  mallocmatrix(&mat1,6,6);
+	  mallocmatrix(&mat2,6,6);
+        }
+	cleartens4(R66);
+	cleartens4(CA);
+	cleartens4(CB);
+	cleartens4(PA);
+        cleartens4(C_loc);
+        cleartens4(mat1);
+        cleartens4(mat2);
+
+        eul_mat(euler,R66);
+        transpose(R66,R66,6,6);
+        mat[0]->get_elOp(CA);	
+	mat[1]->get_elOp(CB);
+        error=TensPA(VA, CA, CB, PA);
 
+        addtens4(1.0, CA, -1.0, CB, mat1);             
+        contraction44(mat1, PA, mat2); 
+        addtens4(VA, mat2, 1.0, CB, C_loc);  
+	rot4(R66,C_loc,Cel); 
 }
 
 
@@ -1698,9 +9641,50 @@ void LAM2Ply_Material::unload_step(double* dstrn, double* strs_n, double* statev
 
 void LAM2Ply_Material::get_elOD(double* statev, double** Cel)
 {
- 
+        int error=0;
+        double VA = vf[0];
+        static bool initialized=false;
+	static double** CA=NULL;
+	static double** CB=NULL;
+	static double** PA=NULL;
+	static double** R66=NULL;		//rotation matrix
+	static double** C_loc=NULL;
+	static double** mat1=NULL;
+	static double** mat2=NULL;
+	
+        if(!initialized)
+        {
+          initialized=true;
+ 	  //memory allocation
+	  mallocmatrix(&CA,6,6);
+	  mallocmatrix(&CB,6,6);
+	  mallocmatrix(&PA,6,6);
+	  mallocmatrix(&R66,6,6);
+	  mallocmatrix(&C_loc,6,6);
+	  mallocmatrix(&mat1,6,6);
+	  mallocmatrix(&mat2,6,6);
+        }
+	cleartens4(R66);
+	cleartens4(CA);
+	cleartens4(CB);
+	cleartens4(PA);
+        cleartens4(C_loc);
+        cleartens4(mat1);
+        cleartens4(mat2);
+
+        eul_mat(euler,R66);
+        transpose(R66,R66,6,6);
+        mat[0]->get_elOD(&(statev[idsdv_A]), CA);
+        mat[1]->get_elOD(&(statev[idsdv_B]), CB);
+        error = TensPA(VA, CA, CB, PA);
+
+        addtens4(1.0, CA, -1.0, CB, mat1);             
+        contraction44(mat1, PA, mat2); 
+        addtens4(VA, mat2, 1.0, CB, C_loc);  
+	rot4(R66,C_loc,Cel); 
 }
 
+
 //**************************************************************************************************************************************************
 // COMPOSITE - MORI-TANAKA  
 //PROPS: MODEL, IDDAM, Nph=2, IDMAT matrix, IDMAT inclusion, IDTOP inclusion,
@@ -1714,7 +9698,7 @@ MT_Material::MT_Material(double* props, int idmat):Material(props,idmat){
 	int iddam, idclength;
         int i;
 
-	nsdv=39;  //18 (strn,strs,dstrn) + 21 (MT macro tangent operator) 
+	nsdv=39;  //18 (strn,strs,dstrn) + 21 (MT macro tangent operator)
 	Nph=2;
 
 	iddam = (int) props[idmat+1];
@@ -1741,7 +9725,6 @@ MT_Material::MT_Material(double* props, int idmat):Material(props,idmat){
 	mallocvector(&euler,3);
 
 
-
 	//get topology of inclusion
 	k=idtop_i;
 	vf_i = props[k++];
@@ -1767,10 +9750,15 @@ MT_Material::MT_Material(double* props, int idmat):Material(props,idmat){
 		nsdv += dam->get_nsdv();
 	}
 
-
         clength = init_clength(props,idclength);
-	
+
+#ifdef NONLOCALGMSH
+	if(idclength==0) this->setLocalDamage();
+	else if(idclength!=0) mtx_mat->setNonLocalDamage();  // MT->idclength is used for mtx_mat->idclength
+#endif
 }
+
+
 #ifdef NONLOCALGMSH
 int MT_Material::get_pos_currentplasticstrainfornonlocal() const
 {
@@ -1788,7 +9776,7 @@ int MT_Material::get_pos_effectiveplasticstrainfornonlocal() const
 
 int MT_Material::get_pos_damagefornonlocal() const
 {
-       if(mtx_mat->get_pos_damagefornonlocal() >=0)
+       if(mtx_mat->get_pos_damagefornonlocal() > -1)
 	   return mtx_mat->get_pos_damagefornonlocal()+idsdv_m;
        return -1;
 }
@@ -1809,13 +9797,18 @@ int MT_Material::get_pos_inc_strain () const
    return idsdv_i + icl_mat->get_pos_strn();
 }
 int MT_Material::get_pos_mtx_Dam () const
-{ 
-   return idsdv_m + mtx_mat->get_pos_dam();
+{
+       if(mtx_mat->get_pos_damagefornonlocal() > -1)
+	   return idsdv_m + mtx_mat->get_pos_damagefornonlocal();
+       return -1;
 }
 int MT_Material::get_pos_inc_Dam () const
 {
-   return idsdv_i + icl_mat->get_pos_dam();
+       if(icl_mat->get_pos_damagefornonlocal() > -1)
+	   return idsdv_i + icl_mat->get_pos_damagefornonlocal();
+       return -1;
 }
+
 double MT_Material::getElasticEnergy (double* statev) 
 {
     double eEi = icl_mat->getElasticEnergy(&statev[idsdv_i]);
@@ -1835,6 +9828,22 @@ double MT_Material::getPlasticEnergy (double* statev)
     return eP;
 }
 #endif
+int MT_Material::get_pos_Fd_bar()const
+{
+   if(icl_mat->get_pos_Fd_bar()!= 0) return idsdv_i + icl_mat->get_pos_Fd_bar();
+   else return 0;
+}
+int MT_Material::get_pos_dFd_bar()const
+{
+   if(icl_mat->get_pos_dFd_bar()!= 0) return idsdv_i + icl_mat->get_pos_dFd_bar();
+   else return 0;
+}
+int MT_Material::get_pos_locFd()const
+{
+   if(icl_mat->get_pos_locFd()!= 0) return idsdv_i + icl_mat->get_pos_locFd();
+   else return 0;
+}
+
 
 //destructor
 MT_Material::~MT_Material(){
@@ -1873,7 +9882,68 @@ void MT_Material::print(){
 int MT_Material::constbox(double* dstrn, double* strs_n,  double* strs, double* statev_n, double* statev, double** Cref, double*** dCref, double* tau, double** dtau, double** Calgo, double alpha, double* dpdE, double* strs_dDdp_bar, double *Sp_bar, double** c_g, double* dFd_d_bar, double* dstrs_dFd_bar, double *dFd_dE, double** c_gF, double* dpdFd, double* dFddp, int kinc, int kstep, double dt){
 	//alpha: for mid-point integration law to compute reference MT operator: C_MT = (1-alpha)*C_MT(tn) + alpha*C_MT(tn+1)
 	
-  return (1);
+	int i,j,k,error;
+	static double** Cn=NULL;
+        static bool initialized = false;
+         
+        pos_p = idsdv_m + mtx_mat->get_pos_p();
+
+	//solve the localization problem
+	error=impl_localization(MT, dstrn, mtx_mat, &icl_mat, vf_m, &(vf_i), &(ar), &(euler), statev_n, statev, nsdv, idsdv_m, &idsdv_i, 1, 1, Cref, dCref, Calgo, dpdE, strs_dDdp_bar, Sp_bar, dFd_d_bar, dstrs_dFd_bar, dFd_dE, c_gF, kinc, kstep, dt);
+
+	//compute macro stress
+	addtens2(vf_m, &(statev[idsdv_m + mtx_mat->get_pos_strs()]),vf_i,&(statev[idsdv_i + icl_mat->get_pos_strs()]),strs);
+
+	//update MT statev
+	addtens2(1., statev_n, 1., dstrn, statev); 
+	copyvect(strs, &(statev[pos_strs]),6);
+	copyvect(dstrn, &(statev[pos_dstrn]),6);
+	
+
+	//store reference operator at tn+1
+	k=pos_C;
+	for(i=0;i<6;i++){
+		for(j=i;j<6;j++){
+			statev[k++] = Cref[i][j];
+		}
+	}
+
+	//generalized mid-point rule
+	if(alpha < 1.){
+
+		//get reference operator of the previous time step
+                if(!initialized)
+		{
+                  mallocmatrix(&Cn,6,6);
+		  initialized = true;
+                }
+                cleartens4(Cn);
+                get_refOp(statev_n, Cn, kinc, kstep);
+
+		if(alpha==0){
+			copymatr(Cn,Cref,6,6);
+			cleartens6(dCref);
+		
+		}
+		else{
+			addtens4((1.-alpha),Cn,alpha,Cref,Cref);
+
+			for(i=0;i<6;i++){
+				for(j=0;j<6;j++){
+					for(k=0;k<6;k++){
+						dCref[i][j][k] *= alpha;
+					}
+				}
+			}
+		}
+		//freematrix(Cn,6);
+	}
+
+	
+	//TO DO: call damage box, if any
+
+        clength->creat_cg(statev_n, pos_p, c_g);      //*********add by wu ling 
+        return error;
 }
 
 void MT_Material::get_refOp(double* statev, double** C, int kinc, int kstep){
@@ -2095,7 +10165,105 @@ MTSecF_Material::~MTSecF_Material(){
 int MTSecF_Material::constbox(double* dstrn, double* strs_n,  double* strs, double* statev_n, double* statev, double** Cref, double*** dCref, double* tau, double** dtau, double** Calgo, double alpha, double* dpdE, double* dstrsdp_bar, double *Sp_bar, double** c_g, double* dFd_d_bar, double* dstrs_dFd_bar, double *dFd_dE, double** c_gF, double* dpdFd, double* dFddp, int kinc, int kstep, double dt){
 	//alpha: for mid-point integration law to compute reference MT operator: C_MT = (1-alpha)*C_MT(tn) + alpha*C_MT(tn+1)
 	
-  return (1);
+	int i,j,k,error;
+	static double** Cn=NULL;
+        static double *statev_uload=NULL;
+        static double *strs_r=NULL;               //residual stress
+        static double *dstrn_uload=NULL;          //strain increment from residual strain
+        double** R66=NULL;
+        static int oldnsdv=0; 
+
+
+        if(strs_r==NULL)
+        {
+          mallocvector(&strs_r,6);
+          mallocvector(&dstrn_uload,6);
+        }
+        cleartens2(strs_r);
+        cleartens2(dstrn_uload);
+        if(nsdv!=oldnsdv)
+        {
+          if(statev_uload!=NULL) free(statev_uload);
+          mallocvector(&statev_uload,nsdv);
+          oldnsdv=nsdv;
+        }
+        for (i=0;i<nsdv;i++)
+        {
+          statev_uload[i]=0.;
+        }
+
+        // unloading by Ling WU June 2012
+        copyvect(statev_n,statev_uload,nsdv);
+        copyvect(strs_n,strs_r,6);
+        copyvect(dstrn,dstrn_uload,6);
+
+        pos_p = idsdv_m + mtx_mat->get_pos_p();
+
+
+        unload_step(dstrn_uload, strs_r, statev_uload, kinc, kstep);
+
+
+
+	//solve the localization problem with SecantMT method
+
+	error=impl_SecLocal(MT, dstrn_uload, mtx_mat, &icl_mat, &LCC, vf_m, &(vf_i), &(ar), &(euler), R66, statev_uload, statev, nsdv, idsdv_m, &idsdv_i, 1, 1, Cref, dCref, Calgo, dpdE, dstrsdp_bar, Sp_bar, dFd_d_bar, dstrs_dFd_bar, dFd_dE, c_gF, dpdFd, dFddp, kinc, kstep, dt);
+
+	//compute macro stress: the update stress is in the state variable
+
+	//update MT statev
+	addtens2(1., statev_n, 1., dstrn, statev); 
+	copyvect(&(statev[pos_strs]),strs,6);
+	copyvect(dstrn, &(statev[pos_dstrn]),6);
+	
+
+	//store reference operator at tn+1
+	k=pos_C;
+	for(i=0;i<6;i++){
+		for(j=i;j<6;j++){
+			statev[k++] = Cref[i][j];
+		}
+	}
+
+	//generalized mid-point rule
+	if(alpha < 1.){
+
+		//get reference operator of the previous time step
+                if(Cn==NULL)
+                {
+                  mallocmatrix(&Cn,6,6);
+                }
+                cleartens4(Cn);
+		get_refOp(statev_n, Cn, kinc, kstep);
+
+		if(alpha==0){
+			copymatr(Cn,Cref,6,6);
+			cleartens6(dCref);
+		
+		}
+		else{
+			addtens4((1.-alpha),Cn,alpha,Cref,Cref);
+
+			for(i=0;i<6;i++){
+				for(j=0;j<6;j++){
+					for(k=0;k<6;k++){
+						dCref[i][j][k] *= alpha;
+					}
+				}
+			}
+		}
+		//freematrix(Cn,6);
+	}
+
+	
+	//TO DO: call damage box, if any
+
+        clength->creat_cg(statev_n, pos_p, c_g);     //*********add by wu ling 
+
+        //free(statev_uload);
+        //free(strs_r);
+        //free(dstrn_uload);
+        
+        return error;
 }
 
 
@@ -2128,6 +10296,9 @@ void MTSecF_Material::unload_step(double* dstrn, double* strs_n, double* statev_
         static double *dstrn_c=NULL;
         static double *dstrn_m=NULL;
         static double *dstrn_i=NULL;
+        
+        /* double E1,E2,E3,nu12,nu21,nu13,nu31,nu23,nu32,G12,G12bis,G13,G23; */
+        
         if(C0==NULL)
         {
           mallocmatrix(&C0,6,6);
@@ -2189,6 +10360,36 @@ void MTSecF_Material::unload_step(double* dstrn, double* strs_n, double* statev_
 
 	inverse(Cel,invCel,&error,6);
 	if(error!=0) printf("problem while inversing Cel in unload_step of MTSecF\n");
+	
+	/*
+	E1 = 1.0/invCel[0][0];
+	E2 = 1.0/invCel[1][1];
+	E3 = 1.0/invCel[2][2];
+	nu21 = -E2*invCel[0][1];
+	nu31 = -E3*invCel[0][2];
+	nu12 = -E1*invCel[1][0];
+	nu32 = -E3*invCel[1][2];
+	nu13 = -E1*invCel[2][0];
+	nu23 = -E2*invCel[2][1];
+	G12 = (1.0/invCel[3][3])/2;
+	G12bis = E1/(2*(1+nu12));
+	G13 = (1.0/invCel[4][4])/2;
+	G23 = (1.0/invCel[5][5])/2;
+
+	printf("E1: %lf \n",E1);
+	printf("E2: %lf \n",E2);
+	printf("E3: %lf \n",E3);
+	printf("nu21: %lf \n",nu21);
+	printf("nu31: %lf \n",nu31);
+	printf("nu12: %lf \n",nu12);
+	printf("nu32: %lf \n",nu32);
+	printf("nu13: %lf \n",nu13);
+	printf("nu23: %lf \n",nu23);
+	printf("G12: %lf \n",G12);
+	printf("G12bis: %lf \n",G12bis);
+	printf("G13: %lf \n",G13);
+	printf("G23: %lf \n",G23);
+	*/
 
 	//if fibers not oriented with e3:
 	if ( (ar[0] != 1.0 || ar[1] != 1.0) && (fabs(euler[0]) > 1e-3 || fabs(euler[1]) > 1e-3)){
@@ -2232,17 +10433,20 @@ void MTSecF_Material::unload_step(double* dstrn, double* strs_n, double* statev_
 
 #if Crmatrix_1st==1
        statev_n[idsdv_m + mtx_mat->get_pos_strs()+i]= statev_n[idsdv_m + mtx_mat->get_pos_strs()+i]-dstrs_m[i];  //residual stress in marix
-#else
+#elif Crmatrix_1st==0
        statev_n[idsdv_m + mtx_mat->get_pos_strs()+i]= 0.0;
+#else
+       statev_n[idsdv_m + mtx_mat->get_pos_strs()+i]= statev_n[idsdv_m + mtx_mat->get_pos_strs()+i]-dstrs_m[i];  //residual stress in marix
 #endif
         statev_n[idsdv_m + mtx_mat->get_pos_strn()+i]= statev_n[idsdv_m + mtx_mat->get_pos_strn()+i]-dstrn_m[i];  //residual strain in marix
      
 #if Crinclusion==1
         statev_n[idsdv_i + icl_mat->get_pos_strs()+i]= statev_n[idsdv_i + icl_mat->get_pos_strs()+i]-dstrs_i[i];  //residual stress in inclusion
-#else
+#elif Crinclusion==0
         statev_n[idsdv_i + icl_mat->get_pos_strs()+i]= 0.0;
+#else
+        statev_n[idsdv_i + icl_mat->get_pos_strs()+i]= statev_n[idsdv_i + icl_mat->get_pos_strs()+i]-dstrs_i[i];  //residual stress in inclusion
 #endif
-
         statev_n[idsdv_i + icl_mat->get_pos_strn()+i]= statev_n[idsdv_i + icl_mat->get_pos_strn()+i]-dstrn_i[i];  //residual strain in inclusion
         } 
 
@@ -2252,9 +10456,9 @@ void MTSecF_Material::unload_step(double* dstrn, double* strs_n, double* statev_
 
 void MTSecF_Material::setEuler(double e1, double e2, double e3)
 {
-  //delete euler;
-  //double* euler = NULL; 
-  //mallocvector(&euler,3);
+  delete euler;
+  double* euler = NULL; 
+  mallocvector(&euler,3);
   euler[0] = e1;
   euler[1] = e2;
   euler[2] = e3;
@@ -2262,6 +10466,26 @@ void MTSecF_Material::setEuler(double e1, double e2, double e3)
   icl_mat->setEuler(e1,e2,e3);
 }
 
+#ifdef NONLOCALGMSH
+
+void MTSecF_Material:: get_elOp_mtx(double* statev, double** Cel){
+       mtx_mat->get_elOp(&statev[idsdv_m],Cel);
+}
+
+void MTSecF_Material::get_elOp_icl(double* statev, double** Cel){
+       icl_mat->get_elOp(&statev[idsdv_i],Cel);
+}
+
+void MTSecF_Material:: get_elOp_mtx(double** Cel){
+       mtx_mat->get_elOp(Cel);
+}
+
+void MTSecF_Material::get_elOp_icl(double** Cel){
+       icl_mat->get_elOp(Cel);
+}
+
+#endif
+
 
 //**************************************************************************************************************************************************
 // COMPOSITE - MORI-TANAKA   
@@ -2290,8 +10514,99 @@ MTSecNtr_Material::~MTSecNtr_Material(){
 int MTSecNtr_Material::constbox(double* dstrn, double* strs_n,  double* strs, double* statev_n, double* statev, double** Cref, double*** dCref, double* tau, double** dtau, double** Calgo, double alpha, double* dpdE, double* dstrsdp_bar, double *Sp_bar, double** c_g, double* dFd_d_bar, double* dstrs_dFd_bar, double *dFd_dE, double** c_gF, double* dpdFd, double* dFddp, int kinc, int kstep, double dt){
 	//alpha: for mid-point integration law to compute reference MT operator: C_MT = (1-alpha)*C_MT(tn) + alpha*C_MT(tn+1)
 	
+	int i,j,k,error;
+	static double** Cn=NULL;
+        static double *statev_uload=NULL;
+        static double *strs_r=NULL;               //residual stress
+        static double *dstrn_uload=NULL;          //strain increment from residual strain
+        double** R66=NULL;
+        static int oldnsdv = 0;
+
+        if(strs_r==NULL)
+        {
+          mallocvector(&strs_r,6);
+          mallocvector(&dstrn_uload,6);
+        }
+        cleartens2(strs_r);
+        cleartens2(dstrn_uload);
+        if(nsdv!=oldnsdv)
+        {
+          if(statev_uload!=NULL) free(statev_uload);
+          mallocvector(&statev_uload,nsdv);
+          oldnsdv=nsdv;
+        }
+        for (i=0;i<nsdv;i++)
+        {
+          statev_uload[i]=0.;
+        }
+
+
+        // unloading by Ling WU Feb 2014
+        copyvect(statev_n,statev_uload,nsdv);
+        copyvect(strs_n,strs_r,6);
+        copyvect(dstrn,dstrn_uload,6);
+
+        pos_p = idsdv_m + mtx_mat->get_pos_p();
+
+        unload_step(dstrn_uload, strs_r, statev_uload, kinc, kstep);
+
+	//solve the localization problem with SecantMT method
+
+	error=impl_SecLocal(MTSecNtr, dstrn_uload, mtx_mat, &icl_mat, &LCC, vf_m, &(vf_i), &(ar), &(euler), R66, statev_uload, statev, nsdv, idsdv_m, &idsdv_i, 1, 1, Cref, dCref, Calgo, dpdE, dstrsdp_bar, Sp_bar, dFd_d_bar, dstrs_dFd_bar, dFd_dE, c_gF, dpdFd, dFddp, kinc, kstep, dt);
+
+
+	//compute macro stress: the update stress is in the state variable
+
+	//update MT statev
+	addtens2(1., statev_n, 1., dstrn, statev); 
+	copyvect(&(statev[pos_strs]),strs,6);
+	copyvect(dstrn, &(statev[pos_dstrn]),6);
+	
+
+	//store reference operator at tn+1
+	k=pos_C;
+	for(i=0;i<6;i++){
+		for(j=i;j<6;j++){
+			statev[k++] = Cref[i][j];
+		}
+	}
+
+	//generalized mid-point rule
+	if(alpha < 1.){
+
+		//get reference operator of the previous time step
+                if(Cn==NULL)
+                {
+                  mallocmatrix(&Cn,6,6);
+                }
+                cleartens4(Cn);
+		get_refOp(statev_n, Cn, kinc, kstep);
+
+		if(alpha==0){
+			copymatr(Cn,Cref,6,6);
+			cleartens6(dCref);
+		
+		}
+		else{
+			addtens4((1.-alpha),Cn,alpha,Cref,Cref);
+
+			for(i=0;i<6;i++){
+				for(j=0;j<6;j++){
+					for(k=0;k<6;k++){
+						dCref[i][j][k] *= alpha;
+					}
+				}
+			}
+		}
+		//freematrix(Cn,6);
+	}
+
+	
+	//TO DO: call damage box, if any
+
+        clength->creat_cg(statev_n, pos_p, c_g);     //*********add by wu ling 
+        return error;
 
-  return (1);
 }
 
 
@@ -2524,8 +10839,97 @@ MTSecSd_Material::~MTSecSd_Material(){
 
 int MTSecSd_Material::constbox(double* dstrn, double* strs_n,  double* strs, double* statev_n, double* statev, double** Cref, double*** dCref, double* tau, double** dtau, double** Calgo, double alpha, double* dpdE, double* dstrsdp_bar, double *Sp_bar, double** c_g, double* dFd_d_bar, double* dstrs_dFd_bar, double *dFd_dE, double** c_gF, double* dpdFd, double* dFddp, int kinc, int kstep, double dt){
 	//alpha: for mid-point integration law to compute reference MT operator: C_MT = (1-alpha)*C_MT(tn) + alpha*C_MT(tn+1)
+	
+	int i,j,k,error;
+	static double** Cn=NULL;
+        static double *statev_uload=NULL;
+        static double *strs_r=NULL;               //residual stress
+        static double *dstrn_uload=NULL;          //strain increment from residual strain
+        static int oldnsdv=0; 
+
+        if(strs_r==NULL)
+        {
+          mallocvector(&strs_r,6);
+          mallocvector(&dstrn_uload,6);
+        }
+        cleartens2(strs_r);
+        cleartens2(dstrn_uload);
+        if(nsdv!=oldnsdv)
+        {
+          if(statev_uload!=NULL) free(statev_uload);
+          mallocvector(&statev_uload,nsdv);
+          oldnsdv=nsdv;
+        }
+        for (i=0;i<nsdv;i++)
+        {
+          statev_uload[i]=0.;
+        }
+
+
+        // unloading by Ling WU June 2012
+        copyvect(statev_n,statev_uload,nsdv);
+        copyvect(strs_n,strs_r,6);
+        copyvect(dstrn,dstrn_uload,6);
+
+        pos_p = idsdv_m + mtx_mat->get_pos_p();
+
+        unload_step(dstrn_uload, strs_r, statev_uload, kinc, kstep);
+
+
+	//solve the localization problem with second-order SecantMT method
+
+        error=homogenize_2rd(MT, dstrn_uload, mtx_mat, &(icl_mat[0]), vf_m, vf_i, ar, euler, statev_uload, statev, 
+                      nsdv, idsdv_m, idsdv_i, &LCC,  Calgo, dpdE, dstrsdp_bar, Sp_bar, kinc, kstep, dt);
+
+
+	//compute macro stress: the update stress is in the state variable
+
+	//update MT statev
+	addtens2(1., statev_n, 1., dstrn, statev); 
+
+       // contraction42(LCC.C, dstrn_uload, &(statev[pos_strs]));
+	addtens2(vf_m, &statev[idsdv_m+mtx_mat->get_pos_strs()], vf_i, &statev[idsdv_i+icl_mat->get_pos_strs()], &statev[pos_strs]);
+	copyvect(&(statev[pos_strs]),strs,6);
+	copyvect(dstrn, &(statev[pos_dstrn]),6);
+	
+
+	//store reference operator at tn+1
+	k=pos_C;
+	for(i=0;i<6;i++){
+		for(j=i;j<6;j++){
+			statev[k++] = LCC.C[i][j];
+		}
+	}
 
-  return (1);       
+	//generalized mid-point rule
+	if(alpha < 1.){
+
+		//get reference operator of the previous time step
+                if(Cn==NULL)
+		{
+                  mallocmatrix(&Cn,6,6);
+                }
+                cleartens4(Cn);
+		get_refOp(statev_n, Cn, kinc, kstep);
+
+		if(alpha==0){
+			copymatr(Cn,Cref,6,6);
+		}
+		else{
+			addtens4((1.-alpha),Cn,alpha,LCC.C,Cref);
+		}
+		//freematrix(Cn,6);
+	}
+
+	
+	//TO DO: call damage box, if any
+
+        clength->creat_cg(statev_n, pos_p, c_g);     //*********add by wu ling 
+
+        //free(statev_uload);
+        //free(strs_r);
+        //free(dstrn_uload);
+        return error;
 }
 
 
@@ -2859,10 +11263,11 @@ int MTSecF_Stoch_Material::get_pos_DamParm2()const
    if(mtx_mat->get_pos_DamParm2()!= 0) return idsdv_m + mtx_mat->get_pos_DamParm2();
    else return 0;
 }
-int MTSecF_Stoch_Material::get_pos_DamParm3()const
+
+int MTSecF_Stoch_Material::get_pos_DamParm3()const   
 {
-  if(mtx_mat->get_pos_DamParm3()!= 0) return idsdv_m + mtx_mat->get_pos_DamParm3();
-  else return 0;
+   if(mtx_mat->get_pos_DamParm3()!= 0) return idsdv_m + mtx_mat->get_pos_DamParm3();
+   else return 0;
 }
 
 
@@ -2876,13 +11281,11 @@ int MTSecF_Stoch_Material::get_pos_INCDamParm2()const
    if(icl_mat->get_pos_DamParm2()!= 0) return idsdv_i + icl_mat->get_pos_DamParm2();
    else return 0;
 }
-
-int MTSecF_Stoch_Material::get_pos_INCDamParm3()const
+int MTSecF_Stoch_Material::get_pos_INCDamParm3()const   
 {
    if(icl_mat->get_pos_DamParm3()!= 0) return idsdv_i + icl_mat->get_pos_DamParm3();
    else return 0;
 }
-
 int MTSecF_Stoch_Material::get_pos_Fd_bar()const   
 {
    if(icl_mat->get_pos_Fd_bar()!= 0) return idsdv_i + icl_mat->get_pos_Fd_bar();
@@ -2902,7 +11305,150 @@ int MTSecF_Stoch_Material::get_pos_locFd()const
 int MTSecF_Stoch_Material::constbox(double* dstrn, double* strs_n,  double* strs, double* statev_n, double* statev, double** Cref, double*** dCref, double* tau, double** dtau, double** Calgo, double alpha, double* dpdE, double* dstrsdp_bar, double *Sp_bar, double** c_g, double* dFd_d_bar, double* dstrs_dFd_bar, double *dFd_dE, double** c_gF, double* dpdFd, double* dFddp, int kinc, int kstep, double dt){
 	//alpha: for mid-point integration law to compute reference MT operator: C_MT = (1-alpha)*C_MT(tn) + alpha*C_MT(tn+1)
 	
-  return (1);
+	int i,j,k,error;
+	static double** Cn=NULL;
+        static double *statev_uload=NULL;
+        static double *strs_r=NULL;               //residual stress
+        static double *dstrn_uload=NULL;          //strain increment from residual strain
+
+        double _Vfm;                  // extra variables for randomness, May 2016
+        double _Vfi;
+        static double* _euler=NULL;
+        static double* _ar=NULL;
+        double** R66=NULL;
+        static int oldnsdv=0;
+        ELcc LCC;
+ 
+        if(strs_r==NULL)
+        {
+          mallocvector(&strs_r,6);
+          mallocvector(&dstrn_uload,6);
+          mallocvector(&_euler,3);
+          mallocvector(&_ar,2);
+        }
+        cleartens2(strs_r);
+        cleartens2(dstrn_uload);
+        for (i=0;i<3;i++)
+        {
+          _euler[i]=0.;
+        }
+        _ar[0] = 0.0;
+        _ar[1] = 0.0;
+
+        if(nsdv!=oldnsdv)
+        {
+          if(statev_uload!=NULL) free(statev_uload);
+          mallocvector(&statev_uload,nsdv);
+          oldnsdv=nsdv;
+        }
+        for (i=0;i<nsdv;i++)
+        {
+          statev_uload[i]=0.;
+        }
+
+        // checking whether random variables are needed
+        if(pos_vfi == 0){
+            _Vfi = vf_i;     
+        }
+        else{
+            _Vfi = statev_n[pos_vfi];
+        }
+        _Vfm = 1.0 - _Vfi;
+        malloc_lcc(&LCC, Nph, _Vfi); 
+
+        if( pos_euler == 0){
+            copyvect(euler,_euler,3);  
+        }
+        else{
+            _euler[0] = statev_n[pos_euler];
+            _euler[1] = statev_n[pos_euler+1];
+            _euler[2] = statev_n[pos_euler+2];
+        }
+
+        if( icl_mat->get_pos_euler() != 0 and pos_euler != 0){
+            copyvect(_euler,&(statev_n[idsdv_i + icl_mat->get_pos_euler()]),3);  
+            copyvect(_euler,&(statev[idsdv_i + icl_mat->get_pos_euler()]),3); 
+        }
+        else if ( icl_mat->get_pos_euler() != 0 and pos_euler == 0){
+            printf("Problem of euler angle in stoch MTSecF\n");
+        }
+
+        if(pos_aspR == 0){
+            copyvect(ar,_ar,2);     
+        }
+        else if(fabs(statev_n[pos_aspR]-1.0) <= 1.0e-6){
+            _ar[0] = 1000000.0;
+            _ar[1] = 1000000.0;
+        }
+        else{            
+            _ar[0] = 1.0;
+            _ar[1] = statev_n[pos_aspR];
+        }
+
+        // unloading by Ling WU June 2012
+        copyvect(statev_n,statev_uload,nsdv);
+        copyvect(strs_n,strs_r,6);
+        copyvect(dstrn,dstrn_uload,6);
+
+        pos_p = idsdv_m + mtx_mat->get_pos_p();
+
+        unload_step(dstrn_uload, strs_r, statev_uload, _Vfm, _Vfi, _euler, _ar, kinc, kstep);
+
+	//solve the localization problem with SecantMT method       
+	error=impl_SecLocal(MT, dstrn_uload, mtx_mat, &icl_mat, &LCC, _Vfm, &(_Vfi), &(_ar), &(_euler), R66, statev_uload, statev, nsdv, idsdv_m, &idsdv_i, 1, 1, Cref, dCref, Calgo, dpdE, dstrsdp_bar, Sp_bar, dFd_d_bar, dstrs_dFd_bar, dFd_dE, c_gF, dpdFd,  dFddp, kinc, kstep, dt);
+
+	//compute macro stress: the update stress is in the state variable
+
+	//update MT statev
+	addtens2(1., statev_n, 1., dstrn, statev); 
+	copyvect(&(statev[pos_strs]),strs,6);
+	copyvect(dstrn, &(statev[pos_dstrn]),6);
+	
+
+	//store reference operator at tn+1
+	k=pos_C;
+	for(i=0;i<6;i++){
+		for(j=i;j<6;j++){
+			statev[k++] = Cref[i][j];
+		}
+	}
+
+	//generalized mid-point rule
+	if(alpha < 1.){
+
+		//get reference operator of the previous time step
+		if(Cn==NULL)
+                {
+                  mallocmatrix(&Cn,6,6);
+                }
+                cleartens4(Cn);
+		get_refOp(statev_n, Cn, kinc, kstep);
+
+		if(alpha==0){
+			copymatr(Cn,Cref,6,6);
+			cleartens6(dCref);
+		
+		}
+		else{
+			addtens4((1.-alpha),Cn,alpha,Cref,Cref);
+
+			for(i=0;i<6;i++){
+				for(j=0;j<6;j++){
+					for(k=0;k<6;k++){
+						dCref[i][j][k] *= alpha;
+					}
+				}
+			}
+		}
+		freematrix(Cn,6);
+	}
+
+	
+	//TO DO: call damage box, if any
+
+        clength->creat_cg(statev_n, pos_p, c_g);     //*********add by wu ling 
+        free_lcc(&LCC);
+        return error;
 }
 
 // unloading step for MTSecF_Material material to reset statev_n in residual condition, by Ling Wu June 2012
@@ -3042,8 +11588,10 @@ void MTSecF_Stoch_Material::unload_step(double* dstrn, double* strs_n, double* s
 
 #if Crmatrix_1st==1
          statev_n[idsdv_m + mtx_mat->get_pos_strs()+i]= statev_n[idsdv_m + mtx_mat->get_pos_strs()+i]-dstrs_m[i];  //residual stress in marix
-#else
+#elif Crmatrix_1st==0
          statev_n[idsdv_m + mtx_mat->get_pos_strs()+i]= 0.0;
+#else
+         statev_n[idsdv_m + mtx_mat->get_pos_strs()+i]= statev_n[idsdv_m + mtx_mat->get_pos_strs()+i]-dstrs_m[i];  //residual stress in marix
 #endif
 
          statev_n[idsdv_m + mtx_mat->get_pos_strn()+i]= statev_n[idsdv_m + mtx_mat->get_pos_strn()+i]-dstrn_m[i];  //residual strain in marix
@@ -3200,8 +11748,8 @@ void MTSecF_Stoch_Material::get_elOp(double* statev, double** Cel){
 		I[i][i] = 1.;
 	}
 
-	mtx_mat->get_elOp(C0);
-	icl_mat->get_elOp(C1);
+	mtx_mat->get_elOp(&statev[idsdv_m],C0);
+	icl_mat->get_elOp(&statev[idsdv_i],C1);
 	
 	//if fibers not oriented with e3:
 	if ( _ar[0] == 1.0 && _ar[1] == 1.0){
@@ -3348,7 +11896,6 @@ void MTSecF_Stoch_Material::get_elOD(double* statev, double** Cel)
 
 }
 
-
 #ifdef NONLOCALGMSH
 
 void MTSecF_Stoch_Material:: get_elOp_mtx(double* statev, double** Cel){
@@ -3397,7 +11944,165 @@ MTSecF_LargD::~MTSecF_LargD(){
 //constbox
 int MTSecF_LargD::constbox(double* dstrn, double* strs_n,  double* strs, double* statev_n, double* statev, double** Cref, double*** dCref, double* tau, double** dtau, double** Calgo, double alpha, double* dpdE, double* dstrsdp_bar, double *Sp_bar, double** c_g, double* dFd_d_bar, double* dstrs_dFd_bar, double *dFd_dE, double** c_gF, double* dpdFd, double* dFddp, int kinc, int kstep, double dt){
 	//alpha: for mid-point integration law to compute reference MT operator: C_MT = (1-alpha)*C_MT(tn) + alpha*C_MT(tn+1)
-  return (1);
+	
+	int i,j,k,error;
+        double JaI, JaM;
+	static double **Cn=NULL;
+        static double *statev_uload=NULL;
+        static double *strs_r=NULL; //residual stress
+        static double *dstrn_uload=NULL;          //strain increment from residual strain
+
+        double _Vfm;                  // extra variables for randomness, May 2016
+        double _Vfi;
+        static double *_ar=NULL;
+        static double **R66=NULL; 
+        static int oldnsdv=0;
+        ELcc LCC;
+        if(strs_r==NULL)
+        {
+          mallocvector(&strs_r,6);
+          mallocvector(&dstrn_uload,6);
+          mallocvector(&_ar,2);
+          mallocmatrix(&R66,6,6);
+        }
+        
+        cleartens2(strs_r);
+        cleartens2(dstrn_uload);
+        for(i=0;i<2;i++) _ar[i]=0.;
+        cleartens4(R66);
+        if(nsdv!=oldnsdv)
+        {
+          if(statev_uload!=NULL) free(statev_uload);
+          mallocvector(&statev_uload,nsdv);
+          oldnsdv=nsdv;
+        }
+        for (i=0;i<nsdv;i++)
+        {
+          statev_uload[i]=0.;
+        }
+
+        // initialize some state varibles
+
+        if( kinc==1 and kstep ==1){
+           statev_n[pos_vfi] = vf_i;
+           statev_n[pos_aspR] = ar[0];
+           statev_n[pos_aspR+1] = ar[1];
+
+           eul_mat(euler, R66);  
+           matrix_to_vect(6, R66, &(statev_n[pos_R66])); 
+           copyvect(statev_n,statev,nsdv);      
+           //here we need to initialize the bases in the phases. Best guess is to use the one of the composite
+           static double **strnini;
+           static double **Baseini;
+           static double *vstrnini;
+           if(strnini==NULL)
+           {
+             mallocmatrix(&strnini,3,3);
+             mallocmatrix(&Baseini,3,3);
+             mallocvector(&vstrnini,3);
+           }
+           GetStretchTensor(dstrn, strnini,sqrt(2.));
+           Jacobian_Eigen( 3, strnini, vstrnini, Baseini);
+           matrix_to_vect(3, Baseini, &(statev_n[idsdv_i + icl_mat->get_pos_Base()]));  
+           matrix_to_vect(3, Baseini, &(statev_n[idsdv_m + mtx_mat->get_pos_Base()]));  
+           matrix_to_vect(3, Baseini, &(statev[idsdv_i + icl_mat->get_pos_Base()]));  
+           matrix_to_vect(3, Baseini, &(statev[idsdv_m + mtx_mat->get_pos_Base()]));  
+         }
+        else{
+            copyvect(statev,dstrn,6);     // keep the final strain in dstrn just for large deformation
+        }
+
+        vect_to_matrix(6, &(statev_n[pos_R66]), R66);
+       
+        // set the needed parameters
+        _Vfi = statev_n[pos_vfi];
+        _Vfm = 1.0 - _Vfi;
+        malloc_lcc(&LCC, Nph, _Vfi); 
+
+        // unloading by Ling WU June 2012
+        copyvect(statev_n,statev_uload,nsdv);
+        copyvect(strs_n,strs_r,6);
+        copyvect(dstrn,dstrn_uload,6);
+
+        pos_p = idsdv_m + mtx_mat->get_pos_p();
+        
+
+        unload_step(dstrn_uload, strs_r, statev_uload, _Vfm, _Vfi, R66, kinc, kstep);
+
+        _ar[0] = statev_uload[pos_aspR];
+        _ar[1] = statev_uload[pos_aspR+1];
+
+	//solve the localization problem with SecantMT method   
+
+	error=impl_SecLocal(MTSecF_LargeDeform, dstrn_uload, mtx_mat, &icl_mat, &LCC, _Vfm, &(_Vfi), &(_ar), &(euler), R66, statev_uload, statev, nsdv, idsdv_m, &idsdv_i, 1, 1, Cref, dCref, Calgo, dpdE, dstrsdp_bar, Sp_bar, dFd_d_bar, dstrs_dFd_bar, dFd_dE, c_gF, dpdFd, dFddp, kinc, kstep, dt);
+    
+        JaI = statev[idsdv_i + icl_mat->get_pos_Ja()];
+        JaM = statev[idsdv_m + mtx_mat->get_pos_Ja()];
+ 
+        statev[pos_vfi] = vf_i*JaI/(vf_i*JaI+(1.0-vf_i)*JaM);
+        statev[pos_aspR] = _ar[0];
+        statev[pos_aspR+1] = _ar[1]; 
+        matrix_to_vect(6, R66, &(statev[pos_R66]));
+
+// **********  compute stress of composite***************************
+//*****  stress tau in each phases,  stress sigma in composite
+
+        for(i=0;i<6;i++){
+            statev[i+6] = statev[pos_vfi]*(statev[idsdv_i+icl_mat->get_pos_strs()+i])/JaI 
+                        + (1.0-statev[pos_vfi])*(statev[idsdv_m + mtx_mat->get_pos_strs()+i])/JaM;
+        }
+
+	//compute macro stress: the update stress is in the state variable
+
+	//update MT statev
+	//addtens2(1., statev_n, 1., dstrn, statev); //already updated at the beginning of the time step 
+	copyvect(&(statev[pos_strs]),strs,6);
+	copyvect(dstrn, &(statev[pos_dstrn]),6);
+	
+	//store reference operator at tn+1
+	k=pos_C;
+	for(i=0;i<6;i++){
+		for(j=i;j<6;j++){
+			statev[k++] = Cref[i][j];
+		}
+	}
+
+	//generalized mid-point rule
+	if(alpha < 1.){
+
+		//get reference operator of the previous time step
+		if(Cn==NULL) 
+                { 
+                  mallocmatrix(&Cn,6,6);
+                }
+                cleartens4(Cn);
+		get_refOp(statev_n, Cn, R66, kinc, kstep);
+
+		if(alpha==0){
+			copymatr(Cn,Cref,6,6);
+			cleartens6(dCref);
+		
+		}
+		else{
+			addtens4((1.-alpha),Cn,alpha,Cref,Cref);
+
+			for(i=0;i<6;i++){
+				for(j=0;j<6;j++){
+					for(k=0;k<6;k++){
+						dCref[i][j][k] *= alpha;
+					}
+				}
+			}
+		}
+		//freematrix(Cn,6);
+	}
+
+	//TO DO: call damage box, if any
+
+        clength->creat_cg(statev_n, pos_p, c_g);     //*********add by wu ling 
+        
+        free_lcc(&LCC);
+        return error;
 }
 
 // unloading step for MTSecF_Material material to reset statev_n in residual condition, by Ling Wu June 2012
@@ -3725,8 +12430,8 @@ void MTSecF_LargD::get_elOp(double* statev, double** _R66, double** Cel){
 		I[i][i] = 1.;
 	}
 
-	mtx_mat->get_elOp(C0);
-	icl_mat->get_elOp(C1);
+	mtx_mat->get_elOp(&statev[idsdv_m], C0);
+	icl_mat->get_elOp(&statev[idsdv_i],C1);
 	
 	//if fibers not oriented with e3:
         mallocvector(&_ar,2);
@@ -3956,7 +12661,13 @@ SC_Material::SC_Material(double* props, int idmat):Material(props, idmat){
 
 
         clength = init_clength(props,idclength);
+
+#ifdef NONLOCALGMSH
+	if(idclength==0) this->setLocalDamage();
+#endif
 }
+
+
 #ifdef NONLOCALGMSH
 int SC_Material::get_pos_currentplasticstrainfornonlocal() const
 {
@@ -4063,8 +12774,97 @@ void SC_Material::print(){
 //constbox
 int SC_Material::constbox(double* dstrn, double* strs_n,  double* strs, double* statev_n, double* statev, double** Cref, double*** dCref, double* tau, double** dtau, double** Calgo, double alpha, double* dpdE, double* strs_dDdp_bar, double *Sp_bar, double** c_g, double* dFd_d_bar, double* dstrs_dFd_bar, double *dFd_dE, double** c_gF, double* dpdFd, double* dFddp, int kinc, int kstep, double dt){
 	
+	int i,j,k,error,errortmp;
+	int pos;
+	
+	static double** Cn=NULL;	
 
-  return (1);
+	int EXPL=1;
+        error=0;
+	
+	get_refOp(statev_n, Cref, kinc, kstep); //Cmacro at tn, first estimate for NR (cannot be done within impl/expl_localization: get_refOp not accessible!)
+
+
+	//localization problem solved with operators at t_n
+	if(EXPL){
+		
+		if(mtx){
+			printf("explicit solver for SC with matrix not implemented yet\n");
+			return 1;
+		}
+
+		errortmp=expl_localization(SC, dstrn, mtx_mat, icl_mat, vf_m, vf_i, ar, euler, statev_n, statev, nsdv, idsdv_m, idsdv_i, mtx, Nicl, Cref, dCref, Calgo, kinc, kstep, dt);
+		if(errortmp!=0) error=1;
+		//compute macro stress	
+		cleartens2(strs);
+		for(i=0;i<Nicl;i++){
+			pos = idsdv_i[i] + (icl_mat[i])->get_pos_strs();
+			addtens2(1.,strs,vf_i[i],&(statev[pos]),strs);	
+		}
+
+	}
+
+
+	//implicit resolution of the equivalent problem (except for Eshelby's tensor)
+	else{
+
+		errortmp=impl_localization(SC, dstrn, mtx_mat, icl_mat, vf_m, vf_i, ar, euler, statev_n, statev, nsdv, idsdv_m, idsdv_i, mtx, Nicl, Cref, dCref, Calgo, dpdE, strs_dDdp_bar, Sp_bar, dFd_d_bar, dstrs_dFd_bar, dFd_dE, c_gF, kinc, kstep, dt);
+	        if(errortmp!=0) error=1;
+		//compute macro stress
+		cleartens2(strs);
+		if(mtx){
+			pos = idsdv_m + mtx_mat->get_pos_strs();
+			addtens2(vf_m,&(statev[pos]),0,strs,strs);
+		}
+		for(i=0;i<Nicl;i++){
+			pos = idsdv_i[i] + (icl_mat[i])->get_pos_strs();
+			addtens2(1.,strs,vf_i[i],&(statev[pos]),strs);	
+		}
+	}
+
+	//update SC statev
+	addtens2(1., statev_n, 1., dstrn, statev); 
+	copyvect(strs, &(statev[6]),6);
+	copyvect(dstrn, &(statev[12]),6);
+	
+	for(i=0;i<6;i++){
+		for(j=0;j<6;j++){
+			statev[18 + (i*6) + j] = Cref[i][j];
+		}
+	}
+
+	//generalized mid-point rule
+	if(alpha < 1.){
+
+		//get reference operator of the previous time step
+		if(Cn=NULL) mallocmatrix(&Cn,6,6);
+                cleartens4(Cn);
+		get_refOp(statev_n, Cn, kinc, kstep);
+
+		if(alpha==0){
+			copymatr(Cn,Cref,6,6);
+			cleartens6(dCref);
+		
+		}
+		else{
+			addtens4((1.-alpha),Cn,alpha,Cref,Cref);
+
+			for(i=0;i<6;i++){
+				for(j=0;j<6;j++){
+					for(k=0;k<6;k++){
+						dCref[i][j][k] *= alpha;
+					}
+				}
+			}
+		}
+		//freematrix(Cn,6);
+	}
+
+
+	//TO DO: call damage box of SC material, if any
+        pos_p=0;
+        clength->creat_cg(statev_n, pos_p, c_g);      //*********add by wu ling 
+        return error;
 }
 
 void SC_Material::get_refOp(double* statev_n, double** C, int kinc, int kstep){
@@ -4337,6 +13137,8 @@ MT_VT_Material::MT_VT_Material(double* props, int idmat):Material(props, idmat){
                 }
 	        else
 	        {
+                  pos_dam=-1;
+		  pos_p=-1;
                   withDamage=false;
 	          dam=NULL;
 	        }
@@ -4480,7 +13282,130 @@ int MT_VT_Material::constbox(double* dstrn, double* strs_n,  double* strs, doubl
 	
 
 
-  return (1);
+  
+
+        int pos,i,j,k,error,errortmp;
+        static double *tautmp=NULL;
+        static double *dpdEtmp=NULL;
+        static double *strs_dDdp_bartmp=NULL;
+        static double *Sp_bartmp=NULL;
+	static double **Calgotmp=NULL;
+	static double **Creftmp=NULL;
+        static double **dtautmp=NULL;
+        static double **c_gtmp=NULL;
+        static double ***dCreftmp=NULL;
+        error=0;
+         if(tautmp==NULL)
+        {
+          mallocvector(&tautmp,6);
+          mallocvector(&dpdEtmp,6);
+          mallocvector(&strs_dDdp_bartmp,6);
+          mallocvector(&Sp_bartmp,6);
+        }
+	cleartens2(tautmp);
+	cleartens2(dpdEtmp);
+	cleartens2(strs_dDdp_bartmp);
+	cleartens2(Sp_bartmp);
+	if(Calgotmp==NULL)
+        {
+          mallocmatrix(&Calgotmp,6,6);
+          mallocmatrix(&Creftmp,6,6);
+          mallocmatrix(&dtautmp,6,6);
+          mallocmatrix(&c_gtmp,6,6);
+        }
+        cleartens4(Calgotmp);
+        cleartens4(Creftmp);
+        cleartens4(dtautmp);
+        cleartens4(c_gtmp);
+        if(dCreftmp==NULL)
+        {
+          malloctens3(&dCreftmp,6,6,6);
+        }
+        cleartens6(dCreftmp);
+	//update strain
+	addtens2(1., &(statev_n[pos_strn]), 1., dstrn, &(statev[pos_strn])); 
+	copyvect(dstrn, &(statev[pos_dstrn]),6);
+
+	cleartens2(strs);
+ 	cleartens4(Calgo);
+ 	cleartens4(Cref);
+        if(withDamage)
+        {
+#ifdef NONLOCALGMSH
+          for(int i=0;i<Total_number_phase;i++)
+          {
+               //send non-local values
+               statev[idsdv_i[i] + (ph_mat[i])->get_pos_effectiveplasticstrainfornonlocal()]=statev[get_pos_effectiveplasticstrainfornonlocal()];
+               statev[idsdv_i[i] + (ph_mat[i])->get_pos_effectiveplasticstrainfornonlocal()+1]=statev[get_pos_effectiveplasticstrainfornonlocal()+1];
+          }
+	  statev[get_pos_damagefornonlocal()]=0.;
+#endif         
+          statev[pos_p]=0.;
+
+        }
+	for(int i=0;i<Total_number_phase;i++){
+	  if(fabs(Wgt[i])>1.e-12)
+	    {
+                  errortmp=(ph_mat[i])->constbox(dstrn, &(statev_n[idsdv_i[i] + (ph_mat[i])->get_pos_strs()]),  &(statev[idsdv_i[i] + (ph_mat[i])->get_pos_strs()]), &(statev_n[idsdv_i[i]]), &(statev[idsdv_i[i]]), Creftmp,dCreftmp, tautmp, dtautmp, Calgotmp, alpha, dpdEtmp, strs_dDdp_bartmp, Sp_bartmp, c_gtmp, dFd_d_bar, dstrs_dFd_bar, dFd_dE, c_gF, dpdFd, dFddp, kinc, kstep, dt);
+                  if(errortmp!=0) error=1;
+
+		  pos = idsdv_i[i] + (ph_mat[i])->get_pos_strs();
+		  addtens2(1.,strs,Wgt[i],&(statev[pos]),strs);
+                  addtens2(1.,tau,Wgt[i],tautmp,tau);
+                  addtens2(1.,dpdE,Wgt[i],dpdEtmp,dpdE);
+                  addtens2(1.,strs_dDdp_bar,Wgt[i],strs_dDdp_bartmp,strs_dDdp_bar);
+                  addtens2(1.,Sp_bar,Wgt[i],Sp_bartmp,Sp_bar);
+                  addtens4(1.,Calgo,Wgt[i],Calgotmp,Calgo);
+                  addtens4(1.,Cref,Wgt[i],Creftmp,Cref);
+                  addtens4(1.,dtau,Wgt[i],dtautmp,dtau);
+                  // addtens4(1.,c_g,Wgt[i],c_gtmp,c_g);
+                  addtens6(1.,dCref,Wgt[i],dCreftmp,dCref);
+
+		  //printf("phase %d, stress phase %f %f %f %f %f %f, weight %e\n", i, statev[pos], statev[pos+1], statev[pos+2], statev[pos+3], statev[pos+4], statev[pos+5], Wgt[i] );
+		  //printf("phase %d, stress total %f %f %f %f %f %f, weight %e\n", i, strs[0], strs[1], strs[2], strs[3], strs[4], strs[5], Wgt[i] );
+		  //printf("phase %d, C phase %f %f %f %f %f %f, weight %e\n", i, Calgotmp[0][0], Calgotmp[0][1], Calgotmp[0][3], Calgotmp[2][2], Calgotmp[4][4], Calgotmp[5][5], Wgt[i] );
+		  //printf("phase %d, C total %f %f %f %f %f %f, weight %e\n", i, Calgo[0][0], Calgo[0][1], Calgo[0][3], Calgo[2][2], Calgo[4][4], Calgo[5][5], Wgt[i] );
+                  if(withDamage)
+                  {
+	            statev[pos_p]+=statev[idsdv_i[i] + (ph_mat[i])->get_pos_p()]*Wgt[i];
+#ifdef NONLOCALGMSH
+	            statev[get_pos_damagefornonlocal()]+=statev[idsdv_i[i] + (ph_mat[i])->get_pos_damagefornonlocal()]*Wgt[i];
+#endif                    
+                  }
+            }
+	}
+	//TO DO: call damage box, if any
+	k=pos_C;
+	for(int i=0;i<6;i++){
+	  for(j=i;j<6;j++){
+	    statev[k++] = Cref[i][j];
+	  }
+	}
+        k=pos_strs;
+	for(i=0;i<6;i++){
+          statev[k++] = strs[i];
+        } 
+        if(withDamage)
+        {
+          clength->creat_cg(statev_n, pos_p, c_g);      
+        }
+        //printf("C11 %e, C22 %e ,C33 %e\n", Calgo[0][0], Calgo[1][1],Calgo[2][2]);
+    
+        return error;
+    
+ 
+#if 0    
+    FILE* fichier = NULL;
+    
+    fichier = fopen("Calgor.xyz", "r+");
+    for(i=0;i<6;i++){
+      for(j=0;j<6;j++){
+        fprintf(fichier,"%lf  ", Calgo[i][j]);
+      }
+      fprintf(fichier,"\n");
+    }
+#endif
+//delete(fichier);
 } 
 void MT_VT_Material::get_refOp(double* statev_n, double** C, int kinc, int kstep){
 
@@ -4588,6 +13513,11 @@ ANEL_Material::ANEL_Material(double* props, int idmat):Material(props, idmat){
 	pos_dstrn=12;
 
         pos_p =0; // for the input of clength->creat_cg, as damage is not implemented in this material
+        v12 = anpr[3];
+        v13 = anpr[4];
+        E1 = anpr[0];
+        E3 = anpr[2];
+        v31 = v13*E3/E1;
 	
 	dam = init_damage(props,iddam);
 	if(dam){
@@ -4604,6 +13534,7 @@ ANEL_Material::ANEL_Material(double* props, int idmat):Material(props, idmat){
 		pos_dFd_bar = pos_dam + dam->get_pos_dFd_bar();
 		pos_locFd = pos_dam + dam->get_pos_locFd();
 		nsdv += dam->get_nsdv();
+                dDeldD = 2.0*(1.0+v12)*v13*v13*E3/E1;
 	}
         else{
                 pos_NFiber = 0;
@@ -4611,15 +13542,27 @@ ANEL_Material::ANEL_Material(double* props, int idmat):Material(props, idmat){
                 pos_Fd_bar = 0;
 		pos_dFd_bar = 0;
                 pos_locFd = 0;
+                dDeldD = 0.0;
 
         }
-	
+
+	if (euler[0] > 180.0+1.0e-6){
+            pos_euler = nsdv;
+            nsdv += 3;
+        }
+        else{
+            pos_euler = 0;
+        }
 
         clength = init_clength(props,idclength);
         cl = sqrt(props[idclength+3]);
 
+#ifdef NONLOCALGMSH
+        if(idclength==0) this->setLocalDamage();
+#endif
 }
 
+
 //destructor
 ANEL_Material::~ANEL_Material(){
 	
@@ -4642,6 +13585,14 @@ void ANEL_Material::print(){
 	if(dam){ dam->print();}
 	
 }
+
+void ANEL_Material::setEuler(double e1, double e2, double e3)
+{
+  euler[0] = e1;
+  euler[1] = e2;
+  euler[2] = e3;
+}
+
 #ifdef NONLOCALGMSH
 int ANEL_Material::get_pos_currentplasticstrainfornonlocal() const {return -1;}
 int ANEL_Material::get_pos_effectiveplasticstrainfornonlocal() const {return -1;}
@@ -4683,13 +13634,374 @@ double ANEL_Material::getPlasticEnergy (double* statev)
 //constbox
 int ANEL_Material::constbox(double* dstrn, double* strs_n,  double* strs, double* statev_n, double* statev, double** Cref, double*** dCref, double* tau, double** dtau, double** Calgo, double alpha, double* dpdE, double* strs_dDdp_bar,double *Sp_bar, double** c_g, double* dFd_d_bar, double* dstrs_dFd_bar, double *dFd_dE, double** c_gF, double* dpdFd, double* dFddp, int kinc, int kstep, double dt){
 
+	static double* strn;
+	static double* strs_ef;
+	static double* dDdE;
+	static double* dDdE_L;
+        static double* eul0;
+        static double* _euler;
+        static double** R66;
+        static double** strs_dDdE;
+        double  dDdp_bar;
+        double D;
+        int i, j, error;
+
+	static bool initialized = false;
+        error=0;
+        if(!initialized){
+          mallocvector(&strn,6);
+          mallocvector(&strs_ef,6);
+          mallocvector(&dDdE,6);
+          mallocvector(&dDdE_L,6);
+          mallocvector(&eul0,3);
+          mallocvector(&_euler,3);
+          mallocmatrix(&R66,6,6);
+          mallocmatrix(&strs_dDdE,6,6);
+          initialized = true;
+        }
+        cleartens2(strn);
+        cleartens2(strs_ef);
+        cleartens2(dDdE);
+        cleartens2(dDdE_L);
+        cleartens4(R66);
+        cleartens4(strs_dDdE);
+        for(i =0; i< 3; i++){
+            eul0[i] = 0.0;
+            _euler[i] = 0.0;
+        }
 
-  return (1);
+        if(pos_euler != 0){
+            _euler[0] = statev_n[pos_euler];   
+            _euler[1] = statev_n[pos_euler+1];  
+            _euler[2] = statev_n[pos_euler+2];  
+	    copyvect(_euler, &(statev[pos_euler]),3);
+        }
+        else{
+            _euler[0] = euler[0];   
+            _euler[1] = euler[1];  
+            _euler[2] = euler[2];   
+        }
+
+	addtens2(1., statev_n, 1., dstrn, statev); 
+        if(dam){
+	    compute_AnisoOperator(anpr, eul0, Calgo);
+            //---------------------------------------
+            copyvect(&(statev[0]), strn, 6);   
+            eul_mat(_euler, R66);              
+            rot2(R66, strn, &(statev[0]));
+            dam->damagebox(statev_n, statev, pos_strn, pos_strs, pos_dam, Calgo, dDdE_L, &dDdp_bar, 1., kinc, kstep); 
+            D = statev[pos_dam]; 
+
+            transpose(R66,R66,6,6); 			//transpose rotation matrix for inverse transformation
+            rot2(R66,dDdE_L,dDdE);
+         }  
+         else{
+            D = 0.0;
+         }   
+	 addtens2(1., statev_n, 1., dstrn, statev); 
+	 //compute reference and algorithmic operators (in global coordinates)
+	 compute_AnisoOperator(anpr, _euler, Calgo);
+	 copymatr(Calgo,Cref,6,6);
+
+	 //compute new stress
+	 contraction42(Calgo,&(statev[0]),strs_ef);           
+         for(i=0;i<6;i++) strs[i] = strs_ef[i]*(1.0-D);
+               
+	//update state variables
+	copyvect(strs, &(statev[6]),6);
+	copyvect(dstrn, &(statev[12]),6);
+
+        if(dam){   
+            for(i=0;i<6;i++){
+                for(j=0;j<6;j++){
+                     strs_dDdE[i][j]=strs_ef[i]*dDdE[j]; 
+	        }        
+            }    
+            // add extra item on Calgo to conside the damage ( stress*dDdE)
+            addtens4 ((1.-D), Calgo, -1.0, strs_dDdE, Calgo);
+        }
+
+	//TO DO: call damage box, if dam!=NULL
+
+        clength->creat_cg(statev_n, pos_p, c_g);     //*********add by wu ling 
+        return error;
 }
 
-int ANEL_Material::constboxSecantMixte(double* dstrn, double* strs_n,  double* strs, double* statev_n, double* statev, double **Calgo, double** Csd, double*** dCsd, double** dCsdp_bar, double* dnu, double& dnudp_bar, double alpha, double* dpdE, double* dstrsdp_bar, double** c_g, int kinc, int kstep, double dt, bool forceZero, bool forceRes)
-{
-  return (1);
+int ANEL_Material::constboxSecantMixte(double* dstrn, double* strs_n,  double* strs, double* statev_n, double* statev, double **Calgo, double** Csd, double*** dCsd, double** dCsdp_bar, double* dnu, double& dnudp_bar, double alpha, double* dpdE, double* dstrsdp_bar, double** c_g, int kinc, int kstep, double dt, bool forceZero, bool forceRes){
+      
+        static double* strn;
+        static double* strn_n;
+	static double* strs_ef;
+	static double* dDdE;
+	static double* dDdE_L;
+        static double* eul0;
+        static double* _euler;
+        static double** R66;
+        static double** dC_dD_L;
+        static double** dC_dD;
+        static double** strs_dDdE;
+        static double** CI0;
+        double  dDdFd_bar;
+        double D,tmp,tmpn;
+        static double* vec;
+        static double* vec_n;
+        static double** ddC_ddD_L;
+        static double** ddC_ddD;
+        int i, j, k,error;
+        double Gc;
+        double eps=1.0e20;
+        double Ke = 0.0;
+        double Fe = 0.0;  
+	static double* anparm;
+
+	static bool initialized = false;
+        error=0;
+        if(!initialized){
+          mallocvector(&strn,6);
+          mallocvector(&strn_n,6);
+          mallocvector(&strs_ef,6);
+          mallocvector(&dDdE,6);
+          mallocvector(&dDdE_L,6);
+          mallocvector(&eul0,3);
+          mallocvector(&_euler,3);
+          mallocmatrix(&R66,6,6);
+          mallocmatrix(&dC_dD,6,6);
+          mallocmatrix(&dC_dD_L,6,6);
+          mallocmatrix(&strs_dDdE,6,6);
+          mallocvector(&anparm,9);
+          mallocmatrix(&CI0,6,6);
+          mallocvector(&vec,6);
+          mallocvector(&vec_n,6);
+          mallocmatrix(&ddC_ddD_L,6,6);
+          mallocmatrix(&ddC_ddD,6,6);
+          initialized = true;
+        }
+        cleartens2(strn);
+        cleartens2(strn_n);
+        cleartens2(strs_ef);
+        cleartens2(dDdE);
+        cleartens2(dDdE_L);
+        cleartens4(R66);
+        cleartens4(dC_dD);
+        cleartens4(dC_dD_L);
+        cleartens4(strs_dDdE);
+        cleartens4(CI0);
+        cleartens2(vec);
+        cleartens2(vec_n);
+        cleartens4(ddC_ddD_L);
+        cleartens4(ddC_ddD);
+
+        for(i =0; i< 3; i++){
+            eul0[i] = 0.0;
+            _euler[i] = 0.0;
+        }
+
+        if(pos_euler != 0){
+            _euler[0] = statev_n[pos_euler];   
+            _euler[1] = statev_n[pos_euler+1];  
+            _euler[2] = statev_n[pos_euler+2];  
+	    copyvect(_euler, &(statev[pos_euler]),3);
+        }
+        else{
+            _euler[0] = euler[0];   
+            _euler[1] = euler[1];  
+            _euler[2] = euler[2];   
+        }
+
+        for(i =0; i< 9; i++) anparm[i] = 0.0;
+  
+        cleartens2(dpdE);
+        cleartens2(dstrsdp_bar);
+        cleartens4(dCsdp_bar);
+        for(i=0;i<6;i++){
+	   for(j=0;j<6;j++){
+              for(k=0;k<6;k++){
+                 dCsd[i][j][k] = 0.0;
+              }
+           }
+        }
+        dnudp_bar = 0.0;
+
+	addtens2(1., statev_n, 1., dstrn, statev); 
+        if(dam){
+
+	    compute_AnisoOperator(anpr, eul0, Calgo);
+            copyvect(&(statev[0]), strn, 6);   
+            eul_mat(_euler, R66);  
+            rot2(R66, strn, &(statev[0]));
+
+            Gc = dam->get_Gc();
+       //----Local damage  **********************************************************
+            if(Gc<=0.0) {
+               dam->damagebox(statev_n, statev, pos_strn, pos_strs, pos_dam, Calgo, dDdE_L, &dDdFd_bar, 1., kinc, kstep); 
+              // useless statev_n[pos_locFd] = statev_n[pos_locFd]*cl;
+               D = statev[pos_dam];
+          // change definition of Csd-----------------------------------
+               for(int i=0; i < 9; i++) anparm[i]= anpr[i];
+               anparm[2]= (1.0-D)*anparm[2];
+               compute_AnisoOperator(anparm, eul0, Csd);
+
+          // in local coordinata---------------
+               double v31D = v31*(1.0-D);
+               double Delta_D = (1.0+v12)*(1.0-v12-2.0*v13*v31D);
+
+               dC_dD_L[0][0] = E1*v13*v31/Delta_D - E1*(1.0-v13*v31D)*dDeldD/Delta_D/Delta_D;
+               dC_dD_L[0][1] = -E1*v13*v31/Delta_D - E1*(v12+v13*v31D)*dDeldD/Delta_D/Delta_D;
+               dC_dD_L[0][2] = -E3*(v13+v12*v13)/Delta_D - E3*(1.0-D)*(v13+v12*v13)*dDeldD/Delta_D/Delta_D;
+               dC_dD_L[2][2] = -E3*(1.0-v12*v12)/Delta_D - E3*(1.0-D)*(1.0-v12*v12)*dDeldD/Delta_D/Delta_D;
+
+               dC_dD_L[1][0] = dC_dD_L[0][1];
+               dC_dD_L[1][1] = dC_dD_L[0][0];
+               dC_dD_L[1][2] = dC_dD_L[0][2];
+               dC_dD_L[2][0] = dC_dD_L[0][2];
+               dC_dD_L[2][1] = dC_dD_L[0][2];
+
+               for(i=0;i<6;i++){
+		   for(j=0;j<6;j++){
+                     for(k=0;k<6;k++){
+                          dCsd[i][j][k] = dC_dD_L[i][j]*dDdE_L[k];
+                     }
+                   }
+               }
+
+               cleartens4(strs_dDdE);
+               copymatr(Csd, strs_dDdE,6,6);
+            
+               for(j=0;j<6;j++){
+                   for(k=0;k<6;k++){
+                      for(i=0;i<6;i++){
+                           strs_dDdE[j][k] +=  statev[i]*dCsd[j][i][k];
+                     }
+                  }
+               }
+
+               transpose(R66,R66,6,6); 			//transpose rotation matrix for inverse transformation
+               rot4(R66,Csd,Calgo);
+	       copymatr(Calgo, Csd,6,6);
+               rot4(R66,strs_dDdE,Calgo);
+            }
+
+
+       //----nonLocal damage  **********************************************************
+            if(Gc>=1.0e-15){ 
+
+               dam->damagebox(statev_n, statev, pos_strn, pos_strs, pos_dam, Calgo, dDdE_L, &dDdFd_bar, 1., kinc, kstep); 
+               D = statev[pos_dam]; 
+               for(int i=0; i < 9; i++) anparm[i]= anpr[i];
+               anparm[2]= (1.0-D)*anparm[2];
+               compute_AnisoOperator(anparm, eul0, Csd);
+               contraction42(Calgo, &(statev[0]),vec); 
+
+               transpose(R66,R66,6,6); 			//transpose rotation matrix for inverse transformation
+               rot4(R66,Csd,Calgo);   
+	       copymatr(Calgo, Csd,6,6);
+
+               if(vec[2]>=0.0){
+
+                 // in local coordinata---------------
+                  double v31D = v31*(1.0-D);
+                  double Delta_D = (1.0+v12)*(1.0-v12-2.0*v13*v31D);
+
+                  dC_dD_L[0][0] = E1*v13*v31/Delta_D - E1*(1.0-v13*v31D)*dDeldD/Delta_D/Delta_D;
+                  dC_dD_L[0][1] = -E1*v13*v31/Delta_D - E1*(v12+v13*v31D)*dDeldD/Delta_D/Delta_D;
+                  dC_dD_L[0][2] = -E3*(v13+v12*v13)/Delta_D - E3*(1.0-D)*(v13+v12*v13)*dDeldD/Delta_D/Delta_D;
+                  dC_dD_L[2][2] = -E3*(1.0-v12*v12)/Delta_D - E3*(1.0-D)*(1.0-v12*v12)*dDeldD/Delta_D/Delta_D;
+
+                  dC_dD_L[1][0] = dC_dD_L[0][1];
+                  dC_dD_L[1][1] = dC_dD_L[0][0];
+                  dC_dD_L[1][2] = dC_dD_L[0][2];
+                  dC_dD_L[2][0] = dC_dD_L[0][2];
+                  dC_dD_L[2][1] = dC_dD_L[0][2];
+
+                  rot4(R66,dC_dD_L,dC_dD);
+    
+                  for(i=0;i<6;i++){
+	     	     for(j=0;j<6;j++){                     
+                         dCsdp_bar[i][j] = dC_dD[i][j]*dDdFd_bar;                // 1. dCsd/dFd
+                     }
+                  }
+
+                  for(i=0;i<6;i++){
+		     for(j=0;j<6;j++){                     
+                        dstrsdp_bar[i] +=  dCsdp_bar[i][j]*strn[j];              // 2.  dstress/dFd
+                     }
+                  }
+
+                  tmp = -0.5*cl/Gc;
+                  statev[pos_locFd] = 0.;
+                  for(i=0;i<6;i++) statev[pos_locFd] += dstrsdp_bar[i]*strn[i];                // local  dpsi/dFd 
+                  statev[pos_locFd] *= tmp; 
+
+                  tmp = -cl/Gc; 
+                  for(i=0;i<6;i++) dpdE[i] = dstrsdp_bar[i]*tmp;                     //  3. d[-l/Gc*dpsi/dFd]/dE
+ 
+
+                  ddC_ddD_L[0][0] = -2.0*E1*v13*v31/Delta_D/Delta_D*dDeldD + 2.0*E1*(1.0-v13*v31D)*dDeldD*dDeldD/Delta_D/Delta_D/Delta_D;
+                  ddC_ddD_L[0][1] = 2.0*E1*v13*v31/Delta_D/Delta_D*dDeldD + 2.0* E1*(v12+v13*v31D)*dDeldD*dDeldD/Delta_D/Delta_D/Delta_D;
+                  ddC_ddD_L[0][2] = 2.0*E3*(v13+v12*v13)/Delta_D/Delta_D*dDeldD + 2.0*E3*(1.0-D)*(v13+v12*v13)*dDeldD*dDeldD/Delta_D/Delta_D/Delta_D;
+                  ddC_ddD_L[2][2] = 2.0*E3*(1.0-v12*v12)/Delta_D/Delta_D*dDeldD + 2.0*E3*(1.0-D)*(1.0-v12*v12)*dDeldD*dDeldD/Delta_D/Delta_D/Delta_D;
+               
+                  double n;
+                  n = dam->get_exp_n();
+                  tmp=0.;
+                  tmp = -n*(n-1.0)*pow(1.0-statev[pos_Fd_bar],n-2.0); 
+                  ddC_ddD_L[0][0] = ddC_ddD_L[0][0]*dDdFd_bar*dDdFd_bar + dC_dD_L[0][0]*tmp;
+                  ddC_ddD_L[0][1] = ddC_ddD_L[0][1]*dDdFd_bar*dDdFd_bar + dC_dD_L[0][1]*tmp;
+                  ddC_ddD_L[0][2] = ddC_ddD_L[0][2]*dDdFd_bar*dDdFd_bar + dC_dD_L[0][2]*tmp;
+                  ddC_ddD_L[2][2] = ddC_ddD_L[2][2]*dDdFd_bar*dDdFd_bar + dC_dD_L[2][2]*tmp;
+                  ddC_ddD_L[1][0] = ddC_ddD_L[0][1];
+                  ddC_ddD_L[1][1] = ddC_ddD_L[0][0];
+                  ddC_ddD_L[1][2] = ddC_ddD_L[0][2];
+                  ddC_ddD_L[2][0] = ddC_ddD_L[0][2];
+                  ddC_ddD_L[2][1] = ddC_ddD_L[0][2];
+
+                  //  derivatives of dissipation term to Fd_bar
+                  for(i=0;i<6;i++){
+                     vec[i] = 0.0;
+                     for(j=0;j<6;j++){                     
+                         vec[i] += ddC_ddD_L[i][j]*statev[j];
+                      }
+                  }
+
+		  for(j=0;j<6;j++) dnudp_bar += vec[j]*statev[j];
+                  dnudp_bar = -dnudp_bar*cl/Gc/2.0;                    // 4.  -l/Gc*dpsi/dFd
+
+                  if(statev_n[pos_dFd_bar] < 0.0 or D>=statev[get_pos_maxD()]){                      
+                      cleartens2(dstrsdp_bar);
+                      cleartens4(dCsdp_bar);                  
+                   }                
+                }
+              /*  if(statev_n[pos_dFd_bar] < 0.0){ 
+                   printf("here negative:, %f,%f\n",statev_n[pos_dFd_bar],statev[pos_Fd_bar]);
+                   //statev[pos_locFd] = statev_n[pos_locFd];
+                   Ke = -cl/Gc*eps;
+                   Fe = cl/Gc*eps*statev_n[pos_dFd_bar];
+                   
+                   dnudp_bar += Ke;
+                   statev[pos_locFd] -= Fe;
+                }*/
+              }
+
+         }
+         else{
+            D = 0.0;
+	    compute_AnisoOperator(anpr, _euler, Csd);
+	    copymatr(Csd, Calgo,6,6);
+            dnudp_bar =0.;
+            for(i=0;i<6;i++){
+              for(j=0;j<6;j++){                     
+                 dCsdp_bar[i][j] = 0.;
+              }
+            }
+         }  
+
+	//update state variables
+        addtens2(1., statev_n, 1., dstrn, statev);
+	contraction42(Csd,&(statev[0]),strs);  
+	copyvect(strs, &(statev[6]),6);
+	copyvect(dstrn, &(statev[12]),6);
+        clength->creat_cg(statev_n, pos_p, c_g);   
+        return error;
 }
 
 
@@ -4699,7 +14011,61 @@ int ANEL_Material::constboxSecantMixte(double* dstrn, double* strs_n,  double* s
 
 int ANEL_Material::constbox_2order(int mtx, double *DE, double* dstrn, double* strs, double* statev_n, double* statev,  double **Calgo, Lcc* LCC, YieldF* YF, double** c_g, int kinc, int kstep, double dt){
 
-   return (1);
+        int i, error;
+        static double* dstrs;
+        static double* _euler;
+	static bool initialized = false;
+        error=0;
+        if(!initialized){
+          mallocvector(&dstrs,6);
+          mallocvector(&_euler,3);
+          initialized = true;
+        }
+
+        for(i =0; i< 3; i++) _euler[i] = 0.0;
+        
+        if(pos_euler != 0){
+            _euler[0] = statev_n[pos_euler];   
+            _euler[1] = statev_n[pos_euler+1];  
+            _euler[2] = statev_n[pos_euler+2];  
+	    copyvect(_euler, &(statev[pos_euler]),3);
+        }
+        else{
+            _euler[0] = euler[0];   
+            _euler[1] = euler[1];  
+            _euler[2] = euler[2];   
+        }
+
+        cleartens2(dstrs);
+	//compute reference and algorithmic operators (in global coordinates)
+	compute_AnisoOperator(anpr, _euler, Calgo);
+
+	//compute new stress
+	contraction42(Calgo,dstrn,dstrs);
+	addtens2(1.,&(statev_n[pos_strs]), 1.,dstrs,strs);
+
+	
+       //clean structure YielF YF before update its values.
+       // for elastic material YF->f...=0, If there is damage in the material YF->dp...will be update
+          YF->trial=0.0;          // no plasticity
+          YF->f=0.0;		  // value of yielding function
+	  YF->dfdmu[0] = YF->dfdmu[1] = YF->dfdp_bar= 0.0;	
+          for(i=0;i<6;i++){
+                     YF->dfdstrn[i]=0.0;            //  derivatives w.r. incremental strain of composite
+                     YF->dpdstrn[i]=0.0;     
+          }
+	  YF->dpdmu[0] = YF->dpdmu[1] = YF->dpdp_bar= 0.0;    //if there is damage	this value will be updated
+
+
+        //update state variables
+	addtens2(1., statev_n, 1., dstrn, statev); 
+	copyvect(strs, &(statev[pos_strs]),6);
+	copyvect(dstrn, &(statev[pos_dstrn]),6);
+
+	//TO DO: call damage box, if dam!=NULL
+
+        clength->creat_cg(statev_n, pos_p, c_g);       //*********add by wu ling 
+        return error;
 }
 
 //end of consbox_2order
@@ -4709,13 +14075,14 @@ int ANEL_Material::constbox_2order(int mtx, double *DE, double* dstrn, double* s
 // = anisotropic elastic operator in any case
 void ANEL_Material::get_refOp(double* statev, double** C, int kinc, int kstep){
 
-	get_elOp(C);
+	get_elOp(statev, C);
 }
-
+                
 void ANEL_Material::get_elOp(double** Cel){
-
+       
 	compute_AnisoOperator(anpr, euler,Cel);
 }
+
 void ANEL_Material::get_elOp(double* statev, double** Cel){
         if(pos_euler != 0){         
             compute_AnisoOperator(anpr, &(statev[pos_euler]),Cel);
@@ -4724,27 +14091,32 @@ void ANEL_Material::get_elOp(double* statev, double** Cel){
             compute_AnisoOperator(anpr, euler,Cel);
         }
 }
+
+
 void ANEL_Material::get_elOD(double* statev, double** Cel)
 {
-     get_elOp(Cel);
-     if(dam)
-     {
-       double damage = statev[get_pos_dam()];
-       for(int i=0; i < 6; i++)
-         for(int j=0; j < 6; j++)
-           Cel[i][j]*=1.-damage;
-    }
+     static double *anparm;
+     static bool initialized = false;
+     if(!initialized){
+         mallocvector(&anparm,9);
+         initialized = true;
+     }
+
+     for(int i=0; i < 9; i++) anparm[i]= anpr[i];
+     if(dam){ 
+         double D = statev[get_pos_dam()];
+         anparm[2]= (1.0-D)*anparm[2];
+     }
+     if ( pos_euler != 0 ){
+         compute_AnisoOperator(anparm, &statev[pos_euler], Cel);
+     }
+     else{   
+         compute_AnisoOperator(anparm, euler,Cel);
+     }  
 }
 
 void ANEL_Material::unload_step(double* dstrn, double* strs_n, double* statev_n, int kinc, int kstep){
 
        printf("unload_step not implemented for ANEL material\n");
 }
-
-void ANEL_Material::setEuler(double e1, double e2, double e3)
-{
-  euler[0] = e1;
-  euler[1] = e2;
-  euler[2] = e3;
-}
 #endif
diff --git a/NonLinearSolver/materialLaw/material.h b/NonLinearSolver/materialLaw/material.h
index 29b90362c91f1e401b005007df130f5ef3c1f9cb..b3d1c7ca479784c26e76008fc9529115f7b56d3b 100644
--- a/NonLinearSolver/materialLaw/material.h
+++ b/NonLinearSolver/materialLaw/material.h
@@ -6,6 +6,7 @@
 #include "clength.h"
 #include "lccfunctions.h"
 #include "elasticlcc.h"
+#include <vector>
 
 
 #ifdef NONLOCALGMSH
@@ -22,6 +23,8 @@ class Material{
 		Damage* dam;
 		int pos_dam;	//position of damage state variables in statev vector
 
+		bool localDamage;
+
                 int pos_p;
 
                 Clength* clength;
@@ -34,6 +37,7 @@ class Material{
 		Material(double* props, int idmat){
 			constmodel = (int) props[idmat];
                         evaluateStiffness = true;
+                        localDamage = false;
 		}
 		virtual ~Material(){ ; }
 		inline int get_constmodel(){  return constmodel; }
@@ -137,8 +141,14 @@ double E, double nu, int htype, double sy0, double hexp, double hmod1, double hm
                 virtual double get_mtx_MaxD(double *statev) const {return -1.; }
                 virtual void set_mtx_MaxD(double *statev, double Dmax) {}
                 
-                virtual void setEuler(double e1, double e2, double e3);
-                
+                virtual std::vector<double> &getEuler(std::vector<double> &_euler) {return _euler;}
+                virtual int getNPatch() const {return -1;}
+                virtual int get_mat_NPatch(int matNb) const {return -1;}
+		virtual int get_mat_constmodel(int matNb) const {return -1;}
+		virtual int get_submat_constmodel(int matNb, int submatNb) const {return -1;}
+		
+		virtual void setEuler(double e1, double e2, double e3);
+
 #ifdef NONLOCALGMSH
 		virtual int get_pos_currentplasticstrainfornonlocal() const = 0;
 		virtual int get_pos_effectiveplasticstrainfornonlocal() const = 0;
@@ -160,54 +170,103 @@ double E, double nu, int htype, double sy0, double hexp, double hmod1, double hm
 		virtual void get_elOp_mtx(double** Cel);
 		virtual void get_elOp_icl(double** Cel);
                 virtual double get_vfI();
-#endif
-		
-    		// some new function
-		virtual int getNPatch() const {return -1;}
-		virtual int get_mat_NPatch(int matNb) const {return -1;}
-		virtual int get_mat_constmodel(int matNb) const {return -1;}
-		virtual int get_submat_constmodel(int matNb, int submatNb) const {return -1;}
-		virtual void populateMaxD(double *statev, double Dmax_Inc, double Dmax_Mtx) const{};
+                
+		virtual void setLocalDamage() {
+			localDamage=true;
+			if(dam) dam->setLocalDamage();
+		}
 
+		virtual void setNonLocalDamage() {
+			localDamage=false;
+			if(dam) dam->setNonLocalDamage();
+		}
+		
+		virtual int get_pos_mat_inc_maxD(int matNb) const {return -1;}
+		virtual int get_pos_mat_mtx_maxD(int matNb) const {return -1;}
+                virtual void populateMaxD(double *statev, double Dmax_Inc, double Dmax_Mtx) const {}
+
+
+		// for VT or LAM_2PLY case (VM, LVM or VLM)
+                virtual int get_pos_mat_strain(int matNb) const {return -1;}
+                virtual int get_pos_mat_stress(int matNb) const {return -1;}
+                virtual int get_pos_mat_Dam(int matNb) const {return -1;}
+                virtual int get_pos_mat_mtx_strain(int matNb) const {return -1;}
+                virtual int get_pos_mat_inc_strain(int matNb) const {return -1;}
+                virtual int get_pos_mat_mtx_stress(int matNb) const {return -1;}
+                virtual int get_pos_mat_inc_stress(int matNb) const {return -1;}
+                virtual int get_pos_mat_mtx_Dam(int matNb) const {return -1;}
+                virtual int get_pos_mat_inc_Dam(int matNb) const {return -1;}
+                
+                // for VT case (VM or VLM)
+                // for VLM case
+		// laminate euler angles
 		virtual std::vector<double> &getEulerVTLam(std::vector<double> &euler_lam, int grainNb) {return euler_lam;}
-
+		// for each VT grain
+		// strain
 		virtual int getPosStrnVTM0(int grainNb) const {return -1;}
 		virtual int getPosStrnVTMT(int grainNb) const {return -1;}
 		virtual int getPosStrnVTLam(int grainNb) const {return -1;}
+		// stress
 		virtual int getPosStrsVTM0(int grainNb) const {return -1.;}
 		virtual int getPosStrsVTMT(int grainNb) const {return -1;}
 		virtual int getPosStrsVTLam(int grainNb) const {return -1;}
+		// damage
                 virtual int getPosDamVTM0(int grainNb) const {return -1;}
+                // for each laminate ply in VT grains
+		// strain
 		virtual int getPosStrnVTLamM0(int grainNb) const {return -1;}
 		virtual int getPosStrnVTLamMT(int grainNb) const {return -1;}
+		// stress
 		virtual int getPosStrsVTLamM0(int grainNb) const {return -1;}
 		virtual int getPosStrsVTLamMT(int grainNb) const {return -1;}
+		// damage
 		virtual int getPosDamVTLamM0(int grainNb) const {return -1;}
+		// for each material phase
+		// strain
 		virtual int getPosStrnVTMTMtx(int grainNb) const {return -1;}
 		virtual int getPosStrnVTMTInc(int grainNb) const {return -1;}
 		virtual int getPosStrnVTLamMTMtx(int grainNb) const {return -1;}
 		virtual int getPosStrnVTLamMTInc(int grainNb) const {return -1;}
+		// stress
 		virtual int getPosStrsVTMTMtx(int grainNb) const {return -1;}
 		virtual int getPosStrsVTMTInc(int grainNb) const {return -1;}
 		virtual int getPosStrsVTLamMTMtx(int grainNb) const {return -1;}
 		virtual int getPosStrsVTLamMTInc(int grainNb) const {return -1;}
+		// damage
 		virtual int getPosDamVTMTMtx(int grainNb) const {return -1;}
 		virtual int getPosDamVTMTInc(int grainNb) const {return -1;}
 		virtual int getPosDamVTLamMTMtx(int grainNb) const {return -1;}
 		virtual int getPosDamVTLamMTInc(int grainNb) const {return -1;}
+                
+                
+                // for LAM_2PLY case (LVM)
+                // for each laminate ply
+                // strain
 		virtual int getPosStrnLamM0(int laminateNb) const {return -1;}
 		virtual int getPosStrnLamVT(int laminateNb) const {return -1;}
+		// stress
 		virtual int getPosStrsLamM0(int laminateNb) const {return -1;}
 		virtual int getPosStrsLamVT(int laminateNb) const {return -1;}
+		// damage
 		virtual int getPosDamLamM0(int laminateNb) const {return -1;}
+		// for each MT grain in VT ply
+		// strain
 		virtual int getPosStrnLamVTMT(int grainNb) const {return -1;}
+		// stress
 		virtual int getPosStrsLamVTMT(int grainNb) const {return -1;}
+		// for each material phase
+		// strain
 		virtual int getPosStrnLamVTMTMtx(int grainNb) const {return -1;}
 		virtual int getPosStrnLamVTMTInc(int grainNb) const {return -1;}
+		// stress
 		virtual int getPosStrsLamVTMTMtx(int grainNb) const {return -1;}
 		virtual int getPosStrsLamVTMTInc(int grainNb) const {return -1;}
+		// damage
 		virtual int getPosDamLamVTMTMtx(int grainNb) const {return -1;}
 		virtual int getPosDamLamVTMTInc(int grainNb) const {return -1;}
+#endif
+
+
 };
 
 //Linear elastic material
@@ -321,7 +380,7 @@ class EP_Stoch_Material : public Material{
 		double _E,_nu,_sy0;
 		int htype;
 		double _hmod1, _hmod2, _hp0, _hexp;
-                int pos_E, pos_nu, pos_sy0, alpha_DP, m_DP, nup;
+                int pos_E, pos_nu, pos_sy0, _alpha_DP, _m_DP, _nup;
                 int pos_hmod1, pos_hmod2, pos_hp0, pos_hexp;
                 int pos_DamParm1, pos_DamParm2, pos_DamParm3;
 		int pos_pstrn, pos_dp, pos_twomu, pos_eqstrs;
@@ -434,10 +493,40 @@ double* dnu, double &dnudp_bar, double alpha, double* dpdE, double* dstrsdp_bar,
 class VT_Material : public Material{
 
 	private:
-		int Nph;					//number of phases in the composite
+		int NGrain;					//number of grains
 		Material** mat;		//array of pointers on Materials
-		double* vf;				//array of volume fraction of each phase
-			
+		double* vf;				//array of volume fraction of each grain
+				
+#ifdef NONLOCALGMSH
+		// for VT case (VM or VLM)
+		// for VLM case
+		// laminate euler angles
+		std::vector<double> euler_vt_lam;
+		// for each VT grain
+		// strain
+		std::vector<int> pos_strn_vt_m0, pos_strn_vt_mt, pos_strn_vt_lam;
+		// stress
+		std::vector<int> pos_strs_vt_m0, pos_strs_vt_mt, pos_strs_vt_lam;
+		// damage
+		std::vector<int> pos_dam_vt_m0;
+		// for each laminate ply in VT grains
+		// strain
+		std::vector<int> pos_strn_vt_lam_m0, pos_strn_vt_lam_mt;
+		// stress
+		std::vector<int> pos_strs_vt_lam_m0, pos_strs_vt_lam_mt;
+		// damage
+		std::vector<int> pos_dam_vt_lam_m0;
+		// for each material phase
+		// strain
+		std::vector<int> pos_strn_vt_mt_mtx, pos_strn_vt_mt_inc;
+		std::vector<int> pos_strn_vt_lam_mt_mtx, pos_strn_vt_lam_mt_inc;
+		// stress
+		std::vector<int> pos_strs_vt_mt_mtx, pos_strs_vt_mt_inc;
+		std::vector<int> pos_strs_vt_lam_mt_mtx, pos_strs_vt_lam_mt_inc;
+		// damage
+		std::vector<int> pos_dam_vt_mt_mtx, pos_dam_vt_mt_inc;
+		std::vector<int> pos_dam_vt_lam_mt_mtx, pos_dam_vt_lam_mt_inc;
+#endif
 
 	public:
 		
@@ -450,12 +539,257 @@ class VT_Material : public Material{
 		virtual void get_elOp(double** Cel);
 		virtual void get_elOD(double* statev, double** Cel);
                 virtual void unload_step(double* dstrn, double* strs_n, double* statev, int kinc, int kstep);
+
+                virtual int getNPatch() const {return NGrain;}
+                virtual int get_mat_NPatch(int grainNb) const {return mat[grainNb]->getNPatch();}                
+                virtual int get_mat_constmodel(int grainNb) const {return mat[grainNb]->get_constmodel();}
+                virtual int get_submat_constmodel(int grainNb, int laminateNb) const {return mat[grainNb]->get_mat_constmodel(laminateNb);}
+                             
 #ifdef NONLOCALGMSH
 		virtual int get_pos_currentplasticstrainfornonlocal() const;
 		virtual int get_pos_effectiveplasticstrainfornonlocal() const;
 		virtual int get_pos_damagefornonlocal() const;
                 virtual double getElasticEnergy (double* statev) ;
 		virtual double getPlasticEnergy (double* statev) ;
+		
+		/*virtual void setLocalDamage()
+		{
+                    Material::setLocalDamage();
+                    for(i=0;i<NGrain;i++){
+		        mat[i]->setLocalDamage();
+                    }
+                }*/
+                
+                virtual int get_pos_mat_inc_maxD(int grainNb) const {             
+                	int idsdv = 18;  // position in statev where the statev of the first phase start
+                	for(int i=0;i<grainNb;i++) {
+                		idsdv += mat[i]->get_nsdv();
+                	}
+                	
+			switch(mat[grainNb]->get_constmodel()){		                
+				case MTSecF:  // MFH Fisrst order secant
+					if(mat[grainNb]->get_pos_inc_maxD()>-1)  // MT-Inc phase
+						return (idsdv + mat[grainNb]->get_pos_inc_maxD());
+					return -1;
+					break;
+					
+				default:
+					return -1;
+					break;
+			}        
+                }
+                
+                virtual int get_pos_mat_mtx_maxD(int grainNb) const {             
+                	int idsdv = 18;  // position in statev where the statev of the first phase start
+                	for(int i=0;i<grainNb;i++) {
+                		idsdv += mat[i]->get_nsdv();
+                	}
+                	
+			switch(mat[grainNb]->get_constmodel()){		                
+				case EP:  // pure matrix
+		                	if(mat[grainNb]->get_pos_maxD()>-1)  // EP case
+		                		return (idsdv + mat[grainNb]->get_pos_maxD());
+		                	return -1;
+		                	break;
+				
+				case MTSecF:  // MFH Fisrst order secant
+					if(mat[grainNb]->get_pos_mtx_maxD()>-1)  // MT-Inc phase
+						return (idsdv + mat[grainNb]->get_pos_mtx_maxD());
+					return -1;
+					break;
+					
+				default:
+					return -1;
+					break;
+			}        
+                }
+            
+		// here we only work for the initial value, will not work to block damage evolution in the grain on the fly
+                virtual void populateMaxD(double *statev, double Dmax_Inc, double Dmax_Mtx) const {                    
+                	int idsdv = 18;  // position in statev where the statev of the first phase start
+                	for(int i=0;i<NGrain;i++) {
+                        	switch(mat[i]->get_constmodel()){
+                        		case EP:  // pure matrix
+                        			if (mat[i]->get_pos_maxD()>-1)
+		                		{
+		                    			statev[idsdv + mat[i]->get_pos_maxD()] = Dmax_Mtx;
+		                		}
+		                		break;
+		                		
+		                	case MTSecF:  // MFH First order secant
+		                		if(mat[i]->get_pos_inc_maxD()>-1)  // MT-Inc phase
+		                		{
+		                    			statev[idsdv + mat[i]->get_pos_inc_maxD()] = Dmax_Inc;
+		                		}
+		                		if(mat[i]->get_pos_mtx_maxD()>-1)  // MT-Mtx phase
+		                		{
+		                    			statev[idsdv + mat[i]->get_pos_mtx_maxD()] = Dmax_Mtx;
+		                		}
+		                		break;
+		                		
+		                	case LAM_2PLY:
+		                		for(int j=0;j<mat[i]->getNPatch();j++)
+		                		{
+		                			if(mat[i]->get_pos_mat_inc_maxD(j)>-1)  // LAM_2PLY-Inc phase
+		                			{
+		                    				statev[idsdv + mat[i]->get_pos_mat_inc_maxD(j)] = Dmax_Inc;
+		                			}
+		                			if(mat[i]->get_pos_mat_mtx_maxD(j)>-1)  // LAM_2PLY-Mtx phase
+		                			{
+		                    				statev[idsdv + mat[i]->get_pos_mat_mtx_maxD(j)] = Dmax_Mtx;
+		                			}
+		                		}
+		                		break;
+		                }
+		                
+		                idsdv += mat[i]->get_nsdv();
+		        }
+                }
+                
+                // for VT case (VM or VLM)
+                // for each VT grain
+                // strain
+                virtual int get_pos_mat_strain (int grainNb) const
+                {
+                    int idsdv = 18;  // position in statev where the statev of the first phase start
+                    for(int i=0;i<grainNb;i++){
+                        idsdv += mat[i]->get_nsdv();
+                    }
+		    return idsdv + mat[grainNb]->get_pos_strn();
+		}
+		// stress
+		virtual int get_pos_mat_stress (int grainNb) const
+                {
+                    int idsdv = 18;  // position in statev where the statev of the first phase start
+                    for(int i=0;i<grainNb;i++){
+                        idsdv += mat[i]->get_nsdv();
+                    }
+		    return idsdv + mat[grainNb]->get_pos_strs();
+		}
+		// damage
+		virtual int get_pos_mat_Dam (int grainNb) const
+                {
+                    if(mat[grainNb]->get_pos_damagefornonlocal()>-1){
+                        int idsdv = 18;  // position in statev where the statev of the first phase start
+                        for(int i=0;i<grainNb;i++){
+                            idsdv += mat[i]->get_nsdv();
+                        }
+		        return idsdv + mat[grainNb]->get_pos_damagefornonlocal();
+		    }
+		    else{
+		        return -1;
+		    }
+		}
+		// for each material phase
+		// strain
+		virtual int get_pos_mat_mtx_strain (int grainNb) const
+		{
+		    int idsdv = 18;  // position in statev where the statev of the first phase start
+                    for(int i=0;i<grainNb;i++){
+                        idsdv += mat[i]->get_nsdv();
+                    }
+		    return idsdv + mat[grainNb]->get_pos_mtx_strain();
+		}
+		virtual int get_pos_mat_inc_strain (int grainNb) const
+		{
+		    int idsdv = 18;  // position in statev where the statev of the first phase start
+                    for(int i=0;i<grainNb;i++){
+                        idsdv += mat[i]->get_nsdv();
+                    } 
+		    return idsdv + mat[grainNb]->get_pos_inc_strain();
+		}
+		// stress
+		virtual int get_pos_mat_mtx_stress (int grainNb) const
+		{
+		    int idsdv = 18;  // position in statev where the statev of the first phase start
+                    for(int i=0;i<grainNb;i++){
+                        idsdv += mat[i]->get_nsdv();
+                    }
+		    return idsdv + mat[grainNb]->get_pos_mtx_stress();
+		}
+		virtual int get_pos_mat_inc_stress (int grainNb) const
+		{
+		    int idsdv = 18;  // position in statev where the statev of the first phase start
+                    for(int i=0;i<grainNb;i++){
+                        idsdv += mat[i]->get_nsdv();
+                    }
+		    return idsdv + mat[grainNb]->get_pos_inc_stress();
+		}
+		// damage
+		virtual int get_pos_mat_mtx_Dam (int grainNb) const
+		{
+		    if(mat[grainNb]->get_pos_mtx_Dam()>-1){
+                        int idsdv = 18;  // position in statev where the statev of the first phase start
+                        for(int i=0;i<grainNb;i++){
+                            idsdv += mat[i]->get_nsdv();
+                        }
+		        return idsdv + mat[grainNb]->get_pos_mtx_Dam();
+		    }
+		    else{
+		        return -1;
+		    }
+		}
+		virtual int get_pos_mat_inc_Dam (int grainNb) const
+		{
+		    if(mat[grainNb]->get_pos_inc_Dam()>-1){
+                        int idsdv = 18;  // position in statev where the statev of the first phase start
+                        for(int i=0;i<grainNb;i++){
+                            idsdv += mat[i]->get_nsdv();
+                        }
+		        return idsdv + mat[grainNb]->get_pos_inc_Dam();
+		    }
+		    else{
+		        return -1;
+		    }
+		}
+
+		// for VT case (VM or VLM)
+		// for VLM case
+		// laminate euler angles
+		virtual std::vector<double> &getEulerVTLam(std::vector<double> &euler_lam, int grainNb)
+		{
+			euler_lam.clear();
+			euler_lam.emplace_back(euler_vt_lam[0+grainNb*3]);
+			euler_lam.emplace_back(euler_vt_lam[1+grainNb*3]);
+			euler_lam.emplace_back(euler_vt_lam[2+grainNb*3]);
+			return euler_lam;
+		}
+		// for each VT grain
+		// strain
+		virtual int getPosStrnVTM0(int grainNb) const {return (int)pos_strn_vt_m0[grainNb];}
+		virtual int getPosStrnVTMT(int grainNb) const {return (int)pos_strn_vt_mt[grainNb];}
+		virtual int getPosStrnVTLam(int grainNb) const {return (int)pos_strn_vt_lam[grainNb];}
+		// stress
+		virtual int getPosStrsVTM0(int grainNb) const {return (int)pos_strs_vt_m0[grainNb];}
+		virtual int getPosStrsVTMT(int grainNb) const {return (int)pos_strs_vt_mt[grainNb];}
+		virtual int getPosStrsVTLam(int grainNb) const {return (int)pos_strs_vt_lam[grainNb];}
+		// damage
+		virtual int getPosDamVTM0(int grainNb) const {return (int)pos_dam_vt_m0[grainNb];}
+		// for each laminate ply in VT grains
+		// strain
+		virtual int getPosStrnVTLamM0(int grainNb) const {return (int)pos_strn_vt_lam_m0[grainNb];}
+		virtual int getPosStrnVTLamMT(int grainNb) const {return (int)pos_strn_vt_lam_mt[grainNb];}
+		// stress
+		virtual int getPosStrsVTLamM0(int grainNb) const {return (int)pos_strs_vt_lam_m0[grainNb];}
+		virtual int getPosStrsVTLamMT(int grainNb) const {return (int)pos_strs_vt_lam_mt[grainNb];}
+		// damage
+		virtual int getPosDamVTLamM0(int grainNb) const {return (int)pos_dam_vt_lam_m0[grainNb];}
+                // for each material phase
+                // strain
+                virtual int getPosStrnVTMTMtx(int grainNb) const {return (int)pos_strn_vt_mt_mtx[grainNb];}
+                virtual int getPosStrnVTMTInc(int grainNb) const {return (int)pos_strn_vt_mt_inc[grainNb];}
+                virtual int getPosStrnVTLamMTMtx(int grainNb) const {return (int)pos_strn_vt_lam_mt_mtx[grainNb];}
+                virtual int getPosStrnVTLamMTInc(int grainNb) const {return (int)pos_strn_vt_lam_mt_inc[grainNb];}
+                // stress
+                virtual int getPosStrsVTMTMtx(int grainNb) const {return (int)pos_strs_vt_mt_mtx[grainNb];}
+                virtual int getPosStrsVTMTInc(int grainNb) const {return (int)pos_strs_vt_mt_inc[grainNb];}
+                virtual int getPosStrsVTLamMTMtx(int grainNb) const {return (int)pos_strs_vt_lam_mt_mtx[grainNb];}
+                virtual int getPosStrsVTLamMTInc(int grainNb) const {return (int)pos_strs_vt_lam_mt_inc[grainNb];}
+                // damage
+                virtual int getPosDamVTMTMtx(int grainNb) const {return (int)pos_dam_vt_mt_mtx[grainNb];}
+                virtual int getPosDamVTMTInc(int grainNb) const {return (int)pos_dam_vt_mt_inc[grainNb];}
+                virtual int getPosDamVTLamMTMtx(int grainNb) const {return (int)pos_dam_vt_lam_mt_mtx[grainNb];}
+                virtual int getPosDamVTLamMTInc(int grainNb) const {return (int)pos_dam_vt_lam_mt_inc[grainNb];}
 #endif
 
 };  
@@ -464,12 +798,35 @@ class VT_Material : public Material{
 class LAM2Ply_Material : public Material{
 
 	private:
-		int Nph;					//number of phases in the composite
+		int NPly=2;					//number of plies
 		Material** mat;		//array of pointers on Materials
-		double* vf;				//array of volume fraction of each phase
+		double* vf;				//array of volume fraction of each ply
                 int idsdv_A, idsdv_B;
                 double* euler;
-                int pos_C;  
+                int pos_C;
+                
+#ifdef NONLOCALGMSH
+		// for LAM_2PLY case (LVM)
+		// for each laminate ply
+		// strain
+		std::vector<int> pos_strn_lam_m0, pos_strn_lam_vt;
+		// stress
+		std::vector<int> pos_strs_lam_m0, pos_strs_lam_vt;
+		// damage
+		std::vector<int> pos_dam_lam_m0;
+		// for each MT grain in VT ply
+		// strain
+		std::vector<int> pos_strn_lam_vt_mt;
+		// stress
+		std::vector<int> pos_strs_lam_vt_mt;
+		// for each material phase
+		// strain
+		std::vector<int> pos_strn_lam_vt_mt_mtx, pos_strn_lam_vt_mt_inc;
+		// stress
+		std::vector<int> pos_strs_lam_vt_mt_mtx, pos_strs_lam_vt_mt_inc;
+		// damage
+		std::vector<int> pos_dam_lam_vt_mt_mtx, pos_dam_lam_vt_mt_inc;
+#endif                
 	
 	public:
 		
@@ -482,13 +839,292 @@ class LAM2Ply_Material : public Material{
 		virtual void get_elOp(double** Cel);
 		virtual void get_elOD(double* statev, double** Cel);
                 virtual void unload_step(double* dstrn, double* strs_n, double* statev, int kinc, int kstep);
-                virtual int get_pos_C() const {	return pos_C; } 
+                virtual int get_pos_C() const {	return pos_C; }
+
+		virtual std::vector<double> &getEuler(std::vector<double> &_euler)
+		{
+			_euler.clear();
+			_euler.emplace_back(euler[0]);
+			_euler.emplace_back(euler[1]);
+			_euler.emplace_back(euler[2]);
+			return _euler;
+		}
+
+		virtual int getNPatch() const {return NPly;}
+		virtual int get_mat_NPatch(int laminateNb) const {return mat[laminateNb]->getNPatch();}
+		virtual int get_mat_constmodel(int laminateNb) const {return mat[laminateNb]->get_constmodel();}
+		virtual int get_submat_constmodel(int laminateNb, int grainNb) const {return mat[laminateNb]->get_mat_constmodel(grainNb);}
+
 #ifdef NONLOCALGMSH
 		virtual int get_pos_currentplasticstrainfornonlocal() const;
 		virtual int get_pos_effectiveplasticstrainfornonlocal() const;
 		virtual int get_pos_damagefornonlocal() const;
                 virtual double getElasticEnergy (double* statev) ;
 		virtual double getPlasticEnergy (double* statev) ;
+
+		/*virtual void setLocalDamage()
+		{
+                    Material::setLocalDamage();
+                    for(i=0;i<NPly;i++){
+		        mat[i]->setLocalDamage();
+                    }
+                }*/
+                
+                virtual int get_pos_mat_inc_maxD(int laminateNb) const {             
+                	int idsdv = 39;  // position in statev where the statev of the first phase start
+                	for(int i=0;i<laminateNb;i++) {
+                		idsdv += mat[i]->get_nsdv();
+                	}
+                	
+			switch(mat[laminateNb]->get_constmodel()){		                
+				case MTSecF:  // MFH Fisrst order secant
+					if(mat[laminateNb]->get_pos_inc_maxD()>-1)  // MT-Inc phase
+						return (idsdv + mat[laminateNb]->get_pos_inc_maxD());
+					return -1;
+					break;
+				
+				default:
+					return -1;
+					break;
+				
+			}        
+                }
+                
+                virtual int get_pos_mat_mtx_maxD(int laminateNb) const {             
+                	int idsdv = 39;  // position in statev where the statev of the first phase start
+                	for(int i=0;i<laminateNb;i++) {
+                		idsdv += mat[i]->get_nsdv();
+                	}
+                	
+			switch(mat[laminateNb]->get_constmodel()){		                
+				case EP:  // pure matrix
+		                	if(mat[laminateNb]->get_pos_maxD()>-1)  // EP case
+						return (idsdv + mat[laminateNb]->get_pos_maxD());
+		                	return -1;
+		                	break;
+				
+				case MTSecF:  // MFH Fisrst order secant
+					if(mat[laminateNb]->get_pos_mtx_maxD()>-1)  // MT-Inc phase
+						return (idsdv + mat[laminateNb]->get_pos_mtx_maxD());
+					return -1;
+					break;
+					
+				default:
+					return -1;
+					break;
+			}        
+                }
+                
+                // here we only work for the initial value, will not work to block damage evolution in the grain on the fly
+                virtual void populateMaxD(double *statev, double Dmax_Inc, double Dmax_Mtx) const {                    
+                	int idsdv = 39;  // position in statev where the statev of the first phase start
+                	for(int i=0;i<NPly;i++) {
+                        	switch(mat[i]->get_constmodel()){
+                        		case EP:  // pure matrix
+                        			if (mat[i]->get_pos_maxD()>-1)
+		                		{
+		                    			statev[idsdv + mat[i]->get_pos_maxD()] = Dmax_Mtx;
+		                		}
+		                		break;
+		                		
+		                	case MTSecF:  // MFH First order secant
+		                		if(mat[i]->get_pos_inc_maxD()>-1)  // MT-Inc phase
+		                		{
+		                    			statev[idsdv + mat[i]->get_pos_inc_maxD()] = Dmax_Inc;
+		                		}
+		                		if(mat[i]->get_pos_mtx_maxD()>-1)  // MT-Mtx phase
+		                		{
+		                    			statev[idsdv + mat[i]->get_pos_mtx_maxD()] = Dmax_Mtx;
+		                		}
+		                		break;
+		                		
+		                	case VT:
+		                		for(int j=0;j<mat[i]->getNPatch();j++)
+		                		{
+		                			if(mat[i]->get_pos_mat_inc_maxD(j)>-1)  // LAM_2PLY-Inc phase
+		                			{
+		                    				statev[idsdv + mat[i]->get_pos_mat_inc_maxD(j)] = Dmax_Inc;
+		                			}
+		                			if(mat[i]->get_pos_mat_mtx_maxD(j)>-1)  // LAM_2PLY-Mtx phase
+		                			{
+		                    				statev[idsdv + mat[i]->get_pos_mat_mtx_maxD(j)] = Dmax_Mtx;
+		                			}
+		                		}
+		                		break;
+		                }
+		                
+		                idsdv += mat[i]->get_nsdv();
+		        }
+                }
+
+		/*virtual std::vector<int> &get_allPos_mtx_maxD() const {
+                    std::vector<int> allPos_mtx_maxD;
+                    
+                    int idsdv = 39;  // position in statev where the statev of the first phase start                    
+		    for(int i=0;i<NPly;i++) {
+		        switch(mat[i]->get_constmodel()){
+		            case EP:  // pure matrix
+		                if (mat[i]->get_pos_maxD()>-1)  // EP case
+		                {
+		                    allPos_mtx_maxD.emplace_back(idsdv + mat[i]->get_pos_maxD());
+		                }
+		                break;
+		                
+		            case MTSecF:  // MFH Fisrst order secant
+		                if(mat[i]->get_pos_mtx_maxD()>-1)  // MT-Mtx phase
+		                {
+		                    allPos_mtx_maxD.emplace_back(idsdv + mat[i]->get_pos_mtx_maxD());
+		                }
+		                break;
+		                
+		            case VT:
+		                std::vector<int> allPos_mat_mtx_maxD = mat[i]->get_allPos_mtx_maxD();
+		                for(int j=0;j<allPos_mat_mtx_maxD.size();j++)  // LAM_2PLY-Mtx phase
+		                {
+		                    allPos_mtx_maxD.emplace_back(idsdv + allPos_mat_mtx_maxD[j]);
+		                }
+		                break;		        
+		        }
+		        		        
+		        idsdv += mat[i]->get_nsdv();
+		    }
+		    
+		    return allPos_mtx_maxD;
+                }
+
+                virtual void populateMaxD(double *statev, double Dmax_Inc, double Dmax_Mtx) const {
+                    std::vector<int> allPos_inc_maxD = this->get_allPos_inc_maxD();
+		    for(int i=0;i<allPos_inc_maxD.size();i++) {
+		        statev[allPos_inc_maxD[i]] = Dmax_Inc;
+		    }
+		    std::vector<int> allPos_mtx_maxD = this->get_allPos_mtx_maxD();
+		    for(int i=0;i<allPos_mtx_maxD.size();i++) {
+		        statev[allPos_mtx_maxD[i]] = Dmax_Mtx;
+		    }
+                }*/
+
+		// for LAM_2PLY case (LVM)
+                // for each laminate ply
+                // strain
+                virtual int get_pos_mat_strain (int laminateNb) const
+                {
+                    int idsdv = 39;  // position in statev where the statev of the first phase start
+                    for(int i=0;i<laminateNb;i++){
+                        idsdv += mat[i]->get_nsdv();
+                    }
+		    return idsdv + mat[laminateNb]->get_pos_strn();
+		}
+		// stress
+		virtual int get_pos_mat_stress (int laminateNb) const
+                {
+                    int idsdv = 39;  // position in statev where the statev of the first phase start
+                    for(int i=0;i<laminateNb;i++){
+                        idsdv += mat[i]->get_nsdv();
+                    }
+		    return idsdv + mat[laminateNb]->get_pos_strs();
+		}
+		// damage
+		virtual int get_pos_mat_Dam (int laminateNb) const
+                {
+                    if(mat[laminateNb]->get_pos_damagefornonlocal()>-1){
+                        int idsdv = 39;  // position in statev where the statev of the first phase start
+                        for(int i=0;i<laminateNb;i++){
+                            idsdv += mat[i]->get_nsdv();
+                        }
+		        return idsdv + mat[laminateNb]->get_pos_damagefornonlocal();
+		    }
+		    else{
+		        return -1;
+		    }
+		}
+		// for each material phase
+		// strain
+		virtual int get_pos_mat_mtx_strain (int laminateNb) const
+                {
+                    int idsdv = 39;  // position in statev where the statev of the first phase start
+                    for(int i=0;i<laminateNb;i++){
+                        idsdv += mat[i]->get_nsdv();
+                    }
+		    return idsdv + mat[laminateNb]->get_pos_mtx_strain();
+		}
+		virtual int get_pos_mat_inc_strain (int laminateNb) const
+                {
+                    int idsdv = 39;  // position in statev where the statev of the first phase start
+                    for(int i=0;i<laminateNb;i++){
+                        idsdv += mat[i]->get_nsdv();
+                    }
+		    return idsdv + mat[laminateNb]->get_pos_inc_strain();
+		}
+		// stress
+		virtual int get_pos_mat_mtx_stress (int laminateNb) const
+                {
+                    int idsdv = 39;  // position in statev where the statev of the first phase start
+                    for(int i=0;i<laminateNb;i++){
+                        idsdv += mat[i]->get_nsdv();
+                    }
+		    return idsdv + mat[laminateNb]->get_pos_mtx_stress();
+		}
+		virtual int get_pos_mat_inc_stress (int laminateNb) const
+                {
+                    int idsdv = 39;  // position in statev where the statev of the first phase start
+                    for(int i=0;i<laminateNb;i++){
+                        idsdv += mat[i]->get_nsdv();
+                    }
+		    return idsdv + mat[laminateNb]->get_pos_inc_stress();
+		}
+		// damage
+		virtual int get_pos_mat_mtx_Dam (int laminateNb) const
+                {
+                    if(mat[laminateNb]->get_pos_mtx_Dam()>-1){
+                        int idsdv = 39;  // position in statev where the statev of the first phase start
+                        for(int i=0;i<laminateNb;i++){
+                            idsdv += mat[i]->get_nsdv();
+                        }
+		        return idsdv + mat[laminateNb]->get_pos_mtx_Dam();
+		    }
+		    else{
+		        return -1;
+		    }
+		}
+		virtual int get_pos_mat_inc_Dam (int laminateNb) const
+                {
+                    if(mat[laminateNb]->get_pos_inc_Dam()>-1){
+                        int idsdv = 39;  // position in statev where the statev of the first phase start
+                        for(int i=0;i<laminateNb;i++){
+                            idsdv += mat[i]->get_nsdv();
+                        }
+		        return idsdv + mat[laminateNb]->get_pos_inc_Dam();
+		    }
+		    else{
+		        return -1;
+		    }
+		}
+		
+		// for LAM_2PLY case (LVM)
+		// for each laminate ply
+		// strain
+		virtual int getPosStrnLamM0(int laminateNb) const {return (int)pos_strn_lam_m0[laminateNb];}
+		virtual int getPosStrnLamVT(int laminateNb) const {return (int)pos_strn_lam_vt[laminateNb];}
+		// stress
+		virtual int getPosStrsLamM0(int laminateNb) const {return (int)pos_strs_lam_m0[laminateNb];}
+		virtual int getPosStrsLamVT(int laminateNb) const {return (int)pos_strs_lam_vt[laminateNb];}
+		// damage
+		virtual int getPosDamLamM0(int laminateNb) const {return (int)pos_dam_lam_m0[laminateNb];}
+		// for each MT grain in VT ply
+		// strain
+		virtual int getPosStrnLamVTMT(int grainNb) const {return (int)pos_strn_lam_vt_mt[grainNb];}
+		// stress
+		virtual int getPosStrsLamVTMT(int grainNb) const {return (int)pos_strs_lam_vt_mt[grainNb];}
+		// for each material phase
+		// strain
+		virtual int getPosStrnLamVTMTMtx(int grainNb) const {return (int)pos_strn_lam_vt_mt_mtx[grainNb];}
+		virtual int getPosStrnLamVTMTInc(int grainNb) const {return (int)pos_strn_lam_vt_mt_inc[grainNb];}
+		// stress
+		virtual int getPosStrsLamVTMTMtx(int grainNb) const {return (int)pos_strs_lam_vt_mt_mtx[grainNb];}
+		virtual int getPosStrsLamVTMTInc(int grainNb) const {return (int)pos_strs_lam_vt_mt_inc[grainNb];}
+		// damage
+		virtual int getPosDamLamVTMTMtx(int grainNb) const {return (int)pos_dam_lam_vt_mt_mtx[grainNb];}
+		virtual int getPosDamLamVTMTInc(int grainNb) const {return (int)pos_dam_lam_vt_mt_inc[grainNb];}
 #endif
 
 };  
@@ -518,37 +1154,39 @@ class MT_Material : public Material{
 		virtual void get_elOp(double** Cel);
 		virtual void get_elOD(double* statev, double** Cel);
                 virtual void unload_step(double* dstrn, double* strs_n, double* statev, int kinc, int kstep);
+
                 virtual int get_pos_inc_maxD() const {
-                   if(icl_mat->get_pos_maxD()>=0)	
+                   if(icl_mat->get_pos_maxD()>-1)
 	              return icl_mat->get_pos_maxD()+idsdv_i;
                    return -1;
                 }
                 virtual double get_inc_MaxD(double *statev) const {
-                   if(icl_mat->get_pos_maxD()>=0)	
+                   if(icl_mat->get_pos_maxD()>-1)
 	              return statev[get_pos_inc_maxD()];
                    return -1.;
                 }
-
                 virtual void set_inc_MaxD(double *statev, double Dmax)
                 {
-                   if(icl_mat->get_pos_maxD()>=0)	
+                   if(icl_mat->get_pos_maxD()>-1)
 	              statev[get_pos_inc_maxD()]=Dmax;
                 }
+
                 virtual int get_pos_mtx_maxD() const {
-                   if(mtx_mat->get_pos_maxD()>=0)	
+                   if(mtx_mat->get_pos_maxD()>-1)
 	              return mtx_mat->get_pos_maxD()+idsdv_m;
                    return -1;
                 }
                 virtual double get_mtx_MaxD(double *statev) const {
-                   if(mtx_mat->get_pos_maxD()>=0)	
+                   if(mtx_mat->get_pos_maxD()>-1)
 	              return statev[get_pos_mtx_maxD()];
                    return -1.;
                 }
                 virtual void set_mtx_MaxD(double *statev, double Dmax)
                 {
-                   if(mtx_mat->get_pos_maxD()>=0)	
+                   if(mtx_mat->get_pos_maxD()>-1)
 	              statev[get_pos_mtx_maxD()]=Dmax;
                 }
+
 		virtual int getNbNonLocalVariables() const 
                 {
                    int nb=0;
@@ -556,6 +1194,10 @@ class MT_Material : public Material{
                    nb=nb+icl_mat->getNbNonLocalVariables(); 
                    return nb;
                 }
+                virtual int get_pos_Fd_bar()const;
+                virtual int get_pos_dFd_bar()const;
+                virtual int get_pos_locFd() const;
+
 
 #ifdef NONLOCALGMSH
 		virtual int get_pos_currentplasticstrainfornonlocal() const;
@@ -570,9 +1212,12 @@ class MT_Material : public Material{
                 virtual double getElasticEnergy (double* statev) ;
 		virtual double getPlasticEnergy (double* statev) ;
 
-
-
-
+		/*virtual void setLocalDamage()
+		{
+                    Material::setLocalDamage();
+                    mtx_mat->setLocalDamage();
+                    inc_mat->setLocalDamage();
+                }*/
 #endif
 };
 
@@ -586,11 +1231,19 @@ class MTSecF_Material : public MT_Material{
 		
 		MTSecF_Material(double* props, int idmat);
 		~MTSecF_Material();
+		
+		virtual void setEuler(double e1, double e2, double e3);
 
 		virtual int constbox(double* dstrn, double* strs_n,  double* strs, double* statev_n, double* statev, double** Cref, double*** dCref, double* tau, double** dtau, double** Calgo, double alpha, double* dpdE, double* strs_dDdp_bar, double *Sp_bar, double** c_g, double* dFd_d_bar, double* dstrs_dFd_bar, double *dFd_dE, double** c_gF,  double* dpdFd, double* dFddp, int kinc, int kstep, double dt);
                 virtual void unload_step(double* dstrn, double* strs_n, double* statev, int kinc, int kstep);
                 
-                virtual void setEuler(double e1, double e2, double e3);
+#ifdef NONLOCALGMSH
+		virtual void get_elOp_mtx(double* statev, double** Cel);
+		virtual void get_elOp_icl(double* statev, double** Cel);
+		virtual void get_elOp_mtx(double** Cel);
+		virtual void get_elOp_icl(double** Cel);
+                inline double get_vfI() {return vf_i;}
+#endif
 };
 
 //Composite material homogenized with Mori-Tanaka scheme with incremental secant method, second moment for the elastic predictor
@@ -822,8 +1475,8 @@ class ANEL_Material : public Material{
                 double dDeldD;
                 double v12, v13, v31, E1, E3;
                 int pos_euler;
-                
-    
+
+
 	public:
 		
 		ANEL_Material(double* props, int idmat);
@@ -861,7 +1514,7 @@ class ANEL_Material : public Material{
 		virtual double getPlasticEnergy (double* statev) ;
 #endif
 		
-}; 
+};
 
 #ifdef NONLOCALGMSH
 #else
diff --git a/NonLinearSolver/nlsolver/homogenizedData.cpp b/NonLinearSolver/nlsolver/homogenizedData.cpp
index 1bcdb430fac8146939d81070e59f7341c8936550..2790ebf175cfae4033d95f6d6c154646ec522d0d 100644
--- a/NonLinearSolver/nlsolver/homogenizedData.cpp
+++ b/NonLinearSolver/nlsolver/homogenizedData.cpp
@@ -143,7 +143,7 @@ deformationEnergy(src.deformationEnergy),plasticEnergy(src.plasticEnergy),irreve
 dIrreversibleEnergydF(src.dIrreversibleEnergydF), dIrreversibleEnergydG(src.dIrreversibleEnergydG),
 dIrreversibleEnergydgradT(src.dIrreversibleEnergydgradT),dIrreversibleEnergydT(src.dIrreversibleEnergydT),
 dIrreversibleEnergydgradV(src.dIrreversibleEnergydgradV),irreversibleEnergyExtraction(src.irreversibleEnergyExtraction),
-cohesiveLawExtraction(src.cohesiveLawExtraction), dUdF(src.dUdF),dQdG_correction(src.dQdG_correction)
+cohesiveLawExtraction(src.cohesiveLawExtraction), dUdF(src.dUdF), dUdG(src.dUdG), dQdG_correction(src.dQdG_correction)
 {};
 homogenizedData& homogenizedData::operator = (const homogenizedData& src){
 	P = src.P;
@@ -208,6 +208,7 @@ homogenizedData& homogenizedData::operator = (const homogenizedData& src){
 	irreversibleEnergyExtraction = src.irreversibleEnergyExtraction;
 	cohesiveLawExtraction = src.cohesiveLawExtraction;
 	dUdF = src.dUdF;
+	dUdG = src.dUdG;
 	dQdG_correction = src.dQdG_correction;
 	return *this;
 };
diff --git a/NonLinearSolver/nlsolver/homogenizedData.h b/NonLinearSolver/nlsolver/homogenizedData.h
index c0a7137165afb9e647ae4adb02d3ed46ada08228..23b0f9d1bf7af41137bcbc1e2d4c61315a645c23 100644
--- a/NonLinearSolver/nlsolver/homogenizedData.h
+++ b/NonLinearSolver/nlsolver/homogenizedData.h
@@ -117,6 +117,7 @@ class homogenizedData {
 		std::vector<SVector3> dIrreversibleEnergydgradV;
 
     std::map<Dof, STensor3> dUdF;
+    std::map<Dof, STensor33> dUdG;
 
   public:
     homogenizedData(const nonLinearMechSolver* solver, const bool failureExtr, const bool irrEnergExtract);
@@ -295,6 +296,7 @@ class homogenizedData {
 
 		const SVector3& getHomogenizedTangentOperator_gradV_T(const int fluxIndex, const int fieldIndex) const{return dfluxVdT[fluxIndex][fieldIndex];}
 	        std::map<Dof, STensor3>& getdUnknowndF() {return dUdF;};
+	        std::map<Dof, STensor33>& getdUnknowndG() {return dUdG;};
 };
 
 class allFirstOrderMechanicsFiles{
diff --git a/NonLinearSolver/nlsolver/nonLinearMechSolver.cpp b/NonLinearSolver/nlsolver/nonLinearMechSolver.cpp
index 2dc54959cba126d78f47aeee1b22a1d3ea4f830b..495b8b7425f5fbd97991b41bf44f1f9274dc64fd 100644
--- a/NonLinearSolver/nlsolver/nonLinearMechSolver.cpp
+++ b/NonLinearSolver/nlsolver/nonLinearMechSolver.cpp
@@ -5847,8 +5847,7 @@ void nonLinearMechSolver::computeBodyForceVector(){
     this->getMicroBC()->setTime(1.); 
     G1 = this->getMicroBC()->getSecondOrderKinematicalVariable();
     this->getMicroBC()->setTime(curtime);
-    //G1 = this->getMicroBC()->getSecondOrderKinematicalVariable();
-    
+       
     G1 -=G0;
     for (int idom=0; idom<domainVector.size(); idom++){
         partDomain* dom = domainVector[idom];
@@ -9374,7 +9373,7 @@ double nonLinearMechSolver::computeRightHandSide()
     if (_systemType == nonLinearMechSolver::MULT_ELIM){
       _pAl->assembleConstraintResidualToSystem();
       this->computeStiffMatrix();
-      if(computedUdF() and _pathFollowing and usePresentModuli()){
+      if(computedUdF() and _pathFollowing){
          this->computeBodyForceVector();
       }
     }
@@ -12873,9 +12872,10 @@ void nonLinearMechSolver::extractAveragePropertiesByCondensation(homogenizedData
   if(computedUdF())
   {
     static STensor53 dPdG;
+    static STensor53 dQdF;
     static STensor63 dQdG;
-    this->HOStressTangent_modificationTerm(dPdG, dQdG);
-    this->modifyHOStressTangent(L,dPdG, dQdG); //to get the homogenized stress derivative with respect to GM we want the body force effect
+    this->HOStressTangent_modificationTerm(dPdG, dQdF, dQdG);
+    this->modifyHOStressTangent(L,dPdG, dQdF, dQdG); //to get the homogenized stress derivative with respect to GM we want the body force effect
   }
   
   t = Cpu() -t;
@@ -13013,9 +13013,12 @@ void nonLinearMechSolver::extractAveragePropertiesByInSystemCondensationDISP_MUL
 void nonLinearMechSolver::extractAveragePropertiesByInSystemCondensation(homogenizedData* homoData){
   // extract tangent
   bool needdUdF = false;
-  if(computedUdF()) 
+  bool needdUdG = false;
+
+  if(computedUdF()){ 
     needdUdF=true; 
-  
+    needdUdG = true;
+  }
   double vRVE = this->getRVEVolume();
   // estimation of stress matrix
   _pAl->zeroStressMatrix();
@@ -13046,19 +13049,24 @@ void nonLinearMechSolver::extractAveragePropertiesByInSystemCondensation(homogen
   double t= Cpu();
   if (_multiscaleFlag == false)
     Msg::Info("Begin performing in-system condensation");
-  int goodSolve = _pAl->condensationSolve(L,vRVE,needdUdF, pAssembler,&homoData->getdUnknowndF());  
+  int goodSolve = _pAl->condensationSolve(L,vRVE,needdUdF, needdUdG, pAssembler,&homoData->getdUnknowndF(),&homoData->getdUnknowndG());  
   t = Cpu() -t;
   if (_multiscaleFlag == false)
     Msg::Info("Done performing in-system condensation (%f s)",t);
     
-   if(computedUdF())
+   if(needdUdF)
   {
+    _ipf->setdFmdFM(homoData->getdUnknowndF(), IPStateBase::current);
+    if(needdUdG)
+      _ipf->setdFmdGM(homoData->getdUnknowndG(), IPStateBase::current);
+
     static STensor53 dPdG;
+    static STensor53 dQdF;
     static STensor63 dQdG;
-    this->HOStressTangent_modificationTerm(dPdG, dQdG);
+    this->HOStressTangent_modificationTerm(dPdG, dQdF, dQdG);
     const STensor63& dQdG_correction = homoData->getHomogenizedCorrectionTerm_G_G();
     dQdG += dQdG_correction;
-    this->modifyHOStressTangent(L,dPdG, dQdG); //to get the homogenized stress derivative with respect to GM we want the body force effect
+    this->modifyHOStressTangent(L,dPdG, dQdF, dQdG); //to get the homogenized stress derivative with respect to GM we want the body force effect
 
   }  
   fillTangent(L,homoData);
@@ -13185,7 +13193,7 @@ void nonLinearMechSolver::extractAveragePropertiesByInSystemCondensation(homogen
     t= Cpu();
     if (_multiscaleFlag == false)
       Msg::Info("Begin performing in-system condensation");
-    int goodSolve = _pAl->condensationSolve(L,vRVE,needdUdF, pAssembler,&homoData->getdUnknowndF());
+    int goodSolve = _pAl->condensationSolve(L,vRVE,needdUdF, needdUdG, pAssembler,&homoData->getdUnknowndF(),&homoData->getdUnknowndG()); 
     t = Cpu() -t;
     if (_multiscaleFlag == false)
       Msg::Info("Done performing in-system condensation (%f s)",t);
@@ -13200,6 +13208,29 @@ void nonLinearMechSolver::extractAveragePropertiesByInSystemCondensation(homogen
 
 };
 
+void nonLinearMechSolver::extractdUdFByInSystemCondensation(homogenizedData* homoData){
+  // extract tangent
+  _pAl->zeroBodyForceMatrix();
+
+  for (int idom=0; idom<domainVector.size(); idom++){
+     partDomain* dom = domainVector[idom];
+     if (dom->elementGroupSize()>0){
+	AssembleBodyForceMatrix(*dom->getBilinearBodyForceTangentTerm(),*dom->getFunctionSpace(),dom->element_begin(),
+           dom->element_end(),*dom->getBulkGaussIntegrationRule(),*pAssembler,_elementErosionFilter);
+     }
+  }
+
+  double t= Cpu();
+  if (_multiscaleFlag == false)
+    Msg::Info("Begin performing in-system condensationfor dUdF");
+  int goodSolve = _pAl->condensationdUdF(pAssembler, &homoData->getdUnknowndF());  
+  t = Cpu() -t;
+  if (_multiscaleFlag == false)
+    Msg::Info("Done performing in-system condensation (%f s)",t);
+    
+  //_ipf->setdFmdFM(homoData->getdUnknowndF(), IPStateBase::current);
+};
+
 void nonLinearMechSolver::extractAverageStress(homogenizedData* homoData){
   if (_homogenizeStressMethod == VOLUME)
     this->extractAverageStressByVolumeIntegral(homoData);
@@ -14293,20 +14324,22 @@ void  nonLinearMechSolver::set2ndOrderHomogenizedTangentOperatorWithCorrection()
 }       
 
 
-void nonLinearMechSolver::HOStressTangent_modificationTerm(STensor53& dPdG, STensor63& dQdG){
+void nonLinearMechSolver::HOStressTangent_modificationTerm(STensor53& dPdG, STensor53& dQdF, STensor63& dQdG){
   double volumeRVEInv = 1./this->getRVEVolume();
   STensorOperation::zero(dQdG);
+  STensorOperation::zero(dQdF);
   STensorOperation::zero(dPdG);
   for (int i=0; i<domainVector.size(); i++){
-      domainVector[i]->computeAverageHighOrderStressTangentModification(_ipf,this->getRVEVolume(),dPdG,dQdG);
+      domainVector[i]->computeAverageHighOrderStressTangentModification(_ipf,this->getRVEVolume(),dPdG, dQdF, dQdG);
   };
     dPdG *= (volumeRVEInv);    
+    dQdF *= (volumeRVEInv);
     dQdG *= (volumeRVEInv);
 }
 
 
 
-void nonLinearMechSolver::modifyHOStressTangent(fullMatrix<double>& L, const STensor53& dPdG, const STensor63& dQdG){
+void nonLinearMechSolver::modifyHOStressTangent(fullMatrix<double>& L, const STensor53& dPdG, const STensor53& dQdF, const STensor63& dQdG){
 	// stress vector is arranged by this order
 	// S = [P Q FD fluxT1 mecaSrc1 -- fluxTn mecaSrcn fluxV1 --- fluxVm]
 	// K = [F G gradT1 T1 --- gradTn Tn gradV1 --- gradVm] see nonLinearMicroBC::getKinematicVector
@@ -14324,8 +14357,21 @@ void nonLinearMechSolver::modifyHOStressTangent(fullMatrix<double>& L, const STe
 	L(row,col) += dPdG(i,j,p,q,r);
     };
   }
-  // tangent Q-G	
+  // tangent Q-F	
   atRow = 9;
+  atCol = 0;
+  for (int row = atRow; row<atRow+27; row++){
+    int i,j,k;
+    Tensor33::getIntsFromIndex(row-atRow,i,j,k);
+    for (int col=atCol; col < atCol+9; col++){
+      int p,q;
+      Tensor23::getIntsFromIndex(col-atCol,p,q);
+      L(row,col) += dQdF(i,j,k,p,q);
+    }
+  }  
+  
+  // tangent Q-G
+  atCol = 9;	
   for (int row = atRow; row<atRow+27; row++){
     int i,j,k;
     Tensor33::getIntsFromIndex(row-atRow,i,j,k);
@@ -14338,6 +14384,7 @@ void nonLinearMechSolver::modifyHOStressTangent(fullMatrix<double>& L, const STe
 };
 
 
+
 void nonLinearMechSolver::checkFailureOnset(){
   if (_checkFailureOnset){
     const homogenizedData* homoDataPrev = this->getHomogenizationState(IPStateBase::previous);
@@ -15160,6 +15207,7 @@ double nonLinearMechSolver::solveMicroSolverSNL(){
   //
   _sucessMicroSolve = false;
   bool willFinish = false;
+  bool dUdF_Flag = false;
   
   while(!_timeManager->reachEndTime())
   {
@@ -15179,16 +15227,21 @@ double nonLinearMechSolver::solveMicroSolverSNL(){
     pAssembler->setTimeStep(dt);
     _ipf->setTime(curtime,dt,ii+1);
     if(computedUdF()){
-    _ipf->setdFmdFM(this->getHomogenizationState(IPStateBase::current)->getdUnknowndF(), IPStateBase::current);
+      if(dUdF_Flag){
+         homogenizedData* homoData = this->getHomogenizationState(IPStateBase::current);
+         this->extractdUdFByInSystemCondensation(homoData);
+         _ipf->setdFmdFM(homoData->getdUnknowndF(), IPStateBase::current);
+     }
+     else{
+         dUdF_Flag = true;
+     } 
     }
     
     // Solve one step by NR scheme
     int niteNR = 0;
     if (_pathFollowing)
     {
-      if(computedUdF() and !usePresentModuli()){
-         this->computeBodyForceVector();
-      }
+
       pathSys->setPathFollowingIncrement(dt);
       _pAl->updateConstraint(_ipf);
       
@@ -15253,9 +15306,6 @@ double nonLinearMechSolver::solveMicroSolverSNL(){
       nonsys->resetUnknownsToPreviousTimeStep();
       _ipf->copy(IPStateBase::previous,IPStateBase::current);
 
-      /*if (_pathFollowing and computedUdF()){
-          pathSys->resetScaleParameter(_timeManager->getTimeStepFactorReduction());
-      }*/
 
       this->getHomogenizationState(IPStateBase::current)->operator=(*this->getHomogenizationState(IPStateBase::previous));
        
@@ -15295,10 +15345,6 @@ double nonLinearMechSolver::solveMicroSolverSNL(){
       else
       {
         // get next step without saving
-     /*   if(computedUdF()){
-          this->extractAverageProperties(_tangentflag);
-          _ipf->setdFmdFM(this->getHomogenizationState(IPStateBase::current)->getdUnknowndF(), IPStateBase::current);
-        }*/
         this->nextStep(curtime,ii+1);
       }
       if (_pathFollowing)
diff --git a/NonLinearSolver/nlsolver/nonLinearMechSolver.h b/NonLinearSolver/nlsolver/nonLinearMechSolver.h
index 96b4e8b82193873001697fcdea1384cf14cd10c4..2242921c9ef1f960307deb7fc6912d2704ee11b5 100644
--- a/NonLinearSolver/nlsolver/nonLinearMechSolver.h
+++ b/NonLinearSolver/nlsolver/nonLinearMechSolver.h
@@ -1469,8 +1469,8 @@ class nonLinearMechSolver
   void microNumberDof();
   
   void set2ndOrderHomogenizedTangentOperatorWithCorrection();
-  void modifyHOStressTangent(fullMatrix<double>& L, const STensor53& dPdG,  const STensor63& dQdG);
-  void HOStressTangent_modificationTerm(STensor53& dPdG, STensor63& dQdG);
+  void modifyHOStressTangent(fullMatrix<double>& L, const STensor53& dPdG, const STensor53& dQdF, const STensor63& dQdG);
+  void HOStressTangent_modificationTerm(STensor53& dPdG, STensor53& dQdF, STensor63& dQdG);
 
   void fillTangent(const fullMatrix<double>& L, homogenizedData* homoData);
 
@@ -1488,7 +1488,7 @@ class nonLinearMechSolver
   void extractAveragePropertiesPerturbation(homogenizedData* homoData);
   void extractAveragePropertiesByInSystemCondensationDISP_MULT(homogenizedData* homoData);
   void extractAveragePropertiesByInSystemCondensation(homogenizedData* homoData);
-
+  void extractdUdFByInSystemCondensation(homogenizedData* homoData);
   void extractAverageStressAndTangent(homogenizedData* homoData);
 
   void homogenizedDataToFile(const double time);
diff --git a/NonLinearSolver/pathFollowing/pbcPathFollowingSystemPETSc.h b/NonLinearSolver/pathFollowing/pbcPathFollowingSystemPETSc.h
index c1d8622182712844d9f2240d68a8a92c0dbab33f..cd024607abc3358e853e489aedf2cb6df8435b1a 100644
--- a/NonLinearSolver/pathFollowing/pbcPathFollowingSystemPETSc.h
+++ b/NonLinearSolver/pathFollowing/pbcPathFollowingSystemPETSc.h
@@ -40,7 +40,7 @@ class pbcPathFollowingSystemPETSC : public pbcNonLinearSystemPETSc<scalar>,
     int _iter; //  specify predictor and corrector
     double uScale2; // equal to _uScale^2
     bool _isAllocatedBodyForceVector;
-    double _loadReduceRatio =1.0;
+    
 
 
   public:
@@ -201,7 +201,7 @@ class pbcPathFollowingSystemPETSC : public pbcNonLinearSystemPETSc<scalar>,
       _controlParameterPrev = 0.;
       _controlStep = 0.;
       _setScale = false;
-      _loadReduceRatio = 1.0;
+  
   
       _try(VecAssemblyBegin(_stateStep));
       _try(VecAssemblyEnd(_stateStep));
@@ -215,7 +215,6 @@ class pbcPathFollowingSystemPETSC : public pbcNonLinearSystemPETSc<scalar>,
     
     virtual void resetScaleParameter(const double val){
        _setScale = false;
-       _loadReduceRatio = _loadReduceRatio*val;
     }   
 
     virtual int systemSolve(){
@@ -234,13 +233,17 @@ class pbcPathFollowingSystemPETSC : public pbcNonLinearSystemPETSc<scalar>,
       _try(MatMultAdd(this->_CT,_q,_qeff,_qeff));
       _try(VecScale(_qeff,this->_scale));
       
-      if (_isAllocatedBodyForceVector)
-          _try(MatMultAdd(this->_Q,_BF,_qeff,_qeff));
-          
-      //  try to reduce load vector
-      PetscScalar reduce = 1./_loadReduceRatio;  
-      _try(VecScale(_qeff,reduce));    
-
+      if (_isAllocatedBodyForceVector){
+       //  if(_iter==0){
+       //    _try(MatMultAdd(this->_Q,_BF,_qeff,_qeff));
+       //  }
+       //  else{
+           PetscScalar inv_dt = 1./_pseudoTimeIncrement;
+           _try(VecScale(_BF, inv_dt));
+           _try(MatMultAdd(this->_Q,_BF,_qeff,_qeff));
+      //   }
+       }
+      
       _try(VecAssemblyBegin(_qeff));
       _try(VecAssemblyEnd(_qeff));
 
@@ -260,7 +263,7 @@ class pbcPathFollowingSystemPETSC : public pbcNonLinearSystemPETSc<scalar>,
         }
         PetscScalar A0 =  _aU*vTv/uScale2+_aL;
 
-        double a1 = _loadReduceRatio*_pseudoTimeIncrement/sqrt(A0);
+        double a1 = _pseudoTimeIncrement/sqrt(A0);
         double a2 = -1.*a1;
 
         PetscScalar uprevTu;
@@ -268,14 +271,14 @@ class pbcPathFollowingSystemPETSC : public pbcNonLinearSystemPETSc<scalar>,
         
         if (uprevTu>= 0){
            _controlStep = a1;
-            _controlParameter +=  a1/_loadReduceRatio;
+            _controlParameter +=  a1;
             _try(VecAXPY(_stateStep,a1,this->_x));
             _try(VecAXPY(this->_xsol,a1,this->_x));
 
         }
         else{
           _controlStep = a2;
-          _controlParameter +=  a2/_loadReduceRatio;
+          _controlParameter +=  a2;
           _try(VecAXPY(_stateStep,a2,this->_x));
           _try(VecAXPY(this->_xsol,a2,this->_x));
         }
@@ -342,7 +345,7 @@ class pbcPathFollowingSystemPETSC : public pbcNonLinearSystemPETSc<scalar>,
         PetscScalar D = _aU*_aU*(vTdr/uScale2)*(vTdr/uScale2) - A*drTdr/uScale2*_aU;
         PetscScalar E = (_aL*_controlStep+ _aU*vTdu/uScale2)*(vTdr/uScale2)*_aU - A*duTdr/uScale2*_aU;
         PetscScalar F = (_aL*_controlStep+ _aU*vTdu/uScale2)*(_aL*_controlStep+ _aU*vTdu/uScale2)
-                        -A*(_aU*duTdu/uScale2+_aL*_controlStep*_controlStep - _loadReduceRatio*_loadReduceRatio*_pseudoTimeIncrement*_pseudoTimeIncrement);
+                        -A*(_aU*duTdu/uScale2+_aL*_controlStep*_controlStep - _pseudoTimeIncrement*_pseudoTimeIncrement);
 
         double delta = E*E -D*F;
         PetscScalar _beta = 1.;
@@ -373,7 +376,7 @@ class pbcPathFollowingSystemPETSC : public pbcNonLinearSystemPETSc<scalar>,
         C*= _aU;
         C /= uScale2;
         double dlamda2 = _controlStep*_controlStep*_aL;
-        dlamda2 -= _loadReduceRatio*_loadReduceRatio*_pseudoTimeIncrement*_pseudoTimeIncrement;
+        dlamda2 -= _pseudoTimeIncrement*_pseudoTimeIncrement;
 
         C += dlamda2;
 
@@ -403,7 +406,7 @@ class pbcPathFollowingSystemPETSC : public pbcNonLinearSystemPETSc<scalar>,
             s = a2;
           }
           _controlStep += s;
-          _controlParameter += s/_loadReduceRatio;
+          _controlParameter += s;
           _try(VecAXPY(_stateStep,s,this->_x));
           _try(VecAXPY(this->_xsol,_beta,dr));
           _try(VecAXPY(this->_xsol,s,this->_x));
@@ -444,8 +447,6 @@ class pbcPathFollowingSystemPETSC : public pbcNonLinearSystemPETSc<scalar>,
     virtual void setPathFollowingIncrement(const double dt) {};
     virtual double getStateParameter() const {return 0.;};
 		virtual void resetControlParameter() {};
-		virtual void resetScaleParameter(){};
-		virtual void resetScaleParameter() {};
 		virtual void addToPathFollowingContraint(const scalar& val) {};
 		virtual void addToDPathFollowingConstraintDUnknown(const int col, const scalar& val) {};
 		virtual void addToDPathFollowingConstraintDControlParameter(const scalar& val) {};
diff --git a/NonLinearSolver/periodicBC/pbcAlgorithm.cpp b/NonLinearSolver/periodicBC/pbcAlgorithm.cpp
index e0bd2ed30031b57d7f513ac62f7262b856e7e5cb..5c4981e5f78f484c2cd26e7708765e48389a0bbf 100644
--- a/NonLinearSolver/periodicBC/pbcAlgorithm.cpp
+++ b/NonLinearSolver/periodicBC/pbcAlgorithm.cpp
@@ -422,7 +422,23 @@ void pbcAlgorithm::zeroBodyForceVector(){
   }
 };
 
-int pbcAlgorithm::condensationSolve(fullMatrix<double>& L,double rvevolume, const bool needdUdF, nlsDofManager* pAss,  std::map<Dof, STensor3>* dUdF){
+int pbcAlgorithm::condensationSolve(fullMatrix<double>& L, double rvevolume, const bool needdUdF,const bool needdUdG, nlsDofManager* pAss,  
+             std::map<Dof, STensor3 >* dUdF, std::map<Dof, STensor33 >* dUdG)
+{
+  std::string name = "A";
+  linearSystem<double>* lsys = _solver->getDofManager()->getLinearSystem(name);
+  pbcSystemBase<double>* pbcsys = dynamic_cast<pbcSystemBase<double>*>(lsys);
+  if (pbcsys == NULL){
+    Msg::Error("pbc system must be used pbcAlgorithm::zeroInSystemHomogenizedTangentMatrix");
+    return 0;
+  }
+  else{
+    int ok = pbcsys->condensationSolve(L,rvevolume, needdUdF,needdUdG, pAss, dUdF,dUdG);
+    return ok;
+  }
+};
+
+int pbcAlgorithm::condensationdUdF(nlsDofManager* pAss,  std::map<Dof, STensor3>* dUdF ){
   std::string name = "A";
   linearSystem<double>* lsys = _solver->getDofManager()->getLinearSystem(name);
   pbcSystemBase<double>* pbcsys = dynamic_cast<pbcSystemBase<double>*>(lsys);
@@ -431,7 +447,7 @@ int pbcAlgorithm::condensationSolve(fullMatrix<double>& L,double rvevolume, cons
     return 0;
   }
   else{
-    int ok = pbcsys->condensationSolve(L,rvevolume, needdUdF, pAss, dUdF);
+    int ok = pbcsys->condensationdUdF(pAss, dUdF);
     return ok;
   }
 };
diff --git a/NonLinearSolver/periodicBC/pbcAlgorithm.h b/NonLinearSolver/periodicBC/pbcAlgorithm.h
index 8b8db1f0c3d571937be11e498130f2b0507b440f..106940e2bf75977f4873d7465d1499789da3c45d 100644
--- a/NonLinearSolver/periodicBC/pbcAlgorithm.h
+++ b/NonLinearSolver/periodicBC/pbcAlgorithm.h
@@ -64,7 +64,9 @@ class pbcAlgorithm{
     void zeroStressMatrix();
     void zeroBodyForceMatrix();
     void zeroBodyForceVector();
-    int condensationSolve(fullMatrix<double>& L, double rvevolume, const bool needdUdF=false, nlsDofManager* pAss=NULL,  std::map<Dof, STensor3 >* dUdF = NULL);
+    int condensationSolve(fullMatrix<double>& L, double rvevolume, const bool needdUdF=false,const bool needdUdG=false, nlsDofManager* pAss=NULL,  
+             std::map<Dof, STensor3 >* dUdF = NULL, std::map<Dof, STensor33 >* dUdG = NULL);
+    int condensationdUdF(nlsDofManager* pAss=NULL,  std::map<Dof, STensor3 >* dUdF = NULL);
 
     // for lagrange multipliers method : multipliers are accounted as normal dofs
     void sparsityLagMultiplierDofs(); //pre allocated
diff --git a/NonLinearSolver/periodicBC/pbcConstraintEliminationNonLinearSystemPETSc.h b/NonLinearSolver/periodicBC/pbcConstraintEliminationNonLinearSystemPETSc.h
index bb5b741b64a755022e026e5fe63fb4b61dafa72d..217a1468a81bc95eaedd01210797bdd0323958cc 100644
--- a/NonLinearSolver/periodicBC/pbcConstraintEliminationNonLinearSystemPETSc.h
+++ b/NonLinearSolver/periodicBC/pbcConstraintEliminationNonLinearSystemPETSc.h
@@ -531,12 +531,15 @@ class pbcConstraintEliminationNonLinearSystemPETSc : public pbcSystemConden<scal
 
 		};
 
-    virtual int condensationSolve(fullMatrix<double>& L, const double rvevolume, const bool needdUdF, nlsDofManager* pAss,  std::map<Dof, STensor3 >* dUdF) {
+    virtual int condensationSolve(fullMatrix<double>& L, const double rvevolume, const bool needdUdF,const bool needdUdG, nlsDofManager* pAss,  
+             std::map<Dof, STensor3 >* dUdF, std::map<Dof, STensor33 >* dUdG) {
       int _dimKin = _pAl->getNumberOfMacroToMicroKinematicVariables();
       L.resize(_dimStress,_dimKin);
       L.setAll(0.);
       if(needdUdF){
          dUdF->clear();
+         if(needdUdG)
+            dUdG->clear();
          if (_isModifiedBodyForceMatrix){
           _try(MatAssemblyBegin(_BodyForceMatrix,MAT_FINAL_ASSEMBLY));
           _try(MatAssemblyEnd(_BodyForceMatrix,MAT_FINAL_ASSEMBLY));
@@ -623,6 +626,23 @@ class pbcConstraintEliminationNonLinearSystemPETSc : public pbcSystemConden<scal
              }
            }          
         }
+        if(needdUdG){
+           if(i>=9 and i<36){ 
+             int k, l, s; 
+             PetscScalar Sval, Txval;
+             Tensor33::getIntsFromIndex(i,k,l,s); // convert vector to matrix
+             const std::map<Dof, int>& unknown = pAss->getUnknownMap();
+
+             for (std::map<Dof, int>::const_iterator it= unknown.begin(); it != unknown.end(); it++) {
+               STensor33& dUcompdG = dUdG->operator[](it->first);
+               PetscInt idof = it->second;
+               MatGetValue(_S,idof,col,&Sval);
+               PetscInt ix[]={idof};
+               VecGetValues(Tx,1,ix,&Txval);
+               dUcompdG(k,l,s) = Sval-Txval;                             
+             }
+           }          
+        }
         //
       }
       _try(VecDestroy(&StressMatX));
@@ -633,7 +653,74 @@ class pbcConstraintEliminationNonLinearSystemPETSc : public pbcSystemConden<scal
       _try(VecDestroy(&Tx));
       _try(VecDestroy(&kinematicRHS));
       return 1;
-		};
+    };
+    
+    
+    virtual int condensationdUdF(nlsDofManager* pAss,  std::map<Dof, STensor3 >* dUdF) {
+      int _dimKin = _pAl->getNumberOfMacroToMicroKinematicVariables();
+      dUdF->clear();
+      if (_isModifiedBodyForceMatrix){
+        _try(MatAssemblyBegin(_BodyForceMatrix,MAT_FINAL_ASSEMBLY));
+        _try(MatAssemblyEnd(_BodyForceMatrix,MAT_FINAL_ASSEMBLY));
+        _isModifiedBodyForceMatrix = false;
+      }
+     
+      createKSPSolver();  
+      
+      // compute kinematic kinMatRHS
+      // MatRHS = (-TT*K*S)
+      Mat TTK;
+      _try(MatTransposeMatMult(_T,this->_a,MAT_INITIAL_MATRIX,PETSC_DECIDE,&TTK));
+      Mat kinMatRHS;
+      _try(MatMatMult(TTK,_S,MAT_INITIAL_MATRIX,PETSC_DECIDE,&kinMatRHS));
+      //
+      Mat TTBmdGMat;
+      _try(MatTransposeMatMult(_T,_BodyForceMatrix,MAT_INITIAL_MATRIX,PETSC_DECIDE,&TTBmdGMat));
+      _try(MatAXPY(kinMatRHS,-1.,TTBmdGMat,DIFFERENT_NONZERO_PATTERN));
+      _try(MatDestroy(&TTBmdGMat));
+
+      // solve for each column of _KinematicMatrix
+      Vec x, Tx;
+      _try(VecDuplicate(_xConden,&x));
+      _try(VecDuplicate(this->_xsol,&Tx));
+
+      Vec kinematicRHS;
+        _try(VecDuplicate(_xConden,&kinematicRHS));
+
+      for (int i=0; i< 9; i++){
+        PetscInt col = i;
+        _try(MatGetColumnVector(kinMatRHS,kinematicRHS,col));
+
+        PetscReal NormRHS;
+        _try(VecNorm(kinematicRHS,NORM_INFINITY,&NormRHS));
+
+        if (NormRHS > 0.){
+          // solve if norm greater than 0
+          _try(KSPSolve(this->_ksp, kinematicRHS, x));
+          _try(MatMult(_T,x,Tx));
+        }
+        int k, l; 
+        PetscScalar Sval, Txval;
+        Tensor23::getIntsFromIndex(i,k,l); // convert vector to matrix
+        const std::map<Dof, int>& unknown = pAss->getUnknownMap();
+
+        for (std::map<Dof, int>::const_iterator it= unknown.begin(); it != unknown.end(); it++) {
+           STensor3& dUcompdF = dUdF->operator[](it->first);
+           PetscInt idof = it->second;
+           MatGetValue(_S,idof,col,&Sval);
+           PetscInt ix[]={idof};
+           VecGetValues(Tx,1,ix,&Txval);
+           dUcompdF(k,l) = Sval-Txval;                             
+        }
+     }          
+        
+     _try(MatDestroy(&kinMatRHS));
+     _try(MatDestroy(&TTK));
+     _try(VecDestroy(&x));
+     _try(VecDestroy(&Tx));
+     _try(VecDestroy(&kinematicRHS));
+     return 1;
+   };
 
 #else
     pbcConstraintEliminationNonLinearSystemPETSc(){Msg::Error("Petsc is not available");};
@@ -655,7 +742,9 @@ class pbcConstraintEliminationNonLinearSystemPETSc : public pbcSystemConden<scal
     virtual void allocateBodyForcesMatrix(int stressDim, int nbR) {};
     virtual void addToBodyForceMatrix(int row, int col, const scalar& val) {};
     virtual void zeroBodyForceMatrix() {};
-    virtual int condensationSolve(fullMatrix<double>& L, const double rvevolume,const bool needdUdF, nlsDofManager* pAss,  std::map<Dof, STensor3 >* dUdF)  {};
+    virtual int condensationSolve(fullMatrix<double>& L, const double rvevolume,const bool needdUdF,const bool needdUdG, nlsDofManager* pAss, 
+                std::map<Dof, STensor3 >* dUdF, std::map<Dof, STensor33 >* dUdG)  {};
+    virtual int condensationdUdF(nlsDofManager* pAss=NULL,  std::map<Dof, STensor3 >* dUdF=NULL)  {};
 
 #endif // HAVE_PETSC
 };
diff --git a/NonLinearSolver/periodicBC/pbcNonLinearSystemPETSc.h b/NonLinearSolver/periodicBC/pbcNonLinearSystemPETSc.h
index 6b6409aa17e3c82c8950a2678d6cb49302d5046f..03f2a0117626699ced6d76d843743bd20f150fc4 100644
--- a/NonLinearSolver/periodicBC/pbcNonLinearSystemPETSc.h
+++ b/NonLinearSolver/periodicBC/pbcNonLinearSystemPETSc.h
@@ -463,12 +463,15 @@ class pbcNonLinearSystemPETSc : public pbcSystem<scalar>,
 		};
 
 
-   virtual int condensationSolve(fullMatrix<double>& L, const double rvevolume,const bool needdUdF, nlsDofManager* pAss=NULL,  std::map<Dof, STensor3 >* dUdF=NULL) {
+   virtual int condensationSolve(fullMatrix<double>& L, const double rvevolume,const bool needdUdF,const bool needdUdG, nlsDofManager* pAss=NULL,  std::map<Dof, STensor3 >* dUdF=NULL, 
+                               std::map<Dof, STensor33 >* dUdG=NULL) {
       L.resize(_dimStress,_dimKin);
       L.setAll(0.);
 
       if(needdUdF){
            dUdF->clear();
+           if(needdUdG)
+             dUdG->clear();
       if (_isModifiedBodyForceMatrix){
           _try(MatAssemblyBegin(_BodyForceMatrix,MAT_FINAL_ASSEMBLY));
           _try(MatAssemblyEnd(_BodyForceMatrix,MAT_FINAL_ASSEMBLY));
@@ -559,6 +562,23 @@ class pbcNonLinearSystemPETSc : public pbcSystem<scalar>,
              }
            }          
         }
+        
+       if(needdUdG){
+           if(i>=9 and i<36){ 
+             int k, l, s; 
+             PetscScalar x_val;
+             Tensor33::getIntsFromIndex(i,k,l,s); // convert vector to matrix
+             const std::map<Dof, int>& unknown = pAss->getUnknownMap();
+
+             for (std::map<Dof, int>::const_iterator it= unknown.begin(); it != unknown.end(); it++) {
+               STensor33& dUcompdG = dUdG->operator[](it->first);
+               PetscInt idof = it->second;
+               PetscInt ix[]={idof};
+               VecGetValues(x,1,ix,&x_val);
+               dUcompdG(k,l,s) = x_val;                             
+             }
+           }          
+        }       
       }
       _try(MatDestroy(&kinMatRHS));
       _try(VecDestroy(&x));
@@ -566,7 +586,82 @@ class pbcNonLinearSystemPETSc : public pbcSystem<scalar>,
       _try(VecDestroy(&kinematicRHS));
       return 1;
       };
+      
+      
+   virtual int condensationdUdF(nlsDofManager* pAss=NULL,  std::map<Dof, STensor3 >* dUdF=NULL) {
+      dUdF->clear();
+      if (_isModifiedBodyForceMatrix){
+          _try(MatAssemblyBegin(_BodyForceMatrix,MAT_FINAL_ASSEMBLY));
+          _try(MatAssemblyEnd(_BodyForceMatrix,MAT_FINAL_ASSEMBLY));
+          _isModifiedBodyForceMatrix = false;
+      }
+      
+      if (!_isSolvedPass){
+        createKSPSolver();
+      }
+      _isSolvedPass = false;
+
+      if (_isModifiedKinematicMatrix){
+        _try(MatAssemblyBegin(_KinematicMatrix,MAT_FINAL_ASSEMBLY));
+        _try(MatAssemblyEnd(_KinematicMatrix,MAT_FINAL_ASSEMBLY));
+        _isModifiedKinematicMatrix = false;
+      }
+
+      // compute kinematic kinMatRHS
+      // MatRHS = (CT-QT*K*R)*_KinematicMatrix
+      Mat kinMatRHS;
+      Mat KRkMat, QTKRkMat;
+      _try(MatMatMult(_CT,_KinematicMatrix,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&kinMatRHS));
+      _try(MatScale(kinMatRHS,_scale));
+      _try(MatMatMatMult(this->_a,_R,_KinematicMatrix,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&KRkMat));
+      _try(MatTransposeMatMult(_Q,KRkMat,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&QTKRkMat));
+      _try(MatAXPY(kinMatRHS,-1.,QTKRkMat,DIFFERENT_NONZERO_PATTERN));
+
+      Mat QTBmdGMat;
+      _try(MatTransposeMatMult(_Q,_BodyForceMatrix,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&QTBmdGMat));
+      _try(MatAXPY(kinMatRHS,1.,QTBmdGMat,DIFFERENT_NONZERO_PATTERN));
+      _try(MatDestroy(&QTBmdGMat));
+      
+      _try(MatDestroy(&QTKRkMat));
+      _try(MatDestroy(&KRkMat));
+
+      //
+      Vec kinematicRHS;
+      _try(VecDuplicate(this->_x,&kinematicRHS));
+      Vec x;
+      _try(VecDuplicate(kinematicRHS,&x));
+
+      // solve for each column of _KinematicMatrix
+      for (int i=0; i< 9; i++){
+        PetscInt col = i;
+        _try(MatGetColumnVector(kinMatRHS,kinematicRHS,col));
+        PetscReal NormRHS;
+        _try(VecNorm(kinematicRHS,NORM_INFINITY,&NormRHS));
 
+        if (NormRHS > 0.){
+          // solve if norm greater than 0
+          _try(KSPSolve(this->_ksp, kinematicRHS, x));
+        }        
+        int k, l; 
+        PetscScalar x_val;
+        Tensor23::getIntsFromIndex(i,k,l); // convert vector to matrix
+        const std::map<Dof, int>& unknown = pAss->getUnknownMap();
+
+        for (std::map<Dof, int>::const_iterator it= unknown.begin(); it != unknown.end(); it++) {
+          STensor3& dUcompdF = dUdF->operator[](it->first);
+          PetscInt idof = it->second;
+          PetscInt ix[]={idof};
+          VecGetValues(x,1,ix,&x_val);
+          dUcompdF(k,l) = x_val;                             
+        }               
+      }
+        
+      _try(MatDestroy(&kinMatRHS));
+      _try(VecDestroy(&x));
+      _try(VecDestroy(&kinematicRHS));
+      return 1;
+   };
+      
   #else
   public:
     pbcNonLinearSystemPETSc(){Msg::Error("Petsc is not available");};
@@ -604,7 +699,9 @@ class pbcNonLinearSystemPETSc : public pbcSystem<scalar>,
     
 
     // tangent solve
-		virtual int condensationSolve(fullMatrix<double>& L, const double rvevolume,const bool fl=false, nlsDofManager* pAss=NULL,  std::map<Dof, STensor3 >* dUdF=NULL)  {};
+		virtual int condensationSolve(fullMatrix<double>& L, const double rvevolume,const bool fl=false, const bool fl1=false, nlsDofManager* pAss=NULL, 
+		 std::map<Dof, STensor3 >* dUdF=NULL, std::map<Dof, STensor33 >* dUdG=NULL)  {};
+		virtual int condensationdUdF(nlsDofManager* pAss=NULL,  std::map<Dof, STensor3 >* dUdF=NULL)  {};
 	#endif
 };
 #endif // PBCNONLINEARSYSTEM_H_
diff --git a/NonLinearSolver/periodicBC/pbcSystems.h b/NonLinearSolver/periodicBC/pbcSystems.h
index d3fadad39074fd44c757ae1f15cf64d68cdc1592..87c5ea3effabd1f174d484382da69523bb37ffca 100644
--- a/NonLinearSolver/periodicBC/pbcSystems.h
+++ b/NonLinearSolver/periodicBC/pbcSystems.h
@@ -31,7 +31,9 @@ class pbcSystemBase{
     virtual bool NeedBodyForceVector() const = 0;
     virtual void setNeedBodyForceVector(bool needBodyForceVector) = 0;
 
-    virtual int condensationSolve(fullMatrix<double>& L, const double rvevolume, const bool fl=false, nlsDofManager* pAss=NULL,  std::map<Dof, STensor3 >* dUdF=NULL)  = 0;
+    virtual int condensationSolve(fullMatrix<double>& L, const double rvevolume, const bool fl=false, const bool fl1=false, nlsDofManager* pAss=NULL, 
+                 std::map<Dof, STensor3 >* dUdF=NULL,  std::map<Dof, STensor33>* dUdG=NULL)  = 0;
+    virtual int condensationdUdF(nlsDofManager* pAss=NULL, std::map<Dof, STensor3 >* dUdF=NULL)  = 0;
 };
 
 // interface to introduce linear constraints
@@ -73,7 +75,9 @@ class pbcSystem : public pbcSystemBase<scalar>{
     virtual void setNeedBodyForceVector(bool needBodyForceVector) {};
 
     // tangent solve
-		virtual int condensationSolve(fullMatrix<double>& L, const double rvevolume, const bool fl=false, nlsDofManager* pAss=NULL,  std::map<Dof, STensor3 >* dUdF=NULL)  = 0;
+    virtual int condensationSolve(fullMatrix<double>& L, const double rvevolume, const bool fl=false, const bool fl1=false, nlsDofManager* pAss=NULL, 
+		 std::map<Dof, STensor3 >* dUdF=NULL, std::map<Dof, STensor33 >* dUdG=NULL)  = 0;
+    virtual int condensationdUdF(nlsDofManager* pAss=NULL, std::map<Dof, STensor3 >* dUdF=NULL)  = 0;
 };
 
 template<class scalar>
@@ -101,7 +105,9 @@ class pbcSystemConden : public pbcSystemBase<scalar>{
     virtual void addToBodyForceVector(int row, const scalar& val) {};
     virtual bool NeedBodyForceVector() const {};
     virtual void setNeedBodyForceVector(bool needBodyForceVector) {};
-    virtual int condensationSolve(fullMatrix<double>& L, const double rvevolume, const bool fl=false, nlsDofManager* pAss=NULL,  std::map<Dof, STensor3 >* dUdF=NULL)  = 0;
+    virtual int condensationSolve(fullMatrix<double>& L, const double rvevolume, const bool fl=false, const bool fl1=false,  nlsDofManager* pAss=NULL, 
+                 std::map<Dof, STensor3 >* dUdF=NULL, std::map<Dof, STensor33 >* dUdG=NULL)  = 0;
+    virtual int condensationdUdF(nlsDofManager* pAss=NULL, std::map<Dof, STensor3 >* dUdF=NULL)  = 0;
 };
 
 #endif // PBCSYSTEMS_H_
diff --git a/cm3apps/install.txt b/cm3apps/install.txt
index e925819276ec3c1a2fda65d0eb199971cdf83aa8..9ae01b71883d4c97e3e9b608dc6235a471b1b6cf 100644
--- a/cm3apps/install.txt
+++ b/cm3apps/install.txt
@@ -587,52 +587,64 @@ C) Install Open Cascade (optional)
 
 D) Install Torch
         cd local
-       // no gpu
-          wget https://download.pytorch.org/libtorch/cpu/libtorch-shared-with-deps-1.4.0%2Bcpu.zip
-          unzip libtorch-shared-with-deps-1.4.0+cpu.zip 
+        // no gpu
+          wget https://download.pytorch.org/libtorch/nightly/cpu/libtorch-shared-with-deps-latest.zip
+          unzip libtorch-shared-with-deps-latest.zip
           if you need in python3 without gpu
-          pip3 install torch==1.7.1+cpu torchvision==0.8.2+cpu torchaudio==0.7.2 -f https://download.pytorch.org/whl/torch_stable.html
+          sudo pip3 install --pre torch torchvision torchaudio --extra-index-url https://download.pytorch.org/whl/nightly/cpu
        // gpu
-           1) clean up
+           1) clean up (still with new ubuntu?, to check)
            sudo rm /etc/apt/sources.list.d/cuda*
            sudo apt remove --autoremove nvidia-cuda-toolkit
            sudo apt remove --autoremove nvidia-*
-           2) purge
+           2) purge (still with new ubuntu?, to check)
            sudo apt-get purge nvidia*
            sudo apt-get autoremove
            sudo apt-get autoclean
            sudo rm -rf /usr/local/cuda*
-           3) install graphics
+           3) install graphics (still with new ubuntu?, to check)
            sudo apt update
            sudo add-apt-repository ppa:graphics-drivers
-           sudo apt-key adv --fetch-keys http://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64/7fa2af80.pub
-           sudo bash -c 'echo "deb http://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64 /" > /etc/apt/sources.list.d/cuda.list'
-           sudo bash -c 'echo "deb http://developer.download.nvidia.com/compute/machine-learning/repos/ubuntu2004/x86_64 /" > /etc/apt/sources.list.d/cuda_learn.list'
+           sudo apt-key adv --fetch-keys http://developer.download.nvidia.com/compute/cuda/repos/ubuntu2204/x86_64/3bf863cc.pub
+           sudo bash -c 'echo "deb http://developer.download.nvidia.com/compute/cuda/repos/ubuntu2204/x86_64 /" > /etc/apt/sources.list.d/cuda.list'
+           //sudo bash -c 'echo "deb http://developer.download.nvidia.com/compute/machine-learning/repos/ubuntu2004/x86_64 /" > /etc/apt/sources.list.d/cuda_learn.list'
+               // alternative?
+                wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2204/x86_64/cuda-ubuntu2204.pinsudo 
+                mv cuda-ubuntu2204.pin /etc/apt/preferences.d/cuda-repository-pin-600
+                wget https://developer.download.nvidia.com/compute/cuda/11.7.1/local_installers/cuda-repo-ubuntu2204-11-7-local_11.7.1-515.65.01-1_amd64.debsudo 
+                dpkg -i cuda-repo-ubuntu2204-11-7-local_11.7.1-515.65.01-1_amd64.debsudo 
+                cp /var/cuda-repo-ubuntu2204-11-7-local/cuda-*-keyring.gpg /usr/share/keyrings/sudo apt-get update
+           
+           4) install cuda
            sudo apt update
-           sudo apt install cuda-11-0
-           sudo apt install libcudnn7
+           sudo apt install cuda-11-7
+          
            add in your .bashrc
            export PATH=/usr/local/cuda/bin/:$PATH
            export LD_LIBRARY_PATH=/usr/local/cuda/lib64/:$LD_LIBRARY_PATH
-           4) install cudnn 
-           download cudnn from nvidia (you need to register and downloadmanualy
-           https://developer.nvidia.com/compute/machine-learning/cudnn/secure/8.0.4/11.0_20200923/cudnn-11.0-linux-x64-v8.0.4.30.tgz
-           copy in your local directory
-           tar xvf cudnn-11.0-linux-x64-v8.0.4.30.tgz
-           sudo cp cuda/include/cudnn*.h /usr/local/cuda/include
-           or  sudo ln -s ~/local/cuda/include/cudnn* /usr/local/cuda/include/
-           sudo cp cuda/lib64/libcudnn* /usr/local/cuda/lib64
-           or  sudo ln -s ~/local/cuda/lib64/libcudnn* /usr/local/cuda/lib64
-           sudo chmod a+r /usr/local/cuda/include/cudnn*.h /usr/local/cuda/lib64/libcudnn*
-           5) download torch with gpu
-           wget https://download.pytorch.org/libtorch/cu110/libtorch-shared-with-deps-1.7.0%2Bcu110.zip
-           unzip libtorch-shared-with-deps-1.7.0%2Bcu110.zip
+           5) install cudnn (still with new ubuntu?, to check)
+           method 1)
+             sudo apt-get -y install nvidia-cudnn
+             
+           method 2)
+             download cudnn from nvidia (you need to register and downloadmanualy
+             https://developer.nvidia.com/compute/cudnn/secure/8.5.0/local_installers/11.7/cudnn-local-repo-cross-sbsa-ubuntu2204-8.5.0.96_1.0-1_all.deb 
+             copy in your local directory
+             tar xvf cudnn-11.0-linux-x64-v8.0.4.30.tgz
+             sudo ln -s ~/local/cuda/include/cudnn* /usr/local/cuda/include/
+             sudo ln -s ~/local/cuda/lib64/libcudnn* /usr/local/cuda/lib64
+             sudo chmod a+r /usr/local/cuda/include/cudnn*.h /usr/local/cuda/lib64/libcudnn*
+           6) download torch with gpu
+           wget https://download.pytorch.org/libtorch/nightly/cu117/libtorch-shared-with-deps-latest.zip
+           unzip libtorch-shared-with-deps-latest.zip
+           
   
-           6) if you need in python3 
+           7) if you need in python3 
            (with gpu)
-           sudo pip3 install torch==1.7.1+cu110 torchvision==0.8.2+cu110 torchaudio===0.7.2 -f https://download.pytorch.org/whl/torch_stable.html
+           pip3 install --pre torch torchvision torchaudio --extra-index-url https://download.pytorch.org/whl/nightly/cu117
            (without gpu)
-           sudo pip3 install torch==1.7.1+cpu torchvision==0.8.2+cpu torchaudio==0.7.2 -f https://download.pytorch.org/whl/torch_stable.html
+           pip3 install --pre torch torchvision torchaudio --extra-index-url https://download.pytorch.org/whl/nightly/cpu
+           
 
  
 
diff --git a/dG3D/src/FractureCohesiveDG3DIPVariable.h b/dG3D/src/FractureCohesiveDG3DIPVariable.h
index 8438de9525527e2bd3d633db957d15397ba973b1..c65afcd22760d5512e4e78a9214f5a0b542e852a 100644
--- a/dG3D/src/FractureCohesiveDG3DIPVariable.h
+++ b/dG3D/src/FractureCohesiveDG3DIPVariable.h
@@ -183,6 +183,14 @@ class FractureCohesive3DIPVariable : public IPVariable2ForFracture<dG3DIPVariabl
   {
    return _ipvbulk->getRefToDFmdFM();
   }  
+  virtual const STensor53 &getConstRefToDFmdGM() const
+  {
+   return _ipvbulk->getConstRefToDFmdGM();
+  }  
+  virtual STensor53 &getRefToDFmdGM()
+  {
+   return _ipvbulk->getRefToDFmdGM();
+  }
 
   virtual const SVector3 &getConstRefToBm() const
   {
@@ -201,14 +209,7 @@ class FractureCohesive3DIPVariable : public IPVariable2ForFracture<dG3DIPVariabl
   {
    return _ipvbulk->getRefTodBmdGM();
   } 
-  virtual const STensor53 &getConstRefTodPMGdFm() const
-  {
-    return _ipvbulk->getConstRefTodPMGdFm();
-  }  
-  virtual STensor53 &getRefTodPMGdFm()
-  {
-   return _ipvbulk->getRefTodPMGdFm();
-  }  
+  
   virtual const STensor43 &getConstRefTodPmdFM() const
   {
     return _ipvbulk->getConstRefTodPmdFM();
diff --git a/dG3D/src/dG3DDomain.cpp b/dG3D/src/dG3DDomain.cpp
index 769042e90a7d772660e392dcea23738b15d2a1f4..e5f71e42bc5f6a1bce875a67c84de1833cdf2915 100644
--- a/dG3D/src/dG3DDomain.cpp
+++ b/dG3D/src/dG3DDomain.cpp
@@ -1482,6 +1482,423 @@ void dG3DDomain::computedFmdFM(MElement *e, IntPt *GP, AllIPState::ipstateElemen
 }
 
     
+    
+void dG3DDomain::computedFmdGM(AllIPState *aips, MInterfaceElement *ie, IntPt *GP, partDomain* efMinus, partDomain *efPlus,
+                               std::map<Dof, STensor33> &dUdG, std::vector<Dof> &Rm, std::vector<Dof> &Rp,const bool useBarF, const IPStateBase::whichState ws) const   
+{
+  MElement *ele = dynamic_cast<MElement*>(ie);
+  
+  // do nothing if element is already eliminated
+  if (!getElementErosionFilter()(ele)) return;
+  nlsFunctionSpace<double>* _spaceminus = dynamic_cast<nlsFunctionSpace<double>*>(efMinus->getFunctionSpace());
+  nlsFunctionSpace<double>* _spaceplus = dynamic_cast<nlsFunctionSpace<double>*>(efPlus->getFunctionSpace());
+  
+  const dG3DMaterialLaw *mlawMinus = static_cast<const dG3DMaterialLaw*>(this->getMaterialLawMinus());
+  int npts=integBound->getIntPoints(ele,&GP);
+  MElement *em = ie->getElem(0);
+  MElement *ep = ie->getElem(1);
+  AllIPState::ipstateElementContainer *vips = aips->getIPstate(ele->getNum());
+  
+  // Get Gauss points values on minus and plus elements
+  IntPt *GPm; IntPt *GPp;
+  _interQuad->getIntPoints(ie,GP,&GPm,&GPp);
+  static std::vector<SVector3> dBarJdum,dBarJdup;
+  static std::vector< std::vector< STensor33 > > dBarFdum,dBarFdup; //for each GP and for each node
+  if(useBarF){
+      int nbFFm = _spaceminus->getNumShapeFunctions(em,0); // same for component 0, 1, 2
+      int nbFFp = _spaceplus->getNumShapeFunctions(ep,0);
+      dBarJdum.resize(nbFFm);
+      dBarFdum.resize(npts);
+      dBarJdup.resize(nbFFp);
+      dBarFdup.resize(npts);
+      for (int k=0;k<nbFFm;k++){
+        STensorOperation::zero(dBarJdum[k]); //check here if ok
+      }
+      for (int k=0;k<nbFFp;k++){
+        STensorOperation::zero(dBarJdup[k]); //check here if ok
+      }
+      for (int ipg = 0; ipg < npts; ipg++){
+        dBarFdum[ipg].resize(nbFFm);
+        dBarFdup[ipg].resize(nbFFp);
+        for (int k=0;k<nbFFm;k++){
+          STensorOperation::zero(dBarFdum[ipg][k]); //check here if ok
+        }
+        for (int k=0;k<nbFFp;k++){
+          STensorOperation::zero(dBarFdup[ipg][k]); //check here if ok
+        }
+      }
+      
+      double totalWeight=0.;
+      for(int ipg = 0; ipg < npts; ipg++)
+        totalWeight+=GP[ipg].weight;
+      for(int ipg = 0; ipg < npts; ipg++)
+      {
+        const IPStateBase *ipsm = (*vips)[ipg];
+        const dG3DIPVariableBase *ipvm  = static_cast<const dG3DIPVariableBase*>(ipsm->getState(IPStateBase::current));
+        const IPStateBase *ipsp  = (*vips)[ipg+npts];
+        const dG3DIPVariableBase *ipvp     = static_cast<const dG3DIPVariableBase*>(ipsp->getState(IPStateBase::current));
+        const FractureCohesive3DIPVariable *ipvwfm;
+        const FractureCohesive3DIPVariable *ipvwfp;
+        const STensor3 *barFm;
+        const STensor3 *barFp;
+        if(mlawMinus->getType() == materialLaw::fracture )
+        {
+          ipvwfm = static_cast<const FractureCohesive3DIPVariable*>(ipvm);
+          barFm=&ipvwfm->getBulkDeformationGradient(); //this is actually barF
+          ipvwfp = static_cast<const FractureCohesive3DIPVariable*>(ipvp);
+          barFp=&ipvwfp->getBulkDeformationGradient(); //this is actually barF
+        }
+        else
+        {
+          barFm=&ipvm->getConstRefToDeformationGradient(); //this is actually barF
+          barFp=&ipvp->getConstRefToDeformationGradient(); //this is actually barF
+        }
+        const std::vector<TensorialTraits<double>::GradType> &Gradsm = ipvm->gradf(_spaceminus,ie->getElem(0),GPm[ipg]);
+        const std::vector<TensorialTraits<double>::GradType> &Gradsp = ipvp->gradf(_spaceplus,ie->getElem(1),GPp[ipg]);
+
+        STensor3 invBarFm(barFm->invert());
+        double localJm=ipvm->getLocalJ();
+        double barJm=ipvm->getBarJ();
+        double weightm=GP[ipg].weight*pow(localJm,1.-1./((double)(_dim)))*pow(barJm,1./((double)(_dim)))/totalWeight;
+
+        STensor3 invBarFp(barFp->invert());
+        double localJp=ipvp->getLocalJ();
+        double barJp=ipvp->getBarJ();
+        double weightp=GP[ipg].weight*pow(localJp,1.-1./((double)(_dim)))*pow(barJp,1./((double)(_dim)))/totalWeight;
+
+        for(int k=0;k<nbFFm;k++)
+        {
+          SVector3 dBarJduTmp;
+          STensorOperation::zero(dBarJduTmp);
+          for(int ll=0; ll<_dim; ll++)
+          {
+            for(int n=0; n<_dim; n++)
+            {
+              dBarJduTmp(ll) += invBarFm(n,ll)*Gradsm[k][n]*weightm;
+            }
+          }
+          dBarJdum[k]+=dBarJduTmp; 
+        }
+        for(int k=0;k<nbFFp;k++)
+        {
+          SVector3 dBarJduTmp;
+          STensorOperation::zero(dBarJduTmp);
+          for(int ll=0; ll<_dim; ll++)
+          {
+            for(int n=0; n<_dim; n++)
+            {
+              dBarJduTmp(ll) += invBarFp(n,ll)*Gradsp[k][n]*weightp;
+            }
+          }
+          dBarJdup[k]+=dBarJduTmp; 
+        }
+      }
+      
+      static STensor3 I;
+      STensorOperation::unity(I);
+      for (int ipg = 0; ipg < npts; ipg++)
+      {
+        const IPStateBase *ipsm        = (*vips)[ipg];
+        const dG3DIPVariableBase *ipvm     = static_cast<const dG3DIPVariableBase*>(ipsm->getState(IPStateBase::current));
+        const IPStateBase *ipsp        = (*vips)[ipg+npts];
+        const dG3DIPVariableBase *ipvp     = static_cast<const dG3DIPVariableBase*>(ipsp->getState(IPStateBase::current));
+        const FractureCohesive3DIPVariable *ipvwfm;
+        const FractureCohesive3DIPVariable *ipvwfp;
+        const STensor3 *barFm;
+        const STensor3 *barFp;
+        
+        if(mlawMinus->getType() == materialLaw::fracture )
+        {
+          ipvwfm = static_cast<const FractureCohesive3DIPVariable*>(ipvm);
+          barFm=&ipvwfm->getBulkDeformationGradient(); //this is actually barF
+          ipvwfp = static_cast<const FractureCohesive3DIPVariable*>(ipvp);
+          barFp=&ipvwfp->getBulkDeformationGradient(); //this is actually barF
+        }
+        else
+        {
+          barFm=&ipvm->getConstRefToDeformationGradient(); //this is actually barF
+          barFp=&ipvp->getConstRefToDeformationGradient(); //this is actually barF
+        }
+
+        const std::vector<TensorialTraits<double>::GradType> &Gradsm = ipvm->gradf(_spaceminus,ie->getElem(0),GPm[ipg]);
+        const std::vector<TensorialTraits<double>::GradType> &Gradsp = ipvp->gradf(_spaceplus,ie->getElem(1),GPp[ipg]);
+
+        STensor3 invBarFm(barFm->invert());
+        double localJm=ipvm->getLocalJ();
+        double barJm=ipvm->getBarJ();
+        double weightm=GP[ipg].weight*pow(localJm,1.-1./((double)(_dim)))*pow(barJm,1./((double)(_dim)))/totalWeight;
+
+        STensor3 invBarFp(barFp->invert());
+        double localJp=ipvp->getLocalJ();
+        double barJp=ipvp->getBarJ();
+        double weightp=GP[ipg].weight*pow(localJp,1.-1./((double)(_dim)))*pow(barJp,1./((double)(_dim)))/totalWeight;
+
+        for(int k=0;k<nbFFm;k++)
+        {
+          static STensor33 dBarFduTmp;
+          STensorOperation::zero(dBarFduTmp);
+          for(int kk=0; kk<_dim; kk++)
+          {
+            for(int m=0; m<_dim; m++)
+            {
+              for(int jj=0; jj<_dim; jj++)
+              {
+                dBarFduTmp(kk,m,jj) += pow(barJm,1./((double)(_dim)))*pow(localJm,-1./((double)(_dim)))*I(kk,jj)*Gradsm[k](m);
+                for(int p=0; p<_dim; p++)
+                {
+                  dBarFduTmp(kk,m,jj) -= 1./((double)(_dim))*pow(barJm,1./((double)(_dim)))*pow(localJm,-1./((double)(_dim)))*
+                                                        barFm->operator()(kk,m)*invBarFm(p,jj)*Gradsm[k](p);             
+                }
+                dBarFduTmp(kk,m,jj) += 1./((double)(_dim))/barJm*barFm->operator()(kk,m)*dBarJdum[k](jj);
+              }                                
+            }
+          }
+          if(_dim==2 or _dim==1)
+            dBarFduTmp(2,2,2)=Gradsm[k](3);
+          if(_dim==1)
+            dBarFduTmp(1,1,1)=Gradsm[k](2);
+          dBarFdum[ipg][k]=dBarFduTmp;
+        }
+        for(int k=0;k<nbFFp;k++)
+        {
+          static STensor33 dBarFduTmp;
+          STensorOperation::zero(dBarFduTmp);
+          for(int kk=0; kk<_dim; kk++)
+          {
+            for(int m=0; m<_dim; m++)
+            {
+              for(int jj=0; jj<_dim; jj++)
+              {
+                dBarFduTmp(kk,m,jj) += pow(barJp,1./((double)(_dim)))*pow(localJp,-1./((double)(_dim)))*I(kk,jj)*Gradsp[k](m);
+                for(int p=0; p<_dim; p++)
+                {
+                  dBarFduTmp(kk,m,jj) -= 1./((double)(_dim))*pow(barJp,1./((double)(_dim)))*pow(localJp,-1./((double)(_dim)))*
+                                                        barFp->operator()(kk,m)*invBarFp(p,jj)*Gradsp[k](p);             
+                }
+                dBarFduTmp(kk,m,jj) += 1./((double)(_dim))/barJp*barFp->operator()(kk,m)*dBarJdup[k](jj);
+              }                                
+            }
+          }
+          if(_dim==2 or _dim==1)
+            dBarFduTmp(2,2,2)=Gradsp[k](3);
+          if(_dim==1)
+            dBarFduTmp(1,1,1)=Gradsp[k](2);
+          dBarFdup[ipg][k]=dBarFduTmp;
+        }
+      }
+    }
+    
+
+  for(int j=0;j<npts;j++) {    
+     IPStateBase *ipsm = (*vips)[j];
+     IPStateBase *ipsp = (*vips)[j + npts];
+
+     dG3DIPVariableBase *ipvm = static_cast<dG3DIPVariableBase *>(ipsm->getState(ws));
+     dG3DIPVariableBase *ipvp = static_cast<dG3DIPVariableBase *>(ipsp->getState(ws));
+
+     // get shape function gradients
+     const std::vector<TensorialTraits<double>::GradType> &Gradm = ipvm->gradf(_spaceminus, em, GPm[j]);
+     const std::vector<TensorialTraits<double>::GradType> &Gradp = ipvp->gradf(_spaceplus, ep, GPp[j]);
+       
+     STensor53 &dFm = ipvm->getRefToDFmdGM();
+     STensor53 &dFp = ipvp->getRefToDFmdGM();
+     if(dUdG.find(Rm[_spaceminus->getShapeFunctionsIndex(em, 0)]) != dUdG.end()){
+        STensorOperation::zero(dFm);
+        STensorOperation::zero(dFp);
+        for (int cc = 0; cc < 3; cc++) {
+           int nbFFm = _spaceminus->getNumShapeFunctions(em, cc);
+           int nbFFmTotalLast = _spaceminus->getShapeFunctionsIndex(em, cc);
+           int nbFFp = _spaceplus->getNumShapeFunctions(ep, cc);
+           int nbFFpTotalLast = _spaceplus->getShapeFunctionsIndex(ep, cc); 
+        if(useBarF){
+          for (int i = 0; i < nbFFm; i++) {
+             for (int ll = 0; ll < 3; ll++){
+                for (int m = 0; m < 3; m++) {
+                   for (int n = 0; n < 3; n++) {
+                      for (int s = 0; s < 3; s++) {
+                        dFm(ll,0,m,n,s) += dBarFdum[j][i](ll,0,cc) * dUdG[Rm[i + nbFFmTotalLast]](m,n,s);  
+                        dFm(ll,1,m,n,s) += dBarFdum[j][i](ll,1,cc) * dUdG[Rm[i + nbFFmTotalLast]](m,n,s);
+                        dFm(ll,2,m,n,s) += dBarFdum[j][i](ll,2,cc) * dUdG[Rm[i + nbFFmTotalLast]](m,n,s);
+                      }  
+                   }   
+                }
+             }
+          }             
+          for (int i = 0; i < nbFFp; i++) {
+             for (int ll = 0; ll < 3; ll++){
+                for (int m = 0; m < 3; m++) {
+                   for (int n = 0; n < 3; n++) {
+                     for (int s = 0; s < 3; s++) {
+                       dFp(ll,0,m,n,s) += dBarFdup[j][i](ll,0,cc) * dUdG[Rp[i + nbFFpTotalLast]](m,n,s);
+                       dFp(ll,1,m,n,s) += dBarFdup[j][i](ll,1,cc) * dUdG[Rp[i + nbFFpTotalLast]](m,n,s);
+                       dFp(ll,2,m,n,s) += dBarFdup[j][i](ll,2,cc) * dUdG[Rp[i + nbFFpTotalLast]](m,n,s);
+                     }  
+                   }
+                }
+            }   
+         }        
+        }
+        else{                  
+           for (int i = 0; i < nbFFm; i++) {
+             for (int m = 0; m < 3; m++) {
+                for (int n = 0; n < 3; n++) {
+                  for (int s = 0; s < 3; s++) {
+                   dFm(cc,0,m,n,s) += Gradm[i + nbFFmTotalLast][0] * dUdG[Rm[i + nbFFmTotalLast]](m,n,s);  
+                   dFm(cc,1,m,n,s) += Gradm[i + nbFFmTotalLast][1] * dUdG[Rm[i + nbFFmTotalLast]](m,n,s);
+                   dFm(cc,2,m,n,s) += Gradm[i + nbFFmTotalLast][2] * dUdG[Rm[i + nbFFmTotalLast]](m,n,s);
+                  }
+                }
+             }
+          }
+            
+          for (int i = 0; i < nbFFp; i++) {
+             for (int m = 0; m < 3; m++) {
+                for (int n = 0; n < 3; n++) {
+                  for (int s = 0; s < 3; s++) {
+                   dFp(cc,0,m,n,s) += Gradp[i + nbFFpTotalLast][0] * dUdG[Rp[i + nbFFpTotalLast]](m,n,s);
+                   dFp(cc,1,m,n,s) += Gradp[i + nbFFpTotalLast][1] * dUdG[Rp[i + nbFFpTotalLast]](m,n,s);
+                   dFp(cc,2,m,n,s) += Gradp[i + nbFFpTotalLast][2] * dUdG[Rp[i + nbFFpTotalLast]](m,n,s);
+                  }  
+                }
+             }   
+         }
+       }  
+     }  
+   } 
+  }   
+}        
+           
+                
+void dG3DDomain::computedFmdGM(MElement *e, IntPt *GP, AllIPState::ipstateElementContainer *vips, std::map<Dof, STensor33> &dUdG, std::vector<Dof> &R, const bool useBarF, IPStateBase::whichState ws) const
+{
+  if (!getElementErosionFilter()(e)) return;
+  const nlsFunctionSpace<double>* nlspace  = dynamic_cast<const nlsFunctionSpace<double>*>(getFunctionSpace());
+  int npts_bulk=integBulk->getIntPoints(e,&GP);
+  static std::vector<SVector3> dBarJdu;
+  static std::vector< std::vector< STensor33 > > dBarFdu; //for each GP and for each node
+  if(useBarF){
+     int nbFF = nlspace->getNumShapeFunctions(e,0);
+     dBarJdu.resize(nbFF);
+     dBarFdu.resize(npts_bulk);
+     for (int k=0;k<nbFF;k++){
+        STensorOperation::zero(dBarJdu[k]); //check here if ok
+     }
+     for (int ipg = 0; ipg < npts_bulk; ipg++){
+        dBarFdu[ipg].resize(nbFF);
+        for (int k=0;k<nbFF;k++){
+          STensorOperation::zero(dBarFdu[ipg][k]); //check here if ok
+        }
+     }
+     double totalWeight=0.;
+     for(int ipg = 0; ipg < npts_bulk; ipg++)
+        totalWeight+=GP[ipg].weight;
+     for(int ipg = 0; ipg < npts_bulk; ipg++){
+        const IPStateBase *ips = (*vips)[ipg];
+        const dG3DIPVariableBase *ipv  = static_cast<const dG3DIPVariableBase*>(ips->getState(IPStateBase::current));
+        const std::vector<TensorialTraits<double>::GradType>& Gradsipg = ipv->gradf(getFunctionSpace(),e,GP[ipg]);
+        const STensor3 &barF = ipv->getConstRefToDeformationGradient(); //this is actually barF
+        STensor3 invBarF(barF.invert());
+        double localJ=ipv->getLocalJ();
+        double barJ=ipv->getBarJ();
+        double weight=GP[ipg].weight*pow(localJ,1.-(1./((double)(_dim))))*pow(barJ,1./((double)(_dim)))/totalWeight;
+        for(int k=0;k<nbFF;k++)
+        {
+          SVector3 dBarJduTmp;
+          STensorOperation::zero(dBarJduTmp);
+          SVector3 Bipg;
+          Bipg(0) = Gradsipg[k][0];
+          Bipg(1) = Gradsipg[k][1];
+          Bipg(2) = Gradsipg[k][2];
+          for(int ll=0; ll<_dim; ll++)
+          {
+            for(int n=0; n<_dim; n++)
+            {
+              dBarJduTmp(ll) += invBarF(n,ll)*Bipg(n)*weight;
+            }
+          }
+          dBarJdu[k]+=dBarJduTmp; 
+        }
+      }
+      
+      static STensor3 I;
+      STensorOperation::unity(I);
+      for (int ipg = 0; ipg < npts_bulk; ipg++)
+      {
+        const IPStateBase *ips = (*vips)[ipg];
+        const dG3DIPVariableBase *ipv = static_cast<const dG3DIPVariableBase*>(ips->getState(IPStateBase::current));
+        const std::vector<TensorialTraits<double>::GradType>& Gradsipg = ipv->gradf(getFunctionSpace(),e,GP[ipg]);
+        const STensor3 &barF = ipv->getConstRefToDeformationGradient(); //this is actually barF
+        STensor3 invBarF(barF.invert());
+        double localJ=ipv->getLocalJ();
+        double barJ=ipv->getBarJ();
+        for(int k=0;k<nbFF;k++)
+        {
+          static STensor33 dBarFduTmp;
+          STensorOperation::zero(dBarFduTmp);
+          for(int kk=0; kk<_dim; kk++){
+            for(int m=0; m<_dim; m++){
+              for(int jj=0; jj<_dim; jj++){
+                dBarFduTmp(kk,m,jj) += pow(barJ,1./((double)(_dim)))*pow(localJ,-1./((double)(_dim)))*I(kk,jj)*Gradsipg[k](m);
+                for(int p=0; p<_dim; p++){
+                  dBarFduTmp(kk,m,jj) -= 1./((double)(_dim))*pow(barJ,1./((double)(_dim)))*pow(localJ,-1./((double)(_dim)))*barF(kk,m)*invBarF(p,jj)*Gradsipg[k](p);             
+                }
+                dBarFduTmp(kk,m,jj) += 1./((double)(_dim))/barJ*barF(kk,m)*dBarJdu[k](jj);
+              }                                
+            }
+          }
+          if(_dim==2 or _dim==1)
+            dBarFduTmp(2,2,2)=Gradsipg[k](3);
+          if(_dim==1)
+            dBarFduTmp(1,1,1)=Gradsipg[k](2);
+          dBarFdu[ipg][k]=dBarFduTmp;
+        }
+      }
+    }
+  
+  for (int j = 0; j < npts_bulk; j++) {
+     IPStateBase *ips = (*vips)[j];
+     dG3DIPVariableBase *ipv = static_cast<dG3DIPVariableBase *>(ips->getState(ws));
+     // get grad of shape function from Gauss point
+     const std::vector<TensorialTraits<double>::GradType> &Grads = ipv->gradf(getFunctionSpace(), e, GP[j]);
+     STensor53 &dF = ipv->getRefToDFmdGM();
+     if(dUdG.find(R[nlspace->getShapeFunctionsIndex(e, 0)]) != dUdG.end()){
+        STensorOperation::zero(dF);
+        for (int k = 0; k < 3; k++) {
+          int nbFF = nlspace->getNumShapeFunctions(e, k);
+          int nbFFTotalLast = nlspace->getShapeFunctionsIndex(e, k);
+          if(useBarF){
+            for (int i = 0; i < nbFF; i++){
+             for (int ll = 0; ll < 3; ll++){
+               for (int m = 0; m < 3; m++) {
+                 for (int n = 0; n < 3; n++) {
+                   for (int s = 0; s < 3; s++) {
+                     dF(ll,0,m,n,s) += dBarFdu[j][i](ll,0,k) * dUdG[R[i + nbFFTotalLast]](m,n,s);  
+                     dF(ll,1,m,n,s) += dBarFdu[j][i](ll,1,k) * dUdG[R[i + nbFFTotalLast]](m,n,s);  
+                     dF(ll,2,m,n,s) += dBarFdu[j][i](ll,2,k) * dUdG[R[i + nbFFTotalLast]](m,n,s); 
+                   }        
+                 }
+               }
+             }  
+            }     
+         } 
+         else{
+           for (int i = 0; i < nbFF; i++) {
+             for (int m = 0; m < 3; m++) {
+               for (int n = 0; n < 3; n++) {
+                 for (int s = 0; s < 3; s++) {
+                   dF(k,0,m,n,s) += Grads[i + nbFFTotalLast][0] * dUdG[R[i + nbFFTotalLast]](m,n,s);  
+                   dF(k,1,m,n,s) += Grads[i + nbFFTotalLast][1] * dUdG[R[i + nbFFTotalLast]](m,n,s);  
+                   dF(k,2,m,n,s) += Grads[i + nbFFTotalLast][2] * dUdG[R[i + nbFFTotalLast]](m,n,s);     
+                 }      
+               }
+             }
+          } 
+        }  
+      }   
+    } 
+  }
+}
+    
 
 ////ling Wu // begin 
 
@@ -1540,6 +1957,65 @@ void dG3DDomain::setdFmdFM(AllIPState *aips, std::map<Dof, STensor3> &dUdF,const
   }
 };
 
+
+
+
+void dG3DDomain::setdFmdGM(AllIPState *aips, std::map<Dof, STensor33> &dUdG,const IPStateBase::whichState ws){
+  IntPt *GP;
+  std::vector<Dof> Rm;
+  std::vector<Dof> Rp;
+  // interface elements
+  if (gi->size() >0)
+  {
+    dG3DMaterialLaw *mlawMinus = static_cast<dG3DMaterialLaw*>(this->getMaterialLawMinus());
+    dG3DMaterialLaw *mlawPlus = static_cast<dG3DMaterialLaw*>(this->getMaterialLawPlus());
+    dG3DMaterialLaw *mlawbulkm;
+    dG3DMaterialLaw *mlawbulkp;
+    if(mlawMinus->getType() == materialLaw::fracture)
+      mlawbulkm = static_cast< dG3DMaterialLaw* >((static_cast< FractureByCohesive3DLaw* > (mlawMinus) )->getBulkLaw());
+    else
+      mlawbulkm= static_cast<dG3DMaterialLaw*>(mlawMinus);
+    if(mlawPlus->getType() == materialLaw::fracture)
+      mlawbulkp = static_cast< dG3DMaterialLaw* >((static_cast< FractureByCohesive3DLaw* > (mlawPlus) )->getBulkLaw());
+    else
+      mlawbulkp= static_cast<dG3DMaterialLaw*>(mlawPlus);
+    if (mlawbulkm->getUseBarF()!=mlawbulkp->getUseBarF()) //check with the bulk law
+      Msg::Error("dG3DDomain::computeIpv All the constitutive laws need to use Fbar or not");
+    bool useBarF=mlawbulkm->getUseBarF();
+    
+    for(elementGroup::elementContainer::const_iterator it=gi->begin(); it!=gi->end();++it)
+    {
+      MInterfaceElement *ie = dynamic_cast<MInterfaceElement*>(it->second);
+      Rm.clear();
+      this->getMinusDomain()->getFunctionSpace()->getKeys(ie->getElem(0),Rm);
+      Rp.clear();
+      this->getPlusDomain()->getFunctionSpace()->getKeys(ie->getElem(1),Rp);
+      
+      this->computedFmdGM(aips, ie, GP, getMinusDomain(), getPlusDomain(), dUdG, Rm, Rp,useBarF, ws);
+    }
+  }
+  // bulk
+  if (g->size() > 0)
+  {
+    dG3DMaterialLaw *mlaw;
+    if(_mlaw->getType() == materialLaw::fracture)
+      mlaw = static_cast< dG3DMaterialLaw* >((static_cast< FractureByCohesive3DLaw* > (getMaterialLaw()) )->getBulkLaw());
+    else{
+      mlaw= static_cast<dG3DMaterialLaw*>(getMaterialLaw());
+    }
+    bool useBarF=mlaw->getUseBarF();
+    for (elementGroup::elementContainer::const_iterator it = g->begin(); it != g->end(); ++it){
+      MElement *e = it->second;
+      //std::cout << "Elem: " << e->getNum() << std::endl;
+      Rm.clear();
+      getFunctionSpace()->getKeys(e,Rm);
+
+      this->computedFmdGM(e, GP, aips->getIPstate(e->getNum()), dUdG, Rm, useBarF, ws); 
+    }
+  }
+};
+
+
 //ling wu // end
 
 
@@ -2128,15 +2604,12 @@ void dG3DDomain::computeIpv(AllIPState *aips,MElement *e, IPStateBase::whichStat
   }
   bool useBarF=mlaw->getUseBarF();
   bool needDTangent=false;
-  bool usePreviousModuli = false;
+  bool usePresentModuli = false;
   
   if (hasBodyForceForHO()){
-    if(usePresentModuliHO()){
-       needDTangent=true;
-    }   
-    else{ 
-        usePreviousModuli = true;
-    } 
+         needDTangent=true;
+    if(usePresentModuliHO())
+         usePresentModuli = true;
   }      
   if(_evalStiff) { this->computeStrain(e,npts_bulk,GP,vips,ws,disp,useBarF);};
   for(int j=0;j<npts_bulk;j++)
@@ -2153,10 +2626,14 @@ void dG3DDomain::computeIpv(AllIPState *aips,MElement *e, IPStateBase::whichStat
       else
       	mlaw->stress(ipv,ipvprev, stiff,true,needDTangent);
       	
-      if(needDTangent)
-        ipv->setValueForBodyForce(ipv->getConstRefToTangentModuli(),needDTangent); 
-      if(usePreviousModuli)  
-        ipv->setValueForBodyForce(ipvprev->getConstRefToTangentModuli(),needDTangent);   	
+      if(needDTangent){
+        if(usePresentModuli){  
+          ipv->setValueForBodyForce(ipv->getConstRefToTangentModuli(),usePresentModuli); 
+        }
+        else{
+          ipv->setValueForBodyForce(ipvprev->getConstRefToTangentModuli(),usePresentModuli);  
+        } 
+      } 	
     }
     else if (_subSteppingMethod == 2)
     {
@@ -2216,11 +2693,14 @@ void dG3DDomain::computeIpv(AllIPState *aips,MElement *e, IPStateBase::whichStat
         // next step
         iter++;
       }
-      if(needDTangent)
-        ipv->setValueForBodyForce(ipv->getConstRefToTangentModuli(),needDTangent); 
-      if(usePreviousModuli)  
-        ipv->setValueForBodyForce(ipvTemp->getConstRefToTangentModuli(),needDTangent); 
-         
+      if(needDTangent){
+        if(usePresentModuli){
+            ipv->setValueForBodyForce(ipv->getConstRefToTangentModuli(),usePresentModuli); 
+        }    
+        else{  
+            ipv->setValueForBodyForce(ipvTemp->getConstRefToTangentModuli(),usePresentModuli); 
+        }
+      }  
       if (ipvTemp!=NULL) delete ipvTemp;
     }
     else
@@ -3243,15 +3723,12 @@ void dG3DDomain::computeIpv(AllIPState *aips,MInterfaceElement *ie, IntPt *GP,co
 
     int npts=integBound->getIntPoints(ele,&GP);
     bool needDTangent=false;
-    bool usePreviousModuli = false;
+    bool usePresentModuli = false;
   
     if (hasBodyForceForHO()){
-      if(usePresentModuliHO()){
-        needDTangent=true;
-      }   
-      else{ 
-        usePreviousModuli = true;
-      } 
+         needDTangent=true;
+      if(usePresentModuliHO())
+         usePresentModuli = true;
     } 
     AllIPState::ipstateElementContainer *vips = aips->getIPstate(ele->getNum());
     //Msg::Info("nb interf gp %d",npts);
@@ -3426,12 +3903,14 @@ void dG3DDomain::computeIpv(AllIPState *aips,MInterfaceElement *ie, IntPt *GP,co
         Msg::Error("This substepping method %d has not been implemented",_subSteppingMethod);
       }
       if(needDTangent){
-        ipvp->setValueForBodyForce(ipvp->getConstRefToTangentModuli(),needDTangent);
-        ipvm->setValueForBodyForce(ipvm->getConstRefToTangentModuli(),needDTangent);
-      }
-      if(usePreviousModuli){  
-        ipvp->setValueForBodyForce(ipvpprev->getConstRefToTangentModuli(),needDTangent);
-        ipvm->setValueForBodyForce(ipvmprev->getConstRefToTangentModuli(),needDTangent);
+        if(usePresentModuli){  
+          ipvp->setValueForBodyForce(ipvp->getConstRefToTangentModuli(),usePresentModuli);
+          ipvm->setValueForBodyForce(ipvm->getConstRefToTangentModuli(),usePresentModuli);
+        }
+        else{      
+          ipvp->setValueForBodyForce(ipvpprev->getConstRefToTangentModuli(),usePresentModuli);
+          ipvm->setValueForBodyForce(ipvmprev->getConstRefToTangentModuli(),usePresentModuli);
+        }
       }
     }  
   }
@@ -5041,15 +5520,12 @@ void dG3DDomain::computeIPVariableMPI(AllIPState *aips,const unknownField *ufiel
     };
   };
   bool needDTangent=false;
-  bool usePreviousModuli = false;
+  bool usePresentModuli = false;
   
   if (hasBodyForceForHO()){
-    if(usePresentModuliHO()){
-       needDTangent=true;
-    }   
-    else{ 
-        usePreviousModuli = true;
-    } 
+         needDTangent=true;
+    if(usePresentModuliHO())
+         usePresentModuli = true;
   } 
   for (std::set<int>::iterator it = _domainIPBulk.begin(); it != _domainIPBulk.end(); it++){
     int num = *it;
diff --git a/dG3D/src/dG3DDomain.h b/dG3D/src/dG3DDomain.h
index aa4936cf2ea744d80ea4f9d13aa18f8ed3618be0..0c1b2219934211a51bcc5e11c51b22b8bdde3610 100644
--- a/dG3D/src/dG3DDomain.h
+++ b/dG3D/src/dG3DDomain.h
@@ -191,8 +191,13 @@ class dG3DDomain : public dgPartDomain{
                                std::map<Dof, STensor3> &dUdF, std::vector<Dof> &R, const bool useBarF, IPStateBase::whichState ws) const;                                
   virtual void computedFmdFM(AllIPState *aips, MInterfaceElement *ie, IntPt *GP, partDomain* efMinus, partDomain *efPlus,
                                std::map<Dof, STensor3> &dUdF, std::vector<Dof> &Rm, std::vector<Dof> &Rp,const bool useBarF, const IPStateBase::whichState ws) const;
+  virtual void computedFmdGM(MElement *e, IntPt *GP, AllIPState::ipstateElementContainer *vips, 
+                               std::map<Dof, STensor33> &dUdG, std::vector<Dof> &R, const bool useBarF, IPStateBase::whichState ws) const;                                
+  virtual void computedFmdGM(AllIPState *aips, MInterfaceElement *ie, IntPt *GP, partDomain* efMinus, partDomain *efPlus,
+                               std::map<Dof, STensor33> &dUdG, std::vector<Dof> &Rm, std::vector<Dof> &Rp,const bool useBarF, const IPStateBase::whichState ws) const;
   virtual void setDeformationGradientGradient(AllIPState *aips, const STensor33 &GM,const IPStateBase::whichState ws); 
   virtual void setdFmdFM(AllIPState *aips, std::map<Dof, STensor3> &dUdF,const IPStateBase::whichState ws);    
+  virtual void setdFmdGM(AllIPState *aips, std::map<Dof, STensor33> &dUdG,const IPStateBase::whichState ws);  
   virtual void setValuesForBodyForce(AllIPState *aips, const IPStateBase::whichState ws);                           
   virtual void computeAllIPStrain(AllIPState *aips,const unknownField *ufield,const IPStateBase::whichState ws, const bool virt);
   virtual void computeIPVariable(AllIPState *aips,const unknownField *ufield,const IPStateBase::whichState ws, bool stiff);
diff --git a/dG3D/src/dG3DHomogenizedTangentTerms.cpp b/dG3D/src/dG3DHomogenizedTangentTerms.cpp
index 82c3d397bd8b6d2c71f6e8547a71222b7998688e..79eb95eef755a0c69b8d436c8c4a606baf0cd5e0 100644
--- a/dG3D/src/dG3DHomogenizedTangentTerms.cpp
+++ b/dG3D/src/dG3DHomogenizedTangentTerms.cpp
@@ -207,9 +207,7 @@ void dG3DHomogenizedTangent::get(MElement *ele,int npts,IntPt *GP,fullMatrix<dou
       // for high order with body force
      
      if(ipv->hasBodyForceForHO()){
-         const STensor33& dBdF = ipv->getConstRefTodBmdFm();  
-         const STensor53& dPMGdFm = ipv->getConstRefTodPMGdFm();  
-         const STensor43& dPmdFM = ipv->getConstRefTodPmdFM(); 
+         const STensor33& dBdF = ipv->getConstRefTodBmdFm();    
          for (int row=firstRowQ; row< lastRowQ; row++){
            int ii,jj,kk;
            Tensor33::getIntsFromIndex(row-firstRowQ,ii,jj,kk);
@@ -218,16 +216,11 @@ void dG3DHomogenizedTangent::get(MElement *ele,int npts,IntPt *GP,fullMatrix<dou
                for (int r= 0; r<3; r++){
                  if(useBarF){
                    for (int ll= 0; ll<3; ll++){
-                    m(row,j+k*nbFF)-= 0.5*dBdF(ii,ll,r)*(pt[jj]*pt[kk]-_rveGeoInertia(jj,kk)/_rveVolume)*dBarFdu[i][j](ll,r,k)*ratio;
-                    for(int s=0; s<3; s++)
-                     m(row,j+k*nbFF) -= 0.5*(dPMGdFm(ii,jj,s,ll,r)*_rveGeoInertia(s,kk)+ dPMGdFm(ii,kk,s,ll,r)*_rveGeoInertia(s,jj))*dBarFdu[i][j](ll,r,k)*ratio/_rveVolume;                            
+                    m(row,j+k*nbFF)-= 0.5*dBdF(ii,ll,r)*(pt[jj]*pt[kk]-_rveGeoInertia(jj,kk)/_rveVolume)*dBarFdu[i][j](ll,r,k)*ratio;                
                    }   
                  }
                 else{
                   m(row,j+k*nbFF)-= 0.5*dBdF(ii,k,r)*(pt[jj]*pt[kk]-_rveGeoInertia(jj,kk)/_rveVolume) *Grads[j+k*nbFF](r)*ratio;
-                  for(int s=0; s<3; s++){
-                     m(row,j+k*nbFF) -= 0.5*(dPMGdFm(ii,jj,s,k,r)*_rveGeoInertia(s,kk)+ dPMGdFm(ii,kk,s,k,r)*_rveGeoInertia(s,jj))*Grads[j+k*nbFF](r)*ratio/_rveVolume;                 
-                 }
                } 
              }              
         }                        
@@ -454,20 +447,25 @@ void dG3DBodyForceTermPathFollowing::get(MElement *ele,int npts,IntPt *GP,fullVe
   {
     const IPStateBase *ips  = (*vips)[i];
     const dG3DIPVariableBase *ipv  = static_cast<const dG3DIPVariableBase*>(ips->getState(IPStateBase::current));
+    const dG3DIPVariableBase *ipvprev  = static_cast<const dG3DIPVariableBase*>(ips->getState(IPStateBase::previous));
 		
     const std::vector<TensorialTraits<double>::ValType>&  Vals = ipv->f(sp,ele,GP[i]);		
     const double weight = GP[i].weight;
     double &detJ = ipv->getJacobianDeterminant(ele,GP[i]);
 		
     const double ratio = detJ*weight;
-    SVector3 Bm;
-    ipv->computeBodyForce(G, Bm);
+  //  SVector3 Bm;
+  //  ipv->computeBodyForce(G, Bm);
+    const SVector3 &Bm0 = ipvprev->getConstRefToBm();
+    const SVector3 &Bm = ipv->getConstRefToBm();
+  
+    
       
     if (_dom->getHomogenizationOrder() == 2 and ipv->hasBodyForceForHO())
     {
        for (int j=0; j<nbFF; j++)
           for (int k=0; k<3; k++){
-              bm(j+k*nbFF)+= Bm(k)*Vals[j+k*nbFF]*ratio;
+              bm(j+k*nbFF)+= (Bm(k)-Bm0(k))*Vals[j+k*nbFF]*ratio;
           }           
     }	
   }
diff --git a/dG3D/src/dG3DIPVariable.cpp b/dG3D/src/dG3DIPVariable.cpp
index f73b15f8db64a72a9ad07f9e66a154218d9988c6..016944b880bd11b77ff359cd264bc8b04bd42e05 100644
--- a/dG3D/src/dG3DIPVariable.cpp
+++ b/dG3D/src/dG3DIPVariable.cpp
@@ -113,7 +113,7 @@ bodyForceForHO::bodyForceForHO()
 {
   STensorOperation::unity(dFmdFM);
 };
-bodyForceForHO::bodyForceForHO(const bodyForceForHO& src):  GM(src.GM), dFmdFM(src.dFmdFM), Bm(src.Bm), dBmdFm(src.dBmdFm), dBmdGM(src.dBmdGM), dCmdFm(src.dCmdFm), dPMGdFm(src.dPMGdFm), dPmdFM(src.dPmdFM) 
+bodyForceForHO::bodyForceForHO(const bodyForceForHO& src):  GM(src.GM), dFmdFM(src.dFmdFM),  dFmdGM(src.dFmdGM), Bm(src.Bm), dBmdFm(src.dBmdFm), dBmdGM(src.dBmdGM), dCmdFm(src.dCmdFm), dPmdFM(src.dPmdFM) 
 {
 
 };
@@ -121,11 +121,11 @@ bodyForceForHO& bodyForceForHO::operator = (const bodyForceForHO& src)
 {
     GM=src.GM;
     dFmdFM=src.dFmdFM;
+    dFmdGM=src.dFmdGM;
     Bm = src.Bm;
     dBmdFm=src.dBmdFm;
     dBmdGM=src.dBmdGM;
     dCmdFm=src.dCmdFm;
-    dPMGdFm=src.dPMGdFm;
     dPmdFM =src.dPmdFM;
     return *this;
 };
@@ -133,11 +133,11 @@ void bodyForceForHO::restart()
 {
   restartManager::restart(GM);
   restartManager::restart(dFmdFM);
+  restartManager::restart(dFmdGM);
   restartManager::restart(Bm);
   restartManager::restart(dBmdFm);
   restartManager::restart(dBmdGM);
   restartManager::restart(dCmdFm);
-  restartManager::restart(dPMGdFm);
   restartManager::restart(dPmdFM);
 };
 //
@@ -1097,6 +1097,21 @@ double dG3DIPVariable::get(const int comp) const
       return CL(2,2);
     }
   }
+  else if (comp == IPField::BODYFORCE_X){
+    if(hasBodyForceForHO())
+      return _bodyForceForHO->Bm(0);
+    else  return 0.0;  
+  }
+  else if (comp == IPField::BODYFORCE_Y){
+    if(hasBodyForceForHO())
+      return _bodyForceForHO->Bm(1);
+    else  return 0.0;  
+  }
+  else if (comp == IPField::BODYFORCE_Z){
+    if(hasBodyForceForHO())
+      return _bodyForceForHO->Bm(2);
+    else  return 0.0;  
+  }
   else
      return 0.;
   return 0.;
@@ -1161,6 +1176,8 @@ void dG3DIPVariable::computeBodyForce(const STensor33& G, SVector3& B) const{
 
 
 void dG3DIPVariable::setValueForBodyForce(const STensor43& K, const bool usePresentModuli){
+  // STensor43& K = elasticTangentModuli;
+
  if(hasBodyForceForHO()){
    static STensor33 tmp1;
    static STensor33 tmp2;
@@ -1177,6 +1194,7 @@ void dG3DIPVariable::setValueForBodyForce(const STensor43& K, const bool usePres
         }
       }
     }
+   
     STensorOperation::zero(_bodyForceForHO->dBmdGM);
     for (int i=0; i<3; i++){
       for (int j=0; j<3; j++){
@@ -1190,7 +1208,6 @@ void dG3DIPVariable::setValueForBodyForce(const STensor43& K, const bool usePres
       }
     }
     STensorOperation::zero(_bodyForceForHO->dBmdFm);
-    STensorOperation::zero(_bodyForceForHO->dPMGdFm);
     if(usePresentModuli){
       STensorOperation::multSTensor43STensor33(_bodyForceForHO->dFmdFM, _bodyForceForHO->GM, tmp1);
       STensorOperation::multSTensor43STensor33RightTranspose(_bodyForceForHO->dFmdFM, _bodyForceForHO->GM, tmp2);
@@ -1201,9 +1218,6 @@ void dG3DIPVariable::setValueForBodyForce(const STensor43& K, const bool usePres
                 for (int p=0; p<3; p++){
                   for (int q=0; q<3; q++){                    
                       _bodyForceForHO->dBmdFm(i,p,q) -= _bodyForceForHO->dCmdFm(i,j,k,l,p,q)*(tmp1(k,l,j)+tmp2(k,l,j))/2.0;                            
-                    for (int s=0; s<3; s++){
-                      _bodyForceForHO->dPMGdFm(i,j,s,p,q) += _bodyForceForHO->dCmdFm(i,j,k,l,p,q)*(tmp1(k,l,s)+tmp2(k,l,s))/2.0;
-                    }
                   }
                 }
              }    
diff --git a/dG3D/src/dG3DIPVariable.h b/dG3D/src/dG3DIPVariable.h
index ee551a5cb1d1a7c17d2bb86098da6d44227a39aa..c2527007704810707342e33e77940eb8a28f7a7e 100644
--- a/dG3D/src/dG3DIPVariable.h
+++ b/dG3D/src/dG3DIPVariable.h
@@ -164,11 +164,11 @@ class dG3DIPVariableBase : public ipFiniteStrain
   virtual STensor43 &getRefTodBmdGM()=0;
   virtual const STensor43 &getConstRefToDFmdFM() const=0;
   virtual STensor43 &getRefToDFmdFM()=0;
+  virtual const STensor53 &getConstRefToDFmdGM() const=0;
+  virtual STensor53 &getRefToDFmdGM()=0;
   virtual const STensor63 &getConstRefTodCmdFm() const=0;
   virtual STensor63 &getRefTodCmdFm()=0;
   virtual STensor63 *getPtrTodCmdFm()=0;
-  virtual const STensor53 &getConstRefTodPMGdFm() const=0;
-  virtual STensor53 &getRefTodPMGdFm()=0;
   virtual const STensor43 &getConstRefTodPmdFM() const=0;
   virtual STensor43 &getRefTodPmdFM()=0;
   //-----------------get 1st piola before AV ------------//
@@ -384,11 +384,11 @@ class bodyForceForHO{
 
     STensor33 GM;
     STensor43 dFmdFM;
+    STensor53 dFmdGM;
     SVector3 Bm;
     STensor33 dBmdFm;
     STensor43 dBmdGM;
     STensor63 dCmdFm;
-    STensor53 dPMGdFm;
     STensor43 dPmdFM;
 
   public:
@@ -717,8 +717,8 @@ protected:
       return _bodyForceForHO->dFmdFM;
     else{
       Msg::Error("getConstRefToDFmdFM is not defined");
-    static STensor43 VoidGM;
-    return VoidGM;
+    static STensor43 VoiddFmdFM;
+    return VoiddFmdFM;
     }
   }  
   virtual STensor43 &getRefToDFmdFM()
@@ -732,6 +732,28 @@ protected:
       return VoiddFmdFM;
     }
   }  
+  
+  virtual const STensor53 &getConstRefToDFmdGM() const
+  {
+    if(hasBodyForceForHO())
+      return _bodyForceForHO->dFmdGM;
+    else{
+      Msg::Error("getConstRefToDFmdGM is not defined");
+    static STensor53 VoiddFmdGM;
+    return VoiddFmdGM;
+    }
+  }  
+  virtual STensor53 &getRefToDFmdGM()
+  {
+    if(hasBodyForceForHO())
+      return _bodyForceForHO->dFmdGM;
+    else
+    {
+      Msg::Error("getRefToDFmdGM is not defined");
+      static STensor53 VoiddFmdGM;
+      return VoiddFmdGM;
+    }
+  }  
 
 virtual const SVector3 &getConstRefToBm() const
   {
@@ -801,28 +823,6 @@ virtual STensor33 &getRefTodBmdFm()
     }
   }  
   
-virtual const STensor53 &getConstRefTodPMGdFm() const
-  {
-    if(hasBodyForceForHO())
-      return _bodyForceForHO->dPMGdFm;
-    else
-    {
-      Msg::Error("getConstRefTodPMGdFm is not defined");
-      static STensor53 VoiddPMGdFm;
-      return VoiddPMGdFm;
-    }
-  }  
-virtual STensor53 &getRefTodPMGdFm()
-  {
-    if(hasBodyForceForHO())
-      return _bodyForceForHO->dPMGdFm;
-    else
-    {
-      Msg::Error("getRefTodPMGdFm is not defined");
-      static STensor53 VoiddPMGdFm;
-      return VoiddPMGdFm;
-    }
-  }
 
 virtual const STensor43 &getConstRefTodPmdFM() const
   {
diff --git a/dG3D/src/nonLocalDamageDG3DIPVariable.h b/dG3D/src/nonLocalDamageDG3DIPVariable.h
index 400eb483d71a3e659e0f7323ddabf66edcb93694..d9c4f62026315008a62a286e826fe57004a24b37 100644
--- a/dG3D/src/nonLocalDamageDG3DIPVariable.h
+++ b/dG3D/src/nonLocalDamageDG3DIPVariable.h
@@ -259,6 +259,28 @@ class virtualNonLocalDamageDG3DIPVariable : public dG3DIPVariableBase{
     }
   }  
   
+  virtual const STensor53 &getConstRefToDFmdGM() const
+  {
+    if(hasBodyForceForHO())
+      return _bodyForceForHO->dFmdGM;
+    else
+      Msg::Error("getConstRefToDFmdGM is not defined");
+    static STensor53 VoiddFmdGM;
+    return VoiddFmdGM;
+  }  
+  virtual STensor53 &getRefToDFmdGM()
+  {
+    if(hasBodyForceForHO())
+      return _bodyForceForHO->dFmdGM;
+    else
+    {
+      Msg::Error("getRefToDFmdGM is not defined");
+      static STensor53 VoiddFmdGM;
+      return VoiddFmdGM;
+    }
+  }  
+  
+  
   virtual const SVector3 &getConstRefToBm() const
   {
     if(hasBodyForceForHO())
@@ -327,30 +349,6 @@ virtual STensor33 &getRefTodBmdFm()
     }
   }  
 
-
-
-virtual const STensor53 &getConstRefTodPMGdFm() const
-  {
-    if(hasBodyForceForHO())
-      return _bodyForceForHO->dPMGdFm;
-    else
-    {
-      Msg::Error("getConstRefTodPMGdFm is not defined");
-      static STensor53 VoiddPMGdFm;
-      return VoiddPMGdFm;
-    }
-  }  
-virtual STensor53 &getRefTodPMGdFm()
-  {
-    if(hasBodyForceForHO())
-      return _bodyForceForHO->dPMGdFm;
-    else
-    {
-      Msg::Error("getRefTodPMGdFm is not defined");
-      static STensor53 VoiddPMGdFm;
-      return VoiddPMGdFm;
-    }
-  } 
   
 virtual const STensor43 &getConstRefTodPmdFM() const
   {