diff --git a/NonLinearSolver/internalPoints/ipField.cpp b/NonLinearSolver/internalPoints/ipField.cpp index cad06a1bdb708f3a9e133d133d7ee0a5286b3dd7..bbbe9e24b9763e827506ec81c5ea158c46b246a5 100644 --- a/NonLinearSolver/internalPoints/ipField.cpp +++ b/NonLinearSolver/internalPoints/ipField.cpp @@ -1041,6 +1041,16 @@ std::string IPField::ToString(const int i){ else if (i == corKir_XY) return "corKir_XY"; else if (i == corKir_XZ) return "corKir_XZ"; else if (i == corKir_YZ) return "corKir_YZ"; + else if (i == mandel_XX) return "mandel_XX"; + else if (i == mandel_YY) return "mandel_YY"; + else if (i == mandel_ZZ) return "mandel_ZZ"; + else if (i == mandel_XY) return "mandel_XY"; + else if (i == mandel_XZ) return "mandel_XZ"; + else if (i == mandel_YZ) return "mandel_YZ"; + else if (i == mandel_YX) return "mandel_YX"; + else if (i == mandel_ZX) return "mandel_ZX"; + else if (i == mandel_ZY) return "mandel_ZY"; + else if (i == mandelCommuteChecker) return "mandelCommuteChecker"; else if (i == corKirExtra_XX) return "corKirExtra_XX"; else if (i == corKirExtra_YY) return "corKirExtra_YY"; else if (i == corKirExtra_ZZ) return "corKirExtra_ZZ"; diff --git a/NonLinearSolver/internalPoints/ipField.h b/NonLinearSolver/internalPoints/ipField.h index 9804de242a5b0f85fc8ddbf05bd849c3b8512d69..1c6bdb3b7a97bca82976ae75363f54807d21185f 100644 --- a/NonLinearSolver/internalPoints/ipField.h +++ b/NonLinearSolver/internalPoints/ipField.h @@ -323,7 +323,7 @@ class IPField : public elementsField { Ee_XX, Ee_YY, Ee_ZZ, Ee_XY, Ee_XZ, Ee_YZ, Eve1_XX, Eve1_YY, Eve1_ZZ, Eve1_XY, Eve1_XZ, Eve1_YZ, Eve2_XX, Eve2_YY, Eve2_ZZ, Eve2_XY, Eve2_XZ, Eve2_YZ, - corKir_XX, corKir_YY, corKir_ZZ, corKir_XY, corKir_XZ, corKir_YZ, + corKir_XX, corKir_YY, corKir_ZZ, corKir_XY, corKir_XZ, corKir_YZ, mandel_XX, mandel_YY, mandel_ZZ, mandel_XY, mandel_XZ, mandel_YZ, mandel_YX, mandel_ZX, mandel_ZY, mandelCommuteChecker, corKirExtra_XX, corKirExtra_YY, corKirExtra_ZZ, corKirExtra_XY, corKirExtra_XZ, corKirExtra_YZ, Dev_corKir_Inf_XX, Dev_corKir_Inf_YY, Dev_corKir_Inf_ZZ, Dev_corKir_Inf_XY, Dev_corKir_Inf_XZ, Dev_corKir_Inf_YZ, Tr_corKir_Inf, hyperElastic_BulkScalar,hyperElastic_ShearScalar, diff --git a/NonLinearSolver/internalPoints/ipHyperelastic.cpp b/NonLinearSolver/internalPoints/ipHyperelastic.cpp index 80e933732a4f4bbb42238953287a40a25a6707fd..dfabd5fc5a4c9b501aff7ec2b19f4d318985d4ef 100644 --- a/NonLinearSolver/internalPoints/ipHyperelastic.cpp +++ b/NonLinearSolver/internalPoints/ipHyperelastic.cpp @@ -15,14 +15,15 @@ IPHyperViscoElastic::IPHyperViscoElastic(const int N):IPVariableMechanics(),_N(N),_elasticEnergy(0.),_Ee(0.),_kirchhoff(0.), _irreversibleEnergy(0.),_DirreversibleEnergyDF(0.), _viscousEnergyPart(0.), _dElasticEnergyPartdF(0.), _dViscousEnergyPartdF(0.), _elasticBulkPropertyScaleFactor(1.), _elasticShearPropertyScaleFactor(1.), - _intA(0.), _intB(0.), _DintA(0.), _DintB(0.) + _intA(0.), _intB(0.), _DintA(0.), _DintB(0.), _Re(0.), _Re0(0.), _Ee0(0.) { - _A.clear(); + _A.clear(); _A_rot.clear(); _B.clear(); _psi_branch.clear(); for (int i=0; i< N; i++){ STensor3 el(0.); _A.push_back(el); + _A_rot.push_back(el); _B.push_back(0.); _psi_branch.push_back(0.); } @@ -32,7 +33,7 @@ IPHyperViscoElastic::IPHyperViscoElastic(const IPHyperViscoElastic& src): IPVari _irreversibleEnergy(src._irreversibleEnergy),_DirreversibleEnergyDF(src._DirreversibleEnergyDF), _viscousEnergyPart(src._viscousEnergyPart), _dElasticEnergyPartdF(src._dElasticEnergyPartdF), _dViscousEnergyPartdF(src._dViscousEnergyPartdF), _elasticBulkPropertyScaleFactor(src._elasticBulkPropertyScaleFactor), _elasticShearPropertyScaleFactor(src._elasticShearPropertyScaleFactor), - _intA(src._intA),_intB(src._intB), _psi_branch(src._psi_branch), _DintA(src._DintA),_DintB(src._DintB) + _intA(src._intA),_intB(src._intB), _psi_branch(src._psi_branch), _DintA(src._DintA),_DintB(src._DintB), _A_rot(src._A_rot), _Re(src._Re), _Re0(src._Re0), _Ee0(src._Ee0) { @@ -60,6 +61,10 @@ IPHyperViscoElastic& IPHyperViscoElastic::operator =(const IPVariable& src){ _DintA= psrc->_DintA; _DintB= psrc->_DintB; _psi_branch= psrc->_psi_branch; + _A_rot=psrc->_A_rot; + _Re=psrc->_Re; + _Re0=psrc->_Re0; + _Ee0=psrc->_Ee0; } return *this; }; @@ -84,6 +89,10 @@ void IPHyperViscoElastic::restart() { restartManager::restart(_DintA); restartManager::restart(_DintB); restartManager::restart(_psi_branch); + restartManager::restart(_A_rot); + restartManager::restart(_Re); + restartManager::restart(_Re0); + restartManager::restart(_Ee0); }; void IPHyperViscoElastic::getViscoElasticStrain(int i, STensor3& Ev) const diff --git a/NonLinearSolver/internalPoints/ipHyperelastic.h b/NonLinearSolver/internalPoints/ipHyperelastic.h index e1ccba37b8d58702163381fc7aaf4aa286c91424..5ec1b777bb9234638dba16c5c106bcd665de384c 100644 --- a/NonLinearSolver/internalPoints/ipHyperelastic.h +++ b/NonLinearSolver/internalPoints/ipHyperelastic.h @@ -20,11 +20,14 @@ class IPHyperViscoElastic : public IPVariableMechanics{ public: //viscoelastic history int _N; // number spring-Dashpot of element - std::vector<STensor3> _A; // N elements + std::vector<STensor3> _A, _A_rot; // N elements std::vector<double> _B; // N elements double _elasticEnergy; // elastic energy stored STensor3 _Ee; // elastic strain STensor3 _kirchhoff; // corotational Kirchhoff stress + STensor3 _Re; // rotation tensor: Fe = Re . Ue + STensor3 _Re0; // rotation tensor: Fe0 = Re0 . Ue0 + STensor3 _Ee0; // rotation tensor: Fe0 = Re0 . Ue0 double _irreversibleEnergy; STensor3 _DirreversibleEnergyDF; diff --git a/NonLinearSolver/internalPoints/ipNonLinearTVM.cpp b/NonLinearSolver/internalPoints/ipNonLinearTVM.cpp index be3d6fa710da72276bb524fffa4f80dee755e31a..2add8a286b6acb57644da770eb524c9b0daa8e65 100644 --- a/NonLinearSolver/internalPoints/ipNonLinearTVM.cpp +++ b/NonLinearSolver/internalPoints/ipNonLinearTVM.cpp @@ -21,7 +21,8 @@ IPNonLinearTVM::IPNonLinearTVM(const J2IsotropicHardening* comp, _psiMax(0.), _mullinsDamage(0.), _DpsiDT(0.), _DpsiDE(0.), _DmullinsDamage_Dpsi_cap(0.), _DmullinsDamage_DT(0.), _P_cap(0.), _pressure(0.), _Av_TVE(1.), _Bd_TVE(1.), _dAv_dTrEe(0.), _dBd_dTrEe(0.), _dAv_dTrEe_TVE(0.), _intAv_TVE(0.), _intBd_TVE(0.), _intAv_1_TVE(0.), _intBd_1_TVE(0.), _intAv_2_TVE(0.), _intBd_2_TVE(0.), _dBd_dDevEe(0.), _dBd_dDevEe_TVE(0.), - _viscousDissipatedEnergy(0.), _mullinsDissipatedEnergy(0.), _psiInfCorrector(0.){ + _viscousDissipatedEnergy(0.), _mullinsDissipatedEnergy(0.), _psiInfCorrector(0.), _ModMandel(0.), _mandelCommuteChecker(0.), + _R(0.),_dRdEe(0.),_dRtdEe(0.){ _DA_DT.clear(); _DDA_DTT.clear(); _DA_DtrE.clear(); _DDA_DTDtrE.clear(); @@ -80,7 +81,8 @@ IPNonLinearTVM::IPNonLinearTVM(const IPNonLinearTVM& src): IPHyperViscoElastoPla _Av_TVE_vector(src._Av_TVE_vector), _Bd_TVE_vector(src._Bd_TVE_vector), _dAv_dTrEe_TVE_vector(src._dAv_dTrEe_TVE_vector), _dBd_dTrEe_TVE_vector(src._dBd_dTrEe_TVE_vector), _intAv_TVE_vector(src._intAv_TVE_vector), _intBd_TVE_vector(src._intBd_TVE_vector),_DintAv_TVE_vector(src._DintAv_TVE_vector), _DintBd_TVE_vector(src._DintBd_TVE_vector), _dBd_dDevEe_TVE_vector(src._dBd_dDevEe_TVE_vector), - _viscousDissipatedEnergy(src._viscousDissipatedEnergy), _mullinsDissipatedEnergy(src._mullinsDissipatedEnergy), _psiInfCorrector(src._psiInfCorrector){ + _viscousDissipatedEnergy(src._viscousDissipatedEnergy), _mullinsDissipatedEnergy(src._mullinsDissipatedEnergy), _psiInfCorrector(src._psiInfCorrector), + _ModMandel(src._ModMandel), _mandelCommuteChecker(src._mandelCommuteChecker),_R(src._R),_dRdEe(src._dRdEe),_dRtdEe(src._dRtdEe){ if (src._ipMullinsEffect != NULL) _ipMullinsEffect = dynamic_cast<IPMullinsEffect*>(src._ipMullinsEffect->clone()); @@ -153,6 +155,11 @@ IPNonLinearTVM& IPNonLinearTVM::operator=(const IPVariable& src) _viscousDissipatedEnergy = psrc->_viscousDissipatedEnergy; _mullinsDissipatedEnergy = psrc->_mullinsDissipatedEnergy; _psiInfCorrector = psrc->_psiInfCorrector; + _ModMandel = psrc->_ModMandel; + _mandelCommuteChecker = psrc->_mandelCommuteChecker; + _R = psrc->_R; + _dRdEe = psrc->_dRdEe; + _dRtdEe = psrc->_dRtdEe; if ( psrc->_ipMullinsEffect != NULL) { if (_ipMullinsEffect == NULL){ @@ -239,6 +246,11 @@ void IPNonLinearTVM::restart(){ restartManager::restart(_viscousDissipatedEnergy); restartManager::restart(_mullinsDissipatedEnergy); restartManager::restart(_psiInfCorrector); + restartManager::restart(_ModMandel); + restartManager::restart(_mandelCommuteChecker); + restartManager::restart(_R); + restartManager::restart(_dRdEe); + restartManager::restart(_dRtdEe); if (_ipMullinsEffect != NULL) restartManager::restart(_ipMullinsEffect); diff --git a/NonLinearSolver/internalPoints/ipNonLinearTVM.h b/NonLinearSolver/internalPoints/ipNonLinearTVM.h index 755f0cdd36d5d89c68c2e58fa3701882acad9aa9..0d77fe80ea600c632c1f7aa3d8df92d21946524e 100644 --- a/NonLinearSolver/internalPoints/ipNonLinearTVM.h +++ b/NonLinearSolver/internalPoints/ipNonLinearTVM.h @@ -30,6 +30,10 @@ class IPNonLinearTVM : public IPHyperViscoElastoPlastic{ double _DmechSrcTVEdT; STensor3 _DmechSrcTVEdE; + // mandel and commuteChecker + STensor3 _ModMandel; + double _mandelCommuteChecker; + // CorKir - Inf and extraBranch TVE double _trCorKirinf_TVE; STensor3 _devCorKirinf_TVE; @@ -74,6 +78,11 @@ class IPNonLinearTVM : public IPHyperViscoElastoPlastic{ double _viscousDissipatedEnergy; double _mullinsDissipatedEnergy; + // Rotation tensors & derivatives + STensor3 _R; + STensor43 _dRdEe, _dRtdEe; + + public: IPNonLinearTVM(const J2IsotropicHardening* comp, const J2IsotropicHardening* trac, diff --git a/NonLinearSolver/internalPoints/ipNonLinearTVP.cpp b/NonLinearSolver/internalPoints/ipNonLinearTVP.cpp index aec94de8f42fb64858adc4c1ded5468450f67901..79f7847a74c358e5f607c4fdc858e8edbc9b5553 100644 --- a/NonLinearSolver/internalPoints/ipNonLinearTVP.cpp +++ b/NonLinearSolver/internalPoints/ipNonLinearTVP.cpp @@ -15,7 +15,7 @@ IPNonLinearTVP::IPNonLinearTVP(const J2IsotropicHardening* comp, const J2Isotrop const kinematicHardening* kin, const int N, const mullinsEffect* mullins):IPNonLinearTVM(comp,trac,kin,N,mullins), _DgammaDT(0.),_DGammaDT(0.), _DGammaDF(0.), _DirreversibleEnergyDT(0.), _psiTVM(0.), _DpsiTVMdT(0.), _DDpsiTVMdTT(0.), - _ModMandel(0.),_DModMandelDT(0.), _DbackSigDT(0.), _DModMandelDF(0.), _DbackSigDF(0.), _DphiPDF(0.), _GammaN(0.), _dGammaNdT(0.), _dGammaNdF(0.), + _DModMandelDT(0.), _DbackSigDT(0.), _DModMandelDF(0.), _DbackSigDF(0.), _DphiPDF(0.), _GammaN(0.), _dGammaNdT(0.), _dGammaNdF(0.), _mechSrcTVP(0.),_DmechSrcTVPdT(0.),_DmechSrcTVPdF(0.), _dPlasticEnergyPartdT(0.),_dElasticEnergyPartdT(0.),_dViscousEnergyPartdT(0.), _IsoHardForce_simple(0.), _dIsoHardForcedT_simple(0.), _dIsoHardForcedF_simple(0.), _DphiDF(0.),_DphiDT(0.) @@ -38,7 +38,7 @@ IPNonLinearTVP::IPNonLinearTVP(const IPNonLinearTVP& src):IPNonLinearTVM(src), _ddIsoHardForcedTT(src._ddIsoHardForcedTT), _psiTVM(src._psiTVM), _DpsiTVMdT(src._DpsiTVMdT), _DDpsiTVMdTT(src._DDpsiTVMdTT), _mechSrcTVP(src._mechSrcTVP),_DmechSrcTVPdT(src._DmechSrcTVPdT),_DmechSrcTVPdF(src._DmechSrcTVPdF), - _ModMandel(src._ModMandel), _DModMandelDT(src._DModMandelDT), _DbackSigDT(src._DbackSigDT), _DphiPDF(src._DphiPDF), + _DModMandelDT(src._DModMandelDT), _DbackSigDT(src._DbackSigDT), _DphiPDF(src._DphiPDF), _GammaN(src._GammaN), _dGammaNdT(src._dGammaNdT), _dGammaNdF(src._dGammaNdF), _DModMandelDF(src._DModMandelDF), _DbackSigDF(src._DbackSigDF), _dPlasticEnergyPartdT(src._dPlasticEnergyPartdT),_dElasticEnergyPartdT(src._dElasticEnergyPartdT), @@ -69,7 +69,6 @@ IPNonLinearTVP& IPNonLinearTVP::operator =(const IPVariable &source){ _mechSrcTVP = ps->_mechSrcTVP; _DmechSrcTVPdT = ps->_DmechSrcTVPdT; _DmechSrcTVPdF = ps->_DmechSrcTVPdF; - _ModMandel = ps->_ModMandel; _DModMandelDT = ps->_DModMandelDT; _DModMandelDF = ps->_DModMandelDF; _DbackSigDT = ps->_DbackSigDT; @@ -111,7 +110,6 @@ void IPNonLinearTVP::restart() { restartManager::restart(_mechSrcTVP); restartManager::restart(_DmechSrcTVPdT); restartManager::restart(_DmechSrcTVPdF); - restartManager::restart(_ModMandel); restartManager::restart(_DModMandelDT); restartManager::restart(_DModMandelDF); restartManager::restart(_DbackSigDT); diff --git a/NonLinearSolver/internalPoints/ipNonLinearTVP.h b/NonLinearSolver/internalPoints/ipNonLinearTVP.h index 8cc1e9aed6195f5003e2f9345e44321baec0b579..750c5bb400b4a38a029cef3a1a4ae8541f39d9cf 100644 --- a/NonLinearSolver/internalPoints/ipNonLinearTVP.h +++ b/NonLinearSolver/internalPoints/ipNonLinearTVP.h @@ -39,7 +39,6 @@ class IPNonLinearTVP : public IPNonLinearTVM{ double _DDpsiTVMdTT; STensor3 _DGammaDF; - STensor3 _ModMandel; STensor3 _DModMandelDT; STensor3 _DbackSigDT; STensor3 _DphiDT; diff --git a/NonLinearSolver/materialLaw/CMakeLists.txt b/NonLinearSolver/materialLaw/CMakeLists.txt index 341ace0e973297e1d0654f9ac325875f6b289b94..bed4818d58f43a62c966e84079fdc99d77bc8d92 100644 --- a/NonLinearSolver/materialLaw/CMakeLists.txt +++ b/NonLinearSolver/materialLaw/CMakeLists.txt @@ -107,6 +107,7 @@ set(SRC mlawNonLinearTVE.cpp mlawNonLinearTVP.cpp mlawNonLinearTVENonLinearTVP.cpp + mlawNonLinearTVENonLinearTVP2.cpp mlawCoupledThermoMechanics.cpp mullinsEffect.cpp mlawHyperelasticWithPotential.cpp diff --git a/NonLinearSolver/materialLaw/STensorOperations.cpp b/NonLinearSolver/materialLaw/STensorOperations.cpp index 528c234ad730164c81e23deca9458421b9d17b88..59c2e516af09e8daf095e5fa11ee9cbe3543b6e0 100644 --- a/NonLinearSolver/materialLaw/STensorOperations.cpp +++ b/NonLinearSolver/materialLaw/STensorOperations.cpp @@ -362,17 +362,17 @@ void STensorOperation::expSTensor3(const STensor3& a, const int order, STensor3& } void STensorOperation::getEigenDecomposition(const STensor3& a, double& x1, double& x2, double& x3, STensor3& E1, STensor3& E2, STensor3& E3, - STensor3& dx1da, STensor3& dx2da, STensor3& dx3da, STensor43& dE1da, STensor43& dE2da, STensor43& dE3da) -{ - getEigenDecomposition(a, x1, x2, x3, E1, E2, E3); + STensor3& dx1da, STensor3& dx2da, STensor3& dx3da, STensor43& dE1da, STensor43& dE2da, STensor43& dE3da){ + + getEigenDecomposition(a, x1, x2, x3, E1, E2, E3); + /* double x1p,x2p,x3p,x1m,x2m,x3m; static STensor3 E1p,E2p,E3p, E1m,E2m, E3m, ap, am; double pert=1.e-9; - for(int i=0; i<3; i++) - { - for(int j=0; j<3; j++) - { + + for(int i=0; i<3; i++){ + for(int j=0; j<3; j++){ ap=a; am=a; ap(i,j)=ap(i,j)+pert; @@ -392,10 +392,231 @@ void STensorOperation::getEigenDecomposition(const STensor3& a, double& x1, doub } } } - } + }*/ + + double tr = a.trace(); + double det = STensorOperation::determinantSTensor3(a); + static STensor3 ainv, dI3da; + STensorOperation::inverseSTensor3(a,ainv); + dI3da = ainv; + dI3da *= det; + + const STensor43 I4(1.,1.); + static STensor43 dainvda; + for (int i=0; i<3; i++) + for (int s=0; s<3; s++) + for (int k=0; k<3; k++) + for (int l=0; l<3; l++){ + dainvda(i,s,k,l) = 0.; + for (int m=0; m<3; m++) + for (int j=0; j<3; j++) + dainvda(i,s,k,l) -= ainv(i,m)*I4(m,j,k,l)*ainv(j,s); + } + + dx1da = E1; + dx2da = E2; + dx3da = E3; + + double D1(0.),D2(0.),D3(0.); + static STensor3 dD1da, dD2da, dD3da; + STensorOperation::subMember_getEigenDecomposition_getDi(x1,tr,det,dx1da,dI3da,D1,dD1da); + STensorOperation::subMember_getEigenDecomposition_getDi(x2,tr,det,dx2da,dI3da,D2,dD2da); + STensorOperation::subMember_getEigenDecomposition_getDi(x3,tr,det,dx3da,dI3da,D3,dD3da); + STensorOperation::subMember_getEigenDecomposition_getdEidC(E1,x1,det,D1,ainv,dx1da,dainvda,dI3da,dD1da,dE1da); + STensorOperation::subMember_getEigenDecomposition_getdEidC(E2,x2,det,D2,ainv,dx2da,dainvda,dI3da,dD2da,dE2da); + STensorOperation::subMember_getEigenDecomposition_getdEidC(E3,x3,det,D3,ainv,dx3da,dainvda,dI3da,dD3da,dE3da); + } +void STensorOperation::getBasisRotationTensor(const STensor3& A, const STensor3& B, STensor3& R, STensor43& dRdB, STensor43& dRtdB){ + + // Only for single-legged symmetric tensors A and B -> leftEigenVect = rightEigenVect and eigenvals are always real + // R rotates the bases of A to that of B, so R = R_(ba), i.e., R = sum (eb * ea) + // B = R*A*Rt + + static fullMatrix<double> m1(3, 3), m2(3, 3); + static fullVector<double> eigenValReal1(3), eigenValReal2(3), AlignedEigenValReal1(3); + static fullVector<double> eigenValImag1(3), eigenValImag2(3); + static fullMatrix<double> leftEigenVect1(3,3), leftEigenVect2(3,3); + static fullMatrix<double> rightEigenVect1(3,3), rightEigenVect2(3,3), AlignedRightEigenVect1(3,3); + m1.setAll(0.); m2.setAll(0.); + eigenValReal1.setAll(0.); eigenValReal2.setAll(0.); AlignedEigenValReal1.setAll(0.); + eigenValImag1.setAll(0.); eigenValImag2.setAll(0.); + leftEigenVect1.setAll(0.); leftEigenVect2.setAll(0.); + rightEigenVect1.setAll(0.); rightEigenVect2.setAll(0.); AlignedRightEigenVect1.setAll(0.); + + // Get eigen values and vectors + A.getMat(m1); B.getMat(m2); + m1.eig(eigenValReal1,eigenValImag1,leftEigenVect1,rightEigenVect1,false); + m2.eig(eigenValReal2,eigenValImag2,leftEigenVect2,rightEigenVect2,false); + + // Make sure rightEigenVect1 is aligned with rightEigenVect2 + // STensorOperation::alignEigenDecomposition_EigenVectorDotProductBased(eigenValReal1,eigenValReal2,rightEigenVect1,rightEigenVect2,AlignedEigenValReal1,AlignedRightEigenVect1); + double a1_align, a2_align, a3_align; + STensorOperation::alignEigenDecomposition_NormBased(A,B,eigenValReal1,eigenValReal2,rightEigenVect1,rightEigenVect2, a1_align, a2_align, a3_align, AlignedRightEigenVect1); + rightEigenVect1 = AlignedRightEigenVect1; + + STensorOperation::zero(R); + for(int i=0; i<3; i++) + for(int j=0; j<3; j++) + R(i,j) += rightEigenVect2(i,0)*rightEigenVect1(j,0) + rightEigenVect2(i,1)*rightEigenVect1(j,1) + rightEigenVect2(i,2)*rightEigenVect1(j,2); + + static STensor33 de0dB, de1dB, de2dB; + STensorOperation::getEigenDecomposition_getdeidC(rightEigenVect2,eigenValReal2(0),eigenValReal2(1),eigenValReal2(2),de0dB,de1dB,de2dB); + + STensorOperation::zero(dRdB); STensorOperation::zero(dRtdB); + for(int i=0; i<3; i++) + for(int j=0; j<3; j++) + for (int k=0; k<3; k++) + for (int l=0; l<3; l++){ + dRdB(i,j,k,l) += de0dB(i,k,l)*rightEigenVect1(j,0) + de1dB(i,k,l)*rightEigenVect1(j,1) + de2dB(i,k,l)*rightEigenVect1(j,2); + dRtdB(i,j,k,l) += de0dB(j,k,l)*rightEigenVect1(i,0) + de1dB(j,k,l)*rightEigenVect1(i,1) + de2dB(j,k,l)*rightEigenVect1(i,2); + } + + /* + // checkers + static STensor3 B1,B2,B3; + double b1,b2,b3; + static STensor43 dBdB; // must be I4(1.,1.) + STensorOperation::zero(dBdB); + STensorOperation::getEigenDecomposition(B,b1,b2,b3,B1,B2,B3); + for(int i=0; i<3; i++) + for(int j=0; j<3; j++) + for (int k=0; k<3; k++) + for (int l=0; l<3; l++){ + dBdB(i,j,k,l) += B1(i,j)*B1(k,l) + B2(i,j)*B2(k,l) + B3(i,j)*B3(k,l) + + b1*(de0dB(i,k,l)*rightEigenVect2(j,0) + de0dB(j,k,l)*rightEigenVect2(i,0)) + + b2*(de1dB(i,k,l)*rightEigenVect2(j,1) + de1dB(j,k,l)*rightEigenVect2(i,1)) + + b3*(de2dB(i,k,l)*rightEigenVect2(j,2) + de2dB(j,k,l)*rightEigenVect2(i,2)); + }*/ +} + +void STensorOperation::alignEigenDecomposition_NormBased_indexOnly(const STensor3& A, const STensor3& B, fullVector<int>& alignedIndex){ + // Align A to B, where B is fixed + + // Initialise 1 + alignedIndex(0) = 0; alignedIndex(1) = 1; alignedIndex(2) = 2; + static fullVector<double> eigenValReal1(3); eigenValReal1.setAll(0.); + double a1,a2,a3,b1,b2,b3; // eigenvalues + static STensor3 A1,A2,A3,B1,B2,B3; // bases + + // Get eigen and assign + STensorOperation::getEigenDecomposition(A,a1,a2,a3,A1,A2,A3); + STensorOperation::getEigenDecomposition(B,b1,b2,b3,B1,B2,B3); + eigenValReal1(0) = a1; eigenValReal1(1) = a2; eigenValReal1(2) = a3; + + // Initialise 2 + double norm(0.), norm_min(1.e+20); + static STensor3 A_reformed; + // Generate permutated eigVal vector + static fullVector<double> eigenValReal1_permuted(3); + static fullVector<int> eigenValReal1_permuted_Index(3); + for (int p=0; p<3; p++) + for (int q=0; q<3; q++){ + if(q!=p){ + for (int r=0; r<3; r++){ + if(r!=p && r!=q){ + + zero(A_reformed); + for (int k=0; k<3; k++) + for (int l=0; l<3; l++) + A_reformed(k,l) += eigenValReal1(p)*B1(k,l) + eigenValReal1(q)*B2(k,l) + eigenValReal1(r)*B3(k,l); + A_reformed -= A; + doubleContractionSTensor3(A_reformed,A_reformed,norm); + norm = pow(norm,0.5); + + if(norm < norm_min){ // if( ( - norm + norm_min)>1.e-6 ) + norm_min = norm; + eigenValReal1_permuted(0) = eigenValReal1(p); + eigenValReal1_permuted_Index(0) = p; + eigenValReal1_permuted(1) = eigenValReal1(q); + eigenValReal1_permuted_Index(1) = q; + eigenValReal1_permuted(2) = eigenValReal1(r); + eigenValReal1_permuted_Index(2) = r; + } + } + } + + } + } + + // Assign the aligned indices + alignedIndex = eigenValReal1_permuted_Index; + } + + +void STensorOperation::alignEigenDecomposition_NormBased(const STensor3& A, const STensor3& B, + const double& b1, const double& b2, const double& b3, const STensor3& B1, const STensor3& B2, const STensor3& B3, + const fullVector<double> eigenValReal1, int& index1, int& index2, int& index3, + double& a1_align, double& a2_align, double& a3_align){ + // Align 1 to 2, where 2 is fixed + + // Form the tensor + double norm(0.), norm_min(1.e+20); + static STensor3 A_reformed; + + // Generate permutated eigVal vector + static fullVector<double> eigenValReal1_permuted(3); + static fullVector<int> eigenValReal1_permuted_Index(3); + for (int p=0; p<3; p++) + for (int q=0; q<3; q++){ + if(q!=p){ + for (int r=0; r<3; r++){ + if(r!=p && r!=q){ + + zero(A_reformed); + for (int k=0; k<3; k++) + for (int l=0; l<3; l++) + A_reformed(k,l) += eigenValReal1(p)*B1(k,l) + eigenValReal1(q)*B2(k,l) + eigenValReal1(r)*B3(k,l); + A_reformed -= A; + doubleContractionSTensor3(A_reformed,A_reformed,norm); + norm = pow(norm,0.5); + + if(norm < norm_min){ // if( ( - norm + norm_min)>1.e-6 ) + norm_min = norm; + eigenValReal1_permuted(0) = eigenValReal1(p); + eigenValReal1_permuted_Index(0) = p; + eigenValReal1_permuted(1) = eigenValReal1(q); + eigenValReal1_permuted_Index(1) = q; + eigenValReal1_permuted(2) = eigenValReal1(r); + eigenValReal1_permuted_Index(2) = r; + } + } + } + + } + } + + /* + // Get dotproducts of Eigen Vectors -> 3C1*3C1 possibilities + static STensor3 dot1, theta1; + zero(dot1); + for (int k=0; k<3; k++) + for (int l=0; l<3; l++) + for(int i=0; i<3; i++){ + dot1(k,l) += rightEigenVect1(k,i)*rightEigenVect2(l,i); + } + + // Get angles + double pi = 3.14159265358979323846; + zero(theta1); + for (int k=0; k<3; k++) + for (int l=0; l<3; l++){ + theta1(k,l) = acos(dot1(k,l)); // /(abs1(k)*abs2(l))); + if (theta1(k,l) > pi/2) { + theta1(k,l) = pi - theta1(k,l); + } + }*/ + + // Align the eigVals and eigVecs + index1 = eigenValReal1_permuted_Index(0); + index2 = eigenValReal1_permuted_Index(1); + index3 = eigenValReal1_permuted_Index(2); + a1_align = eigenValReal1_permuted(0); + a2_align = eigenValReal1_permuted(1); + a3_align = eigenValReal1_permuted(2); + } void STensorOperation::VRDecomposition(const STensor3& a, STensor3& V, STensor3&R) { @@ -469,4 +690,20 @@ void STensorOperation::RUDecomposition(const STensor3& a, STensor3& U, STensor3& } +/* TBD +void STensorOperation::rotateTensorBasesMinimumEnergy(const STensor3& A, const STensor3& B, const STensor3& stress, STensor3& C){ + + double a1,a2,a3,b1,b2,b3; + static STensor3 A1,A2,A3,B1,B2,B3; + STensorOperation::getEigenDecompositionExplicitBase(A,a1,a2,a3,A1,A2,A3); + STensorOperation::getEigenDecompositionExplicitBase(B,b1,b2,b3,B1,B2,B3); + + double initialEnergy = 0.; + STensorOperation::doubleContractionSTensor3(stress,A,initialEnergy); + + static fullVector<double> A_eigVal(3); + A(0)=a1; A(1)=a2; A(2)=a3; + +} +*/ diff --git a/NonLinearSolver/materialLaw/STensorOperations.h b/NonLinearSolver/materialLaw/STensorOperations.h index 6b8bd995a58862a5c741da8f4fce4ed6baecc801..f807f40517e088db52a1ae6cf1a1b7eb5bc967e9 100644 --- a/NonLinearSolver/materialLaw/STensorOperations.h +++ b/NonLinearSolver/materialLaw/STensorOperations.h @@ -8,7 +8,7 @@ #include "STensor63.h" #include "fullMatrix.h" #include <cmath> - +#include <algorithm> namespace STensorOperation{ inline void zero(double& a){ @@ -1613,11 +1613,317 @@ namespace STensorOperation{ } } + inline void getBasisRotationTensor(const STensor3& A, const STensor3& B, STensor3& R){ + // Only for single-legged symmetric tensors A and B -> leftEigenVect = rightEigenVect and eigenvals are always real + // R rotates the bases of A to that of B, so R = R_(ba), i.e., R = sum (eb * ea) + // B = R*A*Rt + + static fullMatrix<double> m1(3, 3), m2(3, 3); + static fullVector<double> eigenValReal1(3), eigenValReal2(3); + static fullVector<double> eigenValImag1(3), eigenValImag2(3); + static fullMatrix<double> leftEigenVect1(3,3), leftEigenVect2(3,3); + static fullMatrix<double> rightEigenVect1(3,3), rightEigenVect2(3,3); + m1.setAll(0.); m2.setAll(0.); + eigenValReal1.setAll(0.); eigenValReal2.setAll(0.); + eigenValImag1.setAll(0.); eigenValImag2.setAll(0.); + leftEigenVect1.setAll(0.); leftEigenVect2.setAll(0.); + rightEigenVect1.setAll(0.); rightEigenVect2.setAll(0.); + + // Get eigen values and vectors + A.getMat(m1); B.getMat(m2); + m1.eig(eigenValReal1,eigenValImag1,leftEigenVect1,rightEigenVect1,false); + m2.eig(eigenValReal2,eigenValImag2,leftEigenVect2,rightEigenVect2,false); + + zero(R); + for(int i=0; i<3; i++) + for(int j=0; j<3; j++) + R(i,j) += rightEigenVect2(i,0)*rightEigenVect1(j,0) + rightEigenVect2(i,1)*rightEigenVect1(j,1) + rightEigenVect2(i,2)*rightEigenVect1(j,2); + + /* + // checkers + static STensor3 check; + for(int i=0; i<3; i++) + for(int j=0; j<3; j++){ + check(i,j) = 0.; + for(int k=0; k<3; k++) + for(int l=0; l<3; l++) + check(i,j) += R(i,k)*A(k,l)*R(j,l); + } + + static fullMatrix<double> m(3, 3); + static fullVector<double> eigenValReal(3); + static fullVector<double> eigenValImag(3); + static fullMatrix<double> leftEigenVect(3,3); + static fullMatrix<double> rightEigenVect(3,3); + m.setAll(0.); + eigenValReal.setAll(0.); + eigenValImag.setAll(0.); + leftEigenVect.setAll(0.); + rightEigenVect.setAll(0.); + + // Get eigen values and vectors + check.getMat(m); + m.eig(eigenValReal,eigenValImag,leftEigenVect,rightEigenVect,false); + */ + } + + void getBasisRotationTensor(const STensor3& A, const STensor3& B, STensor3& R, STensor43& dRdB, STensor43& dRtdB); void getEigenDecomposition(const STensor3& a, double& x1, double& x2, double& x3, STensor3& E1, STensor3& E2, STensor3& E3, STensor3& dx1da, STensor3& dx2da, STensor3& dx3da, STensor43& dE1da, STensor43& dE2da, STensor43& dE3da); + inline void subMember_getEigenDecomposition_getDi(const double& xi, const double& tr, const double& det, const STensor3& dxidC, const STensor3& dI3dC, double& Di, STensor3& dDidC){ + // C is 42 tensor + Di = 2*pow(xi,2) - tr*xi + det/xi; + + STensor3 I(1.); + + zero(dDidC); + for(int i=0; i<3; i++) + for(int j=0; j<3; j++) + dDidC(i,j) += 4*xi*dxidC(i,j) - xi*I(i,j) - tr*dxidC(i,j) + dI3dC(i,j)*1/xi - (det/pow(xi,2))*dxidC(i,j); + } + + inline void subMember_getEigenDecomposition_getdEidC(const STensor3& Ei, const double& xi, const double& det, const double& Di, const STensor3& Cinv, const STensor3& dxidC, const STensor43& dCinvdC, + const STensor3& dI3dC, const STensor3& dDidC, STensor43& dEidC){ + // C is 42 tensor + STensor3 I(1.); + STensor43 I4(1.,1.); + + zero(dEidC); + if(abs(xi)>0. && abs(Di)>0.){ + for(int i=0; i<3; i++) + for(int j=0; j<3; j++) + for (int k=0; k<3; k++) + for (int l=0; l<3; l++){ + dEidC(i,j,k,l) += Ei(i,j)*dxidC(k,l)/xi + + xi/Di*(I4(i,j,k,l) - I(i,j)*I(k,l) + I(i,j)*dxidC(k,l) + det*(1/xi*dCinvdC(i,j,k,l) - (1/pow(xi,2))*Cinv(i,j)*dxidC(k,l)) + 1/xi * Cinv(i,j)*dI3dC(k,l)) + - Ei(i,j)/Di*dDidC(k,l); + } + } + } + + inline void getEigenDecomposition_getdeidC(const fullMatrix<double>& rightEigenVect, const double& x0, const double& x1, const double& x2, STensor33& de0dC, STensor33& de1dC, STensor33& de2dC){ + // C is 42 tensor + + zero(de0dC); zero(de1dC); zero(de2dC); + for(int i=0; i<3; i++) + for (int k=0; k<3; k++) + for (int l=0; l<3; l++){ + + if (x0!=x1){ + de0dC(i,k,l) += 1/(x0-x1)/2.*(rightEigenVect(l,0)*rightEigenVect(k,1)+rightEigenVect(k,0)*rightEigenVect(l,1))*rightEigenVect(i,1); + de1dC(i,k,l) += 1/(x1-x0)/2.*(rightEigenVect(l,1)*rightEigenVect(k,0)+rightEigenVect(k,1)*rightEigenVect(l,0))*rightEigenVect(i,0); + } + + if (x0!=x2){ + de0dC(i,k,l) += 1/(x0-x2)/2.*(rightEigenVect(l,0)*rightEigenVect(k,2)+rightEigenVect(k,0)*rightEigenVect(l,2))*rightEigenVect(i,2); + de2dC(i,k,l) += 1/(x2-x0)/2.*(rightEigenVect(l,2)*rightEigenVect(k,0)+rightEigenVect(k,2)*rightEigenVect(l,0))*rightEigenVect(i,0); + } + + if (x1!=x2){ + de1dC(i,k,l) += 1/(x1-x2)/2.*(rightEigenVect(l,1)*rightEigenVect(k,2)+rightEigenVect(k,1)*rightEigenVect(l,2))*rightEigenVect(i,2); + de2dC(i,k,l) += 1/(x2-x1)/2.*(rightEigenVect(l,2)*rightEigenVect(k,1)+rightEigenVect(k,2)*rightEigenVect(l,1))*rightEigenVect(i,1); + } + } + } + + inline void alignEigenDecomposition_EigenVectorDotProductBased(const fullVector<double> eigenValReal1, const fullVector<double> eigenValReal2, + const fullMatrix<double>& rightEigenVect1, const fullMatrix<double>& rightEigenVect2, + double& a1_align, double& a2_align, double& a3_align, fullMatrix<double>& rightEigenVect){ + // Align 1 to 2 where 2 is fixed + + + // Get abs values of Eigenvectors + static fullVector<double> abs1(3), abs2(3); + double sumSquare1(0.), sumSquare2(0.); + for(int i=0; i<3; i++){ + for (int k=0; k<3; k++){ + sumSquare1 += rightEigenVect1(k,i)*rightEigenVect1(k,i); + sumSquare2 += rightEigenVect2(k,i)*rightEigenVect2(k,i); + } + abs1(i) = pow(sumSquare1,0.5); + abs2(i) = pow(sumSquare2,0.5); + sumSquare1 = 0.; + sumSquare2 = 0.; + } + + // Get dotproducts of Eigen Vectors -> 3C1*3C1 possibilities + static STensor3 dot1, theta1; + zero(dot1); + for (int k=0; k<3; k++) + for (int l=0; l<3; l++) + for(int i=0; i<3; i++){ + dot1(k,l) += rightEigenVect1(k,i)*rightEigenVect2(l,i); + } + + // Get angles + double pi = 3.14159265358979323846; + zero(theta1); + for (int k=0; k<3; k++) + for (int l=0; l<3; l++){ + theta1(k,l) = acos(dot1(k,l)); // /(abs1(k)*abs2(l))); + if (theta1(k,l) > pi/2) { + theta1(k,l) = pi - theta1(k,l); + } + } + + + // Compare and pick the smallest theta1 for the 1st aligned Eigenvector wrt Eigenvectors2 + double smol1 = theta1(0,0); + double smol2 = theta1(1,1); + double smol3 = theta1(2,2); + int index1 = 0, index2 = 1, index3 = 2; + + // pick 1 + int temp1 = 0; + for (int l=0; l<3; l++){ + if(temp1==0){ + smol1 = theta1(l,0); + index1 = l; + temp1 = 1; + } + else if(theta1(l,0)<smol1 && temp1!=0){ + smol1 = theta1(l,0); + index1 = l; + temp1 = 1; + } + } + + // pick 2 + int temp2 = 0; + for (int l=0; l<3; l++){ + if(l!=index1){ + if(temp1==0){ + smol2 = theta1(l,1); + index2 = l; + temp2 = 1; + } + if(theta1(l,1)<smol2 && temp2!=0){ + smol2 = theta1(l,1); + index2 = l; + temp2 = 1; + } + } + } + + // pick 3 + for (int l=0; l<3; l++){ + if(l!=index1 && l!=index2) index3 = l; + } + + a1_align = eigenValReal1(index1); + a2_align = eigenValReal1(index2); + a3_align = eigenValReal1(index3); + for(int i=0; i<3; i++){ + rightEigenVect(i,0) = rightEigenVect1(i,index1); + rightEigenVect(i,1) = rightEigenVect1(i,index2); + rightEigenVect(i,2) = rightEigenVect1(i,index3); + } + + // Convert to tensors + static STensor3 eig1, eig2, eig_Align; + for (int k=0; k<3; k++) + for (int l=0; l<3; l++){ + eig1(k,l) = rightEigenVect1(k,l); + eig2(k,l) = rightEigenVect2(k,l); + eig_Align(k,l) = rightEigenVect(k,l); + } + + } + + inline void alignEigenDecomposition_NormBased(const STensor3& A, const STensor3& B, const fullVector<double> eigenValReal1, const fullVector<double> eigenValReal2, + const fullMatrix<double>& rightEigenVect1, const fullMatrix<double>& rightEigenVect2, + double& a1_align, double& a2_align, double& a3_align, fullMatrix<double>& rightEigenVect){ + // Align 1 to 2 where 2 is fixed + + // Get eigen bases + double b1, b2, b3; + static STensor3 B1, B2, B3; + getEigenDecomposition(B,b1,b2,b3,B1,B2,B3); + + // Form the tensor + double norm(0.), norm_min(0.); + static STensor3 A_reformed; + + // Generate permutated eigVal vector + static fullVector<double> eigenValReal1_permuted(3); + static fullVector<int> eigenValReal1_permuted_Index(3); + double l1(0.), l2(0.), l3(0.); + for (int p=0; p<3; p++){ + l1 = eigenValReal1(p); + for (int q=0; q<3; q++){ + if(q!=p){ + l2 = eigenValReal1(q); + for (int r=0; r<3; r++){ + if(r!=p && r!=q){ + l3 = eigenValReal1(r); + + zero(A_reformed); + for (int k=0; k<3; k++) + for (int l=0; l<3; l++) + A_reformed(k,l) += l1*B1(k,l) + l2*B2(k,l) + l3*B3(k,l); + A_reformed -= A; + doubleContractionSTensor3(A_reformed,A_reformed,norm); + norm = pow(norm,0.5); + + if(norm_min == 0.){ + norm_min = norm; // initialise + eigenValReal1_permuted(0) = l1; + eigenValReal1_permuted_Index(0) = p; + eigenValReal1_permuted(1) = l2; + eigenValReal1_permuted_Index(1) = q; + eigenValReal1_permuted(2) = l3; + eigenValReal1_permuted_Index(2) = r; + } + else{ + if(norm < norm_min){ // if( ( - norm + norm_min)>1.e-6 ) + norm_min = norm; + eigenValReal1_permuted(0) = l1; + eigenValReal1_permuted_Index(0) = p; + eigenValReal1_permuted(1) = l2; + eigenValReal1_permuted_Index(1) = q; + eigenValReal1_permuted(2) = l3; + eigenValReal1_permuted_Index(2) = r; + } + } + } + } + + } + } + } + + // Align the eigVals and eigVecs + a1_align = eigenValReal1_permuted(0); + a2_align = eigenValReal1_permuted(1); + a3_align = eigenValReal1_permuted(2); + for(int i=0; i<3; i++){ + rightEigenVect(i,0) = rightEigenVect1(i,eigenValReal1_permuted_Index(0)); + rightEigenVect(i,1) = rightEigenVect1(i,eigenValReal1_permuted_Index(1)); + rightEigenVect(i,2) = rightEigenVect1(i,eigenValReal1_permuted_Index(2)); + } + + + // Convert to tensors + static STensor3 eig1, eig2, eig_align; + for (int k=0; k<3; k++) + for (int l=0; l<3; l++){ + eig1(k,l) = rightEigenVect1(k,l); + eig2(k,l) = rightEigenVect2(k,l); + eig_align(k,l) = rightEigenVect(k,l); + } + + } + + void alignEigenDecomposition_NormBased_indexOnly(const STensor3& A, const STensor3& B, fullVector<int>& alignedIndex); + + void alignEigenDecomposition_NormBased(const STensor3& A, const STensor3& B, + const double& b1, const double& b2, const double& b3, const STensor3& B1, const STensor3& B2, const STensor3& B3, + const fullVector<double> eigenValReal1, int& index1, int& index2, int& index3, + double& a1_align, double& a2_align, double& a3_align); + inline void getEigenDecompositionExplicitBase(const STensor3& a, double& x1, double& x2, double& x3, STensor3& E1, STensor3& E2, STensor3& E3) { // a = x1*E1+x2*E2+x3*E3 diff --git a/NonLinearSolver/materialLaw/mlaw.h b/NonLinearSolver/materialLaw/mlaw.h index d440e62ad6564f0ef2d6b6a55c84a982076529a0..4f2ed086c46255a0c2e818fbdd6f2e7383561547 100644 --- a/NonLinearSolver/materialLaw/mlaw.h +++ b/NonLinearSolver/materialLaw/mlaw.h @@ -35,7 +35,7 @@ class materialLaw{ ThermalConducter,AnIsotropicTherMech, localDamageJ2Hyper,linearElastic,nonLocalDamageGursonThermoMechanics, localDamageJ2SmallStrain,nonLocalDamageJ2SmallStrain,cluster,tfa,ANN, DMN, torchANN, NonlocalDamageTorchANN, LinearElecMagTherMech, LinearElecMagInductor, hyperviscoelastic, GenericThermoMechanics, ElecMagGenericThermoMechanics, ElecMagInductor, - nonlineartvm,nonlinearTVE,nonlinearTVP,vevpmfh, VEVPUMAT, IMDEACPUMAT, Hill48,nonlinearTVEnonlinearTVP, + nonlineartvm,nonlinearTVE,nonlinearTVP,vevpmfh, VEVPUMAT, IMDEACPUMAT, Hill48,nonlinearTVEnonlinearTVP,nonlinearTVEnonlinearTVP2, MultipleLaws}; diff --git a/NonLinearSolver/materialLaw/mlawHyperelastic.cpp b/NonLinearSolver/materialLaw/mlawHyperelastic.cpp index e15627afd345e1775f0abda078bd5edca516a235..5ed49eeaa8254666715e054521cfd7c8481d2961 100644 --- a/NonLinearSolver/materialLaw/mlawHyperelastic.cpp +++ b/NonLinearSolver/materialLaw/mlawHyperelastic.cpp @@ -401,66 +401,6 @@ void mlawHyperViscoElastic::evaluatePhiPCorrection(double tr, const STensor3 &de // Msg::Error(" Inside extraBranch_Hyper Type = TensionCompressionRegularisedType, D1 = 0. or D4 = 0., incompatibility with Mullin's effect"); } } - /*else if(_extraBranchNLType == hyper_exp_TCasymm_Type){ - - // Msg::Error(" Inside evaluatePhiPCorrection, A_v = %e, B_d = %e !!", A_v, B_d); - // Regularising function - double m = _tensionCompressionRegularisation; - double expmtr = exp(-m*tr); - // if (exp(-m*tr)<1.e+10){ expmtr = exp(-m*tr);} - double sigmoid = 1/(1.+expmtr); - - double x1 = getXiVolumeCorrection()*tr*tr + getZetaVolumeCorrection(); - double x2 = _xivolCorrection2*tr*tr + _zetavolCorrection2; - - A_v = -1. + sigmoid*(getVolumeCorrection()/sqrt(x1)) + (1-sigmoid)*_compCorrection*(getVolumeCorrection()/sqrt(x1) + _volCorrection2*exp(x2)); - - dA_vdE = sigmoid*(-getVolumeCorrection()*getXiVolumeCorrection()*tr/pow(x1,1.5)) - + (1.-sigmoid)*_compCorrection*( -getVolumeCorrection()*getXiVolumeCorrection()*tr/pow(x1,1.5) + 2*_volCorrection2*_xivolCorrection2*tr*exp(x2)) - + (m*expmtr/pow((1.+expmtr),2.))*getVolumeCorrection()*1./sqrt(x1) - (m*expmtr/pow((1.+expmtr),2.))*_compCorrection*(getVolumeCorrection()/sqrt(x1) + _volCorrection2*exp(x2)) ; - - if(getXiVolumeCorrection()>0. && _xivolCorrection2>0.){ - double integrand1 = 1./getXiVolumeCorrection()*sqrt(x1); // integral of A_v * trEe - integrand1 -= ( 1./getXiVolumeCorrection()*sqrt(getZetaVolumeCorrection()) ); // value at trEe = 0. - integrand1 *= getVolumeCorrection(); - - double integrand2 = exp(x2)/(2*_xivolCorrection2); - integrand2 -= exp(_zetavolCorrection2)/(2*_xivolCorrection2); - integrand2 *= _volCorrection2; - - intA = - tr*tr/2. + sigmoid*integrand1 + (1.-sigmoid)*_compCorrection*(integrand1 + integrand2); - } - else{ - intA = - tr*tr/2.; - } - - double y1 = getThetaDevCorrection()*dev.dotprod() + getPiDevCorrection(); - double y2 = _thetadevCorrection2*dev.dotprod() + _pidevCorrection2; - B_d = -1. + sigmoid*(getDevCorrection()/sqrt(y1)) + (1-sigmoid)*_compCorrection*(getDevCorrection()/sqrt(y1) + _devCorrection2*exp(y2)); - - STensorOperation::zero(dB_vddev); - dB_vddev = dev; - dB_vddev *= ( sigmoid*(-getDevCorrection()*getThetaDevCorrection()/pow(y1,1.5)) - + (1.-sigmoid)*_compCorrection*( -getDevCorrection()*getThetaDevCorrection()/pow(y1,1.5) + 2*_devCorrection2*_thetadevCorrection2*exp(y2)) ); - if(dB_dTrEe!=NULL){ - *dB_dTrEe = (m*expmtr/pow((1.+expmtr),2.))*getDevCorrection()*1./sqrt(y1) - (m*expmtr/pow((1.+expmtr),2.))*_compCorrection*(getDevCorrection()/sqrt(y1) + _devCorrection2*exp(y2)); - } - if(getThetaDevCorrection()>0. && _thetadevCorrection2>0.){ - - double integrand1 = 1./getThetaDevCorrection()*sqrt(y1); // integral of B_d * devEe - integrand1 -= (1./getThetaDevCorrection()*sqrt(getPiDevCorrection()) ); // value at devEe = 0. - integrand1 *= getDevCorrection(); - - double integrand2 = exp(y2)/(2*_thetadevCorrection2); - integrand2 -= exp(_pidevCorrection2)/(2*_thetadevCorrection2); - integrand2 *= _devCorrection2; - - intB = -dev.dotprod()/2. + sigmoid*integrand1 + (1.-sigmoid)*_compCorrection*(integrand1 + integrand2); - } - else{ - intB = -dev.dotprod()/2.; - } - }*/ else if(_extraBranchNLType == hyper_exp_TCasymm_Type){ // hyper_TCasymm_Type2 // To make it simpler for the sake of it @@ -485,24 +425,26 @@ void mlawHyperViscoElastic::evaluatePhiPCorrection(double tr, const STensor3 &de double sigmoid = 1/(1.+expmtr); double x1 = V1*tr*tr + V2; - double x2 = V4*tr*tr + V5; - A_v = -1. + sigmoid*( (1./sqrt(x1)+V3*(1+tanh(x2))) ) + (1-sigmoid)*_compCorrection*( 1./sqrt(x1)+V3 ); + double x2 = V4*tr*tr; + A_v = -1. + sigmoid*( (1./sqrt(x1)+V3*(V5 + tanh(x2))) ) + (1-sigmoid)*_compCorrection*( 1./sqrt(x1)+V0 ); dA_vdE = -sigmoid*(V1*tr/pow(x1,1.5) - V3*(2*V4*tr*pow(1/cosh(x2),2))) - (1.-sigmoid)*(V1*_compCorrection*tr/pow(x1,1.5)) - + (m*expmtr/pow((1.+expmtr),2.))*(1./sqrt(x1)+ V3*(1+tanh(x2)))- (_compCorrection*m*expmtr/pow((1.+expmtr),2.))*(1./sqrt(x1) + V3); + + (m*expmtr/pow((1.+expmtr),2.))*(1./sqrt(x1)+ V3*(V5+tanh(x2)))- (_compCorrection*m*expmtr/pow((1.+expmtr),2.))*(1./sqrt(x1) + V0); if(V1>0.){ - double integrand1 = 1./V1*sqrt(x1) + V3*tr*tr/2.; // integral of A_v * trEe + double integrand1 = 1./V1*sqrt(x1) + V3*V5*tr*tr/2.; // integral of A_v * trEe double integrand2 = 0.; + double integrand3 = 1./V1*sqrt(x1) + V0*tr*tr/2.; // integral of A_v * trEe if(V4 != 0.){ integrand2 = V3/(2.*V4)*log(cosh(x2)); } integrand1 -= ( 1./V1*sqrt(V2) ); // value at trEe = 0. - intA = - tr*tr/2. + sigmoid*(integrand1 + integrand2) + _compCorrection*(1.-sigmoid)*integrand1; + integrand3 -= ( 1./V1*sqrt(V2) ); // value at trEe = 0. + intA = - tr*tr/2. + sigmoid*(integrand1 + integrand2) + _compCorrection*(1.-sigmoid)*integrand3; // intA *= getVolumeCorrection(); if(DintA!=NULL){ - *DintA = (m*expmtr/pow((1.+expmtr),2.))*integrand1 - (Ci*m*expmtr/pow((1.+expmtr),2.))*integrand2; + *DintA = (m*expmtr/pow((1.+expmtr),2.))*(integrand1 + integrand2) - (Ci*m*expmtr/pow((1.+expmtr),2.))*integrand3; } } else{ @@ -510,31 +452,33 @@ void mlawHyperViscoElastic::evaluatePhiPCorrection(double tr, const STensor3 &de } double y1 = D1*dev.dotprod() + D2; - double y2 = D4*dev.dotprod() + D5; + double y2 = D4*dev.dotprod(); - B_d = -1. + sigmoid*(1./sqrt(y1) + D3*(1+tanh(y2))) + (1.-sigmoid)*(_compCorrection*(1./sqrt(y1) + D3)) ; + B_d = -1. + sigmoid*(1./sqrt(y1) + D3*(D5+tanh(y2))) + (1.-sigmoid)*(_compCorrection*(1./sqrt(y1) + D0)) ; STensorOperation::zero(dB_vddev); dB_vddev = dev; dB_vddev *= (-sigmoid*(D1/pow(y1,1.5) - D3*(2*D4*pow(1/cosh(y2),2))) - (1.-sigmoid)*(D1*_compCorrection/pow(y1,1.5))); if(dB_dTrEe!=NULL){ - *dB_dTrEe = (m*expmtr/pow((1.+expmtr),2.))*(1./sqrt(y1) + D3*(1+tanh(y2))) - (m*expmtr/pow((1.+expmtr),2.))*(_compCorrection*(1./sqrt(y1) + D3)); + *dB_dTrEe = (m*expmtr/pow((1.+expmtr),2.))*(1./sqrt(y1) + D3*(D5+tanh(y2))) - (m*expmtr/pow((1.+expmtr),2.))*(_compCorrection*(1./sqrt(y1) + D0)); // *dB_dTrEe *= getDevCorrection(); } if(D1>0.){ - double integrand1 = 1./D1*sqrt(y1) + D3*dev.dotprod()/2.; // integral of B_d * devEe + double integrand1 = 1./D1*sqrt(y1) + D3*D5*dev.dotprod()/2.; // integral of B_d * devEe double integrand2 = 0.; + double integrand3 = 1./D1*sqrt(y1) + D0*dev.dotprod()/2.; // integral of B_d * devEe if(D4 != 0.){ integrand2 = D3/(2.*D4)*log(cosh(y2)); } integrand1 -= (1./D1*sqrt(D2) ); // value at devEe = 0. - intB = -dev.dotprod()/2. + sigmoid*(integrand1 + integrand2) + _compCorrection*(1.-sigmoid)*integrand1; + integrand3 -= (1./D1*sqrt(D2) ); // value at devEe = 0. + intB = -dev.dotprod()/2. + sigmoid*(integrand1 + integrand2) + _compCorrection*(1.-sigmoid)*integrand3; // intB *= getDevCorrection(); if(DintB!=NULL){ - *DintB = (m*expmtr/pow((1.+expmtr),2.))*integrand1 - (Ci*m*expmtr/pow((1.+expmtr),2.))*integrand2; + *DintB = (m*expmtr/pow((1.+expmtr),2.))*(integrand1 + integrand2) - (Ci*m*expmtr/pow((1.+expmtr),2.))*integrand3; } } else{ diff --git a/NonLinearSolver/materialLaw/mlawNonLinearTVENonLinearTVP.cpp b/NonLinearSolver/materialLaw/mlawNonLinearTVENonLinearTVP.cpp index 7db46ba61b9be195ea518d152d4eb08fc27de70f..8492c3f2c89c98c7a579c792b4f398b38b3c8993 100644 --- a/NonLinearSolver/materialLaw/mlawNonLinearTVENonLinearTVP.cpp +++ b/NonLinearSolver/materialLaw/mlawNonLinearTVENonLinearTVP.cpp @@ -474,18 +474,60 @@ void mlawNonLinearTVENonLinearTVP::predictorCorrector_TVP_nonAssociatedFlow_nonL DlnDCe = DlnDCepr; // update A, B -> ExtraBranch calculations are within - double Ke(0.), Ge(0.), Ke_pr(0.), Ge_pr(0.), DKDTsum(0.), DGDTsum(0.); + double Ke(0.), Ge(0.), Ke_pr(0.), Ge_pr(0.); static STensor43 Ge_Tensor_pr, Ge_Tensor, Bd_stiffnessTerm, Ge_TrEeTensor_pr, Ge_TrEeTensor; STensorOperation::zero(Ge_Tensor_pr); STensorOperation::zero(Ge_Tensor); STensorOperation::zero(Ge_TrEeTensor_pr); STensorOperation::zero(Ge_TrEeTensor); + // NEW EIGEN + static fullVector<int> alignedIndex(3); alignedIndex(0) = 0; alignedIndex(1) = 1; alignedIndex(2) = 2; + static STensor3 Ee0_rot, R; + static STensor43 dRdEe, dRtdEe, rotationStiffness_pr ,rotationStiffness; + STensorOperation::zero(rotationStiffness_pr); STensorOperation::zero(rotationStiffness); + q1->_Ee0 = q0->_Ee; + mlawNonLinearTVM::rotationTensor_N_to_Nplus1(q0->_Ee0,q0->_Fe,Fe,Ce,Ee,q0->_Ee,R,dRdEe,dRtdEe); + for(int i=0; i<3; i++) + for(int j=0; j<3; j++){ + Ee0_rot(i,j) = 0.; + for(int k=0; k<3; k++) + for(int l=0; l<3; l++) + Ee0_rot(i,j) += R(i,k)*q0->_Ee(k,l)*R(j,l); + } + // NEW EIGEN + + // NEW EIGEN + if ((_Ki.size() > 0) or (_Gi.size() > 0)){ + for (int i=0; i<_Gi.size(); i++){ + for(int k=0; k<3; k++) + for(int l=0; l<3; l++){ + q1->_A_rot[i](k,l) = 0.; + for(int p=0; p<3; p++) + for(int q=0; q<3; q++) + q1->_A_rot[i](k,l) += R(k,p)*q0->_A[i](p,q)*R(l,q); + } + } + } + // NEW EIGEN + if (_extraBranchNLType == TensionCompressionRegularisedType || _extraBranchNLType == hyper_exp_TCasymm_Type || _ExtraBranch_TVE_option == 3 || _ExtraBranch_TVE_option == 4 || _ExtraBranch_TVE_option == 5){ - // TC asymmetry -> for either case of TensionCompressionRegularisedType and _ExtraBranch_TVE_option == 3,',( - mlawNonLinearTVM::ThermoViscoElasticPredictor(Ee,q0->_Ee,q0,q1,Ke,Ge,DKDTsum,DGDTsum,T0,T,stiff,Bd_stiffnessTerm,&Ge_TrEeTensor); - Ge_TrEeTensor_pr = Ge_TrEeTensor; + // TC asymmetry -> for either case of TensionCompressionRegularisedType and _ExtraBranch_TVE_option == 3 + if (!_useRotationCorrection){ + mlawNonLinearTVM::ThermoViscoElasticPredictor(Ee,q0->_Ee,q0,q1,Ke,Ge,T0,T,stiff,Bd_stiffnessTerm,&Ge_TrEeTensor); + } + else{ + mlawNonLinearTVM::ThermoViscoElasticPredictor_forTVP(Ce,Ee,Ee0_rot,q0,q1,Ke,Ge,T0,T,stiff,alignedIndex,Bd_stiffnessTerm,&Ge_TrEeTensor,&rotationStiffness); // NEW EIGEN + } + Ge_TrEeTensor_pr = Ge_TrEeTensor; + rotationStiffness_pr = rotationStiffness; } else{ - mlawNonLinearTVM::ThermoViscoElasticPredictor(Ee,q0->_Ee,q0,q1,Ke,Ge,DKDTsum,DGDTsum,T0,T,stiff,Bd_stiffnessTerm); + if (!_useRotationCorrection){ + mlawNonLinearTVM::ThermoViscoElasticPredictor(Ee,q0->_Ee,q0,q1,Ke,Ge,T0,T,stiff,Bd_stiffnessTerm); + } + else{ + mlawNonLinearTVM::ThermoViscoElasticPredictor_forTVP(Ce,Ee,Ee0_rot,q0,q1,Ke,Ge,T0,T,stiff,alignedIndex,Bd_stiffnessTerm,NULL,&rotationStiffness); // NEW EIGEN + } + rotationStiffness_pr = rotationStiffness; } Ge_Tensor = _I4; @@ -499,6 +541,27 @@ void mlawNonLinearTVENonLinearTVP::predictorCorrector_TVP_nonAssociatedFlow_nonL Ge_Tensor_pr *= Ge_pr*2; // Because the function does not do it Ge_Tensor_pr += Bd_stiffnessTerm; + // NEW - EIGEN + static fullMatrix<double> m1(3, 3), m2(3, 3), m3(3, 3), m4(3, 3), m5(3, 3); + static fullVector<double> eigenValReal1(3), eigenValReal2(3), eigenValReal3(3), eigenValReal4(3), eigenValReal5(3); + static fullVector<double> eigenValImag1(3), eigenValImag2(3), eigenValImag3(3), eigenValImag4(3), eigenValImag5(3); + static fullMatrix<double> leftEigenVect1(3,3), leftEigenVect2(3,3), leftEigenVect3(3,3), leftEigenVect4(3,3), leftEigenVect5(3,3); + static fullMatrix<double> rightEigenVect1(3,3), rightEigenVect2(3,3), rightEigenVect3(3,3), rightEigenVect4(3,3), rightEigenVect5(3,3); + m1.setAll(0.); m2.setAll(0.); m3.setAll(0.); m4.setAll(0.); m5.setAll(0.); + eigenValReal1.setAll(0.); eigenValReal2.setAll(0.); eigenValReal3.setAll(0.); eigenValReal4.setAll(0.); eigenValReal5.setAll(0.); + eigenValImag1.setAll(0.); eigenValImag2.setAll(0.); eigenValImag3.setAll(0.); eigenValImag4.setAll(0.); eigenValImag5.setAll(0.); + leftEigenVect1.setAll(0.); leftEigenVect2.setAll(0.); leftEigenVect3.setAll(0.); leftEigenVect4.setAll(0.); leftEigenVect5.setAll(0.); + rightEigenVect1.setAll(0.); rightEigenVect2.setAll(0.); rightEigenVect3.setAll(0.); rightEigenVect4.setAll(0.); rightEigenVect5.setAll(0.); + + // Get eigen values and vectors + q1->_kirchhoff.getMat(m1); Ce.getMat(m2); Ee.getMat(m3); q0->_Ee.getMat(m4); Ee0_rot.getMat(m5); + m1.eig(eigenValReal1,eigenValImag1,leftEigenVect1,rightEigenVect1,false); + m2.eig(eigenValReal2,eigenValImag2,leftEigenVect2,rightEigenVect2,false); + m3.eig(eigenValReal3,eigenValImag3,leftEigenVect3,rightEigenVect3,false); + m4.eig(eigenValReal4,eigenValImag4,leftEigenVect4,rightEigenVect4,false); + m5.eig(eigenValReal5,eigenValImag5,leftEigenVect5,rightEigenVect5,false); + // NEW - EIGEN + // get predictor - dKeprDT mlawNonLinearTVM::getTVEdCorKirDT(q0,q1,T0,T); const STensor3& dKeprDT = q1->_DcorKirDT; // This has all extrabranches now @@ -592,7 +655,7 @@ void mlawNonLinearTVENonLinearTVP::predictorCorrector_TVP_nonAssociatedFlow_nonL } else{ if (f>_tol){ - // Msg::Error("Plasticity"); + Msg::Error("Plasticity"); q1->getRefToDissipationActive() = true; // plasticity @@ -851,11 +914,37 @@ void mlawNonLinearTVENonLinearTVP::predictorCorrector_TVP_nonAssociatedFlow_nonL mlawNonLinearTVP::getModifiedMandel(Ce, q0, q1); // update Mandel const STensor3& MS = q1->_ModMandel; Me = MS; + // second Piola Kirchhoff stress static STensor3 S, Ceinv; STensorOperation::inverseSTensor3(Ce,Ceinv); STensorOperation::multSTensor3(Ceinv,q1->_ModMandel,S); + static STensor3 S2, M2; + for(int i=0; i<3; i++) + for(int j=0; j<3; j++){ + S2(i,j) = 0.; + for(int k=0; k<3; k++) + S2(i,j) += 0.5* ( KS(i,k)*Ceinv(k,j) + Ceinv(k,i)*KS(j,k) ); + } + STensorOperation::multSTensor3(Ce,S2,M2); + + + static STensor3 _temp1, _temp2, _temp3, _temp4, _temp6, commuteCheck; + STensorOperation::multSTensor3(Ce, S, _temp1); + STensorOperation::multSTensor3(S, Ce, _temp2); + STensorOperation::multSTensor3(KS, Ce, _temp3); + STensorOperation::multSTensor3(Ce, KS, _temp4); + + // Check S + commuteCheck = _temp1; + commuteCheck -= _temp2; + + // Check corKir (just for fun) + _temp6 = _temp3; + _temp6 -= _temp4; + + // first PK for(int i=0; i<3; i++) for(int j=0; j<3; j++){ @@ -947,6 +1036,11 @@ void mlawNonLinearTVENonLinearTVP::predictorCorrector_TVP_nonAssociatedFlow_nonL DcorKirDEe_pr += Ge_TrEeTensor_pr; // TC Assymmetry DcorKirDEe += Ge_TrEeTensor; // TC Assymmetry + // NEW EIGEN + DcorKirDEe_pr += rotationStiffness_pr; + DcorKirDEe += rotationStiffness; + // NEW EIGEN + static STensor43 DcorKir_pr_DCepr, DcorKirDCepr; STensorOperation::multSTensor43(DcorKirDEe_pr,DlnDCepr,DcorKir_pr_DCepr); STensorOperation::multSTensor43(DcorKirDEe,DlnDCepr,DcorKirDCepr); @@ -2179,7 +2273,7 @@ void mlawNonLinearTVENonLinearTVP::getDho(const double& Gamma, const STensor3& C } void mlawNonLinearTVENonLinearTVP::getIterated_DPhi(const double& T0, const double& T, const IPNonLinearTVP *q0, IPNonLinearTVP *q1, - const double& Gamma, const double& Cxtr, const double& Cxdev, + double& Gamma, const double& Cxtr, const double& Cxdev, const STensor3& Cepr, const STensor3& Eepr, const double& trXn, const STensor3& devXn, double& Ke, double& Ge, STensor43& Ge_Tensor, @@ -2230,14 +2324,13 @@ void mlawNonLinearTVENonLinearTVP::getIterated_DPhi(const double& T0, const doub // Initialise corKir static STensor3 KS; static STensor43 Bd_stiffnessTerm; - double DKDTsum, DGDTsum; if (Ge_TrEeTensor == NULL){ // mlawNonLinearTVM::ThermoViscoElasticPredictor_forTVP(Ee,q0->_Ee,q0,q1,Ke,Ge,T0,T,true,Bd_stiffnessTerm); - mlawNonLinearTVM::ThermoViscoElasticPredictor(Ee,q0->_Ee,q0,q1,Ke,Ge,DKDTsum,DGDTsum,T0,T,true,Bd_stiffnessTerm); + mlawNonLinearTVM::ThermoViscoElasticPredictor(Ee,q0->_Ee,q0,q1,Ke,Ge,T0,T,true,Bd_stiffnessTerm); } else{ // TC asymmetry // mlawNonLinearTVM::ThermoViscoElasticPredictor_forTVP(Ee,q0->_Ee,q0,q1,Ke,Ge,T0,T,true,Bd_stiffnessTerm,Ge_TrEeTensor); - mlawNonLinearTVM::ThermoViscoElasticPredictor(Ee,q0->_Ee,q0,q1,Ke,Ge,DKDTsum,DGDTsum,T0,T,true,Bd_stiffnessTerm,Ge_TrEeTensor); + mlawNonLinearTVM::ThermoViscoElasticPredictor(Ee,q0->_Ee,q0,q1,Ke,Ge,T0,T,true,Bd_stiffnessTerm,Ge_TrEeTensor); } Ge_Tensor = _I4; Ge_Tensor *= Ge*2; // *2 because the function doesnt do it @@ -2299,7 +2392,7 @@ void mlawNonLinearTVENonLinearTVP::getIterated_DPhi(const double& T0, const doub // Initialise numerical quantities static STensor3 Phi_plus, J_plus, devPhi_plus, N_plus, GammaN_plus, Ee_plus, Ce_plus, KS_plus, MS_plus, expGN_plus, Hinv_plus, devN_plus, devX_plus; double pPhi_plus,Ke_plus,Ge_plus, trN_plus, trX_plus; - static STensor43 dJdPhi_plus, dJdPhi_plus_inv, dexpAdA_plus, Bd_stiffnessTerm_plus,Ge_Tensor_plus; + static STensor43 dJdPhi_plus, dJdPhi_plus_inv, dexpAdA_plus, Bd_stiffnessTerm_plus,Ge_Tensor_plus, dJdPhi_plus2, dJdPhi_plus2_inv; STensor43* Ge_TrEeTensor_plus = NULL; static IPNonLinearTVP q1_plus(*q0); @@ -2312,6 +2405,7 @@ void mlawNonLinearTVENonLinearTVP::getIterated_DPhi(const double& T0, const doub // numerical Dho4inv (Jacobian dJ/dPhi) // _perturbationfactor = DPhi_numerical + /* for (int i=0; i<3; i++){ for (int j=0; j<3; j++){ @@ -2321,7 +2415,7 @@ void mlawNonLinearTVENonLinearTVP::getIterated_DPhi(const double& T0, const doub STensorOperation::decomposeDevTr(Phi_plus,devPhi_plus,pPhi_plus); pPhi_plus = Phi_plus.trace()/3; N_plus = _I; - N_plus *= 2.*_b/3; + N_plus *= 2.*_b/3*pPhi_plus; N_plus += 3*devPhi_plus; GammaN_plus = N_plus; GammaN_plus *= Gamma; @@ -2337,13 +2431,14 @@ void mlawNonLinearTVENonLinearTVP::getIterated_DPhi(const double& T0, const doub Ce_plus(ii,jj) += Hinv_plus(ii,kk)*Hinv_plus(kk,ll)*Cepr(ll,jj); } - Ee_plus = - Gamma*N_plus; - Ee_plus += Eepr(i,j); + // Ee_plus = - Gamma*N_plus; + // Ee_plus += Eepr(i,j); + bool ok=STensorOperation::logSTensor3(Ce_plus,_order,Ee_plus); if (Ge_TrEeTensor_plus == NULL){ - mlawNonLinearTVM::ThermoViscoElasticPredictor(Ee_plus,q0->_Ee,q0,&q1_plus,Ke_plus,Ge_plus,DKDTsum,DGDTsum,T0,T,true,Bd_stiffnessTerm_plus); + mlawNonLinearTVM::ThermoViscoElasticPredictor(Ee_plus,q0->_Ee,q0,&q1_plus,Ke_plus,Ge_plus,T0,T,true,Bd_stiffnessTerm_plus); } else{ // TC asymmetry - mlawNonLinearTVM::ThermoViscoElasticPredictor(Ee_plus,q0->_Ee,q0,&q1_plus,Ke_plus,Ge_plus,DKDTsum,DGDTsum,T0,T,true,Bd_stiffnessTerm_plus,Ge_TrEeTensor_plus); + mlawNonLinearTVM::ThermoViscoElasticPredictor(Ee_plus,q0->_Ee,q0,&q1_plus,Ke_plus,Ge_plus,T0,T,true,Bd_stiffnessTerm_plus,Ge_TrEeTensor_plus); } Ge_Tensor_plus = _I4; Ge_Tensor_plus *= Ge_plus*2; // *2 because the function doesnt do it @@ -2427,6 +2522,7 @@ void mlawNonLinearTVENonLinearTVP::getIterated_DPhi(const double& T0, const doub if(!ok) { Phi(0,0) = Phi(1,1) = Phi(2,2) = sqrt(-1.); + // Gamma *= 0.1; return; } Ee *= 0.5; @@ -2434,11 +2530,11 @@ void mlawNonLinearTVENonLinearTVP::getIterated_DPhi(const double& T0, const doub // update corKir if (Ge_TrEeTensor == NULL){ // mlawNonLinearTVM::ThermoViscoElasticPredictor_forTVP(Ee,q0->_Ee,q0,q1,Ke,Ge,T0,T,true,Bd_stiffnessTerm); - mlawNonLinearTVM::ThermoViscoElasticPredictor(Ee,q0->_Ee,q0,q1,Ke,Ge,DKDTsum,DGDTsum,T0,T,true,Bd_stiffnessTerm); + mlawNonLinearTVM::ThermoViscoElasticPredictor(Ee,q0->_Ee,q0,q1,Ke,Ge,T0,T,true,Bd_stiffnessTerm); } else{ // TC asymmetry // mlawNonLinearTVM::ThermoViscoElasticPredictor_forTVP(Ee,q0->_Ee,q0,q1,Ke,Ge,T0,T,true,Bd_stiffnessTerm,Ge_TrEeTensor); - mlawNonLinearTVM::ThermoViscoElasticPredictor(Ee,q0->_Ee,q0,q1,Ke,Ge,DKDTsum,DGDTsum,T0,T,true,Bd_stiffnessTerm, Ge_TrEeTensor); + mlawNonLinearTVM::ThermoViscoElasticPredictor(Ee,q0->_Ee,q0,q1,Ke,Ge,T0,T,true,Bd_stiffnessTerm, Ge_TrEeTensor); } Ge_Tensor = _I4; Ge_Tensor *= Ge*2; // *2 because the function doesnt do it @@ -2483,15 +2579,14 @@ void mlawNonLinearTVENonLinearTVP::getIterated_DPhi(const double& T0, const doub }*/ // debug - /* for (int i=0; i<3; i++) for (int j=0; j<3; j++) for (int k=0; k<3; k++) for (int l=0; l<3; l++) - dJdPhi_plus(k,l,i,j) = (J(k,l) - J0(k,l))/(_perturbationfactor); + // dJdPhi_plus2(k,l,i,j) = (J(k,l) - J0(k,l))/(_perturbationfactor); - STensorOperation::inverseSTensor43(dJdPhi_plus,dJdPhi_plus_inv); - J0 = J;*/ + // STensorOperation::inverseSTensor43(dJdPhi_plus2,dJdPhi_plus2_inv); + // J0 = J; for (int i=0; i<3; i++) for (int j=0; j<3; j++) @@ -2513,15 +2608,16 @@ void mlawNonLinearTVENonLinearTVP::getIterated_DPhi(const double& T0, const doub if (fabs(J_tol) <_tol) break; if(ite > maxite){ - Msg::Error("No convergence for iterated Phi mlawNonLinearTVENonLinearTVP nonAssociatedFlow iter = %d, J_tol = %e!!",ite,J_tol); + // Msg::Error("No convergence for iterated Phi mlawNonLinearTVENonLinearTVP nonAssociatedFlow iter = %d, J_tol = %e!!",ite,J_tol); // Msg::Error("Exiting the function Iterated Phi!!"); // Phi(0,0) = Phi(1,1) = Phi(2,2) = sqrt(-1.); + // Gamma *= 0.1; return; } } // while } - +/* void mlawNonLinearTVENonLinearTVP::TEST_predictorCorrector_TVP_nonAssociatedFlow_nonLinearTVE( const STensor3& F0, const STensor3& F, const IPNonLinearTVP *q0, IPNonLinearTVP *q1, const double T0, const double T, const STensor3& Fepr, const STensor3& Cepr, @@ -2584,7 +2680,7 @@ void mlawNonLinearTVENonLinearTVP::TEST_predictorCorrector_TVP_nonAssociatedFlow static STensor43 Ge_Tensor_pr, Ge_Tensor, Bd_stiffnessTerm; STensorOperation::zero(Ge_Tensor_pr); STensorOperation::zero(Ge_Tensor); - mlawNonLinearTVM::ThermoViscoElasticPredictor_forTVP(Ee,q0->_Ee,q0,q1,Ke,Ge,T0,T,true,Bd_stiffnessTerm); + mlawNonLinearTVM::ThermoViscoElasticPredictor(Ce,Ee,q0->_Ee,q0,q1,Ke,Ge,T0,T,true,Bd_stiffnessTerm); Ge_Tensor = _I4; Ge_Tensor *= Ge*2; // Because the function does not do it Ge_Tensor += Bd_stiffnessTerm; @@ -2815,11 +2911,11 @@ void mlawNonLinearTVENonLinearTVP::TEST_predictorCorrector_TVP_nonAssociatedFlow // Update A A = sqrt(6.*PhiEq*PhiEq+4.*_b*_b/3.*ptilde*ptilde); - /* - Dgamma = pow(kk,1)*Gamma*A; // pow(kk,2) DEBUG - updateEqPlasticDeformation(q1,q0,q1->_nup,Dgamma); - hardening(q0,q1,T); - getYieldCoefficients(q1,a);*/ + + // Dgamma = pow(kk,1)*Gamma*A; // pow(kk,2) DEBUG + // updateEqPlasticDeformation(q1,q0,q1->_nup,Dgamma); + // hardening(q0,q1,T); + // getYieldCoefficients(q1,a); // Update f, g f = a(2)*pow(PhiEq,_n) - (a(1)*ptilde+a(0)); diff --git a/NonLinearSolver/materialLaw/mlawNonLinearTVENonLinearTVP.h b/NonLinearSolver/materialLaw/mlawNonLinearTVENonLinearTVP.h index 35e26d4bedf3070726ad9676bba1cae7b2b2f600..2ecb9c61a8d4d050d2c9eb925fc2f85c586512c2 100644 --- a/NonLinearSolver/materialLaw/mlawNonLinearTVENonLinearTVP.h +++ b/NonLinearSolver/materialLaw/mlawNonLinearTVENonLinearTVP.h @@ -25,7 +25,7 @@ class mlawNonLinearTVENonLinearTVP : public mlawNonLinearTVP{ virtual void freeEnergyPlasticityDerivatives(const IPNonLinearTVP *q0, IPNonLinearTVP *q1, const double& T0, const double& T, STensor3& dPsy_TVPdF, double& dPsy_TVPdT) const; virtual void getIterated_DPhi(const double& T0, const double& T, const IPNonLinearTVP *q0, IPNonLinearTVP *q1, - const double& Gamma, const double& Cxtr, const double& Cxdev, + double& Gamma, const double& Cxtr, const double& Cxdev, const STensor3& Cepr, const STensor3& Eepr, const double& trXn, const STensor3& devXn, double& Ke, double& Ge, STensor43& Ge_Tensor, @@ -45,7 +45,7 @@ class mlawNonLinearTVENonLinearTVP : public mlawNonLinearTVP{ virtual void TEST_predictorCorrector_TVP_nonAssociatedFlow_nonLinearTVE( const STensor3& F0, const STensor3& F, const IPNonLinearTVP *q0, IPNonLinearTVP *q1, const double T0, const double T, const STensor3& Fepr, const STensor3& Cepr, - double& ptilde, STensor3& devPhi, double& Gamma, double& Dgamma, double& A, double& f, STensor3& Me, STensor3& P) const; + double& ptilde, STensor3& devPhi, double& Gamma, double& Dgamma, double& A, double& f, STensor3& Me, STensor3& P) const{}; virtual void predictorCorrector_TVP_nonAssociatedFlow_nonLinearTVE(const STensor3& F0, const STensor3& F, const IPNonLinearTVP *q0_, IPNonLinearTVP *q1, STensor3&P, const bool stiff, STensor43& Tangent, STensor43& dFedF, STensor43& dFpdF, STensor3& dFedT, STensor3& dFpdT, diff --git a/NonLinearSolver/materialLaw/mlawNonLinearTVENonLinearTVP2.cpp b/NonLinearSolver/materialLaw/mlawNonLinearTVENonLinearTVP2.cpp new file mode 100644 index 0000000000000000000000000000000000000000..02dc4d6696f2b68d326640e7f29ce30c8d99391a --- /dev/null +++ b/NonLinearSolver/materialLaw/mlawNonLinearTVENonLinearTVP2.cpp @@ -0,0 +1,3056 @@ +// +// C++ Interface: Material Law +// +// Description: Non-Linear Thermo-Visco-Mechanics (Thermo-ViscoElasto-ViscoPlasto Law) with Non-Local Damage Interface (soon.....) +// +// Author: <Ujwal Kishore J - FLE_Knight>, (C) 2024 +// +// Copyright: See COPYING file that comes with this distribution +// +// + +#include "nonLinearMechSolver.h" +#include "mlawNonLinearTVENonLinearTVP2.h" + + +mlawNonLinearTVENonLinearTVP2::mlawNonLinearTVENonLinearTVP2(const int num,const double E,const double nu, const double rho, const double tol, + const double Tinitial, const double Alpha, const double KThCon, const double Cp, + const bool matrixbyPerturbation, const double pert, const double stressIteratorTol, const bool thermalEstimationPreviousConfig): + mlawNonLinearTVP(num, E, nu, rho, tol, Tinitial, Alpha, KThCon, Cp, matrixbyPerturbation, pert, thermalEstimationPreviousConfig), _stressIteratorTol(stressIteratorTol) { +}; + +mlawNonLinearTVENonLinearTVP2::mlawNonLinearTVENonLinearTVP2(const mlawNonLinearTVENonLinearTVP2& src): mlawNonLinearTVP(src), _stressIteratorTol(src._stressIteratorTol) { +}; + +mlawNonLinearTVENonLinearTVP2& mlawNonLinearTVENonLinearTVP2::operator=(const materialLaw& source){ + + mlawNonLinearTVP::operator=(source); + const mlawNonLinearTVENonLinearTVP2* src =dynamic_cast<const mlawNonLinearTVENonLinearTVP2*>(&source); + if(src != NULL){ + _stressIteratorTol = src->_stressIteratorTol; + } + return *this; +}; + +mlawNonLinearTVENonLinearTVP2::~mlawNonLinearTVENonLinearTVP2(){ +}; + +double mlawNonLinearTVENonLinearTVP2::freeEnergyPlasticity(const IPNonLinearTVP *q0, IPNonLinearTVP *q1, const double& T0, const double& T) const{ + + double Psy_TVP(0.); + + // 1. Kinematic Hardening + double Hb(0.); + if (q1->_ipKinematic != NULL){ + Hb = q1->_ipKinematic->getR(); // kinematic hardening parameter + } + + double kk = 1./sqrt(1.+2.*q1->_nup*q1->_nup); + static STensor3 alpha; + STensorOperation::zero(alpha); + if(Hb>0.){ + alpha = q1->_backsig; + alpha *= 1/(pow(kk,1)*Hb); //pow(kk,2) debug + } + STensorOperation::doubleContractionSTensor3(q1->_backsig,alpha,Psy_TVP); + + // 2. Isotropic Hardening + double intR = q1->_ipCompression->getIntegR(); + double sigc0 = q1->_ipCompression->getR0(); + intR -= sigc0*q1->_epspbarre; + + Psy_TVP += intR; + + // If mullins, then calculate psi_VP derivatives + // if (_mullinsEffect != NULL && q._ipMullinsEffect != NULL){ + // *DpsiDT = 0.; + // STensorOperation::zero(*DpsiDE); + // } + return Psy_TVP; +} + +void mlawNonLinearTVENonLinearTVP2::freeEnergyPlasticityDerivatives(const IPNonLinearTVP *q0, IPNonLinearTVP *q1, const double& T0, const double& T, + STensor3& dPsy_TVPdF, double& dPsy_TVPdT) const{ + + STensorOperation::zero(dPsy_TVPdF); + dPsy_TVPdT = 0.; + + // 1. Kinematic Hardening + double Hb(0.), dHb(0.), dHbdT(0.); + if (q1->_ipKinematic != NULL){ + Hb = q1->_ipKinematic->getR(); // kinematic hardening parameter + dHb = q1->_ipKinematic->getDR(); // kinematic hardening parameter derivative (dHb/dgamma) + dHbdT = q1->_ipKinematic->getDRDT(); // make sure to normalise DRDT while defining in python file + } + + double kk = 1./sqrt(1.+2.*q1->_nup*q1->_nup); + if(Hb>0.){ + + static STensor3 term1, term2; + STensorOperation::multSTensor3STensor43(q1->_backsig,q1->_DbackSigDF,term1); + term2 = q1->_DgammaDF; + term2 *= (-1./(2*Hb)*dHb*q1->_backsig.dotprod()); + + dPsy_TVPdF = term1; + dPsy_TVPdF += term2; + dPsy_TVPdF *= 1./(pow(kk,1)*Hb); //pow(kk,2) debug + + double term3, term4; + STensorOperation::doubleContractionSTensor3(q1->_backsig,q1->_DbackSigDT,term3); + term4 = -(dHbdT + dHb*q1->_DgammaDT)/(2*Hb)*q1->_backsig.dotprod(); + dPsy_TVPdT = (term3+term4)/(pow(kk,1)*Hb); //pow(kk,2) debug + + } + + + // 2. Isotropic Hardening + + // Get Hc, etc. + double intR = q1->_ipCompression->getIntegR(); + double sigc0 = q1->_ipCompression->getR0(); // Initial yield stress + intR -= sigc0*q1->_epspbarre; + + double R(0.), dsigc0dT(0.), sigc(0.); + dsigc0dT = sigc0*_temFunc_Sy0->getDiff(T); + sigc = q1->_ipCompression->getR(); + + // Get R + R = sigc - sigc0; + + dPsy_TVPdF += R*q1->_DgammaDF; + dPsy_TVPdT += (R*q1->_DgammaDT + _temFunc_Sy0->getDiff(T)/ _temFunc_Sy0->getVal(T)*intR - dsigc0dT*q1->_epspbarre); +} + +void mlawNonLinearTVENonLinearTVP2::constitutive( // This function is just a placeholder, defined in the pure virtual class -> does nothing, its never called. + const STensor3& F0, // previous deformation gradient (input @ time n) + const STensor3& F1, // current deformation gradient (input @ time n+1) + STensor3 &P1, // current 1st Piola-Kirchhoff stress tensor (output) + const IPVariable *q0i, // array of previous internal variables + IPVariable *q1i, // current array of internal variable (in ipvcur on output), + STensor43 &Tangent, // tangents (output) + const bool stiff, // if true compute the tangents + STensor43* elasticTangent, + const bool dTangent, + STensor63* dCalgdeps) const{ + static SVector3 gradT, temp2; + static STensor3 temp3; + static STensor33 temp33; + static double tempVal; + static STensor43 dFpdF, dFedF; + static STensor3 dFpdT, dFedT; + + const IPNonLinearTVP *q0 = dynamic_cast<const IPNonLinearTVP *> (q0i); + IPNonLinearTVP *q1 = dynamic_cast<IPNonLinearTVP *>(q1i); + + if(elasticTangent != NULL) Msg::Error("mlawNonLinearTVENonLinearTVP2 elasticTangent not defined"); + predictorCorrector_ThermoViscoPlastic(F0,F1,P1,q0,q1,Tangent,dFpdF, dFpdT, dFedF, dFedT, + _Tref,_Tref,gradT,gradT,temp2,temp3,temp3,temp2,temp33, + tempVal,tempVal,temp3, + tempVal,tempVal,temp3, + stiff, NULL); +}; + +void mlawNonLinearTVENonLinearTVP2::constitutive( + const STensor3& F0, // initial deformation gradient (input @ time n) + const STensor3& F1, // updated deformation gradient (input @ time n+1) + STensor3& P, // updated 1st Piola-Kirchhoff stress tensor (output) + const IPVariable *q0i, // array of initial internal variable + IPVariable *q1i, // updated array of internal variable (in ipvcur on output), + STensor43 &Tangent, // constitutive mechanical tangents (output) + const double& T0, // previous temperature + const double& T, // temperature + const SVector3 &gradT0, // previous temperature gradient + const SVector3 &gradT, // temperature gradient + SVector3 &fluxT, // temperature flux + STensor3 &dPdT, // mechanical-thermal coupling + STensor3 &dfluxTdgradT, // thermal tengent + SVector3 &dfluxTdT, + STensor33 &dfluxTdF, // thermal-mechanical coupling + double &thermalSource, // - Cp*dTdt + double &dthermalSourcedT, // thermal source + STensor3 &dthermalSourcedF, + double &mechanicalSource, // mechanical source--> convert to heat + double &dmechanicalSourcedT, + STensor3 &dmechanicalSourceF, + const bool stiff, + STensor43* elasticTangent) const{ + + const IPNonLinearTVP *q0 = dynamic_cast<const IPNonLinearTVP *>(q0i); + IPNonLinearTVP *q1 = dynamic_cast<IPNonLinearTVP *>(q1i); + + // Declaring here, coz I dont know better. + static STensor43 dFedF, dFpdF; + static STensor3 dFpdT, dFedT; + + if (!_tangentByPerturbation){ + + this->predictorCorrector_ThermoViscoPlastic(F0, F1, P, q0, q1, Tangent, dFpdF, dFpdT, dFedF, dFedT, + T0, T, gradT0, gradT, fluxT, dPdT, dfluxTdgradT, dfluxTdT, dfluxTdF, + thermalSource, dthermalSourcedT, dthermalSourcedF, + mechanicalSource, dmechanicalSourcedT, dmechanicalSourceF, + stiff, elasticTangent); + } + + else{ + + this->predictorCorrector_ThermoViscoPlastic(F0, F1, P, q0, q1, T0, T, gradT0, gradT, fluxT, thermalSource, mechanicalSource, elasticTangent); + if (stiff) + this->tangent_full_perturbation(F0,F1,P,q0,q1,T0, T, gradT0, gradT, fluxT, thermalSource, mechanicalSource, + Tangent, dFpdF, dFpdT, dFedF, dFedT, + dPdT, dfluxTdgradT, dfluxTdT, dfluxTdF, + dthermalSourcedT, dthermalSourcedF, + dmechanicalSourcedT, dmechanicalSourceF); + } +}; + + +void mlawNonLinearTVENonLinearTVP2::predictorCorrector_ThermoViscoPlastic( + const STensor3& F0, // initial deformation gradient (input @ time n) + const STensor3& F1, // updated deformation gradient (input @ time n+1) + STensor3 &P, // updated 1st Piola-Kirchhoff stress tensor (output) + const IPNonLinearTVP *q0, // array of initial internal variable + IPNonLinearTVP *q1, // updated array of internal variable (in ipvcur on output), + const double& T0, // previous temperature + const double& T, // temperature + const SVector3 &gradT0, // previous temeprature gradient + const SVector3 &gradT, // temeprature gradient + SVector3 &fluxT, // temperature flux) + double &thermalSource, + double& mechanicalSource, + STensor43* elasticTangent) const{ + // temp variables + static STensor43 Tangent, dFpdF, dFedF; + static STensor3 dPdT, dfluxTdgradT, dthermalSourcedF, dmechanicalSourceF, dFpdT, dFedT; + static STensor33 dfluxTdF; + static SVector3 dfluxTdT; + static double dthermalSourcedT, dmechanicalSourcedT; + predictorCorrector_ThermoViscoPlastic(F0,F1,P,q0,q1,Tangent,dFpdF,dFpdT,dFedF,dFedT, + T0,T,gradT0,gradT,fluxT,dPdT,dfluxTdgradT,dfluxTdT,dfluxTdF, + thermalSource,dthermalSourcedT,dthermalSourcedF, + mechanicalSource,dmechanicalSourcedT,dmechanicalSourceF,false,elasticTangent); +}; + +void mlawNonLinearTVENonLinearTVP2::tangent_full_perturbation( + const STensor3& F0, + const STensor3& F1, // updated deformation gradient (input @ time n+1) + STensor3& P, // updated 1st Piola-Kirchhoff stress tensor (output) + const IPNonLinearTVP *q0, // array of initial internal variable + IPNonLinearTVP *q1, // updated array of internal variable (in ipvcur on output), + const double& T0, // previous temperature + const double& T, // temperature + const SVector3 &gradT0, // previous temeprature gradient + const SVector3 &gradT, // temeprature gradient + SVector3 &fluxT, // temperature flux) + double &thermalSource, + double &mechanicalSource, + STensor43 &Tangent, // mechanical tangents (output) + STensor43 &dFpdF, // plastic tangent + STensor3 &dFpdT, // plastic tangent + STensor43 &dFedF, // elastic tangent + STensor3 &dFedT, // elastic tangent + STensor3 &dPdT, // mechanical-thermal coupling + STensor3 &dfluxTdgradT, // thermal tengent + SVector3 &dfluxTdT, + STensor33 &dfluxTdF, // thermal-mechanical coupling + double &dthermalSourcedT, // thermal source + STensor3 &dthermalSourcedF, + double &dmechanicalSourcedT, + STensor3 &dmechanicalSourceF) const{ + + static STensor3 Fplus, Pplus; + static SVector3 fluxTPlus, gradTplus; + static double thermalSourcePlus; + static double mechanicalSourcePlus; + static IPNonLinearTVP qPlus(*q0); + + // perturb F + for (int i=0; i<3; i++){ + for (int j=0; j<3; j++){ + Fplus = F1; + Fplus(i,j) += _perturbationfactor; + + predictorCorrector_ThermoViscoPlastic(F0,Fplus,Pplus,q0,&qPlus,T0,T,gradT0,gradT,fluxTPlus,thermalSourcePlus,mechanicalSourcePlus, NULL); + + q1->_DgammaDF(i,j) = (qPlus._epspbarre - q1->_epspbarre)/_perturbationfactor; + q1->_DirreversibleEnergyDF(i,j) = (qPlus._irreversibleEnergy - q1->_irreversibleEnergy)/_perturbationfactor; + + for (int k=0; k<3; k++){ + for (int l=0; l<3; l++){ + Tangent(k,l,i,j) = (Pplus(k,l) - P(k,l))/(_perturbationfactor); + dFpdF(k,l,i,j) = (qPlus._Fp(k,l)-q1->_Fp(k,l))/_perturbationfactor; + dFedF(k,l,i,j) = (qPlus._Fe(k,l)-q1->_Fe(k,l))/_perturbationfactor; + } + dfluxTdF(k,i,j) = (fluxTPlus(k) - fluxT(k))/_perturbationfactor; + } + + q1->getRefToDElasticEnergyPartdF()(i,j)=(qPlus.getConstRefToElasticEnergyPart()-q1->getConstRefToElasticEnergyPart())/_perturbationfactor; + q1->getRefToDViscousEnergyPartdF()(i,j)=(qPlus.getConstRefToViscousEnergyPart()-q1->getConstRefToViscousEnergyPart())/_perturbationfactor; + q1->getRefToDPlasticEnergyPartdF()(i,j)=(qPlus.getConstRefToPlasticEnergyPart()-q1->getConstRefToPlasticEnergyPart())/_perturbationfactor; + + dthermalSourcedF(i,j) = (thermalSourcePlus - thermalSource)/_perturbationfactor; + dmechanicalSourceF(i,j) = (mechanicalSourcePlus - mechanicalSource)/_perturbationfactor; + } + } + + // perturb gradT + double gradTpert = _perturbationfactor*T0/1e-3; + for (int i=0; i<3; i++){ + gradTplus = gradT; + gradTplus(i) += gradTpert; + predictorCorrector_ThermoViscoPlastic(F0,F1,Pplus,q0,&qPlus,T0,T,gradT0,gradTplus,fluxTPlus,thermalSourcePlus,mechanicalSourcePlus, NULL); + for (int k=0; k<3; k++){ + dfluxTdgradT(k,i) = (fluxTPlus(k) - fluxT(k))/gradTpert; + } + } + + // perturb T + double Tplus = T+ _perturbationfactor*T0; + predictorCorrector_ThermoViscoPlastic(F0,F1,Pplus,q0,&qPlus,T0,Tplus,gradT0,gradT,fluxTPlus,thermalSourcePlus,mechanicalSourcePlus, NULL); + + q1->_DgammaDT = (qPlus._epspbarre - q1->_epspbarre)/(_perturbationfactor*T0); + q1->_DirreversibleEnergyDT = (qPlus._irreversibleEnergy - q1->_irreversibleEnergy)/(_perturbationfactor*T0); + + for (int k=0; k<3; k++){ + for (int l=0; l<3; l++){ + dFpdT(k,l) = (qPlus._Fp(k,l) - q1->_Fp(k,l))/(_perturbationfactor*T0); + dFedT(k,l) = (qPlus._Fe(k,l) - q1->_Fe(k,l))/(_perturbationfactor*T0); + dPdT(k,l) = (Pplus(k,l) - P(k,l))/(_perturbationfactor*T0); + } + dfluxTdT(k) = (fluxTPlus(k) - fluxT(k))/(_perturbationfactor*T0); + } + + q1->getRefToDElasticEnergyPartdT() = (qPlus.getConstRefToElasticEnergyPart()-q1->getConstRefToElasticEnergyPart())/(_perturbationfactor*T0); + q1->getRefToDViscousEnergyPartdT() = (qPlus.getConstRefToViscousEnergyPart()-q1->getConstRefToViscousEnergyPart())/(_perturbationfactor*T0); + q1->getRefToDPlasticEnergyPartdT() = (qPlus.getConstRefToPlasticEnergyPart()-q1->getConstRefToPlasticEnergyPart())/(_perturbationfactor*T0); + + dthermalSourcedT = (thermalSourcePlus - thermalSource)/(_perturbationfactor*T0); + dmechanicalSourcedT = (mechanicalSourcePlus - mechanicalSource)/(_perturbationfactor*T0); + +}; + +void mlawNonLinearTVENonLinearTVP2::predictorCorrector_ThermoViscoPlastic( + const STensor3& F0, // initial deformation gradient (input @ time n) + const STensor3& F1, // updated deformation gradient (input @ time n+1) + STensor3& P, // updated 1st Piola-Kirchhoff stress tensor (output) + const IPNonLinearTVP *q0, // array of initial internal variable + IPNonLinearTVP *q1, // updated array of internal variable (in ipvcur on output), + STensor43 &Tangent, // mechanical tangents (output) + STensor43 &dFpdF, // plastic tangent + STensor3 &dFpdT, // plastic tangent + STensor43 &dFedF, // elastic tangent + STensor3 &dFedT, // elastic tangent + const double& T0, // previous temperature + const double& T, // temperature + const SVector3 &gradT0, // previoustemeprature gradient + const SVector3 &gradT, // temeprature gradient + SVector3 &fluxT, // temperature flux + STensor3 &dPdT, // mechanical-thermal coupling + STensor3 &dfluxTdgradT, // thermal tengent + SVector3 &dfluxTdT, + STensor33 &dfluxTdF, // thermal-mechanical coupling + double &thermalSource, // - cp*dTdt + double &dthermalSourcedT, // thermal source + STensor3 &dthermalSourcedF, + double &mechanicalSource, // mechanical source--> convert to heat + double &dmechanicalSourcedT, + STensor3 &dmechanicalSourceF, + const bool stiff, + STensor43* elasticTangent) const{ + + if (_tangentByPerturbation){ + if (_nonAssociatedFlow){ + this->predictorCorrector_TVP_nonAssociatedFlow_nonLinearTVE(F0,F1,q0,q1,P,false,Tangent,dFedF,dFpdF,dFedT,dFpdT, + T0,T,gradT0,gradT,fluxT,dPdT,dfluxTdgradT,dfluxTdT,dfluxTdF, + thermalSource,dthermalSourcedT,dthermalSourcedF, + mechanicalSource,dmechanicalSourcedT,dmechanicalSourceF); + } + else{ + this->mlawNonLinearTVP::predictorCorrector_TVP_AssociatedFlow(F1,q0,q1,P,false,Tangent,dFedF,dFpdF,T0,T); + } + + } + else{ + if (_nonAssociatedFlow){ + this->predictorCorrector_TVP_nonAssociatedFlow_nonLinearTVE(F0,F1,q0,q1,P,stiff,Tangent,dFedF,dFpdF,dFedT,dFpdT, + T0,T,gradT0,gradT,fluxT,dPdT,dfluxTdgradT,dfluxTdT,dfluxTdF, + thermalSource,dthermalSourcedT,dthermalSourcedF, + mechanicalSource,dmechanicalSourcedT,dmechanicalSourceF); + } + else{ + this->mlawNonLinearTVP::predictorCorrector_TVP_AssociatedFlow(F1,q0,q1,P,stiff,Tangent,dFedF,dFpdF,T0,T); + } + } + +}; + + +void mlawNonLinearTVENonLinearTVP2::predictorCorrector_TVP_nonAssociatedFlow_nonLinearTVE(const STensor3& F0, const STensor3& F, const IPNonLinearTVP *q0, IPNonLinearTVP *q1, + STensor3&P, const bool stiff, STensor43& Tangent, STensor43& dFedF, STensor43& dFpdF, STensor3& dFedT, STensor3& dFpdT, + const double T0, + const double T, + const SVector3 &gradT0, // previous temperature gradient + const SVector3 &gradT, // temperature gradient + SVector3 &fluxT, // temperature flux + STensor3 &dPdT, // mechanical-thermal coupling + STensor3 &dfluxTdgradT, // thermal tengent + SVector3 &dfluxTdT, + STensor33 &dfluxTdF, // thermal-mechanical coupling + double &thermalSource, // - Cp*dTdt + double &dthermalSourcedT, // thermal source + STensor3 &dthermalSourcedF, + double &mechanicalSource, // mechanical source--> convert to heat + double &dmechanicalSourcedT, + STensor3 &dmechanicalSourceF) const{ + + // compute elastic predictor + STensor3& Fp1 = q1->_Fp; + const STensor3& Fp0 = q0->_Fp; + + // Update the Properties to the current temperature (see below which ones are being used) + double CpT, DCpDT; getCp(CpT,T,&DCpDT); + + // Initialise predictor values + Fp1 = Fp0; // plastic deformation tensor + q1->_epspbarre = q0->_epspbarre; // plastic equivalent strain + q1->_epspCompression = q0->_epspCompression; + q1->_epspTraction = q0->_epspTraction; + q1->_epspShear = q0->_epspShear; + q1->_backsig = q0->_backsig; // backstress tensor + q1->_DbackSigDT = q0->_DbackSigDT; // DbackSigDT + q1->_DgammaDt = 0.; + + // Get hardening parameters + this->mlawNonLinearTVP::hardening(q0,q1,T); + static fullVector<double> a(3), Da(3); // yield coefficients and derivatives with respect to plastic deformation + this->mlawNonLinearTVP::getYieldCoefficients(q1,a); + //a.print("a init"); + + double Hb(0.), dHb(0.), ddHb(0.), dHbdT(0.), ddHbdgammadT(0.), ddHbddT(0.); + if (q1->_ipKinematic != NULL){ + Hb = q1->_ipKinematic->getR(); // kinematic hardening parameter + dHb = q1->_ipKinematic->getDR(); // kinematic hardening parameter derivative (dHb/dgamma) + dHbdT = q1->_ipKinematic->getDRDT(); // make sure to normalise DRDT while defining in python file + ddHbddT = q1->_ipKinematic->getDDRDTT(); + ddHbdgammadT = q1->_ipKinematic->getDDRDT(); + } + + double eta(0.),Deta(0.),DetaDT(0.); + if (_viscosity != NULL) + _viscosity->get(q1->_epspbarre,T,eta,Deta,DetaDT); + + // Get Cepr, Ceinvpr + static STensor3 Fpinv, Ce, Fepr; + STensorOperation::inverseSTensor3(Fp1,Fpinv); + STensorOperation::multSTensor3(F,Fpinv,Fepr); + STensorOperation::multSTensor3FirstTranspose(Fepr,Fepr,Ce); + + static STensor3 Eepr, Cepr, Ceinvpr; + Cepr = Ce; + STensorOperation::inverseSTensor3(Cepr,Ceinvpr); + + static STensor3 invFp0; // plastic predictor + invFp0= Fpinv; + STensor3& Fe = q1->_Fe; + Fe = Fepr; + + // Predictor - TVE + static STensor43 DlnDCepr, DlnDCe; + static STensor63 DDlnDDCe; + static STensor3 expGN, GammaN; + static STensor43 dexpAdA; // estimation of dexpA/dA + expGN = _I; // if Gamma = 0, expGN = _I + // dexpAdA = _I4; + STensorOperation::zero(dexpAdA); // CHECKERS + + STensor3& Ee = q1->_Ee; + // STensorOperation::logSTensor3(Ce,_order,Ee,&DlnDCepr,&DDlnDDCe); + bool ok=STensorOperation::logSTensor3(Ce,_order,Ee,&DlnDCepr,&DDlnDDCe); + if(!ok) + { + P(0,0) = P(1,1) = P(2,2) = sqrt(-1.); + return; + } + Ee *= 0.5; + Eepr = Ee; + DlnDCe = DlnDCepr; + + // update A, B -> ExtraBranch calculations are within + double Ke(0.), Ge(0.), Ke_pr(0.), Ge_pr(0.); + static STensor43 Ge_Tensor_pr, Ge_Tensor, Bd_stiffnessTerm, Ge_TrEeTensor_pr, Ge_TrEeTensor; + STensorOperation::zero(Ge_Tensor_pr); STensorOperation::zero(Ge_Tensor); + STensorOperation::zero(Ge_TrEeTensor_pr); STensorOperation::zero(Ge_TrEeTensor); + + // NEW EIGEN + static fullVector<int> alignedIndex(3); alignedIndex(0) = 0; alignedIndex(1) = 1; alignedIndex(2) = 2; + STensor3& R = q1->_R; + STensor43& dRdEe = q1->_dRdEe; + STensor43& dRtdEe = q1->_dRtdEe; + static STensor3 Ee0_rot; + static STensor43 rotationStiffness_pr ,rotationStiffness; + STensorOperation::zero(rotationStiffness_pr); STensorOperation::zero(rotationStiffness); + q1->_Ee0 = q0->_Ee; + if (_rotationCorrectionScheme == 0 && _rotationCorrectionScheme == 1){ + mlawNonLinearTVM::rotationTensor_N_to_Nplus1(q0->_Ee0,q0->_Fp,Fp1,Ce,Ee,q0->_Ee,R,dRdEe,dRtdEe); + for(int i=0; i<3; i++) + for(int j=0; j<3; j++){ + Ee0_rot(i,j) = 0.; + for(int k=0; k<3; k++) + for(int l=0; l<3; l++) + Ee0_rot(i,j) += R(i,k)*q0->_Ee(k,l)*R(j,l); + } + } + else if(_rotationCorrectionScheme == 2){ + Ee0_rot = q0->_Ee; + STensorOperation::alignEigenDecomposition_NormBased_indexOnly(q0->_Ee,Ee,alignedIndex); + } + // NEW EIGEN + + if (_extraBranchNLType == TensionCompressionRegularisedType || _extraBranchNLType == hyper_exp_TCasymm_Type || _ExtraBranch_TVE_option == 3 || _ExtraBranch_TVE_option == 4 || _ExtraBranch_TVE_option == 5){ + // TC asymmetry -> for either case of TensionCompressionRegularisedType and _ExtraBranch_TVE_option == 3 + if (!_useRotationCorrection){ + mlawNonLinearTVM::ThermoViscoElasticPredictor(Ee,q0->_Ee,q0,q1,Ke,Ge,T0,T,stiff,Bd_stiffnessTerm,&Ge_TrEeTensor); + } + else{ + mlawNonLinearTVM::ThermoViscoElasticPredictor_forTVP(Ce,Ee,Ee0_rot,q0,q1,Ke,Ge,T0,T,stiff,alignedIndex,Bd_stiffnessTerm,&Ge_TrEeTensor,&rotationStiffness); // NEW EIGEN + } + Ge_TrEeTensor_pr = Ge_TrEeTensor; + rotationStiffness_pr = rotationStiffness; + } + else{ + if (!_useRotationCorrection){ + mlawNonLinearTVM::ThermoViscoElasticPredictor(Ee,q0->_Ee,q0,q1,Ke,Ge,T0,T,stiff,Bd_stiffnessTerm); + } + else{ + mlawNonLinearTVM::ThermoViscoElasticPredictor_forTVP(Ce,Ee,Ee0_rot,q0,q1,Ke,Ge,T0,T,stiff,alignedIndex,Bd_stiffnessTerm,NULL,&rotationStiffness); // NEW EIGEN + } + rotationStiffness_pr = rotationStiffness; + } + + Ge_Tensor = _I4; + Ge_Tensor *= Ge*2; // Because the function does not do it + Ge_Tensor += Bd_stiffnessTerm; + + // Keep the predictor values of Ke and Ge for tangents later + Ke_pr = Ke; + Ge_pr = Ge; + Ge_Tensor_pr = _I4; + Ge_Tensor_pr *= Ge_pr*2; // Because the function does not do it + Ge_Tensor_pr += Bd_stiffnessTerm; + +/* + // NEW - EIGEN + static STensor3 Fp0inv, Ce0, Fe0; + STensorOperation::inverseSTensor3(Fp0,Fp0inv); + STensorOperation::multSTensor3(F0,Fpinv,Fe0); + STensorOperation::multSTensor3FirstTranspose(Fe0,Fe0,Ce0); + + static fullMatrix<double> m1(3, 3), m2(3, 3), m3(3, 3), m4(3, 3), m5(3, 3); + static fullVector<double> eigenValReal1(3), eigenValReal2(3), eigenValReal3(3), eigenValReal4(3), eigenValReal5(3); + static fullVector<double> eigenValImag1(3), eigenValImag2(3), eigenValImag3(3), eigenValImag4(3), eigenValImag5(3); + static fullMatrix<double> leftEigenVect1(3,3), leftEigenVect2(3,3), leftEigenVect3(3,3), leftEigenVect4(3,3), leftEigenVect5(3,3); + static fullMatrix<double> rightEigenVect1(3,3), rightEigenVect2(3,3), rightEigenVect3(3,3), rightEigenVect4(3,3), rightEigenVect5(3,3); + m1.setAll(0.); m2.setAll(0.); m3.setAll(0.); m4.setAll(0.); m5.setAll(0.); + eigenValReal1.setAll(0.); eigenValReal2.setAll(0.); eigenValReal3.setAll(0.); eigenValReal4.setAll(0.); eigenValReal5.setAll(0.); + eigenValImag1.setAll(0.); eigenValImag2.setAll(0.); eigenValImag3.setAll(0.); eigenValImag4.setAll(0.); eigenValImag5.setAll(0.); + leftEigenVect1.setAll(0.); leftEigenVect2.setAll(0.); leftEigenVect3.setAll(0.); leftEigenVect4.setAll(0.); leftEigenVect5.setAll(0.); + rightEigenVect1.setAll(0.); rightEigenVect2.setAll(0.); rightEigenVect3.setAll(0.); rightEigenVect4.setAll(0.); rightEigenVect5.setAll(0.); + + // Get eigen values and vectors + q1->_kirchhoff.getMat(m1); Ce.getMat(m2); Ee.getMat(m3); q0->_Ee.getMat(m4); Ee0_rot.getMat(m5); + m1.eig(eigenValReal1,eigenValImag1,leftEigenVect1,rightEigenVect1,false); + m2.eig(eigenValReal2,eigenValImag2,leftEigenVect2,rightEigenVect2,false); + m3.eig(eigenValReal3,eigenValImag3,leftEigenVect3,rightEigenVect3,false); + m4.eig(eigenValReal4,eigenValImag4,leftEigenVect4,rightEigenVect4,false); + m5.eig(eigenValReal5,eigenValImag5,leftEigenVect5,rightEigenVect5,false); + // NEW - EIGEN +*/ + + // get predictor - dKeprDT + mlawNonLinearTVM::getTVEdCorKirDT(q0,q1,T0,T); + const STensor3& dKeprDT = q1->_DcorKirDT; // This has all extrabranches now + + // Initialise Dho + static STensor43 Dho, Dho2inv, Dho2_u_inv; // These will be important tensors. + double Dho2_v_inv(0.); + + // Get Kepr + static STensor3 Kepr; // Ke is corKir + Kepr = q1->_kirchhoff; + + // Get Xn; Initialise X + static STensor3 devXn, devX; + static double trXn, pXn, eXn, trX; + STensorOperation::decomposeDevTr(q0->_backsig,devXn,trXn); // needed for chaboche model + pXn = 1./3.*trXn; // 1st invariant of Xn + eXn = sqrt(1.5*devXn.dotprod()); // J2 invariant of Xn + + // Initialise Phipr + static STensor3 PhiPr, Phi; + PhiPr = q1->_kirchhoff; + PhiPr -= q1->_backsig; + Phi = PhiPr; + + static STensor3 devPhipr, devPhi; // effective dev stress predictor + double ptildepr(0.), ptilde(0.); + STensorOperation::decomposeDevTr(PhiPr,devPhipr,ptildepr); + ptildepr/= 3.; + + // Initialise Normal + static STensor3 devN, N; // dev part of yield normal + double trN = 0.; // trace part of yield normal + STensorOperation::zero(devN); + STensorOperation::zero(N); + + // Get plastic poisson ratio + q1->_nup = (9.-2.*_b)/(18.+2.*_b); + double kk = (1./sqrt(1.+2.*q1->_nup*q1->_nup)); + + // Initialise variables + double& Gamma = q1->_Gamma; // flow rule parameter + Gamma = 0.; + double dDgammaDGamma = 0.; + double Dgamma = 0.; // eqplastic strain increment + static fullVector<double> m(2); + mlawNonLinearTVP::getChabocheCoeffs(m,0,q1); + + double DfDGamma(0.), dfdDgamma(0.), dfdGamma(0.), dAdDgamma(0.), dAdGamma(0.); + + // Initialise Cx + double Cxdev = 1. + 3.*m(1)*pow(kk,1)*Hb; // pow(kk,2) DEBUG + double Cxtr = 1. + 2.*_b/3. *m(1)*pow(kk,1)*Hb; // pow(kk,2) DEBUG + double dCxdevdDgamma(0.), dCxtrdDgamma(0.); + if (Hb>0.){ + Cxdev -= m(0)*dHb*Dgamma/Hb + 1./Hb * dHbdT * (T-T0); + Cxtr -= m(0)*dHb*Dgamma/Hb + 1./Hb * dHbdT * (T-T0); + } + + // Initialise ptilde and devPhi + ptilde = ptildepr; + devPhi = devPhipr; + + // Initialise the rest + if (_extraBranchNLType == TensionCompressionRegularisedType || _extraBranchNLType == hyper_exp_TCasymm_Type || _ExtraBranch_TVE_option == 3 || _ExtraBranch_TVE_option == 4 || _ExtraBranch_TVE_option == 5){ + // TC asymmetry -> for either case of TensionCompressionRegularisedType and _ExtraBranch_TVE_option == 3 + getDho(Gamma,Cepr,Ceinvpr,Kepr,Ke,Ge_Tensor,kk,Hb,Cxtr,Cxdev,expGN,dexpAdA,Dho,Dho2inv,Dho2_u_inv,Dho2_v_inv,&Ge_TrEeTensor,&rotationStiffness); + } + else{ + getDho(Gamma,Cepr,Ceinvpr,Kepr,Ke,Ge_Tensor,kk,Hb,Cxtr,Cxdev,expGN,dexpAdA,Dho,Dho2inv,Dho2_u_inv,Dho2_v_inv,NULL,&rotationStiffness); + } + + double PhiEqpr2 = 1.5*devPhi.dotprod(); + double PhiEqpr = sqrt(PhiEqpr2); // -> second invariant + double PhiEq = PhiEqpr; // current effective deviator + + // Get f and A + double f = a(2)*pow(PhiEq,_n) - (a(1)*ptilde+a(0)); + double A = sqrt(6.*PhiEq*PhiEq+4.*_b*_b/3.*ptilde*ptilde); + + // Initialise g + double dgdDgamma(0.), dgdGamma(0.); + double g = Dgamma - kk*Gamma*A; + + // NR Loop - Gamma and Dgamma + if (q1->dissipationIsBlocked()){ + q1->getRefToDissipationActive() = false; + } + else{ + if (f>_tol){ + // Msg::Error("Plasticity"); + q1->getRefToDissipationActive() = true; + + // plasticity + int ite = 0; + int maxite = 100; // maximal number of iters + // Msg::Error("plasticity occurs f = %e",f); + //double f0 = fabs(f); + + while (fabs(f) >_tol or ite <1){ + + // Viscosity term + double etaOverDt = eta/this->getTimeStep(); + + // Get dCxdevdDgamma, dCxtrdDgamma + dCxdevdDgamma = 0.; dCxtrdDgamma = 0.; + if (Hb>0.){ + dCxdevdDgamma = -m(0)*1./Hb*dHb - m(0)*Dgamma*(-1./pow(Hb,2.)*pow(dHb,2.) + 1./Hb*ddHb) - (T-T0)*(-1./pow(Hb,2.)*dHb*dHbdT + 1./Hb*ddHbdgammadT); + dCxtrdDgamma = dCxdevdDgamma; + } + dCxdevdDgamma += 3.*m(1)*pow(kk,1)*dHb; // pow(kk,2) DEBUG + dCxtrdDgamma += (2.*_b/3.)*m(1)*pow(kk,1)*dHb; // pow(kk,2) DEBUG + + // Get Hp = dPhiPdDgamma, dPhiPdGamma + double Hp = ( 2*_b*pow(kk,1)*Gamma/3.*ptilde*(Hb/pow(Cxtr,2)*dCxtrdDgamma-1./Cxtr*dHb) + 1./3.*trXn/pow(Cxtr,2)*dCxtrdDgamma ) * Dho2_v_inv; // pow(kk,2) DEBUG + double dPhiPdGamma = -2*_b*ptilde*(Ke + pow(kk,1)*Hb/(3.*Cxtr)) * Dho2_v_inv; // pow(kk,2) DEBUG + + // Get He = dPhiEdGamma + // Get DdevPhidGamma + static STensor3 DdevPhidDgamma, DdevPhidDgamma_RHS; + static STensor3 DdevPhidGamma, DdevPhidGamma_RHS; + STensorOperation::zero(DdevPhidDgamma); STensorOperation::zero(DdevPhidGamma); + STensorOperation::zero(DdevPhidDgamma_RHS); STensorOperation::zero(DdevPhidGamma_RHS); + + for (int i=0; i<3; i++) + for (int j=0; j<3; j++){ + DdevPhidDgamma_RHS(i,j) += ( 3*Gamma*pow(kk,1)*( Hb/pow(Cxdev,2.)*dCxdevdDgamma - dHb/Cxdev ) * devPhi(i,j) + + devXn(i,j)/pow(Cxdev,2.)*dCxdevdDgamma ); // pow(kk,2) DEBUG + DdevPhidGamma_RHS(i,j) += (- 3*pow(kk,1)*Hb/Cxdev*devPhi(i,j) ); // pow(kk,2) DEBUG + for (int k=0; k<3; k++) + for (int l=0; l<3; l++){ + DdevPhidDgamma_RHS(i,j) += 2.*_b/3.*Gamma*( - Ge_TrEeTensor(i,j,k,l) - rotationStiffness(i,j,k,l))*_I(k,l)*Hp; // EIGEN + DdevPhidGamma_RHS(i,j) += ( -3.*Ge_Tensor(i,j,k,l)*devPhi(k,l) + 2.*_b/3.*Gamma*(- Ge_TrEeTensor(i,j,k,l) - rotationStiffness(i,j,k,l) )*_I(k,l)*dPhiPdGamma ); // EIGEN + DdevPhidGamma_RHS(i,j) += (-Ge_TrEeTensor(i,j,k,l) - rotationStiffness(i,j,k,l) )*N(k,l); // DEBUG // EIGEN + } + } + for (int i=0; i<3; i++) + for (int j=0; j<3; j++) + for (int k=0; k<3; k++) + for (int l=0; l<3; l++){ + DdevPhidDgamma(i,j) += Dho2_u_inv(i,j,k,l)*DdevPhidDgamma_RHS(k,l); + DdevPhidGamma(i,j) += Dho2_u_inv(i,j,k,l)*DdevPhidGamma_RHS(k,l); + } + + double Stemp1 = STensorOperation::doubledot(devPhi,DdevPhidDgamma); + double Stemp2 = STensorOperation::doubledot(devPhi,DdevPhidGamma); + double He = 1.5*Stemp1/PhiEq; + double dPhiEdGamma = 1.5*Stemp2/PhiEq; + + + // dAdGamma and dDgammaDGamma + dAdDgamma = (12.*PhiEq*He + 8.*_b*_b*ptilde*Hp/3.)/(2.*A); + dAdGamma = (12.*PhiEq*dPhiEdGamma + 8.*_b*_b*ptilde*dPhiPdGamma/3.)/(2.*A); + + dDgammaDGamma = pow(kk,1)*(A+Gamma*dAdGamma); // mistake in the paper (VD 2016) // pow(kk,2) DEBUG + + this->getYieldCoefficientDerivatives(q1,q1->_nup,Da); + + dfdDgamma = Da(2)*pow(PhiEq,_n) - Da(1)*ptilde -Da(0); + dfdDgamma += a(2)*_n*pow(PhiEq,(_n-1.))*He - a(1)*Hp; + + if (Gamma>0 and etaOverDt>0) + dfdDgamma -= _p*pow(etaOverDt,_p-1.)*Deta/this->getTimeStep()*pow(Gamma,_p); // THIS term is absent in the paper!! + + dfdGamma = _n*a(2)*pow(PhiEq,(_n-1.))*dPhiEdGamma - a(1)*dPhiPdGamma; + if (Gamma>0 and etaOverDt>0) + dfdGamma -= pow(etaOverDt,_p)*_p*pow(Gamma,(_p-1.)); + + DfDGamma = dfdDgamma*dDgammaDGamma + dfdGamma; // unused + + dgdDgamma = 1. - kk*Gamma*dAdDgamma; + dgdGamma = - dDgammaDGamma; + + double dGamma = (-f + dfdDgamma*g/dgdDgamma)/(-dfdDgamma*dgdGamma/dgdDgamma + dfdGamma); // NR + double dDgamma = -(g+dgdGamma*dGamma)/dgdDgamma; // NR + + if (Gamma + dGamma <=0.){ + Gamma /= 2.; // NR + } + else + Gamma += dGamma; + + // Dgammma_test += dDgamma; + if (Dgamma + dDgamma <=0.){ + Dgamma /= 2.; + } + else + Dgamma += dDgamma; + + //Msg::Error("Gamma = %e",Gamma); + //Msg::Error("Dgamma = %e",Dgamma); + + + // UPDATE FOR NEXT ITERATION + + // Update gamma and all Hardening moduli + mlawNonLinearTVP::updateEqPlasticDeformation(q1,q0,q1->_nup,Dgamma); + mlawNonLinearTVP::hardening(q0,q1,T); + mlawNonLinearTVP::getYieldCoefficients(q1,a); + if (q1->_ipKinematic != NULL){ + Hb = q1->_ipKinematic->getR(); // kinematic hardening parameter + dHb = q1->_ipKinematic->getDR(); // kinematic hardening parameter derivative (dHb/dgamma ??) + dHbdT = q1->_ipKinematic->getDRDT(); // make sure to normalise DRDT while defining in python file //NEW + ddHbddT = q1->_ipKinematic->getDDRDTT(); + ddHbdgammadT = q1->_ipKinematic->getDDRDT(); + } + //a.print("a update"); + + // Update Viscosity -> NEW 23rd May,2024 + if (_viscosity != NULL) + _viscosity->get(q1->_epspbarre,T,eta,Deta,DetaDT); + + // Update Cx + Cxdev = 1. + 3.*m(1)*pow(kk,1)*Hb; // pow(kk,2) DEBUG + Cxtr = 1. + 2.*_b/3. *m(1)*pow(kk,1)*Hb; // pow(kk,2) DEBUG + if (Hb>0.){ + Cxdev -= m(0)*dHb*Dgamma/Hb - 1./Hb * dHbdT * (T-T0); + Cxtr -= m(0)*dHb*Dgamma/Hb - 1./Hb * dHbdT * (T-T0); + } + + // Update Phi + if (_extraBranchNLType == TensionCompressionRegularisedType || _extraBranchNLType == hyper_exp_TCasymm_Type || _ExtraBranch_TVE_option == 3 || _ExtraBranch_TVE_option == 4 || _ExtraBranch_TVE_option == 5){ + // TC asymmetry -> for either case of TensionCompressionRegularisedType and _ExtraBranch_TVE_option == 3 + getIterated_DPhi(F,T0,T,q0,q1,Gamma,Cxtr,Cxdev,Cepr,Eepr,trXn,devXn,Ke,Ge,Ge_Tensor,ptilde,devPhi,Phi,N,expGN,dexpAdA, + Dho,Dho2inv,Dho2_u_inv,Dho2_v_inv,Fp1,alignedIndex,&Ge_TrEeTensor,&rotationStiffness); + } + else{ + getIterated_DPhi(F,T0,T,q0,q1,Gamma,Cxtr,Cxdev,Cepr,Eepr,trXn,devXn,Ke,Ge,Ge_Tensor,ptilde,devPhi,Phi,N,expGN,dexpAdA, + Dho,Dho2inv,Dho2_u_inv,Dho2_v_inv,Fp1,alignedIndex,NULL,&rotationStiffness); + } + + PhiEq = sqrt(1.5*devPhi.dotprod()); + + // Update A + A = sqrt(6.*PhiEq*PhiEq+4.*_b*_b/3.*ptilde*ptilde); + + /* + Dgamma = pow(kk,1)*Gamma*A; // pow(kk,2) DEBUG + updateEqPlasticDeformation(q1,q0,q1->_nup,Dgamma); + hardening(q0,q1,T); + getYieldCoefficients(q1,a);*/ + + // Update f, g + f = a(2)*pow(PhiEq,_n) - (a(1)*ptilde+a(0)); + double viscoTerm = etaOverDt*Gamma; + if (Gamma>0. and etaOverDt>0.) f-= pow(viscoTerm,_p); + + g = Dgamma - kk*Gamma*A; + + ite++; + // if (ite> maxite-5) + // Msg::Error("it = %d, DfDGamma = %e error = %e dGamma = %e, Gamma = %e",ite,DfDGamma,f,dGamma,Gamma); + + if (fabs(f) <_tol) break; + + if(ite > maxite){ + Msg::Error("No convergence for plastic correction in mlawNonLinearTVENonLinearTVP2 nonAssociatedFlow iter = %d, f = %e!!",ite,f); + P(0,0) = P(1,1) = P(2,2) = sqrt(-1.); + return; + } + + } // while + + q1->_DgammaDt = Dgamma/this->getTimeStep(); + + // Correct Cx + Cxdev = 1. + 3.*m(1)*pow(kk,1)*Hb; // pow(kk,2) DEBUG + Cxtr = 1. + 2.*_b/3. *m(1)*pow(kk,1)*Hb; // pow(kk,2) DEBUG + if (Hb>0.){ + Cxdev -= m(0)*dHb*Dgamma/Hb - 1./Hb * dHbdT * (T-T0); + Cxtr -= m(0)*dHb*Dgamma/Hb - 1./Hb * dHbdT * (T-T0); + } + + // Correct Phi + if (_extraBranchNLType == TensionCompressionRegularisedType || _extraBranchNLType == hyper_exp_TCasymm_Type || _ExtraBranch_TVE_option == 3 || _ExtraBranch_TVE_option == 4 || _ExtraBranch_TVE_option == 5){ + // TC asymmetry -> for either case of TensionCompressionRegularisedType and _ExtraBranch_TVE_option == 3 + getIterated_DPhi(F,T0,T,q0,q1,Gamma,Cxtr,Cxdev,Cepr,Eepr,trXn,devXn,Ke,Ge,Ge_Tensor,ptilde,devPhi,Phi,N,expGN,dexpAdA, + Dho,Dho2inv,Dho2_u_inv,Dho2_v_inv,Fp1,alignedIndex,&Ge_TrEeTensor,&rotationStiffness); + } + else{ + getIterated_DPhi(F,T0,T,q0,q1,Gamma,Cxtr,Cxdev,Cepr,Eepr,trXn,devXn,Ke,Ge,Ge_Tensor,ptilde,devPhi,Phi,N,expGN,dexpAdA, + Dho,Dho2inv,Dho2_u_inv,Dho2_v_inv,Fp1,alignedIndex,NULL,&rotationStiffness); + } + PhiEq = sqrt(1.5*devPhi.dotprod()); + + // Correct Normal, H = expGN + STensorOperation::decomposeDevTr(N,devN,trN); + + // Get GammaN for mechSrcTVP -> done within the loop already + /* + STensorOperation::zero(GammaN); + GammaN = N; + GammaN *= Gamma; + q1->_GammaN = GammaN;*/ + + // Correct plastic deformation tensor + STensorOperation::multSTensor3(expGN,Fp0,Fp1); + + // Correct IP gamma + updateEqPlasticDeformation(q1,q0,q1->_nup,Dgamma); + // Msg::Info("setting: gamma=%e ",q1->_epspbarre); + + // Correct elastic deformation tensor, corotational stress + STensorOperation::inverseSTensor3(Fp1,Fpinv); + STensorOperation::multSTensor3(F,Fpinv,Fe); + STensorOperation::multSTensor3FirstTranspose(Fe,Fe,Ce); + + bool ok=STensorOperation::logSTensor3(Ce,_order,Ee,&DlnDCe,&DDlnDDCe); + if(!ok) + { + P(0,0) = P(1,1) = P(2,2) = sqrt(-1.); + return; + } + Ee *= 0.5; + + // Corrected corKir, mandel, backStress are already in the IP due to getIterated_DPhi + /* + // Correct A, B + mlawNonLinearTVM::ThermoViscoElasticPredictor_forTVP(Ce,Ee,q0->_Ee,q0,q1,Ke,Ge,T0,T,stiff,Bd_stiffnessTerm); + Ge_Tensor = _I4; + Ge_Tensor *= Ge*2; // *2 because the function doesnt do it + Ge_Tensor += Bd_stiffnessTerm; + + // Correct backstress; + devX = (pow(kk,1)*Hb*Gamma*devN + devXn); // pow(kk,2) DEBUG + devX *= 1./Cxdev; + trX = (pow(kk,1)*Hb*Gamma*trN + trXn)*1./Cxtr; // pow(kk,2) DEBUG + q1->_backsig = devX; + q1->_backsig(0,0) += trX/3.; + q1->_backsig(1,1) += trX/3.; + q1->_backsig(2,2) += trX/3.; + + // Correct Mandel + q1->_ModMandel = devPhi; + q1->_ModMandel += q1->_backsig; + q1->_ModMandel(0,0) += (ptilde); + q1->_ModMandel(1,1) += (ptilde); + q1->_ModMandel(2,2) += (ptilde); */ + + } // 2nd if + else{ + q1->getRefToDissipationActive() = false; + // Msg::Error("Elasticity"); + } + } // 1st if + + // corKir + const STensor3& KS = q1->_kirchhoff; + + // second Piola Kirchhoff stress + static STensor3 S, Ceinv; + STensorOperation::inverseSTensor3(Ce,Ceinv); + STensorOperation::multSTensor3STensor43(KS,DlnDCe,S); + + // mandel_e + static STensor3 MS; + for(int i=0; i<3; i++) + for(int j=0; j<3; j++){ + MS(i,j) = 0.; + for(int k=0; k<3; k++) + MS(i,j) += Ce(i,k)*S(k,j); + } + q1->_ModMandel = MS; + + // commuteChecker -> for commuting tensors Ce and Se, Me has to be symmetric -> + // For two cases, both in the case of viscoplasticity if Een and Ee dont share eigenvectors: 1. Due to plasticity (Rp) 2. Due to non-proportional loading + static STensor3 commuteChecker, MST; + STensorOperation::transposeSTensor3(MS,MST); + commuteChecker = MS; + commuteChecker -= MST; + q1->_mandelCommuteChecker = commuteChecker.norm0(); + if(q1->_mandelCommuteChecker > 1.e-6){ + // Msg::Error("Mandel does not commute in mlawNonLinearTVENonLinearTVP2, norm = %e, tol = %e !!",q1->_mandelCommuteChecker,1.e-6); + } + + // first PK + for(int i=0; i<3; i++) + for(int j=0; j<3; j++){ + P(i,j) = 0.; + for(int k=0; k<3; k++) + for(int l=0; l<3; l++) + P(i,j) += Fe(i,k)*S(k,l)*Fpinv(j,l); + } + + // Msg::Error(" Inside TVP, after correction, after updating q1->_elasticEnergy = %e, eta = %e !!",q1->_elasticEnergy, eta_mullins); + + // q1->getRefToElasticEnergy()=deformationEnergy(*q1); + q1->getRefToViscousEnergyPart()=viscousEnergy(*q0,*q1)+q0->getConstRefToViscousEnergyPart(); + q1->getRefToPlasticEnergy() = q0->plasticEnergy(); + if (Gamma > 0.){ + double dotKSN = dot(KS,N); + q1->getRefToPlasticEnergy() += Gamma*dotKSN; // = Dp:Ke + } + + // fluxT + double KThConT, DKThConDT; + mlawNonLinearTVM::getKTHCon(KThConT,T,&DKThConDT); + double J = 1.; + STensor3 Finv(0.); + if (_thermalEstimationPreviousConfig){ // ADD _thermalEstimationPreviousConfig + STensorOperation::inverseSTensor3(F0,Finv); + J = STensorOperation::determinantSTensor3(F0); + } + else{ + STensorOperation::inverseSTensor3(F,Finv); + J = STensorOperation::determinantSTensor3(F); + } + + static STensor3 Cinv; + STensorOperation::multSTensor3SecondTranspose(Finv,Finv,Cinv); + STensorOperation::multSTensor3SVector3(Cinv,gradT,fluxT); + fluxT *= (-KThConT*J); + + // ThermSrc and MechSrc after dPdF and dPdT - But need the following tensors for the mechSrcTVP function call + static STensor3 DphiPDF; + STensorOperation::zero(DphiPDF); + STensorOperation::zero(dFpdF); //dFpdT + static STensor43 CeprToF, DEeDCepr, DEeDF, dGammaNdCepr; // conversion tensors + STensorOperation::zero(CeprToF); + STensorOperation::zero(DEeDCepr); + STensorOperation::zero(DEeDF); + STensorOperation::zero(dGammaNdCepr); + + // I didnt make this + if (this->getMacroSolver()->getPathFollowingLocalIncrementType() == pathFollowingManager::DEFO_ENERGY){ + q1->getRefToIrreversibleEnergy() = q1->defoEnergy(); + } + else if ((this->getMacroSolver()->getPathFollowingLocalIncrementType() == pathFollowingManager::PLASTIC_ENERGY) or + (this->getMacroSolver()->getPathFollowingLocalIncrementType() == pathFollowingManager::DISSIPATION_ENERGY)){ + q1->getRefToIrreversibleEnergy() = q1->plasticEnergy(); + } + else{ + q1->getRefToIrreversibleEnergy() = 0.; + } + + + if (stiff){ + + // dPdF + + // 1. get Dp_pr_DCepr, DpDCepr + static STensor3 Dp_pr_DCepr, DpDCepr; + STensorOperation::multSTensor3STensor43(_I,DlnDCepr,Dp_pr_DCepr); + STensorOperation::multSTensor3STensor43(_I,DlnDCepr,DpDCepr); + Dp_pr_DCepr*= (0.5*Ke_pr); + DpDCepr*= (0.5*Ke); + + // Ke and Ge_Tensor are already corrected if Gamma>0. because of the NR loop on Phi - Reuse DcorKirDEe later + static STensor43 DcorKirDEe_pr, DcorKirDEe; + STensorOperation::zero(DcorKirDEe_pr); + STensorOperation::zero(DcorKirDEe); + for (int i=0; i<3; i++) + for (int j=0; j<3; j++) + for (int k=0; k<3; k++) + for (int l=0; l<3; l++){ + DcorKirDEe(i,j,k,l) += Ke*_I(i,j)*_I(k,l); + DcorKirDEe_pr(i,j,k,l) += Ke_pr*_I(i,j)*_I(k,l); + for (int p=0; p<3; p++) + for (int q=0; q<3; q++){ + DcorKirDEe_pr(i,j,k,l) += Ge_Tensor_pr(i,j,p,q)*_Idev(p,q,k,l); + DcorKirDEe(i,j,k,l) += Ge_Tensor(i,j,p,q)*_Idev(p,q,k,l); + } + } + DcorKirDEe_pr += Ge_TrEeTensor_pr; // TC Assymmetry + DcorKirDEe += Ge_TrEeTensor; // TC Assymmetry + + // NEW EIGEN + DcorKirDEe_pr += rotationStiffness_pr; + DcorKirDEe += rotationStiffness; + // NEW EIGEN + + static STensor43 DcorKir_pr_DCepr, DcorKirDCepr; + STensorOperation::multSTensor43(DcorKirDEe_pr,DlnDCepr,DcorKir_pr_DCepr); + STensorOperation::multSTensor43(DcorKirDEe,DlnDCepr,DcorKirDCepr); + DcorKir_pr_DCepr *= 0.5; // use for DMeprDCepr + DcorKirDCepr *= 0.5; // correct this one later + + // 2. get DCeprDCepr = _I4 and DCeinvprDCepr + static STensor43 DCeinvprDCepr; + + for (int i=0; i<3; i++) + for (int s=0; s<3; s++) + for (int k=0; k<3; k++) + for (int l=0; l<3; l++){ + DCeinvprDCepr(i,s,k,l) = 0.; + for (int m=0; m<3; m++) + for (int j=0; j<3; j++) + DCeinvprDCepr(i,s,k,l) -= Ceinvpr(i,m)*_I4(m,j,k,l)*Ceinvpr(j,s); + } + + // + static STensor43 DdevCorKir_pr_DCepr; + STensorOperation::zero(DdevCorKir_pr_DCepr); + for (int i=0; i<3; i++) + for (int s=0; s<3; s++) + for (int k=0; k<3; k++) + for (int l=0; l<3; l++) + DdevCorKir_pr_DCepr(i,s,k,l) += DcorKir_pr_DCepr(i,s,k,l) - _I(i,s)*Dp_pr_DCepr(k,l); + + //4. get DdevphiDCepr and DphiPprDCepr; and DphiEprDCepr + static STensor3 DphiPDCepr, DphiEDCepr, DphiEDdevPhi; + static STensor43 DdevphiDCepr, DphiDCepr; + + DphiPDCepr = Dp_pr_DCepr; + DdevphiDCepr = DdevCorKir_pr_DCepr; + + if (PhiEq >0.){ + DphiEDdevPhi = devPhi; + DphiEDdevPhi *= 1.5/(PhiEq); + } + + STensorOperation::multSTensor3STensor43(DphiEDdevPhi,DdevphiDCepr,DphiEDCepr); + + DphiDCepr = DdevphiDCepr; + for (int i=0; i<3; i++) + for (int s=0; s<3; s++) + for (int k=0; k<3; k++) + for (int l=0; l<3; l++) + DphiDCepr(i,s,k,l) += _I(i,s)*DphiPDCepr(k,l); + + // 6. to 11. (inside if loop-> Gamma > 0.) + static STensor3 dAdCepr, dfDCepr, dgDCepr, DGDCepr, DgammaDCepr, DtrNDCepr, dTrXdCepr; + static STensor43 DdevNDCepr, dFpDCepr, dDevXdCepr, dXdCepr; + + if (Gamma >0.){ + + //5.1 update DphiPDCepr to include the Gamma term + STensorOperation::zero(DphiPDCepr); + STensorOperation::multSTensor3STensor43(_I,DlnDCepr,DphiPDCepr); + DphiPDCepr*= (0.5*Ke); + DphiPDCepr *= Dho2_v_inv; + + // update DpDCepr (needed for DdevphiDCepr) + for (int i=0; i<3; i++) + for (int j=0; j<3; j++) + DpDCepr(i,j) -= Ke*2*_b*(Gamma*DphiPDCepr(i,j)); + + //5.2 update DdevphiDCepr to include the Gamma term + STensorOperation::zero(DdevphiDCepr); + + // get G1 tensor + // static STensor43 G1; + // mlawNonLinearTVENonLinearTVP2::get_G1_Tensor(Cepr,expGN,DCeinvprDCepr,KS,G1); + + // get RHS + static STensor43 DdevphiDCepr_RHS; + STensorOperation::zero(DdevphiDCepr_RHS); + for (int i=0; i<3; i++) + for (int j=0; j<3; j++) + for (int k=0; k<3; k++) + for (int l=0; l<3; l++){ + + for (int p=0; p<3; p++) + for (int q=0; q<3; q++){ + + DdevphiDCepr_RHS(i,j,k,l) += ( (Ge_TrEeTensor(i,j,p,q) + rotationStiffness(i,j,p,q) )*0.5*DlnDCepr(p,q,k,l) + + (-Ge_TrEeTensor(i,j,p,q) - rotationStiffness(i,j,p,q))* ( 2.*_b*Gamma/3.*_I(p,q)*DphiPDCepr(k,l) ) ); // EIGEN + + for (int r=0; r<3; r++) + for (int s=0; s<3; s++){ + + DdevphiDCepr_RHS(i,j,k,l) += ( Ge_Tensor(i,j,p,q)*_Idev(p,q,r,s)*0.5*DlnDCepr(r,s,k,l)); + } + + } + } // DEBUG + // DdevphiDCepr = DdevMeprDCepr; // DEBUG + // STensorOperation::multSTensor43(Dho2_u_inv,DdevMeprDCepr,DdevphiDCepr); // DEBUG + STensorOperation::multSTensor43(Dho2_u_inv,DdevphiDCepr_RHS,DdevphiDCepr); // DEBUG + STensorOperation::multSTensor3STensor43(DphiEDdevPhi,DdevphiDCepr,DphiEDCepr); + + //6. get dAdCepr, dfDCepr + double fact = a(2)*_n*pow(PhiEq,_n-1.); + for (int i=0; i<3; i++) + for (int j=0; j<3; j++){ + dAdCepr(i,j) = ( 4./3.*_b*_b*ptilde*DphiPDCepr(i,j) + 6.*PhiEq*DphiEDCepr(i,j) )/A; + dfDCepr(i,j) = fact*DphiEDCepr(i,j)-a(1)*DphiPDCepr(i,j); + // dgDCepr(i,j) = -kk*Gamma*dAdCepr(i,j); + } + dgDCepr = dAdCepr; + dgDCepr *= (-kk*Gamma); + + //7. get DGDCepr, DgammaDCepr + for (int i=0; i<3; i++) + for (int j=0; j<3; j++){ + DGDCepr(i,j) = (-dfDCepr(i,j) + dfdDgamma*dgDCepr(i,j)/dgdDgamma)/(dfdGamma - dfdDgamma*dgdGamma/dgdDgamma); + DgammaDCepr(i,j) = (-dgdGamma*DGDCepr(i,j) - dgDCepr(i,j))/dgdDgamma; + } + + //8.1 update DphiPDCepr + STensorOperation::zero(DphiPDCepr); + STensorOperation::multSTensor3STensor43(_I,DlnDCepr,DphiPDCepr); + DphiPDCepr*= (0.5*Ke); + for (int i=0; i<3; i++) + for (int j=0; j<3; j++){ + DphiPDCepr(i,j) += ( - Ke* 2.*_b*ptilde*DGDCepr(i,j) + - 2.*_b*pow(kk,1)/3. * ( (dHb/Cxtr - Hb/pow(Cxtr,2)*dCxtrdDgamma)*DgammaDCepr(i,j)*Gamma*ptilde + Hb/Cxtr*DGDCepr(i,j)*ptilde ) + + 1./3.*trXn/pow(Cxtr,2)*dCxtrdDgamma*DgammaDCepr(i,j)); + // DEBUG pow(kk,2) + } + DphiPDCepr *= Dho2_v_inv; + + // update DpDCepr (needed for DdevphiDCepr) + STensorOperation::zero(DpDCepr); + STensorOperation::multSTensor3STensor43(_I,DlnDCepr,DpDCepr); + DpDCepr*= (0.5*Ke); + for (int i=0; i<3; i++) + for (int j=0; j<3; j++) + DpDCepr(i,j) -= Ke*2*_b*( DGDCepr(i,j)*ptilde + Gamma*DphiPDCepr(i,j)); + + //8.2 update DdevphiDCepr and DphiEDCepr + STensorOperation::zero(DdevphiDCepr); + + // get G1 tensor + // mlawNonLinearTVENonLinearTVP2::get_G1_Tensor(Cepr,expGN,DCeinvprDCepr,KS,G1); + + // get RHS + // static STensor43 DdevphiDCepr_RHS; + STensorOperation::zero(DdevphiDCepr_RHS); + for (int i=0; i<3; i++) + for (int j=0; j<3; j++) + for (int k=0; k<3; k++) + for (int l=0; l<3; l++){ + + DdevphiDCepr_RHS(i,j,k,l) += ( - 3.*pow(kk,1)*( ( dHb/Cxdev - Hb/pow(Cxdev,2)*dCxdevdDgamma )*Gamma*devPhi(i,j)*DgammaDCepr(k,l) + Hb/Cxdev*devPhi(i,j)*DGDCepr(k,l) ) + + 1./pow(Cxdev,2)*dCxdevdDgamma*devXn(i,j)*DgammaDCepr(k,l)); // DEBUG pow(kk,2) + + for (int p=0; p<3; p++) + for (int q=0; q<3; q++){ + + DdevphiDCepr_RHS(i,j,k,l) += ( - 3.*Ge_Tensor(i,j,p,q)*devPhi(p,q)*DGDCepr(k,l) + + (-Ge_TrEeTensor(i,j,p,q) -rotationStiffness(i,j,p,q)) * ( N(p,q)*DGDCepr(k,l) + 2.*_b*Gamma/3.*_I(p,q)*DphiPDCepr(k,l) ) + + (Ge_TrEeTensor(i,j,p,q) + rotationStiffness(i,j,p,q)) *0.5*DlnDCepr(p,q,k,l) ) ; // EIGEN + for (int r=0; r<3; r++) + for (int s=0; s<3; s++){ + + DdevphiDCepr_RHS(i,j,k,l) += ( Ge_Tensor(i,j,p,q)*_Idev(p,q,r,s)*0.5*DlnDCepr(r,s,k,l) ); + } + + } + } + + STensorOperation::multSTensor43(Dho2_u_inv,DdevphiDCepr_RHS,DdevphiDCepr); + STensorOperation::multSTensor3STensor43(DphiEDdevPhi,DdevphiDCepr,DphiEDCepr); + + DphiDCepr = DdevphiDCepr; + for (int i=0; i<3; i++) + for (int s=0; s<3; s++) + for (int k=0; k<3; k++) + for (int l=0; l<3; l++) + DphiDCepr(i,s,k,l) += _I(i,s)*DphiPDCepr(k,l); + + //9. get DtrNDCepr DdevNdCepr + DtrNDCepr = DphiPDCepr; + DtrNDCepr *= (2.*_b); + + DdevNDCepr = DdevphiDCepr; + DdevNDCepr *= 3.; + + /* + //0.0 Numerical Derivatives wrt Cepr + double ptilde_plus, Gamma_plus, Dgamma_plus, A_plus, f_plus; + static STensor3 devPhi_plus, Me_plus, P_plus; + static IPNonLinearTVP qPlus(*q0); + + static STensor3 Cepr_plus, Fepr_plus, DphiPDCepr_plus, DGDCepr_plus, DgammaDCepr_plus, dAdCepr_plus, dfDCepr_plus; + static STensor43 DdevphiDCepr_plus; + Fepr_plus = Fepr; + for (int i=0; i<3; i++){ + for (int j=0; j<3; j++){ + Cepr_plus = Cepr; + Cepr_plus(i,j) += 0.5*_perturbationfactor; + Cepr_plus(j,i) += 0.5*_perturbationfactor; + + + TEST_predictorCorrector_TVP_nonAssociatedFlow_nonLinearTVE(F0,F,q0,&qPlus,T0,T, + Fepr_plus,Cepr_plus,ptilde_plus,devPhi_plus,Gamma_plus,Dgamma_plus,A_plus,f_plus,Me_plus,P_plus); + + + DGDCepr_plus(i,j) = (Gamma_plus-Gamma)/_perturbationfactor; + DgammaDCepr_plus(i,j) = (Dgamma_plus-Dgamma)/_perturbationfactor; + dAdCepr_plus(i,j) = (A_plus-A)/_perturbationfactor; + dfDCepr_plus(i,j) = (f_plus-f)/_perturbationfactor; + DphiPDCepr_plus(i,j) = (ptilde_plus-ptilde)/_perturbationfactor; + + for (int k=0; k<3; k++){ + for (int l=0; l<3; l++){ + DdevphiDCepr_plus(k,l,i,j) = (devPhi_plus(k,l)-devPhi(k,l))/_perturbationfactor; + } + } + } + }*/ + + // 10. get dFpDCepr + STensorOperation::zero(dGammaNdCepr); + for (int i=0; i<3; i++) + for (int j=0; j<3; j++) + for (int k=0; k<3; k++) + for (int l=0; l<3; l++) + dGammaNdCepr(i,j,k,l) = N(i,j)*DGDCepr(k,l) + Gamma*DdevNDCepr(i,j,k,l) + Gamma/3.*_I(i,j)*DtrNDCepr(k,l); + + static STensor43 CeprFp0; + for (int i=0; i<3; i++) + for (int j=0; j<3; j++) + for (int k=0; k<3; k++) + for (int l=0; l<3; l++){ + CeprFp0(i,j,k,l) = 0.; + for (int s=0; s<3; s++){ + CeprFp0(i,j,k,l) += dexpAdA(i,s,k,l)*Fp0(s,j); + } + } + + STensorOperation::multSTensor43(CeprFp0,dGammaNdCepr,dFpDCepr); + + // 10.1 get dXDCepr + for (int i=0; i<3; i++) + for (int j=0; j<3; j++){ + dTrXdCepr(i,j) = pow(kk,1.)*( (dHb/Cxtr - Hb/pow(Cxtr,2)*dCxtrdDgamma)*Gamma*trN*DgammaDCepr(i,j) + + Hb/Cxtr*( trN*DGDCepr(i,j) + Gamma*DtrNDCepr(i,j) ) ) + - trXn/pow(Cxtr,2)*dCxtrdDgamma*DgammaDCepr(i,j); // pow(kk,2.) DEBUG + for (int k=0; k<3; k++) + for (int l=0; l<3; l++){ + dDevXdCepr(i,j,k,l) = pow(kk,1.)*( (dHb/Cxdev - Hb/pow(Cxdev,2)*dCxdevdDgamma)*Gamma*devN(i,j)*DgammaDCepr(k,l) + + Hb/Cxdev*( devN(i,j)*DGDCepr(k,l) + Gamma*DdevNDCepr(i,j,k,l) ) ) + - 1./pow(Cxdev,2)*dCxdevdDgamma*devXn(i,j)*DgammaDCepr(k,l); // pow(kk,2.) DEBUG + } + } + + STensorOperation::zero(dXdCepr); + dXdCepr = dDevXdCepr; + for (int i=0; i<3; i++) + for (int j=0; j<3; j++) + for (int k=0; k<3; k++) + for (int l=0; l<3; l++) + dXdCepr(i,j,k,l) += 1./3. * _I(i,j)*dTrXdCepr(k,l); + + // 11. update DcorKirDCepr + for (int i=0; i<3; i++) + for (int j=0; j<3; j++) + for (int k=0; k<3; k++) + for (int l=0; l<3; l++) + for (int p=0; p<3; p++) + for (int q=0; q<3; q++) + DcorKirDCepr(i,j,k,l) -= DcorKirDEe(i,j,p,q)*dGammaNdCepr(p,q,k,l); + } // if Gamma + else{ + // elastic + STensorOperation::zero(DgammaDCepr); STensorOperation::zero(DGDCepr); STensorOperation::zero(DtrNDCepr); + STensorOperation::zero(dFpDCepr); STensorOperation::zero(dTrXdCepr); STensorOperation::zero(DdevNDCepr); + STensorOperation::zero(dDevXdCepr); STensorOperation::zero(dXdCepr); STensorOperation::zero(dGammaNdCepr); + } + + // 12. get CeprToF conversion tensor + for (int i=0; i<3; i++) + for (int j=0; j<3; j++) + for (int k=0; k<3; k++) + for (int l=0; l<3; l++) + CeprToF(i,j,k,l) = 2.*Fepr(k,i)*invFp0(j,l); + + // 13. get DcorKirDF + static STensor43 DKcorDF; + STensorOperation::multSTensor43(DcorKirDCepr,CeprToF,DKcorDF); + + // 14. dXdF, dGammaNdF, DphiPDF for mechSrc + STensor43& dXdF = q1->getRefToDbackStressdF(); + STensorOperation::zero(dXdF); + STensorOperation::multSTensor43(dXdCepr,CeprToF,dXdF); + + STensor43& dGammaNdF = q1->_dGammaNdF; + STensorOperation::zero(dGammaNdF); + STensorOperation::multSTensor43(dGammaNdCepr,CeprToF,dGammaNdF); + + // DphiPDCepr - use this for the pressure term in R + STensorOperation::zero(DphiPDF); + for (int i=0; i<3; i++) + for (int j=0; j<3; j++) + for (int k=0; k<3; k++) + for (int l=0; l<3; l++) + DphiPDF(i,j) = DphiPDCepr(k,l)*CeprToF(k,l,i,j); + + // 15. get DgammaDF + STensor3& DgammaDF = q1->_DgammaDF; + STensor3& DGammaDF = q1->_DGammaDF; + STensor43& DphiDF = q1->_DphiDF; + STensorOperation::zero(DgammaDF); + STensorOperation::zero(DGammaDF); + STensorOperation::zero(DphiDF); + if (Gamma > 0){ + STensorOperation::multSTensor3STensor43(DgammaDCepr,CeprToF,DgammaDF); + STensorOperation::multSTensor3STensor43(DGDCepr,CeprToF,DGammaDF); + STensorOperation::multSTensor43(dFpDCepr,CeprToF,dFpdF); + } + STensorOperation::multSTensor43(DphiDCepr,CeprToF,DphiDF); + + // 16. Everything else - Conversion Tensors + static STensor43 DinvFpDF, dCedF, dCeinvDF; + for (int i=0; i<3; i++) + for (int s=0; s<3; s++) + for (int k=0; k<3; k++) + for (int l=0; l<3; l++){ + DinvFpDF(i,s,k,l) = 0.; + for (int m=0; m<3; m++) + for (int j=0; j<3; j++) + DinvFpDF(i,s,k,l) -= Fpinv(i,m)*dFpdF(m,j,k,l)*Fpinv(j,s); + } + + for (int m=0; m<3; m++) + for (int j=0; j<3; j++) + for (int k=0; k<3; k++) + for (int l=0; l<3; l++){ + dFedF(m,j,k,l) = _I(m,k)*Fpinv(l,j); + for (int s=0; s<3; s++) + dFedF(m,j,k,l) += F(m,s)*DinvFpDF(s,j,k,l); + } + + for (int i=0; i<3; i++) + for (int j=0; j<3; j++) + for (int k=0; k<3; k++) + for (int l=0; l<3; l++){ + dCedF(i,j,k,l) = 0.; + for (int p=0; p<3; p++){ + dCedF(i,j,k,l) += Fe(p,i)*dFedF(p,j,k,l) + dFedF(p,i,k,l)*Fe(p,j); // This Works! + } + } + + for (int i=0; i<3; i++) + for (int s=0; s<3; s++) + for (int k=0; k<3; k++) + for (int l=0; l<3; l++){ + dCeinvDF(i,s,k,l) = 0.; + for (int m=0; m<3; m++) + for (int j=0; j<3; j++) + dCeinvDF(i,s,k,l) -= Ceinv(i,m)*dCedF(m,j,k,l)*Ceinv(j,s); + } + + // 17. Tangent - dPdF + static STensor43 dSdCepr, dSdF, dMedCepr; + STensor43& dMedF = q1->getRefToDModMandelDF(); + STensorOperation::zero(dMedF); + + for (int i=0; i<3; i++) + for (int j=0; j<3; j++) + for (int k=0; k<3; k++) + for (int l=0; l<3; l++) + dMedF(i,j,k,l) = DKcorDF(i,j,k,l); // KS is corKir + + + static STensor63 DlnDF; + if (_order != 1){ + for (int i=0; i<3; i++){ + for (int j=0; j<3; j++){ + for (int k=0; k<3; k++){ + for (int l=0; l<3; l++){ + for (int p=0; p<3; p++){ + for (int q=0; q<3; q++){ + DlnDF(i,j,k,l,p,q) = 0.; + for (int r=0; r<3; r++){ + for (int s=0; s<3; s++){ + for (int a=0; a<3; a++){ + DlnDF(i,j,k,l,p,q) += DDlnDDCe(i,j,k,l,r,s)*2.*Fe(a,r)*dFedF(a,s,p,q); + } + } + } + } + } + } + } + } + } + + } + else{ + STensorOperation::zero(DlnDF); + } + + STensorOperation::zero(dSdF); + for (int i=0; i<3; i++) + for (int j=0; j<3; j++) + for (int k=0; k<3; k++) + for (int l=0; l<3; l++) + for (int m=0; m<3; m++) + for (int n=0; n<3; n++){ + dSdF(i,j,k,l) += DKcorDF(m,n,k,l)*DlnDCe(m,n,i,j); + dSdF(i,j,k,l) += KS(m,n)*DlnDF(m,n,i,j,k,l); + } + + for (int i=0; i<3; i++) + for (int j=0; j<3; j++) + for (int k=0; k<3; k++) + for (int l=0; l<3; l++){ + Tangent(i,j,k,l) = 0.; + for (int m=0; m<3; m++){ + for (int n=0; n<3; n++){ + Tangent(i,j,k,l) += dFedF(i,m,k,l)*S(m,n)*Fpinv(j,n); + Tangent(i,j,k,l) += Fe(i,m)*dSdF(m,n,k,l)*Fpinv(j,n); + Tangent(i,j,k,l) += Fe(i,m)*S(m,n)*DinvFpDF(j,n,k,l); + } + } + } + + + // dP/dT + + // 1. get dMeprDT from dKeprDT -> DcorKirprDT from TVE + static STensor3 dDevKeprDT, dDevCorKirDT, DcorKirDT; + double DpDT(0.), dpKeprDT(0.); + + STensorOperation::decomposeDevTr(dKeprDT,dDevKeprDT,dpKeprDT); + dpKeprDT = dKeprDT.trace()/3.; + + DcorKirDT = dKeprDT; // update later + + // 2. initialise dXdT - > need this for DmechsourceDT -> initialise here (X is backStress) + STensor3& dXdT = q1->getRefToDbackStressdT(); + STensorOperation::zero(dXdT); + STensor3& dGammaNdT = q1->_dGammaNdT; + STensorOperation::zero(dGammaNdT); + + // 3. get dPhipprDT and dDevPhiprDT + double dPhiPdT(0.); + static STensor3 dDevPhiDT; + STensor3& DphiDT = q1->_DphiDT; + + dPhiPdT = dpKeprDT; + dDevPhiDT = dDevKeprDT; + + DphiDT = dDevPhiDT; + for (int i=0; i<3; i++) + for (int j=0; j<3; j++) + DphiDT(i,j) += dPhiPdT*_I(i,j); + + // 4. get dPhiEdT + double dPhiEdT(0.); + STensorOperation::doubleContractionSTensor3(DphiEDdevPhi,dDevPhiDT,dPhiEdT); + + // 5. to 11. (inside if loop-> Gamma > 0.) + double& dGammaDT = q1->_DGammaDT; + double& DgammaDT = q1->_DgammaDT; + dGammaDT = 0.; DgammaDT =0.; + + double dAdT(0.), dfdT(0.), dgdT(0.), DtrNdT(0.), DtrXdT(0.); + static STensor3 DdevNdT, dFpDT, DdevXdT; + + // eta(0.), Deta(0.), DetaDT(0.); + if (_viscosity != NULL) + _viscosity->get(q1->_epspbarre,T,eta,Deta,DetaDT); + double etaOverDt = eta/this->getTimeStep(); + + if (Gamma >0){ + // plastic + + // =============================== ROUND 1 - Updates for dAdT, dfdT, dgdT ================================================== // + + // 5.1 update dCxdT + double dCxdevdT(0.), dCxtrdT(0.); + // dHbdT+dHb*DgammaDT + if (Hb>0.){ + dCxdevdT = -m(0)*( -1./pow(Hb,2.)*dHb*Dgamma*(dHbdT) + 1./Hb*(ddHbdgammadT*Dgamma + dHb*DgammaDT)) + + (1./pow(Hb,2.)*(dHbdT)*(dHbdT) - 1./Hb*ddHbddT)*(T-T0) -1./Hb*dHbdT; + } + dCxtrdT = dCxdevdT; + dCxdevdT += 3.*m(1)*pow(kk,1.)*(dHbdT); // pow(kk,2.) DEBUG + dCxtrdT += 2.*_b/3.*m(1)*pow(kk,1.)*(dHbdT); // pow(kk,2.) DEBUG + + // 5.2 update DcorKirDT for shift factor derivatives - // dAdT and dBdT for maxwell elements are updated inside the loop for Phi + mlawNonLinearTVM::getTVEdCorKirDT(q0,q1,T0,T); + DcorKirDT = q1->_DcorKirDT; + STensorOperation::decomposeDevTr(DcorKirDT,dDevCorKirDT,DpDT); + DpDT = DcorKirDT.trace()/3.; + + // 5.2 update dPhiPdT, dDevPhiDT to get dAdT, dfdT, dgdT + dPhiPdT = DpDT + Ke*(-2*_b*ptilde*dGammaDT) + - 2.*_b*pow(kk,1)/3.*( (dHbdT/Cxtr - Hb/pow(Cxtr,2)*dCxtrdT ) *Gamma*ptilde + Hb/Cxtr*dGammaDT*ptilde ) + + 1./3.*trXn/pow(Cxtr,2)*dCxtrdT ; // pow(kk,2.) DEBUG + dPhiPdT *= Dho2_v_inv; + + // 5.3 update DpDT + DpDT += 2*_b*Ke*(-dGammaDT*ptilde - Gamma*dPhiPdT); + + // 5.4 update DdevphiDT + static STensor3 DdevphiDT_RHS; + for (int i=0; i<3; i++) + for (int j=0; j<3; j++){ + DdevphiDT_RHS(i,j) = ( dDevCorKirDT(i,j) ) + - 3*pow(kk,1)*( (dHbdT/Cxdev - Hb/pow(Cxdev,2)*dCxdevdT)*Gamma*devPhi(i,j) + Hb/Cxdev*dGammaDT*devPhi(i,j) ) + + 1./pow(Cxdev,2)*dCxdevdT*devXn(i,j); // pow(kk,2.) DEBUG + for (int k=0; k<3; k++) + for (int l=0; l<3; l++){ + DdevphiDT_RHS(i,j) += ( -3*dGammaDT*Ge_Tensor(i,j,k,l)*devPhi(k,l) + + (-Ge_TrEeTensor(i,j,k,l) -rotationStiffness(i,j,k,l))*( dGammaDT*N(k,l) + 2.*_b/3.*dPhiPdT*_I(k,l) ) ); // EIGEN + } + } + + STensorOperation::multSTensor3STensor43(DdevphiDT_RHS,Dho2_u_inv,dDevPhiDT); + STensorOperation::doubleContractionSTensor3(DphiEDdevPhi,dDevPhiDT,dPhiEdT); + + // =============================== ROUND 1 - END ========================================================================= // + + // 6. get dAdT, dfdT, dgdT + fullVector<double> DaDT(3), DDaDTT(3); + getYieldCoefficientTempDers(q1,T,DaDT,DDaDTT); + + dAdT = (4./3.*_b*_b*ptilde*dPhiPdT + 6.*PhiEq*dPhiEdT)/A; + dfdT = DaDT(2)*pow(PhiEq,_n) + a(2)*_n*pow(PhiEq,_n-1.)*dPhiEdT - DaDT(1)*ptilde - a(1)*dPhiPdT - DaDT(0); + if (this->getTimeStep()>0){ + dfdT -= (DetaDT*Gamma/this->getTimeStep())*_p*pow((eta*Gamma/this->getTimeStep()),(_p-1.)); + } + + dgdT = -kk*Gamma*dAdT; + + // 7. get dGammaDT, DgammaDT + dGammaDT = (-dfdT + dfdDgamma*dgdT/dgdDgamma)/(dfdGamma - dfdDgamma*dgdGamma/dgdDgamma); + DgammaDT = (-dgdGamma*dGammaDT - dgdT)/dgdDgamma; + + // =============================== ROUND 2 - Updates for dPhiPdT, DdevphiDT ================================================== // + // 8. update dCxdT + // dHbdT+dHb*DgammaDT + if (Hb>0.){ + dCxdevdT = -m(0)*( -1./pow(Hb,2.)*dHb*Dgamma*(dHbdT) + 1./Hb*(ddHbdgammadT*Dgamma + dHb*DgammaDT)) + + (1./pow(Hb,2.)*(dHbdT)*(dHbdT) - 1./Hb*ddHbddT)*(T-T0) -1./Hb*dHbdT; + } + dCxtrdT = dCxdevdT; + dCxdevdT += 3.*m(1)*pow(kk,1.)*(dHbdT); // pow(kk,2.) DEBUG + dCxtrdT += 2.*_b/3.*m(1)*pow(kk,1.)*(dHbdT); // pow(kk,2.) DEBUG + + // 9. update DpDT 1 - shift factor derivatives + DpDT = DcorKirDT.trace()/3.; + + // 10. update dPhiPdT + dPhiPdT = DpDT + Ke*(-2*_b*ptilde*dGammaDT) + - 2.*_b*pow(kk,1)/3.*( (dHbdT/Cxtr - Hb/pow(Cxtr,2)*dCxtrdT ) *Gamma*ptilde + Hb/Cxtr*dGammaDT*ptilde ) + + 1./3.*trXn/pow(Cxtr,2)*dCxtrdT ; // pow(kk,2.) DEBUG + dPhiPdT *= Dho2_v_inv; + + // 10.1 update DpDT 2 + DpDT += 2*_b*Ke*(-dGammaDT*ptilde - Gamma*dPhiPdT); + + // 11. update DdevphiDT + STensorOperation::zero(DdevphiDT_RHS); + for (int i=0; i<3; i++) + for (int j=0; j<3; j++){ + DdevphiDT_RHS(i,j) = ( dDevCorKirDT(i,j) ) + - 3*pow(kk,1)*( (dHbdT/Cxdev - Hb/pow(Cxdev,2)*dCxdevdT)*Gamma*devPhi(i,j) + Hb/Cxdev*dGammaDT*devPhi(i,j) ) + + 1./pow(Cxdev,2)*dCxdevdT*devXn(i,j); // pow(kk,2.) DEBUG + for (int k=0; k<3; k++) + for (int l=0; l<3; l++){ + DdevphiDT_RHS(i,j) += ( -3*dGammaDT*Ge_Tensor(i,j,k,l)*devPhi(k,l) + + (-Ge_TrEeTensor(i,j,k,l) - rotationStiffness(i,j,k,l))*( dGammaDT*N(k,l) + 2.*_b/3.*Gamma*dPhiPdT*_I(k,l) ) ); // EIGEN + } + } + + STensorOperation::multSTensor3STensor43(DdevphiDT_RHS,Dho2_u_inv,dDevPhiDT); + + DphiDT = dDevPhiDT; + for (int i=0; i<3; i++) + for (int j=0; j<3; j++) + DphiDT(i,j) += dPhiPdT*_I(i,j); + + // =============================== ROUND 2 - END ========================================================================= // + + // 12. get DtrNdT, DdevNdT + DtrNdT = dPhiPdT; + DtrNdT *= (2.*_b); + + DdevNdT = dDevPhiDT; + DdevNdT *= 3.; + + // 13. get dFpdT + STensorOperation::zero(dGammaNdT); + for (int i=0; i<3; i++) + for (int j=0; j<3; j++) + dGammaNdT(i,j) += N(i,j)*dGammaDT + Gamma*DdevNdT(i,j) + Gamma/3.*_I(i,j)*DtrNdT; + + static STensor43 CeprFp0; + for (int i=0; i<3; i++) + for (int j=0; j<3; j++) + for (int k=0; k<3; k++) + for (int l=0; l<3; l++){ + CeprFp0(i,j,k,l) = 0.; + for (int s=0; s<3; s++) + CeprFp0(i,j,k,l) += dexpAdA(i,s,k,l)*Fp0(s,j); + } + + for (int i=0; i<3; i++) + for (int j=0; j<3; j++){ + dFpdT(i,j) = 0.; + for (int k=0; k<3; k++) + for (int l=0; l<3; l++) + dFpdT(i,j) += CeprFp0(i,j,k,l)*dGammaNdT(k,l); + } + + // 14. dXdT - backstress temperature derivative -> correction - CHECK!!! + DtrXdT = pow(kk,1.)*( (dHbdT/Cxtr - Hb/pow(Cxtr,2)*dCxtrdT ) *Gamma*trN + Hb/Cxtr*(dGammaDT*trN + Gamma*DtrNdT) ) - trXn/pow(Cxtr,2)*dCxtrdT; // pow(kk,2.) DEBUG + for (int i=0; i<3; i++) + for (int j=0; j<3; j++) + DdevXdT(i,j) = pow(kk,1.)*( (dHbdT/Cxdev - Hb/pow(Cxdev,2)*dCxdevdT)*Gamma*devN(i,j) + Hb/Cxdev*( dGammaDT*devN(i,j) + Gamma*DdevNdT(i,j) ) ) + - 1./pow(Cxdev,2)*dCxdevdT * devXn(i,j); // pow(kk,2.) DEBUG + + STensorOperation::zero(dXdT); + dXdT = DdevXdT; + dXdT(0,0) = DtrXdT/3.; + dXdT(1,1) = DtrXdT/3.; + dXdT(2,2) = DtrXdT/3.; + + // 15. update DcorKirDT + for (int i=0; i<3; i++) + for (int j=0; j<3; j++) + for (int k=0; k<3; k++) + for (int l=0; l<3; l++) + DcorKirDT(i,j) -= DcorKirDEe(i,j,k,l)*dGammaNdT(k,l); + + q1->_DcorKirDT = DcorKirDT; // update in IP + + } // if Gamma + else{ + // elastic + STensorOperation::zero(dFpDT); STensorOperation::zero(DdevXdT); STensorOperation::zero(DdevNdT); + } + + // 16. get dKcorDT + // done above + + // 17. get DinvFpdT, dFedT, dCedT, dCeinvDT + static STensor3 DinvFpdT, dFedT, dCedT, dCeinvdT; + STensorOperation::zero(DinvFpdT); + for (int i=0; i<3; i++) + for (int j=0; j<3; j++) + for (int p=0; p<3; p++) + for (int q=0; q<3; q++) + DinvFpdT(i,j) -= Fpinv(i,p)*dFpdT(p,q)*Fpinv(q,j); + + STensorOperation::zero(dFedT); + for (int i=0; i<3; i++) + for (int j=0; j<3; j++) + for (int k=0; k<3; k++) + dFedT(i,j) += F(i,k)*DinvFpdT(k,j); + + STensorOperation::zero(dCedT); + for (int i=0; i<3; i++) + for (int j=0; j<3; j++) + for (int p=0; p<3; p++) + dCedT(i,j) += Fe(p,i)*dFedT(p,j) + dFedT(p,i)*Fe(p,j); // This Works! + + STensorOperation::zero(dCeinvdT); + for (int i=0; i<3; i++) + for (int s=0; s<3; s++) + for (int k=0; k<3; k++) + for (int l=0; l<3; l++) + dCeinvdT(i,s) -= Ceinv(i,k)*dCedT(k,l)*Ceinv(l,s); + + // 18. get dMeDT -> needed for DmechSourceDT + STensor3& dMeDT = q1->getRefToDModMandelDT(); + STensorOperation::zero(dMeDT); + + for (int i=0; i<3; i++) + for (int j=0; j<3; j++) + dMeDT(i,j) = DcorKirDT(i,j); + + // 19. get dSdT + + static STensor43 DLDT; + STensorOperation::zero(DLDT); + for (int i=0; i<3; i++) + for (int j=0; j<3; j++) + for (int k=0; k<3; k++) + for (int l=0; l<3; l++) + for (int r=0; r<3; r++) + for (int s=0; s<3; s++) + for (int a=0; a<3; a++) + DLDT(i,j,k,l) += DDlnDDCe(i,j,k,l,r,s)*2.*Fe(a,r)*dFedT(a,s); + + static STensor3 dSdT; + for (int i=0; i<3; i++) + for (int j=0; j<3; j++){ + dSdT(i,j) = 0.; + for (int r=0; r<3; r++) + for (int s=0; s<3; s++){ + dSdT(i,j) += DcorKirDT(r,s)*DlnDCe(r,s,i,j) + KS(r,s)*DLDT(r,s,i,j); + } + } + + // 20. Finally, get dPdT + for (int i=0; i<3; i++) + for (int j=0; j<3; j++){ + dPdT(i,j) = 0.; + for (int k=0; k<3; k++) + for (int l=0; l<3; l++){ + dPdT(i,j) += (dFedT(i,k)*S(k,l)*Fpinv(j,l) + Fe(i,k)*dSdT(k,l)*Fpinv(j,l) + Fe(i,k)*S(k,l)*DinvFpdT(j,l)); + } + } + + // TVP - flux derivatives + // fluxT + dfluxTdT = fluxT; + dfluxTdT *= (DKThConDT/KThConT); + dfluxTdgradT = Cinv; + dfluxTdgradT *= (-KThConT*J); + STensorOperation::zero(dfluxTdF); + + if (!_thermalEstimationPreviousConfig){ + + static STensor3 DJDF; + static STensor43 DCinvDF; + for (int i=0; i<3; i++){ + for (int j=0; j<3; j++){ + DJDF(i,j) = J*Finv(j,i); + for (int k=0; k<3; k++){ + for (int l=0; l<3; l++){ + DCinvDF(i,j,k,l) = 0.; + for (int p=0; p<3; p++){ + for (int a=0; a<3; a++){ + for (int b=0; b<3; b++){ + DCinvDF(i,j,k,l) -= 2.*F(k,p)*Cinv(i,a)*Cinv(j,b)*_I4(a,b,p,l); + } + } + } + } + } + } + } + + for (int i=0; i<3; i++){ + for (int j=0; j<3; j++){ + for (int k=0; k<3; k++){ + dfluxTdF(i,j,k) += (DJDF(j,k)*fluxT(i)/J); + for (int l=0; l<3; l++){ + dfluxTdF(i,j,k) -= (J*DCinvDF(i,l,j,k)*gradT(l)*KThConT); + } + } + } + } + } + + } // if stiff + + + // thermalEnergy + if (stiff){ + double& DDpsiTVMdTT = q1->getRefToDDFreeEnergyTVMdTT(); + // getFreeEnergyTVM(q0,q1,T0,T,NULL,NULL,&DDpsiTVMdTT); + // CpT = -T*DDpsiTVMdTT; + getCp(CpT,T); + } + else{ + getCp(CpT,T); + } + + q1->_thermalEnergy = CpT*T; + + // thermalSource + if (this->getTimeStep() > 0.){ + thermalSource = -CpT*(T-T0)/this->getTimeStep(); + } + else + thermalSource = 0.; + + // mechanical Source + double& Wm_TVP = q1->getRefToMechSrcTVP(); // TVP + double& Wm_TVE = q1->getRefToMechSrcTVE(); // TVE + + mechanicalSource = 0.; + double mechanicalSource_cap = 0.; // in case of mullins, undamaged mechanicalSource + + // 1) ThermoElastic Heat -> _DcorKirDT needs to corrected for plasticity ( DcorKirDT = dcorKir_dT + dCorKirDEe * dEeDT ) + static STensor3 DEe; + DEe = q1->_Ee; + DEe -= q0->_Ee; + if (this->getTimeStep() > 0){ + // mechanicalSource += (STensorOperation::doubledot(q1->_DcorKirDT,DEe)*T/this->getTimeStep()); + } + + // 2) Viscoelastic Contribution to mechSrc + double& dWmdT_TVE = q1->getRefTodMechSrcTVEdT(); + STensor3& dWmdF_TVE = q1->getRefTodMechSrcTVEdF(); + static STensor3 dWmdE_TVE; + mlawNonLinearTVM::getMechSource_nonLinearTVE_term(q0,q1,T0,T,Wm_TVE,stiff,dWmdE_TVE,dWmdT_TVE); + // mechanicalSource += Wm_TVE; + + // 3) Viscoplastic Contribution to mechSrc + double& dWmdT_TVP = q1->getRefTodMechSrcTVPdT(); + STensor3& dWmdF_TVP = q1->getRefTodMechSrcTVPdF(); + mlawNonLinearTVP::getMechSourceTVP(F0,F,q0,q1,T0,T,Fepr,Cepr,DphiPDF,Wm_TVP,dWmdF_TVP,dWmdT_TVP); + mechanicalSource += Wm_TVP; + + // -------------------------------------------------------------------------------------------- + // TVE energy and derivatives + double& Dpsi_DT = q1->getRefTo_Dpsi_DT(); + STensor3& Dpsi_TVEdE = q1->getRefTo_Dpsi_DE(); + q1->_elasticEnergy = mlawNonLinearTVM::freeEnergyMechanical(*q0,*q1,T0,T,&Dpsi_DT,&Dpsi_TVEdE); + + // TVP energy and derivatives + double psi_TVP = freeEnergyPlasticity(q0,q1,T0,T); + double Dpsi_TVPdT(0.); + static STensor3 Dpsi_TVPdF; + freeEnergyPlasticityDerivatives(q0,q1,T0,T,Dpsi_TVPdF,Dpsi_TVPdT); + // q1->_elasticEnergy += psi_TVP; // Mullins TVP + // Dpsi_DT += Dpsi_TVPdT; // add plastic part // Mullins TVP + Dpsi_DT -= dot(Dpsi_TVEdE,q1->_dGammaNdT); // add plastic dependency of elastic strain // Mullins TVP + + // Mullins Effect + if (_mullinsEffect != NULL && q1->_ipMullinsEffect != NULL){ + mlawNonLinearTVM::calculateMullinsEffectScaler(q0, q1, T, &Dpsi_DT); + } + double eta_mullins = 1.; + + if (q1->_ipMullinsEffect != NULL){ + + // Put Stress in IP + q1->_P_cap = P; + + // Modify Stress for mullins + eta_mullins = q1->_ipMullinsEffect->getEta(); + P *= eta_mullins; + // q1->_elasticEnergy *= eta_mullins; + + mechanicalSource_cap = mechanicalSource; + mechanicalSource *= q1->_ipMullinsEffect->getEta(); + if (this->getTimeStep() > 0){ + mechanicalSource -= q1->_ipMullinsEffect->getDpsiNew_DpsiMax()*(q1->_ipMullinsEffect->getpsiMax() - q0->_ipMullinsEffect->getpsiMax())/this->getTimeStep(); + } + } + + + if(stiff){ + + // -------------------------------------------------------------------------------------------- + // Important conversion tensors + STensorOperation::zero(DEeDCepr); + STensorOperation::zero(DEeDF); + + // DEeDCepr to DEeDF + // STensorOperation::multSTensor43(_I4, DlnDCepr, DEeDCepr); + DEeDCepr = DlnDCepr; + DEeDCepr *= 0.5; + DEeDCepr -= dGammaNdCepr; + STensorOperation::multSTensor43(DEeDCepr, CeprToF, DEeDF); + + // Note: DEeDT = - dGammaNdT + // -------------------------------------------------------------------------------------------- + + // thermSrc and MechSrc Derivatives + + // thermal source derivatives + double DCpDT(0.); + mlawNonLinearTVM::getCp(CpT,T,&DCpDT); + static STensor3 DCpDF; + STensorOperation::zero(DCpDF); // CHANGE for DCpDF + + if (this->getTimeStep() > 0){ + dthermalSourcedT = -DCpDT*(T-T0)/this->getTimeStep() - CpT/this->getTimeStep(); + // dthermalSourcedT = -CpT/this->getTimeStep() - (CpT-CpT_0)/this->getTimeStep(); + for(int i = 0; i< 3; i++){ + for(int j = 0; j< 3; j++){ + dthermalSourcedF(i,j) = -DCpDF(i,j)*(T-T0)/this->getTimeStep(); + } + } + } + else{ + dthermalSourcedT = 0.; + STensorOperation::zero(dthermalSourcedF); + } + + // mechSourceTVP derivatives + dmechanicalSourcedT = 0.; + STensorOperation::zero(dmechanicalSourceF); + static STensor3 dmechanicalSourceE; + STensorOperation::zero(dmechanicalSourceE); + + // DcorKirDT Term + STensor3& DDcorKirDTT = q1->getRefToDDcorKirDTT(); + STensor43& DDcorKirDTDEe = q1->getRefToDDcorKirDTDE(); + + static STensor3 DcorKirDT_I; + STensorOperation::multSTensor3STensor43(q1->_DcorKirDT,_I4,DcorKirDT_I); + if (this->getTimeStep() > 0){ + for (int i=0; i<3; i++){ + for (int j=0; j<3; j++){ + dmechanicalSourceE(i,j) += T*DcorKirDT_I(i,j)/this->getTimeStep(); + for (int k=0; k<3; k++) + for (int l=0; l<3; l++){ + dmechanicalSourceE(i,j) += T*DDcorKirDTDEe(k,l,i,j)*DEe(k,l)/this->getTimeStep(); + DDcorKirDTT(i,j) += - DDcorKirDTDEe(i,j,k,l)*q1->_dGammaNdT(k,l); // additional term due to TVP + } + } + } + // STensorOperation::multSTensor3STensor43(dmechanicalSourceE,DEeDF,dmechanicalSourceF); + + // dmechanicalSourcedT += (STensorOperation::doubledot(q1->_DcorKirDT,DEe)/this->getTimeStep()); + // dmechanicalSourcedT += T*(STensorOperation::doubledot(DDcorKirDTT,DEe)/this->getTimeStep()); + // dmechanicalSourcedT -= T*(STensorOperation::doubledot(q1->_DcorKirDT,q1->_dGammaNdT)/this->getTimeStep()); + } + + // TVE Term + STensorOperation::multSTensor3STensor43(dWmdE_TVE, DEeDF, dWmdF_TVE); + for (int i=0; i<3; i++) + for (int j=0; j<3; j++) + dWmdT_TVE += - dWmdE_TVE(i,j) * q1->_dGammaNdT(i,j); // the second term in dWmdT_TVE from dependency of Ee on plasticity + + // dmechanicalSourceF += dWmdF_TVE; + // dmechanicalSourcedT += dWmdT_TVE; + + + // TVP Term + dmechanicalSourceF += dWmdF_TVP; + dmechanicalSourcedT += dWmdT_TVP; + + // Mullins Effect Derivatives + + // Compute Tangents for Mullin's Effect + if (_mullinsEffect != NULL && q1->_ipMullinsEffect != NULL){ + + // 1st Term + Tangent *= q1->_ipMullinsEffect->getEta(); + dPdT *= q1->_ipMullinsEffect->getEta(); + dmechanicalSourceF *= q1->_ipMullinsEffect->getEta(); + dmechanicalSourcedT *= q1->_ipMullinsEffect->getEta(); + + + // 2nd Term + double Deta_mullins_DT(0.); + static STensor3 Deta_mullins_DF, Deta_mullins_DEe; + + // Deta_mullins_DF + STensorOperation::multSTensor3STensor43(q1->_DpsiDE,DEeDF,Deta_mullins_DF); + Deta_mullins_DF *= q1->_DmullinsDamage_Dpsi_cap; // elastic part + // Deta_mullins_DF += Dpsi_TVPdF*q1->_DmullinsDamage_Dpsi_cap; // plastic part // Mullins TVP + + // Deta_mullins_DT + // STensorOperation::doubleContractionSTensor3(q1->_DpsiDE,q1->_dGammaNdT,Deta_mullins_DT); // Remove - Mullins TVP + // Deta_mullins_DT *= -q1->_DmullinsDamage_Dpsi_cap; // Remove - Mullins TVP + // Deta_mullins_DT += q1->_DmullinsDamage_DT; // Remove - Mullins TVP + Deta_mullins_DT = q1->_DmullinsDamage_DT; // + q1->_DmullinsDamage_Dpsi_cap*q1->_DpsiDT; // Mullins TVP + + // 2nd Term - 1st PK + for (int i=0; i<3; i++) + for (int j=0; j<3; j++){ + dPdT(i,j) += q1->_P_cap(i,j) * Deta_mullins_DT; + for (int k=0; k<3; k++) + for (int l=0; l<3; l++) + Tangent(i,j,k,l) += q1->_P_cap(i,j) * Deta_mullins_DF(k,l); + } + + + // 2nd Term - MechSrc + dmechanicalSourcedT += mechanicalSource_cap*Deta_mullins_DT; + for (int i=0; i<3; i++) + for (int j=0; j<3; j++){ + dmechanicalSourceF(i,j) += mechanicalSource_cap*Deta_mullins_DF(i,j); + } + + static STensor3 DDpsiNew_DpsiMaxDF, DpsiMax_DF; + STensorOperation::multSTensor3STensor43(q1->_DpsiDE,DEeDF,DDpsiNew_DpsiMaxDF); + STensorOperation::multSTensor3STensor43(q1->_DpsiDE,DEeDF,DpsiMax_DF); + DDpsiNew_DpsiMaxDF *= q1->_ipMullinsEffect->getDDpsiNew_DpsiMaxDpsi(); + DpsiMax_DF *= q1->_ipMullinsEffect->getDpsiMax_Dpsi(); + + if (this->getTimeStep() > 0){ + dmechanicalSourcedT -= (q1->_ipMullinsEffect->getDDpsiNew_DpsiMaxDT()*(q1->_ipMullinsEffect->getpsiMax() - q0->_ipMullinsEffect->getpsiMax())/this->getTimeStep() + + q1->_ipMullinsEffect->getDpsiNew_DpsiMax()*q1->_ipMullinsEffect->getDpsiMax_Dpsi()*q1->_DpsiDT/this->getTimeStep()); + for (int i=0; i<3; i++) + for (int j=0; j<3; j++){ + dmechanicalSourceF(i,j) -= DDpsiNew_DpsiMaxDF(i,j)*(q1->_ipMullinsEffect->getpsiMax() - q0->_ipMullinsEffect->getpsiMax())/this->getTimeStep(); + dmechanicalSourceF(i,j) -= q1->_ipMullinsEffect->getDpsiNew_DpsiMax()*DpsiMax_DF(i,j)/this->getTimeStep(); + } + } + + } // mullin's + } + +} + +void mlawNonLinearTVENonLinearTVP2::get_G1_Tensor(const STensor3& Cepr, const STensor3& expGN, + const STensor43& DCeinvprDCepr, const STensor3& KS, STensor43& G1) const{ + + static STensor3 Hinv; + STensorOperation::inverseSTensor3(expGN,Hinv); + + static STensor3 Ceinvpr; + STensorOperation::inverseSTensor3(Cepr,Ceinvpr); + + static STensor43 term1, term2; + + for (int i=0; i<3; i++) + for (int j=0; j<3; j++) + for (int k=0; k<3; k++) + for (int l=0; l<3; l++){ + term1(i,j,k,l) = 0.; + term2(i,j,k,l) = 0.; + for (int p=0; p<3; p++) + for (int q=0; q<3; q++) + for (int r=0; r<3; r++) + for (int s=0; s<3; s++) + for (int m=0; m<3; m++) + for (int o=0; o<3; o++){ + term1(i,j,k,l) += Hinv(i,p)*Hinv(p,q)*_I4(q,r,k,l)*KS(r,s)*Ceinvpr(s,m)*expGN(m,o)*expGN(o,j); + term2(i,j,k,l) += Hinv(i,p)*Hinv(p,q)*Cepr(q,r)*KS(r,s)*DCeinvprDCepr(s,m,k,l)*expGN(m,o)*expGN(o,j); + } + } + STensorOperation::zero(G1); + G1 = term1+term2; +} + +void mlawNonLinearTVENonLinearTVP2::getDho(const double& Gamma, const STensor3& Cepr, const STensor3& Ceinvpr, const STensor3& KS, + const double& Ke, const STensor43& Ge_Tensor, + const double& kk, const double& Hb, const double& Cxtr, const double& Cxdev, + const STensor3& expGN, const STensor43& dexpAdA, + STensor43& Dho, STensor43& Dho2inv, STensor43& Dho2_u_inv, double& Dho2_v_inv, STensor43* Ge_TrEeTensor, STensor43* rotationStiffness) const{ + + // Ge_TrEeTensor -> Dependence of devCorKir on TrEe. DO NOT CHANGE ITS VALUE! + + // Get DcorKirDEe for Dho 2nd term + static STensor43 DcorKirDEe; + STensorOperation::zero(DcorKirDEe); + for (int i=0; i<3; i++) + for (int j=0; j<3; j++) + for (int k=0; k<3; k++) + for (int l=0; l<3; l++){ + DcorKirDEe(i,j,k,l) += Ke*_I(i,j)*_I(k,l); + for (int p=0; p<3; p++) + for (int q=0; q<3; q++) + DcorKirDEe(i,j,k,l) += Ge_Tensor(i,j,p,q)*_Idev(p,q,k,l); + } + if (Ge_TrEeTensor!= NULL){ + DcorKirDEe += (*Ge_TrEeTensor); + } + + if (rotationStiffness!= NULL){ + DcorKirDEe += (*rotationStiffness); + } + + // + // Get Dho2 -> dJdPhi, Dho2_u -> LHS of dDevPhidDgamma, dDevPhidGamma, Dho2_v -> LHS + // + + // Get dMeDphi + static STensor43 dMedGN, dMeDphi; + STensorOperation::zero(dMedGN); + STensorOperation::zero(dMeDphi); + + for (int i=0; i<3; i++) + for (int j=0; j<3; j++) + for (int k=0; k<3; k++) + for (int l=0; l<3; l++) + for (int p=0; p<3; p++) + for (int q=0; q<3; q++) + dMedGN(i,j,k,l) += DcorKirDEe(i,j,p,q)*(-_I4(p,q,k,l)); + + for (int i=0; i<3; i++) + for (int j=0; j<3; j++) + for (int k=0; k<3; k++) + for (int l=0; l<3; l++) + for (int p=0; p<3; p++) + for (int q=0; q<3; q++) + dMeDphi(i,j,k,l) += dMedGN(i,j,p,q)*Gamma*(3.*_Idev(p,q,k,l) + 2.*_b/3 * 1./3 * _I(p,q)*_I(k,l)); + + // Get dXdPhi + static STensor43 dXdPhi; + STensorOperation::zero(dXdPhi); + for (int i=0; i<3; i++) + for (int j=0; j<3; j++) + for (int k=0; k<3; k++) + for (int l=0; l<3; l++) + dXdPhi(i,j,k,l) = pow(kk,1)*Hb*Gamma*(3./Cxdev*_Idev(i,j,k,l) + 2.*_b/(3.*Cxtr) * 1./3 * _I(i,j)*_I(k,l)); // DEBUG pow(kk,2) + + // Get Dho2, Dho2inv + static STensor43 Dho2; + Dho2 = _I4; + Dho2 -= dMeDphi; + Dho2 += dXdPhi; + STensorOperation::inverseSTensor43(Dho2,Dho2inv); + + // Get Dho2_u, Dho2_u_inv + static STensor43 Dho2_u; + + Dho2_u = _I4; + for (int i=0; i<3; i++) + for (int j=0; j<3; j++) + for (int k=0; k<3; k++) + for (int l=0; l<3; l++){ + Dho2_u(i,j,k,l) += 3*Gamma*pow(kk,1)*Hb/Cxdev * _I4(i,j,k,l); // DEBUG pow(kk,2) + for (int p=0; p<3; p++) + for (int q=0; q<3; q++){ + Dho2_u(i,j,k,l) += 3.*Gamma*(Ge_Tensor(i,j,p,q)*_Idev(p,q,k,l)); // Ge_Tensor(i,j,p,q)*_I4(p,q,k,l) - CHECKERS + } + } + if (Ge_TrEeTensor!= NULL){ + static STensor43 Ge_TrEeTensor_temp; + STensorOperation::zero(Ge_TrEeTensor_temp); + Ge_TrEeTensor_temp = (*Ge_TrEeTensor); + Ge_TrEeTensor_temp *= (3*Gamma); + Dho2_u += Ge_TrEeTensor_temp; + } + if (rotationStiffness!= NULL){ + static STensor43 rotationStiffness_Temp; + STensorOperation::zero(rotationStiffness_Temp); + rotationStiffness_Temp = (*rotationStiffness); + rotationStiffness_Temp *= (3*Gamma); + Dho2_u += rotationStiffness_Temp; + } + STensorOperation::inverseSTensor43(Dho2_u,Dho2_u_inv); + + // Get Dho2_v, Dho2_v_inv + double Dho2_v = 1. + 2.*_b*Gamma*(Ke + pow(kk,1)*Hb/(3.*Cxtr)); // pow(kk,2) DEBUG + Dho2_v_inv = 1./Dho2_v; +} + +void mlawNonLinearTVENonLinearTVP2::getIterated_DPhi(const STensor3& F, const double& T0, const double& T, const IPNonLinearTVP *q0, IPNonLinearTVP *q1, + double& Gamma, const double& Cxtr, const double& Cxdev, + const STensor3& Cepr, const STensor3& Eepr, + const double& trXn, const STensor3& devXn, + double& Ke, double& Ge, STensor43& Ge_Tensor, + double& ptilde, STensor3& devPhi, + STensor3& Phi, STensor3& N, STensor3& expGN, STensor43& dexpAdA, + STensor43& Dho, STensor43& Dho2inv, STensor43& Dho2_u_inv , double& Dho2_v_inv, STensor3& Fp1, const fullVector<int>& alignedIndex, + STensor43* Ge_TrEeTensor, STensor43* rotationStiffness) const{ + + // This function calculates Phi iteratively. + // At every iteration it will calculate Ee, corKir and N + + // EIGEN NEW - Initialise Fe + static STensor3 Fpinv; + STensor3& Fe = q1->_Fe; + STensorOperation::multSTensor3(expGN,q0->_Fp,Fp1); + STensorOperation::inverseSTensor3(Fp1,Fpinv); + STensorOperation::multSTensor3(F,Fpinv,Fe); + // EIGEN NEW - Initialise Fe + + // Initialise GammaN in IP -> for mechSrc later + STensor3& GammaN = q1->getRefToGammaN(); + + // Initialise Hinv + static STensor3 Hinv, Ceinvpr; + STensorOperation::inverseSTensor3(expGN,Hinv); + STensorOperation::inverseSTensor3(Cepr,Ceinvpr); + + // Initialise Ce, Ceinv + static STensor3 Ce, Ceinv; // Temporary Local Variable + for (int i=0; i<3; i++) + for (int j=0; j<3; j++){ + Ce(i,j) = 0.; + Ceinv(i,j) = 0.; + for (int k=0; k<3; k++) + for (int l=0; l<3; l++){ + Ce(i,j) += Hinv(i,k)*Hinv(k,l)*Cepr(l,j); + Ceinv(i,j) += Ceinvpr(i,k)*expGN(k,l)*expGN(l,j); + } + } + + // Initialise Ee + static STensor3 Ee; + for (int i=0; i<3; i++) + for (int j=0; j<3; j++) + Ee(i,j) = Eepr(i,j) - Gamma*N(i,j); + + // Initialise corKir + static STensor3 KS; + static STensor43 Bd_stiffnessTerm; + + // NEW EIGEN + // double e1, e2, e3; static STensor3 E1, E2, E3; STensorOperation::getEigenDecomposition(Ee,e1,e2,e3,E1,E2,E3); + static STensor3 Ee0_rot; + if (_rotationCorrectionScheme == 0 && _rotationCorrectionScheme == 1){ + for(int i=0; i<3; i++) + for(int j=0; j<3; j++){ + Ee0_rot(i,j) = 0.; + for(int k=0; k<3; k++) + for(int l=0; l<3; l++) + Ee0_rot(i,j) += q1->_R(i,k)*q0->_Ee(k,l)*q1->_R(j,l); + } + } + else if(_rotationCorrectionScheme == 2){ + Ee0_rot = q0->_Ee; + // mlawNonLinearTVM::getEe0s2(Ce,Ee,q0->_Ee,Ee0_rot,dEe0sdEe); // Dont do it here + } + // NEW EIGEN + + if (Ge_TrEeTensor == NULL){ + if (!_useRotationCorrection){ + mlawNonLinearTVM::ThermoViscoElasticPredictor(Ee,q0->_Ee,q0,q1,Ke,Ge,T0,T,true,Bd_stiffnessTerm); + } + else{ + mlawNonLinearTVM::ThermoViscoElasticPredictor_forTVP(Ce,Ee,Ee0_rot,q0,q1,Ke,Ge,T0,T,true,alignedIndex,Bd_stiffnessTerm,NULL,rotationStiffness); // NEW EIGEN + } + } + else{ // TC asymmetry + if (!_useRotationCorrection){ + mlawNonLinearTVM::ThermoViscoElasticPredictor(Ee,q0->_Ee,q0,q1,Ke,Ge,T0,T,true,Bd_stiffnessTerm,Ge_TrEeTensor); + } + else{ + mlawNonLinearTVM::ThermoViscoElasticPredictor_forTVP(Ce,Ee,Ee0_rot,q0,q1,Ke,Ge,T0,T,true,alignedIndex,Bd_stiffnessTerm,Ge_TrEeTensor,rotationStiffness); // NEW EIGEN + } + } + + Ge_Tensor = _I4; + Ge_Tensor *= Ge*2; // *2 because the function doesnt do it + Ge_Tensor += Bd_stiffnessTerm; + KS = q1->_kirchhoff; + + // Get Hb + double Hb(0.); + if (q1->_ipKinematic != NULL) + Hb = q1->_ipKinematic->getR(); // kinematic hardening parameter + double kk = (1./sqrt(1.+2.*q1->_nup*q1->_nup)); + + // Initialise backStress + static STensor3 devX, devN; + double trX, trN; + STensorOperation::decomposeDevTr(N,devN,trN); + devX = pow(kk,1)*Hb*Gamma*devN + devXn; // pow(kk,2) DEBUG + devX *= 1./Cxdev; + trX = (pow(kk,1)*Hb*Gamma*trN + trXn)*1./Cxtr; // pow(kk,2) DEBUG + q1->_backsig = devX; + q1->_backsig(0,0) += trX/3.; + q1->_backsig(1,1) += trX/3.; + q1->_backsig(2,2) += trX/3.; + + // Initialise J + static STensor3 J; + STensorOperation::zero(J); + for (int i=0; i<3; i++) + for (int j=0; j<3; j++) + J(i,j) += Phi(i,j) - KS(i,j) + q1->_backsig(i,j); + + // static STensor3 J0; //debug + // J0 = J; //debug + + // Initialise J_tol + double J_tol = 0.; + J_tol = J.norm0(); + J_tol/=(_K+_G); + // for (int i=0; i<3; i++) + // for (int j=0; j<3; j++) + // J_tol += abs(J(i,j)) ; + + // Initialise Dho, Dho2, Dho2inv + if (Ge_TrEeTensor == NULL){ + getDho(Gamma,Cepr,Ceinvpr,KS,Ke,Ge_Tensor,kk,Hb,Cxtr,Cxdev,expGN,dexpAdA,Dho,Dho2inv,Dho2_u_inv,Dho2_v_inv,NULL,rotationStiffness); + } + else{ // TC asymmetry + getDho(Gamma,Cepr,Ceinvpr,KS,Ke,Ge_Tensor,kk,Hb,Cxtr,Cxdev,expGN,dexpAdA,Dho,Dho2inv,Dho2_u_inv,Dho2_v_inv,Ge_TrEeTensor,rotationStiffness); + } + + // Initialise DPhi + static STensor3 DPhi; + + // Initialise numerical quantities + /* + static STensor3 Phi_plus, J_plus, devPhi_plus, N_plus, GammaN_plus, Ee_plus, Ce_plus, KS_plus, MS_plus, expGN_plus, Hinv_plus, devN_plus, devX_plus, Ee0_rot_plus; + double pPhi_plus,Ke_plus,Ge_plus, trN_plus, trX_plus; + static STensor43 dJdPhi_plus, dJdPhi_plus_inv, dexpAdA_plus, Bd_stiffnessTerm_plus,Ge_Tensor_plus, dJdPhi_plus2, dJdPhi_plus2_inv; + static STensor43 Ge_TrEeTensor_plus, rotationStiffness_plus; + static IPNonLinearTVP q1_plus(*q0); + STensor3& R_plus = q1_plus._R; + STensor43& dRdEe_plus = q1_plus._dRdEe; + STensor43& dRtdEe_plus = q1_plus._dRtdEe; + fullVector<int> alignedIndex_plus(3); alignedIndex_plus(0) = 0; alignedIndex_plus(1) = 1; alignedIndex_plus(2) = 2;*/ + + int ite = 0; + int maxite = 100; + + double tol = _stressIteratorTol; // 1e-6; + + while (fabs(J_tol) > tol or ite <1){ + + /* + // ################################################################## + // numerical Dho4inv (Jacobian dJ/dPhi) + // _perturbationfactor = DPhi_numerical + + + for (int i=0; i<3; i++){ + for (int j=0; j<3; j++){ + Phi_plus = Phi; + Phi_plus(i,j) += 0.5*_perturbationfactor; + Phi_plus(j,i) += 0.5*_perturbationfactor; + STensorOperation::decomposeDevTr(Phi_plus,devPhi_plus,pPhi_plus); + pPhi_plus = Phi_plus.trace()/3; + N_plus = _I; + N_plus *= 2.*_b/3*pPhi_plus; + N_plus += 3*devPhi_plus; + GammaN_plus = N_plus; + GammaN_plus *= Gamma; + STensorOperation::expSTensor3(GammaN_plus,_order,expGN_plus,&dexpAdA_plus); + STensorOperation::inverseSTensor3(expGN_plus,Hinv_plus); + + // update Ce, Ceinv + for (int ii=0; ii<3; ii++) + for (int jj=0; jj<3; jj++){ + Ce_plus(ii,jj) = 0.; + for (int kk=0; kk<3; kk++) + for (int ll=0; ll<3; ll++) + Ce_plus(ii,jj) += Hinv_plus(ii,kk)*Hinv_plus(kk,ll)*Cepr(ll,jj); + } + + Ee_plus = - Gamma*N_plus; + Ee_plus += Eepr; + // bool ok=STensorOperation::logSTensor3(Ce_plus,_order,Ee_plus); + + + q1_plus._Ee0 = q0->_Ee; + mlawNonLinearTVM::rotationTensor_N_to_Nplus1(q0->_Ee0,q0->_Fp,Fp1,Ce_plus,Ee_plus,q0->_Ee,q1_plus._R,q1_plus._dRdEe,q1_plus._dRtdEe); + for(int p=0; p<3; p++) + for(int q=0; q<3; q++){ + Ee0_rot_plus(p,q) = 0.; + for(int r=0; r<3; r++) + for(int m=0; m<3; m++) + Ee0_rot_plus(p,q) += q1_plus._R(p,r)*q0->_Ee(r,m)*q1_plus._R(q,m); + } + + // update corKir + if (Ge_TrEeTensor == NULL){ + if (!_useRotationCorrection){ + mlawNonLinearTVM::ThermoViscoElasticPredictor(Ee_plus,q0->_Ee,q0,&q1_plus,Ke_plus,Ge_plus,T0,T,true,Bd_stiffnessTerm_plus); + } + else{ + mlawNonLinearTVM::ThermoViscoElasticPredictor_forTVP(Ce_plus,Ee_plus,Ee0_rot_plus,q0,&q1_plus,Ke_plus,Ge_plus,T0,T,true,alignedIndex_plus,Bd_stiffnessTerm_plus,NULL,\ + &rotationStiffness_plus); // NEW EIGEN + } + } + else{ // TC asymmetry + if (!_useRotationCorrection){ + mlawNonLinearTVM::ThermoViscoElasticPredictor(Ee_plus,q0->_Ee,q0,&q1_plus,Ke_plus,Ge_plus,T0,T,true,Bd_stiffnessTerm_plus,&Ge_TrEeTensor_plus); + } + else{ + mlawNonLinearTVM::ThermoViscoElasticPredictor_forTVP(Ce_plus,Ee_plus,Ee0_rot_plus,q0,&q1_plus,Ke_plus,Ge_plus,T0,T,true,alignedIndex_plus,Bd_stiffnessTerm_plus,&Ge_TrEeTensor_plus,\ + &rotationStiffness_plus); // NEW EIGEN + } + } + + Ge_Tensor_plus = _I4; + Ge_Tensor_plus *= Ge_plus*2; // *2 because the function doesnt do it + Ge_Tensor_plus += Bd_stiffnessTerm_plus; + KS_plus = q1_plus._kirchhoff; + + // update mandel + // mlawNonLinearTVP::getModifiedMandel(Ce_plus, q0, &q1_plus); + // MS_plus = q1_plus._ModMandel; + + STensorOperation::decomposeDevTr(N_plus,devN_plus,trN_plus); + devX_plus = pow(kk,1)*Hb*Gamma*devN_plus + devXn; // pow(kk,2) DEBUG + devX_plus *= 1./Cxdev; + trX_plus = (pow(kk,1)*Hb*Gamma*trN_plus + trXn)*1./Cxtr; // pow(kk,2) DEBUG + q1_plus._backsig = devX_plus; + q1_plus._backsig(0,0) += trX_plus/3.; + q1_plus._backsig(1,1) += trX_plus/3.; + q1_plus._backsig(2,2) += trX_plus/3.; + + for (int k=0; k<3; k++){ + for (int l=0; l<3; l++){ + J_plus(k,l) = Phi_plus(k,l) - KS_plus(k,l) + q1_plus._backsig(k,l); + dJdPhi_plus(k,l,i,j) = (J_plus(k,l) - J(k,l))/(_perturbationfactor); + } + } + } + } + STensorOperation::inverseSTensor43(dJdPhi_plus,dJdPhi_plus_inv); + + // END NUMERICAL + // ################################################################## + */ + + // update DPhi + for (int i=0; i<3; i++) + for (int j=0; j<3; j++){ + DPhi(i,j) = 0.; + for (int k=0; k<3; k++) + for (int l=0; l<3; l++){ + DPhi(i,j) -= Dho2inv(i,j,k,l)*J(k,l); + } + } + + // update devPhi + for (int i=0; i<3; i++){ + for (int j=0; j<3; j++){ + Phi(i,j) += DPhi(i,j); + } + } + + // update devPhi, ptilde + STensorOperation::decomposeDevTr(Phi,devPhi,ptilde); + ptilde = Phi.trace()/3; + + // update N + STensorOperation::zero(N); + for (int i=0; i<3; i++) + for (int j=0; j<3; j++) + N(i,j) = 3.*devPhi(i,j) + 2.*_b/3.*ptilde*_I(i,j); + + // update H = exp(GN) = A in dexpAdA; Hinv + GammaN = N; + GammaN *= Gamma; + STensorOperation::expSTensor3(GammaN,_order,expGN,&dexpAdA); + STensorOperation::inverseSTensor3(expGN,Hinv); + + // update Ce, Ceinv + for (int i=0; i<3; i++) + for (int j=0; j<3; j++){ + Ce(i,j) = 0.; + Ceinv(i,j) = 0.; + for (int k=0; k<3; k++) + for (int l=0; l<3; l++){ + Ce(i,j) += Hinv(i,k)*Hinv(k,l)*Cepr(l,j); + Ceinv(i,j) += Ceinvpr(i,k)*expGN(k,l)*expGN(l,j); + } + } + + // update Ee + STensorOperation::zero(Ee); + for (int i=0; i<3; i++) + for (int j=0; j<3; j++) + Ee(i,j) = Eepr(i,j) - Gamma*N(i,j); + + // EIGEN NEW - update Fe + STensorOperation::multSTensor3(expGN,q0->_Fp,Fp1); + STensorOperation::inverseSTensor3(Fp1,Fpinv); + STensorOperation::multSTensor3(F,Fpinv,Fe); + + // STensorOperation::getEigenDecomposition(Ee,e1,e2,e3,E1,E2,E3); + // NEW EIGEN + + // update corKir + if (Ge_TrEeTensor == NULL){ + if (!_useRotationCorrection){ + mlawNonLinearTVM::ThermoViscoElasticPredictor(Ee,q0->_Ee,q0,q1,Ke,Ge,T0,T,true,Bd_stiffnessTerm); + } + else{ + mlawNonLinearTVM::ThermoViscoElasticPredictor_forTVP(Ce,Ee,Ee0_rot,q0,q1,Ke,Ge,T0,T,true,alignedIndex,Bd_stiffnessTerm,NULL,rotationStiffness); // NEW EIGEN + } + } + else{ // TC asymmetry + if (!_useRotationCorrection){ + mlawNonLinearTVM::ThermoViscoElasticPredictor(Ee,q0->_Ee,q0,q1,Ke,Ge,T0,T,true,Bd_stiffnessTerm,Ge_TrEeTensor); + } + else{ + mlawNonLinearTVM::ThermoViscoElasticPredictor_forTVP(Ce,Ee,Ee0_rot,q0,q1,Ke,Ge,T0,T,true,alignedIndex,Bd_stiffnessTerm,Ge_TrEeTensor,rotationStiffness); // NEW EIGEN + } + } + + Ge_Tensor = _I4; + Ge_Tensor *= Ge*2; // *2 because the function doesnt do it + Ge_Tensor += Bd_stiffnessTerm; + KS = q1->_kirchhoff; + + // update backStress + STensorOperation::decomposeDevTr(N,devN,trN); + devX = pow(kk,1)*Hb*Gamma*devN + devXn; // pow(kk,2) DEBUG + devX *= 1./Cxdev; + trX = (pow(kk,1)*Hb*Gamma*trN + trXn)*1./Cxtr; // pow(kk,2) DEBUG + q1->_backsig = devX; + q1->_backsig(0,0) += trX/3.; + q1->_backsig(1,1) += trX/3.; + q1->_backsig(2,2) += trX/3.; + + // update J + STensorOperation::zero(J); + for (int i=0; i<3; i++) + for (int j=0; j<3; j++) + J(i,j) += ( Phi(i,j) - KS(i,j) + q1->_backsig(i,j) ); + + // update Dho2, Dho2inv + if (Ge_TrEeTensor == NULL){ + getDho(Gamma,Cepr,Ceinvpr,KS,Ke,Ge_Tensor,kk,Hb,Cxtr,Cxdev,expGN,dexpAdA,Dho,Dho2inv,Dho2_u_inv,Dho2_v_inv,NULL,rotationStiffness); + } + else{ // TC asymmetry + getDho(Gamma,Cepr,Ceinvpr,KS,Ke,Ge_Tensor,kk,Hb,Cxtr,Cxdev,expGN,dexpAdA,Dho,Dho2inv,Dho2_u_inv,Dho2_v_inv,Ge_TrEeTensor,rotationStiffness); + } + + // update J_tol + /* + J_tol = 0.; + for (int i=0; i<3; i++){ + for (int j=0; j<3; j++){ + J_tol += abs(J(i,j)); + } + }*/ + + // debug + /* + for (int i=0; i<3; i++) + for (int j=0; j<3; j++) + for (int k=0; k<3; k++) + for (int l=0; l<3; l++) + // dJdPhi_plus2(k,l,i,j) = (J(k,l) - J0(k,l))/(_perturbationfactor); + + // STensorOperation::inverseSTensor43(dJdPhi_plus2,dJdPhi_plus2_inv); + // J0 = J; + + for (int i=0; i<3; i++) + for (int j=0; j<3; j++) + for (int k=0; k<3; k++) + for (int l=0; l<3; l++){ + // Msg::Error(" Dho2inv(%d,%d,%d,%d)=%d",i,j,k,l,Dho2inv(i,j,k,l)); + // Msg::Error(" dJdPhi_plus_inv(%d,%d,%d,%d)=%d",i,j,k,l,dJdPhi_plus_inv(i,j,k,l)); + }*/ + + J_tol = J.norm0(); + J_tol/=(_K+_G); + // J_tol/=(1.e+10); + + ite++; + + // if (ite> maxite-5) + // Msg::Info("ite = %d, tol %e, J_tol = %e, Gamma = %e",ite,tol,J_tol,Gamma); + + if (fabs(J_tol) <_tol) break; + + if(ite > maxite){ + Msg::Error("No convergence for iterated Phi mlawNonLinearTVENonLinearTVP2 nonAssociatedFlow iter = %d, J_tol = %e!!",ite,J_tol); + // Msg::Error("No convergence for iterated Phi mlawNonLinearTVENonLinearTVP2 nonAssociatedFlow iter = %d, e1 = %e, e2 = %e, e3 = %e !!",ite,e1,e2,e3); + // Msg::Error("Exiting the function Iterated Phi!!"); + // Phi(0,0) = Phi(1,1) = Phi(2,2) = sqrt(-1.); + // Gamma *= 0.1; + return; + } + } // while + +} + +/* +void mlawNonLinearTVENonLinearTVP2::TEST_predictorCorrector_TVP_nonAssociatedFlow_nonLinearTVE( + const STensor3& F0, const STensor3& F, const IPNonLinearTVP *q0, IPNonLinearTVP *q1, const double T0, const double T, + const STensor3& Fepr, const STensor3& Cepr, + double& ptilde, STensor3& devPhi, double& Gamma, double& Dgamma, double& A, double& f, STensor3& Me, STensor3& P) const{ + + // compute elastic predictor + static STensor3 Fp1, Fpinv, Fe, Ce, Ee; // = q1->_Fp; + const STensor3& Fp0 = q0->_Fp; + + Fp1 = Fp0; + STensorOperation::inverseSTensor3(Fp1,Fpinv); + + static STensor3 invFp0; // plastic predictor + invFp0 = Fpinv; + + // Update the Properties to the current temperature (see below which ones are being used) + double CpT, DCpDT; getCp(CpT,T,&DCpDT); + + // Get hardening parameters + this->mlawNonLinearTVP::hardening(q0,q1,T); + static fullVector<double> a(3), Da(3); // yield coefficients and derivatives in respect to plastic deformation + this->mlawNonLinearTVP::getYieldCoefficients(q1,a); + //a.print("a init"); + + double Hb(0.), dHb(0.), ddHb(0.), dHbdT(0.), ddHbdgammadT(0.), ddHbddT(0.); + if (q1->_ipKinematic != NULL){ + Hb = q1->_ipKinematic->getR(); // kinematic hardening parameter + dHb = q1->_ipKinematic->getDR(); // kinematic hardening parameter derivative (dHb/dgamma) + dHbdT = q1->_ipKinematic->getDRDT(); // make sure to normalise DRDT while defining in python file //NEW + ddHbddT = q1->_ipKinematic->getDDRDTT(); + ddHbdgammadT = q1->_ipKinematic->getDDRDT(); + } + + double eta(0.),Deta(0.),DetaDT(0.); + if (_viscosity != NULL) + _viscosity->get(q1->_epspbarre,T,eta,Deta,DetaDT); + + // Get Cepr, Ceinvpr + static STensor3 Eepr, Ceinvpr; + Ce = Cepr; + STensorOperation::inverseSTensor3(Cepr,Ceinvpr); + + Fe = Fepr; + + // Predictor - TVE + static STensor43 DlnDCepr, DlnDCe; + static STensor63 DDlnDDCe; + static STensor3 expGN, GammaN; + static STensor43 dexpAdA; // estimation of dexpA/dA + expGN = _I; // if Gamma = 0, expGN = _I + dexpAdA = _I4; + + STensorOperation::logSTensor3(Ce,_order,Ee,&DlnDCepr,&DDlnDDCe); + Ee *= 0.5; + Eepr = Ee; + DlnDCe = DlnDCepr; + + // update A, B -> ExtraBranch calculations are within + double Ke(0.), Ge(0.), Ke_pr(0.), Ge_pr(0.); + static STensor43 Ge_Tensor_pr, Ge_Tensor, Bd_stiffnessTerm; + STensorOperation::zero(Ge_Tensor_pr); + STensorOperation::zero(Ge_Tensor); + mlawNonLinearTVM::ThermoViscoElasticPredictor_forTVP(Ce,Ee,q0->_Ee,q0,q1,Ke,Ge,T0,T,true,Bd_stiffnessTerm); + Ge_Tensor = _I4; + Ge_Tensor *= Ge*2; // Because the function does not do it + Ge_Tensor += Bd_stiffnessTerm; + + // Keep the predictor values of Ke and Ge for tangents later + Ke_pr = Ke; + Ge_pr = Ge; + Ge_Tensor_pr = _I4; + Ge_Tensor_pr *= Ge_pr*2; // Because the function does not do it + Ge_Tensor_pr += Bd_stiffnessTerm; + + // get predictor - dKeprDT + mlawNonLinearTVM::getTVEdCorKirDT(q0,q1,T0,T); + const STensor3& dKeprDT = q1->_DcorKirDT; + + // Initialise Dho + static STensor43 Dho, Dho2inv, Dho2_u_inv; // This will be the final important tensor. + double Dho2_v_inv(0.); + + // Get Mepr + static STensor3 Mepr, Kepr; // Ke is corKir + mlawNonLinearTVP::getModifiedMandel(Ce,q0,q1); + Me = q1->_ModMandel; + Mepr = Me; + Kepr = q1->_kirchhoff; + + // Get Xn; Initialise X + static STensor3 devXn, devX; + static double trXn, pXn, eXn, trX; + STensorOperation::decomposeDevTr(q0->_backsig,devXn,trXn); // needed for chaboche model + pXn = 1./3.*trXn; // 1st invariant of Xn + eXn = sqrt(1.5*devXn.dotprod()); // J2 invariant of Xn + + // Initialise Phipr + static STensor3 PhiPr, Phi; + PhiPr = q1->_ModMandel; + PhiPr -= q1->_backsig; + Phi = PhiPr; + + static STensor3 devPhipr; // effective dev stress predictor + static double ptildepr; + STensorOperation::decomposeDevTr(PhiPr,devPhipr,ptildepr); + ptildepr/= 3.; + + // Initialise Normal + static STensor3 devN; // dev part of yield normal + double trN = 0.; // trace part of yield normal + static STensor3 N; // yield normal + STensorOperation::zero(devN); + STensorOperation::zero(N); + + // Get plastic poisson ratio + q1->_nup = (9.-2.*_b)/(18.+2.*_b); + double kk = (1./sqrt(1.+2.*q1->_nup*q1->_nup)); + + // Initialise variables + Gamma = 0.; + double dDgammaDGamma = 0.; + static fullVector<double> m(2); + mlawNonLinearTVP::getChabocheCoeffs(m,0,q1); + + double DfDGamma(0.), dfdDgamma(0.), dfdGamma(0.), dAdDgamma(0.), dAdGamma(0.); + + // Initialise Cx + double Cxdev = 1. + 3.*m(1)*pow(kk,1)*Hb; // pow(kk,2) DEBUG + double Cxtr = 1. + 2.*_b/3. *m(1)*pow(kk,1)*Hb; // pow(kk,2) DEBUG + double dCxdevdDgamma(0.), dCxtrdDgamma(0.); + if (Hb>0.){ + Cxdev -= m(0)*dHb*Dgamma/Hb + 1./Hb * dHbdT * (T-T0); + Cxtr -= m(0)*dHb*Dgamma/Hb + 1./Hb * dHbdT * (T-T0); + } + + // Initialise ptilde and devPhi + ptilde = ptildepr; + devPhi = devPhipr; + + // Initialise the rest + getDho(Gamma,Cepr,Ceinvpr,Kepr,Ke,Ge_Tensor,kk,Hb,Cxtr,Cxdev,expGN,dexpAdA,Dho,Dho2inv,Dho2_u_inv,Dho2_v_inv); + + double PhiEqpr2 = 1.5*devPhi.dotprod(); + double PhiEqpr = sqrt(PhiEqpr2); // -> second invariant + double PhiEq = PhiEqpr; // current effective deviator + + // Get f and A + f = a(2)*pow(PhiEq,_n) - (a(1)*ptilde+a(0)); + A = sqrt(6.*PhiEq*PhiEq+4.*_b*_b/3.*ptilde*ptilde); + + // Initialise g + double dgdDgamma(0.), dgdGamma(0.); + double g = Dgamma - kk*Gamma*A; + + // NR Loop - Gamma and Dgamma + if (q1->dissipationIsBlocked()){ + q1->getRefToDissipationActive() = false; + } + else{ + if (f>_tol){ + q1->getRefToDissipationActive() = true; + + // plasticity + int ite = 0; + int maxite = 100; // maximal number of iters + // Msg::Error("plasticity occurs f = %e",f); + //double f0 = fabs(f); + + while (fabs(f) >_tol or ite <1){ + + // Viscosity term + double etaOverDt = eta/this->getTimeStep(); + + // Get dCxdevdDgamma, dCxtrdDgamma + dCxdevdDgamma = 0.; dCxtrdDgamma = 0.; + if (Hb>0.){ + dCxdevdDgamma = -m(0)*1./Hb*dHb - m(0)*Dgamma*(-1./pow(Hb,2.)*pow(dHb,2.) + 1./Hb*ddHb) - (T-T0)*(-1./pow(Hb,2.)*dHb*dHbdT + 1./Hb*ddHbdgammadT); + dCxtrdDgamma = dCxdevdDgamma; + } + dCxdevdDgamma += 3.*m(1)*pow(kk,1)*dHb; // pow(kk,2) DEBUG + dCxtrdDgamma += (2.*_b/3.)*m(1)*pow(kk,1)*dHb; // pow(kk,2) DEBUG + + // Get Hp = dPhiPdDgamma, dPhiPdGamma + double Hp = 2*_b*pow(kk,1)*Gamma/3.*ptilde*( Hb/pow(Cxtr,2)*dCxtrdDgamma - 1./Cxtr*dHb ) * Dho2_v_inv; // pow(kk,2) DEBUG + double dPhiPdGamma = -2*_b*ptilde*(Ke + pow(kk,1)*Hb/(3.*Cxtr)) * Dho2_v_inv; // pow(kk,2) DEBUG + + // Get He = dPhiEdGamma + // Get DdevPhidGamma + static STensor3 DdevPhidDgamma, DdevPhidDgamma_RHS; + static STensor3 DdevPhidGamma, DdevPhidGamma_RHS; + STensorOperation::zero(DdevPhidDgamma); STensorOperation::zero(DdevPhidGamma); + STensorOperation::zero(DdevPhidDgamma_RHS); STensorOperation::zero(DdevPhidGamma_RHS); + + for (int i=0; i<3; i++) + for (int j=0; j<3; j++){ + DdevPhidDgamma_RHS(i,j) += ( 0.5*2*_b*Gamma*Ke*Hp*_I(i,j) + 3*Gamma*pow(kk,1)*( Hb/pow(Cxdev,2.)*dCxdevdDgamma - dHb/Cxdev ) * devPhi(i,j) ); // pow(kk,2) DEBUG + DdevPhidGamma_RHS(i,j) += ( -0.5*2*_b*Ke*(-ptilde-Gamma*dPhiPdGamma)*_I(i,j) - 3*pow(kk,1)*Hb/Cxdev*devPhi(i,j) ); // pow(kk,2) DEBUG + for (int k=0; k<3; k++) + for (int l=0; l<3; l++){ + DdevPhidDgamma_RHS(i,j) += 0.5* 2.*_b/3.*Gamma*Dho(i,j,k,l)*_I(k,l)*Hp; + DdevPhidGamma_RHS(i,j) += 0.5* ( -3.*Ge_Tensor(i,j,k,l)*devPhi(k,l) + 2.*_b/3.*Gamma*Dho(i,j,k,l)*_I(k,l)*dPhiPdGamma ); + DdevPhidGamma_RHS(i,j) += 0.5*Dho(i,j,k,l)*N(k,l); // DEBUG + } + } + for (int i=0; i<3; i++) + for (int j=0; j<3; j++) + for (int k=0; k<3; k++) + for (int l=0; l<3; l++){ + DdevPhidDgamma(i,j) += Dho2_u_inv(i,j,k,l)*DdevPhidDgamma_RHS(k,l); + DdevPhidGamma(i,j) += Dho2_u_inv(i,j,k,l)*DdevPhidGamma_RHS(k,l); + } + + double Stemp1 = STensorOperation::doubledot(devPhi,DdevPhidDgamma); + double Stemp2 = STensorOperation::doubledot(devPhi,DdevPhidGamma); + double He = 1.5*Stemp1/PhiEq; + double dPhiEdGamma = 1.5*Stemp2/PhiEq; + + + // dAdGamma and dDgammaDGamma + dAdDgamma = (12.*PhiEq*He + 8.*_b*_b*ptilde*Hp/3.)/(2.*A); + dAdGamma = (12.*PhiEq*dPhiEdGamma + 8.*_b*_b*ptilde*dPhiPdGamma/3.)/(2.*A); + + dDgammaDGamma = pow(kk,1)*(A+Gamma*dAdGamma); // mistake in the paper (VD 2016) // pow(kk,2) DEBUG + + this->getYieldCoefficientDerivatives(q1,q1->_nup,Da); + + dfdDgamma = Da(2)*pow(PhiEq,_n) - Da(1)*ptilde -Da(0); + dfdDgamma += a(2)*_n*pow(PhiEq,(_n-1.))*He - a(1)*Hp; + + if (Gamma>0 and etaOverDt>0) + dfdDgamma -= _p*pow(etaOverDt,_p-1.)*Deta/this->getTimeStep()*pow(Gamma,_p); // THIS term is absent in the paper!! + + dfdGamma = _n*a(2)*pow(PhiEq,(_n-1.))*dPhiEdGamma - a(1)*dPhiPdGamma; + if (Gamma>0 and etaOverDt>0) + dfdGamma -= pow(etaOverDt,_p)*_p*pow(Gamma,(_p-1.)); + + DfDGamma = dfdDgamma*dDgammaDGamma + dfdGamma; + + dgdDgamma = 1. - kk*Gamma*dAdDgamma; + dgdGamma = - dDgammaDGamma; + + double dGamma = (-f + dfdDgamma*g/dgdDgamma)/(-dfdDgamma*dgdGamma/dgdDgamma + dfdGamma); // NR + double dDgamma = -(g+dgdGamma*dGamma)/dgdDgamma; // NR + + if (Gamma + dGamma <=0.){ + Gamma /= 2.; // NR + } + else + Gamma += dGamma; + + // Dgammma_test += dDgamma; + if (Dgamma + dDgamma <=0.){ + Dgamma /= 2.; + } + else + Dgamma += dDgamma; + + //Msg::Error("Gamma = %e",Gamma); + //Msg::Error("Dgamma = %e",Dgamma); + + + // UPDATE FOR NEXT ITERATION + + // Update gamma and all Hardening moduli + mlawNonLinearTVP::updateEqPlasticDeformation(q1,q0,q1->_nup,Dgamma); + mlawNonLinearTVP::hardening(q0,q1,T); + mlawNonLinearTVP::getYieldCoefficients(q1,a); + if (q1->_ipKinematic != NULL){ + Hb = q1->_ipKinematic->getR(); // kinematic hardening parameter + dHb = q1->_ipKinematic->getDR(); // kinematic hardening parameter derivative (dHb/dgamma ??) + dHbdT = q1->_ipKinematic->getDRDT(); // make sure to normalise DRDT while defining in python file //NEW + ddHbddT = q1->_ipKinematic->getDDRDTT(); + ddHbdgammadT = q1->_ipKinematic->getDDRDT(); + } + //a.print("a update"); + + + // Update Cx + Cxdev = 1. + 3.*m(1)*pow(kk,1)*Hb; // pow(kk,2) DEBUG + Cxtr = 1. + 2.*_b/3. *m(1)*pow(kk,1)*Hb; // pow(kk,2) DEBUG + if (Hb>0.){ + Cxdev -= m(0)*dHb*Dgamma/Hb - 1./Hb * dHbdT * (T-T0); + Cxtr -= m(0)*dHb*Dgamma/Hb - 1./Hb * dHbdT * (T-T0); + } + + // Update Phi + getIterated_DPhi(F,T0,T,q0,q1,Gamma,Cxtr,Cxdev,Cepr,Eepr,trXn,devXn,Ke,Ge,Ge_Tensor,ptilde,devPhi,Phi,N,expGN,dexpAdA, + Dho,Dho2inv,Dho2_u_inv,Dho2_v_inv,Fp1); + PhiEq = sqrt(1.5*devPhi.dotprod()); + + // Update A + A = sqrt(6.*PhiEq*PhiEq+4.*_b*_b/3.*ptilde*ptilde); + + + // Dgamma = pow(kk,1)*Gamma*A; // pow(kk,2) DEBUG + // updateEqPlasticDeformation(q1,q0,q1->_nup,Dgamma); + // hardening(q0,q1,T); + // getYieldCoefficients(q1,a); + + // Update f, g + f = a(2)*pow(PhiEq,_n) - (a(1)*ptilde+a(0)); + double viscoTerm = etaOverDt*Gamma; + if (Gamma>0. and etaOverDt>0.) f-= pow(viscoTerm,_p); + + g = Dgamma - kk*Gamma*A; + + ite++; + // if (ite> maxite-5) + // Msg::Error("it = %d, DfDGamma = %e error = %e dGamma = %e, Gamma = %e",ite,DfDGamma,f,dGamma,Gamma); + + if (fabs(f) <_tol) break; + + if(ite > maxite){ + Msg::Error("No convergence for plastic correction in mlawNonLinearTVP nonAssociatedFlow Maxwell iter = %d, f = %e!!",ite,f); + P(0,0) = P(1,1) = P(2,2) = sqrt(-1.); + return; + } + + } // while + + q1->_DgammaDt = Dgamma/this->getTimeStep(); + + // Correct Cx + Cxdev = 1. + 3.*m(1)*pow(kk,1)*Hb; // pow(kk,2) DEBUG + Cxtr = 1. + 2.*_b/3. *m(1)*pow(kk,1)*Hb; // pow(kk,2) DEBUG + if (Hb>0.){ + Cxdev -= m(0)*dHb*Dgamma/Hb - 1./Hb * dHbdT * (T-T0); + Cxtr -= m(0)*dHb*Dgamma/Hb - 1./Hb * dHbdT * (T-T0); + } + + // Correct Phi + getIterated_DPhi(F,T0,T,q0,q1,Gamma,Cxtr,Cxdev,Cepr,Eepr,trXn,devXn,Ke,Ge,Ge_Tensor,ptilde,devPhi,Phi,N,expGN,dexpAdA, + Dho,Dho2inv,Dho2_u_inv,Dho2_v_inv,Fp1); + PhiEq = sqrt(1.5*devPhi.dotprod()); + + // Correct Normal, H = expGN + STensorOperation::decomposeDevTr(N,devN,trN); + + // Get GammaN for mechSrcTVP + STensorOperation::zero(GammaN); + GammaN = N; + GammaN *= Gamma; + q1->_GammaN = GammaN; + + // Correct plastic deformation tensor + STensorOperation::multSTensor3(expGN,Fp0,Fp1); + + // Correct IP gamma + updateEqPlasticDeformation(q1,q0,q1->_nup,Dgamma); + // Msg::Info("setting: gamma=%e ",q1->_epspbarre); + + // Correct elastic deformation tensor, corotational stress + STensorOperation::inverseSTensor3(Fp1,Fpinv); + STensorOperation::multSTensor3(F,Fpinv,Fe); + STensorOperation::multSTensor3FirstTranspose(Fe,Fe,Ce); + STensorOperation::logSTensor3(Ce,_order,Ee,&DlnDCe,&DDlnDDCe); + Ee *= 0.5; + + } // 2nd if + else{ + q1->getRefToDissipationActive() = false; + } + } // 1st if + + const STensor3& KS = q1->_kirchhoff; + mlawNonLinearTVP::getModifiedMandel(Ce, q0, q1); // update Mandel + + const STensor3& MS = q1->_ModMandel; + Me = MS; + // second Piola Kirchhoff stress + static STensor3 S, Ceinv; + STensorOperation::inverseSTensor3(Ce,Ceinv); + STensorOperation::multSTensor3(Ceinv,q1->_ModMandel,S); + + // first PK + for(int i=0; i<3; i++) + for(int j=0; j<3; j++){ + P(i,j) = 0.; + for(int k=0; k<3; k++) + for(int l=0; l<3; l++) + P(i,j) += Fe(i,k)*S(k,l)*Fpinv(j,l); + } +}*/ + +/* + // + // NUMERICAL phi ders wrt gamma, Gamma + + double dPhiPdGamma_plus, dPhiPdDgamma_plus; + static STensor3 DdevPhidDgamma_plus, DdevPhidGamma_plus; + double Gamma_plus = Gamma + _perturbationfactor; + double Dgamma_plus = Dgamma; // + _perturbationfactor; + + static IPNonLinearTVP qPlus1(*q0); + + + // Numerical update hardening stuff + + static fullVector<double> a_plus(3), Da_plus(3); + updateEqPlasticDeformation(&qPlus1,q0,q1->_nup,Dgamma_plus); + hardening(q0,&qPlus1,T); + getYieldCoefficients(&qPlus1,a_plus); + + double Hb_plus(0.), dHb_plus(0.), ddHb_plus(0.), dHbdT_plus(0.), ddHbdgammadT_plus(0.), ddHbddT_plus(0.); + if (qPlus1._ipKinematic != NULL){ + Hb_plus = qPlus1._ipKinematic->getDR(); // kinematic hardening parameter + dHb_plus = qPlus1._ipKinematic->getDDR(); // kinematic hardening parameter derivative (dHb/dgamma) + dHbdT_plus = Hb_plus * qPlus1._ipKinematic->getDRDT(); // make sure to normalise DRDT while defining in python file //NEW + // ddHbddT_plus = Hb_plus * qPlus1._ipKinematic->getDDRDDT(); + } + + double eta_plus(0.),Deta_plus(0.),DetaDT_plus(0.); + if (_viscosity != NULL) + _viscosity->get(qPlus1._epspbarre,T,eta_plus,Deta_plus,DetaDT_plus); + + // Numerical Update Cx, u, v + double Cxdev_plus, Cxtr_plus, u_plus, v_plus, Gt_plus, Kt_plus; + double ptilde_plus, Dho4_v_inv_plus, DsigV_dTrEe_plus; + static STensor3 devPhi_plus, Phi_plus, N_plus, expGN_plus, sigExtra_plus; + static STensor43 dexpAdA_plus, Dho3_plus, Dho4inv_plus, Dho4_u_inv_plus; + static STensor43 DsigD_dDevEe_plus; + + expGN_plus = _I; dexpAdA_plus = _I4; + + Cxdev_plus = 1. + 3*m(1)*pow(kk,1)*Hb_plus; // pow(kk,2) DEBUG + Cxtr_plus = 1. + 2*_b/3 *m(1)*pow(kk,1)*Hb_plus; // pow(kk,2) DEBUG + if (Hb_plus>0.){ + Cxdev_plus -= m(0)*dHb_plus*Dgamma_plus/Hb_plus - 1/Hb_plus * dHbdT_plus * (T-T0); + Cxtr_plus -= m(0)*dHb_plus*Dgamma_plus/Hb_plus - 1/Hb_plus * dHbdT_plus * (T-T0); + } + Gt_plus = Ge + pow(kk,1) * Hb_plus/(2*Cxdev_plus); // pow(kk,2) DEBUG + Kt_plus = Ke + pow(kk,1) * Hb_plus/(3*Cxtr_plus); // pow(kk,2) DEBUG + u_plus = 1.+6.*Gt_plus*Gamma_plus; + v_plus = 1.+2.*_b*Kt_plus*Gamma_plus; + + // Inititalise phi + ptilde_plus = ptilde; + devPhi_plus = devPhi; + + // Numerical Update Phi + getIterated_DPhi(T,q0,&qPlus1,u_plus,v_plus,Gamma_plus,Cxtr_plus,Cxdev_plus,PhiPr,trXn,devXn,Cepr,Eepr,Kepr,ptilde_plus,devPhi_plus,Phi_plus, + N_plus,expGN_plus,dexpAdA_plus, + Dho3_plus,Dho4inv_plus,Dho4_u_inv_plus,Dho4_v_inv_plus, + sigExtra_pr,sigExtra_plus,DsigV_dTrEe_plus,DsigD_dDevEe_plus); + + dPhiPdGamma_plus = (ptilde_plus-ptilde)/_perturbationfactor; + dPhiPdDgamma_plus = (ptilde_plus-ptilde)/_perturbationfactor; + + + DdevPhidGamma_plus = devPhi_plus; + DdevPhidGamma_plus -= devPhi; + DdevPhidGamma_plus *= 1/_perturbationfactor; + + DdevPhidDgamma_plus = devPhi_plus; + DdevPhidDgamma_plus -= devPhi; + DdevPhidDgamma_plus *= 1/_perturbationfactor; + + /*for (int i=0; i<3; i++) + for (int j=0; j<3; j++) + for (int k=0; k<3; k++) + for (int l=0; l<3; l++){ + STensorOperation::inverseSTensor3(H_plus,Hinv_plus); + STensorOperation::multSTensor3(H_plus,H_plus,HH_plus); + STensorOperation::multSTensor3(Hinv_plus,Hinv_plus,HinvHinv_plus); + dHdH_plus(k,l,i,j) = (H_plus(k,l) - expGN(k,l))/(_perturbationfactor); + dHinvdH_plus(k,l,i,j) = (Hinv_plus(k,l) - Hinv(k,l))/(_perturbationfactor); + dHHdH_plus(k,l,i,j) = (HH_plus(k,l) - HH(k,l))/(_perturbationfactor); + dHinvHinvdH_plus(k,l,i,j) = (HinvHinv_plus(k,l) - HinvHinv(k,l))/(_perturbationfactor); + } +*/ diff --git a/NonLinearSolver/materialLaw/mlawNonLinearTVENonLinearTVP2.h b/NonLinearSolver/materialLaw/mlawNonLinearTVENonLinearTVP2.h new file mode 100644 index 0000000000000000000000000000000000000000..11556db260dea8e631d9877757cd9b5ffbb33667 --- /dev/null +++ b/NonLinearSolver/materialLaw/mlawNonLinearTVENonLinearTVP2.h @@ -0,0 +1,201 @@ +// +// C++ Interface: Material Law +// +// Description: Non-Linear Thermo-Visco-Mechanics (Thermo-ViscoElasto-ViscoPlasto Law) with Non-Local Damage Interface (soon....?) +// +// Author: <Ujwal Kishore J - FLE_Knight>, (C) 2024 +// +// Copyright: See COPYING file that comes with this distribution +// +// +#ifndef MLAWNONLINEARTVENONLINEARTVP2_H_ +#define MLAWNONLINEARTVENONLINEARTVP2_H_ + +#include "ipNonLinearTVP.h" +#include "mlawNonLinearTVP.h" + +class mlawNonLinearTVENonLinearTVP2 : public mlawNonLinearTVP{ + + protected: + double _stressIteratorTol; + + protected: + virtual double freeEnergyPlasticity(const IPNonLinearTVP *q0, IPNonLinearTVP *q1, const double& T0, const double& T) const; + + virtual void freeEnergyPlasticityDerivatives(const IPNonLinearTVP *q0, IPNonLinearTVP *q1, const double& T0, const double& T, STensor3& dPsy_TVPdF, double& dPsy_TVPdT) const; + + virtual void getIterated_DPhi(const STensor3& F, const double& T0, const double& T, const IPNonLinearTVP *q0, IPNonLinearTVP *q1, + double& Gamma, const double& Cxtr, const double& Cxdev, + const STensor3& Cepr, const STensor3& Eepr, + const double& trXn, const STensor3& devXn, + double& Ke, double& Ge, STensor43& Ge_Tensor, + double& ptilde, STensor3& devPhi, + STensor3& Phi, STensor3& N, STensor3& expGN, STensor43& dexpAdA, + STensor43& Dho, STensor43& Dho2inv, STensor43& Dho2_u_inv, double& Dho2_v_inv, STensor3& Fp1, const fullVector<int>& alignedIndex, + STensor43* Ge_TrEeTensor = NULL, STensor43* rotationStiffness = NULL) const; + + virtual void getDho(const double& Gamma, const STensor3& Cepr, const STensor3& Ceinvpr, const STensor3& KS, + const double& Ke, const STensor43& Ge_Tensor, + const double& kk, const double& Hb, const double& Cxtr, const double& Cxdev, + const STensor3& expGN, const STensor43& dexpAdA, + STensor43& Dho, STensor43& Dho2inv, STensor43& Dho2_u_inv, double& Dho2_v_inv, STensor43* Ge_TrEeTensor = NULL, STensor43* rotationStiffness = NULL) const; + + virtual void get_G1_Tensor(const STensor3& Cepr, const STensor3& expGN, const STensor43& DCeinvprDCepr, const STensor3& KS, STensor43& G1) const; + + virtual void TEST_predictorCorrector_TVP_nonAssociatedFlow_nonLinearTVE( + const STensor3& F0, const STensor3& F, const IPNonLinearTVP *q0, IPNonLinearTVP *q1, const double T0, const double T, + const STensor3& Fepr, const STensor3& Cepr, + double& ptilde, STensor3& devPhi, double& Gamma, double& Dgamma, double& A, double& f, STensor3& Me, STensor3& P) const{}; + + virtual void predictorCorrector_TVP_nonAssociatedFlow_nonLinearTVE(const STensor3& F0, const STensor3& F, const IPNonLinearTVP *q0_, IPNonLinearTVP *q1, + STensor3&P, const bool stiff, STensor43& Tangent, STensor43& dFedF, STensor43& dFpdF, STensor3& dFedT, STensor3& dFpdT, + const double T0, const double T1, + const SVector3 &gradT0, // previous temperature gradient + const SVector3 &gradT, // temperature gradient + SVector3 &fluxT, // temperature flux + STensor3 &dPdT, // mechanical-thermal coupling + STensor3 &dfluxTdgradT, // thermal tengent + SVector3 &dfluxTdT, + STensor33 &dfluxTdF, // thermal-mechanical coupling + double &thermalSource, // - Cp*dTdt + double &dthermalSourcedT, // thermal source + STensor3 &dthermalSourcedF, + double &mechanicalSource, // mechanical source--> convert to heat + double &dmechanicalSourcedT, + STensor3 &dmechanicalSourceF) const; + + + virtual void predictorCorrector_ThermoViscoPlastic( + const STensor3& F0, // initial deformation gradient (input @ time n) + const STensor3& F1, // updated deformation gradient (input @ time n+1) + STensor3& P, // updated 1st Piola-Kirchhoff stress tensor (output) + const IPNonLinearTVP *q0, // array of initial internal variable + IPNonLinearTVP *q1, // updated array of internal variable (in ipvcur on output), + const double& T0, // previous temperature + const double& T, // temperature + const SVector3 &gradT0, // previous temeprature gradient + const SVector3 &gradT, // temeprature gradient + SVector3 &fluxT, // temperature flux) + double &thermalSource, + double &mechanicalSource, + STensor43* elasticTangent) const; + + virtual void predictorCorrector_ThermoViscoPlastic( + const STensor3& F0, // initial deformation gradient (input @ time n) + const STensor3& F1, // updated deformation gradient (input @ time n+1) + STensor3& P, // updated 1st Piola-Kirchhoff stress tensor (output) + const IPNonLinearTVP *q0, // array of initial internal variable + IPNonLinearTVP *q1, // updated array of internal variable (in ipvcur on output), + STensor43 &Tangent, // mechanical tangents (output) + STensor43 &dFpdF, // plastic tangent + STensor3 &dFpdT, // plastic tangent + STensor43 &dFedF, // elastic tangent + STensor3 &dFedT, // elastic tangent + const double& T0, // previous temperature + const double& T, // temperature + const SVector3 &gradT0, // previoustemeprature gradient + const SVector3 &gradT, // temeprature gradient + SVector3 &fluxT, // temperature flux + STensor3 &dPdT, // mechanical-thermal coupling + STensor3 &dfluxTdgradT, // thermal tengent + SVector3 &dfluxTdT, + STensor33 &dfluxTdF, // thermal-mechanical coupling + double &thermalSource, // - cp*dTdt + double &dthermalSourcedT, // thermal source + STensor3 &dthermalSourcedF, + double &mechanicalSource, // mechanical source--> convert to heat + double &dmechanicalSourcedT, + STensor3 &dmechanicalSourceF, + const bool stiff, + STensor43* elasticTangent) const; // tangent is used by pointer, if NULL->no compute + + virtual void tangent_full_perturbation( // compute tangent by perturbation + const STensor3& F0, // initial deformation gradient (input @ time n) + const STensor3& F1, // updated deformation gradient (input @ time n+1) + STensor3& P, // updated 1st Piola-Kirchhoff stress tensor (output) + const IPNonLinearTVP *q0, // array of initial internal variable + IPNonLinearTVP *q1, // updated array of internal variable (in ipvcur on output), + const double& T0, // previous temperature + const double& T, // temperature + const SVector3 &gradT0, // previous temeprature gradient + const SVector3 &gradT, // temeprature gradient + SVector3 &fluxT, // temperature flux) + double &thermalSource, + double &mechanicalSource, + STensor43 &Tangent, // mechanical tangents (output) + STensor43 &dFpdF, // plastic tangent + STensor3 &dFpdT, // plastic tangent + STensor43 &dFedF, // elastic tangent + STensor3 &dFedT, // elastic tangent + STensor3 &dPdT, // mechanical-thermal coupling + STensor3 &dfluxTdgradT, // thermal tengent + SVector3 &dfluxTdT, + STensor33 &dfluxTdF, // thermal-mechanical coupling + double &dthermalSourcedT, // thermal source + STensor3 &dthermalSourcedF, + double &dmechanicalSourcedT, + STensor3 &dmechanicalSourceF) const; + + + public: + mlawNonLinearTVENonLinearTVP2(const int num, const double E, const double nu, const double rho, const double tol, + const double Tinitial, const double Alpha, const double KThCon, const double Cp, + const bool matrixbyPerturbation = false, const double pert = 1e-8, const double stressIteratorTol = 1.e-9, const bool thermalEstimationPreviousConfig = true); + + #ifndef SWIG + mlawNonLinearTVENonLinearTVP2(const mlawNonLinearTVENonLinearTVP2& src); + mlawNonLinearTVENonLinearTVP2& operator=(const materialLaw& source); + virtual ~mlawNonLinearTVENonLinearTVP2(); + + virtual bool withEnergyDissipation() const {return true;}; + + virtual matname getType() const{return materialLaw::nonlinearTVEnonlinearTVP2;} + virtual void createIPState(IPStateBase* &ips, bool hasBodyForce, const bool* state_=NULL,const MElement *ele=NULL, + const int nbFF_=0, const IntPt *GP=NULL, const int gpt = 0) const{ + Msg::Error("mlawNonLinearTVENonLinearTVP2::createIPState has not been defined"); + } + virtual void initLaws(const std::map<int,materialLaw*> &maplaw){}; // this law is initialized so nothing to do + + virtual void constitutive( + const STensor3& F0, // initial deformation gradient (input @ time n) + const STensor3& Fn, // updated deformation gradient (input @ time n+1) + STensor3 &P, // updated 1st Piola-Kirchhoff stress tensor (output) + const IPVariable *q0, // array of initial internal variable + IPVariable *q1, // updated array of internal variable (in ipvcur on output), + STensor43 &Tangent, // constitutive tangents (output) + const bool stiff, // if true compute the tangents + STensor43* elasticTangent = NULL, + const bool dTangent =false, + STensor63* dCalgdeps = NULL) const; + + virtual void constitutive( + const STensor3& F0, // initial deformation gradient (input @ time n) + const STensor3& F1, // updated deformation gradient (input @ time n+1) + STensor3& P, // updated 1st Piola-Kirchhoff stress tensor (output) + const IPVariable *q0, // array of initial internal variable + IPVariable *q1, // updated array of internal variable (in ipvcur on output), + STensor43 &Tangent, // constitutive mechanical tangents (output) + const double& T0, // previous temperature + const double& T, // temperature + const SVector3 &gradT0, // previous temperature gradient + const SVector3 &gradT, // temperature gradient + SVector3 &fluxT, // temperature flux + STensor3 &dPdT, // mechanical-thermal coupling + STensor3 &dfluxTdgradT, // thermal tengent + SVector3 &dfluxTdT, + STensor33 &dfluxTdF, // thermal-mechanical coupling + double &thermalSource, // - Cp*dTdt + double &dthermalSourcedT, // thermal source + STensor3 &dthermalSourcedF, + double &mechanicalSource, // mechanical source--> convert to heat + double &dmechanicalSourcedT, + STensor3 &dmechanicalSourceF, + const bool stiff, + STensor43* elasticTangent = NULL) const; + + virtual materialLaw* clone() const{return new mlawNonLinearTVENonLinearTVP2(*this);}; + virtual void checkInternalState(IPVariable* ipv, const IPVariable* ipvprev) const{}; // do nothing + #endif // SWIG +}; + +#endif //mlawNonLinearTVENonLinearTVP2 diff --git a/NonLinearSolver/materialLaw/mlawNonLinearTVM.cpp b/NonLinearSolver/materialLaw/mlawNonLinearTVM.cpp index 412ae54f97fa561f9c56149936fd8b353f0a2a95..c909e0c24a60f2b714144697e3d4d735b27631ea 100644 --- a/NonLinearSolver/materialLaw/mlawNonLinearTVM.cpp +++ b/NonLinearSolver/materialLaw/mlawNonLinearTVM.cpp @@ -22,7 +22,7 @@ mlawNonLinearTVM::mlawNonLinearTVM(const int num,const double E,const double nu, _Tinitial(Tinitial),_scalarAlpha(Alpha),_scalarK(KThCon),_Cp(Cp), _thermalEstimationPreviousConfig(thermalEstimationPreviousConfig), _mullinsEffect(NULL), _elasticPotential(NULL), _useExtraBranch(false), _useExtraBranch_TVE(false), _ExtraBranch_TVE_option(2), _V0(0.),_V1(0.),_V2(0.),_D0(0.),_D1(0.),_D2(0.),_Ci(0.), - _V3(0.),_V4(0.),_V5(0.),_D3(0.),_D4(0.),_D5(0.){ + _V3(0.),_V4(0.),_V5(0.),_D3(0.),_D4(0.),_D5(0.),_useRotationCorrection(false),_rotationCorrectionScheme(0){ _G = _mu; @@ -65,6 +65,8 @@ mlawNonLinearTVM::mlawNonLinearTVM(const mlawNonLinearTVM& src): mlawPowerYieldH _ExtraBranch_TVE_option = src._ExtraBranch_TVE_option; _V0 = src._V0; _V1 = src._V1; _V2 = src._V2; _D0 = src._D0; _D1 = src._D1; _D2 = src._D2; _Ci = src._Ci; _V3 = src._V3; _V4 = src._V4; _V5 = src._V5; _D3 = src._D3; _D4 = src._D4; _D5 = src._D5; + _useRotationCorrection = src._useRotationCorrection; + _rotationCorrectionScheme = src._rotationCorrectionScheme; _temFunc_K = NULL; // bulk modulus if (src._temFunc_K != NULL){ _temFunc_K = src._temFunc_K->clone();} @@ -116,8 +118,9 @@ mlawNonLinearTVM& mlawNonLinearTVM::operator=(const materialLaw &source){ _ExtraBranch_TVE_option = src->_ExtraBranch_TVE_option; _V0 = src->_V0; _V1 = src->_V1; _V2 = src->_V2; _D0 = src->_D0; _D1 = src->_D1; _D2 = src->_D2; _Ci = src->_Ci; _V3 = src->_V3; _V4 = src->_V4; _V5 = src->_V5; _D3 = src->_D3; _D4 = src->_D4; _D5 = src->_D5; + _useRotationCorrection = src->_useRotationCorrection; + _rotationCorrectionScheme = src->_rotationCorrectionScheme; - if(_temFunc_K != NULL) delete _temFunc_K; // bulk modulus if (src->_temFunc_K != NULL){ _temFunc_K = src->_temFunc_K->clone();} @@ -196,7 +199,7 @@ void mlawNonLinearTVM::setCorrectionsAllBranchesTVE(const int i, const double V0 else{ _V0[i-1] = V0; _V1[i-1] = V1; _V2[i-1] = V2; _D0[i-1] = D0; _D1[i-1] = D1; _D2[i-1] = D2; - Msg::Info("setting: element=%d, V0 = %e, V1 = %e, V2 = %e, D0 = %e, D1 = %e, D2 = %e",i-1,V0,V1,V2,D0,D1,D2); + // Msg::Info("setting: element=%d, V0 = %e, V1 = %e, V2 = %e, D0 = %e, D1 = %e, D2 = %e",i-1,V0,V1,V2,D0,D1,D2); } }; @@ -206,7 +209,7 @@ void mlawNonLinearTVM::setAdditionalCorrectionsAllBranchesTVE(const int i, const else{ _V3[i-1] = V3; _D3[i-1] = D3; - Msg::Info("setting: element=%d, V3 = %e, D3 = %e",i-1,V3,D3); + // Msg::Info("setting: element=%d, V3 = %e, D3 = %e",i-1,V3,D3); } }; @@ -216,7 +219,7 @@ void mlawNonLinearTVM::setAdditionalCorrectionsAllBranchesTVE(const int i, const else{ _V3[i-1] = V3; _V4[i-1] = V4; _V5[i-1] = V5; _D3[i-1] = D3; _D4[i-1] = D4; _D5[i-1] = D5; - Msg::Info("setting: element=%d, V3 = %e, V4 = %e, V5 = %e, D3 = %e, D4 = %e, D5 = %e",i-1,V3,V4,V5,D3,D4,D5); + // Msg::Info("setting: element=%d, V3 = %e, V4 = %e, V5 = %e, D3 = %e, D4 = %e, D5 = %e",i-1,V3,V4,V5,D3,D4,D5); } }; @@ -226,7 +229,7 @@ void mlawNonLinearTVM::setCompressionCorrectionsAllBranchesTVE(const int i, cons else{ _Ci[i-1] = Ci; - Msg::Info("setting: element=%d, Ci = %e",i-1,Ci); + // Msg::Info("setting: element=%d, Ci = %e",i-1,Ci); } }; @@ -602,11 +605,12 @@ double mlawNonLinearTVM::freeEnergyMechanical(const IPNonLinearTVM& q0, IPNonLin // Therefore, to derive CTasymm, first divide to remove it and then derive. // Regularising function + /* double m = _tensionCompressionRegularisation; double expmtr = exp(-m*q._B[i]); double sigmoid = 1/(1.+expmtr); double CTasymm = sigmoid + _compCorrection*(1.-sigmoid); - double dCTasymmDtrE = m*expmtr/pow((1.+expmtr),2.)*(1.-_compCorrection); + double dCTasymmDtrE = m*expmtr/pow((1.+expmtr),2.)*(1.-_compCorrection);*/ (*DpsiDT) += (_Ki[i]*q._Av_TVE_vector[i]*q._B[i]*dTrEei_DT + 2.*_Gi[i]*q._Bd_TVE_vector[i]*STensorOperation::doubledot(q._A[i],dDevEei_DT)); // * CTasymm; @@ -620,11 +624,22 @@ double mlawNonLinearTVM::freeEnergyMechanical(const IPNonLinearTVM& q0, IPNonLin // (*DpsiDE)(j,k) += (_Ki[i]*q._intAv_TVE_vector[i] + 2.*_Gi[i]*q._intBd_TVE_vector[i])/CTasymm * dCTasymmDtrE * exp_mid_k*_I(j,k); (*DpsiDE)(j,k) += (_Ki[i]*q._DintAv_TVE_vector[i] + 2.*_Gi[i]*q._DintBd_TVE_vector[i])* exp_mid_k*_I(j,k); for (int p=0; p<3; p++) - for (int r=0; r<3; r++) + for (int r=0; r<3; r++){ (*DpsiDE)(j,k) += 2.*_Gi[i]*q._Bd_TVE_vector[i]*q._A[i](p,r)*exp_mid_g*_Idev(p,r,j,k); // * CTasymm; - } - - } + + // NEW EIGEN + if ( _useRotationCorrection == true && _rotationCorrectionScheme == 1){ + for (int l=0; l<3; l++) + for (int s=0; s<3; s++){ + (*DpsiDE)(j,k) += 2.*_Gi[i]*q._Bd_TVE_vector[i]*q._A[i](p,r)*( exp_rec_g*( q._dRdEe(p,l,j,k)*q0._A[i](l,s)*q._R(s,r) + q._R(p,l)*q0._A[i](l,s)*q._dRtdEe(s,r,j,k) ) + + exp_mid_g*( - q._dRdEe(p,l,j,k)*devEe0(l,s)*q._R(s,r) - q._R(p,l)*devEe0(l,s)*q._dRtdEe(s,r,j,k) ) ); + } + } + // NEW EIGEN + } + } // for loop + + } // if } } @@ -674,6 +689,204 @@ void mlawNonLinearTVM::corKirInfinity(const IPNonLinearTVM *q1, const STensor3& CorKirTrInf = KT*(trEe - 3*AlphaT*(T1-_Tinitial)); } +void mlawNonLinearTVM::rotationTensor_N_to_Nplus1(const STensor3& Ee00, const STensor3& Fe0, const STensor3& Fe, const STensor3& Ce, const STensor3& Ee, const STensor3& Ee0, + STensor3& R, STensor43& dRdEe, STensor43& dRtdEe) const{ + + STensorOperation::zero(R); + + // Eigenvalue check + double e1, e2, e3; + static STensor3 E1, E2, E3; + STensorOperation::getEigenDecomposition(Ee,e1,e2,e3,E1,E2,E3); + + if (_rotationCorrectionScheme == 0){ + STensorOperation::getBasisRotationTensor(Ee00,Ee0,R); // EIGEN 2 + STensorOperation::zero(dRdEe); // EIGEN 2 + STensorOperation::zero(dRtdEe); // EIGEN 2 + } + else if (_rotationCorrectionScheme == 1){ + + double pert = _perturbationfactor/1.e-5; + static STensor3 Ee_plus, R_plus; + static STensor43 dRdEe_plus, dRtdEe_plus; + /* + for(int i=0; i<3; i++) + for(int j=0; j<3; j++){ + Ee_plus = Ee; + Ee_plus(i,j) += 0.5*pert; + Ee_plus(j,i) += 0.5*pert; + STensorOperation::getBasisRotationTensor(Ee0,Ee_plus,R_plus); + + for(int k=0; k<3; k++) + for(int l=0; l<3; l++){ + dRdEe_plus(k,l,i,j) = (R_plus(k,l)-R(k,l))/pert; + dRtdEe_plus(k,l,i,j) = (R_plus(l,k)-R(l,k))/pert; + } + }*/ + /* + if (e1==e2 || e1==e3 || e2==e3){ + STensorOperation::zero(dRdEe_plus); // EIGEN 2 + STensorOperation::zero(dRtdEe_plus); // EIGEN 2 + } + else{ + STensorOperation::getBasisRotationTensor(Ee0,Ee,R,dRdEe_plus,dRtdEe_plus); + }*/ + + STensorOperation::getBasisRotationTensor(Ee0,Ee,R,dRdEe_plus,dRtdEe_plus); // R rotates the bases of Ee0 to that of E + dRdEe = dRdEe_plus; + dRtdEe = dRtdEe_plus; + } + + // static STensor3 Ue, Re, Ue0, Re0, Vp0, Vp, Rp0, Rp; + // static STensor43 dEedFe, dEedCe, dRedEe; + // mlawNonLinearTVM::getdRedEe(Fe,Ce,dEedFe,dEedCe,Ue,Re,dRedEe); + // STensorOperation::VRDecomposition(Fe0,Vp0,Rp0); //EIGEN 2 - remove + // STensorOperation::VRDecomposition(Fe,Vp,Rp); //EIGEN 2 - remove + // STensorOperation::RUDecomposition(Fe0,Ue0,Re0); +} + +void mlawNonLinearTVM::getdRedEe(const STensor3& Fe, const STensor3& Ce, const STensor43& dEedFe, const STensor43& dEedCe, + STensor3& Ue, STensor3& Re, STensor43& dRedEe) const{ + STensorOperation::zero(Re); + STensorOperation::zero(Ue); + STensorOperation::RUDecomposition(Fe,Ue,Re); + + static STensor43 dFedEe, dCedEe; + STensorOperation::inverseSTensor43(dEedFe,dFedEe); + STensorOperation::inverseSTensor43(dEedCe,dCedEe); + + static STensor43 dFedFe; + STensorOperation::zero(dFedFe); + for(int i=0; i<3; i++) + for(int j=0; j<3; j++) + for(int k=0; k<3; k++) + for(int l=0; l<3; l++) + dFedFe(i,j,k,l) += _I(i,k)*_I(j,l); + + static STensor3 Ueinv; + STensorOperation::inverseSTensor3(Ue,Ueinv); + static STensor43 dUedCe, dUeinvdCe; + mlawNonLinearTVM::getdUedCe(Ce,Ue,dUedCe); + for (int i=0; i<3; i++) + for (int s=0; s<3; s++) + for (int k=0; k<3; k++) + for (int l=0; l<3; l++){ + dUeinvdCe(i,s,k,l) = 0.; + for (int m=0; m<3; m++) + for (int j=0; j<3; j++) + dUeinvdCe(i,s,k,l) -= Ueinv(i,m)*dUedCe(m,j,k,l)*Ueinv(j,s); + } + + static STensor43 dUeinvdEe; + STensorOperation::multSTensor43(dUeinvdCe,dCedEe,dUeinvdEe); + + STensorOperation::zero(dRedEe); + for(int i=0; i<3; i++) + for(int j=0; j<3; j++) + for(int k=0; k<3; k++) + for(int l=0; l<3; l++) + for(int r=0; r<3; r++) + dRedEe(i,j,k,l) += dFedEe(i,r,k,l)*Ueinv(r,j) + Fe(i,r)*dUeinvdEe(r,j,k,l); + +} +void mlawNonLinearTVM::getdUedCe(const STensor3& Ce, const STensor3& Ue, STensor43& dUedCe) const{ + + double c1,c2,c3,x1,x2,x3; // eigenvalues + static STensor3 C1,C2,C3,E1,E2,E3; // bases + static STensor3 dc1da,dc2da,dc3da,dx1da,dx2da,dx3da; // eigenvalue derivatives + static STensor43 dC1da,dC2da,dC3da,dE1da,dE2da,dE3da; // bases derivatives + + STensorOperation::getEigenDecomposition(Ce,c1,c2,c3,C1,C2,C3,dc1da,dc2da,dc3da,dC1da,dC2da,dC3da); + STensorOperation::getEigenDecomposition(Ue,x1,x2,x3,E1,E2,E3,dx1da,dx2da,dx3da,dE1da,dE2da,dE3da); + + static STensor43 dCedCe; + STensorOperation::zero(dCedCe); + STensorOperation::zero(dUedCe); + for(int i=0; i<3; i++) + for(int j=0; j<3; j++) + for(int k=0; k<3; k++) + for(int l=0; l<3; l++){ + dCedCe(i,j,k,l) += dc1da(i,j)*C1(k,l) + dc2da(i,j)*C2(k,l) + dc3da(i,j)*C3(k,l) + c1*dC1da(i,j,k,l) + c2*dC2da(i,j,k,l) + c3*dC3da(i,j,k,l); // Should be equal to _I4 + dUedCe(i,j,k,l) += dx1da(i,j)*E1(k,l) + dx2da(i,j)*E2(k,l) + dx3da(i,j)*E3(k,l) + x1*dE1da(i,j,k,l) + x2*dE2da(i,j,k,l) + x3*dE3da(i,j,k,l); + } + + static STensor43 check; + check = dCedCe; + check -= _I4; +} + +void mlawNonLinearTVM::getdEe0dEe(const STensor3& Ce, const STensor3& Ee, const STensor3& Ee0, STensor43& dEe0sdEe) const{ + + // Ee0 becomes Ee0_star expressed in the same configuration as Ee + + double e01,e02,e03,c1,c2,c3; // eigenvalues + static STensor3 E01,E02,E03,C1,C2,C3; // bases + static STensor3 dc1da,dc2da,dc3da; // eigenvalue derivatives + static STensor43 dC1da,dC2da,dC3da; // bases derivatives + + STensorOperation::getEigenDecomposition(Ee0,e01,e02,e03,E01,E02,E03); + STensorOperation::getEigenDecomposition(Ce,c1,c2,c3,C1,C2,C3,dc1da,dc2da,dc3da,dC1da,dC2da,dC3da); + + // ##### + // Align the eigenVals of Ee0 with Ee + static fullMatrix<double> m1(3, 3), m2(3, 3); + static fullVector<double> eigenValReal1(3), eigenValReal2(3), AlignedEigenValReal1(3); + static fullVector<double> eigenValImag1(3), eigenValImag2(3); + static fullMatrix<double> leftEigenVect1(3,3), leftEigenVect2(3,3); + static fullMatrix<double> rightEigenVect1(3,3), rightEigenVect2(3,3), AlignedRightEigenVect1(3,3); + m1.setAll(0.); m2.setAll(0.); + eigenValReal1.setAll(0.); eigenValReal2.setAll(0.); AlignedEigenValReal1.setAll(0.); + eigenValImag1.setAll(0.); eigenValImag2.setAll(0.); + leftEigenVect1.setAll(0.); leftEigenVect2.setAll(0.); + rightEigenVect1.setAll(0.); rightEigenVect2.setAll(0.); AlignedRightEigenVect1.setAll(0.); + + // Get eigen values and vectors + Ee0.getMat(m1); Ee.getMat(m2); + m1.eig(eigenValReal1,eigenValImag1,leftEigenVect1,rightEigenVect1,false); + m2.eig(eigenValReal2,eigenValImag2,leftEigenVect2,rightEigenVect2,false); + + // for printing - Debug + e01 = eigenValReal1(0); + e02 = eigenValReal1(1); + e03 = eigenValReal1(2); + + // Make sure rightEigenVect1 is aligned with rightEigenVect2 + STensorOperation::alignEigenDecomposition_NormBased(Ee0,Ee,eigenValReal1,eigenValReal2,rightEigenVect1,rightEigenVect2, e01, e02, e03, AlignedRightEigenVect1); + // eigenValReal1 = AlignedEigenValReal1; + rightEigenVect1 = AlignedRightEigenVect1; + // e01 = AlignedEigenValReal1(0); + // e02 = AlignedEigenValReal1(1); + // e03 = AlignedEigenValReal1(2); + // ##### + + if(c1==0.) {STensorOperation::zero(dC1da);} + if(c2==0.) {STensorOperation::zero(dC2da);} + if(c3==0.) {STensorOperation::zero(dC3da);} + + static STensor43 dEe0sdCe, dCedCe; + STensorOperation::zero(dEe0sdCe); + STensorOperation::zero(dCedCe); + for(int i=0; i<3; i++) + for(int j=0; j<3; j++) + for(int k=0; k<3; k++) + for(int l=0; l<3; l++){ + dEe0sdCe(i,j,k,l) += e01*dC1da(i,j,k,l) + e02*dC2da(i,j,k,l) + e03*dC3da(i,j,k,l); + dCedCe(i,j,k,l) += dc1da(i,j)*C1(k,l) + dc2da(i,j)*C2(k,l) + dc3da(i,j)*C3(k,l) + c1*dC1da(i,j,k,l) + c2*dC2da(i,j,k,l) + c3*dC3da(i,j,k,l); // Should be equal to _I4 + } + + static STensor43 check; + check = dCedCe; + check -= _I4; + + // convert to dEe0sdEe + static STensor3 Ee2, exp_Ee2; + static STensor43 dCedEe; + STensorOperation::zero(dCedEe); + Ee2 = Ee; + Ee2 *= 2; + STensorOperation::expSTensor3(Ee2,_order,exp_Ee2,&dCedEe); + STensorOperation::multSTensor43(dEe0sdCe,dCedEe,dEe0sdEe); +} void mlawNonLinearTVM::evaluateElasticCorrection(const double trE, const STensor3 &devE, const double& T, double &A_v, double &dA_vdE, double &intA, double &dAdT, @@ -1132,67 +1345,6 @@ void mlawNonLinearTVM::extraBranch_nonLinearTVE(const int i, const STensor3& Ee, // Msg::Error(" Inside extraBranch_nonLinearTVE Type 4, _D1 = 0. or _D4 = 0., incompatibility with Mullin's effect"); } } - /*else if (_ExtraBranch_TVE_option == 5){ - - // Sigmoid + Exponential + Tension-Compression Asymmetry - // Standard form => A_v = sigmoid*a/(sqrt(b*tr*tr+c)) + (1-sigmoid)* Comp* (a/(sqrt(b*tr*tr+c)) + d*exp(f*tr*tr+g)) - - // Regularising function - double m = _tensionCompressionRegularisation; - double expmtr = exp(-m*tr); - // if (exp(-m*tr)<1.e+10){ expmtr = exp(-m*tr);} - double sigmoid = 1/(1.+expmtr); - - // Av - double x1 = _V1[i]*tr*tr + _V2[i]; - double x2 = _V4[i]*tr*tr + _V5[i]; - Av = sigmoid*(getVolumeCorrection()/sqrt(x1)) + (1-sigmoid)*_Ci[i]*(getVolumeCorrection()/sqrt(x1) + _V3[i]*exp(x2)); - - dA_dTrEe = sigmoid*(-getVolumeCorrection()*_V1[i]*tr/pow(x1,1.5)) + (1.-sigmoid)*_Ci[i]*( -getVolumeCorrection()*_V1[i]*tr/pow(x1,1.5) + 2*_V3[i]*_V4[i]*tr*exp(x2)) - + (m*expmtr/pow((1.+expmtr),2.))*getVolumeCorrection()*1./sqrt(x1) - (m*expmtr/pow((1.+expmtr),2.))*_Ci[i]*(getVolumeCorrection()/sqrt(x1) + _V3[i]*exp(x2)) ; - - if(_V1[i]>0. && _V4[i]>0.){ - double integrand1 = 1./_V1[i]*sqrt(x1); // integral of A_v * trEe - integrand1 -= ( 1./_V1[i]*sqrt(_V2[i]) ); // value at trEe = 0. - integrand1 *= getVolumeCorrection(); - - double integrand2 = exp(x2)/(2*_V4[i]); - integrand2 -= exp(_V5[i])/(2*_V4[i]); - integrand2 *= _V3[i]; - - intA = sigmoid*integrand1 + (1.-sigmoid)*_Ci[i]*(integrand1 + integrand2); - } - else{ - intA = 1.; - } - - // Bd - double y1 = _D1[i]*dev.dotprod() + _D2[i]; - double y2 = _D4[i]*dev.dotprod() + _D5[i]; - Bd = sigmoid*(getDevCorrection()/sqrt(y1)) + (1-sigmoid)*_Ci[i]*(getDevCorrection()/sqrt(y1) + _D3[i]*exp(y2)); - - STensorOperation::zero(dB_dDevEe); - dB_dDevEe = dev; - dB_dDevEe *= ( sigmoid*(-getDevCorrection()*_D1[i]/pow(y1,1.5)) + (1.-sigmoid)*_Ci[i]*( -getDevCorrection()*_D1[i]/pow(y1,1.5) + 2*_D3[i]*_D4[i]*exp(y2)) ); - - if(dB_dTrEe!=NULL){ - *dB_dTrEe = (m*expmtr/pow((1.+expmtr),2.))*getDevCorrection()*1./sqrt(y1) - (m*expmtr/pow((1.+expmtr),2.))*_Ci[i]*(getDevCorrection()/sqrt(y1) + _D3[i]*exp(y2)); - } - if(_D1[i]>0. && _D4[i]>0.){ - double integrand1 = 1./_D1[i]*sqrt(y1); // integral of B_d * devEe - integrand1 -= (1./_D1[i]*sqrt(_D2[i]) ); // value at devEe = 0. - integrand1 *= getDevCorrection(); - - double integrand2 = exp(y2)/(2*_D4[i]); - integrand2 -= exp(_D5[i])/(2*_D4[i]); - integrand2 *= _D3[i]; - - intB = sigmoid*integrand1 + (1.-sigmoid)*_Ci[i]*(integrand1 + integrand2); - } - else{ - intB = 1.; - } - }*/ else if (_ExtraBranch_TVE_option == 5){ // Tension-Compression Asymmetry @@ -1207,25 +1359,28 @@ void mlawNonLinearTVM::extraBranch_nonLinearTVE(const int i, const STensor3& Ee, // Av double x1 = _V1[i]*tr*tr + _V2[i]; - double x2 = _V4[i]*tr*tr + _V5[i]; - Av = sigmoid*(1./sqrt(x1)+ _V3[i]*(1+tanh(x2))) + (1.-sigmoid)*(_Ci[i]*(1./sqrt(x1) + _V3[i])); + double x2 = _V4[i]*tr*tr; + Av = sigmoid*(1./sqrt(x1)+ _V3[i]*(_V5[i]+tanh(x2))) + (1.-sigmoid)*(_Ci[i]*(1./sqrt(x1) + _V0[i])); + // Av = sigmoid*(1./sqrt(x1)+_V0[i]) + (1.-sigmoid)*_Ci[i]*(1/sqrt(x2)+_V3[i]); -> Type4 // Av *= getVolumeCorrection(); dA_dTrEe = -sigmoid*(_V1[i]*tr/pow(x1,1.5) - _V3[i]*(2*_V4[i]*tr*pow(1/cosh(x2),2))) - (1.-sigmoid)*(_V1[i]*_Ci[i]*tr/pow(x1,1.5)) - + (m*expmtr/pow((1.+expmtr),2.))*(1./sqrt(x1) + _V3[i]*(1+tanh(x2)))- (_Ci[i]*m*expmtr/pow((1.+expmtr),2.))*(1./sqrt(x1) + _V3[i]); + + (m*expmtr/pow((1.+expmtr),2.))*(1./sqrt(x1) + _V3[i]*(_V5[i]+tanh(x2)))- (_Ci[i]*m*expmtr/pow((1.+expmtr),2.))*(1./sqrt(x1) + _V0[i]); // dA_dTrEe *= getVolumeCorrection(); if(_V1[i]>0.){ - double integrand1 = 1./_V1[i]*sqrt(x1) + _V3[i]*tr*tr/2.; // integral of A_v * trEe + double integrand1 = 1./_V1[i]*sqrt(x1) + _V3[i]*_V5[i]*tr*tr/2.; // integral of A_v * trEe double integrand2 = 0.; + double integrand3 = 1./_V1[i]*sqrt(x1) + _V0[i]*tr*tr/2.; if(_V4[i] != 0.){ integrand2 = _V3[i]/(2.*_V4[i])*log(cosh(x2)); } integrand1 -= ( 1./_V1[i]*sqrt(_V2[i]) ); // value at trEe = 0. - intA = sigmoid*(integrand1 + integrand2) + _Ci[i]*(1.-sigmoid)*integrand1; + integrand3 -= ( 1./_V1[i]*sqrt(_V2[i]) ); // value at trEe = 0. + intA = sigmoid*(integrand1 + integrand2) + _Ci[i]*(1.-sigmoid)*integrand3; // intA *= getVolumeCorrection(); - DintA = (m*expmtr/pow((1.+expmtr),2.))*integrand1 - _Ci[i]*(m*expmtr/pow((1.+expmtr),2.))*integrand2; + DintA = (m*expmtr/pow((1.+expmtr),2.))*(integrand1 + integrand2) - _Ci[i]*(m*expmtr/pow((1.+expmtr),2.))*integrand3; } else{ intA = 1.; @@ -1233,8 +1388,8 @@ void mlawNonLinearTVM::extraBranch_nonLinearTVE(const int i, const STensor3& Ee, // Bd double y1 = _D1[i]*dev.dotprod() + _D2[i]; - double y2 = _D4[i]*dev.dotprod() + _D5[i]; - Bd = sigmoid* (1./sqrt(y1) + _D3[i]*(1+tanh(y2))) + (1.-sigmoid)*(_Ci[i]*(1./sqrt(y1) + _D3[i])) ; + double y2 = _D4[i]*dev.dotprod(); + Bd = sigmoid* (1./sqrt(y1) + _D3[i]*(_D5[i] + tanh(y2))) + (1.-sigmoid)*(_Ci[i]*(1./sqrt(y1) + _D0[i])) ; // Bd *= getDevCorrection(); STensorOperation::zero(dB_dDevEe); @@ -1243,20 +1398,22 @@ void mlawNonLinearTVM::extraBranch_nonLinearTVE(const int i, const STensor3& Ee, // dB_dDevEe *= getDevCorrection(); if(dB_dTrEe!=NULL){ - *dB_dTrEe = (m*expmtr/pow((1.+expmtr),2.))*(1./sqrt(y1) + _D3[i]*(1+tanh(y2))) - (m*expmtr/pow((1.+expmtr),2.))*(_Ci[i]*(1./sqrt(y1) + _D3[i])); + *dB_dTrEe = (m*expmtr/pow((1.+expmtr),2.))*(1./sqrt(y1) + _D3[i]*(_D5[i] + tanh(y2))) - (m*expmtr/pow((1.+expmtr),2.))*(_Ci[i]*(1./sqrt(y1) + _D0[i])); // *dB_dTrEe *= getDevCorrection(); } if(_D1[i]>0.){ - double integrand1 = 1./_D1[i]*sqrt(y1) + _D3[i]*dev.dotprod()/2.; // integral of B_d * devEe + double integrand1 = 1./_D1[i]*sqrt(y1) + _D3[i]*_D5[i]*dev.dotprod()/2.; // integral of B_d * devEe double integrand2 = 0.; + double integrand3 = 1./_D1[i]*sqrt(y1) + _D0[i]*dev.dotprod()/2.; if(_D4[i] != 0.){ integrand2 = _D3[i]/(2.*_D4[i])*log(cosh(y2)); } integrand1 -= (1./_D1[i]*sqrt(_D2[i]) ); // value at devEe = 0. - intB = sigmoid*(integrand1 + integrand2) + _Ci[i]*(1.-sigmoid)*integrand1; + integrand3 -= (1./_D1[i]*sqrt(_D2[i]) ); // value at devEe = 0. + intB = sigmoid*(integrand1 + integrand2) + _Ci[i]*(1.-sigmoid)*integrand3; // intB *= getDevCorrection(); - DintB = (m*expmtr/pow((1.+expmtr),2.))*integrand1 - _Ci[i]*(m*expmtr/pow((1.+expmtr),2.))*integrand2; + DintB = (m*expmtr/pow((1.+expmtr),2.))*(integrand1 + integrand2) - _Ci[i]*(m*expmtr/pow((1.+expmtr),2.))*integrand3; } else{ intB = 1.; @@ -1301,7 +1458,7 @@ void mlawNonLinearTVM::extraBranch_nonLinearTVE(const int i, const STensor3& Ee, void mlawNonLinearTVM::ThermoViscoElasticPredictor(const STensor3& Ee, const STensor3& Ee0, const IPNonLinearTVM *q0, IPNonLinearTVM *q1, - double& Ke, double& Ge, double& DKDTsum, double& DGDTsum, + double& Ke, double& Ge, const double T0, const double T1, const bool stiff, STensor43& Bd_stiffnessTerm, STensor43* Bd_stiffnessTerm2) const{ // NEW @@ -1345,7 +1502,6 @@ void mlawNonLinearTVM::ThermoViscoElasticPredictor(const STensor3& Ee, const STe // Initialise Moduli Ke = KT; Ge = GT; - DKDTsum = DKDT; DGDTsum = DGDT; if(_useExtraBranch){ @@ -1457,11 +1613,9 @@ void mlawNonLinearTVM::ThermoViscoElasticPredictor(const STensor3& Ee, const STe // Ge for DcorKirDE Ge += _Gi[i]*exp_mid_g; // 2* (..) - Dont multiply by 2 if using lambda and mu in Hooks tensor function - DGDTsum += -_Gi[i]/(_gi[i])*Ddt_shiftDT_mid*exp_mid_g; // Ke for DcorKirDE Ke += _Ki[i]*exp_mid_k; - DKDTsum += -_Ki[i]/(_ki[i])*Ddt_shiftDT_mid*exp_mid_k; // Single Convolution for (int k=0; k<3; k++) @@ -1490,12 +1644,10 @@ void mlawNonLinearTVM::ThermoViscoElasticPredictor(const STensor3& Ee, const STe // Ge for DcorKirDE Ge += ( exp_mid_g *_Gi[i] * q0->_Bd_TVE ); // 2* (..) - Dont multiply by 2 if using lambda and mu in Hooks tensor function - DGDTsum += ( -_Gi[i]/(_gi[i])*Ddt_shiftDT_mid*exp_mid_g ); // Ke for DcorKirDE Ke += ( exp_mid_k *_Ki[i] * Av ) ; Ke += ( exp_mid_k *_Ki[i]* q0->_B[i]/Av * dA_dTrEe ); - DKDTsum += (-_Ki[i]/(_ki[i])*Ddt_shiftDT_mid*exp_mid_k); // Single Convolution double temp2(0.); @@ -2454,18 +2606,42 @@ void mlawNonLinearTVM::predictorCorrector_ThermoViscoElastic( E *= 0.5; // strain // Stresses and Effective Moduli - double Ke(0.), Ge(0.), DKDTsum(0.), DGDTsum(0.); + double Ke(0.), Ge(0.); static STensor43 Bd_stiffnessTerm, Bd_stiffnessTerm2; STensorOperation::zero(Bd_stiffnessTerm); STensorOperation::zero(Bd_stiffnessTerm2); + + if(_extraBranchNLType == TensionCompressionRegularisedType || _extraBranchNLType == hyper_exp_TCasymm_Type || _ExtraBranch_TVE_option == 3 || _ExtraBranch_TVE_option == 4 || _ExtraBranch_TVE_option == 5){ - ThermoViscoElasticPredictor(E,q0->_Ee,q0,q1,Ke,Ge,DKDTsum,DGDTsum,T0,T,stiff,Bd_stiffnessTerm,&Bd_stiffnessTerm2); + ThermoViscoElasticPredictor(E,q0->_Ee,q0,q1,Ke,Ge,T0,T,stiff,Bd_stiffnessTerm,&Bd_stiffnessTerm2); // Updates the values of moduli to the current temperatures and calculate stresses. } else{ - ThermoViscoElasticPredictor(E,q0->_Ee,q0,q1,Ke,Ge,DKDTsum,DGDTsum,T0,T,stiff,Bd_stiffnessTerm); + ThermoViscoElasticPredictor(E,q0->_Ee,q0,q1,Ke,Ge,T0,T,stiff,Bd_stiffnessTerm); } + + static fullMatrix<double> m1(3, 3), m2(3, 3); + static fullVector<double> eigenValReal1(3), eigenValReal2(3); + static fullVector<double> eigenValImag1(3), eigenValImag2(3); + static fullMatrix<double> leftEigenVect1(3,3), leftEigenVect2(3,3); + static fullMatrix<double> rightEigenVect1(3,3), rightEigenVect2(3,3); + m1.setAll(0.); m2.setAll(0.); + eigenValReal1.setAll(0.); eigenValReal2.setAll(0.); + eigenValImag1.setAll(0.); eigenValImag2.setAll(0.); + leftEigenVect1.setAll(0.); leftEigenVect2.setAll(0.); + rightEigenVect1.setAll(0.); rightEigenVect2.setAll(0.); + + // Get eigen values and vectors + q1->_kirchhoff.getMat(m1); C.getMat(m2); + m1.eig(eigenValReal1,eigenValImag1,leftEigenVect1,rightEigenVect1,false); + m2.eig(eigenValReal2,eigenValImag2,leftEigenVect2,rightEigenVect2,false); + + double eig1, eig2, eig3, eig10,eig20,eig30; + static STensor3 E1,E2,E3,E10,E20,E30; + STensorOperation::getEigenDecomposition(q1->_kirchhoff,eig1,eig2,eig3,E1,E2,E3); + STensorOperation::getEigenDecomposition(C,eig10,eig20,eig30,E10,E20,E30); + // additional hyperelastic branch - NOt necessary anymore // NEW /* @@ -2485,17 +2661,51 @@ void mlawNonLinearTVM::predictorCorrector_ThermoViscoElastic( STensorOperation::decomposeDevTr(corKir,devT,pT); q1->_pressure = pT/3.; - static STensor3 secondPK; // , Ceinv, Me, temp1_Me, temp2_Me; - /* - STensorOperation::inverseSTensor3(C,Ceinv); - STensorOperation::multSTensor3(C, q1->_kirchhoff, temp1_Me); - STensorOperation::multSTensor3(temp1_Me, Ceinv, temp2_Me); - Me = 0.5*(q1->_kirchhoff + temp2_Me); - STensorOperation::multSTensor3(Ceinv,Me,secondPK);*/ - + static STensor3 secondPK; STensorOperation::multSTensor3STensor43(q1->_kirchhoff,dlnCdC,secondPK); STensorOperation::multSTensor3(F,secondPK,P); // 1st PK + static STensor3 M; + STensorOperation::multSTensor3(C,secondPK,M); + q1->_ModMandel = M; + + // commuteChecker -> for commuting tensors Ce and Se, Me has to be symmetric -> + // For two cases, both in the case of viscoplasticity if Een and Ee dont share eigenvectors: 1. Due to plasticity (Rp) 2. Due to non-proportional loading + static STensor3 commuteChecker, MT; + STensorOperation::transposeSTensor3(M,MT); + commuteChecker = M; + commuteChecker -= MT; + q1->_mandelCommuteChecker = commuteChecker.norm0(); + if(q1->_mandelCommuteChecker > 1.e-6){ + // Msg::Error("Mandel does not commute in mlawNonLinearTVM, norm = %e, tol = %e !!",q1->_mandelCommuteChecker,1.e-6); + } + + // + + // check + /* + double Ke_new, Ge_new; + static STensor3 Ee0_rot, R, secondPK_new, Me_new; + static STensor43 dRdEe, dRtdEe, Bd_stiffnessTerm_new, Bd_stiffnessTerm2_new; + mlawNonLinearTVM::rotationTensor_N_to_Nplus1(E,q0->_Ee,R,dRdEe,dRtdEe); + for(int i=0; i<3; i++) + for(int j=0; j<3; j++){ + Ee0_rot(i,j) = 0.; + for(int k=0; k<3; k++) + for(int l=0; l<3; l++) + Ee0_rot(i,j) += R(i,k)*q0->_Ee(k,l)*R(j,l); + } + + static IPNonLinearTVM q1_test(*q0); + if(_extraBranchNLType == TensionCompressionRegularisedType || _extraBranchNLType == hyper_exp_TCasymm_Type || _ExtraBranch_TVE_option == 3 || _ExtraBranch_TVE_option == 4 || _ExtraBranch_TVE_option == 5){ + ThermoViscoElasticPredictor(E,Ee0_rot,q0,&q1_test,Ke,Ge,T0,T,stiff,Bd_stiffnessTerm_new,&Bd_stiffnessTerm2_new); + } + else{ + ThermoViscoElasticPredictor(E,Ee0_rot,q0,&q1_test,Ke,Ge,T0,T,stiff,Bd_stiffnessTerm2_new); + } + STensorOperation::multSTensor3STensor43(q1_test._kirchhoff,dlnCdC,secondPK_new); + STensorOperation::multSTensor3(C,secondPK_new,Me_new);*/ + // elastic energy and derivatives double& Dpsi_DT = q1->getRefTo_Dpsi_DT(); STensor3& Dpsi_DE = q1->getRefTo_Dpsi_DE(); @@ -2784,12 +2994,12 @@ void mlawNonLinearTVM::predictorCorrector_ThermoViscoElastic( } } } - // dmechanicalSourceE += dWmdE_TVE; // TVE term + dmechanicalSourceE += dWmdE_TVE; // TVE term STensorOperation::multSTensor3STensor43(dmechanicalSourceE,DEeDFe,dmechanicalSourceF); dmechanicalSourcedT += (STensorOperation::doubledot(DcorKirDT,DEe)/this->getTimeStep()); dmechanicalSourcedT += T*(STensorOperation::doubledot(DDcorKirDT,DEe)/this->getTimeStep()); - // dmechanicalSourcedT += dWmdT_TVE; // TVE term + dmechanicalSourcedT += dWmdT_TVE; // TVE term } // Compute Tangents for Mullin's Effect @@ -2839,10 +3049,325 @@ void mlawNonLinearTVM::predictorCorrector_ThermoViscoElastic( } }; -void mlawNonLinearTVM::ThermoViscoElasticPredictor_forTVP(const STensor3& Ee, const STensor3& Ee0, - const IPNonLinearTVM *q0, IPNonLinearTVM *q1, - double& Ke, double& Ge, - const double T0, const double T1, const bool stiff, STensor43& Bd_stiffnessTerm, STensor43* Bd_stiffnessTerm2) const{ +void mlawNonLinearTVM::getEe0s(const STensor3& Ce, const STensor3& Ee, const STensor3& Ee0, STensor3& Ee0s, STensor43& dEe0sdEe) const{ + + // Ee0 becomes Ee0_star expressed in the same configuration as Ee + + double e01,e02,e03, e1,e2,e3, c1,c2,c3; // eigenvalues + static STensor3 E01,E02,E03,E1,E2,E3,C1,C2,C3; // bases + static STensor3 dc1da,dc2da,dc3da; // eigenvalue derivatives + static STensor43 dC1da,dC2da,dC3da; // bases derivatives + + STensorOperation::getEigenDecomposition(Ee0,e01,e02,e03,E01,E02,E03); + STensorOperation::getEigenDecomposition(Ee,e1,e2,e3,E1,E2,E3); + STensorOperation::getEigenDecomposition(Ce,c1,c2,c3,C1,C2,C3,dc1da,dc2da,dc3da,dC1da,dC2da,dC3da); + + // ##### + // Align the eigenVals of Ee0 with Ee + static fullMatrix<double> m1(3, 3), m2(3, 3); + static fullVector<double> eigenValReal1(3), eigenValReal2(3), AlignedEigenValReal1(3); + static fullVector<double> eigenValImag1(3), eigenValImag2(3); + static fullMatrix<double> leftEigenVect1(3,3), leftEigenVect2(3,3); + static fullMatrix<double> rightEigenVect1(3,3), rightEigenVect2(3,3), AlignedRightEigenVect1(3,3); + m1.setAll(0.); m2.setAll(0.); + eigenValReal1.setAll(0.); eigenValReal2.setAll(0.); AlignedEigenValReal1.setAll(0.); + eigenValImag1.setAll(0.); eigenValImag2.setAll(0.); + leftEigenVect1.setAll(0.); leftEigenVect2.setAll(0.); + rightEigenVect1.setAll(0.); rightEigenVect2.setAll(0.); AlignedRightEigenVect1.setAll(0.); + + // Get eigen values and vectors + Ee0.getMat(m1); Ce.getMat(m2); + m1.eig(eigenValReal1,eigenValImag1,leftEigenVect1,rightEigenVect1,false); + m2.eig(eigenValReal2,eigenValImag2,leftEigenVect2,rightEigenVect2,false); + + // for printing - Debug + e01 = eigenValReal1(0); + e02 = eigenValReal1(1); + e03 = eigenValReal1(2); + + // Make sure rightEigenVect1 is aligned with rightEigenVect2 + STensorOperation::alignEigenDecomposition_NormBased(Ee0,Ce,eigenValReal1,eigenValReal2,rightEigenVect1,rightEigenVect2, e01, e02, e03, AlignedRightEigenVect1); + rightEigenVect1 = AlignedRightEigenVect1; + // ##### + + if(c1==0.) {STensorOperation::zero(dC1da);} + if(c2==0.) {STensorOperation::zero(dC2da);} + if(c3==0.) {STensorOperation::zero(dC3da);} + + static STensor43 dEe0sdCe, dCedCe; + STensorOperation::zero(dEe0sdCe); + STensorOperation::zero(dCedCe); + STensorOperation::zero(Ee0s); + for(int i=0; i<3; i++) + for(int j=0; j<3; j++){ + Ee0s(i,j) += e01*C1(i,j) + e02*C2(i,j) + e03*C3(i,j); + for(int k=0; k<3; k++) + for(int l=0; l<3; l++){ + dEe0sdCe(i,j,k,l) += e01*dC1da(i,j,k,l) + e02*dC2da(i,j,k,l) + e03*dC3da(i,j,k,l); + dCedCe(i,j,k,l) += dc1da(i,j)*C1(k,l) + dc2da(i,j)*C2(k,l) + dc3da(i,j)*C3(k,l) + c1*dC1da(i,j,k,l) + c2*dC2da(i,j,k,l) + c3*dC3da(i,j,k,l); // Should be equal to _I4 + } + } + + static STensor43 check; + check = dCedCe; + check -= _I4; + + // convert to dEe0sdEe + static STensor3 Ee2, exp_Ee2; + static STensor43 dCedEe; + STensorOperation::zero(dCedEe); + Ee2 = Ee; + Ee2 *= 2; + STensorOperation::expSTensor3(Ee2,_order,exp_Ee2,&dCedEe); + STensorOperation::multSTensor43(dEe0sdCe,dCedEe,dEe0sdEe); +} + +void mlawNonLinearTVM::getEe0s2(const STensor3& Ce, const STensor3& Ee, const STensor3& Ee0, int& index1, int& index2, int& index3, STensor3& Ee0s, STensor43& dEe0sdEe) const{ + + // Ee0 becomes Ee0_star expressed in the same configuration as Ee + + static fullVector<double> eigenValReal1(3); eigenValReal1.setAll(0.); + double e01,e02,e03,e1,e2,e3; // eigenvalues + static STensor3 E01,E02,E03,E1,E2,E3; // bases + static STensor3 de1da,de2da,de3da; // eigenvalue derivatives + static STensor43 dE1da,dE2da,dE3da; // bases derivatives + STensorOperation::getEigenDecomposition(Ee0,e01,e02,e03,E01,E02,E03); + eigenValReal1(0) = e01; eigenValReal1(1) = e02; eigenValReal1(2) = e03; + + + double det = STensorOperation::determinantSTensor3(Ee); + if(det!=0.){ + STensorOperation::getEigenDecomposition(Ee,e1,e2,e3,E1,E2,E3,de1da,de2da,de3da,dE1da,dE2da,dE3da); + + // Make sure rightEigenVect1 is aligned with rightEigenVect2 + // STensorOperation::alignEigenDecomposition_NormBased(Ee0,Ee,eigenValReal1,eigenValReal2,rightEigenVect1,rightEigenVect2, e01, e02, e03, AlignedRightEigenVect1); + // rightEigenVect1 = AlignedRightEigenVect1; + // STensorOperation::alignEigenDecomposition_EigenVectorDotProductBased(eigenValReal1,eigenValReal2,rightEigenVect1,rightEigenVect2, e01, e02, e03, AlignedRightEigenVect1); + STensorOperation::alignEigenDecomposition_NormBased(Ee0,Ee,e1,e2,e3,E1,E2,E3,eigenValReal1,index1,index2,index3,e01,e02,e03); + + + static STensor43 dEedEe; + STensorOperation::zero(dEe0sdEe); + STensorOperation::zero(dEedEe); + STensorOperation::zero(Ee0s); + for(int i=0; i<3; i++) + for(int j=0; j<3; j++){ + Ee0s(i,j) += e01*E1(i,j) + e02*E2(i,j) + e03*E3(i,j); + for(int k=0; k<3; k++) + for(int l=0; l<3; l++){ + dEe0sdEe(i,j,k,l) += e01*dE1da(i,j,k,l) + e02*dE2da(i,j,k,l) + e03*dE3da(i,j,k,l); + dEedEe(i,j,k,l) += de1da(i,j)*E1(k,l) + de2da(i,j)*E2(k,l) + de3da(i,j)*E3(k,l) + e1*dE1da(i,j,k,l) + e2*dE2da(i,j,k,l) + e3*dE3da(i,j,k,l); // Should be equal to _I4 + } + } + + static STensor43 check; + check = dEedEe; + check -= _I4; + } + else{ + STensorOperation::zero(de1da); STensorOperation::zero(de2da); STensorOperation::zero(de3da); STensorOperation::zero(dE1da); STensorOperation::zero(dE2da); STensorOperation::zero(dE3da); + Ee0s=Ee0; + } + +} + +void mlawNonLinearTVM::getAi0s2(const STensor3& Ce, const STensor3& Ee, const std::vector<STensor3>& Ai0, std::vector<STensor3>& Ai0s, std::vector<STensor43>& dAi0sdEe) const{ + + // Ee0 becomes Ee0_star expressed in the same configuration as Ee + + double e01,e02,e03,e1,e2,e3; // eigenvalues + static STensor3 E01,E02,E03,E1,E2,E3; // bases + static STensor3 de1da,de2da,de3da; // eigenvalue derivatives + static STensor43 dE1da,dE2da,dE3da; // bases derivatives + + double det = STensorOperation::determinantSTensor3(Ee); + if(det!=0.){ + STensorOperation::getEigenDecomposition(Ee,e1,e2,e3,E1,E2,E3,de1da,de2da,de3da,dE1da,dE2da,dE3da); + } + else{ + STensorOperation::zero(de1da); STensorOperation::zero(de2da); STensorOperation::zero(de3da); STensorOperation::zero(dE1da); STensorOperation::zero(dE2da); STensorOperation::zero(dE3da); + } + + + // ##### + // Align the eigenVals of Ee0 with Ee + static fullMatrix<double> m1(3, 3), m2(3, 3); + static fullVector<double> eigenValReal1(3), eigenValReal2(3), AlignedEigenValReal1(3); + static fullVector<double> eigenValImag1(3), eigenValImag2(3); + static fullMatrix<double> leftEigenVect1(3,3), leftEigenVect2(3,3); + static fullMatrix<double> rightEigenVect1(3,3), rightEigenVect2(3,3), AlignedRightEigenVect1(3,3); + m1.setAll(0.); m2.setAll(0.); + eigenValReal1.setAll(0.); eigenValReal2.setAll(0.); AlignedEigenValReal1.setAll(0.); + eigenValImag1.setAll(0.); eigenValImag2.setAll(0.); + leftEigenVect1.setAll(0.); leftEigenVect2.setAll(0.); + rightEigenVect1.setAll(0.); rightEigenVect2.setAll(0.); AlignedRightEigenVect1.setAll(0.); + + // Get eigen values and vectors + Ee.getMat(m2); m2.eig(eigenValReal2,eigenValImag2,leftEigenVect2,rightEigenVect2,false); + + // Loop + for (int i=0; i<_Gi.size(); i++){ + + // Get eigen values and vectors + m1.setAll(0.); eigenValReal1.setAll(0.); eigenValImag1.setAll(0.); leftEigenVect1.setAll(0.); rightEigenVect1.setAll(0.); AlignedRightEigenVect1.setAll(0.); + STensorOperation::getEigenDecomposition(Ai0[i],e01,e02,e03,E01,E02,E03); + Ai0[i].getMat(m1); + m1.eig(eigenValReal1,eigenValImag1,leftEigenVect1,rightEigenVect1,false); + + + // eigenvalues + e01 = eigenValReal1(0); + e02 = eigenValReal1(1); + e03 = eigenValReal1(2); + + // Make sure rightEigenVect1 is aligned with rightEigenVect2 + STensorOperation::alignEigenDecomposition_NormBased(Ai0[i],Ee,eigenValReal1,eigenValReal2,rightEigenVect1,rightEigenVect2, e01, e02, e03, AlignedRightEigenVect1); + // STensorOperation::alignEigenDecomposition_EigenVectorDotProductBased(eigenValReal1,eigenValReal2,rightEigenVect1,rightEigenVect2, e01, e02, e03, AlignedRightEigenVect1); + rightEigenVect1 = AlignedRightEigenVect1; + + STensorOperation::zero(dAi0sdEe[i]); + // STensorOperation::zero(dCedCe); + STensorOperation::zero(Ai0s[i]); + for(int p=0; p<3; p++) + for(int j=0; j<3; j++){ + Ai0s[i](p,j) += e01*E1(p,j) + e02*E2(p,j) + e03*E3(p,j); + for(int k=0; k<3; k++) + for(int l=0; l<3; l++){ + dAi0sdEe[i](p,j,k,l) += e01*dE1da(p,j,k,l) + e02*dE2da(p,j,k,l) + e03*dE3da(p,j,k,l); + // dCedCe(p,j,k,l) += dc1da(p,j)*C1(k,l) + dc2da(p,j)*C2(k,l) + dc3da(p,j)*C3(k,l) + c1*dC1da(p,j,k,l) + c2*dC2da(p,j,k,l) + c3*dC3da(p,j,k,l); // Should be equal to _I4 + } + } + } +} + +void mlawNonLinearTVM::getAi0s2(const STensor3& Ce, const STensor3& Ee, const int& index1, const int& index2, const int& index3, + const std::vector<STensor3>& Ai0, std::vector<STensor3>& Ai0s, std::vector<STensor43>& dAi0sdEe) const{ + + // Ee0 becomes Ee0_star expressed in the same configuration as Ee + + static fullVector<double> eigenValReal1(3); eigenValReal1.setAll(0.); + double e01_s,e02_s,e03_s,e01,e02,e03,e1,e2,e3; // eigenvalues + static STensor3 E01,E02,E03,E1,E2,E3; // bases + static STensor3 de1da,de2da,de3da; // eigenvalue derivatives + static STensor43 dE1da,dE2da,dE3da; // bases derivatives + + double det = STensorOperation::determinantSTensor3(Ee); + if(det!=0.){ + STensorOperation::getEigenDecomposition(Ee,e1,e2,e3,E1,E2,E3,de1da,de2da,de3da,dE1da,dE2da,dE3da); + + // Loop + for (int i=0; i<_Gi.size(); i++){ + + // Assign + STensorOperation::getEigenDecomposition(Ai0[i],e01,e02,e03,E01,E02,E03); + eigenValReal1(0) = e01; eigenValReal1(1) = e02; eigenValReal1(2) = e03; + + // Reassign + e01_s = eigenValReal1(index1); e02_s = eigenValReal1(index2); e03_s = eigenValReal1(index3); + + STensorOperation::zero(dAi0sdEe[i]); + // STensorOperation::zero(dEedEe); + STensorOperation::zero(Ai0s[i]); + for(int p=0; p<3; p++) + for(int j=0; j<3; j++){ + Ai0s[i](p,j) += e01_s*E1(p,j) + e02_s*E2(p,j) + e03_s*E3(p,j); + for(int k=0; k<3; k++) + for(int l=0; l<3; l++){ + dAi0sdEe[i](p,j,k,l) += e01_s*dE1da(p,j,k,l) + e02_s*dE2da(p,j,k,l) + e03_s*dE3da(p,j,k,l); + // dEedEe(p,j,k,l) += de1da(p,j)*E1(k,l) + de2da(p,j)*E2(k,l) + de3da(p,j)*E3(k,l) + e1*dE1da(p,j,k,l) + e2*dE2da(p,j,k,l) + e3*dE3da(p,j,k,l); // Should be equal to _I4 + } + } + } + + } + else{ + STensorOperation::zero(de1da); STensorOperation::zero(de2da); STensorOperation::zero(de3da); STensorOperation::zero(dE1da); STensorOperation::zero(dE2da); STensorOperation::zero(dE3da); + } +} + +void mlawNonLinearTVM::get_Ee0s_Ai0s_ders(const STensor3& Ce, const STensor3& Ee, const STensor3& Ee0, const std::vector<STensor3>& Ai0, const fullVector<int>& alignedIndex, + STensor3& Ee0s, STensor43& dEe0sdEe, std::vector<STensor3>& Ai0s, std::vector<STensor43>& dAi0sdEe) const{ + + // Ee0 becomes Ee0_star expressed in the same configuration as Ee, Ai0 becomes Ai0s + + static fullVector<double> eigenValReal1(3); eigenValReal1.setAll(0.); + double e01,e02,e03,ai1,ai2,ai3,e1,e2,e3; // eigenvalues + double e01_s,e02_s,e03_s,ai1_s,ai2_s,ai3_s; // eigenvalues_rotated + static STensor3 E01,E02,E03,Ai1,Ai2,Ai3,E1,E2,E3; // bases + static STensor3 de1da,de2da,de3da; // eigenvalue derivatives + static STensor43 dE1da,dE2da,dE3da; // bases derivatives + + STensorOperation::getEigenDecomposition(Ee0,e01,e02,e03,E01,E02,E03); + + double det = STensorOperation::determinantSTensor3(Ee); + if(det!=0.){ + STensorOperation::getEigenDecomposition(Ee,e1,e2,e3,E1,E2,E3,de1da,de2da,de3da,dE1da,dE2da,dE3da); + + // Align Ee0 and get its derivative + + // Assign + STensorOperation::getEigenDecomposition(Ee0,e01,e02,e03,E01,E02,E03); + eigenValReal1(0) = e01; eigenValReal1(1) = e02; eigenValReal1(2) = e03; + + // Reassign aligned eigVal + e01_s = eigenValReal1(alignedIndex(0)); e02_s = eigenValReal1(alignedIndex(1)); e03_s = eigenValReal1(alignedIndex(2)); + + static STensor43 dEedEe; + STensorOperation::zero(dEe0sdEe); + STensorOperation::zero(dEedEe); + STensorOperation::zero(Ee0s); + for(int i=0; i<3; i++) + for(int j=0; j<3; j++){ + Ee0s(i,j) += e01_s*E1(i,j) + e02_s*E2(i,j) + e03_s*E3(i,j); + for(int k=0; k<3; k++) + for(int l=0; l<3; l++){ + dEe0sdEe(i,j,k,l) += e01_s*dE1da(i,j,k,l) + e02_s*dE2da(i,j,k,l) + e03_s*dE3da(i,j,k,l); + dEedEe(i,j,k,l) += de1da(i,j)*E1(k,l) + de2da(i,j)*E2(k,l) + de3da(i,j)*E3(k,l) + e1*dE1da(i,j,k,l) + e2*dE2da(i,j,k,l) + e3*dE3da(i,j,k,l); // Should be equal to _I4 + } + } + + static STensor43 check; + check = dEedEe; + check -= _I4; + + // Loop + for (int i=0; i<_Gi.size(); i++){ + + // Assign + STensorOperation::getEigenDecomposition(Ai0[i],ai1,ai2,ai3,Ai1,Ai2,Ai3); + eigenValReal1(0) = ai1; eigenValReal1(1) = ai2; eigenValReal1(2) = ai3; + + // Reassign aligned eigVal + ai1_s = eigenValReal1(alignedIndex(0)); ai2_s = eigenValReal1(alignedIndex(1)); ai3_s = eigenValReal1(alignedIndex(2)); + + STensorOperation::zero(Ai0s[i]); + STensorOperation::zero(dAi0sdEe[i]); + for(int p=0; p<3; p++) + for(int j=0; j<3; j++){ + Ai0s[i](p,j) += ai1_s*E1(p,j) + ai2_s*E2(p,j) + ai3_s*E3(p,j); + for(int k=0; k<3; k++) + for(int l=0; l<3; l++) + dAi0sdEe[i](p,j,k,l) += ai1_s*dE1da(p,j,k,l) + ai2_s*dE2da(p,j,k,l) + ai3_s*dE3da(p,j,k,l); + } + } + + } + else{ + STensorOperation::zero(de1da); STensorOperation::zero(de2da); STensorOperation::zero(de3da); STensorOperation::zero(dE1da); STensorOperation::zero(dE2da); STensorOperation::zero(dE3da); + STensorOperation::zero(dEe0sdEe); + Ee0s = Ee0; + for (int i=0; i<_Gi.size(); i++){ + Ai0s[i] = Ai0[i]; + STensorOperation::zero(dAi0sdEe[i]); + } + } +} + +void mlawNonLinearTVM::ThermoViscoElasticPredictor_forTVP(const STensor3& Ce, const STensor3& Ee, const STensor3& Ee0, + const IPNonLinearTVM *q0, IPNonLinearTVM *q1, double& Ke, double& Ge, const double T0, const double T1, + const bool stiff, const fullVector<int>& alignedIndex, STensor43& Bd_stiffnessTerm, STensor43* Bd_stiffnessTerm2, STensor43* rotationStiffness) const{ + + // Caution!! -> For _rotationCorrectionScheme == 0 and 1, Ee0 is already rotated. _R and its derivatives are in the IP // STensorOperation::zero(Bd_stiffnessTerm); @@ -2850,6 +3375,50 @@ void mlawNonLinearTVM::ThermoViscoElasticPredictor_forTVP(const STensor3& Ee, co if(Bd_stiffnessTerm2!= NULL){ STensorOperation::zero(*Bd_stiffnessTerm2); } + + // NEW EIGEN + static STensor3 devEe0, devEe0s; double trEe0; + STensorOperation::zero(devEe0s); + STensorOperation::decomposeDevTr(q0->_Ee,devEe0,trEe0); + + static STensor43 dDevEe0sdEe; + STensorOperation::zero(dDevEe0sdEe); + std::vector<STensor43> rotationDer1, rotationDer2, dAi0sdEe; + rotationDer1.clear(); rotationDer2.clear(); dAi0sdEe.clear(); + for (int i=0; i<_Gi.size(); i++){ + STensor43 el43(0.); + dAi0sdEe.push_back(el43); + rotationDer1.push_back(el43); + rotationDer2.push_back(el43); + } + + if (_rotationCorrectionScheme == 0 && _rotationCorrectionScheme == 1){ + if ((_Ki.size() > 0) or (_Gi.size() > 0)){ + for (int i=0; i<_Gi.size(); i++){ + for(int k=0; k<3; k++) + for(int l=0; l<3; l++){ + q1->_A_rot[i](k,l) = 0.; + for(int p=0; p<3; p++) + for(int q=0; q<3; q++) + q1->_A_rot[i](k,l) += q1->_R(k,p)*q0->_A[i](p,q)*q1->_R(l,q); + } + } + } + } + else if (_rotationCorrectionScheme == 2){ + // devEe0.print("before"); + // mlawNonLinearTVM::getEe0s2(Ce,Ee,devEe0,devEe0s,dDevEe0sdEe); + q1->_A_rot = q0->_A; + // mlawNonLinearTVM::getAi0s2(Ce,Ee,q0->_A,q1->_A_rot,dAi0sdEe); + mlawNonLinearTVM::get_Ee0s_Ai0s_ders(Ce,Ee,devEe0,q0->_A,alignedIndex,devEe0s,dDevEe0sdEe,q1->_A_rot,dAi0sdEe); + // devEe0s.print("after"); + // Msg::Error("alignedIndex = %d, %d, %d",alignedIndex(0),alignedIndex(1),alignedIndex(2)); + } + + if(rotationStiffness!= NULL){ + STensorOperation::zero(*rotationStiffness); + } + // NEW EIGEN // Set Temperature to calculate temperature updated properties double T_set = setTemp(T0,T1,1); // 1->T1, 2->T_mid, 3->T_midshift @@ -2868,6 +3437,10 @@ void mlawNonLinearTVM::ThermoViscoElasticPredictor_forTVP(const STensor3& Ee, co DE -= Ee0; STensorOperation::decomposeDevTr(DE,devDE,trDE); STensorOperation::decomposeDevTr(Ee,devEe,trEe); + if (_rotationCorrectionScheme == 2){ + devDE = devEe; + devDE -= devEe0s; + } // Initialise effective trEe - include thermal expansion double eff_trEe(0.), eff_trDE(0.); @@ -2885,7 +3458,7 @@ void mlawNonLinearTVM::ThermoViscoElasticPredictor_forTVP(const STensor3& Ee, co // Initialise Moduli Ke = KT; Ge = GT; - + if(_useExtraBranch){ double A(0.), B(0.), dA_dTrEe(0.), psiInfCorrector(0.); @@ -2992,7 +3565,8 @@ void mlawNonLinearTVM::ThermoViscoElasticPredictor_forTVP(const STensor3& Ee, co // Single Convolution for (int k=0; k<3; k++) for (int l=0; l<3; l++){ - q1->_A[i](k,l) = exp_rec_g*q0->_A[i](k,l) + exp_mid_g*devDE(k,l); + // q1->_A[i](k,l) = exp_rec_g*q0->_A[i](k,l) + exp_mid_g*devDE(k,l); + q1->_A[i](k,l) = exp_rec_g*q1->_A_rot[i](k,l) + exp_mid_g*devDE(k,l); // NEW EIGEN } q1->_B[i] = exp_rec_k*q0->_B[i] + exp_mid_k*eff_trDE ; //*trDE; NEW @@ -3002,6 +3576,39 @@ void mlawNonLinearTVM::ThermoViscoElasticPredictor_forTVP(const STensor3& Ee, co // Add to volumetric stress p += _Ki[i]*q1->_B[i]; + + // NEW EIGEN + // Add rotation derivatives + /*static STensor43 dAi0sdEe; + if (_rotationCorrectionScheme == 2){ + mlawNonLinearTVM::getdEe0dEe(Ce,Ee,q0->_A[i],dAi0sdEe); + }*/ + for (int k=0; k<3; k++) + for (int l=0; l<3; l++) + for (int p=0; p<3; p++) + for (int q=0; q<3; q++){ + if (_rotationCorrectionScheme == 2){ + rotationDer1[i](k,l,p,q) += dAi0sdEe[i](k,l,p,q); + rotationDer2[i](k,l,p,q) += (-dDevEe0sdEe(k,l,p,q)); + // (*rotationStiffness)(k,l,p,q) += 2*_Gi[i]*( exp_rec_g*dAi0sdEe(k,l,p,q) - exp_mid_g*dDevEe0sdEe(k,l,p,q) ); + } + for (int r=0; r<3; r++) + for (int s=0; s<3; s++){ + if (_rotationCorrectionScheme == 1){ + rotationDer1[i](k,l,p,q) += ( q1->_dRdEe(k,r,p,q)*q0->_A[i](r,s)*q1->_R(l,s) + q1->_R(k,r)*q0->_A[i](r,s)*q1->_dRtdEe(s,l,p,q) ); + rotationDer2[i](k,l,p,q) += ( - q1->_dRdEe(k,r,p,q)*devEe0(r,s)*q1->_R(l,s) - q1->_R(k,r)*devEe0(r,s)*q1->_dRtdEe(s,l,p,q) ) ; + /*(*rotationStiffness)(k,l,p,q) += 2*_Gi[i]*( exp_rec_g*( q1->_dRdEe(k,r,p,q)*q0->_A[i](r,s)*q1->_R(l,s) + q1->_R(k,r)*q0->_A[i](r,s)*q1->_dRtdEe(s,l,p,q) ) + + exp_mid_g*( - q1->_dRdEe(k,r,p,q)*devEe0(r,s)*q1->_R(l,s) - q1->_R(k,r)*devEe0(r,s)*q1->_dRtdEe(s,l,p,q) ) );*/ + } + } + } + for (int k=0; k<3; k++) + for (int l=0; l<3; l++) + for (int p=0; p<3; p++) + for (int q=0; q<3; q++) + (*rotationStiffness)(k,l,p,q) += 2*_Gi[i]*( exp_rec_g*rotationDer1[i](k,l,p,q) + exp_mid_g*rotationDer2[i](k,l,p,q) ); + // NEW EIGEN + } else{ // all extraBranches @@ -3041,8 +3648,10 @@ void mlawNonLinearTVM::ThermoViscoElasticPredictor_forTVP(const STensor3& Ee, co // Single Convolution - get branchElasticStrain for (int k=0; k<3; k++) - for (int l=0; l<3; l++) - q1->_A[i](k,l) = exp_rec_g*q0->_A[i](k,l) + exp_mid_g*devDE(k,l); + for (int l=0; l<3; l++){ + // q1->_A[i](k,l) = exp_rec_g*q0->_A[i](k,l) + exp_mid_g*devDE(k,l); + q1->_A[i](k,l) = exp_rec_g*q1->_A_rot[i](k,l) + exp_mid_g*devDE(k,l); // NEW EIGEN + } q1->_B[i] = exp_rec_k*q0->_B[i] + exp_mid_k*eff_trDE; // trDE; // NEW @@ -3093,6 +3702,57 @@ void mlawNonLinearTVM::ThermoViscoElasticPredictor_forTVP(const STensor3& Ee, co // Add to volumetric stress p += ( _Ki[i]*Av*q1->_B[i] ); + + // NEW EIGEN + // Add rotation derivatives + /*static STensor43 dAi0sdEe; + if (_rotationCorrectionScheme == 2){ + mlawNonLinearTVM::getdEe0dEe(Ce,Ee,q0->_A[i],dAi0sdEe); + }*/ + for (int k=0; k<3; k++) + for (int l=0; l<3; l++) + for (int p=0; p<3; p++) + for (int q=0; q<3; q++){ + if (_rotationCorrectionScheme == 2){ + rotationDer1[i](k,l,p,q) += dAi0sdEe[i](k,l,p,q); + rotationDer2[i](k,l,p,q) += (-dDevEe0sdEe(k,l,p,q)); + // (*rotationStiffness)(k,l,p,q) += 2*_Gi[i]*Bd*( exp_rec_g*dAi0sdEe(k,l,p,q) - exp_mid_g*dDevEe0sdEe(k,l,p,q) ); + } + for (int r=0; r<3; r++) + for (int s=0; s<3; s++){ + if (_rotationCorrectionScheme == 1){ + rotationDer1[i](k,l,p,q) += ( q1->_dRdEe(k,r,p,q)*q0->_A[i](r,s)*q1->_R(l,s) + q1->_R(k,r)*q0->_A[i](r,s)*q1->_dRtdEe(s,l,p,q) ); + rotationDer2[i](k,l,p,q) += ( - q1->_dRdEe(k,r,p,q)*devEe0(r,s)*q1->_R(l,s) - q1->_R(k,r)*devEe0(r,s)*q1->_dRtdEe(s,l,p,q) ) ; + /*(*rotationStiffness)(k,l,p,q) += 2.*_Gi[i]*Bd*( exp_rec_g*( q1->_dRdEe(k,r,p,q)*q0->_A[i](r,s)*q1->_R(l,s) + q1->_R(k,r)*q0->_A[i](r,s)*q1->_dRtdEe(s,l,p,q) ) + + exp_mid_g*( - q1->_dRdEe(k,r,p,q)*devEe0(r,s)*q1->_R(l,s) - q1->_R(k,r)*devEe0(r,s)*q1->_dRtdEe(s,l,p,q) ) );*/ + } + + if (_rotationCorrectionScheme == 2){ + // Ignore this term - ADDED on 20/06 + // (*rotationStiffness)(k,l,p,q) += 2.*_Gi[i]*q1->_A[i](k,l)*dB_dDevEe(r,s) * ( exp_rec_g*dAi0sdEe[i](r,s,p,q) - exp_mid_g*dDevEe0sdEe(r,s,p,q) ); + } + for (int m=0; m<3; m++) + for (int n=0; n<3; n++){ + if (_rotationCorrectionScheme == 1){ + // Ignore this term - ADDED on 20/06 + /*(*rotationStiffness)(k,l,p,q) += 2.*_Gi[i]*q1->_A[i](k,l)*dB_dDevEe(r,s) * (exp_rec_g*( q1->_dRdEe(r,m,p,q)*q0->_A[i](m,n)*q1->_R(s,n) + q1->_R(r,m)*q0->_A[i](m,n)*q1->_dRtdEe(n,s,p,q) ) + + exp_mid_g*( - q1->_dRdEe(r,m,p,q)*devEe0(m,n)*q1->_R(s,n) - q1->_R(r,m)*devEe0(m,n)*q1->_dRtdEe(n,s,p,q) ));*/ + } + } + } + } + + for (int k=0; k<3; k++) + for (int l=0; l<3; l++) + for (int r=0; r<3; r++) + for (int s=0; s<3; s++){ + (*rotationStiffness)(k,l,r,s) += 2*_Gi[i]*Bd*( exp_rec_g*rotationDer1[i](k,l,r,s) + exp_mid_g*rotationDer2[i](k,l,r,s) ); + for (int p=0; p<3; p++) + for (int q=0; q<3; q++){ + (*rotationStiffness)(k,l,r,s) += 2.*_Gi[i]*q1->_A[i](k,l)*dB_dDevEe(p,q)*( exp_rec_g*rotationDer1[i](p,q,r,s) + exp_mid_g*rotationDer2[i](p,q,r,s) ); + } + } + // NEW EIGEN } } // all extrabranches @@ -3158,6 +3818,15 @@ void mlawNonLinearTVM::ThermoViscoElasticPredictor_forTVP(const STensor3& Ee, co // _Idev is pre-multiplied !! DA_DdevE[i](k,l,r,s) = exp_mid_g*_Idev(k,l,r,s); DDA_DTDdevE[i](k,l,r,s) = Dexp_mid_g_DT*_Idev(k,l,r,s); + + // NEW EIGEN + if ( _useRotationCorrection == true){ + if(_rotationCorrectionScheme == 1 && _rotationCorrectionScheme == 2){ + DA_DdevE[i](k,l,r,s) += ( exp_rec_g*rotationDer1[i](k,l,r,s) + exp_mid_g*rotationDer2[i](k,l,r,s) ); + DDA_DTDdevE[i](k,l,r,s) += ( Dexp_rec_g_DT*rotationDer1[i](k,l,r,s) + Dexp_mid_g_DT*rotationDer2[i](k,l,r,s) ); + } + } + // NEW EIGEN } } } @@ -3234,6 +3903,18 @@ void mlawNonLinearTVM::ThermoViscoElasticPredictor_forTVP(const STensor3& Ee, co for (int p=0; p<3; p++) for (int q=0; q<3; q++){ DDA_DTDdevE[i](k,l,r,s) += exp_mid_g * q1->_dBd_dDevEe_TVE_vector[i](p,q)*dDevEei_DT(p,q)*_I4(k,l,r,s); + + + // NEW EIGEN + if ( _useRotationCorrection == true){ + if(_rotationCorrectionScheme == 1 && _rotationCorrectionScheme == 2){ + DA_DdevE[i](k,l,r,s) += ( q1->_A[i](k,l)*q1->_dBd_dDevEe_TVE_vector[i](p,q) + q1->_Bd_TVE_vector[i] * _I4(k,l,p,q) ) * + ( exp_rec_g*rotationDer1[i](p,q,r,s) + exp_mid_g*rotationDer2[i](p,q,r,s) ); + DDA_DTDdevE[i](k,l,r,s) += ( q1->_A[i](k,l)*q1->_dBd_dDevEe_TVE_vector[i](p,q) + q1->_Bd_TVE_vector[i] * _I4(k,l,p,q) ) * + ( Dexp_rec_g_DT*rotationDer1[i](p,q,r,s) + Dexp_mid_g_DT*rotationDer2[i](p,q,r,s) ); + } + } + // NEW EIGEN } } } @@ -3342,6 +4023,91 @@ double mlawNonLinearTVM::soundSpeed() const { // Correct this for current temp return sqrt((_K+4.*_G/3.)/_rho); } +void mlawNonLinearTVM::getAi0s(const STensor3& Ce, const STensor3& Ee, const std::vector<STensor3>& Ai0, std::vector<STensor3>& Ai0s, std::vector<STensor43>& dAi0sdEe) const{ + + // Ee0 becomes Ee0_star expressed in the same configuration as Ee + + double e01,e02,e03, e1,e2,e3, c1,c2,c3; // eigenvalues + static STensor3 E01,E02,E03,E1,E2,E3,C1,C2,C3; // bases + static STensor3 dc1da,dc2da,dc3da; // eigenvalue derivatives + static STensor43 dC1da,dC2da,dC3da; // bases derivatives + + STensorOperation::getEigenDecomposition(Ee,e1,e2,e3,E1,E2,E3); + STensorOperation::getEigenDecomposition(Ce,c1,c2,c3,C1,C2,C3,dc1da,dc2da,dc3da,dC1da,dC2da,dC3da); + if(c1==0.) {STensorOperation::zero(dC1da);} + if(c2==0.) {STensorOperation::zero(dC2da);} + if(c3==0.) {STensorOperation::zero(dC3da);} + + + // ##### + // Align the eigenVals of Ee0 with Ee + static fullMatrix<double> m1(3, 3), m2(3, 3); + static fullVector<double> eigenValReal1(3), eigenValReal2(3), AlignedEigenValReal1(3); + static fullVector<double> eigenValImag1(3), eigenValImag2(3); + static fullMatrix<double> leftEigenVect1(3,3), leftEigenVect2(3,3); + static fullMatrix<double> rightEigenVect1(3,3), rightEigenVect2(3,3), AlignedRightEigenVect1(3,3); + m1.setAll(0.); m2.setAll(0.); + eigenValReal1.setAll(0.); eigenValReal2.setAll(0.); AlignedEigenValReal1.setAll(0.); + eigenValImag1.setAll(0.); eigenValImag2.setAll(0.); + leftEigenVect1.setAll(0.); leftEigenVect2.setAll(0.); + rightEigenVect1.setAll(0.); rightEigenVect2.setAll(0.); AlignedRightEigenVect1.setAll(0.); + + // Get eigen values and vectors + Ce.getMat(m2); m2.eig(eigenValReal2,eigenValImag2,leftEigenVect2,rightEigenVect2,false); + + // conversion tensor to dEe0sdEe + static STensor3 Ee2, exp_Ee2; + static STensor43 dCedEe; + STensorOperation::zero(dCedEe); + Ee2 = Ee; + Ee2 *= 2; + STensorOperation::expSTensor3(Ee2,_order,exp_Ee2,&dCedEe); + + // Loop + for (int i=0; i<_Gi.size(); i++){ + + // Get eigen values and vectors + m1.setAll(0.); eigenValReal1.setAll(0.); eigenValImag1.setAll(0.); leftEigenVect1.setAll(0.); rightEigenVect1.setAll(0.); AlignedRightEigenVect1.setAll(0.); + STensorOperation::getEigenDecomposition(Ai0[i],e01,e02,e03,E01,E02,E03); + Ai0[i].getMat(m1); + m1.eig(eigenValReal1,eigenValImag1,leftEigenVect1,rightEigenVect1,false); + + + // eigenvalues + e01 = eigenValReal1(0); + e02 = eigenValReal1(1); + e03 = eigenValReal1(2); + + // Make sure rightEigenVect1 is aligned with rightEigenVect2 + STensorOperation::alignEigenDecomposition_NormBased(Ai0[i],Ce,eigenValReal1,eigenValReal2,rightEigenVect1,rightEigenVect2, e01, e02, e03, AlignedRightEigenVect1); + rightEigenVect1 = AlignedRightEigenVect1; + + static STensor43 dAi0sdCe; // , dCedCe; + STensorOperation::zero(dAi0sdCe); + // STensorOperation::zero(dCedCe); + STensorOperation::zero(Ai0s[i]); + for(int p=0; p<3; p++) + for(int j=0; j<3; j++){ + Ai0s[i](p,j) += e01*C1(p,j) + e02*C2(p,j) + e03*C3(p,j); + for(int k=0; k<3; k++) + for(int l=0; l<3; l++){ + dAi0sdCe(p,j,k,l) += e01*dC1da(p,j,k,l) + e02*dC2da(p,j,k,l) + e03*dC3da(p,j,k,l); + // dCedCe(p,j,k,l) += dc1da(p,j)*C1(k,l) + dc2da(p,j)*C2(k,l) + dc3da(p,j)*C3(k,l) + c1*dC1da(p,j,k,l) + c2*dC2da(p,j,k,l) + c3*dC3da(p,j,k,l); // Should be equal to _I4 + } + } + + // debug + STensorOperation::getEigenDecomposition(Ai0s[i],e01,e02,e03,E01,E02,E03); + + /* + static STensor43 check; + check = dCedCe; + check -= _I4;*/ + + STensorOperation::multSTensor43(dAi0sdCe,dCedEe,dAi0sdEe[i]); + } +} + // Older definition of non-linear mechSrc /* void mlawNonLinearTVM::getMechSource_nonLinearTVE_term(const IPNonLinearTVM *q0, IPNonLinearTVM *q1, const double& T0, const double& T, diff --git a/NonLinearSolver/materialLaw/mlawNonLinearTVM.h b/NonLinearSolver/materialLaw/mlawNonLinearTVM.h index 245bf095e0800c64167a3399bab7340f385fc247..7d73767c0408284fe6bb1d36490c25e83f2d17e3 100644 --- a/NonLinearSolver/materialLaw/mlawNonLinearTVM.h +++ b/NonLinearSolver/materialLaw/mlawNonLinearTVM.h @@ -62,6 +62,8 @@ class mlawNonLinearTVM : public mlawPowerYieldHyper{ elasticPotential* _elasticPotential; bool _useExtraBranch; bool _useExtraBranch_TVE; + bool _useRotationCorrection; + int _rotationCorrectionScheme; int _ExtraBranch_TVE_option; scalarFunction* _temFunc_elasticCorrection_Bulk; scalarFunction* _temFunc_elasticCorrection_Shear; @@ -117,15 +119,29 @@ class mlawNonLinearTVM : public mlawPowerYieldHyper{ void corKirInfinity(const IPNonLinearTVM *q1, const STensor3& devEe, const double& trEe, const double T, STensor3& CorKirDevInf, double& CorKirTrInf) const; + void rotationTensor_N_to_Nplus1(const STensor3& Ee00, const STensor3& Fe0, const STensor3& Fe, const STensor3& Ce, const STensor3& Ee, const STensor3& Ee0, + STensor3& R, STensor43& dRdEe, STensor43& dRtdEe) const; + + void getdRedEe(const STensor3& Fe, const STensor3& Ce, const STensor43& dEedFe, const STensor43& dEedCe, STensor3& Ue, STensor3& Re, STensor43& dRedEe) const; + void getdUedCe(const STensor3& Ce, const STensor3& Ue, STensor43& dUedCe) const; + void getEe0s(const STensor3& Ce, const STensor3& Ee, const STensor3& Ee0, STensor3& Ee0s, STensor43& dEe0sdEe) const; + void getAi0s(const STensor3& Ce, const STensor3& Ee, const std::vector<STensor3>& Ai0, std::vector<STensor3>& Ai0s, std::vector<STensor43>& dAi0sdEe) const; + + void getEe0s2(const STensor3& Ce, const STensor3& Ee, const STensor3& Ee0, int& index1, int& index2, int& index3, STensor3& Ee0s, STensor43& dEe0sdEe) const; + void getAi0s2(const STensor3& Ce, const STensor3& Ee, const std::vector<STensor3>& Ai0, std::vector<STensor3>& Ai0s, std::vector<STensor43>& dAi0sdEe) const; + void getAi0s2(const STensor3& Ce, const STensor3& Ee, const int& index1, const int& index2, const int& index3, const std::vector<STensor3>& Ai0, std::vector<STensor3>& Ai0s, std::vector<STensor43>& dAi0sdEe) const; + void getdEe0dEe(const STensor3& Ce, const STensor3& Ee, const STensor3& Ee0, STensor43& dEe0sdEe) const; + void get_Ee0s_Ai0s_ders(const STensor3& Ce, const STensor3& Ee, const STensor3& Ee0, const std::vector<STensor3>& Ai0, const fullVector<int>& alignedIndex, + STensor3& Ee0s, STensor43& dEe0sdEe, std::vector<STensor3>& Ai0s, std::vector<STensor43>& dAi0sdEe) const; + void ThermoViscoElasticPredictor(const STensor3& Ee, const STensor3& Ee0, - const IPNonLinearTVM *q0, IPNonLinearTVM *q1, - double& Ke, double& Ge, double& DKDTsum, double& DGDTsum, - const double T0, const double T1, const bool stiff, STensor43& Bd_stiffnessTerm, STensor43* Bd_stiffnessTerm2 = NULL) const; - - void ThermoViscoElasticPredictor_forTVP(const STensor3& Ee, const STensor3& Ee0, const IPNonLinearTVM *q0, IPNonLinearTVM *q1, double& Ke, double& Ge, const double T0, const double T1, const bool stiff, STensor43& Bd_stiffnessTerm, STensor43* Bd_stiffnessTerm2 = NULL) const; + + void ThermoViscoElasticPredictor_forTVP(const STensor3& Ce, const STensor3& Ee, const STensor3& Ee0, + const IPNonLinearTVM *q0, IPNonLinearTVM *q1, double& Ke, double& Ge, const double T0, const double T1, + const bool stiff, const fullVector<int>& alignedIndex, STensor43& Bd_stiffnessTerm, STensor43* Bd_stiffnessTerm2 = NULL, STensor43* rotationStiffness = NULL) const; void isotropicHookTensor(const double K, const double G, STensor43& L) const; @@ -214,6 +230,8 @@ class mlawNonLinearTVM : public mlawPowerYieldHyper{ virtual void useExtraBranchBool(const bool useExtraBranch){_useExtraBranch = useExtraBranch;}; virtual void useExtraBranchBool_TVE(const bool useExtraBranch_TVE, const int ExtraBranch_TVE_option){ _useExtraBranch_TVE = useExtraBranch_TVE; _ExtraBranch_TVE_option = ExtraBranch_TVE_option;}; + virtual void useRotationCorrectionBool(const bool useRotationCorrection, const int rotationCorrectionScheme){_useRotationCorrection = useRotationCorrection; + _rotationCorrectionScheme = rotationCorrectionScheme;}; void setTemperatureFunction_BulkModulus(const scalarFunction& Tfunc){ if (_temFunc_K != NULL) delete _temFunc_K; _temFunc_K = Tfunc.clone(); diff --git a/NonLinearSolver/materialLaw/mlawNonLinearTVP.cpp b/NonLinearSolver/materialLaw/mlawNonLinearTVP.cpp index 8c38474fb3228fbdaa1fe44c6cb93371ab87fa3e..0b0191953c5d0a561c9bdcbaf53255f873826972 100644 --- a/NonLinearSolver/materialLaw/mlawNonLinearTVP.cpp +++ b/NonLinearSolver/materialLaw/mlawNonLinearTVP.cpp @@ -471,7 +471,7 @@ void mlawNonLinearTVP::getMechSourceTVP(const STensor3& F0, const STensor3& F, const double& gamma0 = q0->_epspbarre; const double& gamma1 = q1->_epspbarre; const STensor3& Fp1 = q1->_Fp; - const STensor3& Me = q1->_ModMandel; + const STensor3& Me = q1->_kirchhoff; // q1->_ModMandel; // debug const STensor3& X = q1->_backsig; const STensor3& dXdT = q1->_DbackSigDT; const STensor43& dXdF = q1->_DbackSigDF; @@ -920,7 +920,7 @@ void mlawNonLinearTVP::predictorCorrector_TVP_nonAssociatedFlow(const STensor3& double DKe, DGe = 0.; double DKde, DGde = 0.; double DKDTsum, DGDTsum = 0.; static STensor43 Bd_stiffnessTerm; // ThermoViscoElasticPredictor(Ee,q0->_Ee,q0,q1,Ke,Ge,Kde,Gde,DKe,DGe,DKde,DGde,KTsum,GTsum,DKDTsum,DGDTsum,T0,T); - mlawNonLinearTVM::ThermoViscoElasticPredictor(Ee,q0->_Ee,q0,q1,Ke,Ge,DKDTsum,DGDTsum,T0,T,stiff,Bd_stiffnessTerm); + mlawNonLinearTVM::ThermoViscoElasticPredictor(Ee,q0->_Ee,q0,q1,Ke,Ge,T0,T,stiff,Bd_stiffnessTerm); mlawNonLinearTVM::getTVEdCorKirDT(q0,q1,T0,T); // additional branch - update predictor @@ -1257,10 +1257,10 @@ void mlawNonLinearTVP::predictorCorrector_TVP_nonAssociatedFlow(const STensor3& Ee *= 0.5; // Correct A, B - // ThermoViscoElasticPredictor(Ee,q0->_Ee,q0,q1,Ke,Ge,Kde,Gde,DKe,DGe,DKde,DGde,KTsum,GTsum,DKDTsum,DGDTsum,T0,T); //,false); - mlawNonLinearTVM::ThermoViscoElasticPredictor(Ee,q0->_Ee,q0,q1,Ke,Ge,DKDTsum,DGDTsum,T0,T,stiff,Bd_stiffnessTerm); //,false); + // ThermoViscoElasticPredictor(Ee,q0->_Ee,q0,q1,Ke,Ge,Kde,Gde,DKe,DGe,DKde,DGde,KTsum,GTsum,DKDTsum,DGDTsum,T0,T); //,false); - DEPRECATED + mlawNonLinearTVM::ThermoViscoElasticPredictor(Ee,q0->_Ee,q0,q1,Ke,Ge,T0,T,stiff,Bd_stiffnessTerm); //,false); mlawNonLinearTVM::getTVEdCorKirDT(q0,q1,T0,T); // update dCorKirdT - don't do this probably - // DKDTsum and DGDTsum = sum of bulk/shear moduli derivatives wrt T + // DKDTsum and DGDTsum = sum of bulk/shear moduli derivatives wrt T - DEPRECATED // Correct Extrabranch - update stress if (_useExtraBranch){ @@ -1417,7 +1417,7 @@ void mlawNonLinearTVP::predictorCorrector_TVP_nonAssociatedFlow(const STensor3& } // 2) Viscoelastic Contribution to mechSrc - // mlawNonLinearTVE::getMechSourceTVE(q0,q1,T0,T,DKDTsum,DGDTsum,_I4,&Wm_TVE); // mechSourceTVE + // mlawNonLinearTVE::getMechSourceTVE(q0,q1,T0,T,_I4,&Wm_TVE); // mechSourceTVE double& dWmdT_TVE = q1->getRefTodMechSrcTVEdT(); STensor3& dWmdF_TVE = q1->getRefTodMechSrcTVEdF(); static STensor3 dWmdE_TVE; @@ -2904,11 +2904,11 @@ void mlawNonLinearTVP::predictorCorrector_TVP_AssociatedFlow(const STensor3& F, // update A, B // double Ge, Ke; - double Ke, Ge = 0.; double Kde, Gde = 0.; double KTsum, GTsum = 0.; - double DKe, DGe = 0.; double DKde, DGde = 0.; double DKDTsum, DGDTsum = 0.; + double Ke(0.), Ge(0.); + double DKDTsum, DGDTsum = 0.; // Deprecated static STensor43 Bd_stiffnessTerm; // ThermoViscoElasticPredictor(Ee,q0->_Ee,q0,q1,Ke,Ge,Kde,Gde,DKe,DGe,DKde,DGde,KTsum,GTsum,DKDTsum,DGDTsum,T0,T); - ThermoViscoElasticPredictor(Ee,q0->_Ee,q0,q1,Ke,Ge,DKDTsum,DGDTsum,T0,T,stiff,Bd_stiffnessTerm); + ThermoViscoElasticPredictor(Ee,q0->_Ee,q0,q1,Ke,Ge,T0,T,stiff,Bd_stiffnessTerm); static STensor3 devKpr; // dev corotational kirchoff stress predictor static double ppr; // pressure predictor @@ -3088,7 +3088,7 @@ void mlawNonLinearTVP::predictorCorrector_TVP_AssociatedFlow(const STensor3& F, // // ThermoViscoElasticPredictor(Ee,q0->_Ee,q0,q1,Ke,Ge,Kde,Gde,DKe,DGe,DKde,DGde,KTsum,GTsum,DKDTsum,DGDTsum,T0,T,false); - ThermoViscoElasticPredictor(Ee,q0->_Ee,q0,q1,Ke,Ge,DKDTsum,DGDTsum,T0,T,false,Bd_stiffnessTerm); + ThermoViscoElasticPredictor(Ee,q0->_Ee,q0,q1,Ke,Ge,T0,T,false,Bd_stiffnessTerm); } else{ q1->getRefToDissipationActive() = false; diff --git a/NonLinearSolver/materialLaw/mullinsEffect.cpp b/NonLinearSolver/materialLaw/mullinsEffect.cpp index 50ec2a4da39a0777d63dcd795314f19fe9937c33..8cc2aeaa3e65c83f8b31dc7f69362a104a662f38 100644 --- a/NonLinearSolver/materialLaw/mullinsEffect.cpp +++ b/NonLinearSolver/materialLaw/mullinsEffect.cpp @@ -100,140 +100,87 @@ void negativeExponentialScaler::mullinsEffectScaling(double _psi0, double _psi, // at unloading intitiation-> eta = 1.; unloading end-> eta = eta_min; reloading -> eta = eta_min; - double eta0 = ipvprev.getEta(); - double _psi_max0 = ipvprev.getpsiMax(); - double psi_cap = _psi; - double eta = 1., DetaDpsi_cap = 0., DDetaDpsipsi = 0., DetaDT = 0., DDetaDTT = 0.; - double DpsiNew_DpsiMax(0.), DDpsiNew_DpsiMaxDpsi(0.), DDpsiNew_DpsiMaxDT(0.); - - double _psi_max = std::max(_psi,_psi_max0); - // Msg::Error(" Inside mullinsEffectScaling, _psi = %e, _psi_max = %e !!", _psi, _psi_max); - - double Dpsi_maxDpsi_cap = 1.; // Dpsi_maxDpsi_cap = 1. if _psi_max = _psi - double Term = sqrt(_m*(_psi_max-eta*psi_cap)); // Term = 0. if _psi_max = _psi - - if (Term!=0){ - - int ite = 0; - int maxite = 100; - double _tol = 1e-8; - double DfDeta(0.), Deta(0.); - double f = eta + _r*(1-exp(-Term)) - 1.; - - while (fabs(f) >_tol or ite <1){ - - DfDeta = 1 + _r*(-_m*psi_cap*exp(-Term)/(2*Term)); - Deta = - f/DfDeta; - - if (eta + Deta > 1.){ - eta = 0.99; // NR - } - else - eta += Deta; - - // eta += Deta; - // Msg::Error(" Inside iterator, ite = %d, f = %e, DfDeta = %e, Deta = %e, eta = %e !!", ite, f, DfDeta, Deta, eta); - - Term = sqrt(_m*(_psi_max-eta*psi_cap)); - f = eta + _r*(1-exp(-Term)) - 1.; - - ite++; - if (fabs(f) <_tol) break; - - if(ite > maxite){ - // Msg::Error("No convergence for eta in mullinsEffectScaling: ite= %d, f = %e!!",ite,f); - eta = sqrt(-1.); - return; - } - } - - Dpsi_maxDpsi_cap = 0.; - - DetaDpsi_cap = (-_r*_m*exp(-Term)/(2*Term)) * (Dpsi_maxDpsi_cap - eta) / (1 - _r*_m*exp(-Term)/(2*Term)*psi_cap); - } - else{ - eta = 1.; - DetaDpsi_cap = 0.; - } + double r = _r; + double m = _m; - ipv.set(eta,DetaDpsi_cap,DDetaDpsipsi,DetaDT,DDetaDTT,DpsiNew_DpsiMax, DDpsiNew_DpsiMaxDpsi, DDpsiNew_DpsiMaxDT); - ipv.setPsiMax(_psi_max); + double eta0 = ipvprev.getEta(); + double _psi_max0 = ipvprev.getpsiMax(); + double psi_cap = _psi; + double eta = 1., DetaDpsi_cap = 0., DDetaDpsipsi = 0., DetaDT = 0., DDetaDTT = 0.; + double DpsiNew_DpsiMax(0.), DDpsiNew_DpsiMaxDpsi(0.), DDpsiNew_DpsiMaxDT(0.); + double Dpsi_max_Dpsi_cap(0.), Dpsi_max_DT(0.); + + double _psi_max = std::max(_psi,_psi_max0); + // Msg::Error(" Inside mullinsEffectScaling, _psi = %e, _psi_max = %e !!", _psi, _psi_max); + + if (_psi_max>0.){ + + // eta + double temp = m*(_psi_max-psi_cap); + eta = (1-r*sqrt(tanh(temp))); + + // derivatives + if (psi_cap >= _psi_max){ + Dpsi_max_Dpsi_cap = 1.; + } + + DetaDpsi_cap = m*r/2.*pow( 1/cosh(temp) ,2)/sqrt(tanh(temp)) * (1- Dpsi_max_Dpsi_cap); + + double DetaDpsi_max = -m*r/2.*pow( 1/cosh(temp) ,2)/sqrt(tanh(temp)); + DpsiNew_DpsiMax = r*( sqrt(tanh(temp)) - sqrt(tanh(m*_psi_max)) ); // definition + DDpsiNew_DpsiMaxDpsi = DetaDpsi_max + r*m/2.*(pow( 1/cosh(temp) ,2)/sqrt(tanh(temp)) - pow( 1/cosh(m*_psi_max) ,2)/sqrt(tanh(m*_psi_max)) ) * Dpsi_max_Dpsi_cap; + } + + ipv.set(eta,DetaDpsi_cap,DDetaDpsipsi,DetaDT,DDetaDTT,DpsiNew_DpsiMax, DDpsiNew_DpsiMaxDpsi, DDpsiNew_DpsiMaxDT); + ipv.setPsiMax(_psi_max); + ipv.setDpsiMax_Dpsi(Dpsi_max_Dpsi_cap); } void negativeExponentialScaler::mullinsEffectScaling(double _psi0, double _psi, const IPMullinsEffect &ipvprev, IPMullinsEffect &ipv, const double T, const double& dPsi_capDT) const{ double r = _r*_temFunc_r->getVal(T); double m = _m*_temFunc_m->getVal(T); + double drdT = _r*_temFunc_r->getDiff(T); + double dmdT = _m*_temFunc_m->getDiff(T); double eta0 = ipvprev.getEta(); double _psi_max0 = ipvprev.getpsiMax(); double psi_cap = _psi; double eta = 1., DetaDpsi_cap = 0., DDetaDpsipsi = 0., DetaDT = 0., DDetaDTT = 0.; double DpsiNew_DpsiMax(0.), DDpsiNew_DpsiMaxDpsi(0.), DDpsiNew_DpsiMaxDT(0.); + double Dpsi_max_Dpsi_cap(0.), Dpsi_max_DT(0.); double _psi_max = std::max(_psi,_psi_max0); // Msg::Error(" Inside mullinsEffectScaling, _psi = %e, _psi_max = %e !!", _psi, _psi_max); - double Dpsi_maxDpsi_cap = 1.; // Dpsi_maxDpsi_cap = 1. if _psi_max = _psi - double Term = sqrt(m*(_psi_max-eta*psi_cap)); // Term = 0. if _psi_max = _psi - - if (Term!=0){ - - int ite = 0; - int maxite = 100; - double _tol = 1e-8; - double DfDeta(0.), Deta(0.); - double f = eta + r*(1-exp(-Term)) - 1.; - - while (fabs(f) >_tol or ite <1){ - - DfDeta = 1 + r*(-m*psi_cap*exp(-Term)/(2*Term)); - Deta = - f/DfDeta; - - if (eta + Deta > 1.){ - eta = 0.99; // NR - } - else - eta += Deta; - - // eta += Deta; - // Msg::Error(" Inside iterator, ite = %d, f = %e, DfDeta = %e, Deta = %e, eta = %e !!", ite, f, DfDeta, Deta, eta); - - Term = sqrt(m*(_psi_max-eta*psi_cap)); - f = eta + r*(1-exp(-Term)) - 1.; - - ite++; - if (fabs(f) <_tol) break; - - if(ite > maxite){ - // Msg::Error("No convergence for eta in mullinsEffectScaling: ite= %d, f = %e!!",ite,f); - eta = sqrt(-1.); - return; - } + if (_psi_max>0.){ + + // eta + double temp = m*(_psi_max-psi_cap); + eta = (1-r*sqrt(tanh(temp))); + + // derivatives + if (psi_cap >= _psi_max){ + Dpsi_max_Dpsi_cap = 1.; + Dpsi_max_DT = dPsi_capDT; } - Dpsi_maxDpsi_cap = 0.; - - DetaDpsi_cap = (-r*m*exp(-Term)/(2*Term)) * (Dpsi_maxDpsi_cap - eta) / (1 - r*m*exp(-Term)/(2*Term)*psi_cap); - } - else{ - eta = 1.; - DetaDpsi_cap = 0.; + DetaDpsi_cap = m*r/2.*pow( 1/cosh(temp) ,2)/sqrt(tanh(temp)) * (1- Dpsi_max_Dpsi_cap); + DetaDT = -drdT*(sqrt(tanh(temp))) - dmdT*r/2.*(_psi_max-psi_cap)*pow( 1/cosh(temp) ,2)/sqrt(tanh(temp)) + + m*r/2.*pow( 1/cosh(temp) ,2)/sqrt(tanh(temp)) * (1- Dpsi_max_Dpsi_cap)*dPsi_capDT + - m*r/2.*pow( 1/cosh(temp) ,2)/sqrt(tanh(temp)) * Dpsi_max_DT; + + double DetaDpsi_max = -m*r/2.*pow( 1/cosh(temp) ,2)/sqrt(tanh(temp)); + DpsiNew_DpsiMax = r*( sqrt(tanh(temp)) - sqrt(tanh(m*_psi_max)) ); // definition + DDpsiNew_DpsiMaxDpsi = DetaDpsi_max + r*m/2.*(pow( 1/cosh(temp) ,2)/sqrt(tanh(temp)) - pow( 1/cosh(m*_psi_max) ,2)/sqrt(tanh(m*_psi_max)) ) * Dpsi_max_Dpsi_cap; + DDpsiNew_DpsiMaxDT = DDpsiNew_DpsiMaxDpsi*dPsi_capDT - drdT*( sqrt(tanh(temp)) - sqrt(tanh(m*_psi_max)) ) + + r*dmdT/2.*( (_psi_max-psi_cap)*pow( 1/cosh(temp) ,2)/sqrt(tanh(temp)) - (_psi_max)*pow( 1/cosh(m*_psi_max) ,2)/sqrt(tanh(m*_psi_max)) ) + + r*m/2.*(pow( 1/cosh(temp) ,2)/sqrt(tanh(temp)) - pow( 1/cosh(m*_psi_max) ,2)/sqrt(tanh(m*_psi_max)) ) * Dpsi_max_DT; } - - /* - if (_psi<_psi_max){ // unloading - eta = 1. - _r*( 1. - exp( - sqrt(_m*(_psi_max-_psi)) ) ); - } - else if (_psi<_psi0){ // reinitiate eta after reloading, before unloading - eta = 1.; - } - else{ // reloading - eta = 1.; - }*/ ipv.set(eta,DetaDpsi_cap,DDetaDpsipsi,DetaDT,DDetaDTT,DpsiNew_DpsiMax, DDpsiNew_DpsiMaxDpsi, DDpsiNew_DpsiMaxDT); ipv.setPsiMax(_psi_max); + ipv.setDpsiMax_Dpsi(Dpsi_max_Dpsi_cap); } mullinsEffect *negativeExponentialScaler::clone() const diff --git a/NonLinearSolver/materialLaw/mullinsEffect.h b/NonLinearSolver/materialLaw/mullinsEffect.h index 53f3b65578dc3aa1ed9bc8b958057d3ecb833591..c985389b31a4d97414eab0db273afa43763e2ae0 100644 --- a/NonLinearSolver/materialLaw/mullinsEffect.h +++ b/NonLinearSolver/materialLaw/mullinsEffect.h @@ -40,7 +40,8 @@ class mullinsEffect { }; -// eta = 1 - r* ( 1 - exp(-sqrt(m*(psi_max-psi))) ) -> Ricker et al, 2021 (modified Zuniga, 2005) +// eta = 1 - r* ( 1 - exp(-sqrt(m*(psi_max-psi))) ) -> Ricker et al, 2021 (modified Zuniga, 2005) - OLD and deleted +// eta = (1-r*sqrt(tanh(m*(_psi_max-psi_cap))) (modified Wrublescki Marczak, 2015) - NEW and correct class negativeExponentialScaler : public mullinsEffect{ #ifndef SWIG protected: diff --git a/dG3D/benchmarks/nonLinearTVP_allExtraBranches_cube/cubeTVP.py b/dG3D/benchmarks/nonLinearTVP_allExtraBranches_cube/cubeTVP.py index f6b4f958964f031502eb52dc8f688ea8392b7a68..8c32626d8a6215703f66134de6960ae739555e5a 100644 --- a/dG3D/benchmarks/nonLinearTVP_allExtraBranches_cube/cubeTVP.py +++ b/dG3D/benchmarks/nonLinearTVP_allExtraBranches_cube/cubeTVP.py @@ -87,21 +87,22 @@ hardent = LinearExponentialJ2IsotropicHardening(2, sy0t, ht, 5., 20.) # hardent.setTemperatureFunction_hexp(ShiftFactor_tempfunc) hardenk = PolynomialKinematicHardening(3,3) # 1 -> PP +hardenk.setCoefficients(0,1.) # 300.) hardenk.setCoefficients(1,1.) # 300.) hardenk.setCoefficients(2,2.) # 200.) -hardenk.setCoefficients(3,5.) +# hardenk.setCoefficients(3,5.) -law1 = NonLinearTVENonLinearTVPDG3DMaterialLaw(lawnum,rho,E,nu,1e-6,Tinitial,Alpha,KThCon,Cp,False,1e-8,1e-8) +law1 = NonLinearTVENonLinearTVPDG3DMaterialLaw(lawnum,rho,E,nu,1e-6,Tinitial,Alpha,KThCon,Cp,False,1e-8,1e-6) law1.setCompressionHardening(hardenc) law1.setTractionHardening(hardent) -law1.setKinematicHardening(hardenk) +# law1.setKinematicHardening(hardenk) law1.setYieldPowerFactor(3) # 3.5) law1.setNonAssociatedFlow(True) law1.nonAssociatedFlowRuleFactor(0.64) # 0.5 -law1.setStrainOrder(11) +law1.setStrainOrder(-1) law1.setViscoelasticMethod(0) law1.setShiftFactorConstantsWLF(C1,C2) law1.setReferenceTemperature(Tref) @@ -130,7 +131,7 @@ a = -0.9/(90.) x0 = 273.15-20 linear_tempfunc = linearScalarFunction(x0,0.9,a) # mullins.setTemperatureFunction_r(linear_tempfunc) -# law1.setMullinsEffect(mullins) +law1.setMullinsEffect(mullins) eta = constantViscosityLaw(1,1000.) #(1,3e4) law1.setViscosityEffect(eta,0.1) @@ -159,7 +160,7 @@ pertFactor = 1e-8 pertLaw1 = dG3DMaterialLawWithTangentByPerturbation(law1,pertFactor) ThermoMechanicsEqRatio = 1.e1 # setConstitutiveExtraDofDiffusionEqRatio(ThermoMechanicsEqRatio) thermalSource = True -mecaSource = False +mecaSource = True myfield1 = ThermoMechanicsDG3DDomain(1000,nfield,space1,lawnum,fullDg,ThermoMechanicsEqRatio) myfield1.setConstitutiveExtraDofDiffusionAccountSource(thermalSource,mecaSource) myfield1.stabilityParameters(beta1) @@ -191,7 +192,7 @@ mysolver.displacementBC("Face",32,2,0.) # face z = 0 # thermal BC mysolver.initialBC("Volume","Position",nfield,3,Tinitial) fT = LinearFunctionTime(0,Tinitial,ftime,Tinitial) # Linear Displacement with time -mysolver.displacementBC("Volume",nfield,3,fT) +# mysolver.displacementBC("Volume",nfield,3,fT) # Field-Output mysolver.internalPointBuildView("strain_zz", IPField.STRAIN_ZZ, 1, nstepArch); diff --git a/dG3D/benchmarks/nonLinearTVP_cube_Rotation_biaxialShear/CMakeLists.txt b/dG3D/benchmarks/nonLinearTVP_cube_Rotation_biaxialShear/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..a0177858b739eed0c6a4bfbece73db3029b79186 --- /dev/null +++ b/dG3D/benchmarks/nonLinearTVP_cube_Rotation_biaxialShear/CMakeLists.txt @@ -0,0 +1,14 @@ +# test file + +set(PYFILE cubeTVP.py) + +set(FILES2DELETE + for*.csv + ene*.csv + Nod*.csv + disp* + stress* + IPVol* +) + +add_cm3python_test(${PYFILE} "${FILES2DELETE}") diff --git a/dG3D/benchmarks/nonLinearTVP_cube_Rotation_biaxialShear/cube.geo b/dG3D/benchmarks/nonLinearTVP_cube_Rotation_biaxialShear/cube.geo new file mode 100644 index 0000000000000000000000000000000000000000..7b69582119311ad0f199829d872fc7eb4f36c967 --- /dev/null +++ b/dG3D/benchmarks/nonLinearTVP_cube_Rotation_biaxialShear/cube.geo @@ -0,0 +1,48 @@ +// Cube.geo +mm=1.0; // Units +n=1; // Number of layers (in thickness / along z) +m = 1; // Number of element + 1 along y +p = 1; // Number of element + 1 along x +L=1.*mm; // Cube lenght +sl1=L/n; + +// Face z = 0 (point in anti-clockwise order) +Point(1)={0,0,0,sl1}; +Point(2)={L,0,0,sl1}; +Point(3)={L,L,0,sl1}; +Point(4)={0,L,0,sl1}; +Line(1)={1,2}; +Line(2)={2,3}; +Line(3)={3,4}; +Line(4)={4,1}; +Line Loop(5) = {3, 4, 1, 2}; +Plane Surface(6) = {5}; + +// Cube extrusion +Extrude {0, 0, L} { + Surface{6}; Layers{n}; Recombine; +} + +// Physical entities + // Volume +Physical Volume(29) = {1}; + // Surface +Physical Surface(30) = {19}; // Left face x = 0 +Physical Surface(31) = {27}; // Right face x = L +Physical Surface(32) = {6}; // Back face z = 0 +Physical Surface(33) = {28}; // Front face z = L +Physical Surface(34) = {15}; // Down face y = 0 +Physical Surface(35) = {23}; // Up face y = L + +// Mesh +Transfinite Line {2, 4} = m Using Progression 1; +Transfinite Line {1, 3} = p Using Progression 1; +Transfinite Surface {6}; +Recombine Surface{6}; + + +// To save cube elongation +Physical Point(41) = {1}; // Point on left face (0,0,0) +Physical Point(42) = {4}; // Point on left face (0,L,0) +Physical Point(43) = {2}; // Point on right face (L,0,0) +Physical Point(44) = {3}; // Point on right face (L,L,0) diff --git a/dG3D/benchmarks/nonLinearTVP_cube_Rotation_biaxialShear/cubeTVP.py b/dG3D/benchmarks/nonLinearTVP_cube_Rotation_biaxialShear/cubeTVP.py new file mode 100644 index 0000000000000000000000000000000000000000..5f1c45498fe691be36a7150760c31290c3b07282 --- /dev/null +++ b/dG3D/benchmarks/nonLinearTVP_cube_Rotation_biaxialShear/cubeTVP.py @@ -0,0 +1,290 @@ +#coding-Utf-8-*- + +from gmshpy import * +# from dG3Dpy import* +from dG3DpyDebug import* +from math import* +import csv +import numpy as np +import pandas as pd +import os + +# Load the csv data for relaxation spectrum +with open('relaxationSpectrum_Einf_N27_05_12_23_Tref20.csv', newline='') as csvfile: +# with open('../TPU_relaxationSpectrum_Et_N64_28_03_24_Trefm30.txt', newline='') as csvfile: + reader = csv.reader(csvfile, delimiter=';') + relSpec = np.zeros((1,)) + i = 0 + for row in reader: + if i == 0: + relSpec[i] = float(' '.join(row)) + else: + relSpec = np.append(relSpec, float(' '.join(row))) + i += 1 +# print(relSpec) +N = int(0.5*(i-1)) +relSpec[0:N+1] *= 1e-6 # convert to MPa + +# material law +lawnum = 11 # unique number of law + +E = relSpec[0] #MPa # 2700 +nu = 0.33 #0.33 +K = E/3./(1.-2.*nu) # Bulk mudulus +mu = E/2./(1.+nu) # Shear mudulus +rho = 905e-12 # Bulk mass 905 kg/m3 -> 905e-12 tonne/mm3 +Cp = rho*1900e+6 # 1900 J/kg/K -> 1900e+6 Nmm/tonne/K +KThCon = 0.14 # 0.14 W/m/K -> 0.14 Nmm/s/mm/K +Alpha = 0.6e-6 # 1/K + +Tinitial = 273.15 + 23 # K +C1 = 112.94742152 +C2 = 176.44294359 + +# Temp Settings +Tref = 273.15+20. + +# Default tempfuncs +Alpha_G = 0.2e-6 +Alpha_R = 1.e-6 +KThCon_G = 0.10 +KThCon_R = 1.5*0.12 +k_gibson = 3.36435338e-02 +m_gibson = 0.0 +Tg = Tref +Alpha_tempfunc = GlassTransitionScalarFunction(1, Alpha_R/Alpha_G, Tg, k_gibson, m_gibson, 0) +KThCon_tempfunc = GlassTransitionScalarFunction(1, KThCon_R/KThCon_G, Tg, k_gibson, m_gibson, 0) + +C = 0.0228422 +sy0c = 6.02534075/0.78 +negExp_tempfunc = negativeExponentialFunction(C,Tref) + +a = -0.9/(90.) +x0 = 273.15-20 +linear_tempfunc = linearScalarFunction(x0,0.9,a) + +hardenc = LinearExponentialJ2IsotropicHardening(1, 5., 0.01, 0.01, 30.) +hardent = LinearExponentialJ2IsotropicHardening(2, 5., 0.01, 0.01, 30.) +# hardenc.setTemperatureFunction_h1(linear_tempfunc) +# hardenc.setTemperatureFunction_h2(linear_tempfunc) +# hardenc.setTemperatureFunction_hexp(ShiftFactor_tempfunc) +# hardent.setTemperatureFunction_h1(linear_tempfunc) +# hardent.setTemperatureFunction_h2(linear_tempfunc) +# hardent.setTemperatureFunction_hexp(ShiftFactor_tempfunc) + +hardenk = PolynomialKinematicHardening(3,3) # 1 -> PP +hardenk.setCoefficients(0,1.) # 300.) +hardenk.setCoefficients(1,2.) # 200.) +hardenk.setCoefficients(2,5.) +# hardenk.setTemperatureFunction_K(linear_tempfunc) + +law1 = NonLinearTVENonLinearTVP2DG3DMaterialLaw(lawnum,rho,E,nu,1e-6,Tinitial,Alpha,KThCon,Cp,False,1e-5,1e-9) + +law1.setCompressionHardening(hardenc) +law1.setTractionHardening(hardent) +# law1.setKinematicHardening(hardenk) + +law1.setYieldPowerFactor(1.25) # .5) +law1.setNonAssociatedFlow(True) +law1.nonAssociatedFlowRuleFactor(0.64) # 5) + +law1.setStrainOrder(-1) +law1.setViscoelasticMethod(0) +law1.setShiftFactorConstantsWLF(C1,C2) +law1.setReferenceTemperature(Tref) + +law1.useRotationCorrectionBool(True,2) # bool, int_Scheme = 0 -> R0, 1 -> R1 + +""" +law1.setExtraBranchNLType(5) +law1.useExtraBranchBool(False) +law1.useExtraBranchBool_TVE(False,4) +V = 1.48385807e-02 +xi = 4.86512658e+00/V**2 +iota = 2.03662889e-04/V**2 +D = 5.47347064e-02 +theta = 6.57278720e+00/D**2 +pi = 2.77066402e-03/D**2 +# law1.setVolumeCorrection(1., xi, iota, 1., theta, pi) # at 23°C +law1.setVolumeCorrection(0.0,1000,1.5,0.0,1000.,1.5) # at 23°C +law1.setAdditionalVolumeCorrections(0.0,1000,1.5,0.0,1000.,1.5) # NEW +law1.setExtraBranch_CompressionParameter(1.8,0.,0.) # 1.5 +law1.setTensionCompressionRegularisation(1000.) + +# law1.setViscoElasticNumberOfElement(1) +# law1.setViscoElasticData(1,1000,1.) +# law1.setCorrectionsAllBranchesTVE(1, xi, iota, theta, pi) +# law1.setCompressionCorrectionsAllBranchesTVE(i, 1.5) +extraTVE = np.ones((int(0.5*(relSpec.size-1)),13)) # 3 vol + 3 dev + 1 comp + +# tension +extraTVE[:,0] = (np.concatenate((np.linspace(1.0,0.25,14),np.linspace(0.25,0.05,13)))) # (np.linspace(0,0.1,N)) +extraTVE[:,1] = np.flip(np.concatenate((np.linspace(1500,15500,13),np.linspace(15500,35000,14)))) +extraTVE[:,2] = (np.concatenate((np.linspace(12.5,1.25,14),np.linspace(1.25,1.5,13)))) +extraTVE[:,3] = (np.concatenate((np.linspace(1.0,0.25,14),np.linspace(0.25,0.05,13)))) # (np.linspace(0,0.1,N)) +extraTVE[:,4] = np.flip(np.concatenate((np.linspace(1500,15500,13),np.linspace(15500,35000,14)))) +extraTVE[:,5] = (np.concatenate((np.linspace(12.5,1.25,14),np.linspace(1.25,1.5,13)))) +extraTVE[:,6] = np.flip(np.concatenate((np.linspace(1.8,1.8,13),np.linspace(1.8,7.,14)))) # 2.2,2.8,N + +# compression +extraTVE[:,7] = (np.concatenate((np.linspace(1.0,0.1,14),np.linspace(0.1,0.05,13)))) # extraTVE[:,0] +extraTVE[:,8] = np.flip(np.concatenate((np.linspace(4500,8500,13),np.linspace(8500,35000,14)))) # extraTVE[:,1] +extraTVE[:,9] = (np.concatenate((np.linspace(12.5,1.25,14),np.linspace(1.25,1.35,13)))) # extraTVE[:,2] +extraTVE[:,10] = (np.concatenate((np.linspace(1.0,0.1,14),np.linspace(0.1,0.05,13)))) # extraTVE[:,3] +extraTVE[:,11] = np.flip(np.concatenate((np.linspace(4500,8500,13),np.linspace(8500,35000,14)))) # extraTVE[:,4] +extraTVE[:,12] = (np.concatenate((np.linspace(12.5,1.25,14),np.linspace(1.25,1.35,13)))) # extraTVE[:,5] +extraTVE.tolist() +""" + +law1.setViscoElasticNumberOfElement(N) +if N > 0: + for i in range(1, N+1): + law1.setViscoElasticData(i, relSpec[i], relSpec[i+N]) + # law1.setCorrectionsAllBranchesTVE(i, extraTVE[i-1,0],extraTVE[i-1,1],extraTVE[i-1,2],extraTVE[i-1,3],extraTVE[i-1,4],extraTVE[i-1,5]) + # law1.setCompressionCorrectionsAllBranchesTVE(i, extraTVE[i-1,6]) + # law1.setAdditionalCorrectionsAllBranchesTVE(i, extraTVE[i-1,7],extraTVE[i-1,8],extraTVE[i-1,9],extraTVE[i-1,10],extraTVE[i-1,11],extraTVE[i-1,12]) + +law1.setTemperatureFunction_ThermalDilationCoefficient(Alpha_tempfunc) +law1.setTemperatureFunction_ThermalConductivity(KThCon_tempfunc) + +mullins = linearScaler(4, 0.99) +a = -0.9/(90.) +x0 = 273.15-20 +linear_tempfunc = linearScalarFunction(x0,0.99,a) +# mullins.setTemperatureFunction_r(linear_tempfunc) +# law1.setMullinsEffect(mullins) + + +eta = constantViscosityLaw(1,10000.) # 3e4) #(1,3e4) +law1.setViscosityEffect(eta,0.21) # 0.21) +# eta.setTemperatureFunction(negExp_tempfunc) +# law1.setIsotropicHardeningCoefficients(1.,1.,1.) + + +# solver +sol = 2 # Gmm=0 (default) Taucs=1 PETsc=2 +soltype = 1 # StaticLinear=0 (default) StaticNonLinear=1 +nstep = 100 # number of step (used only if soltype=1) +# ftime = 2*np.sum(elongations[:,0])/2.78e-3 # 0.65/2.78e-3 # 4.8 4. # Final time (used only if soltype=1) +ftime = 50.#0.2/0.01 # 0.65/2.78e-3 # 4.8 4. # Final time (used only if soltype=1) +tol=1.e-5 # relative tolerance for NR scheme (used only if soltype=1) +nstepArch=1 # Number of step between 2 archiving (used only if soltype=1) +fullDg = 0 #O = CG, 1 = DG +space1 = 0 # function space (Lagrange=0) +beta1 = 100 + + +# geometry +geofile = "cube.geo" # "line.geo" +meshfile = "cube.msh" # "line.msh" +nfield = 29 + + +pertLaw1 = dG3DMaterialLawWithTangentByPerturbation(law1,1e-8) # use with _pert*T0 (b/c In tangent_by_perturbation_TVP u use _pert*T0) +ThermoMechanicsEqRatio = 1.e1 # setConstitutiveExtraDofDiffusionEqRatio(ThermoMechanicsEqRatio) +thermalSource = True +mecaSource = False +myfield1 = ThermoMechanicsDG3DDomain(1000,nfield,space1,lawnum,fullDg,ThermoMechanicsEqRatio) +myfield1.setConstitutiveExtraDofDiffusionAccountSource(thermalSource,mecaSource) +myfield1.stabilityParameters(beta1) +myfield1.ThermoMechanicsStabilityParameters(beta1,bool(1)) +# myfield1.strainSubstep(2, 10) + +# creation of Solver +mysolver = nonLinearMechSolver(1000) +mysolver.createModel(geofile,meshfile,3,2) +mysolver.loadModel(meshfile) +mysolver.addDomain(myfield1) +mysolver.addMaterialLaw(law1) +# mysolver.addMaterialLaw(pertLaw1) +mysolver.Scheme(soltype) +mysolver.Solver(sol) +mysolver.snlData(nstep,ftime,tol) +mysolver.stepBetweenArchiving(nstepArch) + +# BCs +length = 1 +umax = 0.5*length # 0.65*length # 0.04 -> PP +fu_L = LinearFunctionTime(0,0,ftime,umax); # Linear Displacement with time + +""" +strainRate = 1.e-2 +fu_P = PiecewiseLinearFunction() +fu_P.put(0,0) +fu_P.put(0.5e-2/strainRate,0.5e-2*length) +fu_P.put(1.e-2/strainRate,0.00) # 1 +fu_P.put(2.e-2/strainRate,1.0e-2*length) +fu_P.put(3.e-2/strainRate,0.00) # 2 +fu_P.put(5.e-2/strainRate,2.0e-2*length) +fu_P.put(7.e-2/strainRate,0.00) +fu_P.put(9.5e-2/strainRate,2.5e-2*length) +fu_P.put(12.e-2/strainRate,0.00) +fu_P.put(15.e-2/strainRate,3.0e-2*length) +fu_P.put(18.e-2/strainRate,0.00) +fu_P.put(21.5e-2/strainRate,3.5e-2*length) +fu_P.put(24.e-2/strainRate,0.00) +fu_P.put(28.e-2/strainRate,4.0e-2*length) +""" + +mysolver.displacementBC("Face",30,0,0.) # face x = 0 - Left Face fixed +mysolver.displacementBC("Face",30,1,0.) # face x = 0 - Left Face fixed +mysolver.displacementBC("Face",30,2,0.) # face x = 0 - Left Face fixed +mysolver.displacementBC("Face",31,1,fu_L) # face x = L - Right Face moving +mysolver.displacementBC("Face",31,2,fu_L) # face x = L - Right Face moving +# mysolver.displacementBC("Face",34,1,0.) # face y = 0 +# mysolver.displacementBC("Face",32,2,0.) # face z = 0 + +# thermal BC +mysolver.initialBC("Volume","Position",nfield,3,Tinitial) +fT = LinearFunctionTime(0,Tinitial,ftime,Tinitial) # Linear Displacement with time +mysolver.displacementBC("Volume",nfield,3,fT) + +# Field-Output + +mysolver.internalPointBuildView("strain_zz", IPField.STRAIN_ZZ, 1, nstepArch); +mysolver.internalPointBuildView("svm",IPField.SVM, 1, nstepArch) +mysolver.internalPointBuildView("sig_xx",IPField.SIG_XX, 1, nstepArch) +mysolver.internalPointBuildView("sig_yy",IPField.SIG_YY, 1, nstepArch) +mysolver.internalPointBuildView("sig_zz",IPField.SIG_ZZ, 1, nstepArch) +mysolver.internalPointBuildView("sig_xy",IPField.SIG_XY, 1, nstepArch) +mysolver.internalPointBuildView("sig_yz",IPField.SIG_YZ, 1, nstepArch) +mysolver.internalPointBuildView("sig_xz",IPField.SIG_XZ, 1, nstepArch) +mysolver.internalPointBuildView("mandel_xx",IPField.mandel_XX, 1, nstepArch) +mysolver.internalPointBuildView("mandel_yy",IPField.mandel_YY, 1, nstepArch) +mysolver.internalPointBuildView("mandel_zz",IPField.mandel_ZZ, 1, nstepArch) +mysolver.internalPointBuildView("mandel_xy",IPField.mandel_XY, 1, nstepArch) +mysolver.internalPointBuildView("mandel_yz",IPField.mandel_YZ, 1, nstepArch) +mysolver.internalPointBuildView("mandel_xz",IPField.mandel_XZ, 1, nstepArch) +mysolver.internalPointBuildView("mandel_yx",IPField.mandel_YX, 1, nstepArch) +mysolver.internalPointBuildView("mandel_zy",IPField.mandel_ZY, 1, nstepArch) +mysolver.internalPointBuildView("mandel_zx",IPField.mandel_ZX, 1, nstepArch) +mysolver.internalPointBuildView("epl",IPField.PLASTICSTRAIN, 1, nstepArch) + +# Print/Archive History Outputs +mysolver.archivingAverageValue(IPField.hyperElastic_BulkScalar) +mysolver.archivingAverageValue(IPField.hyperElastic_ShearScalar) +mysolver.archivingAverageValue(IPField.mandel_XX) +mysolver.archivingAverageValue(IPField.mandel_YY) +mysolver.archivingAverageValue(IPField.mandel_ZZ) +mysolver.archivingAverageValue(IPField.mandel_XY) +mysolver.archivingAverageValue(IPField.mandel_XZ) +mysolver.archivingAverageValue(IPField.mandel_YZ) +mysolver.archivingAverageValue(IPField.mandel_YX) +mysolver.archivingAverageValue(IPField.mandel_ZX) +mysolver.archivingAverageValue(IPField.mandel_ZY) +mysolver.archivingAverageValue(IPField.mandelCommuteChecker) + +# mysolver.archivingForceOnPhysicalGroup("Face", 31, 0, nstepArch) # Force on the right force +mysolver.archivingForceOnPhysicalGroup("Face", 30, 0, nstepArch) # Force on the left face === Reaction Force +mysolver.archivingForceOnPhysicalGroup("Face", 30, 1, nstepArch) # Force on the left face === Reaction Force +mysolver.archivingForceOnPhysicalGroup("Face", 30, 2, nstepArch) # Force on the left face === Reaction Force +# mysolver.archivingForceOnPhysicalGroup("Node", 41, 0, nstepArch) # Force on a point on the left face === Reaction Force +mysolver.archivingNodeDisplacement(43, 0, nstepArch) # Displacement of a point on the right face +mysolver.archivingIPOnPhysicalGroup("Volume",nfield, IPField.PLASTICSTRAIN,IPField.MEAN_VALUE); + +# Solve +mysolver.solve() + +# check = TestCheck() +# check.equal(-2.323842427279116e-05,mysolver.getArchivedForceOnPhysicalGroup("Face", 30, 0),1.e-4) # TVM without mechSrc +# check.equal(-1.512641578252656e-05,mysolver.getArchivedForceOnPhysicalGroup("Face", 30, 0),1.e-4) # sy = 1.e-5, without mechSrc diff --git a/dG3D/benchmarks/powerYieldViscoElastoPlastic/cylinder.msh b/dG3D/benchmarks/powerYieldViscoElastoPlastic/cylinder.msh index b0d6ad7b747dba6adae54a969c9d6bec368bce8f..09d89e4b0a67347beacc0e2483ee74663da474be 100644 --- a/dG3D/benchmarks/powerYieldViscoElastoPlastic/cylinder.msh +++ b/dG3D/benchmarks/powerYieldViscoElastoPlastic/cylinder.msh @@ -42,7 +42,7 @@ $Nodes 13 2.296100600555804 5.543277192431141 0 0 14 3.652568583266842 4.760120034676862 0 0 15 4.760120048986037 3.652568564618763 0 0 -16 5.543277197488509 2.296100588346238 0 0 +16 5.543277197488512 2.296100588346232 0 0 17 5.948669168522611 0.783157151195411 0 0 18 0 4.500000000005166 0 0 19 0 3.000000000008336 0 0 @@ -67,7 +67,7 @@ $Nodes 38 2.296100600555804 5.543277192431141 6 0 39 3.652568583266842 4.760120034676862 6 0 40 4.760120048986037 3.652568564618763 6 0 -41 5.543277197488509 2.296100588346238 6 0 +41 5.543277197488512 2.296100588346232 6 0 42 5.948669168522611 0.783157151195411 6 0 43 4.499999999994237 0 6 0 44 2.999999999988567 0 6 0 @@ -178,31 +178,31 @@ $Nodes 149 5.795554958944408 1.552914266099346 3.6 0 150 5.795554958944408 1.552914266099346 4.800000000000001 0 151 0.7831571644793788 5.948669166773743 0.6000000000000079 0 -152 1.552914274817983 5.795554956608258 0.6000000000000001 0 -153 0.7831571554772518 5.948669167958895 1.2 0 -154 0.7831571554772518 5.948669167958895 1.8 0 -155 1.552914274817974 5.79555495660826 1.8 0 -156 0.7831571554772518 5.948669167958895 2.4 0 -157 0.7831571554772518 5.948669167958895 3 0 -158 1.552914274817974 5.79555495660826 3 0 -159 0.7831571554772518 5.948669167958895 3.6 0 -160 0.7831571554772518 5.948669167958895 4.199999999999999 0 -161 1.552914274817974 5.79555495660826 4.2 0 -162 0.7831571554772518 5.948669167958895 4.800000000000001 0 -163 0.7831571554772518 5.948669167958895 5.4 0 -164 1.552914274817982 5.795554956608258 5.4 0 -165 2.296100600342287 5.543277192519582 0.6000000000000001 0 +152 1.552914274817997 5.795554956608253 0.6000000000000001 0 +153 0.7831571554772612 5.948669167958894 1.2 0 +154 0.7831571554772612 5.948669167958894 1.8 0 +155 1.552914274818002 5.795554956608252 1.8 0 +156 0.7831571554772612 5.948669167958894 2.4 0 +157 0.7831571554772612 5.948669167958894 3 0 +158 1.552914274818002 5.795554956608252 3 0 +159 0.7831571554772612 5.948669167958894 3.6 0 +160 0.7831571554772612 5.948669167958894 4.199999999999999 0 +161 1.552914274818002 5.795554956608252 4.2 0 +162 0.7831571554772612 5.948669167958894 4.800000000000001 0 +163 0.7831571554772612 5.948669167958894 5.4 0 +164 1.552914274817997 5.795554956608253 5.4 0 +165 2.2961006003423 5.543277192519577 0.6000000000000001 0 166 3.000000007764873 5.19615241822358 0.6000000000000001 0 -167 2.296100600342287 5.543277192519582 1.2 0 -168 2.296100600342287 5.543277192519582 1.8 0 +167 2.2961006003423 5.543277192519577 1.2 0 +168 2.2961006003423 5.543277192519577 1.8 0 169 3.000000007764873 5.19615241822358 1.8 0 -170 2.296100600342287 5.543277192519582 2.4 0 -171 2.296100600342287 5.543277192519582 3 0 +170 2.2961006003423 5.543277192519577 2.4 0 +171 2.2961006003423 5.543277192519577 3 0 172 3.000000007764873 5.19615241822358 3 0 -173 2.296100600342287 5.543277192519582 3.6 0 -174 2.296100600342287 5.543277192519582 4.2 0 +173 2.2961006003423 5.543277192519577 3.6 0 +174 2.2961006003423 5.543277192519577 4.2 0 175 3.000000007764873 5.19615241822358 4.2 0 -176 2.296100600342287 5.543277192519582 4.800000000000001 0 +176 2.2961006003423 5.543277192519577 4.800000000000001 0 177 2.296100600342296 5.543277192519579 5.4 0 178 3.000000007764873 5.19615241822358 5.4 0 179 3.652568583207426 4.760120034722454 0.6000000000000001 0 diff --git a/dG3D/src/dG3DIPVariable.cpp b/dG3D/src/dG3DIPVariable.cpp index e0791bef702606109a245b0a6c5e573068acece5..b616ee77ed1fc0e0215627ab51c3881e67fbc603 100644 --- a/dG3D/src/dG3DIPVariable.cpp +++ b/dG3D/src/dG3DIPVariable.cpp @@ -5838,6 +5838,16 @@ double NonLinearTVMDG3DIPVariable::get(const int i) const{ else if (i == IPField::corKir_YY){return _ipViscoElastic->_kirchhoff(1,1);} else if (i == IPField::corKir_YZ){return _ipViscoElastic->_kirchhoff(1,2);} else if (i == IPField::corKir_ZZ){return _ipViscoElastic->_kirchhoff(2,2);} + else if (i == IPField::mandel_XX){return _ipViscoElastic->_ModMandel(0,0);} + else if (i == IPField::mandel_XY){return _ipViscoElastic->_ModMandel(0,1);} + else if (i == IPField::mandel_YX){return _ipViscoElastic->_ModMandel(1,0);} + else if (i == IPField::mandel_XZ){return _ipViscoElastic->_ModMandel(0,2);} + else if (i == IPField::mandel_ZX){return _ipViscoElastic->_ModMandel(2,0);} + else if (i == IPField::mandel_YY){return _ipViscoElastic->_ModMandel(1,1);} + else if (i == IPField::mandel_YZ){return _ipViscoElastic->_ModMandel(1,2);} + else if (i == IPField::mandel_ZY){return _ipViscoElastic->_ModMandel(2,1);} + else if (i == IPField::mandel_ZZ){return _ipViscoElastic->_ModMandel(2,2);} + else if (i == IPField::mandelCommuteChecker){return _ipViscoElastic->_mandelCommuteChecker;} else if (i == IPField::hyperElastic_BulkScalar){return _ipViscoElastic->getConstRefToElasticBulkPropertyScaleFactor();} else if (i == IPField::hyperElastic_ShearScalar){return _ipViscoElastic->getConstRefToElasticShearPropertyScaleFactor();} else if (i == IPField::corKirExtra_XX){return _ipViscoElastic->_corKirExtra(0,0);} @@ -6236,6 +6246,16 @@ double NonLinearTVPDG3DIPVariable::get(const int i) const{ else if (i == IPField::corKir_YY){return _ipViscoElastoPlastic->_kirchhoff(1,1);} else if (i == IPField::corKir_YZ){return _ipViscoElastoPlastic->_kirchhoff(1,2);} else if (i == IPField::corKir_ZZ){return _ipViscoElastoPlastic->_kirchhoff(2,2);} + else if (i == IPField::mandel_XX){return _ipViscoElastoPlastic->_ModMandel(0,0);} + else if (i == IPField::mandel_XY){return _ipViscoElastoPlastic->_ModMandel(0,1);} + else if (i == IPField::mandel_YX){return _ipViscoElastoPlastic->_ModMandel(1,0);} + else if (i == IPField::mandel_XZ){return _ipViscoElastoPlastic->_ModMandel(0,2);} + else if (i == IPField::mandel_ZX){return _ipViscoElastoPlastic->_ModMandel(2,0);} + else if (i == IPField::mandel_YY){return _ipViscoElastoPlastic->_ModMandel(1,1);} + else if (i == IPField::mandel_YZ){return _ipViscoElastoPlastic->_ModMandel(1,2);} + else if (i == IPField::mandel_ZY){return _ipViscoElastoPlastic->_ModMandel(2,1);} + else if (i == IPField::mandel_ZZ){return _ipViscoElastoPlastic->_ModMandel(2,2);} + else if (i == IPField::mandelCommuteChecker){return _ipViscoElastoPlastic->_mandelCommuteChecker;} else if (i == IPField::hyperElastic_BulkScalar){return _ipViscoElastoPlastic->getConstRefToElasticBulkPropertyScaleFactor();} else if (i == IPField::hyperElastic_ShearScalar){return _ipViscoElastoPlastic->getConstRefToElasticShearPropertyScaleFactor();} else if (i == IPField::corKirExtra_XX){return _ipViscoElastoPlastic->_corKirExtra(0,0);} diff --git a/dG3D/src/dG3DMaterialLaw.cpp b/dG3D/src/dG3DMaterialLaw.cpp index 6ed9c64645d0c5bec195a60db135b56d76f3c012..029a582049e60db9ac4edb919164f03f5368e327 100644 --- a/dG3D/src/dG3DMaterialLaw.cpp +++ b/dG3D/src/dG3DMaterialLaw.cpp @@ -252,7 +252,7 @@ void dG3DMaterialLawWithTangentByPerturbation::stress(IPVariable* ipv, const IPV ipvcur->getConstRefToDeformationGradient().print("F Analytique"); // FLE ipvcur->getConstRefToFirstPiolaKirchhoffStress().print("P Analytique"); // FLE ipvcur->getConstRefToTangentModuli().print("dPdE Analytique"); - for (int k=0; k< numNonLocalVars; k++) + /* for (int k=0; k< numNonLocalVars; k++) { ipvcur->getConstRefToDLocalVariableDStrain()[k].print("dpdE Analyique"); } @@ -336,7 +336,7 @@ void dG3DMaterialLawWithTangentByPerturbation::stress(IPVariable* ipv, const IPV { Msg::Info("dp dExtraDofDiffusionField Analytique: %e",ipvcur->getRefTodLocalVariableDExtraDofDiffusionField()(k,i)); } - } + }*/ for (unsigned int i = 0; i < numCurlDof; ++i) { ipvcur->getConstRefTodPdVectorPotential()[i].print("dPdMagneticVectorPotential Analytique"); @@ -636,7 +636,7 @@ void dG3DMaterialLawWithTangentByPerturbation::stress(IPVariable* ipv, const IPV ipvcur->getConstRefToDIrreversibleEnergyDDeformationGradient().print("dEnedE Numerique"); } } - for (int i=0; i< numNonLocalVars; i++) + /*for (int i=0; i< numNonLocalVars; i++) { for (int j=0; j< numNonLocalVars; j++) { @@ -707,7 +707,7 @@ void dG3DMaterialLawWithTangentByPerturbation::stress(IPVariable* ipv, const IPV { Msg::Info("dp dExtraDofDiffusionField Numerique: %e",ipvcur->getRefTodLocalVariableDExtraDofDiffusionField()(k,i)); } - } + }*/ for (unsigned int i = 0; i < numCurlDof; ++i) { const unsigned int extradof_T = 0; // Thermal field EM source @@ -10541,6 +10541,9 @@ void NonLinearTVMDG3DMaterialLaw::useExtraBranchBool(const bool useExtraBranch){ void NonLinearTVMDG3DMaterialLaw::useExtraBranchBool_TVE(const bool useExtraBranch_TVE, const int ExtraBranch_TVE_option){ _viscoLaw.useExtraBranchBool_TVE(useExtraBranch_TVE, ExtraBranch_TVE_option); }; +void NonLinearTVMDG3DMaterialLaw::useRotationCorrectionBool(const bool useRotationCorrection, const int rotationCorrectionScheme){ + _viscoLaw.useRotationCorrectionBool(useRotationCorrection,rotationCorrectionScheme); +}; void NonLinearTVMDG3DMaterialLaw::setVolumeCorrection(const double _vc, const double _xivc, const double _zetavc, const double _dc, const double _thetadc, const double _pidc){ _viscoLaw.setVolumeCorrection(_vc,_xivc,_zetavc,_dc,_thetadc,_pidc); }; @@ -11372,6 +11375,9 @@ void NonLinearTVENonLinearTVPDG3DMaterialLaw::useExtraBranchBool(const bool useE void NonLinearTVENonLinearTVPDG3DMaterialLaw::useExtraBranchBool_TVE(const bool useExtraBranch_TVE, const int ExtraBranch_TVE_option){ _viscoLaw.useExtraBranchBool_TVE(useExtraBranch_TVE, ExtraBranch_TVE_option); }; +void NonLinearTVENonLinearTVPDG3DMaterialLaw::useRotationCorrectionBool(const bool useRotationCorrection, const int rotationCorrectionScheme){ + _viscoLaw.useRotationCorrectionBool(useRotationCorrection,rotationCorrectionScheme); +}; void NonLinearTVENonLinearTVPDG3DMaterialLaw::setVolumeCorrection(const double _vc, const double _xivc, const double _zetavc, const double _dc, const double _thetadc, const double _pidc){ _viscoLaw.setVolumeCorrection(_vc,_xivc,_zetavc,_dc,_thetadc,_pidc); }; @@ -11513,3 +11519,299 @@ void NonLinearTVENonLinearTVPDG3DMaterialLaw::stress(IPVariable* ipv, const IPVa } // NonLinearTVENonLinearTVP Law Interface =================================================================== END + + +// NonLinearTVENonLinearTVP2 Law Interface =================================================================== BEGIN + +NonLinearTVENonLinearTVP2DG3DMaterialLaw::NonLinearTVENonLinearTVP2DG3DMaterialLaw(const int num, const double rho, const double E, const double nu, const double tol, + const double Tinitial, const double Alpha, const double KThCon, const double Cp, + const bool matrixbyPerturbation, const double pert, const double stressIteratorTol, const bool thermalEstimationPreviousConfig): + dG3DMaterialLaw(num,rho), _viscoLaw(num,E,nu,rho,tol,Tinitial,Alpha, KThCon, Cp, matrixbyPerturbation,pert, stressIteratorTol, thermalEstimationPreviousConfig) +{ + fillElasticStiffness(E, nu, elasticStiffness); // Why are some of the variables defined in this constructor? --- WHAT?? +}; + +NonLinearTVENonLinearTVP2DG3DMaterialLaw::NonLinearTVENonLinearTVP2DG3DMaterialLaw(const NonLinearTVENonLinearTVP2DG3DMaterialLaw& src): dG3DMaterialLaw(src), _viscoLaw(src._viscoLaw){}; + +void NonLinearTVENonLinearTVP2DG3DMaterialLaw::setStrainOrder(const int order){ + _viscoLaw.setStrainOrder(order); +}; +void NonLinearTVENonLinearTVP2DG3DMaterialLaw::setViscoelasticMethod(const int method){ + _viscoLaw.setViscoelasticMethod(method); +}; +void NonLinearTVENonLinearTVP2DG3DMaterialLaw::setViscoElasticNumberOfElement(const int N){ + _viscoLaw.setViscoElasticNumberOfElement(N); +}; +void NonLinearTVENonLinearTVP2DG3DMaterialLaw::setViscoElasticData(const int i, const double Ei, const double taui){ + _viscoLaw.setViscoElasticData(i,Ei,taui); +}; +/* +void NonLinearTVENonLinearTVP2DG3DMaterialLaw::setViscoElasticData(const int i, const double Ei, const double taui, const double Alphai){ + _viscoLaw.setViscoElasticData(i,Ei,taui,Alphai); +};*/ +void NonLinearTVENonLinearTVP2DG3DMaterialLaw::setViscoElasticData_Bulk(const int i, const double Ki, const double ki){ + _viscoLaw.setViscoElasticData_Bulk(i,Ki,ki); +}; +void NonLinearTVENonLinearTVP2DG3DMaterialLaw::setViscoElasticData_Shear(const int i, const double Gi, const double gi){ + _viscoLaw.setViscoElasticData_Shear(i,Gi,gi); +}; +/* +void NonLinearTVENonLinearTVP2DG3DMaterialLaw::setViscoElasticData_Alpha(const int i, const double Alphai){ + _viscoLaw.setViscoElasticData_Alpha(i,Alphai); +}; +*/ +void NonLinearTVENonLinearTVP2DG3DMaterialLaw::setViscoElasticData(const std::string filename){ + _viscoLaw.setViscoElasticData(filename); +}; +void NonLinearTVENonLinearTVP2DG3DMaterialLaw::setIsotropicHardeningCoefficients(const double HR1, const double HR2, const double HR3){ + _viscoLaw.setIsotropicHardeningCoefficients(HR1,HR2,HR3); +}; +void NonLinearTVENonLinearTVP2DG3DMaterialLaw::setPolynomialOrderChabocheCoeffs(const int order){ + _viscoLaw.setPolynomialOrderChabocheCoeffs(order); +}; +void NonLinearTVENonLinearTVP2DG3DMaterialLaw::setPolynomialCoeffsChabocheCoeffs(const int i, const double val){ + _viscoLaw.setPolynomialCoeffsChabocheCoeffs(i,val); +}; +void NonLinearTVENonLinearTVP2DG3DMaterialLaw::setReferenceTemperature(const double Tref){ + _viscoLaw.setReferenceTemperature(Tref); +}; +/* +void NonLinearTVENonLinearTVP2DG3DMaterialLaw::setTempFuncOption(const double TemFuncOpt){ // To be discarded + _viscoLaw.setTempFuncOption(TemFuncOpt); +}; +void NonLinearTVENonLinearTVP2DG3DMaterialLaw::setModelOption(const int modelFlag){ + _viscoLaw.setModelOption(modelFlag); +}; +void NonLinearTVENonLinearTVP2DG3DMaterialLaw::setTestOption(const int testFlag){ + _viscoLaw.setTestOption(testFlag); +}; +*/ +void NonLinearTVENonLinearTVP2DG3DMaterialLaw::setShiftFactorConstantsWLF(const double C1, const double C2){ + _viscoLaw.setShiftFactorConstantsWLF(C1,C2); +}; +void NonLinearTVENonLinearTVP2DG3DMaterialLaw::setTemperatureFunction_BulkModulus(const scalarFunction& Tfunc){ + _viscoLaw.setTemperatureFunction_BulkModulus(Tfunc); +}; +void NonLinearTVENonLinearTVP2DG3DMaterialLaw::setTemperatureFunction_ShearModulus(const scalarFunction& Tfunc){ + _viscoLaw.setTemperatureFunction_ShearModulus(Tfunc); +}; +void NonLinearTVENonLinearTVP2DG3DMaterialLaw::setTemperatureFunction_ThermalDilationCoefficient(const scalarFunction& Tfunc){ + _viscoLaw.setTemperatureFunction_ThermalDilationCoefficient(Tfunc); +}; +void NonLinearTVENonLinearTVP2DG3DMaterialLaw::setTemperatureFunction_ThermalConductivity(const scalarFunction& Tfunc){ + _viscoLaw.setTemperatureFunction_ThermalConductivity(Tfunc); +}; +void NonLinearTVENonLinearTVP2DG3DMaterialLaw::setTemperatureFunction_SpecificHeat(const scalarFunction& Tfunc){ + _viscoLaw.setTemperatureFunction_SpecificHeat(Tfunc); +}; +void NonLinearTVENonLinearTVP2DG3DMaterialLaw::setTemperatureFunction_ElasticCorrection_Bulk(const scalarFunction& Tfunc){ + _viscoLaw.setTemperatureFunction_ElasticCorrection_Bulk(Tfunc); +}; +void NonLinearTVENonLinearTVP2DG3DMaterialLaw::setTemperatureFunction_ElasticCorrection_Shear(const scalarFunction& Tfunc){ + _viscoLaw.setTemperatureFunction_ElasticCorrection_Shear(Tfunc); +}; +/* +void NonLinearTVENonLinearTVP2DG3DMaterialLaw::setTemperatureFunction_BranchBulkModuli(const scalarFunction& Tfunc, int i){ + _viscoLaw.setTemperatureFunction_BranchBulkModuli(Tfunc,i); +}; +void NonLinearTVENonLinearTVP2DG3DMaterialLaw::setTemperatureFunction_BranchShearModuli(const scalarFunction& Tfunc, int i){ + _viscoLaw.setTemperatureFunction_BranchShearModuli(Tfunc,i); +}; +void NonLinearTVENonLinearTVP2DG3DMaterialLaw::setTemperatureFunction_BranchThermalDilationCoefficient(const scalarFunction& Tfunc, int i){ + _viscoLaw.setTemperatureFunction_BranchThermalDilationCoefficient(Tfunc,i); +}; +*/ +void NonLinearTVENonLinearTVP2DG3DMaterialLaw::setCompressionHardening(const J2IsotropicHardening& comp){ + _viscoLaw.setCompressionHardening(comp); +}; +void NonLinearTVENonLinearTVP2DG3DMaterialLaw::setTractionHardening(const J2IsotropicHardening& trac){ + _viscoLaw.setTractionHardening(trac); +}; +void NonLinearTVENonLinearTVP2DG3DMaterialLaw::setKinematicHardening(const kinematicHardening& kin){ + _viscoLaw.setKinematicHardening(kin); +}; +void NonLinearTVENonLinearTVP2DG3DMaterialLaw::setViscosityEffect(const viscosityLaw& v, const double p){ + _viscoLaw.setViscosityEffect(v,p); +}; +void NonLinearTVENonLinearTVP2DG3DMaterialLaw::setMullinsEffect(const mullinsEffect& mullins){ + _viscoLaw.setMullinsEffect(mullins); +}; + +void NonLinearTVENonLinearTVP2DG3DMaterialLaw::setYieldPowerFactor(const double n){ + _viscoLaw.setPowerFactor(n); +}; +void NonLinearTVENonLinearTVP2DG3DMaterialLaw::nonAssociatedFlowRuleFactor(const double b){ + _viscoLaw.nonAssociatedFlowRuleFactor(b); +}; +void NonLinearTVENonLinearTVP2DG3DMaterialLaw::setPlasticPoissonRatio(const double nup){ + _viscoLaw.setPlasticPoissonRatio(nup); +}; +void NonLinearTVENonLinearTVP2DG3DMaterialLaw::setNonAssociatedFlow(const bool flag){ + _viscoLaw.setNonAssociatedFlow(flag); +}; + +void NonLinearTVENonLinearTVP2DG3DMaterialLaw::setTaylorQuineyFactor(const double f, const bool flag){ + _viscoLaw.setTaylorQuineyFactor(f, flag); +}; +void NonLinearTVENonLinearTVP2DG3DMaterialLaw::setTemperatureFunction_InitialYieldStress(const scalarFunction& Tfunc){ + _viscoLaw.setTemperatureFunction_InitialYieldStress(Tfunc); +}; +void NonLinearTVENonLinearTVP2DG3DMaterialLaw::setTemperatureFunction_Hardening(const scalarFunction& Tfunc){ + _viscoLaw.setTemperatureFunction_Hardening(Tfunc); +}; +void NonLinearTVENonLinearTVP2DG3DMaterialLaw::setTemperatureFunction_KinematicHardening(const scalarFunction& Tfunc){ + _viscoLaw.setTemperatureFunction_KinematicHardening(Tfunc); +}; +void NonLinearTVENonLinearTVP2DG3DMaterialLaw::setTemperatureFunction_Viscosity(const scalarFunction& Tfunc){ + _viscoLaw.setTemperatureFunction_Viscosity(Tfunc); +}; +void NonLinearTVENonLinearTVP2DG3DMaterialLaw::useExtraBranchBool(const bool useExtraBranch){ + _viscoLaw.useExtraBranchBool(useExtraBranch); +}; +void NonLinearTVENonLinearTVP2DG3DMaterialLaw::useExtraBranchBool_TVE(const bool useExtraBranch_TVE, const int ExtraBranch_TVE_option){ + _viscoLaw.useExtraBranchBool_TVE(useExtraBranch_TVE, ExtraBranch_TVE_option); +}; +void NonLinearTVENonLinearTVP2DG3DMaterialLaw::useRotationCorrectionBool(const bool useRotationCorrection, const int rotationCorrectionScheme){ + _viscoLaw.useRotationCorrectionBool(useRotationCorrection,rotationCorrectionScheme); +}; +void NonLinearTVENonLinearTVP2DG3DMaterialLaw::setVolumeCorrection(const double _vc, const double _xivc, const double _zetavc, const double _dc, const double _thetadc, const double _pidc){ + _viscoLaw.setVolumeCorrection(_vc,_xivc,_zetavc,_dc,_thetadc,_pidc); +}; +void NonLinearTVENonLinearTVP2DG3DMaterialLaw::setAdditionalVolumeCorrections(const double V3, const double V4, const double V5, const double D3, const double D4, const double D5){ + _viscoLaw.setAdditionalVolumeCorrections(V3,V4,V5,D3,D4,D5); +}; +void NonLinearTVENonLinearTVP2DG3DMaterialLaw::setExtraBranch_CompressionParameter(const double compCorrection, const double compCorrection_2, const double compCorrection_3){ + _viscoLaw.setExtraBranch_CompressionParameter(compCorrection,compCorrection_2,compCorrection_3); +}; +void NonLinearTVENonLinearTVP2DG3DMaterialLaw::setExtraBranchNLType(const int method){ + _viscoLaw.setExtraBranchNLType(method); +}; +void NonLinearTVENonLinearTVP2DG3DMaterialLaw::setTensionCompressionRegularisation(const double tensionCompressionRegularisation){ + _viscoLaw.setTensionCompressionRegularisation(tensionCompressionRegularisation); +}; +void NonLinearTVENonLinearTVP2DG3DMaterialLaw::setCorrectionsAllBranchesTVE(const int i, const double V0,const double V1, const double V2, const double D0,const double D1, const double D2){ + _viscoLaw.setCorrectionsAllBranchesTVE(i,V0,V1,V2,D0,D1,D2); +}; +void NonLinearTVENonLinearTVP2DG3DMaterialLaw::setAdditionalCorrectionsAllBranchesTVE(const int i, const double V3, const double V4, const double V5, const double D3, const double D4, const double D5){ + _viscoLaw.setAdditionalCorrectionsAllBranchesTVE(i,V3,V4,V5,D3,D4,D5); +}; +void NonLinearTVENonLinearTVP2DG3DMaterialLaw::setCompressionCorrectionsAllBranchesTVE(const int i, const double Ci){ + _viscoLaw.setCompressionCorrectionsAllBranchesTVE(i,Ci); +}; + +// Added extra argument in the NonLinearTVEDG3DIPVariable contructor - Tinitial (added from LinearThermoMech) +void NonLinearTVENonLinearTVP2DG3DMaterialLaw::createIPState(IPStateBase* &ips, bool hasBodyForce, const bool* state_,const MElement *ele, const int nbFF_, const IntPt *GP, const int gpt) const +{ + // check interface element + bool inter=true; + const MInterfaceElement *iele = dynamic_cast<const MInterfaceElement*>(ele); + if(iele==NULL) inter=false; + IPVariable* ipvi = new NonLinearTVPDG3DIPVariable(_viscoLaw,_viscoLaw.getInitialTemperature(),hasBodyForce,inter); // Why 3 times? --- WHAT?? Add getInitialTemperature in Material Law + IPVariable* ipv1 = new NonLinearTVPDG3DIPVariable(_viscoLaw,_viscoLaw.getInitialTemperature(),hasBodyForce,inter); + IPVariable* ipv2 = new NonLinearTVPDG3DIPVariable(_viscoLaw,_viscoLaw.getInitialTemperature(),hasBodyForce,inter); + if(ips != NULL) delete ips; + ips = new IP3State(state_,ipvi,ipv1,ipv2); +} + +void NonLinearTVENonLinearTVP2DG3DMaterialLaw::createIPVariable(IPVariable* &ipv, bool hasBodyForce, const MElement *ele, const int nbFF_, const IntPt *GP, const int gpt) const +{ + if(ipv !=NULL) delete ipv; + bool inter=true; + const MInterfaceElement *iele = dynamic_cast<const MInterfaceElement*>(ele); + if(iele == NULL){ + inter=false; + } + ipv = new NonLinearTVPDG3DIPVariable(_viscoLaw,_viscoLaw.getInitialTemperature(),hasBodyForce,inter); +} + +// 2 Member Functions added from LinearThermoMechanicsDG3DMaterialLaw -- Add these functions in the material law +double NonLinearTVENonLinearTVP2DG3DMaterialLaw::getExtraDofStoredEnergyPerUnitField(double T) const{ + return _viscoLaw.getExtraDofStoredEnergyPerUnitField(T); +} + +double NonLinearTVENonLinearTVP2DG3DMaterialLaw::getInitialExtraDofStoredEnergyPerUnitField() const{ + return _viscoLaw.getInitialExtraDofStoredEnergyPerUnitField(); +}; + +void NonLinearTVENonLinearTVP2DG3DMaterialLaw::checkInternalState(IPVariable* ipv, const IPVariable* ipvp) const{ + // get ipvariable + NonLinearTVPDG3DIPVariable* ipvcur; + const NonLinearTVPDG3DIPVariable* ipvprev; + FractureCohesive3DIPVariable* ipvtmp = dynamic_cast<FractureCohesive3DIPVariable*>(ipv); + if(ipvtmp !=NULL) + { + ipvcur = static_cast<NonLinearTVPDG3DIPVariable*>(ipvtmp->getIPvBulk()); + const FractureCohesive3DIPVariable *ipvtmp2 = static_cast<const FractureCohesive3DIPVariable*>(ipvp); + ipvprev = static_cast<const NonLinearTVPDG3DIPVariable*>(ipvtmp2->getIPvBulk()); + } + else + { + ipvcur = static_cast<NonLinearTVPDG3DIPVariable*>(ipv); + ipvprev = static_cast<const NonLinearTVPDG3DIPVariable*>(ipvp); + } + _viscoLaw.checkInternalState(ipvcur->getInternalData(), ipvprev->getInternalData()); +}; + +void NonLinearTVENonLinearTVP2DG3DMaterialLaw::stress(IPVariable* ipv, const IPVariable* ipvp, const bool stiff, const bool checkfrac, const bool dTangent){ + + // get ipvariable + NonLinearTVPDG3DIPVariable* ipvcur; + const NonLinearTVPDG3DIPVariable* ipvprev; + FractureCohesive3DIPVariable* ipvtmp = dynamic_cast<FractureCohesive3DIPVariable*>(ipv); + if(ipvtmp !=NULL) + { + ipvcur = static_cast<NonLinearTVPDG3DIPVariable*>(ipvtmp->getIPvBulk()); + const FractureCohesive3DIPVariable *ipvtmp2 = static_cast<const FractureCohesive3DIPVariable*>(ipvp); + ipvprev = static_cast<const NonLinearTVPDG3DIPVariable*>(ipvtmp2->getIPvBulk()); + } + else + { + ipvcur = static_cast<NonLinearTVPDG3DIPVariable*>(ipv); + ipvprev = static_cast<const NonLinearTVPDG3DIPVariable*>(ipvp); + } + +// All IP Variables passed to the Constitutive function defined in mlaw + const STensor3& F1 = ipvcur->getConstRefToDeformationGradient(); + const STensor3& F0 = ipvprev->getConstRefToDeformationGradient(); + const double T = ipvcur->getConstRefToTemperature(); + const double T0 = ipvprev->getConstRefToTemperature(); + const SVector3& gradT0 = ipvprev->getConstRefToGradT(); + const SVector3& gradT = ipvcur->getConstRefToGradT(); + STensor3& dPdT = ipvcur->getRefTodPdT(); + SVector3& fluxT = ipvcur->getRefToThermalFlux(); + STensor3& dqdgradT = ipvcur->getRefTodThermalFluxdGradT(); + SVector3& dqdT = ipvcur->getRefTodThermalFluxdT(); + STensor33& dqdF = ipvcur->getRefTodThermalFluxdF(); + + STensor3& P = ipvcur->getRefToFirstPiolaKirchhoffStress(); + STensor43& Tangent = ipvcur->getRefToTangentModuli(); + const double& w0 = ipvprev->getConstRefToThermalSource(); + double& w = ipvcur->getRefToThermalSource(); + double& dwdt = ipvcur->getRefTodThermalSourcedField(); + STensor3& dwdf = ipvcur->getRefTodThermalSourcedF(); + const SVector3& N = ipvcur->getRefToReferenceOutwardNormal(); + const SVector3& ujump = ipvcur->getRefToJump()(0); + const double& Tjump = ipvcur->getRefToFieldJump()(0); + double& Cp = ipvcur->getRefToExtraDofFieldCapacityPerUnitField()(0); + const double& mechSource0 = ipvprev->getConstRefToMechanicalSource()(0); + double& mechSource = ipvcur->getRefToMechanicalSource()(0); + double& dmechSourcedt = ipvcur->getRefTodMechanicalSourcedField()(0,0); + STensor3& dmechSourcedf = ipvcur->getRefTodMechanicalSourcedF()[0]; + + // data for J2 law + IPNonLinearTVP* q1 = ipvcur->getIPNonLinearTVP(); + const IPNonLinearTVP* q0 = ipvprev->getIPNonLinearTVP(); + // static STensor63 dCalgdeps; + STensor43& elasticL = ipvcur->getRefToElasticTangentModuli(); + + // Compute Stress + _viscoLaw.constitutive(F0,F1,P,q0,q1,Tangent,T0,T,gradT0,gradT,fluxT,dPdT,dqdgradT,dqdT,dqdF,w,dwdt,dwdf,mechSource,dmechSourcedt,dmechSourcedf,stiff,&elasticL); + + ipvcur->setRefToDGElasticTangentModuli(this->elasticStiffness); + ipvcur->setRefToLinearConductivity(_viscoLaw.getConductivityTensor()); + ipvcur->setRefToStiff_alphaDilatation(_viscoLaw.getStiff_alphaDilatation()); + + Cp = _viscoLaw.getExtraDofStoredEnergyPerUnitField(T); +} + +// NonLinearTVENonLinearTVP2 Law Interface =================================================================== END diff --git a/dG3D/src/dG3DMaterialLaw.h b/dG3D/src/dG3DMaterialLaw.h index 9c805dd5dcec27e7224417f05bd3457e45bbe432..4ca7436a27e53ef31ba02cb8453b5ca8361e3104 100644 --- a/dG3D/src/dG3DMaterialLaw.h +++ b/dG3D/src/dG3DMaterialLaw.h @@ -58,6 +58,7 @@ #include "mlawNonLinearTVE.h" #include "mlawNonLinearTVP.h" #include "mlawNonLinearTVENonLinearTVP.h" +#include "mlawNonLinearTVENonLinearTVP2.h" #include "mullinsEffect.h" #include "mlawHyperelasticWithPotential.h" #endif @@ -3335,6 +3336,7 @@ class NonLinearTVMDG3DMaterialLaw : public dG3DMaterialLaw{ // public Material void setShiftFactorConstantsWLF(const double C1, const double C2); void useExtraBranchBool(const bool useExtraBranch); void useExtraBranchBool_TVE(const bool useExtraBranch_TVE, const int ExtraBranch_TVE_option); + void useRotationCorrectionBool(const bool useRotationCorrection, const int rotationCorrectionScheme); void setTemperatureFunction_BulkModulus(const scalarFunction& Tfunc); void setTemperatureFunction_ShearModulus(const scalarFunction& Tfunc); void setTemperatureFunction_ThermalDilationCoefficient(const scalarFunction& Tfunc); @@ -3632,6 +3634,7 @@ class NonLinearTVENonLinearTVPDG3DMaterialLaw : public dG3DMaterialLaw{ // pub // void setTemperatureFunction_BranchThermalDilationCoefficient(const scalarFunction& Tfunc,int i); void useExtraBranchBool(const bool useExtraBranch); void useExtraBranchBool_TVE(const bool useExtraBranch_TVE, const int ExtraBranch_TVE_option); + void useRotationCorrectionBool(const bool useRotationCorrection, const int rotationCorrectionScheme); void setVolumeCorrection(const double _vc, const double _xivc, const double _zetavc, const double _dc, const double _thetadc, const double _pidc); void setAdditionalVolumeCorrections(const double V3, const double V4, const double V5, const double D3, const double D4, const double D5); void setExtraBranch_CompressionParameter(const double compCorrection, const double compCorrection_2, const double compCorrection_3); @@ -3700,4 +3703,115 @@ class NonLinearTVENonLinearTVPDG3DMaterialLaw : public dG3DMaterialLaw{ // pub // NonLinearTVENonLinearTVP Law Interface =================================================================== END +// NonLinearTVENonLinearTVP2 Law Interface =================================================================== START + +class NonLinearTVENonLinearTVP2DG3DMaterialLaw : public dG3DMaterialLaw{ // public MaterialLaw + #ifndef SWIG + protected: + mlawNonLinearTVENonLinearTVP2 _viscoLaw; + + #endif //SWIG + public: + NonLinearTVENonLinearTVP2DG3DMaterialLaw(const int num, const double rho, const double E, const double nu, const double tol, + const double Tinitial, const double Alpha, const double KThCon, const double Cp, + const bool matrixbyPerturbation = false, const double pert = 1e-8, const double stressIteratorTol = 1e-9, const bool thermalEstimationPreviousConfig = false); + + void setStrainOrder(const int order); + void setViscoelasticMethod(const int method); + void setViscoElasticNumberOfElement(const int N); + void setViscoElasticData(const int i, const double Ei, const double taui); + // void setViscoElasticData(const int i, const double Ei, const double taui, const double Alphai); + void setViscoElasticData_Bulk(const int i, const double Ki, const double ki); + void setViscoElasticData_Shear(const int i, const double Gi, const double gi); + // void setViscoElasticData_Alpha(const int i, const double Alphai); + void setViscoElasticData(const std::string filename); + void setIsotropicHardeningCoefficients(const double HR1, const double HR2, const double HR3); + void setPolynomialOrderChabocheCoeffs(const int order); + void setPolynomialCoeffsChabocheCoeffs(const int i, const double val); + + void setReferenceTemperature(const double Tref); + // void setTempFuncOption(const double TemFuncOpt); + // void setModelOption(const int modelFlag); + // void setTestOption(const int testFlag); + void setShiftFactorConstantsWLF(const double C1, const double C2); + void setTemperatureFunction_BulkModulus(const scalarFunction& Tfunc); + void setTemperatureFunction_ShearModulus(const scalarFunction& Tfunc); + void setTemperatureFunction_ThermalDilationCoefficient(const scalarFunction& Tfunc); + void setTemperatureFunction_ThermalConductivity(const scalarFunction& Tfunc); + void setTemperatureFunction_SpecificHeat(const scalarFunction& Tfunc); + void setTemperatureFunction_ElasticCorrection_Bulk(const scalarFunction& Tfunc); + void setTemperatureFunction_ElasticCorrection_Shear(const scalarFunction& Tfunc); + // void setTemperatureFunction_BranchBulkModuli(const scalarFunction& Tfunc,int i); + // void setTemperatureFunction_BranchShearModuli(const scalarFunction& Tfunc,int i); + // void setTemperatureFunction_BranchThermalDilationCoefficient(const scalarFunction& Tfunc,int i); + void useExtraBranchBool(const bool useExtraBranch); + void useExtraBranchBool_TVE(const bool useExtraBranch_TVE, const int ExtraBranch_TVE_option); + void useRotationCorrectionBool(const bool useRotationCorrection, const int rotationCorrectionScheme); + void setVolumeCorrection(const double _vc, const double _xivc, const double _zetavc, const double _dc, const double _thetadc, const double _pidc); + void setAdditionalVolumeCorrections(const double V3, const double V4, const double V5, const double D3, const double D4, const double D5); + void setExtraBranch_CompressionParameter(const double compCorrection, const double compCorrection_2, const double compCorrection_3); + void setExtraBranchNLType(const int type); + void setTensionCompressionRegularisation(const double tensionCompressionRegularisation); + void setCorrectionsAllBranchesTVE(const int i, const double V0,const double V1, const double V2, const double D0, const double D1, const double D2); + void setAdditionalCorrectionsAllBranchesTVE(const int i, const double V3, const double V4, const double V5, const double D3, const double D4, const double D5); + void setCompressionCorrectionsAllBranchesTVE(const int i, const double Ci); + + void setCompressionHardening(const J2IsotropicHardening& comp); + void setTractionHardening(const J2IsotropicHardening& trac); + void setKinematicHardening(const kinematicHardening& kin); + void setViscosityEffect(const viscosityLaw& v, const double p); + void setMullinsEffect(const mullinsEffect& mullins); + + void setYieldPowerFactor(const double n); + void nonAssociatedFlowRuleFactor(const double b); + void setPlasticPoissonRatio(const double nup); + void setNonAssociatedFlow(const bool flag); + + void setTaylorQuineyFactor(const double f, const bool flag = false); + void setTemperatureFunction_InitialYieldStress(const scalarFunction& Tfunc); + void setTemperatureFunction_Hardening(const scalarFunction& Tfunc); + void setTemperatureFunction_KinematicHardening(const scalarFunction& Tfunc); + void setTemperatureFunction_Viscosity(const scalarFunction& Tfunc); + + #ifndef SWIG + NonLinearTVENonLinearTVP2DG3DMaterialLaw(const NonLinearTVENonLinearTVP2DG3DMaterialLaw &source); + virtual ~NonLinearTVENonLinearTVP2DG3DMaterialLaw(){} + // set the time of _j2law + virtual void setTime(const double t,const double dtime){ + dG3DMaterialLaw::setTime(t,dtime); + _viscoLaw.setTime(t,dtime); + } + virtual materialLaw::matname getType() const {return _viscoLaw.getType();} + virtual void createIPState(IPStateBase* &ips, bool hasBodyForce, const bool* state_=NULL,const MElement *ele=NULL, const int nbFF_=0, const IntPt *GP=NULL, const int gpt = 0) const; + virtual void createIPVariable(IPVariable* &ipv, bool hasBodyForce, const MElement *ele, const int nbFF_, const IntPt *GP, const int gpt) const; + virtual void initLaws(const std::map<int,materialLaw*> &maplaw){} + virtual double soundSpeed() const{return _viscoLaw.soundSpeed();} // or change value ?? + virtual void stress(IPVariable*ipv, const IPVariable*ipvprev, const bool stiff=true, const bool checkfrac=true, const bool dTangent=false); + virtual const double bulkModulus() const {return _viscoLaw.bulkModulus();} + virtual double scaleFactor() const{return _viscoLaw.scaleFactor();} + + virtual int getNumberOfExtraDofsDiffusion() const {return 1;} + virtual double getExtraDofStoredEnergyPerUnitField(double T) const; + virtual double getInitialExtraDofStoredEnergyPerUnitField() const; + + virtual materialLaw* clone() const{return new NonLinearTVENonLinearTVP2DG3DMaterialLaw(*this);}; + virtual void checkInternalState(IPVariable* ipv, const IPVariable* ipvprev) const; + virtual bool withEnergyDissipation() const {return _viscoLaw.withEnergyDissipation();}; + virtual void setMacroSolver(const nonLinearMechSolver* sv){ + dG3DMaterialLaw::setMacroSolver(sv); + _viscoLaw.setMacroSolver(sv); + }; + + virtual const materialLaw *getConstNonLinearSolverMaterialLaw() const + { + return &_viscoLaw; + } + virtual materialLaw *getNonLinearSolverMaterialLaw() + { + return &_viscoLaw; + } + #endif //SWIG +}; + +// NonLinearTVENonLinearTVP2 Law Interface =================================================================== END #endif