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 {