diff --git a/NonLinearSolver/internalPoints/CMakeLists.txt b/NonLinearSolver/internalPoints/CMakeLists.txt index 845ba8b53bab570c8fbfebcafdcd957c9c297dcd..83a0969341c50a3c734b7cbb0757e9641d220707 100644 --- a/NonLinearSolver/internalPoints/CMakeLists.txt +++ b/NonLinearSolver/internalPoints/CMakeLists.txt @@ -64,6 +64,7 @@ set(SRC ipNonLinearTVM.cpp ipNonLinearTVE.cpp ipNonLinearTVP.cpp + ipMullinsEffect.cpp ) file(GLOB HDR RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.h) diff --git a/NonLinearSolver/internalPoints/ipField.cpp b/NonLinearSolver/internalPoints/ipField.cpp index f653c6f9a7aa1a520305f97e89dca3a0ed71f24e..a1894e700547af65a0de4ff82478bd514c120171 100644 --- a/NonLinearSolver/internalPoints/ipField.cpp +++ b/NonLinearSolver/internalPoints/ipField.cpp @@ -1034,6 +1034,29 @@ std::string IPField::ToString(const int i){ else if (i == Eve2_XY) return "Eve2_XY"; else if (i == Eve2_XZ) return "Eve2_XZ"; else if (i == Eve2_YZ) return "Eve2_YZ"; + else if (i == corKir_XX) return "corKir_XX"; + else if (i == corKir_YY) return "corKir_YY"; + else if (i == corKir_ZZ) return "corKir_ZZ"; + 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 == corKirExtra_XX) return "corKirExtra_XX"; + else if (i == corKirExtra_YY) return "corKirExtra_YY"; + else if (i == corKirExtra_ZZ) return "corKirExtra_ZZ"; + else if (i == corKirExtra_XY) return "corKirExtra_XY"; + else if (i == corKirExtra_XZ) return "corKirExtra_XZ"; + else if (i == corKirExtra_YZ) return "corKirExtra_YZ"; + else if (i == Dev_corKir_Inf_XX) return "Dev_corKir_Inf_XX"; + else if (i == Dev_corKir_Inf_YY) return "Dev_corKir_Inf_YY"; + else if (i == Dev_corKir_Inf_ZZ) return "Dev_corKir_Inf_ZZ"; + else if (i == Dev_corKir_Inf_XY) return "Dev_corKir_Inf_XY"; + else if (i == Dev_corKir_Inf_XZ) return "Dev_corKir_Inf_XZ"; + else if (i == Dev_corKir_Inf_YZ) return "Dev_corKir_Inf_YZ"; + else if (i == Tr_corKir_Inf) return "Tr_corKir_Inf"; + else if (i == hyperElastic_BulkScalar) return "hyperElastic_BulkScalar"; + else if (i == hyperElastic_ShearScalar) return "hyperElastic_ShearScalar"; + else if (i == MAX_DEFO_ENERGY) return "MAX_DEFO_ENERGY"; + else if (i == MULLINS_DAMAGE) return "MULLINS_DAMAGE"; else if (i == USER1) return "USER1"; else if (i == USER2) return "USER2"; else if (i == USER3) return "USER3"; diff --git a/NonLinearSolver/internalPoints/ipField.h b/NonLinearSolver/internalPoints/ipField.h index 7fa320ea097e5cb372309c9542c2d041ff250087..ca42944b3d632f3efd0d158fff6687920b8e91d5 100644 --- a/NonLinearSolver/internalPoints/ipField.h +++ b/NonLinearSolver/internalPoints/ipField.h @@ -323,6 +323,10 @@ 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, + 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, USER0,USER1,USER2,USER3,USER4,USER5,USER6,USER7,USER8,USER9,USER10, MAGNETICVECTORPOTENTIAL_X, MAGNETICVECTORPOTENTIAL_Y, MAGNETICVECTORPOTENTIAL_Z, MAGNETICINDUCTION_X, MAGNETICINDUCTION_Y, MAGNETICINDUCTION_Z, @@ -333,6 +337,8 @@ class IPField : public elementsField { EQUIVALENT_EIGENSTRESS,EQUIVALENT_EIGENSTRAIN, EIGENSTRESS_XX, EIGENSTRESS_YY, EIGENSTRESS_ZZ, EIGENSTRESS_XY, EIGENSTRESS_XZ, EIGENSTRESS_YZ, EIGENSTRAIN_XX, EIGENSTRAIN_YY, EIGENSTRAIN_ZZ, EIGENSTRAIN_XY, EIGENSTRAIN_XZ, EIGENSTRAIN_YZ, + // moduli scalers e.g. mullins effect + MAX_DEFO_ENERGY, MULLINS_DAMAGE, UNDEFINED}; enum Operator { MEAN_VALUE=1, MIN_VALUE, MAX_VALUE, CRUDE_VALUE}; static std::string ToString(const int i); diff --git a/NonLinearSolver/internalPoints/ipHardening.cpp b/NonLinearSolver/internalPoints/ipHardening.cpp index f71905e98f715f3a3c9779ed6777b9849601b507..423e11074a1029fca64b198e4f1d42931da42ec1 100644 --- a/NonLinearSolver/internalPoints/ipHardening.cpp +++ b/NonLinearSolver/internalPoints/ipHardening.cpp @@ -11,13 +11,14 @@ #include "restartManager.h" IPJ2IsotropicHardening::IPJ2IsotropicHardening(const double R0_): - R0(R0_), R(R0_), dR(0.), ddR(0.), integR(0.),_isSaturated(false),dRdT(0.), ddRdTT(0.), wp(0.), dwp(0.) + R0(R0_), R(R0_), dR(0.), ddR(0.), integR(0.),_isSaturated(false),dRdT(0.), ddRdTT(0.), ddRdT(0.), wp(0.), dwp(0.) { } IPJ2IsotropicHardening::IPJ2IsotropicHardening(const IPJ2IsotropicHardening &source): - R0(source.R0), R(source.R), dR (source.dR), ddR (source.ddR),integR(source.integR),_isSaturated(source._isSaturated), dRdT(source.dRdT), ddRdTT(source.ddRdTT), + R0(source.R0), R(source.R), dR (source.dR), ddR (source.ddR),integR(source.integR),_isSaturated(source._isSaturated), + dRdT(source.dRdT), ddRdTT(source.ddRdTT), ddRdT(source.ddRdT), wp(source.wp), dwp(source.dwp) { @@ -33,6 +34,7 @@ IPJ2IsotropicHardening &IPJ2IsotropicHardening::operator=(const IPJ2IsotropicHar _isSaturated = src._isSaturated; dRdT = src.dRdT; ddRdTT = src.ddRdTT; + ddRdT = src.ddRdT; wp = src.wp; dwp = src.dwp; return *this; @@ -48,6 +50,7 @@ void IPJ2IsotropicHardening::restart() restartManager::restart(_isSaturated); restartManager::restart(dRdT); restartManager::restart(ddRdTT); + restartManager::restart(ddRdT); restartManager::restart(wp); restartManager::restart(dwp); return; diff --git a/NonLinearSolver/internalPoints/ipHardening.h b/NonLinearSolver/internalPoints/ipHardening.h index c62fbf01b7df159e43d4b3176c4c94682ef4415d..be17f906b42440df05ba902269a11357292ce593 100644 --- a/NonLinearSolver/internalPoints/ipHardening.h +++ b/NonLinearSolver/internalPoints/ipHardening.h @@ -28,6 +28,7 @@ protected: bool _isSaturated; // harderning modulus become 0 under some conditions double dRdT; // temeprature dependence double ddRdTT; // + double ddRdT; // ddR/dgdT double wp; //yield shrink because of plastic instability double dwp; @@ -50,9 +51,11 @@ protected: virtual double getIntegR() const {return (1-wp)*integR;} virtual double getDRDT() const{ return (1-wp)*dRdT;}; virtual double getDDRDTT() const{ return (1-wp)*ddRdTT;}; + virtual double getDDRDT() const{ return (1-wp)*ddRdT;}; virtual double getWp() const{ return wp;}; virtual double getDWp() const{ return dwp;}; - virtual void set(const double &_r0, const double &_r, const double &_dr, const double &_ddr, const double &_integR, const double& _dRdT, const double& _ddRdTT) final + virtual void set(const double &_r0, const double &_r, const double &_dr, const double &_ddr, const double &_integR, + const double& _dRdT, const double& _ddRdTT, const double& _ddRdT) final { R0 = _r0; R=_r; @@ -61,6 +64,7 @@ protected: integR=_integR; dRdT = _dRdT; ddRdTT = _ddRdTT; + ddRdT = _ddRdT; } virtual void setScaleFactor(double _wp, double _dwp) final { diff --git a/NonLinearSolver/internalPoints/ipHyperelastic.cpp b/NonLinearSolver/internalPoints/ipHyperelastic.cpp index deb6de3487d4ca5ae472debd166498fbd64f3acb..b7d279379c0b11218a0ae93c00c66ed0dfe43360 100644 --- a/NonLinearSolver/internalPoints/ipHyperelastic.cpp +++ b/NonLinearSolver/internalPoints/ipHyperelastic.cpp @@ -14,7 +14,7 @@ #include "STensorOperations.h" 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.) + _irreversibleEnergy(0.),_DirreversibleEnergyDF(0.), _viscousEnergyPart(0.), _dElasticEnergyPartdF(0.), _dViscousEnergyPartdF(0.), _elasticBulkPropertyScaleFactor(1.), _elasticShearPropertyScaleFactor(1.), _intA(0.), _intB(0.) { _A.clear(); _B.clear(); @@ -28,7 +28,7 @@ IPHyperViscoElastic::IPHyperViscoElastic(const IPHyperViscoElastic& src): IPVari _N(src._N),_A(src._A),_B(src._B),_elasticEnergy(src._elasticEnergy), _kirchhoff(src._kirchhoff), _irreversibleEnergy(src._irreversibleEnergy),_DirreversibleEnergyDF(src._DirreversibleEnergyDF), _viscousEnergyPart(src._viscousEnergyPart), _dElasticEnergyPartdF(src._dElasticEnergyPartdF), - _dViscousEnergyPartdF(src._dViscousEnergyPartdF), _elasticBulkPropertyScaleFactor(src._elasticBulkPropertyScaleFactor), _elasticShearPropertyScaleFactor(src._elasticShearPropertyScaleFactor) + _dViscousEnergyPartdF(src._dViscousEnergyPartdF), _elasticBulkPropertyScaleFactor(src._elasticBulkPropertyScaleFactor), _elasticShearPropertyScaleFactor(src._elasticShearPropertyScaleFactor),_intA(src._intA),_intB(src._intB) { @@ -51,6 +51,8 @@ IPHyperViscoElastic& IPHyperViscoElastic::operator =(const IPVariable& src){ _dViscousEnergyPartdF = psrc->_dViscousEnergyPartdF; _elasticBulkPropertyScaleFactor= psrc->_elasticBulkPropertyScaleFactor; _elasticShearPropertyScaleFactor= psrc->_elasticShearPropertyScaleFactor; + _intA= psrc->_intA; + _intB= psrc->_intB; } return *this; }; @@ -70,6 +72,8 @@ void IPHyperViscoElastic::restart() { restartManager::restart(_dViscousEnergyPartdF); restartManager::restart(_elasticBulkPropertyScaleFactor); restartManager::restart(_elasticShearPropertyScaleFactor); + restartManager::restart(_intA); + restartManager::restart(_intB); }; void IPHyperViscoElastic::getViscoElasticStrain(int i, STensor3& Ev) const diff --git a/NonLinearSolver/internalPoints/ipHyperelastic.h b/NonLinearSolver/internalPoints/ipHyperelastic.h index e15a2742f16b6b43abeafc0ac32f111fc67f4f2e..8573370572505414133c3c7ee7d59fd248a1cd23 100644 --- a/NonLinearSolver/internalPoints/ipHyperelastic.h +++ b/NonLinearSolver/internalPoints/ipHyperelastic.h @@ -31,6 +31,8 @@ class IPHyperViscoElastic : public IPVariableMechanics{ double _elasticBulkPropertyScaleFactor; double _elasticShearPropertyScaleFactor; + double _intA; // intA = psi_ExtraBranch/Kinf + double _intB; // intB = psi_ExtraBranch/Ginf protected: //For energy sources diff --git a/NonLinearSolver/internalPoints/ipKinematicHardening.cpp b/NonLinearSolver/internalPoints/ipKinematicHardening.cpp index 923b60aed8d69b75728abdc9d0f3199a14db3bb2..5b087c015900df0d8b35cc784fc9ed7ddf93f979 100644 --- a/NonLinearSolver/internalPoints/ipKinematicHardening.cpp +++ b/NonLinearSolver/internalPoints/ipKinematicHardening.cpp @@ -10,7 +10,7 @@ #include "ipKinematicHardening.h" -IPKinematicHardening::IPKinematicHardening(): R(0), dR(0), ddR(0), dRdT(0.), ddRddT(0.), _isSaturated(false) +IPKinematicHardening::IPKinematicHardening(): R(0), dR(0), ddR(0), dRdT(0.), ddRdTT(0.), ddRdT(0.), _isSaturated(false) { } @@ -21,7 +21,8 @@ IPKinematicHardening::IPKinematicHardening(const IPKinematicHardening &source) dR = source.dR; ddR = source.ddR; dRdT = source.dRdT; - ddRddT = source.ddRddT; + ddRdTT = source.ddRdTT; + ddRdT = source.ddRdT; _isSaturated= source._isSaturated; } @@ -31,7 +32,8 @@ IPKinematicHardening &IPKinematicHardening::operator=(const IPKinematicHardening dR = source.dR; ddR = source.ddR; dRdT = source.dRdT; - ddRddT = source.ddRddT; + ddRdTT = source.ddRdTT; + ddRdT = source.ddRdT; _isSaturated = source._isSaturated; return *this; } @@ -42,7 +44,8 @@ void IPKinematicHardening::restart() restartManager::restart(dR); restartManager::restart(ddR); restartManager::restart(dRdT); - restartManager::restart(ddRddT); + restartManager::restart(ddRdTT); + restartManager::restart(ddRdT); restartManager::restart(_isSaturated); return; } diff --git a/NonLinearSolver/internalPoints/ipKinematicHardening.h b/NonLinearSolver/internalPoints/ipKinematicHardening.h index f47257462cc9845ef513d2c273156b131e8ed6c3..29b49edd5762df0b3f76c2e9cb1a7e83a4f41050 100644 --- a/NonLinearSolver/internalPoints/ipKinematicHardening.h +++ b/NonLinearSolver/internalPoints/ipKinematicHardening.h @@ -16,10 +16,11 @@ class IPKinematicHardening{ protected: double R; - double dR; - double ddR; - double dRdT; // temeprature dependence - double ddRddT; + double dR; // dR/dg where, g = gamma (eqv. plastic strain) + double ddR; // ddR/dgdg + double dRdT; // temperature dependence + double ddRdTT; // ddR/dTdT + double ddRdT; // ddR/dgdT bool _isSaturated; @@ -39,14 +40,16 @@ class IPKinematicHardening{ virtual double getDR() const {return dR;} virtual double getDDR() const {return ddR;}; virtual double getDRDT() const{ return dRdT;}; - virtual double getDDRDDT() const{ return ddRddT;}; - virtual void set(const double &_r, const double &_dr, const double& _ddr, const double& _dRdT, const double& _ddRddT) + virtual double getDDRDTT() const{ return ddRdTT;}; + virtual double getDDRDT() const{ return ddRdT;}; + virtual void set(const double &_r, const double &_dr, const double& _ddr, const double& _dRdT, const double& _ddRdTT, const double& _ddRdT) { R=_r; dR=_dr; ddR = _ddr; dRdT = _dRdT; - ddRddT = _ddRddT; + ddRdTT = _ddRdTT; + ddRdT = _ddRdT; } }; diff --git a/NonLinearSolver/internalPoints/ipMullinsEffect.cpp b/NonLinearSolver/internalPoints/ipMullinsEffect.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b4bba50b44bd1a21b66e4ab886ec41bb20f8e9ba --- /dev/null +++ b/NonLinearSolver/internalPoints/ipMullinsEffect.cpp @@ -0,0 +1,48 @@ +// +// Description: storing class for Mullins Effect +// +// +// Author: <Ujwal Kishore J.>, (C) 2023 +// +// Copyright: See COPYING file that comes with this distribution +// +// + +#include "ipMullinsEffect.h" + +IPMullinsEffect::IPMullinsEffect(): eta(1.0), DetaDpsi(0.), DDetaDpsipsi(0.), DetaDT(0.), DDetaDTT(0.), psiMax(0.) +{ + +} + +IPMullinsEffect::IPMullinsEffect(const IPMullinsEffect &source) +{ + eta = source.eta; + DetaDpsi = source.DetaDpsi; + DDetaDpsipsi = source.DDetaDpsipsi; + DetaDT = source.DetaDT; + DDetaDTT = source.DDetaDTT; + psiMax = source.psiMax; +} + +IPMullinsEffect &IPMullinsEffect::operator=(const IPMullinsEffect &source) +{ + eta = source.eta; + DetaDpsi = source.DetaDpsi; + DDetaDpsipsi = source.DDetaDpsipsi; + DetaDT = source.DetaDT; + DDetaDTT = source.DDetaDTT; + psiMax = source.psiMax; + return *this; +} + +void IPMullinsEffect::restart() +{ + restartManager::restart(eta); + restartManager::restart(DetaDpsi); + restartManager::restart(DDetaDpsipsi); + restartManager::restart(DetaDT); + restartManager::restart(DDetaDTT); + restartManager::restart(psiMax); + return; +} diff --git a/NonLinearSolver/internalPoints/ipMullinsEffect.h b/NonLinearSolver/internalPoints/ipMullinsEffect.h new file mode 100644 index 0000000000000000000000000000000000000000..1aa95461375b460ccedf28873e91bab4606aa62e --- /dev/null +++ b/NonLinearSolver/internalPoints/ipMullinsEffect.h @@ -0,0 +1,55 @@ +// +// Description: storing class for Mullins Effect +// +// +// Author: <Ujwal Kishore J.>, (C) 2023 +// +// Copyright: See COPYING file that comes with this distribution +// +// + +#ifndef IPMULLINSEFFECT_H_ +#define IPMULLINSEFFECT_H_ + +#include "ipHardening.h" + +class IPMullinsEffect{ + + protected: + double eta; // scaling variable + double DetaDpsi; + double DDetaDpsipsi; + double DetaDT; + double DDetaDTT; + double psiMax; + + public: + IPMullinsEffect(); + IPMullinsEffect(const IPMullinsEffect &source); + virtual IPMullinsEffect &operator=(const IPMullinsEffect &source); + virtual ~IPMullinsEffect(){} + virtual void restart(); + + virtual IPMullinsEffect * clone() const {return new IPMullinsEffect(*this);}; + + virtual double getEta() const {return eta;} + virtual double getDetaDpsi() const {return DetaDpsi;} + virtual double getDDetaDpsipsi() const {return DDetaDpsipsi;}; + virtual double getDetaDT() const{ return DetaDT;}; + virtual double getDDetaDTT() const{ return DDetaDTT;}; + virtual double getpsiMax() const{ return psiMax;}; + virtual void set(const double &_eta, const double &_DetaDpsi, const double& _DDetaDpsipsi, const double& _DetaDT, const double& _DDetaDTT) + { + eta=_eta; + DetaDpsi=_DetaDpsi; + DDetaDpsipsi = _DDetaDpsipsi; + DetaDT = _DetaDT; + DDetaDTT = _DDetaDTT; + } + virtual void setPsiMax(const double &_psiMax){ + psiMax = _psiMax; + } +}; + + +#endif // IPMULLINSEFFECT_H_ diff --git a/NonLinearSolver/internalPoints/ipNonLinearTVE.cpp b/NonLinearSolver/internalPoints/ipNonLinearTVE.cpp index 3b9e0ae670bb61dc0824d24e4a26401cff828c15..83eb3464878373fda590380408280cd5ef495a26 100644 --- a/NonLinearSolver/internalPoints/ipNonLinearTVE.cpp +++ b/NonLinearSolver/internalPoints/ipNonLinearTVE.cpp @@ -15,10 +15,11 @@ IPNonLinearTVE::IPNonLinearTVE(const J2IsotropicHardening* comp, const J2IsotropicHardening* trac, - const kinematicHardening* kin, const int N): IPHyperViscoElastoPlastic(comp,trac,kin,N), // IPHyperViscoElastic(N), + const kinematicHardening* kin, const int N, const mullinsEffect* mullins): IPHyperViscoElastoPlastic(comp,trac,kin,N), // IPHyperViscoElastic(N), _T(298.15),_devDE(0.),_trDE(0.),_DE(0.),_DcorKirDT(0.),_DDcorKirDTT(0.), _mechSrcTVE(0.),_DmechSrcTVEdT(0.),_DmechSrcTVEdF(0.), - _thermalEnergy(0.),_dtShift(0.),_DdtShiftDT(0.),_DDdtShiftDDT(0.){ + _thermalEnergy(0.),_dtShift(0.),_DdtShiftDT(0.),_DDdtShiftDDT(0.), _psiMax(0.), + _trCorKirinf_TVE(0.), _devCorKirinf_TVE(0.), _corKirExtra(0.), _mullinsDamage(0.){ _devOGammai.clear(); _trOGammai.clear(); _devDOGammaiDT.clear(); @@ -53,6 +54,9 @@ IPNonLinearTVE::IPNonLinearTVE(const J2IsotropicHardening* comp, _G.push_back(0.); } + _ipMullinsEffect = NULL; + if (mullins!= NULL) mullins->createIPVariable(_ipMullinsEffect); + }; IPNonLinearTVE::IPNonLinearTVE(const IPNonLinearTVE& src): IPHyperViscoElastoPlastic(src), //IPHyperViscoElastic(src), @@ -63,7 +67,15 @@ IPNonLinearTVE::IPNonLinearTVE(const IPNonLinearTVE& src): IPHyperViscoElastoPla _mechSrcTVE(src._mechSrcTVE),_DmechSrcTVEdT(src._DmechSrcTVEdT),_DmechSrcTVEdF(src._DmechSrcTVEdF), _C(src._C),_D(src._D), _E(src._E), _F(src._F), _G(src._G), _thermalEnergy(src._thermalEnergy), - _dtShift(src._dtShift),_DdtShiftDT(src._DdtShiftDT),_DDdtShiftDDT(src._DDdtShiftDDT){}; + _dtShift(src._dtShift),_DdtShiftDT(src._DdtShiftDT),_DDdtShiftDDT(src._DDdtShiftDDT), _psiMax(src._psiMax), + _trCorKirinf_TVE(src._trCorKirinf_TVE), _devCorKirinf_TVE(src._devCorKirinf_TVE), _corKirExtra(src._corKirExtra), _mullinsDamage(src._mullinsDamage){ + + if (src._ipMullinsEffect != NULL) + _ipMullinsEffect = dynamic_cast<IPMullinsEffect*>(src._ipMullinsEffect->clone()); + else + _ipMullinsEffect = NULL; + +}; IPNonLinearTVE& IPNonLinearTVE::operator=(const IPVariable& src) { @@ -100,10 +112,30 @@ IPNonLinearTVE& IPNonLinearTVE::operator=(const IPVariable& src) _dtShift = psrc->_dtShift; _DdtShiftDT = psrc->_DdtShiftDT; _DDdtShiftDDT = psrc->_DDdtShiftDDT; + _psiMax = psrc->_psiMax; + _trCorKirinf_TVE = psrc->_trCorKirinf_TVE; + _devCorKirinf_TVE = psrc->_devCorKirinf_TVE; + _corKirExtra = psrc->_corKirExtra; + _mullinsDamage = psrc->_mullinsDamage; + + if ( psrc->_ipMullinsEffect != NULL) { + if (_ipMullinsEffect == NULL){ + _ipMullinsEffect = dynamic_cast<IPMullinsEffect*>(psrc->_ipMullinsEffect->clone()); + } + else{ + _ipMullinsEffect->operator=(*dynamic_cast<const IPMullinsEffect*>(psrc->_ipMullinsEffect)); + } + } + } return *this; } +IPNonLinearTVE::~IPNonLinearTVE(){ + if (_ipMullinsEffect != NULL) delete _ipMullinsEffect; + _ipMullinsEffect = NULL; +}; + double IPNonLinearTVE::defoEnergy() const { return IPHyperViscoElastic::defoEnergy(); @@ -148,4 +180,23 @@ void IPNonLinearTVE::restart(){ restartManager::restart(_dtShift); restartManager::restart(_DdtShiftDT); restartManager::restart(_DDdtShiftDDT); -} \ No newline at end of file + restartManager::restart(_psiMax); + restartManager::restart(_trCorKirinf_TVE); + restartManager::restart(_devCorKirinf_TVE); + restartManager::restart(_corKirExtra); + restartManager::restart(_mullinsDamage); + + if (_ipMullinsEffect != NULL) + restartManager::restart(_ipMullinsEffect); +} + +const IPMullinsEffect& IPNonLinearTVE::getConstRefToIPMullinsEffect() const{ + if(_ipMullinsEffect==NULL) + Msg::Error("IPNonLinearTVE: _ipMullinsEffect not initialized"); + return *_ipMullinsEffect; +}; +IPMullinsEffect& IPNonLinearTVE::getRefToIPMullinsEffect(){ + if(_ipMullinsEffect==NULL) + Msg::Error("IPNonLinearTVE: _ipMullinsEffect not initialized"); + return *_ipMullinsEffect; +}; \ No newline at end of file diff --git a/NonLinearSolver/internalPoints/ipNonLinearTVE.h b/NonLinearSolver/internalPoints/ipNonLinearTVE.h index c6e6d68223f0ba862d0b726fac748d0acc7af394..25962478ae0eee79eeccc641903a4162fff5bc61 100644 --- a/NonLinearSolver/internalPoints/ipNonLinearTVE.h +++ b/NonLinearSolver/internalPoints/ipNonLinearTVE.h @@ -16,7 +16,7 @@ #include "kinematicHardening.h" #include "STensor3.h" #include "STensor43.h" - +#include "mullinsEffect.h" // class IPNonLinearTVE : public IPHyperViscoElastic{ class IPNonLinearTVE : public IPHyperViscoElastoPlastic{ @@ -32,6 +32,10 @@ class IPNonLinearTVE : public IPHyperViscoElastoPlastic{ double _DmechSrcTVEdT; STensor3 _DmechSrcTVEdF; + double _trCorKirinf_TVE; + STensor3 _devCorKirinf_TVE; + STensor3 _corKirExtra; + // Viscoelastic Strain std::vector<STensor3> _devOGammai; // dev viscoelastic strain for each branch std::vector<double> _trOGammai; // tr viscoelastic strain for each branch @@ -60,13 +64,18 @@ class IPNonLinearTVE : public IPHyperViscoElastoPlastic{ double _DdtShiftDT; double _DDdtShiftDDT; + // Mullins Effect IP + IPMullinsEffect* _ipMullinsEffect; + double _mullinsDamage; + double _psiMax; // maximum strain energy + public: IPNonLinearTVE(const J2IsotropicHardening* comp, const J2IsotropicHardening* trac, - const kinematicHardening* kin, const int N); + const kinematicHardening* kin, const int N, const mullinsEffect* mullins); IPNonLinearTVE(const IPNonLinearTVE& src); virtual IPNonLinearTVE& operator=(const IPVariable& src); - virtual ~IPNonLinearTVE(){}; + virtual ~IPNonLinearTVE(); virtual std::vector<STensor3>& getRefToDevViscoElasticOverStrain() {return _devOGammai;}; virtual const std::vector<STensor3>& getConstRefToDevViscoElasticOverStrain() const {return _devOGammai;}; @@ -126,6 +135,9 @@ class IPNonLinearTVE : public IPHyperViscoElastoPlastic{ virtual double& getShiftedTimeStepTempDoubleDerivative() {return _DDdtShiftDDT;}; virtual const double& getConstShiftedTimeStepTempDoubleDerivative() const {return _DDdtShiftDDT;}; + virtual const IPMullinsEffect& getConstRefToIPMullinsEffect() const; + virtual IPMullinsEffect& getRefToIPMullinsEffect(); + virtual double defoEnergy() const; virtual double getThermalEnergy() const {return _thermalEnergy;}; // Added _thermalEnergy // virtual double getConstRefToFractureEnergy() const {return _fracEnergy;}; // Added - Unused (edit this because its neither "const" nor "ref" here) diff --git a/NonLinearSolver/internalPoints/ipNonLinearTVP.cpp b/NonLinearSolver/internalPoints/ipNonLinearTVP.cpp index 97c878a547f7e4c43ab6d81cfe8eef0109c71076..4f6c567a7dff405c81df77cba1590959a832a913 100644 --- a/NonLinearSolver/internalPoints/ipNonLinearTVP.cpp +++ b/NonLinearSolver/internalPoints/ipNonLinearTVP.cpp @@ -12,12 +12,13 @@ #include "ipNonLinearTVP.h" IPNonLinearTVP::IPNonLinearTVP(const J2IsotropicHardening* comp, const J2IsotropicHardening* trac, - const kinematicHardening* kin, const int N):IPNonLinearTVE(comp,trac,kin,N), + const kinematicHardening* kin, const int N, const mullinsEffect* mullins):IPNonLinearTVE(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.), + _ModMandel(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.) + _dPlasticEnergyPartdT(0.),_dElasticEnergyPartdT(0.),_dViscousEnergyPartdT(0.), + _IsoHardForce_simple(0.), _dIsoHardForcedT_simple(0.), _dIsoHardForcedF_simple(0.) { _IsoHardForce.clear(); _dIsoHardForcedT.clear(); _dIsoHardForcedF.clear(); @@ -38,9 +39,12 @@ IPNonLinearTVP::IPNonLinearTVP(const IPNonLinearTVP& src):IPNonLinearTVE(src), _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), + _GammaN(src._GammaN), _dGammaNdT(src._dGammaNdT), _dGammaNdF(src._dGammaNdF), _DModMandelDF(src._DModMandelDF), _DbackSigDF(src._DbackSigDF), _dPlasticEnergyPartdT(src._dPlasticEnergyPartdT),_dElasticEnergyPartdT(src._dElasticEnergyPartdT), - _dViscousEnergyPartdT(src._dViscousEnergyPartdT) + _dViscousEnergyPartdT(src._dViscousEnergyPartdT), + _IsoHardForce_simple(src._IsoHardForce_simple), + _dIsoHardForcedT_simple(src._dIsoHardForcedT_simple), _dIsoHardForcedF_simple(src._dIsoHardForcedF_simple) { }; @@ -71,9 +75,15 @@ IPNonLinearTVP& IPNonLinearTVP::operator =(const IPVariable &source){ _DbackSigDT = ps->_DbackSigDT; _DbackSigDF = ps->_DbackSigDF; _DphiPDF = ps->_DphiPDF; + _GammaN = ps->_GammaN; + _dGammaNdT = ps->_dGammaNdT; + _dGammaNdF = ps->_dGammaNdF; _dPlasticEnergyPartdT = ps->_dPlasticEnergyPartdT; _dElasticEnergyPartdT = ps->_dElasticEnergyPartdT; _dViscousEnergyPartdT = ps->_dViscousEnergyPartdT; + _IsoHardForce_simple = ps->_IsoHardForce_simple; + _dIsoHardForcedT_simple = ps->_dIsoHardForcedT_simple; + _dIsoHardForcedF_simple = ps->_dIsoHardForcedF_simple; } return *this; @@ -106,8 +116,14 @@ void IPNonLinearTVP::restart() { restartManager::restart(_DbackSigDT); restartManager::restart(_DbackSigDF); restartManager::restart(_DphiPDF); + restartManager::restart(_GammaN); + restartManager::restart(_dGammaNdT); + restartManager::restart(_dGammaNdF); restartManager::restart(_dPlasticEnergyPartdT); restartManager::restart(_dElasticEnergyPartdT); restartManager::restart(_dViscousEnergyPartdT); + restartManager::restart(_IsoHardForce_simple); + restartManager::restart(_dIsoHardForcedT_simple); + restartManager::restart(_dIsoHardForcedF_simple); return; } diff --git a/NonLinearSolver/internalPoints/ipNonLinearTVP.h b/NonLinearSolver/internalPoints/ipNonLinearTVP.h index 7deb4ee21be3d96f7fc3c5c7dac93f5350588142..4f55f692d6b56310189f594d4849cde915247df1 100644 --- a/NonLinearSolver/internalPoints/ipNonLinearTVP.h +++ b/NonLinearSolver/internalPoints/ipNonLinearTVP.h @@ -16,7 +16,7 @@ #include "kinematicHardening.h" #include "STensor3.h" #include "STensor43.h" - +#include "mullinsEffect.h" class IPNonLinearTVP : public IPNonLinearTVE{ @@ -26,6 +26,9 @@ class IPNonLinearTVP : public IPNonLinearTVE{ double _DirreversibleEnergyDT; double _mechSrcTVP; double _DmechSrcTVPdT; + + double _IsoHardForce_simple; + double _dIsoHardForcedT_simple; std::vector<double> _IsoHardForce; std::vector<double> _dIsoHardForcedT; std::vector<double> _ddIsoHardForcedTT; @@ -39,11 +42,16 @@ class IPNonLinearTVP : public IPNonLinearTVE{ STensor3 _DModMandelDT; STensor3 _DbackSigDT; STensor3 _DmechSrcTVPdF; + STensor3 _dIsoHardForcedF_simple; std::vector<STensor3> _dIsoHardForcedF; STensor43 _DbackSigDF; STensor43 _DModMandelDF; STensor3 _DphiPDF; // need this for mechSrc + + STensor3 _GammaN; + STensor3 _dGammaNdT; + STensor43 _dGammaNdF; protected: @@ -53,7 +61,7 @@ class IPNonLinearTVP : public IPNonLinearTVE{ public: IPNonLinearTVP(const J2IsotropicHardening* comp, const J2IsotropicHardening* trac, - const kinematicHardening* kin, const int N); + const kinematicHardening* kin, const int N, const mullinsEffect* mullins); IPNonLinearTVP(const IPNonLinearTVP& src); virtual IPNonLinearTVP& operator =(const IPVariable &source); virtual ~IPNonLinearTVP(); diff --git a/NonLinearSolver/materialLaw/CMakeLists.txt b/NonLinearSolver/materialLaw/CMakeLists.txt index ae6e1f09840bdca319c41b24abf1ad70df618255..f0652edb953c17ee350e0eb36feee1c914817f8c 100644 --- a/NonLinearSolver/materialLaw/CMakeLists.txt +++ b/NonLinearSolver/materialLaw/CMakeLists.txt @@ -104,6 +104,7 @@ set(SRC mlawNonLinearTVM.cpp mlawNonLinearTVE.cpp mlawNonLinearTVP.cpp + mullinsEffect.cpp # src/op_eshelby.cpp # Headers without cpp change this ?? ID.h diff --git a/NonLinearSolver/materialLaw/j2IsotropicHardening.cpp b/NonLinearSolver/materialLaw/j2IsotropicHardening.cpp index 877081750e1f8bee4339d3918a72a83d1e05e020..2035b01297c78953b7a256c376f43a4612494682 100644 --- a/NonLinearSolver/materialLaw/j2IsotropicHardening.cpp +++ b/NonLinearSolver/materialLaw/j2IsotropicHardening.cpp @@ -86,7 +86,7 @@ void PerfectlyPlasticJ2IsotropicHardening::createIPVariable(IPJ2IsotropicHardeni void PerfectlyPlasticJ2IsotropicHardening::hardening(double p0, const IPJ2IsotropicHardening &ipvprev, double p, IPJ2IsotropicHardening &ipv) const { - double dR=0, ddR=0, intR=0, dRdT =0, ddRdTT=0.; + double dR=0, ddR=0, intR=0, dRdT =0, ddRdTT=0., ddRdT=0.; double R0 = getYield0(); double R = R0; if (ipvprev.isSaturated()){ @@ -105,12 +105,12 @@ void PerfectlyPlasticJ2IsotropicHardening::hardening(double p0, const IPJ2Isotro intR=0.5*tol*p*p+getYield0()*p; } } - ipv.set(R0,R,dR,ddR,intR,dRdT,ddRdTT); + ipv.set(R0,R,dR,ddR,intR,dRdT,ddRdTT,ddRdT); } //-------------------------------------added void PerfectlyPlasticJ2IsotropicHardening::hardening(double p0, const IPJ2IsotropicHardening &ipvprev, double p,double T, IPJ2IsotropicHardening &ipv) const { - double dR=0, ddR=0, intR=0, dRdT=0, ddRdTT=0; + double dR=0, ddR=0, intR=0, dRdT=0, ddRdTT=0, ddRdT=0.; double R0 = getYield0(T); double R = R0; if (ipvprev.isSaturated()){ @@ -129,9 +129,10 @@ void PerfectlyPlasticJ2IsotropicHardening::hardening(double p0, const IPJ2Isotro intR=0.5*tol*p*p+getYield0(T)*p; dRdT=getDYield0DT(T); ddRdTT=getDDYield0DTT(T); + ddRdT=0.; } } - ipv.set(R0,R,dR,ddR,intR,dRdT,ddRdTT); + ipv.set(R0,R,dR,ddR,intR,dRdT,ddRdTT,ddRdT); } //-----------------------------------------end J2IsotropicHardening * PerfectlyPlasticJ2IsotropicHardening::clone() const @@ -217,7 +218,7 @@ void PowerLawJ2IsotropicHardening::createIPVariable(IPJ2IsotropicHardening* &ipv void PowerLawJ2IsotropicHardening::hardening(double p0, const IPJ2IsotropicHardening &ipvprev, double p, IPJ2IsotropicHardening &ipv) const { // double tol=1.e-16; - double dR=0, ddR=0, intR=0, dRdT=0, ddRdTT=0; + double dR=0, ddR=0, intR=0, dRdT=0, ddRdTT=0,ddRdT=0.; double R0 = getYield0(); double R = R0; if (ipvprev.isSaturated()){ @@ -245,12 +246,12 @@ void PowerLawJ2IsotropicHardening::hardening(double p0, const IPJ2IsotropicHarde } } - ipv.set(R0,R,dR,ddR,intR,dRdT,ddRdTT); + ipv.set(R0,R,dR,ddR,intR,dRdT,ddRdTT,ddRdT); } //--------------------------------------------------added void PowerLawJ2IsotropicHardening::hardening(double p0, const IPJ2IsotropicHardening &ipvprev, double p,double T, IPJ2IsotropicHardening &ipv) const { - double dR=0, ddR=0, intR=0, dRdT=0, ddRdTT=0; + double dR=0, ddR=0, intR=0, dRdT=0, ddRdTT=0, ddRdT=0.; double R0 = getYield0(T); double R = R0; if (ipvprev.isSaturated()){ @@ -288,22 +289,29 @@ void PowerLawJ2IsotropicHardening::hardening(double p0, const IPJ2IsotropicHarde } double dhdT=_h*_temFunc_h->getDiff(T); + double ddhdTT=_h*_temFunc_h->getDoubleDiff(T); double dhexpdT=_hexp*_temFunc_hexp->getDiff(T); + double ddhexpdTT=_hexp*_temFunc_hexp->getDoubleDiff(T); if(p<tol && dhexpdT != 0) { dRdT=-1e20; + ddRdTT=-1e20; } else if (p<tol && dhexpdT == 0) { dRdT=getDYield0DT(T)+dhdT*pow(p,hexpT); + ddRdTT=getDDYield0DTT(T)+ddhdTT*pow(p,hexpT); + ddRdT = 0.; } else { dRdT=getDYield0DT(T)+dhdT*pow(p,hexpT)+hT*dhexpdT*log(p)*pow(p,hexpT); + ddRdTT=getDDYield0DTT(T)+ddhdTT*pow(p,hexpT)+2.*dhdT*dhexpdT*log(p)*pow(p,hexpT)+hT*( ddhexpdTT*log(p)*pow(p,hexpT) + pow(p,hexpT)*pow(dhexpdT*log(p),2) ); + ddRdT=dhdT*hexpT*pow(p,hexpT-1) + hT*dhexpdT*( pow(p,hexpT-1) + hexpT*(hexpT-1)*pow(p,hexpT-1)*log(p) ); } } - ipv.set(R0,R,dR,ddR,intR,dRdT,ddRdTT); + ipv.set(R0,R,dR,ddR,intR,dRdT,ddRdTT,ddRdT); } //--------------------------------------------------------------------------end J2IsotropicHardening * PowerLawJ2IsotropicHardening::clone() const @@ -388,7 +396,7 @@ void ExponentialJ2IsotropicHardening::createIPVariable(IPJ2IsotropicHardening* & void ExponentialJ2IsotropicHardening::hardening(double p0, const IPJ2IsotropicHardening &ipvprev, double p, IPJ2IsotropicHardening &ipv) const { - double dR=0, ddR=0, intR=0, dRdT=0, ddRdTT=0; + double dR=0, ddR=0, intR=0, dRdT=0, ddRdTT=0, ddRdT=0.; double R0 = getYield0(); double R = R0; if (ipvprev.isSaturated()){ @@ -416,12 +424,12 @@ void ExponentialJ2IsotropicHardening::hardening(double p0, const IPJ2IsotropicHa } } - ipv.set(R0,R,dR,ddR,intR,dRdT,ddRdTT); + ipv.set(R0,R,dR,ddR,intR,dRdT,ddRdTT,ddRdT); } //-----------------------------------------------added void ExponentialJ2IsotropicHardening::hardening(double p0, const IPJ2IsotropicHardening &ipvprev, double p,double T, IPJ2IsotropicHardening &ipv) const { - double dR=0, ddR=0, intR=0, dRdT=0, ddRdTT=0; + double dR=0, ddR=0, intR=0, dRdT=0, ddRdTT=0, ddRdT=0.; double R0 = getYield0(T); double R = R0; if (ipvprev.isSaturated()){ @@ -459,14 +467,16 @@ void ExponentialJ2IsotropicHardening::hardening(double p0, const IPJ2IsotropicHa { dRdT=getDYield0DT(T); ddRdTT=getDDYield0DTT(T); + ddRdT=0.; } else { dRdT=getDYield0DT(T)+dhdT*(1-exp(-hexpT*p))+hT*(dhexpdT*p*exp(-hexpT*p)); ddRdTT=getDDYield0DTT(T)+ddhdTT*(1-exp(-hexpT*p))+dhdT*(dhexpdT*p*exp(-hexpT*p))+dhdT*(dhexpdT*p*exp(-hexpT*p))+hT*(ddhexpdTT*p*exp(-hexpT*p)-dhexpdT*dhexpdT*p*p*exp(-hexpT*p)); + ddRdT=dhdT*hexpT*exp(-hexpT*p) + hT*dhexpdT*(exp(-hexpT*p)-pow(hexpT,2)*exp(-hexpT*p)); } } - ipv.set(R0,R,dR,ddR,intR,dRdT,ddRdTT); + ipv.set(R0,R,dR,ddR,intR,dRdT,ddRdTT,ddRdT); } @@ -558,7 +568,7 @@ void EnhancedExponentialJ2IsotropicHardening::createIPVariable(IPJ2IsotropicHard void EnhancedExponentialJ2IsotropicHardening::hardening(double p0, const IPJ2IsotropicHardening &ipvprev, double p, IPJ2IsotropicHardening &ipv) const { - double dR=0, ddR=0, intR=0, dRdT=0, ddRdTT=0; + double dR=0, ddR=0, intR=0, dRdT=0, ddRdTT=0, ddRdT=0; double R0 = getYield0(); double R = R0; if (ipvprev.isSaturated()){ @@ -582,7 +592,7 @@ void EnhancedExponentialJ2IsotropicHardening::hardening(double p0, const IPJ2Iso intR= ipvprev.getIntegR()+ R*(p-p0); } - ipv.set(R0,R,dR,ddR,intR,dRdT,ddRdTT); + ipv.set(R0,R,dR,ddR,intR,dRdT,ddRdTT,ddRdT); } //-----------------------------------------------added void EnhancedExponentialJ2IsotropicHardening::hardening(double p0, const IPJ2IsotropicHardening &ipvprev, double p,double T, IPJ2IsotropicHardening &ipv) const @@ -681,7 +691,7 @@ void ExponentialSeriesJ2IsotropicHardening::createIPVariable(IPJ2IsotropicHarden void ExponentialSeriesJ2IsotropicHardening::hardening(double p0, const IPJ2IsotropicHardening &ipvprev, double p, IPJ2IsotropicHardening &ipv) const { - double dR=0, ddR=0, intR=0, dRdT=0, ddRdTT=0; + double dR=0, ddR=0, intR=0, dRdT=0, ddRdTT=0,ddRdT=0; double R0 = getYield0(); double R = R0; if (ipvprev.isSaturated()){ @@ -701,12 +711,12 @@ void ExponentialSeriesJ2IsotropicHardening::hardening(double p0, const IPJ2Isotr if(fabs(_hexp[i])!=0) intR+=_h[i]*(exp(-_hexp[i]*p)-exp(0))/(_hexp[i]); } } - ipv.set(R0,R,dR,ddR,intR,dRdT,ddRdTT); + ipv.set(R0,R,dR,ddR,intR,dRdT,ddRdTT,ddRdT); } //-----------------------------------------------added void ExponentialSeriesJ2IsotropicHardening::hardening(double p0, const IPJ2IsotropicHardening &ipvprev, double p,double T, IPJ2IsotropicHardening &ipv) const { - double dR=0, ddR=0, intR=0, dRdT=0, ddRdTT=0; + double dR=0, ddR=0, intR=0, dRdT=0, ddRdTT=0, ddRdT=0; double R0 = getYield0(T); double R = R0; if (ipvprev.isSaturated()){ @@ -733,7 +743,7 @@ void ExponentialSeriesJ2IsotropicHardening::hardening(double p0, const IPJ2Isotr dRdT += dhdT*(1-tmp)+hT*(dhexpdT*p*tmp); } } - ipv.set(R0,R,dR,ddR,intR,dRdT,ddRdTT); + ipv.set(R0,R,dR,ddR,intR,dRdT,ddRdTT,ddRdT); } @@ -821,7 +831,7 @@ void SwiftJ2IsotropicHardening::createIPVariable(IPJ2IsotropicHardening* &ipv) c void SwiftJ2IsotropicHardening::hardening(double p0, const IPJ2IsotropicHardening &ipvprev, double p, IPJ2IsotropicHardening &ipv) const { - double dR=0, ddR=0, intR=0, dRdT=0, ddRdTT=0; + double dR=0, ddR=0, intR=0, dRdT=0, ddRdTT=0, ddRdT=0; double R0 = getYield0(); double R = R0; if (ipvprev.isSaturated()){ @@ -847,12 +857,12 @@ void SwiftJ2IsotropicHardening::hardening(double p0, const IPJ2IsotropicHardenin if(fabs(_hexp+1.)!=0 && fabs(_h)!=0.) intR=R*tmp/(_hexp+1.)/_h; } } - ipv.set(R0,R,dR,ddR,intR,dRdT,ddRdTT); + ipv.set(R0,R,dR,ddR,intR,dRdT,ddRdTT,ddRdT); } //----------------------added void SwiftJ2IsotropicHardening::hardening(double p0, const IPJ2IsotropicHardening &ipvprev, double p,double T, IPJ2IsotropicHardening &ipv) const { - double dR=0, ddR=0, intR=0, dRdT=0, ddRdTT=0; + double dR=0, ddR=0, intR=0, dRdT=0, ddRdTT=0, ddRdT=0; double R0 = getYield0(T); double R = R0; if (ipvprev.isSaturated()){ @@ -890,7 +900,7 @@ void SwiftJ2IsotropicHardening::hardening(double p0, const IPJ2IsotropicHardenin dRdT= R*getDYield0DT(T)/getYield0(T) + R*dhexpdT*log(tmp) + R*hexpT*dhdT*(p-_p0)/tmp; } } - ipv.set(R0,R,dR,ddR,intR,dRdT,ddRdTT); + ipv.set(R0,R,dR,ddR,intR,dRdT,ddRdTT,ddRdT); } //------------------------------end @@ -943,7 +953,7 @@ void MultipleSwiftJ2IsotropicHardening::createIPVariable(IPJ2IsotropicHardening* void MultipleSwiftJ2IsotropicHardening::hardening(double p0, const IPJ2IsotropicHardening &ipvprev, double p, IPJ2IsotropicHardening &ipv) const { - double dR=0., ddR=0., intR=0., dRdT=0., ddRdTT=0.; + double dR=0., ddR=0., intR=0., dRdT=0., ddRdTT=0., ddRdT=0.; double R0 = getYield0(); double R = R0; if (ipvprev.isSaturated()){ @@ -968,13 +978,13 @@ void MultipleSwiftJ2IsotropicHardening::hardening(double p0, const IPJ2Isotropic intR = ipvprev.getIntegR()+ 0.5*(R+ipvprev.getR())*(p-p0); // approximation } } - ipv.set(R0,R,dR,ddR,intR,dRdT,ddRdTT); + ipv.set(R0,R,dR,ddR,intR,dRdT,ddRdTT,ddRdT); } //----------------------added void MultipleSwiftJ2IsotropicHardening::hardening(double p0, const IPJ2IsotropicHardening &ipvprev, double p,double T, IPJ2IsotropicHardening &ipv) const { // temperature dependence has not been implemented - double dR=0., ddR=0., intR=0., dRdT=0., ddRdTT=0.; + double dR=0., ddR=0., intR=0., dRdT=0., ddRdTT=0., ddRdT=0.; double R0 = getYield0(T); double R = R0; if (ipvprev.isSaturated()){ @@ -1011,7 +1021,7 @@ void MultipleSwiftJ2IsotropicHardening::hardening(double p0, const IPJ2Isotropic dRdT = DsigY1DT*pow(pp,_n1); } } - ipv.set(R0,R,dR,ddR,intR,dRdT,ddRdTT); + ipv.set(R0,R,dR,ddR,intR,dRdT,ddRdTT,ddRdT); } //------------------------------end @@ -1120,7 +1130,7 @@ void LinearExponentialJ2IsotropicHardening::createIPVariable(IPJ2IsotropicHarden void LinearExponentialJ2IsotropicHardening::hardening(double p0, const IPJ2IsotropicHardening &ipvprev, double p, IPJ2IsotropicHardening &ipv) const { - double dR=0, ddR=0, intR=0, dRdT=0., ddRdTT=0.; + double dR=0, ddR=0, intR=0, dRdT=0., ddRdTT=0., ddRdT=0.; double R0 = getYield0(); double R = R0; if (ipvprev.isSaturated()){ @@ -1148,13 +1158,13 @@ void LinearExponentialJ2IsotropicHardening::hardening(double p0, const IPJ2Isotr if(fabs(_hexp)!=0) intR+=_h2*(exp(-_hexp*p)-exp(0))/(_hexp); } } - ipv.set(R0,R,dR,ddR,intR,dRdT,ddRdTT); + ipv.set(R0,R,dR,ddR,intR,dRdT,ddRdTT,ddRdT); } //-----------------------------added void LinearExponentialJ2IsotropicHardening::hardening(double p0, const IPJ2IsotropicHardening &ipvprev, double p,double T, IPJ2IsotropicHardening &ipv) const { - double dR=0, ddR=0, intR=0, dRdT=0., ddRdTT=0.; + double dR=0, ddR=0, intR=0, dRdT=0., ddRdTT=0., ddRdT=0.; double R0 = getYield0(T); double R = R0; if (ipvprev.isSaturated()){ @@ -1162,6 +1172,8 @@ void LinearExponentialJ2IsotropicHardening::hardening(double p0, const IPJ2Isotr dR = 0.; ddR = 0.; intR = ipvprev.getIntegR()+ R*(p-p0); + dRdT = 0.; + ddRdTT = 0.; } else { double tol=1.e-16; @@ -1191,19 +1203,20 @@ void LinearExponentialJ2IsotropicHardening::hardening(double p0, const IPJ2Isotr ddRdTT = getDDYield0DTT(T); } else{ + double tmp = exp(-hexpT*p); double dh1dT=_h1*_temFunc_h1->getDiff(T); double ddh1dTT=_h1*_temFunc_h1->getDoubleDiff(T); double dhexpdT=_hexp*_temFunc_hexp->getDiff(T); double ddhexpdTT=_hexp*_temFunc_hexp->getDoubleDiff(T); double dh2dT=_h2*_temFunc_h2->getDiff(T); double ddh2dTT=_h2*_temFunc_h2->getDoubleDiff(T); - dRdT=getDYield0DT(T)+dh1dT*p+dh2dT*(1-exp(-hexpT*p))+h2T*(dhexpdT*p*exp(-hexpT*p)); - ddRdTT=getDDYield0DTT(T)+ddh1dTT*p+ddh2dTT*(1-exp(-hexpT*p))+dh2dT*(dhexpdT*p*exp(-hexpT*p)) - +dh2dT*(dhexpdT*p*exp(-hexpT*p))+h2T*(ddhexpdTT*p*exp(-hexpT*p)-dhexpdT*p*dhexpdT*p*exp(-hexpT*p)); + dRdT=getDYield0DT(T)+dh1dT*p+dh2dT*(1-tmp)+h2T*(dhexpdT*p*tmp); + ddRdTT=getDDYield0DTT(T)+ddh1dTT*p+ddh2dTT*(1-tmp)+dh2dT*(dhexpdT*p*tmp) + +dh2dT*(dhexpdT*p*tmp)+h2T*(ddhexpdTT*p*tmp-dhexpdT*p*dhexpdT*p*tmp); } } - ipv.set(R0,R,dR,ddR,intR,dRdT,ddRdTT); + ipv.set(R0,R,dR,ddR,intR,dRdT,ddRdTT,ddRdT); } //----------------------------end @@ -1256,7 +1269,7 @@ void LinearExponentialFollowedBySwiftLawJ2IsotropicHardening::hardening(double p LinearExponentialJ2IsotropicHardening::hardening(p0,ipvprev,p,ipv); } else{ - double dR=0, ddR=0, intR=0, dRdT=0., ddRdTT=0.; + double dR=0, ddR=0, intR=0, dRdT=0., ddRdTT=0., ddRdT=0.; double R0 = getYield0(); double R = R0; if (ipvprev.isSaturated()){ @@ -1274,7 +1287,7 @@ void LinearExponentialFollowedBySwiftLawJ2IsotropicHardening::hardening(double p ddR = dR*_n3*_h3/(1+_h3*(p-_p3)) - R*_n3*_h3*_h3/((1+_h3*(p-_p3))*(1+_h3*(p-_p3))); intR = ipvprev.getIntegR()+ 0.5*(R+ipvprev.getR())*(p-p0); // approximation } - ipv.set(R0,R,dR,ddR,intR,dRdT,ddRdTT); + ipv.set(R0,R,dR,ddR,intR,dRdT,ddRdTT,ddRdT); } } //-----------------------------added @@ -1284,7 +1297,7 @@ void LinearExponentialFollowedBySwiftLawJ2IsotropicHardening::hardening(double p LinearExponentialJ2IsotropicHardening::hardening(p0,ipvprev,p,T,ipv); } else{ - double dR=0, ddR=0, intR=0, dRdT=0., ddRdTT=0.; + double dR=0, ddR=0, intR=0, dRdT=0., ddRdTT=0.,ddRdT=0.; double R0 = getYield0(T); double R = R0; if (ipvprev.isSaturated()){ @@ -1309,7 +1322,7 @@ void LinearExponentialFollowedBySwiftLawJ2IsotropicHardening::hardening(double p dRdT = getYield0(T)*pow(1+_h3*(p-_p3),_n3); } - ipv.set(R0,R,dR,ddR,intR,dRdT,ddRdTT); + ipv.set(R0,R,dR,ddR,intR,dRdT,ddRdTT,ddRdT); } } @@ -1459,7 +1472,7 @@ void LinearFollowedByExponentialJ2IsotropicHardening::createIPVariable(IPJ2Isotr void LinearFollowedByExponentialJ2IsotropicHardening::hardening(double p0, const IPJ2IsotropicHardening &ipvprev, double p, IPJ2IsotropicHardening &ipv) const { - double dR(0.), ddR(0.), intR(0.), dRdT(0.), ddRdTT(0.); + double dR(0.), ddR(0.), intR(0.), dRdT(0.), ddRdTT(0.), ddRdT(0.); double R0 = getYield0(); double R = R0; if (ipvprev.isSaturated()){ @@ -1502,12 +1515,12 @@ void LinearFollowedByExponentialJ2IsotropicHardening::hardening(double p0, const intR = ipvprev.getIntegR()+ R*(p-p0); } } - ipv.set(R0,R,dR,ddR,intR,dRdT,ddRdTT); + ipv.set(R0,R,dR,ddR,intR,dRdT,ddRdTT,ddRdT); } //-----------------------------added void LinearFollowedByExponentialJ2IsotropicHardening::hardening(double p0, const IPJ2IsotropicHardening &ipvprev, double p,double T, IPJ2IsotropicHardening &ipv) const { - double dR(0.), ddR(0.), intR(0.),dRdT(0.),ddRdTT(0.); + double dR(0.), ddR(0.), intR(0.),dRdT(0.),ddRdTT(0.),ddRdT(0.); double R0 = getYield0(T); double R = R0; if (ipvprev.isSaturated()){ @@ -1583,7 +1596,7 @@ void LinearFollowedByExponentialJ2IsotropicHardening::hardening(double p0, const } } - ipv.set(R0,R,dR,ddR,intR,dRdT,ddRdTT); + ipv.set(R0,R,dR,ddR,intR,dRdT,ddRdTT,ddRdT); } //----------------------------end @@ -1695,7 +1708,7 @@ void LinearFollowedByPowerLawJ2IsotropicHardening::createIPVariable(IPJ2Isotropi void LinearFollowedByPowerLawJ2IsotropicHardening::hardening(double p0, const IPJ2IsotropicHardening &ipvprev, double p, IPJ2IsotropicHardening &ipv) const { - double dR=0., ddR=0., intR=0., dRdT=0., ddRdTT=0.; + double dR=0., ddR=0., intR=0., dRdT=0., ddRdTT=0., ddRdT=0.; double R0 = getYield0(); double R = R0; if (ipvprev.isSaturated()){ @@ -1725,12 +1738,12 @@ void LinearFollowedByPowerLawJ2IsotropicHardening::hardening(double p0, const IP intR += R*p /(_hexp+1.) -((getYield0()+_h1*_pexp)*_pexp/(_hexp+1.)); } } - ipv.set(R0,R,dR,ddR,intR,dRdT,ddRdTT); + ipv.set(R0,R,dR,ddR,intR,dRdT,ddRdTT,ddRdT); } //-----------------------------------------------------added void LinearFollowedByPowerLawJ2IsotropicHardening::hardening(double p0, const IPJ2IsotropicHardening &ipvprev, double p,double T, IPJ2IsotropicHardening &ipv) const { - double dR=0., ddR=0., intR=0., dRdT=0., ddRdTT=0.; + double dR=0., ddR=0., intR=0., dRdT=0., ddRdTT=0., ddRdT=0.; double R0 = getYield0(T); double R = R0; if (ipvprev.isSaturated()){ @@ -1784,7 +1797,7 @@ void LinearFollowedByPowerLawJ2IsotropicHardening::hardening(double p0, const IP } } - ipv.set(R0,R,dR,ddR,intR,dRdT,ddRdTT); + ipv.set(R0,R,dR,ddR,intR,dRdT,ddRdTT,ddRdT); } //--------------------------------end @@ -1823,7 +1836,7 @@ void LinearFollowedByMultiplePowerLawJ2IsotropicHardening::createIPVariable(IPJ2 void LinearFollowedByMultiplePowerLawJ2IsotropicHardening::hardening(double p0, const IPJ2IsotropicHardening &ipvprev, double p, IPJ2IsotropicHardening &ipv) const { - double dR=0., ddR=0., intR=0., dRdT=0., ddRdTT=0.; + double dR=0., ddR=0., intR=0., dRdT=0., ddRdTT=0., ddRdT=0.; double R0 = getYield0(); double R = R0; if (ipvprev.isSaturated()){ @@ -1856,12 +1869,12 @@ void LinearFollowedByMultiplePowerLawJ2IsotropicHardening::hardening(double p0, intR = getYield0()*_p1 + 0.5*_H*_p1*_p1 + sy2*_p2/(_n1+1) - sy1*_p1/(_n1+1) + R*p/(_n2+1) - sy2*_p2/(_n2+1);; } } - ipv.set(R0,R,dR,ddR,intR,dRdT,ddRdTT); + ipv.set(R0,R,dR,ddR,intR,dRdT,ddRdTT,ddRdT); } //-----------------------------------------------------added void LinearFollowedByMultiplePowerLawJ2IsotropicHardening::hardening(double p0, const IPJ2IsotropicHardening &ipvprev, double p,double T, IPJ2IsotropicHardening &ipv) const { - double dR=0., ddR=0., intR=0.,dRdT=0.,ddRdTT=0.; + double dR=0., ddR=0., intR=0.,dRdT=0.,ddRdTT=0.,ddRdT=0.; double R0 = getYield0(T); double R = R0; if (ipvprev.isSaturated()){ @@ -1900,7 +1913,7 @@ void LinearFollowedByMultiplePowerLawJ2IsotropicHardening::hardening(double p0, } } - ipv.set(R0,R,dR,ddR,intR,dRdT,ddRdTT); + ipv.set(R0,R,dR,ddR,intR,dRdT,ddRdTT,ddRdT); } @@ -1949,7 +1962,7 @@ void PolynomialJ2IsotropicHardening::hardening(double p0, const IPJ2IsotropicHar //_coefficients.print("_coefficients"); double R0 = getYield0(); double R = R0; - double dR=0., ddR=0., intR=0., dRdT=0., ddRdTT=0.; + double dR=0., ddR=0., intR=0., dRdT=0., ddRdTT=0., ddRdT=0.; if (ipvprev.isSaturated()){ R = ipvprev.getR(); dR = 0.; @@ -1978,12 +1991,12 @@ void PolynomialJ2IsotropicHardening::hardening(double p0, const IPJ2IsotropicHar else Msg::Error("order %d is not implemented PolynomialJ2IsotropicHaderning::hardening",_order); } - ipv.set(R0,R,dR,ddR,intR,dRdT,ddRdTT); + ipv.set(R0,R,dR,ddR,intR,dRdT,ddRdTT,ddRdT); } void PolynomialJ2IsotropicHardening::hardening(double p0, const IPJ2IsotropicHardening &ipvprev, double p, double T, IPJ2IsotropicHardening &ipv) const { - double dR=0., ddR=0., intR=0.,dRdT=0.,ddRdTT=0.; + double dR=0., ddR=0., intR=0.,dRdT=0.,ddRdTT=0.,ddRdT=0.; double R0 = getYield0(T); double R = R0; if (ipvprev.isSaturated()){ @@ -2018,7 +2031,7 @@ void PolynomialJ2IsotropicHardening::hardening(double p0, const IPJ2IsotropicHar dRdT = getDYield0DT(T); dRdT = getDDYield0DTT(T); } - ipv.set(R0,R,dR,ddR,intR,dRdT,ddRdTT); + ipv.set(R0,R,dR,ddR,intR,dRdT,ddRdTT,ddRdT); }; @@ -2078,7 +2091,7 @@ void TwoExpJ2IsotropicHaderning::hardening(double p0, const IPJ2IsotropicHardeni { double R0 = getYield0(); double R = R0; - double dR=0., ddR=0., intR=0., dRdT=0., ddRdTT=0.; + double dR=0., ddR=0., intR=0., dRdT=0., ddRdTT=0., ddRdT=0.; if (ipvprev.isSaturated()){ R = ipvprev.getR(); dR = 0.; @@ -2091,14 +2104,14 @@ void TwoExpJ2IsotropicHaderning::hardening(double p0, const IPJ2IsotropicHardeni ddR = _K*(exp(p)-4.*exp(-2.*p)); intR = _yield0*p +_K*(exp(p)+0.5*exp(-2.*p)); } - ipv.set(R0,R,dR,ddR,intR,dRdT,ddRdTT); + ipv.set(R0,R,dR,ddR,intR,dRdT,ddRdTT,ddRdT); } //-------------------------------added void TwoExpJ2IsotropicHaderning::hardening(double p0, const IPJ2IsotropicHardening &ipvprev, double p,double T, IPJ2IsotropicHardening &ipv) const { double R0 = getYield0(T); double R = R0; - double dR=0., ddR=0., intR=0., dRdT=0., ddRdTT=0.; + double dR=0., ddR=0., intR=0., dRdT=0., ddRdTT=0., ddRdT=0.; if (ipvprev.isSaturated()){ R = ipvprev.getR(); dR = 0.; @@ -2119,7 +2132,7 @@ void TwoExpJ2IsotropicHaderning::hardening(double p0, const IPJ2IsotropicHardeni dRdT=getDYield0DT(T)+dKdT*(exp(p)-exp(-2.*p)); ddRdTT=getDDYield0DTT(T)+ddKdTT*(exp(p)-exp(-2.*p)); } - ipv.set(R0,R,dR,ddR,intR,dRdT,ddRdTT); + ipv.set(R0,R,dR,ddR,intR,dRdT,ddRdTT,ddRdT); } //-------------------------------------end @@ -2199,7 +2212,7 @@ void TanhJ2IsotropicHardening::hardening(double p0, const IPJ2IsotropicHardening { double R0 = getYield0(); double R = R0; - double dR=0., ddR=0., intR=0.,dRdT=0.,ddRdTT=0.; + double dR=0., ddR=0., intR=0.,dRdT=0.,ddRdTT=0.,ddRdT=0.; if (ipvprev.isSaturated()){ R = ipvprev.getR(); dR = 0.; @@ -2213,14 +2226,14 @@ void TanhJ2IsotropicHardening::hardening(double p0, const IPJ2IsotropicHardening ddR = _K*2.*th*(th*th-1.)/(_p0*_p0); intR = _yield0*p +_K*_p0*log(cosh(p/_p0)); } - ipv.set(R0,R,dR,ddR,intR,dRdT,ddRdTT); + ipv.set(R0,R,dR,ddR,intR,dRdT,ddRdTT,ddRdT); } //------------------------------added void TanhJ2IsotropicHardening::hardening(double p0, const IPJ2IsotropicHardening &ipvprev, double p,double T, IPJ2IsotropicHardening &ipv) const { double R0 = getYield0(T); double R = R0; - double dR=0., ddR=0., intR=0., dRdT=0., ddRdTT=0.; + double dR=0., ddR=0., intR=0., dRdT=0., ddRdTT=0., ddRdT=0.; if (ipvprev.isSaturated()){ R = ipvprev.getR(); dR = 0.; @@ -2246,7 +2259,7 @@ void TanhJ2IsotropicHardening::hardening(double p0, const IPJ2IsotropicHardening ddRdTT=getDDYield0DTT(T)+ddKdTT*tanh(p/p0T)+2*dKdT*(1-th*th)*(-p*dp0dT/p0T/p0T) +KT*(-2*th*(1-th*th)*(-p*dp0dT/p0T/p0T)*(-p*dp0dT/p0T/p0T)+(1-th*th)*(-p*ddp0dTT/p0T/p0T+2*p*dp0dT*dp0dT/pow(p0T,3))); } - ipv.set(R0,R,dR,ddR,intR,dRdT,ddRdTT); + ipv.set(R0,R,dR,ddR,intR,dRdT,ddRdTT,ddRdT); } //------------------------------------------end @@ -2298,7 +2311,7 @@ void TanhSeriesJ2IsotropicHardening::hardening(double p0, const IPJ2IsotropicHar { double R0 = getYield0(); double R = R0; - double dR=0., ddR=0., intR=0.,dRdT=0., ddRdTT=0.; + double dR=0., ddR=0., intR=0.,dRdT=0., ddRdTT=0., ddRdT=0.; if (ipvprev.isSaturated()){ R = ipvprev.getR(); dR = 0.; @@ -2314,14 +2327,14 @@ void TanhSeriesJ2IsotropicHardening::hardening(double p0, const IPJ2IsotropicHar intR += getYield0()*p +_K[i]*_p0[i]*log(cosh(p/_p0[i])); } } - ipv.set(R0,R,dR,ddR,intR,dRdT,ddRdTT); + ipv.set(R0,R,dR,ddR,intR,dRdT,ddRdTT,ddRdT); } //------------------------------added void TanhSeriesJ2IsotropicHardening::hardening(double p0, const IPJ2IsotropicHardening &ipvprev, double p,double T, IPJ2IsotropicHardening &ipv) const { double R0 = getYield0(T); double R = R0; - double dR=0., ddR=0., intR=0.,dRdT=0.,ddRdTT=0.; + double dR=0., ddR=0., intR=0.,dRdT=0.,ddRdTT=0.,ddRdT=0.; if (ipvprev.isSaturated()){ R = ipvprev.getR(); dR = 0.; @@ -2339,7 +2352,7 @@ void TanhSeriesJ2IsotropicHardening::hardening(double p0, const IPJ2IsotropicHar dRdT = getDDYield0DTT(T); } } - ipv.set(R0,R,dR,ddR,intR,dRdT,ddRdTT); + ipv.set(R0,R,dR,ddR,intR,dRdT,ddRdTT,ddRdT); } //------------------------------------------end @@ -2511,7 +2524,7 @@ void LinearFollowedByExponentialFollowedByMultiplePowerLawJ2IsotropicHardening:: { double R0 = getYield0(); double R = R0; - double dR(0.), ddR(0.), intR(0.), dRdT(0.), ddRdTT(0.); + double dR(0.), ddR(0.), intR(0.), dRdT(0.), ddRdTT(0.),ddRdT(0.); if (ipvprev.isSaturated()){ R = ipvprev.getR(); dR = 0.; @@ -2554,14 +2567,14 @@ void LinearFollowedByExponentialFollowedByMultiplePowerLawJ2IsotropicHardening:: } } - ipv.set(R0,R,dR,ddR,intR,dRdT,ddRdTT); + ipv.set(R0,R,dR,ddR,intR,dRdT,ddRdTT,ddRdT); } //-----------------------------added void LinearFollowedByExponentialFollowedByMultiplePowerLawJ2IsotropicHardening::hardening(double p0, const IPJ2IsotropicHardening &ipvprev, double p,double T, IPJ2IsotropicHardening &ipv) const { double R0 = getYield0(T); double R = R0; - double dR(0.), ddR(0.), intR(0.),dRdT(0.),ddRdTT(0.); + double dR(0.), ddR(0.), intR(0.),dRdT(0.),ddRdTT(0.),ddRdT(0.); if (ipvprev.isSaturated()){ R = ipvprev.getR(); dR = 0.; @@ -2638,7 +2651,7 @@ void LinearFollowedByExponentialFollowedByMultiplePowerLawJ2IsotropicHardening:: } } - ipv.set(R0,R,dR,ddR,intR,dRdT,ddRdTT); + ipv.set(R0,R,dR,ddR,intR,dRdT,ddRdTT,ddRdT); } //----------------------------end diff --git a/NonLinearSolver/materialLaw/kinematicHardening.cpp b/NonLinearSolver/materialLaw/kinematicHardening.cpp index 92ca0d92d520c202330a01a6901cf07060ca2603..ec2a7b7c2121eeba524895ff8dc89bf377a5f707 100644 --- a/NonLinearSolver/materialLaw/kinematicHardening.cpp +++ b/NonLinearSolver/materialLaw/kinematicHardening.cpp @@ -92,7 +92,7 @@ void PolynomialKinematicHardening::hardening(double p0, const IPKinematicHardeni p = tol; } //_coefficients.print("_coefficients"); - double R=0., dR=0., ddR=0., dRdT = 0., ddRddT = 0.; + double R=0., dR=0., ddR=0., dRdT = 0., ddRdTT = 0., ddRdT = 0.; if (ipvprev.isSaturated()){ R = ipvprev.getR(); dR = 0.; @@ -132,7 +132,7 @@ void PolynomialKinematicHardening::hardening(double p0, const IPKinematicHardeni else Msg::Error("order %d is not implemented PolynomialJ2IsotropicHaderning::hardening",_order); } - ipv.set(R,dR,ddR,dRdT,ddRddT); + ipv.set(R,dR,ddR,dRdT,ddRdTT,ddRdT); } void PolynomialKinematicHardening::hardening(double p0, const IPKinematicHardening &ipvprev, double _p, double T, IPKinematicHardening &ipv) const @@ -144,14 +144,15 @@ void PolynomialKinematicHardening::hardening(double p0, const IPKinematicHardeni } //_coefficients.print("_coefficients"); - double R=0., dR=0., ddR=0., dRdT=0., ddRddT=0.; + double R=0., dR=0., ddR=0., dRdT=0., ddRdTT=0., ddRdT = 0.; if (ipvprev.isSaturated()){ R = ipvprev.getR(); dR = 0.; ddR = 0.; dRdT = 0.; - ddRddT = 0.; + ddRdTT = 0.; + ddRdT = 0.; } else{ if (_order == 1){ @@ -192,9 +193,9 @@ void PolynomialKinematicHardening::hardening(double p0, const IPKinematicHardeni dR *= _temFunc_K->getVal(T); ddR *= _temFunc_K->getVal(T); dRdT = R*_temFunc_K->getDiff(T); - ddRddT = R*_temFunc_K->getDoubleDiff(T); + ddRdTT = R*_temFunc_K->getDoubleDiff(T); - ipv.set(R,dR,ddR,dRdT,ddRddT); + ipv.set(R,dR,ddR,dRdT,ddRdTT,ddRdT); } kinematicHardening * PolynomialKinematicHardening::clone() const @@ -231,7 +232,7 @@ void PowerKinematicHardening::createIPVariable(IPKinematicHardening* &ipv) const void PowerKinematicHardening::hardening(double p0, const IPKinematicHardening &ipvprev, double p, IPKinematicHardening &ipv) const { - double dR=0., ddR=0., dRdT=0., ddRddT=0.; + double dR=0., ddR=0., dRdT=0., ddRdTT=0., ddRdT = 0.; double R = 0.; if (ipvprev.isSaturated()){ R = ipvprev.getR(); @@ -261,15 +262,15 @@ void PowerKinematicHardening::hardening(double p0, const IPKinematicHardening &i ddR = (_exp-1.)*dR/p; } } - ipv.set(R,dR,ddR,dRdT,ddRddT); + ipv.set(R,dR,ddR,dRdT,ddRdTT,ddRdT); } void PowerKinematicHardening::hardening(double p0, const IPKinematicHardening &ipvprev, double p, double T, IPKinematicHardening &ipv) const { //_coefficients.print("_coefficients"); - double R =0., dR=0., ddR=0., dRdT=0., ddRddT=0.; + double R =0., dR=0., ddR=0., dRdT=0., ddRdTT=0., ddRdT = 0.; - ipv.set(R,dR,ddR,dRdT,ddRddT); + ipv.set(R,dR,ddR,dRdT,ddRdTT,ddRdT); } kinematicHardening * PowerKinematicHardening::clone() const @@ -304,7 +305,7 @@ void CoshKinematicHardening::createIPVariable(IPKinematicHardening* &ipv) const void CoshKinematicHardening::hardening(double p0, const IPKinematicHardening &ipvprev, double p, IPKinematicHardening &ipv) const { - double R(0.), dR(0.), ddR(0.), dRdT(0.), ddRddT(0.); + double R(0.), dR(0.), ddR(0.), dRdT(0.), ddRdTT(0.), ddRdT(0.); if (ipvprev.isSaturated()){ R = ipvprev.getR(); dR = 0.; @@ -316,15 +317,15 @@ void CoshKinematicHardening::hardening(double p0, const IPKinematicHardening &ip ddR = _K*cosh(p/_p0)/(_p0*_p0); } - ipv.set(R,dR,ddR,dRdT,ddRddT); + ipv.set(R,dR,ddR,dRdT,ddRdTT,ddRdT); } void CoshKinematicHardening::hardening(double p0, const IPKinematicHardening &ipvprev, double p, double T, IPKinematicHardening &ipv) const { //_coefficients.print("_coefficients"); - double R =0., dR=0., ddR=0., dRdT=0.,ddRddT=0.; + double R =0., dR=0., ddR=0., dRdT=0., ddRdTT=0., ddRdT = 0.; - ipv.set(R,dR,ddR,dRdT,ddRddT); + ipv.set(R,dR,ddR,dRdT,ddRdTT,ddRdT); } kinematicHardening * CoshKinematicHardening::clone() const @@ -386,8 +387,7 @@ void exponentialKinematicHardeningLaw::createIPVariable(IPKinematicHardening* &i void exponentialKinematicHardeningLaw::hardening(double p0, const IPKinematicHardening &ipvprev, double p, IPKinematicHardening &ipv) const { - double R(0.), dR(0.), ddR(0.); - double dRdT=0., ddRddT=0.; // added + double R(0.), dR(0.), ddR(0.), dRdT(0.), ddRdTT(0.), ddRdT(0.); if (ipvprev.isSaturated()){ R = ipvprev.getR(); dR = 0.; @@ -402,13 +402,13 @@ void exponentialKinematicHardeningLaw::hardening(double p0, const IPKinematicHar ddR = _h*_alpha*((_alpha-1.)* pow(p,_alpha-2.) *(_K-R) - pow(p,_alpha-1.)*dR); } - ipv.set(R,dR,ddR,dRdT,ddRddT); //added dRdT + ipv.set(R,dR,ddR,dRdT,ddRdTT,ddRdT); } // added void exponentialKinematicHardeningLaw::hardening(double p0, const IPKinematicHardening &ipvprev, double p, double T, IPKinematicHardening &ipv) const { - double R(0.), dR(0.), ddR(0.), dRdT(0.), ddRddT(0.); + double R(0.), dR(0.), ddR(0.), dRdT(0.), ddRdTT(0.), ddRdT(0.); if (ipvprev.isSaturated()){ R = ipvprev.getR(); dR = 0.; @@ -419,16 +419,17 @@ void exponentialKinematicHardeningLaw::hardening(double p0, const IPKinematicHar double expTerm = exp(term); double KT = _K*_temFunc_K->getVal(T); double dKdT = _K*_temFunc_K->getDiff(T); - double ddKddT = _K*_temFunc_K->getDoubleDiff(T); + double ddKdTT = _K*_temFunc_K->getDoubleDiff(T); R = KT*(1.-expTerm); dR = _h*_alpha*pow(p,_alpha-1.)*(KT-R); ddR = _h*_alpha*((_alpha-1.)* pow(p,_alpha-2.) *(KT-R) - pow(p,_alpha-1.)*dR); dRdT = dKdT*(1.-expTerm); - ddRddT = ddKddT*(1.-expTerm); + ddRdTT = ddKdTT*(1.-expTerm); + ddRdT = dKdT*_h*_alpha*pow(p,_alpha-1.)*exp(-_h*pow(p,_alpha)); } - ipv.set(R,dR,ddR,dRdT,ddRddT); //added dRdT + ipv.set(R,dR,ddR,dRdT,ddRdTT,ddRdT); //added dRdT } // kinematicHardening * exponentialKinematicHardeningLaw::clone() const diff --git a/NonLinearSolver/materialLaw/mlawHyperelastic.cpp b/NonLinearSolver/materialLaw/mlawHyperelastic.cpp index 7466910b767c71eee88a4199a9d6cae09edfca9b..1f8f2bcf8aadb40e20751c09e12f8b63dbcf3f91 100644 --- a/NonLinearSolver/materialLaw/mlawHyperelastic.cpp +++ b/NonLinearSolver/materialLaw/mlawHyperelastic.cpp @@ -105,7 +105,7 @@ void mlawHyperViscoElastic::setViscoElasticData(const std::string filename){ void mlawHyperViscoElastic::evaluatePhiPCorrection(double tr, const STensor3 &dev, double &A_v, double &dA_vdE, double &intA, double &B_d, STensor3 &dB_vddev, double &intB) const { - int method =1; + int method = 2; if(method ==0) { A_v = getVolumeCorrection()*pow(exp(getXiVolumeCorrection()/3.*tr*tr)-1.,getZetaVolumeCorrection()); @@ -115,13 +115,14 @@ void mlawHyperViscoElastic::evaluatePhiPCorrection(double tr, const STensor3 &de B_d = getDevCorrection()*pow(exp(getThetaDevCorrection()*dev.dotprod())-1.,getPiDevCorrection()); STensorOperation::zero(dB_vddev); - + + // Msg::Error(" Inside evaluatePhiPCorrection, A_v = %e, B_d = %e !!", A_v, B_d); dB_vddev=dev; dB_vddev*=2.*getPiDevCorrection()*getDevCorrection()*pow(exp(getThetaDevCorrection()*dev.dotprod())-1.,getPiDevCorrection()-1.)* exp(getThetaDevCorrection()*dev.dotprod())*getThetaDevCorrection(); Msg::Error("mlawHyperViscoElastic::evaluatePhiPCorrection: need to evaluate the volume energy"); } - else + else if(method == 1) { A_v = getVolumeCorrection()*(tanh(getXiVolumeCorrection()/3.*tr*tr-getZetaVolumeCorrection())+tanh(getZetaVolumeCorrection())); dA_vdE = getVolumeCorrection()*getXiVolumeCorrection()*2./3.*(1.-tanh(getXiVolumeCorrection()/3.*tr*tr-getZetaVolumeCorrection())*tanh(getXiVolumeCorrection()/3.*tr*tr-getZetaVolumeCorrection())); @@ -146,12 +147,76 @@ void mlawHyperViscoElastic::evaluatePhiPCorrection(double tr, const STensor3 &de intB=0.5*getDevCorrection()*(1./getThetaDevCorrection()*(log(cosh(getThetaDevCorrection()*u-getPiDevCorrection())) -log(cosh(-getPiDevCorrection())) ) +tanh(getPiDevCorrection())*u ) ; } + + } + + else if(method == 2){ + + double x = getXiVolumeCorrection()/3.*tr*tr - getZetaVolumeCorrection(); + A_v = getVolumeCorrection()*( x/sqrt(1+x*x) ); + + if(A_v > -1.){ + dA_vdE = getVolumeCorrection()/pow((1.+x*x),1.5) * 2./3.*getXiVolumeCorrection()*tr; + + // Here, psi_extraBranch_Tr = Kinf*int(A_v*trEe) dtrEe = Kinf*intA + intA = getVolumeCorrection()*3./(2.*getXiVolumeCorrection()) * sqrt(1+x*x); + } + else{ + A_v = -1. + 1.e-5; + dA_vdE = 0.; + intA = 0.; // correct it inside extraBranchLaw + } + + + + double y = getThetaDevCorrection()*dev.dotprod()-getPiDevCorrection(); + B_d = getDevCorrection()*( y/sqrt(1+y*y) ); + + if(B_d > -1.){ + dB_vddev = dev; + dB_vddev *= getDevCorrection()*2*getThetaDevCorrection()/pow((1.+y*y),1.5); + intB = getDevCorrection()/(2.*getThetaDevCorrection()) * sqrt(1+y*y); + + } + else{ + B_d = -1. + 1.e-5; + STensorOperation::zero(dB_vddev); + intB = 0.; // correct it inside extraBranchLaw + } + // Msg::Error(" Inside evaluatePhiPCorrection, A_v = %e, B_d = %e !!", A_v, B_d); + + } + else if(method == 3){ + + double x = getXiVolumeCorrection()/3.*tr*tr - getZetaVolumeCorrection(); + A_v = getVolumeCorrection()*( x/(1+x) ); + if(A_v > -1.){ + dA_vdE = 0.; + } + else{ + A_v = -0.999; + dA_vdE = 0.; + } + intA=0.; + + double y = getThetaDevCorrection()*dev.dotprod()-getPiDevCorrection(); + B_d = getDevCorrection()*( y/(1+y) ); + + if(B_d > -1.){ + STensorOperation::zero(dB_vddev); + } + else{ + B_d = -0.999; + STensorOperation::zero(dB_vddev); + } + intB=0.; + + // Msg::Error(" Inside evaluatePhiPCorrection, A_v = %e, B_d = %e !!", A_v, B_d); + - - - } + } } @@ -589,6 +654,7 @@ void mlawHyperViscoElastic::extraBranchLaw(const STensor3& Ee, const IPHyperVisc double intA; double intB; evaluatePhiPCorrection(trEe, devE, A, dAvDtrEe, intA, B, dBDdevEe, intB); + // q1->_elasticShearPropertyScaleFactor = B; // FLE sig = devE; sig *= (2.*Gextra*B); // deviatoric part double p = trEe*Kextra*A; // pressure @@ -1017,10 +1083,11 @@ void mlawPowerYieldHyper::predictorCorrector_nonAssociatedFlow(const STensor3& F q1->_DgammaDt = 0.; - static STensor3 Fpinv, Ce, Fepr; + static STensor3 Fpinv, Ce, Fepr,Cepr; STensorOperation::inverseSTensor3(Fp1,Fpinv); STensorOperation::multSTensor3(F,Fpinv,Fepr); STensorOperation::multSTensor3FirstTranspose(Fepr,Fepr,Ce); + STensorOperation::multSTensor3FirstTranspose(Fepr,Fepr,Cepr); static STensor3 invFp0; // plastic predictor invFp0= Fpinv; @@ -1122,6 +1189,7 @@ void mlawPowerYieldHyper::predictorCorrector_nonAssociatedFlow(const STensor3& F double DfDGamma = 0.; double dfdDgamma = 0.; + double dfdGamma = 0.; //FLE double u = 1.; double v = 1.; @@ -1151,8 +1219,12 @@ void mlawPowerYieldHyper::predictorCorrector_nonAssociatedFlow(const STensor3& F if (_viscosity != NULL) _viscosity->get(q1->_epspbarre,eta,Deta); double etaOverDt = eta/this->getTimeStep(); + double dPhiPdGamma = -2*Kt*_b*ptilde/v; + double dPhiEdGamma = -6*Gt*PhiEq/u; + double dAdGamma_TVP = (12*PhiEq*dPhiEdGamma + 8*_b*_b*ptilde*dPhiPdGamma/3)/(2.*A); double dAdGamma = -(72.*Gt*PhiEq*PhiEq/u+ 16.*Kt*_b*_b*_b*ptilde*ptilde/(3.*v))/(2.*A); + if (ite > 0) { // update if extra branch if plasticity occurs @@ -1161,9 +1233,14 @@ void mlawPowerYieldHyper::predictorCorrector_nonAssociatedFlow(const STensor3& F dDgammaDGamma = kk*(A+Gamma*dAdGamma); this->getYieldCoefficientDerivatives(q1,q1->_nup,Da); - dfdDgamma = Da(2)*pow(PhiEq,_n) - Da(1)*ptilde -Da(0); + + dfdDgamma = Da(2)*pow(PhiEq,_n) - Da(1)*ptilde -Da(0); //OK if (Gamma>0 and etaOverDt>0) dfdDgamma -= _p*pow(etaOverDt,_p-1.)*Deta/this->getTimeStep()*pow(Gamma,_p); + + 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 - (_n*a(2)*6.*Gt)*pow(PhiEq,_n)/u + a(1)*ptilde*2.*_b*Kt/v; if (ite > 0) @@ -1173,7 +1250,14 @@ void mlawPowerYieldHyper::predictorCorrector_nonAssociatedFlow(const STensor3& F } if (Gamma>0 and etaOverDt>0) - DfDGamma -=pow(etaOverDt,_p)*_p*pow(Gamma,_p-1.); + DfDGamma -= pow(etaOverDt,_p)*_p*pow(Gamma,_p-1.); + + /*Msg::Error("dDgammaDGamma = %e, iter = %d",dDgammaDGamma, ite); + Msg::Error("dfdDgamma = %e, iter = %d",dfdDgamma, ite); + Msg::Error("dfdGamma = %e, iter = %d",dfdGamma, ite); + Msg::Error("DfDGamma = %e, iter = %d",DfDGamma, ite); + Msg::Error("Gamma = %e, iter = %d",Gamma, ite); + Msg::Error("Dgamma = %e, iter = %d",Dgamma, ite);*/ double dGamma = -f/DfDGamma; @@ -1254,11 +1338,24 @@ void mlawPowerYieldHyper::predictorCorrector_nonAssociatedFlow(const STensor3& F GammaN = N; GammaN *= Gamma; STensorOperation::expSTensor3(GammaN,_order,expGN,&dexpAdA); - + + // FLE + /* + static STensor3 Hinv, Hinv2, check1, check2, check3, check4; + STensorOperation::inverseSTensor3(expGN,Hinv); + STensorOperation::multSTensor3(Hinv,Hinv,Hinv2); + STensorOperation::multSTensor3(Hinv,Cepr,check1); + STensorOperation::multSTensor3(Cepr,Hinv,check2); + STensorOperation::multSTensor3(Hinv2,Cepr,check3); + STensorOperation::multSTensor3(Cepr,Hinv2,check4); + */ + // FLE + // update plastic deformation tensor STensorOperation::multSTensor3(expGN,Fp0,Fp1); // update IP updateEqPlasticDeformation(q1,q0,q1->_nup,Dgamma); + // Msg::Info("setting: gamma=%e ",q1->_epspbarre); // update elastic deformation tensor, corotational stress STensorOperation::inverseSTensor3(Fp1,Fpinv); @@ -1354,8 +1451,8 @@ void mlawPowerYieldHyper::predictorCorrector_nonAssociatedFlow(const STensor3& F if (Gamma >0){ // plastic static STensor3 dAdCepr, dfDCepr; - - double fact = 1.5*a(2)*_n*pow(PhiEq,_n-2.)/(u*u); + + double fact = 1.5*a(2)*_n*pow(PhiEq,_n-2.)/(u*u); for (int i=0; i<3; i++){ for (int j=0; j<3; j++){ dAdCepr(i,j) = (4.*_b*_b*ptildepr/(A*3.*v*v))*DpprDCepr(i,j); diff --git a/NonLinearSolver/materialLaw/mlawHyperelastic.h b/NonLinearSolver/materialLaw/mlawHyperelastic.h index e9d384d7a2d96296fa018d79fa34966055eccacf..330e6abbdc2d8ad432c17276dd35534ba6cd6007 100644 --- a/NonLinearSolver/materialLaw/mlawHyperelastic.h +++ b/NonLinearSolver/materialLaw/mlawHyperelastic.h @@ -89,13 +89,13 @@ class mlawHyperViscoElastic : public materialLaw{ virtual void setViscoElasticData_Shear(const int i, const double Gi, const double gi); virtual void setViscoElasticData(const std::string filename); virtual void setVolumeCorrection(double _vc, double _xivc, double _zetavc, double _dc, double _thetadc, double _pidc) {_volCorrection=_vc,_xivolCorrection=_xivc,_zetavolCorrection=_zetavc, _devCorrection=_dc,_thetadevCorrection=_thetadc,_pidevCorrection=_pidc;}; - virtual double getVolumeCorrection() const {if (_volCorrection<1.e-5) return 0.; else return _volCorrection;}; - virtual double getXiVolumeCorrection() const {if (_xivolCorrection<1.e-5) return 1.; else return _xivolCorrection;}; - virtual double getZetaVolumeCorrection() const {if (_zetavolCorrection<1.e-5) return 1.; else return _zetavolCorrection;}; + virtual double getVolumeCorrection() const {return _volCorrection;}; + virtual double getXiVolumeCorrection() const {return _xivolCorrection;}; + virtual double getZetaVolumeCorrection() const {return _zetavolCorrection;}; - virtual double getDevCorrection() const {if (_devCorrection<1.e-5) return 0.; else return _devCorrection;}; - virtual double getThetaDevCorrection() const {if (_thetadevCorrection<1.e-5) return 1.; else return _thetadevCorrection;}; - virtual double getPiDevCorrection() const {if (_pidevCorrection<1.e-5) return 1.; else return _pidevCorrection;}; + virtual double getDevCorrection() const {return _devCorrection;}; + virtual double getThetaDevCorrection() const {return _thetadevCorrection;}; + virtual double getPiDevCorrection() const {return _pidevCorrection;}; virtual void setExtraBranchType(const int type); #ifndef SWIG diff --git a/NonLinearSolver/materialLaw/mlawNonLinearTVE.cpp b/NonLinearSolver/materialLaw/mlawNonLinearTVE.cpp index 30b6922b0243d71f0bc2a6bee8542d5be7f398df..87db501e6d5a8870d7483ad530b8e28dbcb16515 100644 --- a/NonLinearSolver/materialLaw/mlawNonLinearTVE.cpp +++ b/NonLinearSolver/materialLaw/mlawNonLinearTVE.cpp @@ -20,7 +20,7 @@ mlawNonLinearTVE::mlawNonLinearTVE(const int num,const double E,const double nu, const bool matrixbyPerturbation, const double pert, const bool thermalEstimationPreviousConfig): mlawPowerYieldHyper(num, E, nu, rho, tol, matrixbyPerturbation, pert), _Tinitial(Tinitial),_scalarAlpha(Alpha),_scalarK(KThCon),_Cp(Cp), - _thermalEstimationPreviousConfig(thermalEstimationPreviousConfig), _Alphai(0){ + _thermalEstimationPreviousConfig(thermalEstimationPreviousConfig), _Alphai(0), _mullinsEffect(NULL), _elasticPotential(NULL), _useExtraBranch(false){ _G = _mu; @@ -44,6 +44,7 @@ mlawNonLinearTVE::mlawNonLinearTVE(const int num,const double E,const double nu, _temFunc_Alpha = new constantScalarFunction(1.); _temFunc_KThCon = new constantScalarFunction(1.); _temFunc_Cp = new constantScalarFunction(1.); + _temFunc_elasticCorrection = new constantScalarFunction(1.); }; @@ -61,6 +62,7 @@ mlawNonLinearTVE::mlawNonLinearTVE(const mlawNonLinearTVE& src): mlawPowerYieldH _C2 = src._C2; _tensorAlpha = src._tensorAlpha; _tensorK = src._tensorK; + _useExtraBranch = src._useExtraBranch; _temFunc_K = NULL; // bulk modulus if (src._temFunc_K != NULL){ _temFunc_K = src._temFunc_K->clone();} @@ -77,6 +79,9 @@ mlawNonLinearTVE::mlawNonLinearTVE(const mlawNonLinearTVE& src): mlawPowerYieldH _temFunc_Cp = NULL; // specific heat if (src._temFunc_Cp!=NULL){ _temFunc_Cp = src._temFunc_Cp->clone();} + _temFunc_elasticCorrection = NULL; // elastic correction + if (src._temFunc_elasticCorrection!=NULL){ _temFunc_elasticCorrection = src._temFunc_elasticCorrection->clone();} + _temFunc_Ki.resize(_N,NULL); // branch bulk moduli for(int i=0;i<_N;i++){ if (src._temFunc_Ki[i]!=NULL) {_temFunc_Ki[i] = src._temFunc_Ki[i]->clone();} @@ -91,6 +96,13 @@ mlawNonLinearTVE::mlawNonLinearTVE(const mlawNonLinearTVE& src): mlawPowerYieldH for(int i=0;i<_N;i++){ if (src._temFunc_Alphai[i]!=NULL) {_temFunc_Alphai[i] = src._temFunc_Alphai[i]->clone();} } + + _mullinsEffect= NULL; + if (src._mullinsEffect) _mullinsEffect = src._mullinsEffect->clone(); + + _elasticPotential = NULL; + if (src._elasticPotential) _elasticPotential = src._elasticPotential->clone(); + }; @@ -112,7 +124,8 @@ mlawNonLinearTVE& mlawNonLinearTVE::operator=(const materialLaw& source){ _C2 = src->_C2; _tensorAlpha = src->_tensorAlpha; _tensorK = src->_tensorK; - + _useExtraBranch = src->_useExtraBranch; + if(_temFunc_K != NULL) delete _temFunc_K; // bulk modulus if (src->_temFunc_K != NULL){ _temFunc_K = src->_temFunc_K->clone();} @@ -127,6 +140,9 @@ mlawNonLinearTVE& mlawNonLinearTVE::operator=(const materialLaw& source){ if(_temFunc_Cp != NULL) delete _temFunc_Cp; // specific heat if (src->_temFunc_Cp!=NULL){ _temFunc_Cp = src->_temFunc_Cp->clone();} + + if(_temFunc_elasticCorrection != NULL) delete _temFunc_elasticCorrection; // elastic correction + if (src->_temFunc_elasticCorrection!=NULL){ _temFunc_elasticCorrection = src->_temFunc_elasticCorrection->clone();} for(int i=0;i<_temFunc_Ki.size();i++){ // branch bulk moduli if(_temFunc_Ki[i]!=NULL) delete _temFunc_Ki[i]; @@ -157,6 +173,12 @@ mlawNonLinearTVE& mlawNonLinearTVE::operator=(const materialLaw& source){ if (src->_temFunc_Alphai[i]!=NULL) _temFunc_Alphai[i] = src->_temFunc_Alphai[i]->clone(); } + + if(_mullinsEffect != NULL) delete _mullinsEffect; + if (src->_mullinsEffect!=NULL){ _mullinsEffect = src->_mullinsEffect->clone();} + + if(_elasticPotential != NULL) delete _elasticPotential; + if (src->_elasticPotential!=NULL){ _elasticPotential = src->_elasticPotential->clone();} } return *this; } @@ -167,6 +189,7 @@ mlawNonLinearTVE::~mlawNonLinearTVE(){ if(_temFunc_Alpha != NULL) delete _temFunc_Alpha; _temFunc_Alpha = NULL; // thermal dilatation coeff; if(_temFunc_KThCon != NULL) delete _temFunc_KThCon; _temFunc_KThCon = NULL; // thermal conductivity; if(_temFunc_Cp != NULL) delete _temFunc_Cp; _temFunc_Cp = NULL; // specific heat; + if(_temFunc_elasticCorrection != NULL) delete _temFunc_elasticCorrection; _temFunc_elasticCorrection = NULL; // elastic correction for(int i=0;i<_temFunc_Ki.size();i++){ if(_temFunc_Ki[i]!=NULL) delete _temFunc_Ki[i]; _temFunc_Ki[i]=NULL; @@ -179,6 +202,9 @@ mlawNonLinearTVE::~mlawNonLinearTVE(){ if(_temFunc_Alphai[i]!=NULL) delete _temFunc_Alphai[i]; _temFunc_Alphai[i]=NULL; } + + if (_mullinsEffect) delete _mullinsEffect; _mullinsEffect = NULL; + if (_elasticPotential) delete _elasticPotential; _elasticPotential = NULL; }; void mlawNonLinearTVE::setViscoElasticNumberOfElement(const int N){ @@ -525,10 +551,11 @@ double mlawNonLinearTVE::setTemp(const double T0, const double T1, const int par return T_set; } -double mlawNonLinearTVE::freeEnergyMechanical(const IPNonLinearTVE& q, const double Tc) const{ +double mlawNonLinearTVE::freeEnergyMechanical(const IPNonLinearTVE& q, const double T0, const double T) const{ // Update the Properties to the current temperature (see below which ones are being used) - double KT, GT, AlphaT; getK(KT,Tc); getG(GT,Tc); getAlpha(AlphaT,Tc); + double KT, GT, AlphaT; + getK(&q,KT,T); getG(&q,GT,T); getAlpha(AlphaT,T); double Psy_mech = 0.; @@ -538,41 +565,85 @@ double mlawNonLinearTVE::freeEnergyMechanical(const IPNonLinearTVE& q, const dou STensorOperation::decomposeDevTr(q._Ee,devEe,trEe); // Get thermal strain - double Eth = 3.*AlphaT*(Tc-_Tinitial); + double Eth = 3.*AlphaT*(T-_Tinitial); // Get Equilibrium freeEnergy_mech Psy_mech = KT*0.5*(trEe-Eth)*(trEe-Eth) + GT*STensorOperation::doubledot(devEe,devEe); + + // Get ExtraBranch freeEnergy + if (_useExtraBranch){ + Psy_mech += KT*q._intA + 2.*GT*q._intB; + } // Add Branch freeEnergy_mech if ((_Ki.size() > 0) or (_Gi.size() > 0)){ - std::vector<double> KiT,GiT,AlphaiT; KiT.resize(_N,0.); GiT.resize(_N,0.); AlphaiT.resize(_N,0.); getKi(KiT,Tc); getGi(GiT,Tc); getAlphai(AlphaiT,Tc); + std::vector<double> KiT,GiT,AlphaiT; + KiT.resize(_N,0.); GiT.resize(_N,0.); AlphaiT.resize(_N,0.); + getKi(&q,KiT,T); getGi(&q,GiT,T); getAlphai(AlphaiT,T); for (int i=0; i<_N; i++){ static STensor3 devEebranch; devEebranch = devEe; + + // viscous overstrain = _OGammai + // viscous strain (_Gammai) = viscous overstrain - Ee + double trGamma = q._trOGammai[i]; + trGamma -= trEe; + static STensor3 devGamma; + devGamma = q._devOGammai[i]; + devGamma -= devEe; + + devEebranch -= devGamma; // temporary tensor - // devEebranch -= q._A[i]; - // Psy_mech += KiT[i]*0.5*(trEe-q._B[i])*(trEe-q._B[i])+GiT[i]*STensorOperation::doubledot(devEebranch,devEebranch); - - double trGamma = q._trOGammai[i]; - static STensor3 devGamma = q._devOGammai[i]; - devEebranch -= devGamma; if (_modelFlag == 2){ // Additional volumetric terms - trGamma += 3*(AlphaT-AlphaiT[i])*(Tc-_Tinitial); + trGamma += 3*(AlphaT-AlphaiT[i])*(T-_Tinitial); } Psy_mech += KiT[i]*0.5*(trEe-trGamma)*(trEe-trGamma) + GiT[i]*STensorOperation::doubledot(devEebranch,devEebranch); } } - + + // Get thermal Energy + // Psy_mech += _Cp*( (T-T0) - T*log(T/T0) ); // this probably does nothing since we are interested only in the elastic energy + return Psy_mech; } -void mlawNonLinearTVE::corKirInfinity( const STensor3& devEe, const double& trEe, const double T1, STensor3& CorKirDevInf, double& CorKirTrInf) const{ +void mlawNonLinearTVE::calculateMullinsEffectScaler(const IPNonLinearTVE* q0, IPNonLinearTVE *q1, const double T) const{ + + + // Msg::Error(" Inside calculateMullinsEffectScaler, before updating eta, q1->_elasticEnergy = %e!!",q1->_elasticEnergy); + // Msg::Error(" Inside calculateMullinsEffectScaler, before updating eta, q1->_psiMax = %e!!",q1->_psiMax); + + // Initialise + double eta = 1., DetaDpsi = 0., DDetaDpsipsi = 0., DetaDT = 0., DDetaDTT = 0.; + + // Msg::Error(" Inside calculateMullinsEffectScaler, before updating eta = %e!!",eta); + + // update eta - Mullins Effect Scalar + if (_mullinsEffect != NULL && q1->_ipMullinsEffect != NULL){ + _mullinsEffect->mullinsEffectScaling(q0->_elasticEnergy, q1->_elasticEnergy, *q0->_ipMullinsEffect, *q1->_ipMullinsEffect); + } + + // get eta - Mullins Effect Scalar (at unloading intitiation-> eta = 1.; unloading end-> eta = eta_min; reloading -> eta = eta_min;) + if (q1->_ipMullinsEffect != NULL){ + eta = q1->_ipMullinsEffect->getEta(); + DetaDpsi = q1->_ipMullinsEffect->getDetaDpsi(); + DetaDT = q1->_ipMullinsEffect->getDetaDT(); + DDetaDTT = q1->_ipMullinsEffect->getDDetaDTT(); + } + // Msg::Error(" Inside calculateMullinsEffectScaler, after getting and updating eta = %e!!",eta); + + // update mullinsDamage scalar + q1->_mullinsDamage = eta; + +}; + +void mlawNonLinearTVE::corKirInfinity(const IPNonLinearTVE *q1, const STensor3& devEe, const double& trEe, const double T1, STensor3& CorKirDevInf, double& CorKirTrInf) const{ double KT, GT, AlphaT; - getK(KT,T1); getG(GT,T1); getAlpha(AlphaT,T1); + getK(q1,KT,T1); getG(q1,GT,T1); getAlpha(AlphaT,T1); CorKirDevInf = 2*GT*devEe; CorKirTrInf = KT*(trEe - 3*AlphaT*(T1-_Tinitial)); } @@ -587,7 +658,7 @@ void mlawNonLinearTVE::getTVEdCorKirDT(const IPNonLinearTVE *q0, IPNonLinearTVE // Update the Properties to the current temperature (see below which ones are being used) double KT, GT, AlphaT, DKDT, DGDT, DAlphaDT, DDKDT, DDGDT, DDAlphaDT; - getK(KT,T,&DKDT,&DDKDT); getG(GT,T,&DGDT,&DDGDT); getAlpha(AlphaT,T,&DAlphaDT,&DDAlphaDT); + getK(q1,KT,T,&DKDT,&DDKDT); getG(q1,GT,T,&DGDT,&DDGDT); getAlpha(AlphaT,T,&DAlphaDT,&DDAlphaDT); // Add corKirinf terms to DcorKirDT STensor3 corKirDevInf, devEe; @@ -604,7 +675,7 @@ void mlawNonLinearTVE::getTVEdCorKirDT(const IPNonLinearTVE *q0, IPNonLinearTVE STensorOperation::decomposeDevTr(DEe,devDE,trDE); // Add Infinity terms - corKirInfinity( devEe, trEe, T, corKirDevInf, corKirTrInf ); + corKirInfinity(q1, devEe, trEe, T, corKirDevInf, corKirTrInf); for (int i=0; i<3; i++){ DcorKirDT(i,i) += corKirTrInf*DKDT/KT - 3*KT*(DAlphaDT*(T-_Tinitial) + AlphaT); DDcorKirDT(i,i) += corKirTrInf*DDKDT/KT - 6*DKDT*(DAlphaDT*(T-_Tinitial) + AlphaT)- 3*KT*(DDAlphaDT*(T-_Tinitial) + 2*DAlphaDT); @@ -672,10 +743,11 @@ void mlawNonLinearTVE::getTVEdCorKirDT(const IPNonLinearTVE *q0, IPNonLinearTVE STensorOperation::zero(DOGammai); STensorOperation::zero(DOGammaiDT); STensorOperation::zero(DDOGammaiDT); if (_TemFuncOpt == 0){ // Use Shift Factor - DKiDT[i] = -_Ki[i]/(_ki[i]) * Ddt_shiftDT*expdtkby2; // Removed _ki/2 and _gi/2 - DDKiDT[i] = -_Ki[i]/(_ki[i]) * (DDdt_shiftDT - 1/(_ki[i])*pow(Ddt_shiftDT,2))*expdtkby2; - DGiDT[i] = -_Gi[i]/(_gi[i]) * Ddt_shiftDT*expdtgby2; - DDGiDT[i] = -_Gi[i]/(_gi[i]) * (DDdt_shiftDT - 1/(_gi[i])*pow(Ddt_shiftDT,2))*expdtgby2; + getKi(q1,KiT,T); getGi(q1,GiT,T); + DKiDT[i] = -KiT[i]/(_ki[i]) * Ddt_shiftDT*expdtkby2; // Removed _ki/2 and _gi/2 + DDKiDT[i] = -KiT[i]/(_ki[i]) * (DDdt_shiftDT - 1/(_ki[i])*pow(Ddt_shiftDT,2))*expdtkby2; + DGiDT[i] = -GiT[i]/(_gi[i]) * Ddt_shiftDT*expdtgby2; + DDGiDT[i] = -GiT[i]/(_gi[i]) * (DDdt_shiftDT - 1/(_gi[i])*pow(Ddt_shiftDT,2))*expdtgby2; } for (int j=0; j<3; j++){ @@ -739,7 +811,7 @@ void mlawNonLinearTVE::getMechSourceTVE(const IPNonLinearTVE *q0, IPNonLinearTVE const double& DKDTsum, const double& DGDTsum, const STensor43& DEeDFe, double *Wm, STensor3 *dWmdF, double *dWmdT) const{ - // I am stupid + // Initialize double mechSrcTVE, dmechSrcTVEdT = 0.; STensor3 dmechSrcTVEdE(0.); STensor3 dmechSrcTVEdF(0.); @@ -824,11 +896,11 @@ void mlawNonLinearTVE::getMechSourceTVE(const IPNonLinearTVE *q0, IPNonLinearTVE STensorOperation::zero(DOGammai); STensorOperation::zero(DOGammaiDT); STensorOperation::zero(DDOGammaiDT); if (_TemFuncOpt == 0){ // Use Shift Factor - getKi(KiT,T); getGi(GiT,T); - DKiDT[i] = -_Ki[i]/(_ki[i]) * Ddt_shiftDT*expdtkby2; // Removed _ki/2 and _gi/2 - DDKiDT[i] = -_Ki[i]/(_ki[i]) * (DDdt_shiftDT - 1/(_ki[i])*pow(Ddt_shiftDT,2))*expdtkby2; - DGiDT[i] = -_Gi[i]/(_gi[i]) * Ddt_shiftDT*expdtgby2; - DDGiDT[i] = -_Gi[i]/(_gi[i]) * (DDdt_shiftDT - 1/(_gi[i])*pow(Ddt_shiftDT,2))*expdtgby2; + getKi(q1,KiT,T); getGi(q1,GiT,T); + DKiDT[i] = -KiT[i]/(_ki[i]) * Ddt_shiftDT*expdtkby2; // Removed _ki/2 and _gi/2 + DDKiDT[i] = -KiT[i]/(_ki[i]) * (DDdt_shiftDT - 1/(_ki[i])*pow(Ddt_shiftDT,2))*expdtkby2; + DGiDT[i] = -GiT[i]/(_gi[i]) * Ddt_shiftDT*expdtgby2; + DDGiDT[i] = -GiT[i]/(_gi[i]) * (DDdt_shiftDT - 1/(_gi[i])*pow(Ddt_shiftDT,2))*expdtgby2; } for (int j=0; j<3; j++){ @@ -878,9 +950,9 @@ void mlawNonLinearTVE::getMechSourceTVE(const IPNonLinearTVE *q0, IPNonLinearTVE STensorOperation::zero(DGammai); STensorOperation::zero(DDGammaiDT); DQiDT -= DOiDT; DDQiDT -= DDOiDT; DDGammaiDT -= DDOGammaiDT; for (int j=0; j<3; j++){ - Qi(j,j) += (_Ki[i]*trEe - trOi[i]); + Qi(j,j) += (KiT[i]*trEe - trOi[i]); for (int k=0; k<3; k++){ - Qi(j,k) += (2*_Gi[i]*devEe(j,k) - devOi[i](j,k)); + Qi(j,k) += (2*GiT[i]*devEe(j,k) - devOi[i](j,k)); } } DGammai += DEe; @@ -893,8 +965,8 @@ void mlawNonLinearTVE::getMechSourceTVE(const IPNonLinearTVE *q0, IPNonLinearTVE static STensor43 temp_DDQiDTDE; static STensor43 temp_DDgammiDtDE; - double Ki_term = (_Ki[i]*(1-expdtkby2)+T*DKiDT[i]); - double Gi_term = (_Gi[i]*(1-expdtgby2)+T*DGiDT[i]); + double Ki_term = (KiT[i]*(1-expdtkby2)+T*DKiDT[i]); + double Gi_term = (GiT[i]*(1-expdtgby2)+T*DGiDT[i]); isotropicHookTensor( Ki_term, Gi_term , temp_DDQiDTDE ); double Ki_term_2 = 1/3*expdtkby2; @@ -988,6 +1060,141 @@ void mlawNonLinearTVE::getMechSourceTVE(const IPNonLinearTVE *q0, IPNonLinearTVE }; +void mlawNonLinearTVE::evaluateElasticCorrection(const double trE, const STensor3 &devE, const double& T, + double &A_v, double &dA_vdE, double &intA, double &dAdT, + double &B_d, STensor3 &dB_vddev, double &intB, double &dBdT, + double *ddAdTT, double *ddBdTT) const{ + + mlawHyperViscoElastic::evaluatePhiPCorrection(trE,devE,A_v,dA_vdE,intA,B_d,dB_vddev,intB); + + A_v *= _temFunc_elasticCorrection->getVal(T); + dA_vdE *= _temFunc_elasticCorrection->getVal(T); + intA *= _temFunc_elasticCorrection->getVal(T); + + dAdT = A_v*_temFunc_elasticCorrection->getDiff(T); + if(ddAdTT!=NULL){ + *ddAdTT = A_v*_temFunc_elasticCorrection->getDoubleDiff(T); + } + + B_d *= _temFunc_elasticCorrection->getVal(T); + dB_vddev *= _temFunc_elasticCorrection->getVal(T); + intB *= _temFunc_elasticCorrection->getVal(T); + dBdT = B_d*_temFunc_elasticCorrection->getDiff(T); + if(ddBdTT!=NULL){ + *ddBdTT = B_d*_temFunc_elasticCorrection->getDoubleDiff(T); + } + +} + +void mlawNonLinearTVE::extraBranchLaw(const STensor3& Ee, const double& T, const IPNonLinearTVE *q0, IPNonLinearTVE *q1, + STensor3& sig, const bool stiff, STensor43* DsigDEe, STensor3* DsigDT, + double* DsigV_dTrEe, STensor43* DsigD_dDevEe, + double* DsigV_dT, STensor3* DsigD_dT, + double* DDsigV_dTT, STensor3* DDsigD_dTT) const +{ + // DsigDEe = DcorKirDE + + if (_extraBranchType == Bilogarithmic) + { + static STensor3 devEe; + double trEe; + STensorOperation::decomposeDevTr(Ee,devEe,trEe); + + double A(0.), B(0.); + double dA_dTrEe = 0.; + STensor3 dB_dDevEe; + double intA(0.), intB(0.), dA_dT(0.), dB_dT(0.), ddA_dTT(0.), ddB_dTT(0.); + evaluateElasticCorrection(trEe, devEe, T, A, dA_dTrEe, intA, dA_dT, B, dB_dDevEe, intB, dB_dT, &ddA_dTT, &ddB_dTT); + + if (A <= -1. + 1.e-5){ // saturated + double trEe_0 = q0->_Ee.trace(); + intA = q0->_intA; + intA += A*0.5 *(trEe*trEe-trEe_0*trEe_0); + } + q1->_intA = intA; + + if (B <= -1. + 1.e-5){ // saturated + static STensor3 devEe_0; + double trEe_0; + STensorOperation::decomposeDevTr(q0->_Ee,devEe_0,trEe_0); + intA = q0->_intB; + intA += B*0.5 *(devEe.dotprod()-devEe_0.dotprod()); + } + q1->_intB = intB; + + double check_1 = (1+A)*_K; + double check_2 = (1+B)*_G; + // Msg::Error(" Inside extraBranchLaw, Kinf = %e, Ginf = %e !!", _K, _G); + // Msg::Error(" Inside extraBranchLaw, (1+A)*Kinf = %e, (1+B)*Ginf = %e !!", check_1, check_2); + + q1->_elasticBulkPropertyScaleFactor = A; + q1->_elasticShearPropertyScaleFactor = B; + + double Gextra, dGex_dT, ddGex_dTT; + getG(q1,Gextra,T, &dGex_dT, &ddGex_dTT); // getUpdatedShearModulus(q1); // We dont update here anymore + double Kextra, dKex_dT, ddKex_dTT; + getK(q1,Kextra,T, &dKex_dT, &ddKex_dTT); // getUpdatedBulkModulus(q1); // We dont update here anymore + + sig = devEe; + sig *= (2.*Gextra*B); // deviatoric part + double p = trEe*Kextra*A; // pressure + sig(0,0) += p; + sig(1,1) += p; + sig(2,2) += p; + + if (stiff) + { + // DsigDE + if(DsigDEe!=NULL){ + STensorOperation::zero(*DsigDEe); + *DsigDEe = _Idev; + *DsigDEe *= (2.*Gextra*B); + STensorOperation::prodAdd(devEe, dB_dDevEe, 2.*Gextra, *DsigDEe); + STensorOperation::prodAdd(_I,_I,Kextra*(A+trEe*dA_dTrEe),*DsigDEe); + } + + // DsigDT + if(DsigDT!=NULL){ + STensorOperation::zero(*DsigDT); + } + + // These can be used for plasticity + if(DsigV_dTrEe!=NULL){ + *DsigV_dTrEe = Kextra*(A + trEe*dA_dTrEe); + } + if(DsigD_dDevEe!=NULL){ + STensorOperation::zero(*DsigD_dDevEe); + *DsigD_dDevEe = _I4; + *DsigD_dDevEe *= (2.*Gextra*B); + STensorOperation::prodAdd(devEe, dB_dDevEe, 2.*Gextra, *DsigD_dDevEe); + } + + if(DsigV_dT!=NULL){ + *DsigV_dT = dKex_dT*A*trEe + Kextra*dA_dT*trEe; + } + if(DsigD_dT!=NULL){ + STensorOperation::zero(*DsigD_dT); + *DsigD_dT = devEe; + *DsigD_dT *= (2*dGex_dT*B + 2*Gextra*dB_dT); + } + + if(DDsigV_dTT!=NULL){ + *DDsigV_dTT = ddKex_dTT*A*trEe + 2*dKex_dT*dA_dT*trEe + Kextra*ddA_dTT*trEe; + } + if(DDsigD_dTT!=NULL){ + STensorOperation::zero(*DDsigD_dTT); + *DDsigD_dTT = devEe; + *DDsigD_dTT *= 2*(ddGex_dTT*B + 2*dGex_dT*dB_dT + Gextra*ddB_dTT); + } + }; + + } + else + { + Msg::Error("extra branch type %d is not defined",_extraBranchType); + } +}; + void mlawNonLinearTVE::ThermoViscoElasticPredictor(const STensor3& Ee, const STensor3& Ee0, const IPNonLinearTVE *q0, IPNonLinearTVE *q1, double& Ke, double& Ge, double& Kde, double& Gde, @@ -1000,7 +1207,7 @@ void mlawNonLinearTVE::ThermoViscoElasticPredictor(const STensor3& Ee, const STe // Update the Properties to the current temperature (see below which ones are being used) double KT, GT, AlphaT_0, AlphaT, DKDT, DGDT, DAlphaDT; - getK(KT,T_set,&DKDT); getG(GT,T_set,&DGDT); getAlpha(AlphaT_0,T0); getAlpha(AlphaT,T_set,&DAlphaDT); + getK(q1,KT,T_set,&DKDT); getG(q1,GT,T_set,&DGDT); getAlpha(AlphaT_0,T0); getAlpha(AlphaT,T_set,&DAlphaDT); // Get LogStrain static STensor3 DE, devDE, devEe; @@ -1014,15 +1221,20 @@ void mlawNonLinearTVE::ThermoViscoElasticPredictor(const STensor3& Ee, const STe static STensor3 devK; STensorOperation::zero(devK); devK = 2*GT*devEe; - + // Initialise CorKirStress - Tr static double p; p = KT*(trEe - 3*AlphaT*(T1-_Tinitial)); - + // Initialise Moduli Ke = KT; Ge = GT; KTsum = KT; GTsum = GT; DKe = DKDT; DGe = DGDT; DKDTsum = DKDT; DGDTsum = DGDT; - + + // Kelvin-Voight + /*double invGe = 1./GT; + double invKe = 1./KT; + STensor3 D(0.); + double V= 0.;*/ // Main Loop for Maxwell Branches if ((_Ki.size() > 0) or (_Gi.size() > 0)){ @@ -1041,7 +1253,7 @@ void mlawNonLinearTVE::ThermoViscoElasticPredictor(const STensor3& Ee, const STe DKiDT.resize(_N,0.); DGiDT.resize(_N,0.); DAlphaiDT.resize(_N,0.); DDKiDT.resize(_N,0.); DDGiDT.resize(_N,0.); if (_TemFuncOpt == 1){ // Use Scalar Functions - getKi(KiT,T_set,&DKiDT,&DDKiDT); getGi(GiT,T_set,&DGiDT,&DDGiDT); getAlphai(AlphaiT_0,T0); getAlphai(AlphaiT,T_set,&DAlphaiDT); + getKi(q1,KiT,T_set,&DKiDT,&DDKiDT); getGi(q1,GiT,T_set,&DGiDT,&DDGiDT); getAlphai(AlphaiT_0,T0); getAlphai(AlphaiT,T_set,&DAlphaiDT); } @@ -1056,11 +1268,14 @@ void mlawNonLinearTVE::ThermoViscoElasticPredictor(const STensor3& Ee, const STe double expdtg = exp(-dtg); // double expdtgby2 = exp(-dtg/2.); double expdtgby2 = exp(-dtg2); - + + // Maxwell if (_TemFuncOpt == 0){ // Use Shift Factor - getGi(GiT,T_set); // Removed 2*_gi[i] - DGiDT[i] = -_Gi[i]/(_gi[i]) * Ddt_shiftDT*expdtgby2; - DDGiDT[i] = -_Gi[i]/(_gi[i]) * (DDdt_shiftDT - 1/(_gi[i])*pow(Ddt_shiftDT,2))*expdtgby2; + getGi(q1,GiT,T_set); // Removed 2*_gi[i] + // Msg::Error(" Inside TVE ThermoViscoElasticPredictor, _Gi[i] = %e", _Gi[i]); + // Msg::Error(" Inside TVE ThermoViscoElasticPredictor, GiT[i] = %e", GiT[i]); + DGiDT[i] = -GiT[i]/(_gi[i]) * Ddt_shiftDT*expdtgby2; + DDGiDT[i] = -GiT[i]/(_gi[i]) * (DDdt_shiftDT - 1/(_gi[i])*pow(Ddt_shiftDT,2))*expdtgby2; } // For Single Convolution @@ -1096,9 +1311,41 @@ void mlawNonLinearTVE::ThermoViscoElasticPredictor(const STensor3& Ee, const STe devOi[i] = 2*GiT[i]*q1->_A[i]; // + q1->_C[i]; devK += devOi[i]; + + // Kelvin-Voight + /* + invGe += (1.-expdtgby2)/_Gi[i]; + for (int k=0; k<3; k++){ + for (int l=0; l<3; l++){ + D(k,l) += q0->_A[i](k,l)*(expdtg-1.); + } + }*/ + } - - + /* + // Kelvin-Voight + Ge = 1./invGe; + // stress increment + static STensor3 DdevK; + DdevK = devDE; // dev corotational kirchoff stress predictor + DdevK += D; + DdevK *= (2.*Ge); + for (int i=0; i< _Gi.size(); i++){ + double dtg = dt_shift_1/(_gi[i]); + double dtg2 = dt_shift_2/(_gi[i]); + double expdtg = exp(-dtg); + double expdtgby2 = exp(-dtg2); + STensorOperation::zero(q1->_A[i]); + for (int k=0; k<3; k++){ + for (int l=0; l<3; l++){ + q1->_A[i](k,l) += expdtg*q0->_A[i](k,l) + expdtgby2*DdevK(k,l)/(2.*_Gi[i]); + } + } + } + STensorOperation::zero(devK); + devK += DdevK;*/ + + // Tr Q_i std::vector<double>& trOi = q1 -> getRefToTrViscoElasticOverStress(); // trOi[i].resize(_N,0.); std::vector<double>& trOGammai = q1 -> getRefToTrViscoElasticOverStrain(); @@ -1110,11 +1357,12 @@ void mlawNonLinearTVE::ThermoViscoElasticPredictor(const STensor3& Ee, const STe double expdtk = exp(-dtk); double expdtkby2 = exp(-dtk2); // double expdtkby2 = exp(-dtk/2.); - + + // Maxwell if (_TemFuncOpt == 0){ // Use Shift Factor - getKi(KiT,T_set); getAlphai(AlphaiT,T_set); // Removed 2*_ki[i] - DKiDT[i] = -_Ki[i]/(_ki[i]) * Ddt_shiftDT *expdtkby2; - DDKiDT[i] = -_Ki[i]/(_ki[i]) * (DDdt_shiftDT - 1/(_ki[i])*pow(Ddt_shiftDT,2)) *expdtkby2; + getKi(q1,KiT,T_set); getAlphai(AlphaiT,T_set); // Removed 2*_ki[i] + DKiDT[i] = -KiT[i]/(_ki[i]) * Ddt_shiftDT *expdtkby2; + DDKiDT[i] = -KiT[i]/(_ki[i]) * (DDdt_shiftDT - 1/(_ki[i])*pow(Ddt_shiftDT,2)) *expdtkby2; } // Single Convolution @@ -1160,9 +1408,33 @@ void mlawNonLinearTVE::ThermoViscoElasticPredictor(const STensor3& Ee, const STe } p += trOi[i]; + + + /* + // Kelvin-Voight + invKe += (1.-expdtkby2)/_Ki[i]; + V += q0->_B[i]*(expdtk-1.); + * */ + } + /* + // Kelvin-Voight + Ke = 1./invKe; + double Dp = Ke*(trDE+ V); // pressure predictor + for (int i=0; i< _Ki.size(); i++){ + double dtk = dt_shift_1/(_ki[i]); + double dtk2 = dt_shift_2/(_ki[i]); + double expdtk = exp(-dtk); + double expdtkby2 = exp(-dtk2); + q1->_B[i] = 0.; + q1->_B[i] += expdtk*q0->_B[i] + expdtkby2*Dp/(_Ki[i]); } + p = 0.; + p += Dp; + * */ } +// Msg::Error(" Inside TVE_predictorCorrector, Ke = %e, Ge = %e !!", Ke, Ge); + if (calculateStress){ q1->_kirchhoff = devK; q1->_kirchhoff(0,0) += p; @@ -1370,7 +1642,7 @@ void mlawNonLinearTVE::predictorCorrector_ThermoViscoElastic( // Update the Properties to the current temperature (see below which ones are being used) double KT, GT, AlphaT, KThConT, CpT, DKDT, DGDT, DAlphaDT, DKThConDT, DCpDT, DDKDT, DDGDT, DDAlphaDT; - getK(KT,T_set,&DKDT,&DDKDT); getG(GT,T_set,&DGDT,&DDGDT); getAlpha(AlphaT,T_set,&DAlphaDT,&DDAlphaDT); getKTHCon(KThConT,T_set,&DKThConDT); getCp(CpT,T_set,&DCpDT); + getK(q1,KT,T_set,&DKDT,&DDKDT); getG(q1,GT,T_set,&DGDT,&DDGDT); getAlpha(AlphaT,T_set,&DAlphaDT,&DDAlphaDT); getKTHCon(KThConT,T_set,&DKThConDT); getCp(CpT,T_set,&DCpDT); // Calculate/update Log Strain static STensor3 C; @@ -1404,14 +1676,58 @@ void mlawNonLinearTVE::predictorCorrector_ThermoViscoElastic( ThermoViscoElasticPredictor(E,q0->_Ee,q0,q1,Ke,Ge,Kde,Gde,DKe,DGe,DKde,DGde,KTsum,GTsum,DKDTsum,DGDTsum,T0,T); // Updates the values of moduli to the current temperatures and calculate stresses. Kde = 0.; Gde = 0.; + + // NEW + // additional branch + static STensor3 sigExtra, DsigExtraDT; + static STensor43 DsigExtraDE; + STensorOperation::zero(sigExtra); + STensorOperation::zero(DsigExtraDE); + STensorOperation::zero(DsigExtraDT); + if (_useExtraBranch){ + mlawNonLinearTVE::extraBranchLaw(E,T,q0,q1,sigExtra,stiff,&DsigExtraDE,&DsigExtraDT); + q1->_corKirExtra = sigExtra; + } + q1->_kirchhoff += sigExtra; + // NEW const STensor3& corKir = q1->getConstRefToCorotationalKirchhoffStress(); static STensor3 secondPK; STensorOperation::multSTensor3STensor43(corKir,dlnCdC,secondPK); STensorOperation::multSTensor3(F,secondPK,P); // 1st PK + // P *= (1+q1->_elasticShearPropertyScaleFactor); + // elastic energy - q1->_elasticEnergy = freeEnergyMechanical(*q1,T); // deformationEnergy(*q1,T); + q1->_elasticEnergy = freeEnergyMechanical(*q1,T0,T); + + /* + // Hyperelastic Potential + double psi_hyper(0.); + static STensor3 P_hyper; + static STensor43 dPdF_hyper; + static STensor63 d2PdFF_hyper; + const bool stiff_hyper = true; + const bool Dstiff_hyper = false; + STensorOperation::zero(P_hyper); + STensorOperation::zero(dPdF_hyper); + STensorOperation::zero(d2PdFF_hyper); + if (_elasticPotential != NULL){ + psi_hyper = _elasticPotential->get(F); + _elasticPotential->constitutive(F,P_hyper,stiff_hyper,&dPdF_hyper,Dstiff_hyper,&d2PdFF_hyper); + }*/ + + // Mullins Effect Scaler + if (_mullinsEffect != NULL && q1->_ipMullinsEffect != NULL){ + mlawNonLinearTVE::calculateMullinsEffectScaler(q0, q1, T); + } + double eta_mullins = 1.; + if (q1->_ipMullinsEffect != NULL){ + eta_mullins = q1->_ipMullinsEffect->getEta(); + P *= eta_mullins; + q1->_elasticEnergy *= eta_mullins; + } + // Msg::Error(" Inside TVE predCorr, after updating q1->_elasticEnergy = %e!!",q1->_elasticEnergy); // thermal energy q1->_thermalEnergy = CpT*T; @@ -1469,7 +1785,17 @@ void mlawNonLinearTVE::predictorCorrector_ThermoViscoElastic( double& trDE = q1->getRefToTrDE(); STensorOperation::decomposeDevTr(DEe,devDE,trDE); - corKirInfinity( devEe, trEe, T, corKirDevInf, corKirTrInf ); + corKirInfinity(q1, devEe, trEe, T, corKirDevInf, corKirTrInf); // MISTAKE HERE -> corKirTrInf is the pressure + + // Add extrabranch to corKir_inf + double tr_sigExtra(0.); + static STensor3 dev_sigExtra; + STensorOperation::decomposeDevTr(sigExtra,dev_sigExtra,tr_sigExtra); + corKirDevInf += dev_sigExtra; + corKirTrInf += 1/3*tr_sigExtra; // LHS is pressure + + q1->_trCorKirinf_TVE = 3*corKirTrInf; + q1->_devCorKirinf_TVE = corKirDevInf; for (int i=0; i<3; i++){ // DcorKirDT(i,i) += corKirTr/3/(Ke+Kde*(T-T_temp))*(DKe + DKde*(T-T_temp)) - 3*KT*(DAlphaDT*(T-_Tinitial) + AlphaT); // 1st formulation @@ -1490,7 +1816,7 @@ void mlawNonLinearTVE::predictorCorrector_ThermoViscoElastic( KiT.resize(_N,0.);GiT.resize(_N,0.);AlphaiT.resize(_N,0.);DKiDT.resize(_N,0.);DGiDT.resize(_N,0.);DAlphaiDT.resize(_N,0.);DDKiDT.resize(_N,0.);DDGiDT.resize(_N,0.);DDAlphaiDT.resize(_N,0.); if (_TemFuncOpt == 1){ - getKi(KiT,T_set,&DKiDT,&DDKiDT); getGi(GiT,T_set,&DGiDT,&DDGiDT); getAlphai(AlphaiT,T_set,&DAlphaiDT,&DDAlphaiDT); + getKi(q1,KiT,T_set,&DKiDT,&DDKiDT); getGi(q1,GiT,T_set,&DGiDT,&DDGiDT); getAlphai(AlphaiT,T_set,&DAlphaiDT,&DDAlphaiDT); } static STensor3 DOiDT; @@ -1549,11 +1875,11 @@ void mlawNonLinearTVE::predictorCorrector_ThermoViscoElastic( STensorOperation::zero(DOGammai); STensorOperation::zero(DOGammaiDT); STensorOperation::zero(DDOGammaiDT); if (_TemFuncOpt == 0){ // Use Shift Factor - getKi(KiT,T_set); getGi(GiT,T_set); getAlphai(AlphaiT,T_set); - DKiDT[i] = -_Ki[i]/(_ki[i]) * Ddt_shiftDT*expdtkby2; // Removed _ki/2 and _gi/2 - DDKiDT[i] = -_Ki[i]/(_ki[i]) * (DDdt_shiftDT - 1/(_ki[i])*pow(Ddt_shiftDT,2))*expdtkby2; - DGiDT[i] = -_Gi[i]/(_gi[i]) * Ddt_shiftDT*expdtgby2; - DDGiDT[i] = -_Gi[i]/(_gi[i]) * (DDdt_shiftDT - 1/(_gi[i])*pow(Ddt_shiftDT,2))*expdtgby2; + getKi(q1,KiT,T_set); getGi(q1,GiT,T_set); getAlphai(AlphaiT,T_set); + DKiDT[i] = -KiT[i]/(_ki[i]) * Ddt_shiftDT*expdtkby2; // Removed _ki/2 and _gi/2 + DDKiDT[i] = -KiT[i]/(_ki[i]) * (DDdt_shiftDT - 1/(_ki[i])*pow(Ddt_shiftDT,2))*expdtkby2; + DGiDT[i] = -GiT[i]/(_gi[i]) * Ddt_shiftDT*expdtgby2; + DDGiDT[i] = -GiT[i]/(_gi[i]) * (DDdt_shiftDT - 1/(_gi[i])*pow(Ddt_shiftDT,2))*expdtgby2; } for (int j=0; j<3; j++){ @@ -1609,9 +1935,9 @@ void mlawNonLinearTVE::predictorCorrector_ThermoViscoElastic( STensorOperation::zero(DGammai); STensorOperation::zero(DDGammaiDT); DQiDT -= DOiDT; DDQiDT -= DDOiDT; DDGammaiDT -= DDOGammaiDT; for (int j=0; j<3; j++){ - Qi(j,j) += (_Ki[i]*trEe - trOi[i]); + Qi(j,j) += (KiT[i]*trEe - trOi[i]); for (int k=0; k<3; k++){ - Qi(j,k) += (2*_Gi[i]*devEe(j,k) - devOi[i](j,k)); + Qi(j,k) += (2*GiT[i]*devEe(j,k) - devOi[i](j,k)); } } DGammai += DEe; @@ -1627,8 +1953,8 @@ void mlawNonLinearTVE::predictorCorrector_ThermoViscoElastic( static STensor43 temp_DDQiDTDE; static STensor43 temp_DDgammiDtDE; - double Ki_term = (_Ki[i]*(1-expdtkby2)+T*DKiDT[i]); - double Gi_term = (_Gi[i]*(1-expdtgby2)+T*DGiDT[i]); + double Ki_term = (KiT[i]*(1-expdtkby2)+T*DKiDT[i]); + double Gi_term = (GiT[i]*(1-expdtgby2)+T*DGiDT[i]); isotropicHookTensor( Ki_term, Gi_term , temp_DDQiDTDE ); double Ki_term_2 = 1/3*expdtkby2; @@ -1695,8 +2021,11 @@ void mlawNonLinearTVE::predictorCorrector_ThermoViscoElastic( // Compute Mechanical Tangents - dSdC and dPdF static STensor43 DcorKDE; - // isotropicHookTensor(Ke,Ge,DcorKDE); // Hookes tensor - isotropicHookTensor(Ke+Kde*(T-T_temp),Ge+Gde*(T-T_temp),DcorKDE); // Reformulate + isotropicHookTensor(Ke,Ge,DcorKDE); // Hookes tensor + // isotropicHookTensor(Ke+Kde*(T-T_temp),Ge+Gde*(T-T_temp),DcorKDE); // Reformulate + + // extraBranch - zero by default + DcorKDE += DsigExtraDE; static STensor43 DCeDFe; //(0.); static STensor43 DEeDFe(0.); @@ -1755,8 +2084,12 @@ void mlawNonLinearTVE::predictorCorrector_ThermoViscoElastic( } } } - + // Compute Mechano-thermal Tangents - dSdT and dPdT + + // extraBranch - zero by default + DcorKirDT += DsigExtraDT; + static STensor3 DSDT; STensorOperation::zero(DSDT); for (int i=0; i<3; i++){ @@ -1804,6 +2137,7 @@ void mlawNonLinearTVE::predictorCorrector_ThermoViscoElastic( for (int i=0; i<3; i++){ for (int j=0; j<3; j++){ for (int k=0; k<3; k++){ + // Msg::Info("dfluxTdF->J: Jacobian= %e",J); 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); diff --git a/NonLinearSolver/materialLaw/mlawNonLinearTVE.h b/NonLinearSolver/materialLaw/mlawNonLinearTVE.h index 9afdddbf5a9a02afeeeb2245871a79f064fa7457..c97804a6925d4caeae3d719a6b10952da2ea9910 100644 --- a/NonLinearSolver/materialLaw/mlawNonLinearTVE.h +++ b/NonLinearSolver/materialLaw/mlawNonLinearTVE.h @@ -15,67 +15,19 @@ #include "STensor3.h" #include "STensor43.h" #include "STensor63.h" -// #include "ipHyperelastic.h" #include "ipNonLinearTVE.h" #include "viscosityLaw.h" #include "mlawHyperelasticFailureCriterion.h" #include "scalarFunction.h" #include "mlawHyperelastic.h" +#include "elasticPotential.h" -/* Patch Notes - -1) 23/12/21 - NonLinearTVE adopted from mlawHyperelastic; Pure ViscoElasticity with Temp Functions for Moduli and Thermal Props (latter Still Unused) - [mLAW FORMED -- .h , .cpp] - Changed mu to G -.......1.0.1) 24/12/21 - Created new IPVariable, updated dG3DMaterialLaw, update dG3DIPVariable, updated mlaw.h, -.......1.0.2) 28/12/21 - Added the mlaw.cpp and ip.cpp to the CMakeFiles.txt in materiallaw/ and internalpoints/ respectively. -.......1.0.3) 28/12/21 - (Tested against previous results of mlawHyperelastic in Octave const Temp results --- Works fine!!). - -...1.1) 29/12/21 - Updated with ThermoMechanics - (UNTESTED so far). -.......1.1.1) 29/12/21 - Updated dG3DIPVariable with inheritance from ThermoMechanicsDG3DIPVariableBase Pure virtual class (and LinearThermoMechanicsDG3DIPVariable). - - Noted that the Pure virtual base class may cause problems when introducing nonLocal Variables. -.......1.1.2) 29/12/21 - Updated dG3DMaterialLaw with adaptations from LinearThermoMechanicsDG3DMaterial. -.......1.1.3) 29/12/21 - Updated ipNonLinearTVE with adaptations from LinearThermoMechanicsDG3DMaterial. -.......1.1.4) 29/12/21 - Updated mlawNonLinearTVE with adaptations from LinearThermoMechanicsDG3DMaterial. - -...1.2) 30/12/21 - Add Temperature BCs, add temperature extradof from dG3DIpvariable (ThermoMechanicsDG3DIPVariableBase), - change the Stress calculation Function in dG3DMaterialLaw; -.......1.2.1) 05/01/22 - linearK and stiff_alphadilatation added to ipvcur pointer in dG3Dmateriallaw.cpp through direct member functions in mlaw....TVE.h - - IC Working, ScalarFluxBC Not Working!!!!!!!!! -.......1.2.2) 06/01/22 - CleanUp! - - Removed thermal props unused member functions from everywhere. - - Remember to add tempFunc multiplication where needed! Note that my Tg scalarFunctions will likely not be normalised functions. -.......1.2.3) 06/01/22 - Attempted addition of coupled ThermoMech features from ThermoElastic part of FullJ2ThermoMech...dG3DMaterialLaw - -...1.3) 15/02/22 - Addition of TTSP -.......1.3.1) 22/02/22 - Addition of WLF shift factor and shifted time member functions -.......1.3.2) 04/03/22 - Addition of convolution single/double integrals in the predictor functions - - CLEANUP 1.0 -> Making mlaw and ipvariable dependent classes of mlawHyperElastic -.......1.3.3) 14/03/22 - Thermal and mechanical source code -.......1.3.4) 24/03/22 - Tangent and mechanical source derivatives -.......1.3.5) 13/04/22 - CLEANUP 2.0 -.......1.3.6) 25/04/22 - Fully Corrected TVE derivatives. -...1.4) 03/06/22 - CLEANUP 3.0 Renamed class to mlawNonLinearTVE -.......1.4.1) 04/06/22 - Removed all Unused Code -.......1.4.2) 07/06/22 - Added calculateStress boolean in ThermoViscoElasticPredictor -> to just update TVE flow in TVP predictorCorrector functions - * -.......1.?.?) ??/??/22 - Addition of new class for Psi_ve - * - -2) 04/06/22 - NonLinearTVP adopted from mlawPowerYieldHyper; Temp Functions for Hardening Moduli and Yield Strengths - [mLAW FORMED -- .h , .cpp, in the mlawNonLinearTVE] -*/ class mlawNonLinearTVE : public mlawPowerYieldHyper{ protected: - // Material Properties at Room Temp. - Mechanical - // double _rho; // Density - // double _E; // Youngs Modulus - // double _nu; // Poissons Ratio - // double _lambda; // 1st Lame parameter + // Renaming _mu to _G double _G; // 2nd Lame parameter (=mu) Shear Modulus - // double _K; // Bulk Modulus // Material Properties at Room Temp. - Thermal double _scalarAlpha; // (scalar) Thermal Dilatation Coefficient (=alpha) - Tensor exists for Anisotropic Dilatation @@ -86,22 +38,12 @@ class mlawNonLinearTVE : public mlawPowerYieldHyper{ STensor3 _tensorK; // (tensor3) Thermal Conductivity (K) // ViscoElastic Data - // viscoelasticType _viscoMethod; // viscoelastic method 0-Maxwell, 1-Kelvin-Voight (ENUM type variable) - TVE only works with Maxwell - // int _N; // number of elements - // std::vector<double> _Ki; // vector of branch bulk moduli - // std::vector<double> _ki; // vector of branch relaxation times for bulk - // std::vector<double> _Gi; // vector of branch shear moduli - // std::vector<double> _gi; // vector of branch relaxation times for shear std::vector<double> _Alphai; // vector of branch alpha // Misc. - // STensor43 Cel; // elastic hook tensor - // int _order ; // to approximate log and exp of a tensor bool _thermalEstimationPreviousConfig; // flap for thermalEstimation using PreviousConfig // Testing - // double _perturbationfactor; // perturbation factor - // bool _tangentByPerturbation; // flag for tangent by perturbation int _testFlag; // for various solutions to convolution // Temperature Settings and Functions @@ -124,6 +66,14 @@ class mlawNonLinearTVE : public mlawPowerYieldHyper{ // Shift factor - Everything related to it double _C1; // WLF Universal Constant 1 - set in .py file double _C2; // WLF Universal Constant 2 - set in .py file + + // Mullins Effect + mullinsEffect* _mullinsEffect; + + // Hyperelastic Potential - Non-linear elasticity + elasticPotential* _elasticPotential; + bool _useExtraBranch; + scalarFunction* _temFunc_elasticCorrection; #ifndef SWIG protected: @@ -133,10 +83,23 @@ class mlawNonLinearTVE : public mlawPowerYieldHyper{ double *t_shift = NULL, double *Ddt_shiftDT = NULL, double *DDdt_shiftDT = NULL, const int opt_time = 1, const int opt_order = 2) const; virtual double linearInterpTemp(const double t_interp, const double t0, const double t1, const double T0, const double T1) const; - virtual double freeEnergyMechanical(const IPNonLinearTVE& q, const double Tc) const ; + virtual double freeEnergyMechanical(const IPNonLinearTVE& q, const double T0, const double T) const ; virtual double setTemp(const double T0, const double T1, const int para) const ; + + virtual void calculateMullinsEffectScaler(const IPNonLinearTVE* q0, IPNonLinearTVE *q1, const double T) const; - void corKirInfinity( const STensor3& devEe, const double& trEe, const double T, STensor3& CorKirDevInf, double& CorKirTrInf) const; + void evaluateElasticCorrection(const double trE, const STensor3 &devE, const double& T, + double &A_v, double &dAdE, double &intA, double &dAdT, + double &B_d, STensor3 &dB_vddev, double &intB, double &dBdT, + double *ddAdTT = NULL, double *ddBdTT = NULL) const; + + void extraBranchLaw(const STensor3& Ee, const double& T, const IPNonLinearTVE *q0, IPNonLinearTVE *q1, + STensor3& sig, const bool stiff = false, STensor43* DsigDEe = NULL, STensor3* DsigDT = NULL, + double* DsigV_dTrEe = NULL, STensor43* DsigD_dDevEe = NULL, + double* DsigV_dT = NULL, STensor3* DsigD_dT = NULL, + double* DDsigV_dTT = NULL, STensor3* DDsigD_dTT = NULL) const; + + void corKirInfinity(const IPNonLinearTVE *q1, const STensor3& devEe, const double& trEe, const double T, STensor3& CorKirDevInf, double& CorKirTrInf) const; void ThermoViscoElasticPredictor(const STensor3& Ee, const STensor3& Ee0, const IPNonLinearTVE *q0, IPNonLinearTVE *q1, double& Ke, double& Ge, double& Kde, double& Gde, @@ -206,6 +169,11 @@ class mlawNonLinearTVE : public mlawPowerYieldHyper{ // Virtual Destructor virtual ~mlawNonLinearTVE(); + + void setMullinsEffect(const mullinsEffect& mullins){ + if (_mullinsEffect) delete _mullinsEffect; + _mullinsEffect = mullins.clone(); + }; // Non-Const Functions for strain_order and VE data that are called from .py file. ---- These WILL change the values of the variables defined in the class object. virtual void setViscoElasticNumberOfElement(const int N); @@ -222,6 +190,7 @@ class mlawNonLinearTVE : public mlawPowerYieldHyper{ virtual void setModelOption(const int modelFlag){_modelFlag = modelFlag;}; virtual void setTestOption(const int testFlag){_testFlag = testFlag;}; void setShiftFactorConstantsWLF(const double C1, const double C2){_C1 = C1; _C2 = C2;}; + virtual void useExtraBranchBool(const bool useExtraBranch){_useExtraBranch = useExtraBranch;}; void setTemperatureFunction_BulkModulus(const scalarFunction& Tfunc){ if (_temFunc_K != NULL) delete _temFunc_K; _temFunc_K = Tfunc.clone(); @@ -242,6 +211,10 @@ class mlawNonLinearTVE : public mlawPowerYieldHyper{ if (_temFunc_Cp != NULL) delete _temFunc_Cp; _temFunc_Cp = Tfunc.clone(); } + void setTemperatureFunction_ElasticCorrection(const scalarFunction& Tfunc){ + if (_temFunc_elasticCorrection != NULL) delete _temFunc_elasticCorrection; + _temFunc_elasticCorrection = Tfunc.clone(); + } void setTemperatureFunction_BranchBulkModuli(const scalarFunction& Tfunc,int i){ if (i> _N or i<1) Msg::Error("This setting is invalid %d > %d",i,_N); @@ -265,6 +238,8 @@ class mlawNonLinearTVE : public mlawPowerYieldHyper{ // Const Functions to get temp-updated values of material properties - Args by reference, or return the variable. + virtual const mullinsEffect* getConstRefToMullinsEffect() const {return _mullinsEffect;}; + virtual std::vector<double> getBetai(const double _K, const std::vector<double> _Ki) const{ std::vector<double> Beta_i; Beta_i.resize(_N,0.); @@ -274,22 +249,24 @@ class mlawNonLinearTVE : public mlawPowerYieldHyper{ return Beta_i; } - virtual void getK(double& KT, const double Tc, double *dK = NULL, double *ddK = NULL) const{ - KT = _K*_temFunc_K->getVal(Tc); + virtual void getK(const IPNonLinearTVE *q1, double& KT, const double Tc, double *dK = NULL, double *ddK = NULL) const{ + double K = _K; // *q1->getConstRefToElasticBulkPropertyScaleFactor(); + KT = K*_temFunc_K->getVal(Tc); if(dK!=NULL){ - *dK=_K*_temFunc_K->getDiff(Tc); // Here, *dK can be imagined as *(dK+0) or dK[0] if dK were a vector. See dKi below. + *dK = K*_temFunc_K->getDiff(Tc); // Here, *dK can be imagined as *(dK+0) or dK[0] if dK were a vector. See dKi below. } if(ddK!=NULL){ - *ddK = _K*_temFunc_K->getDoubleDiff(Tc); + *ddK = K*_temFunc_K->getDoubleDiff(Tc); } } - virtual void getG(double& GT, const double Tc, double *dG = NULL, double *ddG = NULL) const{ - GT = _G*_temFunc_G->getVal(Tc); + virtual void getG(const IPNonLinearTVE *q1, double& GT, const double Tc, double *dG = NULL, double *ddG = NULL) const{ + double G = _G; // *q1->getConstRefToElasticShearPropertyScaleFactor(); + GT = G*_temFunc_G->getVal(Tc); if(dG!=NULL){ - *dG = _G*_temFunc_G->getDiff(Tc); + *dG = G*_temFunc_G->getDiff(Tc); } if(ddG!=NULL){ - *ddG = _G*_temFunc_G->getDoubleDiff(Tc); + *ddG = G*_temFunc_G->getDoubleDiff(Tc); } } virtual void getAlpha(double& alphaT, const double Tc, double *dAlpha = NULL, double *ddAlpha = NULL) const{ @@ -318,29 +295,39 @@ class mlawNonLinearTVE : public mlawPowerYieldHyper{ } // The 3rd argument is a pointer to a vector. - virtual void getKi(std::vector<double>& Ki_T, const double Tc, std::vector<double>* dKi=NULL, std::vector<double>* ddKi=NULL) const{ + virtual void getKi(const IPNonLinearTVE *q1, std::vector<double>& Ki_T, const double Tc, std::vector<double>* dKi=NULL, std::vector<double>* ddKi=NULL) const{ + std::vector<double> Ki; + Ki.clear(); Ki.resize(_N,0.); + for (int i=0; i<_Ki.size();i++){ + Ki[i] = _Ki[i]; // *(1+q1->getConstRefToElasticBulkPropertyScaleFactor()); + } Ki_T.resize(_N,0.); for (int i=0; i<_Ki.size();i++){ - Ki_T[i] = _Ki[i]*_temFunc_Ki[i]->getVal(Tc); + Ki_T[i] = Ki[i]*_temFunc_Ki[i]->getVal(Tc); if(dKi!=NULL){ - dKi->at(i) = _Ki[i]*_temFunc_Ki[i]->getDiff(Tc); + dKi->at(i) = Ki[i]*_temFunc_Ki[i]->getDiff(Tc); } if(ddKi!=NULL){ - ddKi->at(i) = _Ki[i]*_temFunc_Ki[i]->getDoubleDiff(Tc); + ddKi->at(i) = Ki[i]*_temFunc_Ki[i]->getDoubleDiff(Tc); } } } // The 3rd argument is a pointer to a vector. - virtual void getGi(std::vector<double>& Gi_T, const double Tc, std::vector<double>* dGi=NULL, std::vector<double>* ddGi=NULL) const{ + virtual void getGi(const IPNonLinearTVE *q1, std::vector<double>& Gi_T, const double Tc, std::vector<double>* dGi=NULL, std::vector<double>* ddGi=NULL) const{ + std::vector<double> Gi; + Gi.clear(); Gi.resize(_N,0.); + for (int i=0; i<_Gi.size();i++){ + Gi[i] = _Gi[i]; // *(1+q1->getConstRefToElasticShearPropertyScaleFactor()); + } Gi_T.resize(_N,0.); for (int i=0; i<_Gi.size();i++){ - Gi_T[i] = _Gi[i]*_temFunc_Gi[i]->getVal(Tc); + Gi_T[i] = Gi[i]*_temFunc_Gi[i]->getVal(Tc); if(dGi!=NULL){ - dGi->at(i) = _Gi[i]*_temFunc_Gi[i]->getDiff(Tc); // *(dGi+i) is equivalent to dGi[i] + dGi->at(i) = Gi[i]*_temFunc_Gi[i]->getDiff(Tc); // *(dGi+i) is equivalent to dGi[i] } if(ddGi!=NULL){ - ddGi->at(i) = _Gi[i]*_temFunc_Gi[i]->getDoubleDiff(Tc); + ddGi->at(i) = Gi[i]*_temFunc_Gi[i]->getDoubleDiff(Tc); } } } @@ -389,7 +376,7 @@ class mlawNonLinearTVE : public mlawPowerYieldHyper{ // Some more Member Functions virtual matname getType() const{return materialLaw::nonlinearTVE;} // function of materialLaw - virtual void createIPState(IPStateBase* &ips,const bool* state_=NULL,const MElement *ele=NULL, const int nbFF_=0, const IntPt *GP=NULL, const int gpt = 0) const{ + 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("mlawNonLinearTVE::createIPState has not been defined"); }; virtual void initLaws(const std::map<int,materialLaw*> &maplaw){}; // this law is initialized so nothing to do diff --git a/NonLinearSolver/materialLaw/mlawNonLinearTVP.cpp b/NonLinearSolver/materialLaw/mlawNonLinearTVP.cpp index 92c664607a4bf1bf4e8edd9a75bfb4b63c028c75..4cce52295a26180235091936ebd2fb047f7f8aa9 100644 --- a/NonLinearSolver/materialLaw/mlawNonLinearTVP.cpp +++ b/NonLinearSolver/materialLaw/mlawNonLinearTVP.cpp @@ -18,20 +18,27 @@ mlawNonLinearTVP::mlawNonLinearTVP(const int num,const double E,const double nu, const double Tinitial, const double Alpha, const double KThCon, const double Cp, const bool matrixbyPerturbation, const double pert, const bool thermalEstimationPreviousConfig): mlawNonLinearTVE(num, E, nu, rho, tol, Tinitial, Alpha, KThCon, Cp, matrixbyPerturbation, pert, thermalEstimationPreviousConfig), - _TaylorQuineyFactor(0.9), _HR(1.){ + _TaylorQuineyFactor(0.9), _TaylorQuineyFlag(false),_PolyOrderChaboche(0), _HR(1.){ + + _PolyCoeffsChaboche.resize(_PolyOrderChaboche+1); + _PolyCoeffsChaboche.setAll(0.); + _PolyCoeffsChaboche(0) = 1.; // by default, no temperature dependence _temFunc_Sy0 = new constantScalarFunction(1.); _temFunc_H = new constantScalarFunction(1.); _temFunc_Hb = new constantScalarFunction(1.); _temFunc_visc = new constantScalarFunction(1.); - + }; // , mlawPowerYieldHyper(src) mlawNonLinearTVP::mlawNonLinearTVP(const mlawNonLinearTVP& src): mlawNonLinearTVE(src) { - + _TaylorQuineyFactor = src._TaylorQuineyFactor; + _TaylorQuineyFlag = src._TaylorQuineyFlag; + _PolyOrderChaboche = src._PolyOrderChaboche; + _PolyCoeffsChaboche = src._PolyCoeffsChaboche; _HR = src._HR; _temFunc_Sy0 = NULL; // temperature dependence of initial yield stress @@ -42,23 +49,29 @@ mlawNonLinearTVP::mlawNonLinearTVP(const mlawNonLinearTVP& src): mlawNonLinearTV if (src._temFunc_H != NULL){ _temFunc_H = src._temFunc_H->clone(); } - + _temFunc_Hb = NULL; // temperature dependence of kinematic hardening if (src._temFunc_Hb != NULL) _temFunc_Hb = src._temFunc_Hb->clone(); - + _temFunc_visc = NULL; // temperature dependence of viscosity if (src._temFunc_visc != NULL) _temFunc_visc = src._temFunc_visc->clone(); }; mlawNonLinearTVP& mlawNonLinearTVP::operator=(const materialLaw& source){ - + mlawNonLinearTVE::operator=(source); // mlawPowerYieldHyper::operator=(source); const mlawNonLinearTVP* src =dynamic_cast<const mlawNonLinearTVP*>(&source); if(src != NULL){ _TaylorQuineyFactor = src->_TaylorQuineyFactor; + _TaylorQuineyFlag = src->_TaylorQuineyFlag; + _PolyOrderChaboche = src->_PolyOrderChaboche; + + _PolyCoeffsChaboche.resize(src->_PolyCoeffsChaboche.size()); + _PolyCoeffsChaboche.setAll(src->_PolyCoeffsChaboche); + _HR = src->_HR; if(_temFunc_Sy0 != NULL) delete _temFunc_Sy0; // temperature dependence of initial yield stress if (src->_temFunc_Sy0!= NULL) @@ -78,8 +91,8 @@ mlawNonLinearTVP& mlawNonLinearTVP::operator=(const materialLaw& source){ mlawNonLinearTVP::~mlawNonLinearTVP(){ if (_temFunc_Sy0 != NULL) delete _temFunc_Sy0; _temFunc_Sy0 = NULL; - if (_temFunc_H != NULL) delete _temFunc_H; _temFunc_H= NULL; - if (_temFunc_Hb != NULL) delete _temFunc_Hb; _temFunc_Hb= NULL; + if (_temFunc_H != NULL) delete _temFunc_H; _temFunc_H= NULL; + if (_temFunc_Hb != NULL) delete _temFunc_Hb; _temFunc_Hb= NULL; if (_temFunc_visc != NULL) delete _temFunc_visc; _temFunc_visc= NULL; }; @@ -109,55 +122,83 @@ void mlawNonLinearTVP::hardening(const IPNonLinearTVP* q0, IPNonLinearTVP* q1, c }; void mlawNonLinearTVP::getModifiedMandel(const STensor3& C, const IPNonLinearTVP *q0, IPNonLinearTVP *q1) const{ - + STensor3& M = q1->getRefToModifiedMandel(); const STensor3& corKir = q1->getConstRefToCorotationalKirchhoffStress(); - + STensor3 Cinv; STensorOperation::inverseSTensor3(C, Cinv); - + STensor3 temp1, temp2; STensorOperation::multSTensor3(C, corKir, temp1); STensorOperation::multSTensor3(temp1, Cinv, temp2); - + M = 0.5*(corKir + temp2); }; void mlawNonLinearTVP::checkCommutavity(STensor3& commuteCheck,const STensor3& Ce, const STensor3& S, const IPNonLinearTVP *q1) const{ - + const STensor3& M = q1->getConstRefToModifiedMandel(); const STensor3& corKir = q1->getConstRefToCorotationalKirchhoffStress(); - + STensor3 temp1, temp2, temp3, temp4, temp6; STensorOperation::multSTensor3(Ce, S, temp1); STensorOperation::multSTensor3(S, Ce, temp2); STensorOperation::multSTensor3(corKir, Ce, temp3); STensorOperation::multSTensor3(Ce, corKir, temp4); - - // Check S + + // Check S commuteCheck = temp1; commuteCheck -= temp2; - + // Check corKir (just for fun) temp6 = temp3; temp6 -= temp4; - + // RANK OF A ZERO TENSOR is ZERO - maybe use this? }; -void mlawNonLinearTVP::getChabocheCoeffs(fullVector<double>& coeffs, const double& opt, const IPNonLinearTVP *q1) const{ +void mlawNonLinearTVP::setPolynomialOrderChabocheCoeffs(const int order){_PolyOrderChaboche = order;}; + +void mlawNonLinearTVP::setPolynomialCoeffsChabocheCoeffs(const int i, const double val){ + _PolyCoeffsChaboche(i) = val; + Msg::Info("setting: term=%d PolyCoeffsChaboche= %e",i,val); +} + +void mlawNonLinearTVP::getChabocheCoeffs(fullVector<double>& coeffs, const double& opt, const IPNonLinearTVP *q1, std::vector<double>* dcoeffs) const{ - double p = q1->_epspbarre; // eq.plastic strain + const double p = q1->_epspbarre; // eq.plastic strain coeffs.resize(2); - - coeffs(0) = 1; // 1; //DEBUGGING - coeffs(1) = 0; - - // add dependency on p later + + coeffs(0) = 1; // 0; //DEBUGGING + coeffs(1) = 0; // 0; //DEBUGGING + + + if(dcoeffs!=NULL){ + dcoeffs->resize(2); + dcoeffs->at(0) = 1; + dcoeffs->at(1) = 0; + } + if (opt==1){ + if (_PolyOrderChaboche == 1){ + coeffs(0) += _PolyCoeffsChaboche(0)+ _PolyCoeffsChaboche(1)*p; + if(dcoeffs!=NULL){dcoeffs->at(0) += _PolyCoeffsChaboche(1);} + } + else if (_PolyOrderChaboche == 2){ + coeffs(0) += _PolyCoeffsChaboche(0)+ _PolyCoeffsChaboche(1)*p + _PolyCoeffsChaboche(2)*p*p; + if(dcoeffs!=NULL){dcoeffs->at(0) += _PolyCoeffsChaboche(1)+2.*_PolyCoeffsChaboche(2)*p;} + } + else if (_PolyOrderChaboche == 3){ + coeffs(0) += _PolyCoeffsChaboche(0)+ _PolyCoeffsChaboche(1)*p + _PolyCoeffsChaboche(2)*p*p+_PolyCoeffsChaboche(3)*p*p*p; + if(dcoeffs!=NULL){dcoeffs->at(0) += _PolyCoeffsChaboche(1)+2.*_PolyCoeffsChaboche(2)*p+ 3*_PolyCoeffsChaboche(3)*p*p;} + } + else + Msg::Error("order %d is not implemented in PolynomialChacbocheCoeffs of mlawNonLinearTVP::getChabocheCoeffs",_PolyOrderChaboche); + } }; void mlawNonLinearTVP::getPlasticPotential(const double& phiP, const double& phiE, double& Px) const{ - + Px = pow(phiE,2) + _b*pow(phiP,2); }; @@ -167,7 +208,7 @@ void mlawNonLinearTVP::getYieldCoefficientTempDers(const IPNonLinearTVP *q1, con Hc = q1->_ipCompression->getDR(); dsigcdT = q1->_ipCompression->getDRDT(); ddsigcdTT = q1->_ipCompression->getDDRDTT(); - + double sigt(0.), Ht(0.), dsigtdT(0.), ddsigtdTT(0.); sigt = q1->_ipTraction->getR(); @@ -179,23 +220,23 @@ void mlawNonLinearTVP::getYieldCoefficientTempDers(const IPNonLinearTVP *q1, con DcoeffsDT.resize(3); DDcoeffsDTT.resize(3); double m = sigt/sigc; - double DmDT = (dsigtdT*sigc- sigt*dsigcdT)/(sigc*sigc); - double DDmDTT = (ddsigtdTT*sigc - sigt*ddsigcdTT)/(sigc*sigc) - 2*(dsigtdT*sigc- sigt*dsigcdT)/(sigc*sigc*sigc)*dsigcdT; + double DmDT = (dsigtdT*sigc- sigt*dsigcdT)/(sigc*sigc); + double DDmDTT = (ddsigtdTT*sigc - sigt*ddsigcdTT)/(sigc*sigc) - 2.*(dsigtdT*sigc- sigt*dsigcdT)/(sigc*sigc*sigc)*dsigcdT; double Da1Dm = 3./sigc*(_n*pow(m,_n-1.)/(m+1.) - (pow(m,_n)-1.)/(m+1.)/(m+1.)); - double DDa1Dmm = 3./sigc*(_n*(_n-1)*pow(m,_n-2.)/(m+1.) - _n*(pow(m,_n)-1.)/(m+1.)/(m+1.) - _n*pow(m,_n-1)/(m+1.)/(m+1.) + 2.*(pow(m,_n)-1.)/(m+1.)/(m+1.)/(m+1.)); + double DDa1Dmm = 3./sigc*(_n*(_n-1.)*pow(m,_n-2.)/(m+1.) - _n*(pow(m,_n)-1.)/(m+1.)/(m+1.) - _n*pow(m,_n-1)/(m+1.)/(m+1.) + 2.*(pow(m,_n)-1.)/(m+1.)/(m+1.)/(m+1.)); double term = _n*pow(m,_n) + _n*pow(m,_n-1.) - pow(m,_n); - double dterm = pow(_n,2)*pow(m,_n-1.) + _n*(_n-1)*pow(m,_n-2.) - _n*pow(m,_n-1); + double dterm = pow(_n,2.)*pow(m,_n-1.) + _n*(_n-1)*pow(m,_n-2.) - _n*pow(m,_n-1.); DcoeffsDT(2) = -_n*pow(sigc,-_n-1.)*dsigcdT; - DcoeffsDT(1) = Da1Dm*DmDT - 3.*(pow(m,_n)-1.)/(m+1.)/(sigc*sigc)*dsigcdT; - DcoeffsDT(0) = ((_n*pow(m,_n-1)+1.)/(m+1) - (pow(m,_n)+m)/(m+1.)/(m+1.))*DmDT; - - DDcoeffsDTT(2) = -_n*pow(sigc,-_n-1.)*ddsigcdTT -_n*(-_n-1)*pow(sigc,-_n-2.)*dsigcdT*dsigcdT; - DDcoeffsDTT(1) = -1/sigc*dsigcdT*DcoeffsDT(1) + 3/sigc*( (dterm/(m+1.)/(m+1.) -2*term/(m+1.)/(m+1.)/(m+1.))*DmDT*DmDT + term/(m+1.)/(m+1.)*DDmDTT - + 1/sigc*( (1/sigc*pow(dsigtdT,2) - ddsigcdTT) * (pow(m,_n)-1.)/(m+1.) + dsigtdT * term/(m+1.)/(m+1.) ) ); - DDcoeffsDTT(0) = ((_n*pow(m,_n-1)+1.)/(m+1) - (pow(m,_n)+m)/(m+1.)/(m+1.))*DDmDTT - + ((_n*(_n-1)*pow(m,_n-2))/(m+1) + 2*(pow(m,_n)+m)/(m+1.)/(m+1.)/(m+1.))*DmDT*DmDT; - + DcoeffsDT(1) = Da1Dm*DmDT + 3.*(pow(m,_n)-1.)/(m+1.)/(sigc*sigc)*dsigcdT; + DcoeffsDT(0) = ((_n*pow(m,_n-1.)+1.)/(m+1.) - (pow(m,_n)+m)/(m+1.)/(m+1.))*DmDT; + + DDcoeffsDTT(2) = -_n*pow(sigc,-_n-1.)*ddsigcdTT -_n*(-_n-1.)*pow(sigc,-_n-2.)*dsigcdT*dsigcdT; + DDcoeffsDTT(1) = -1./sigc*dsigcdT*DcoeffsDT(1) + 3./sigc*( (dterm/(m+1.)/(m+1.) -2.*term/(m+1.)/(m+1.)/(m+1.))*DmDT*DmDT + term/(m+1.)/(m+1.)*DDmDTT + + 1./sigc*( (1./sigc*pow(dsigtdT,2.) - ddsigcdTT) * (pow(m,_n)-1.)/(m+1.) + dsigtdT * term/(m+1.)/(m+1.) ) ); + DDcoeffsDTT(0) = ((_n*pow(m,_n-1.)+1.)/(m+1) - (pow(m,_n)+m)/(m+1.)/(m+1.))*DDmDTT + + ((_n*(_n-1.)*pow(m,_n-2.))/(m+1.) + 2.*(pow(m,_n)+m)/(m+1.)/(m+1.)/(m+1.))*DmDT*DmDT; + }; void mlawNonLinearTVP::getFreeEnergyTVM(const IPNonLinearTVP *q0, IPNonLinearTVP *q1, const double& T0, const double& T, @@ -208,30 +249,30 @@ void mlawNonLinearTVP::getFreeEnergyTVM(const IPNonLinearTVP *q0, IPNonLinearTVP const STensor3& Me = q1->_ModMandel; const STensor3& X = q1->_backsig; const STensor3& dXdT = q1->_DbackSigDT; - + STensor3 devMe, devX, dDevXdT, dDevMeDT; double trMe, trX, dTrXdT, dTrMeDT; - STensorOperation::decomposeDevTr(q1->_ModMandel,devMe,trMe); - STensorOperation::decomposeDevTr(q1->_backsig,devX,trX); - STensorOperation::decomposeDevTr(q1->_DbackSigDT,dDevXdT,dTrXdT); + STensorOperation::decomposeDevTr(q1->_ModMandel,devMe,trMe); + STensorOperation::decomposeDevTr(q1->_backsig,devX,trX); + STensorOperation::decomposeDevTr(q1->_DbackSigDT,dDevXdT,dTrXdT); STensorOperation::decomposeDevTr(q1->_DModMandelDT,dDevMeDT,dTrMeDT); - + // Start double psiVE, psiVP, psiT = 0.; double DpsiVEdT, DpsiVPdT, DpsiTdT = 0.; double DDpsiVEdTT, DDpsiVPdTT, DpsiTdTT = 0.; - + double CpT, DCpDT, DDCpDTT; mlawNonLinearTVE::getCp(CpT,T,&DCpDT,&DDCpDTT); - - // psiT + + // psiT psiT = CpT*((T-_Tinitial)-T*log(T/_Tinitial)); DpsiTdT = -CpT*log(T/_Tinitial) - psiT/CpT*DCpDT; DpsiTdTT = -CpT/T - psiT/CpT*DDCpDTT; - + // // psiVP - + // get R, dRdT fullVector<double> a(3), Da(3), DaDT(3), DDaDTT(3); getYieldCoefficients(q1,a); @@ -242,31 +283,31 @@ void mlawNonLinearTVP::getFreeEnergyTVM(const IPNonLinearTVP *q0, IPNonLinearTVP Hc = q1->_ipCompression->getDR(); dsigcdT = q1->_ipCompression->getDRDT(); ddsigcdTT = q1->_ipCompression->getDDRDTT(); - + double R1(0.), R2(0.), R3(0.), dR1dT(0.), dR2dT(0.), dR3dT(0.), ddR1dTT(0.), ddR2dTT(0.), ddR3dTT(0.); - + const std::vector<double>& IsoHardForce = q1->_IsoHardForce; const std::vector<double>& dIsoHardForcedT = q1->_dIsoHardForcedT; const std::vector<double>& ddIsoHardForcedTT = q1->_ddIsoHardForcedTT; - + R1 = IsoHardForce[0]; R2 = IsoHardForce[1]; R3 = IsoHardForce[2]; dR1dT = dIsoHardForcedT[0]; dR2dT = dIsoHardForcedT[1]; dR3dT = dIsoHardForcedT[2]; ddR1dTT = ddIsoHardForcedTT[0]; ddR2dTT = ddIsoHardForcedTT[1]; ddR3dTT = ddIsoHardForcedTT[2]; - + // get Kinematic Hardening stuff double Hb(0.), dHbdT(0.), ddHbddT(0.); if (q1->_ipKinematic != NULL){ Hb = q1->_ipKinematic->getDR(); // kinematic hardening parameter dHbdT = q1->_ipKinematic->getDRDT(); - ddHbddT = q1->_ipKinematic->getDDRDDT(); + ddHbddT = q1->_ipKinematic->getDDRDTT(); } double kk = 1./sqrt(1.+2.*q1->_nup*q1->_nup); static STensor3 alpha; alpha = X; alpha *= 1/(pow(kk,2)*Hb); - - // ddXdTT + + // ddXdTT static STensor3 ddXdTT; // ddGammaDTT and ddQDTT are very difficult to estimate STensorOperation::zero(ddXdTT); double delT = T-T0; @@ -276,12 +317,12 @@ void mlawNonLinearTVP::getFreeEnergyTVM(const IPNonLinearTVP *q0, IPNonLinearTVP ddXdTT(i,j) += 2*dXdT(i,j)/(T-T0) - 2*(X(i,j)-q0->_backsig(i,j))/pow((T-T0),2); } } - + static STensor3 dAlphadT, ddAlphadTT; for (int i=0; i<3; i++) for (int j=0; j<3; j++){ dAlphadT(i,j) = dXdT(i,j)*1/(pow(kk,2)*Hb) - X(i,j)*1/(pow(kk*Hb,2))*dHbdT; - ddAlphadTT(i,j) = ddXdTT(i,j)*1/(pow(kk,2)*Hb) - 2*dXdT(i,j)*1/(pow(kk*Hb,2))*dHbdT + ddAlphadTT(i,j) = ddXdTT(i,j)*1/(pow(kk,2)*Hb) - 2*dXdT(i,j)*1/(pow(kk*Hb,2))*dHbdT - X(i,j)*( -2/(pow(kk*Hb,3))*dHbdT*dHbdT + 1/(pow(kk*Hb,2))*ddHbddT); } @@ -289,28 +330,28 @@ void mlawNonLinearTVP::getFreeEnergyTVM(const IPNonLinearTVP *q0, IPNonLinearTVP STensorOperation::doubleContractionSTensor3(X,alpha,psiVP); psiVP *= 0.5; psiVP += 0.5*( 1/_HR[0]*R1*a(1)*sigc + 1/_HR[1]*pow(R2,2) + 1/_HR[2]*pow(R3,2) ); - + for (int i=0; i<3; i++) for (int j=0; j<3; j++){ DpsiVPdT += 0.5*(dXdT(i,j)*alpha(i,j)+X(i,j)*dAlphadT(i,j)); DDpsiVPdTT += 0.5*(ddXdTT(i,j)*alpha(i,j) + 2*dXdT(i,j)*dAlphadT(i,j) + X(i,j)*ddAlphadTT(i,j)); } DpsiVPdT += 0.5*( 1/_HR[0]*(dR1dT*a(1)*sigc + R1*(DaDT(1)*sigc + a(1)*dsigcdT)) + 2/_HR[1]*R2*dR2dT + 2/_HR[2]*R3*dR3dT ); - + DDpsiVPdTT += 0.5*( 1/_HR[0]*(ddR1dTT*a(1)*sigc + 2*dR1dT*(DaDT(1)*sigc + a(1)*dsigcdT) + R1*(DDaDTT(1)*sigc + 2*DaDT(1)*dsigcdT + a(1)*ddsigcdTT)) + 2/_HR[1]*R2*ddR2dTT + 2/_HR[2]*R3*ddR3dTT + 2/_HR[1]*dR2dT*dR2dT + 2/_HR[2]*dR3dT*dR3dT); // CHANGE!! 2nd derivative of R and X are difficult - + // // psiVE - - double KT, GT, cteT, dKdT, ddKdTT, dGdT, ddGdTT, DcteDT, DDcteDTT; getK(KT,T,&dKdT,&ddKdTT); getG(GT,T,&dGdT,&ddGdTT); getAlpha(cteT,T,&DcteDT,&DDcteDTT); - + + double KT, GT, cteT, dKdT, ddKdTT, dGdT, ddGdTT, DcteDT, DDcteDTT; getK(q1,KT,T,&dKdT,&ddKdTT); getG(q1,GT,T,&dGdT,&ddGdTT); getAlpha(cteT,T,&DcteDT,&DDcteDTT); + const STensor3& E = q1->getConstRefToElasticStrain(); static STensor3 devKeinf, DdevKeinfDT, DDdevKeinfDTT, devEe; static double trKeinf, DtrKeinfDT, DDtrKeinfDTT, trEe; STensorOperation::decomposeDevTr(E,devEe,trEe); - mlawNonLinearTVE::corKirInfinity(devEe,trEe,T,devKeinf,trKeinf); - + mlawNonLinearTVE::corKirInfinity(q1,devEe,trEe,T,devKeinf,trKeinf); + DtrKeinfDT = trKeinf*dKdT/KT - 3*KT*(DcteDT*(T-_Tinitial) + cteT); DDtrKeinfDTT = trKeinf*ddKdTT/KT - 6*dKdT*(DcteDT*(T-_Tinitial) + cteT)- 3*KT*(DDcteDTT*(T-_Tinitial) + 2*DcteDT); DdevKeinfDT = devKeinf; @@ -324,31 +365,33 @@ void mlawNonLinearTVP::getFreeEnergyTVM(const IPNonLinearTVP *q0, IPNonLinearTVP const std::vector<double>& trDOiDT = q1->getConstRefToTrDOiDT(); const std::vector<STensor3>& devDDOiDTT = q1->getConstRefToDevDDOiDTT(); const std::vector<double>& trDDOiDTT = q1->getConstRefToTrDDOiDTT(); - - psiVE = mlawNonLinearTVE::freeEnergyMechanical(*q1,T); - + + psiVE = mlawNonLinearTVE::freeEnergyMechanical(*q1,T0,T); + DpsiVEdT = 1/9 * (1/KT * trKeinf * DtrKeinfDT - 1/(2*pow(KT,2)) * dKdT * pow(trKeinf,2)); - DDpsiVEdTT = 1/9 * (1/KT * (pow(DtrKeinfDT,2)+trKeinf*DDtrKeinfDTT) - 1/pow(KT,2)*dKdT*trKeinf*DtrKeinfDT - - 1/(2*pow(KT,2)) *(ddKdTT*pow(trKeinf,2) + 2*dKdT*trKeinf*DtrKeinfDT) - + 1/pow(KT,3)*pow(dKdT,2)*pow(trKeinf,2)); + DDpsiVEdTT = 1/9 * (1/KT * (pow(DtrKeinfDT,2)+trKeinf*DDtrKeinfDTT) - 1/pow(KT,2)*dKdT*trKeinf*DtrKeinfDT + - 1/(2*pow(KT,2)) *(ddKdTT*pow(trKeinf,2) + 2*dKdT*trKeinf*DtrKeinfDT) + + 1/pow(KT,3)*pow(dKdT,2)*pow(trKeinf,2)); for (int i=0; i<3; i++) for (int j=0; j<3; j++){ DpsiVEdT += 2/GT * devKeinf(i,j)*DdevKeinfDT(i,j) - 1/pow(GT,2) * dGdT * devKeinf(i,j)*devKeinf(i,j); - DDpsiVEdTT += 2/GT*(DdevKeinfDT(i,j)*DdevKeinfDT(i,j) + devKeinf(i,j)*DDdevKeinfDTT(i,j) - dGdT*devKeinf(i,j)*DdevKeinfDT(i,j)) + DDpsiVEdTT += 2/GT*(DdevKeinfDT(i,j)*DdevKeinfDT(i,j) + devKeinf(i,j)*DDdevKeinfDTT(i,j) - dGdT*devKeinf(i,j)*DdevKeinfDT(i,j)) - 1/pow(GT,2) * (ddGdTT*devKeinf(i,j)*devKeinf(i,j) + 2*dGdT*devKeinf(i,j)*DdevKeinfDT(i,j)); } if ((_Ki.size() > 0) or (_Gi.size() > 0)){ + std::vector<double> KiT, GiT; KiT.resize(_N,0.); GiT.resize(_N,0.); + getKi(q1,KiT,T); getGi(q1,GiT,T); for (int k=0; k<_Gi.size(); k++){ - DpsiVEdT += 1/9 * 1/_Ki[k] * trOi[k] * trDOiDT[k]; - DDpsiVEdTT += 1/9 * 1/_Ki[k] * (trOi[k]*trDDOiDTT[k] + pow(trDOiDT[k],2)); + DpsiVEdT += 1/9 * 1/KiT[k] * trOi[k] * trDOiDT[k]; + DDpsiVEdTT += 1/9 * 1/KiT[k] * (trOi[k]*trDDOiDTT[k] + pow(trDOiDT[k],2)); for (int i=0; i<3; i++) for (int j=0; j<3; j++){ - DpsiVEdT += 2/_Gi[k] * devOi[k](i,j) * devDOiDT[k](i,j); - DDpsiVEdTT += 2/_Gi[k] * (devOi[k](i,j) * devDDOiDTT[k](i,j) + pow(devDOiDT[k](i,j),2)); - } + DpsiVEdT += 2/GiT[k] * devOi[k](i,j) * devDOiDT[k](i,j); + DDpsiVEdTT += 2/GiT[k] * (devOi[k](i,j) * devDDOiDTT[k](i,j) + pow(devDOiDT[k](i,j),2)); + } } } - + // FINALLY if(psiTVM!=NULL){ *psiTVM = psiT + psiVE + psiVP; @@ -363,285 +406,200 @@ void mlawNonLinearTVP::getFreeEnergyTVM(const IPNonLinearTVP *q0, IPNonLinearTVP }; void mlawNonLinearTVP::getIsotropicHardeningForce(const IPNonLinearTVP *q0, IPNonLinearTVP *q1, const double T0, const double& T, - const STensor3& DphiPDF, std::vector<double>* ddRdTT, std::vector<STensor3>* ddRdFdT) const{ - - const double& Gamma_0 = q0->_Gamma; - const double& Gamma = q1->_Gamma; + double* ddRdTT, STensor3* ddRdFdT) const{ + const double& DgammaDT = q1->_DgammaDT; - const double& dGammaDT_0 = q0->_DGammaDT; - const double& dGammaDT = 0.; // q1->_DGammaDT; = 0. for debugging //DEBUGGING const STensor3& DgammaDF = q1->_DgammaDF; - const STensor3& DGammaDF = q1->_DGammaDF; - const double& gamma0 = q0->_epspbarre; - const double& gamma1 = q1->_epspbarre; - - static STensor3 devMe, devX1, dDevXdT, dDevMeDT; - static double trMe, trX1, dTrXdT, dTrMeDT; - static double trMe_0, trX1_0, dTrXdT_0, dTrMeDT_0; - - STensorOperation::decomposeDevTr(q1->_ModMandel,devMe,trMe); - STensorOperation::decomposeDevTr(q0->_ModMandel,devMe,trMe_0); - STensorOperation::decomposeDevTr(q1->_backsig,devX1,trX1); - STensorOperation::decomposeDevTr(q0->_backsig,devX1,trX1_0); - STensorOperation::decomposeDevTr(q1->_DbackSigDT,dDevXdT,dTrXdT); - STensorOperation::decomposeDevTr(q0->_DbackSigDT,dDevXdT,dTrXdT_0); - STensorOperation::decomposeDevTr(q1->_DModMandelDT,dDevMeDT,dTrMeDT); - STensorOperation::decomposeDevTr(q0->_DModMandelDT,dDevMeDT,dTrMeDT_0); - - trMe /= 3; trX1 /= 3; dTrMeDT /= 3; dTrXdT /= 3; - trMe_0 /= 3; trX1_0 /= 3; dTrMeDT_0 /= 3; dTrXdT_0 /= 3; - dTrMeDT = 0.; dTrXdT = 0.; // for debugging only //DEBUGGING - - // get Dgamma - double Dgamma = gamma1 - gamma0; - - // get R - double eta(0.),Deta(0.),DetaDT(0.),DDetaDTT(0.); - fullVector<double> a(3), Da(3), DaDT(3), DDaDTT(3); - getYieldCoefficients(q1,a); - getYieldCoefficientDerivatives(q1,q1->_nup,Da); - getYieldCoefficientTempDers(q1,T,DaDT,DDaDTT); - - if (_viscosity != NULL) - _viscosity->get(q1->_epspbarre,T,eta,Deta,DetaDT,DDetaDTT); - double etaOverDt = eta/this->getTimeStep(); - double viscoTerm = etaOverDt*Gamma; - - const std::vector<double>& R0 = q0->_IsoHardForce; - std::vector<double>& R = q1->_IsoHardForce; - const std::vector<double>& dRdT_0 = q0->_dIsoHardForcedT; - std::vector<double>& dRdT = q1->_dIsoHardForcedT; - R.resize(3,0.); - dRdT.resize(3,0.); - - double sigc(0.), Hc(0.), dsigcdT(0.), ddsigcdTT(0.); + // Initialize + double& R = q1->_IsoHardForce_simple; + double& dRdT = q1->_dIsoHardForcedT_simple; + STensor3& dRdF = q1->_dIsoHardForcedF_simple; + + // Get Hc, etc. + double sigc0(0.), dsigc0dT(0.), ddsigc0dTT(0.); + double sigc(0.), Hc(0.), dHcdT(0.), dsigcdT(0.), ddsigcdTT(0.); + sigc0 = q1->_ipCompression->getR0(); // Initial yield stress + dsigc0dT = sigc0*_temFunc_Sy0->getDiff(T); + ddsigc0dTT = sigc0*_temFunc_Sy0->getDoubleDiff(T); sigc = q1->_ipCompression->getR(); Hc = q1->_ipCompression->getDR(); + dHcdT = q1->_ipCompression->getDDRDT(); dsigcdT = q1->_ipCompression->getDRDT(); ddsigcdTT = q1->_ipCompression->getDDRDTT(); - - R[0] = - a(1) * (trMe-trX1) * sigc; - dRdT[0] = - DaDT(1)*(trMe-trX1)*sigc - a(1)*( (dTrMeDT-dTrXdT)*sigc + (trMe-trX1) * dsigcdT); - R[1] = - a(0) * sigc; - dRdT[1] = - (DaDT(0) * sigc + a(0) * dsigcdT); - if (Gamma>0 and etaOverDt>0){ - R[2] = - pow(eta*Gamma/this->getTimeStep(),_p) * sigc; - dRdT[2] = - _p*pow(eta*Gamma/this->getTimeStep(),_p-1)*(DetaDT*Gamma + eta*dGammaDT)/this->getTimeStep() * sigc - pow(eta*Gamma/this->getTimeStep(),_p) * dsigcdT; - } - + + // Get R + R = sigc - sigc0; + + // dRdT + dRdT = dsigcdT - dsigc0dT; + // dRdF - // static STensor3 dRdF; - const std::vector<STensor3>& dRdF_0 = q0->_dIsoHardForcedF; - std::vector<STensor3>& dRdF = q1->_dIsoHardForcedF; - dRdF.resize(3,0.); - + STensorOperation::zero(dRdF); for (int i=0; i<3; i++) - for (int j=0; j<3; j++){ - dRdF[0](i,j) = -Da(1)*(trMe-trX1)*DgammaDF(i,j)*sigc - a(1)*(DphiPDF(i,j)*sigc + (trMe-trX1)*Hc*DgammaDF(i,j)); - dRdF[1](i,j) = -Da(0)*DgammaDF(i,j)*sigc - a(0)*Hc*DgammaDF(i,j); - } - - if (Gamma>0 and etaOverDt>0){ - for (int i=0; i<3; i++) - for (int j=0; j<3; j++){ - dRdF[2](i,j) = - _p*pow(eta*Gamma/this->getTimeStep(),_p-1)*(eta*DGammaDF(i,j)/this->getTimeStep())*sigc - pow(eta*Gamma/this->getTimeStep(),_p) * Hc*DgammaDF(i,j); - } - } - + for (int j=0; j<3; j++) + dRdF(i,j) = Hc*DgammaDF(i,j); + + // ddRdTT - double delT = T-T0; if(ddRdTT!=NULL){ - - ddRdTT->at(0) = - DDaDTT(1)*(trMe-trX1)*sigc - a(1)*( 2*(dTrMeDT-dTrXdT)*dsigcdT + (trMe-trX1) * ddsigcdTT ); - ddRdTT->at(1) = -( DDaDTT(0)*sigc + 2*DaDT(0)*dsigcdT + a(0)*ddsigcdTT); - - if (Gamma>0 and etaOverDt>0){ - ddRdTT->at(2) = - _p*(_p-1)*pow(eta*Gamma/this->getTimeStep(),_p-2)*pow(((DetaDT*Gamma + eta*dGammaDT)/this->getTimeStep()),2) * sigc - - _p*pow(eta*Gamma/this->getTimeStep(),_p-1)*((DDetaDTT*Gamma + 2*DetaDT*dGammaDT)/this->getTimeStep() * sigc + - 2*(DetaDT*Gamma + eta*dGammaDT)/this->getTimeStep()* dsigcdT) - - pow(eta*Gamma/this->getTimeStep(),_p) * ddsigcdTT; - } - - if (delT>1e-10){ - double DphiPDT = dTrMeDT- dTrXdT; - double DDphiPDTT = 0.; // (DphiPDT - (trMe-trMe_0+trX1_0-trX1)/delT)/delT; // 2*DphiPDT/delT - 2*(trMe-trMe_0+trX1_0-trX1)/pow(delT,2); // DEBUGGING - ddRdTT->at(0) -= a(1) * DDphiPDTT * sigc; - - if (Gamma>0 and etaOverDt>0){ - double DDGammaDTT = 0.; // 2*dGammaDT/delT - 2*(Gamma-Gamma_0)/pow(delT,2); // DEBUGGING - ddRdTT->at(2) -= _p*pow(eta*Gamma/this->getTimeStep(),_p-1)*(eta*DDGammaDTT)/this->getTimeStep() * sigc; - } - } - q1->_ddIsoHardForcedTT = *ddRdTT; + *ddRdTT = ddsigcdTT - ddsigc0dTT; } - // ddRdTT = 2*dRdT/(T-T0) - 2*(R-R0)/pow((T-T0),2); // ddGammaDTT is very difficult to estimate - + // ddRdTF if(ddRdFdT!=NULL){ - - for (int k=0; k<3; k++){ - STensorOperation::zero(ddRdFdT->at(k)); - if(delT>1e-10){ - ddRdFdT->at(k) = dRdF[k]; - ddRdFdT->at(k) -= dRdF_0[k]; - ddRdFdT->at(k) *= 1/delT; - } - } + STensor3 _ddRdFdT; + STensorOperation::zero(_ddRdFdT); + + for (int i=0; i<3; i++) + for (int j=0; j<3; j++) + _ddRdFdT(i,j) = dHcdT*DgammaDF(i,j); // DDgammaDFDT = 0. + + *ddRdFdT = _ddRdFdT; } }; - -void mlawNonLinearTVP::getMechSourceTVP(const IPNonLinearTVP *q0, IPNonLinearTVP *q1, const double T0, const double& T, - const STensor3& dFpdT, const STensor43& dFpdF, const STensor3& DphiPDF, - double *Wm, STensor3 *dWmdF, double *dWmdT) const{ - - const double& Gamma = q1->_Gamma; + +void mlawNonLinearTVP::getMechSourceTVP(const STensor3& F0, const STensor3& F, + const IPNonLinearTVP *q0, IPNonLinearTVP *q1, const double T0, const double& T, const STensor3& Fepr, const STensor3& Cepr, + const STensor3& DphiPDF, double *Wm, STensor3 *dWmdF, double *dWmdT) const{ + const double& DgammaDT = q1->_DgammaDT; - const double& dGammaDT = q1->_DGammaDT; const STensor3& DgammaDF = q1->_DgammaDF; - const STensor3& DGammaDF = q1->_DGammaDF; const double& gamma0 = q0->_epspbarre; const double& gamma1 = q1->_epspbarre; - const STensor3& Fp0 = q0->_Fp; const STensor3& Fp1 = q1->_Fp; const STensor3& Me = q1->_ModMandel; const STensor3& X1 = q1->_backsig; const STensor3& X0 = q0->_backsig; - const STensor3& dXdT(0.); // = q1->_DbackSigDT; // Just for debugging = 0. //DEBUGGING + const STensor3& dXdT = q1->_DbackSigDT; // For debugging = 0. //DEBUGGING const STensor3& dXdT_0 = q0->_DbackSigDT; const STensor43& dXdF_0 = q0->_DbackSigDF; - const STensor43& dXdF = q1->_DbackSigDF; + const STensor43& dXdF = q1->_DbackSigDF; const STensor3& dMeDT = q1->_DModMandelDT; - const STensor3& dMeDT_0 = q0->_DModMandelDT; const STensor43& dMedF = q1->_DModMandelDF; - const STensor43& dMedF_0 = q0->_DModMandelDF; - - static STensor3 devMe, devX1, dDevXdT, dDevMeDT; - static double trMe, trX1, dTrXdT, dTrMeDT; - - STensorOperation::decomposeDevTr(q1->_ModMandel,devMe,trMe); - STensorOperation::decomposeDevTr(q1->_backsig,devX1,trX1); - STensorOperation::decomposeDevTr(q1->_DbackSigDT,dDevXdT,dTrXdT); - STensorOperation::decomposeDevTr(q1->_DModMandelDT,dDevMeDT,dTrMeDT); - + const STensor43& dGammaNdF = q1->_dGammaNdF; + const STensor3& dGammaNdT = q1->_dGammaNdT; + // get Dgamma double Dgamma = gamma1 - gamma0; - - // get Hb + + // get Hb - Kinematic hardening parameter double Hb(0.), dHb(0), dHbdT(0.), ddHbddT(0.); if (q1->_ipKinematic != NULL){ - Hb = q1->_ipKinematic->getDR(); // kinematic hardening parameter + Hb = q1->_ipKinematic->getDR(); dHb = q1->_ipKinematic->getDDR(); dHbdT = q1->_ipKinematic->getDRDT(); - ddHbddT = q1->_ipKinematic->getDDRDDT(); + ddHbddT = q1->_ipKinematic->getDDRDTT(); } - // get Dp - static STensor3 Fpinv, Fp_dot, Dp; - STensorOperation::inverseSTensor3(Fp1,Fpinv); - Fp_dot = Fp1; - Fp_dot -= Fp0; - Fp_dot *= 1/this->getTimeStep(); - STensorOperation::multSTensor3(Fp_dot,Fpinv,Dp); - - // get alpha + // get Dp - dont use Dp = Fp_dot*Fpinv, USE Dp = Gamma*N/this->getTimeStep() + static STensor3 Dp; + STensorOperation::zero(Dp); + if (this->getTimeStep() > 0){ + Dp = q1->_GammaN; + Dp *= 1/this->getTimeStep(); + } + + // get alpha double kk = 1./sqrt(1.+2.*q1->_nup*q1->_nup); static STensor3 alpha0, alpha1; alpha0 = X0; alpha1 = X1; - alpha0 *= 1/(pow(kk,2)*Hb); alpha1 *= 1/(pow(kk,2)*Hb); // how to get alpha0-current or previous Hb??? WHAT? + if (Hb>0.){ + alpha0 *= 1/(pow(kk,2)* (q0->_ipKinematic->getDR())) ; // using previous Hb for alpha0 + alpha1 *= 1/(pow(kk,2)*Hb); + } alpha1 -= alpha0; - alpha1 *= 1/this->getTimeStep(); - + // get TempX - convenient backStress tensor STensor3 tempX; tempX = X1; - tempX -= T*dXdT; - + tempX -= T*dXdT; + // get R, dRdT, dRdF + double R(0.), dRdT(0.), ddRdTT(0.); + STensor3 dRdF, ddRdFdT; STensorOperation::zero(dRdF); STensorOperation::zero(ddRdFdT); + + // Old Formulation + /* std::vector<double> ddIsoHardForcedTT; ddIsoHardForcedTT.resize(3,0.); std::vector<STensor3> ddIsoHardForcedFdT; ddIsoHardForcedFdT.resize(3,0.); - - getIsotropicHardeningForce(q0,q1,T0,T,DphiPDF,&ddIsoHardForcedTT,&ddIsoHardForcedFdT); + + getIsotropicHardeningForce(q0,q1,T0,T,DphiPDF,&ddIsoHardForcedTT,&ddIsoHardForcedFdT); // For analytical derivatives; for numerical, put the last 2 args as NULL const std::vector<double>& IsoHardForce = q1->_IsoHardForce; const std::vector<double>& dIsoHardForcedT = q1->_dIsoHardForcedT; const std::vector<STensor3>& dIsoHardForcedF = q1->_dIsoHardForcedF; - - double R(0.), dRdT(0.), ddRdTT(0.); - STensor3 dRdF, ddRdFdT; STensorOperation::zero(dRdF); STensorOperation::zero(ddRdFdT); - + for (int i=0; i<3; i++){ - R += IsoHardForce[i]; + R += IsoHardForce[i] dRdT += dIsoHardForcedT[i]; - ddRdTT += ddIsoHardForcedTT[i]; + ddRdTT += ddIsoHardForcedTT[i]; // 0.; dRdF += dIsoHardForcedF[i]; - ddRdFdT += 0.; // ddIsoHardForcedFdT[i]; //DEBUGGING - } - + ddRdFdT += ddIsoHardForcedFdT[i]; // 0.; + }*/ + + // New Formulation + + double ddIsoHardForcedTT(0.); + STensor3 ddIsoHardForcedFdT; + STensorOperation::zero(ddIsoHardForcedFdT); + + getIsotropicHardeningForce(q0,q1,T0,T,&ddIsoHardForcedTT,&ddIsoHardForcedFdT); + R = q1->_IsoHardForce_simple; + dRdT = q1->_dIsoHardForcedT_simple; + dRdF = q1->_dIsoHardForcedF_simple; + + // for convenience R -= T*dRdT; - + // mechSourceTVP if(Wm!=NULL){ double mechSourceTVP = 0.; - if (this->getTimeStep() > 0){ - mechSourceTVP += STensorOperation::doubledot(Me,Dp); - mechSourceTVP -= STensorOperation::doubledot(tempX,alpha1); - mechSourceTVP -= (R*Dgamma)/this->getTimeStep(); + + mechSourceTVP += STensorOperation::doubledot(Me,Dp); + if (!_TaylorQuineyFlag){ + if (this->getTimeStep() > 0){ + alpha1 *= 1/this->getTimeStep(); + mechSourceTVP -= STensorOperation::doubledot(tempX,alpha1); + mechSourceTVP -= (R*Dgamma)/this->getTimeStep(); + } + else{ + mechSourceTVP *= _TaylorQuineyFactor; } + *Wm = mechSourceTVP; - // Second Term TBD - need dXdT, dRdT -> added above + } } - - // Some Generic Conversion Tensors - static STensor43 dDpdFp, dFpinvdFp; - static STensor3 dFpinvdT; - - 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++){ - dFpinvdFp(i,j,k,l) = 0.; - for (int m=0; m<3; m++) - for (int s=0; s<3; s++) - dFpinvdFp(i,j,k,l) -= Fpinv(i,m)*_I4(m,s,k,l)*Fpinv(s,j); - } - + + // dDpdF and dDpdT + // dDpdF = dGammaNdF/this->getTimeStep(); + // dDpdT = dGammaNdT/this->getTimeStep(); + + + // dAlphadF - from dXdF + static STensor43 dAlphadF; + STensorOperation::zero(dAlphadF); + if (Hb>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++){ - dDpdFp(i,j,k,l) = 0.; - for (int m=0; m<3; m++) - dDpdFp(i,j,k,l) += 1/this->getTimeStep()*_I4(i,m,k,l)*Fpinv(m,j) + Fp_dot(i,m)*dFpinvdFp(m,j,k,l); - } - - for (int i=0; i<3; i++) - for (int j=0; j<3; j++){ - dFpinvdT(i,j) = 0.; - for (int m=0; m<3; m++) - for (int s=0; s<3; s++) - dFpinvdT(i,j) -= Fpinv(i,m)*dFpdT(m,s)*Fpinv(s,j); - } - - // dDpdF and dDpdT - static STensor43 dDpdF; - // STensorOperation::zero(dDpdF); - STensorOperation::multSTensor43(dDpdFp, dFpdF, dDpdF); - - static STensor3 dDpdT; + dAlphadF(i,j,k,l) += dXdF(i,j,k,l)*1/(pow(kk,2)*Hb) - X1(i,j)*DgammaDF(k,l)*1/(pow(kk*Hb,2))*dHb; + } + } + + // dAlphadT - from dXdT + static STensor3 dAlphadT; + if (Hb>0.){ for (int i=0; i<3; i++) for (int j=0; j<3; j++){ - dDpdT(i,j) = 0.; - for (int m=0; m<3; m++){ - dDpdT(i,j) += dFpdT(i,m)*Fpinv(m,j)*1/this->getTimeStep() + Fp_dot(i,m)*dFpinvdT(m,j); // dDpdFp(i,j,k,l)*dFpdT(k,l); // maybe use Dp = Fp_dot Fpinv - }} - - // dXdF is available - // const STensor43 dXdF = q1->_DbackSigDF; - + dAlphadT(i,j) = dXdT(i,j)*1/(pow(kk,2)*Hb) - X1(i,j)*DgammaDT*1/(pow(kk*Hb,2))*dHbdT; + } + } + // ddXdTF -> make it -- CHANGE!! - static STensor43 ddXdTF; // ddGammaDTF and ddQDTF are very difficult to estimate + static STensor43 ddXdTdF; // ddGammaDTF and ddQDTF are very difficult to estimate static STensor3 ddXdTT; // ddGammaDTT and ddQDTT are very difficult to estimate - STensorOperation::zero(ddXdTF); + STensorOperation::zero(ddXdTdF); STensorOperation::zero(ddXdTT); double delT = T-T0; if (delT>1e-10){ @@ -650,63 +608,67 @@ void mlawNonLinearTVP::getMechSourceTVP(const IPNonLinearTVP *q0, IPNonLinearTVP // ddXdTT(i,j) += 2*dXdT(i,j)/(T-T0) - 2*(X1(i,j)-X0(i,j))/pow((T-T0),2); //DEBUGGING for (int k=0; k<3; k++) for (int l=0; l<3; l++){ - // ddXdTF(i,j,k,l) += (dXdF(i,j,k,l)-dXdF_0(i,j,k,l))/(T-T0); //DEBUGGING + // ddXdTdF(i,j,k,l) += (dXdF(i,j,k,l)-dXdF_0(i,j,k,l))/(T-T0); //DEBUGGING } } } - - // dAlphadF - from dXdF - static STensor43 dAlphadF; - STensorOperation::zero(dAlphadF); - 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++){ - dAlphadF(i,j,k,l) += dXdF(i,j,k,l)*1/(pow(kk,2)*Hb) + X1(i,j)*DgammaDF(k,l)*1/(pow(kk*Hb,2))*dHb; - } - - // dAlphadT - from dXdT - static STensor3 dAlphadT; - for (int i=0; i<3; i++) - for (int j=0; j<3; j++){ - dAlphadT(i,j) = dXdT(i,j)*1/(pow(kk,2)*Hb) + X1(i,j)*DgammaDT*1/(pow(kk*Hb,2))*dHbdT; - } - - - // dMedF is available - // const STensor43 dMedF = q1->_DModMandelDF; if(dWmdF!=NULL){ STensor3 dmechSourceTVPdF(0.); if (this->getTimeStep() > 0){ - for (int i=0; i<3; i++) - for (int j=0; j<3; j++){ - dmechSourceTVPdF(i,j) = - (dRdF(i,j) - T*ddRdFdT(i,j))*Dgamma/this->getTimeStep() - R*DgammaDF(i,j)/this->getTimeStep(); - for (int k=0; k<3; k++) - for (int l=0; l<3; l++){ - dmechSourceTVPdF(i,j) += dMedF(i,j,k,l)*Dp(i,j) + Me(i,j)*dDpdF(i,j,k,l) - - (dXdF(i,j,k,l) - T*ddXdTF(i,j,k,l))*alpha1(i,j) - tempX(i,j)*dAlphadF(i,j,k,l)/this->getTimeStep(); - } - } - } + + 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++){ + dmechSourceTVPdF(i,j) += dMedF(i,j,k,l)*Dp(i,j) + Me(i,j)*dGammaNdF(i,j,k,l)/this->getTimeStep(); + } + } + + if (!_TaylorQuineyFlag){ + for (int i=0; i<3; i++) + for (int j=0; j<3; j++){ + dmechSourceTVPdF(i,j) = - (dRdF(i,j) - T*ddRdFdT(i,j))*Dgamma/this->getTimeStep() - R*DgammaDF(i,j)/this->getTimeStep(); + for (int k=0; k<3; k++) + for (int l=0; l<3; l++){ + dmechSourceTVPdF(i,j) += - (dXdF(i,j,k,l) - T*ddXdTdF(i,j,k,l))*alpha1(i,j) - tempX(i,j)*dAlphadF(i,j,k,l)/this->getTimeStep(); + } + } + } + else{ + dmechSourceTVPdF *= _TaylorQuineyFactor; + } + + } *dWmdF = dmechSourceTVPdF; } - + if(dWmdT!=NULL){ double dmechSourceTVPdT(0.); if (this->getTimeStep() > 0){ + for (int i=0; i<3; i++) for (int j=0; j<3; j++){ - dmechSourceTVPdT += dMeDT(i,j)*Dp(i,j) + Me(i,j)*dDpdT(i,j) - + T*ddXdTT(i,j)*alpha1(i,j) - tempX(i,j)*dAlphadT(i,j)/this->getTimeStep() - + T*ddRdTT*Dgamma/this->getTimeStep() - R*DgammaDT/this->getTimeStep() ; + dmechSourceTVPdT += dMeDT(i,j)*Dp(i,j) + Me(i,j)*dGammaNdT(i,j)/this->getTimeStep(); } + + if (!_TaylorQuineyFlag){ + + dmechSourceTVPdT += T*ddRdTT*Dgamma/this->getTimeStep() - R*DgammaDT/this->getTimeStep(); + for (int i=0; i<3; i++) + for (int j=0; j<3; j++){ + dmechSourceTVPdT += T*ddXdTT(i,j)*alpha1(i,j) - tempX(i,j)*dAlphadT(i,j)/this->getTimeStep(); + } + } + else{ + dmechSourceTVPdT *= _TaylorQuineyFactor; + } + } *dWmdT = dmechSourceTVPdT; } }; -// NEW void mlawNonLinearTVP::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) @@ -716,27 +678,27 @@ void mlawNonLinearTVP::constitutive( // This function is just a placeholder, def 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, + STensor43* elasticTangent, const bool dTangent, STensor63* dCalgdeps) const{ static SVector3 gradT, temp2; static STensor3 temp3; - static STensor33 temp33; + 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("mlawNonLinearTVP elasticTangent not defined"); + + if(elasticTangent != NULL) Msg::Error("mlawNonLinearTVP 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 mlawNonLinearTVP::constitutive( const STensor3& F0, // initial deformation gradient (input @ time n) const STensor3& F1, // updated deformation gradient (input @ time n+1) @@ -768,7 +730,7 @@ void mlawNonLinearTVP::constitutive( // 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, @@ -777,7 +739,7 @@ void mlawNonLinearTVP::constitutive( mechanicalSource, dmechanicalSourcedT, dmechanicalSourceF, stiff, elasticTangent); } - + else{ this->predictorCorrector_ThermoViscoPlastic(F0, F1, P, q0, q1, T0, T, gradT0, gradT, fluxT, thermalSource, mechanicalSource, elasticTangent); @@ -786,7 +748,7 @@ void mlawNonLinearTVP::constitutive( Tangent, dFpdF, dFpdT, dFedF, dFedT, dPdT, dfluxTdgradT, dfluxTdT, dfluxTdF, dthermalSourcedT, dthermalSourcedF, - dmechanicalSourcedT, dmechanicalSourceF); + dmechanicalSourcedT, dmechanicalSourceF); } }; @@ -856,12 +818,12 @@ void mlawNonLinearTVP::tangent_full_perturbation( 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); @@ -870,16 +832,16 @@ void mlawNonLinearTVP::tangent_full_perturbation( } 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++){ @@ -894,10 +856,10 @@ void mlawNonLinearTVP::tangent_full_perturbation( // 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); @@ -906,14 +868,14 @@ void mlawNonLinearTVP::tangent_full_perturbation( } 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 mlawNonLinearTVP::predictorCorrector_ThermoViscoPlastic( @@ -947,8 +909,8 @@ void mlawNonLinearTVP::predictorCorrector_ThermoViscoPlastic( if (_tangentByPerturbation){ if (_nonAssociatedFlow){ - this->predictorCorrector_TVP_nonAssociatedFlow(F0,F1,q0,q1,P,false,Tangent,dFedF,dFpdF,dFedT,dFpdT, - T0,T,gradT0,gradT,fluxT,dPdT,dfluxTdgradT,dfluxTdT,dfluxTdF, + this->predictorCorrector_TVP_nonAssociatedFlow(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); } @@ -963,8 +925,8 @@ void mlawNonLinearTVP::predictorCorrector_ThermoViscoPlastic( } else{ if (_nonAssociatedFlow){ - this->predictorCorrector_TVP_nonAssociatedFlow(F0,F1,q0,q1,P,stiff,Tangent,dFedF,dFpdF,dFedT,dFpdT, - T0,T,gradT0,gradT,fluxT,dPdT,dfluxTdgradT,dfluxTdT,dfluxTdF, + this->predictorCorrector_TVP_nonAssociatedFlow(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); } @@ -972,51 +934,14 @@ void mlawNonLinearTVP::predictorCorrector_ThermoViscoPlastic( this->predictorCorrector_TVP_AssociatedFlow(F1,q0,q1,P,stiff,Tangent,dFedF,dFpdF,T0,T); } } - - /* - // compute mechanical tengent - if (elasticTangent!= NULL) - { - STensor3 Ptmp(0.); - static IPNonLinearTVP q1tmp(*q1); - q1tmp.operator=(*(dynamic_cast<const IPVariable*> (q1))); - mlawNonLinearTVE::predictorCorrector_ThermoViscoElastic(q0->getConstRefToFe(), q1->getConstRefToFe(), Ptmp, q0, &q1tmp, *elasticTangent, dFedF, dFedT, - T0, T, gradT0, gradT, fluxT, dPdT, dfluxTdgradT, dfluxTdT, dfluxTdF, - thermalSource, dthermalSourcedT, dthermalSourcedF, - mechanicalSource, dmechanicalSourcedT, dmechanicalSourceF, - true); - // mechSource requires taylorQuinney Term - CHANGE - // UPDATE FOR TVP - // thermalSource derivatives -DEFINE LATER - - double CpT; - if (!stiff){ // if stiff, we dont need this technically - getCp(CpT,T); - } - else{ - // thermalSource TVP - CpT = -T*q1->getConstRefToDDFreeEnergyTVMdTT(); - } - - // thermalSource - if (this->getTimeStep() > 0.){ - thermalSource = -CpT*(T-T0)/this->getTimeStep(); - } - else{thermalSource = 0.;} - - // mechSource - TVP - mechanicalSource += q1->getConstRefToMechSrcTVP(); - dmechanicalSourcedT += q1->getConstRefTodMechSrcTVPdT(); - dmechanicalSourceF += q1->getConstRefTodMechSrcTVPdF(); - - }*/ }; + void mlawNonLinearTVP::predictorCorrector_TVP_nonAssociatedFlow(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, + 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 @@ -1030,8 +955,8 @@ void mlawNonLinearTVP::predictorCorrector_TVP_nonAssociatedFlow(const STensor3& double &mechanicalSource, // mechanical source--> convert to heat double &dmechanicalSourcedT, STensor3 &dmechanicalSourceF) const{ - - // compute elastic predictor + + // compute elastic predictor STensor3& Fp1 = q1->_Fp; const STensor3& Fp0 = q0->_Fp; @@ -1049,27 +974,30 @@ void mlawNonLinearTVP::predictorCorrector_TVP_nonAssociatedFlow(const STensor3& this->hardening(q0,q1,T); static fullVector<double> a(3), Da(3); // yield coefficients and derivatives in respect to plastic deformation this->getYieldCoefficients(q1,a); + //a.print("a init"); - double Hb(0.), dHb(0.), dHbdT(0.), ddHbddT(0.); + double Hb(0.), dHb(0.), ddHb(0.), dHbdT(0.), ddHbdgammadT(0.), ddHbddT(0.); if (q1->_ipKinematic != NULL){ Hb = q1->_ipKinematic->getDR(); // kinematic hardening parameter dHb = q1->_ipKinematic->getDDR(); // kinematic hardening parameter derivative (dHb/dgamma) dHbdT = Hb * q1->_ipKinematic->getDRDT(); // make sure to normalise DRDT while defining in python file //NEW - ddHbddT = Hb * q1->_ipKinematic->getDDRDDT(); + ddHbddT = Hb * q1->_ipKinematic->getDDRDTT(); } - - //a.print("a init"); - + + 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 Cepr, Ceinvpr; + + static STensor3 Eepr, Cepr, Ceinvpr; Cepr = Ce; STensorOperation::inverseSTensor3(Cepr,Ceinvpr); - + static STensor3 invFp0; // plastic predictor invFp0= Fpinv; STensor3& Fe = q1->_Fe; @@ -1078,25 +1006,42 @@ void mlawNonLinearTVP::predictorCorrector_TVP_nonAssociatedFlow(const STensor3& // Predictor - TVE static STensor43 DlnDCepr, DlnDCe; static STensor63 DDlnDDCe; - static STensor3 expGN; + static STensor3 expGN, GammaN; static STensor43 dexpAdA; // estimation of dexpA/dA + expGN = _I; // if Gamma = 0, expGN = _I + dexpAdA = _I4; STensor3& Ee = q1->_Ee; - bool ok=STensorOperation::logSTensor3(Ce,_order,Ee,&DlnDCepr,&DDlnDDCe); - if(!ok) - { - P(0,0) = P(1,1) = P(2,2) = sqrt(-1.); - return; - } + STensorOperation::logSTensor3(Ce,_order,Ee,&DlnDCepr,&DDlnDDCe); Ee *= 0.5; + Eepr = Ee; DlnDCe = DlnDCepr; // update A, B double Ke, Ge = 0.; double Kde, Gde = 0.; double KTsum, GTsum = 0.; double DKe, DGe = 0.; double DKde, DGde = 0.; double DKDTsum, DGDTsum = 0.; - 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,Kde,Gde,DKe,DGe,DKde,DGde,KTsum,GTsum,DKDTsum,DGDTsum,T0,T); getTVEdCorKirDT(q0,q1,T0,T); - + + // additional branch - update predictor + double DsigV_dTrEe_pr(0.), DsigV_dTrEe(0.), DsigV_dT(0.); + static STensor3 sigExtra_pr, sigExtra, DsigD_dT; + static STensor43 DsigD_dDevEe_pr, DsigD_dDevEe; + STensorOperation::zero(sigExtra_pr); + STensorOperation::zero(sigExtra); + STensorOperation::zero(DsigD_dT); + STensorOperation::zero(DsigD_dDevEe_pr); + STensorOperation::zero(DsigD_dDevEe); + if (_useExtraBranch){ + mlawNonLinearTVE::extraBranchLaw(Ee,T,q0,q1,sigExtra_pr,stiff,NULL,NULL,&DsigV_dTrEe_pr,&DsigD_dDevEe_pr,&DsigV_dT,&DsigD_dT); + } + q1->_kirchhoff += sigExtra_pr; + const STensor3& dKeprDT = q1->_DcorKirDT; // Get the predicted value - dont add extra branch here + + // Initialise Dho + static STensor43 Dho3, Dho4inv, Dho4_u_inv; // This will be the final important tensor. + double Dho4_v_inv(0.); + // Get Mepr static STensor3 Me, Mepr, Kepr; // Ke is corKir getModifiedMandel(Ce,q0,q1); @@ -1104,18 +1049,19 @@ void mlawNonLinearTVP::predictorCorrector_TVP_nonAssociatedFlow(const STensor3& Mepr = Me; Kepr = q1-> _kirchhoff; - // Get Xn - static STensor3 devXn; - static double trXn, pXn, eXn; + // 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 + pXn = 1./3.*trXn; // 1st invariant of Xn eXn = sqrt(1.5*devXn.dotprod()); // J2 invariant of Xn - + // Initialise Phipr - static STensor3 PhiPr; + static STensor3 PhiPr, Phi; PhiPr = q1->_ModMandel; PhiPr -= q1->_backsig; - + Phi = PhiPr; + static STensor3 devPhipr,devPhi; // effective dev stress predictor static double ptildepr,ptilde; STensorOperation::decomposeDevTr(PhiPr,devPhipr,ptildepr); @@ -1127,129 +1073,161 @@ void mlawNonLinearTVP::predictorCorrector_TVP_nonAssociatedFlow(const STensor3& 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 - // double Gamma = 0.; - double& Gamma = q1->_Gamma; // flow rule parameter + // double Gamma = 0.; + double& Gamma = q1->_Gamma; // flow rule parameter + Gamma = 0.; double dDgammaDGamma = 0.; double Dgamma = 0.; // eqplastic strain static fullVector<double> m(2); getChabocheCoeffs(m,0,q1); double DfDGamma = 0.; - double dfdDgamma = 0.; - double dAdDgamma = 0.; - double dAdGamma = 0.; - double dfdGamma = 0.; + double dfdDgamma(0.), dfdGamma(0.); + double dAdDgamma(0.), dAdGamma(0.); double u = 1.; double v = 1.; - + // Initialise Cx, Gt, Kt - double Px(0.); - getPlasticPotential(pXn, eXn, Px); // CHANGE -> this is wrong, change to backstress instead of phi - double Cx = m(0)*Dgamma + m(1)*Px + 1; - if (Hb>0.){Cx -= 1/Hb * dHbdT * (T-T0);} - double Gt = Ge + pow(kk,1) * Hb/(2*Cx); // pow(kk,2) CHANGE - double Kt = Ke + pow(kk,1) * Hb/(3*Cx); // pow(kk,2) CHANGE - + 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.), dudDgamma(0.), dvdDgamma(0.), dudGamma(0.), dvdGamma(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); + } + double Gt = Ge + pow(kk,1.) * Hb/(2.*Cxdev); // pow(kk,2) DEBUG + double Kt = Ke + pow(kk,1.) * Hb/(3.*Cxtr); // pow(kk,2) DEBUG + // Initialise ptilde and devPhi (phi) ptilde = ptildepr; // current effective pressure -> first invariant devPhi = devPhipr; - + + // Initialise the rest + getDho3(u,v,Gamma,Cepr,Ceinvpr,Kepr,expGN,dexpAdA,Dho3,Dho4inv,Dho4_u_inv,Dho4_v_inv,&DsigV_dTrEe,&DsigD_dDevEe); + double PhiEqpr2 = 1.5*devPhi.dotprod(); double PhiEqpr = sqrt(PhiEqpr2); // -> second invariant - double PhiEq = PhiEqpr; // current effective deviator - + double PhiEq = PhiEqpr; // current effective deviator + // Get f and A - double f = a(2)*pow(PhiEq,_n) - (a(1)*ptilde+a(0)); + double f = a(2)*pow(PhiEq,_n) - (a(1)*ptilde+a(0)); double A = sqrt(6.*PhiEq*PhiEq+4.*_b*_b/3.*ptilde*ptilde); - // NR Loop - 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 - double eta(0.),Deta(0.),DetaDT(0.); - if (_viscosity != NULL) - _viscosity->get(q1->_epspbarre,T,eta,Deta,DetaDT); + // Initialise g + double dgdDgamma=0., dgdGamma = 0.; + double g = Dgamma - kk*Gamma*A; + + // Test + double Dgammma_test = 0.; + + // 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(); - - // dAdGamma and dDgammaDGamma - dAdGamma = -(72.*Gt*PhiEq*PhiEq/u + 16.*Kt*_b*_b*_b*ptilde*ptilde/(3.*v))/(2.*A); - dDgammaDGamma = kk*(A+Gamma*dAdGamma); // mistake in the paper (VD 2016) - this->getYieldCoefficientDerivatives(q1,q1->_nup,Da); - dfdDgamma = Da(2)*pow(PhiEq,_n) - Da(1)*ptilde -Da(0); - - // Get He, Hp - double dCxdDgamma = m(0); // CHANGE to add derivatives of m(0) + dm0Ddgamma*Dgamma + // Get dCxdevdDgamma, dCxtrdDgamma, dudDgamma dvdDgamma, dudGamma, dvdGamma + 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 + + dudDgamma = 6.*Gamma*( pow(kk,1.)/(2.*Cxdev)*dHb - (pow(kk,1.)*Hb)/(2.*pow(Cxdev,2.))*dCxdevdDgamma ); // pow(kk,2.) DEBUG + dvdDgamma = 2.*_b*Gamma*( pow(kk,1.)/(3.*Cxtr)*dHb - (pow(kk,1.)*Hb)/(3.*pow(Cxtr,2.))*dCxtrdDgamma ); // pow(kk,2.) DEBUG + + dudGamma = 6.*(Ge + pow(kk,1.)*Hb/(2.*Cxdev)); // pow(kk,2.) DEBUG + dvdGamma = 2.*_b*(Ke + pow(kk,1.)*Hb/(3.*Cxtr)); // pow(kk,2.) DEBUG + + // Get Hp = dPhiPdDgamma, dPhiPdGamma + double Hp = (1./3.*trXn/(pow(Cxtr,2.))*dCxtrdDgamma - ptilde*dvdDgamma)*Dho4_v_inv; // /v; - // double Stemp = STensorOperation::doubledot(devPhi,devXn); - // double He = (PhiEq*6*Gamma*kk*kk*Hb - Stemp*3.*1./PhiEq)/(2*Cx*Cx*u) * dCxdDgamma; // CHANGE THIS DERIVATIVE -> tensor subtracting scalar //CHECK - // double Hp = ptilde*(2*_b*Gamma*kk*kk*Hb - trXn)/(3*Cx*Cx*v) * dCxdDgamma; // CHECK + double dPhiPdGamma_RHS = - ptilde*dvdGamma; + if (_useExtraBranch){ + dPhiPdGamma_RHS -= 2*_b*ptilde*DsigV_dTrEe; + } + double dPhiPdGamma = dPhiPdGamma_RHS*Dho4_v_inv; // /v; + + // Get He = dPhiEdGamma + // Get DdevPhidGamma + STensor3 DdevPhidDgamma, DdevPhidDgamma_RHS; + STensor3 DdevPhidGamma, DdevPhidGamma_RHS; + for (int i=0; i<3; i++) + for (int j=0; j<3; j++){ + DdevPhidDgamma_RHS(i,j) = devXn(i,j)/(pow(Cxdev,2.))*dCxdevdDgamma - dudDgamma*devPhi(i,j); + DdevPhidGamma_RHS(i,j) = -dudGamma*devPhi(i,j); + for (int k=0; k<3; k++) + for (int l=0; l<3; l++){ + DdevPhidDgamma_RHS(i,j) += (2.*_b/3.)*Gamma*Dho3(i,j,k,l)*_I(k,l)*Hp; //ADD + + DdevPhidGamma_RHS(i,j) += (2.*_b/3.)*Gamma*Dho3(i,j,k,l)*_I(k,l)*dPhiPdGamma; //ADD + + DdevPhidGamma_RHS(i,j) += Dho3(i,j,k,l)*N(k,l); + + if (_useExtraBranch){ + DdevPhidGamma_RHS(i,j) -= DsigD_dDevEe(i,j,k,l)*3*devPhi(k,l); + } + + } + } + for (int i=0; i<3; i++) + for (int j=0; j<3; j++){ + DdevPhidGamma(i,j) = 0.; + DdevPhidGamma(i,j) = 0.; + for (int k=0; k<3; k++) + for (int l=0; l<3; l++){ + DdevPhidDgamma(i,j) += Dho4_u_inv(i,j,k,l)*DdevPhidDgamma_RHS(k,l); + DdevPhidGamma(i,j) += Dho4_u_inv(i,j,k,l)*DdevPhidGamma_RHS(k,l); + } + } - static STensor3 DdevPhidDgamma, term2; - STensorOperation::zero(DdevPhidDgamma); - // 1st term of He - DdevPhidDgamma = 3*Gamma*pow(kk,1)*Hb*devPhipr; // pow(kk,2) CHANGE - DdevPhidDgamma -= devXn*(1 + 6*Gamma*(Ge + pow(kk,1)*Hb/2)); // pow(kk,2) CHANGE - DdevPhidDgamma *= 1/(Cx*Cx*u*u) * dCxdDgamma; + double Stemp1 = STensorOperation::doubledot(devPhi,DdevPhidDgamma); + double Stemp2 = STensorOperation::doubledot(devPhi,DdevPhidGamma); + double He = 1.5*Stemp1/PhiEq; + double dPhiEdGamma = 1.5*Stemp2/PhiEq; - // 2nd term of He - term2 = (3*Gamma*pow(kk,1)*Cx*devPhi); - term2 *= 1/(Cx*Cx*u)*dHb; // pow(kk,2) CHANGE + // 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); - DdevPhidDgamma -= term2; + dDgammaDGamma = kk*(A+Gamma*dAdGamma); // mistake in the paper (VD 2016) - double Stemp = STensorOperation::doubledot(devPhi,DdevPhidDgamma); - double He = 1.5*Stemp/PhiEq; + this->getYieldCoefficientDerivatives(q1,q1->_nup,Da); - double Hp = ( 2*_b*Gamma*pow(kk,1)*Hb*ptildepr - trXn*(1 + 2*_b*Gamma*(Ke + pow(kk,1)*Hb/3)) )*1/(3*Cx*Cx*v*v)*dCxdDgamma; - Hp -= (2*_b*Gamma*pow(kk,1)*Cx*ptilde)*1/(3*Cx*Cx*v) * dHb; + dfdDgamma = Da(2)*pow(PhiEq,_n) - Da(1)*ptilde -Da(0); + dfdDgamma += a(2)*_n*pow(PhiEq,(_n-1.))*He - a(1)*Hp; - 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!! WHAT?? + dfdDgamma -= _p*pow(etaOverDt,_p-1.)*Deta/this->getTimeStep()*pow(Gamma,_p); // THIS term is absent in the paper!! WHY?? - DfDGamma = dfdDgamma*dDgammaDGamma - (_n*a(2)*6.*Gt)*pow(PhiEq,_n)/u + a(1)*ptilde*2.*_b*Kt/v; + 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.); - - // OLD NR - /* - double dGamma = -f/DfDGamma; // NR + dfdGamma -= pow(etaOverDt,_p)*_p*pow(Gamma,(_p-1.)); - if (Gamma + dGamma <=0.){ - Gamma /= 2.; // NR - } - else - Gamma += dGamma;*/ + DfDGamma = dfdDgamma*dDgammaDGamma + dfdGamma; - // NEW NR - dfdGamma = - (_n*a(2)*6.*Gt)*pow(PhiEq,_n)/u + a(1)*ptilde*2.*_b*Kt/v; - if (Gamma>0 and etaOverDt>0) - dfdGamma -= pow(etaOverDt,_p)*_p*pow(Gamma,(_p-1.)); - - dAdDgamma = (12*PhiEq*He + 8/3*_b*_b*ptilde*Hp)/(2*A); - double dgdDgamma = 1 - kk*Gamma*dAdDgamma; - double dgdGamma = - dDgammaDGamma; - double g = Dgamma - kk*Gamma*A; + 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 @@ -1260,18 +1238,19 @@ void mlawNonLinearTVP::predictorCorrector_TVP_nonAssociatedFlow(const STensor3& else Gamma += dGamma; + // Dgammma_test += dDgamma; if (Dgamma + dDgamma <=0.){ Dgamma /= 2.; } else - Dgamma += dDgamma; // Debugging + Dgamma += dDgamma; //Msg::Error("Gamma = %e",Gamma); //Msg::Error("Dgamma = %e",Dgamma); - + // UPDATE FOR NEXT ITERATION - + // Update gamma and all Hardening moduli updateEqPlasticDeformation(q1,q0,q1->_nup,Dgamma); hardening(q0,q1,T); @@ -1280,41 +1259,42 @@ void mlawNonLinearTVP::predictorCorrector_TVP_nonAssociatedFlow(const STensor3& Hb = q1->_ipKinematic->getDR(); // kinematic hardening parameter dHb = q1->_ipKinematic->getDDR(); // kinematic hardening parameter derivative (dHb/dgamma ??) dHbdT = Hb * q1->_ipKinematic->getDRDT(); // make sure to normalise DRDT while defining in python file //NEW - ddHbddT = Hb * q1->_ipKinematic->getDDRDDT(); + ddHbddT = Hb * q1->_ipKinematic->getDDRDTT(); } //a.print("a update"); - // Update Normal and Backstress to get Px - // Can't use this because we Px needs backstress (n+1 step) which comes from normal -> which needs Phi -> which needs Cx -> which needs Px - // Have to put another rate equation in the NR for backstress to get it independently -> dX = kk*Hb*dalpha or something like that - // TBD -> also changes Phi definition and derivatives - // instead Px -> only as a function of backstress (nth step) is used. - // Update Cx, u, v - Cx = m(0)*Dgamma + m(1)*Px + 1; - if (Hb>0.){Cx -= 1/Hb * dHbdT * (T-T0);} - Gt = Ge + pow(kk,1) * Hb/(2*Cx); // pow(kk,2) CHANGE - Kt = Ke + pow(kk,1) * Hb/(3*Cx); // pow(kk,2) CHANGE + 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); + } + Gt = Ge + pow(kk,1.) * Hb/(2.*Cxdev); // pow(kk,2) DEBUG + Kt = Ke + pow(kk,1.) * Hb/(3.*Cxtr); // pow(kk,2) DEBUG u = 1.+6.*Gt*Gamma; v = 1.+2.*_b*Kt*Gamma; // Update Phi - devPhi = devPhipr + devXn*(1-1/Cx); - ptilde = ptildepr + 1/3*trXn*(1-1/Cx); - devPhi *= 1./u; + getIterated_DPhi(T,q0,q1,u,v,Gamma,Cxtr,Cxdev,PhiPr,trXn,devXn,Cepr,Eepr,Kepr,ptilde,devPhi,Phi,N,expGN,dexpAdA, + Dho3,Dho4inv,Dho4_u_inv,Dho4_v_inv, + sigExtra_pr,sigExtra,DsigV_dTrEe,DsigD_dDevEe); PhiEq = sqrt(1.5*devPhi.dotprod()); - ptilde /= v; // Update A A = sqrt(6.*PhiEq*PhiEq+4.*_b*_b/3.*ptilde*ptilde); - // Dgamma = kk*Gamma*A; - //Msg::Error("it = %d, u=%e, v=%e, Dgamma=%e",ite,u,v,Dgamma); + Dgamma = kk*Gamma*A; + updateEqPlasticDeformation(q1,q0,q1->_nup,Dgamma); + hardening(q0,q1,T); + getYieldCoefficients(q1,a); - // Update f + // 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); + double viscoTerm = etaOverDt*Gamma; + if (Gamma>0. and etaOverDt>0.) f-= pow(viscoTerm,_p); + + g = Dgamma - kk*Gamma*A; ite++; //if (ite> maxite-5) @@ -1327,84 +1307,90 @@ void mlawNonLinearTVP::predictorCorrector_TVP_nonAssociatedFlow(const STensor3& P(0,0) = P(1,1) = P(2,2) = sqrt(-1.); return; } - }; - - q1->_DgammaDt = Dgamma/this->getTimeStep(); - - // Correct Phi (effective stress tensor) - devPhi = devPhipr + devXn*(1-1/Cx); - ptilde = ptildepr + 1/3*trXn*(1-1/Cx); - devPhi *= 1./u; - PhiEq = sqrt(1.5*devPhi.dotprod()); - ptilde /= v; - - // Correct normal - devN = devPhi; - devN *= 3.; - trN = 2.*_b*ptilde; - N = devN; - N(0,0) += trN/3.; - N(1,1) += trN/3.; - N(2,2) += trN/3.; - - // estimate exp(GammaN) - // static STensor3 expGN; - static STensor3 GammaN; - GammaN = N; - GammaN *= Gamma; - STensorOperation::expSTensor3(GammaN,_order,expGN,&dexpAdA); + } // while - // Correct plastic deformation tensor - STensorOperation::multSTensor3(expGN,Fp0,Fp1); - // Correct IP gamma - updateEqPlasticDeformation(q1,q0,q1->_nup,Dgamma); + q1->_DgammaDt = Dgamma/this->getTimeStep(); - // 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; // Here We have assumed that, Ce commutes with Q (i.e. with M) - - // Correct A, B - ThermoViscoElasticPredictor(Ee,q0->_Ee,q0,q1,Ke,Ge,Kde,Gde,DKe,DGe,DKde,DGde,KTsum,GTsum,DKDTsum,DGDTsum,T0,T); //,false); - getTVEdCorKirDT(q0,q1,T0,T); // update dCorKirdT - // DKDTsum and DGDTsum = sum of bulk/shear moduli derivatives wrt T - - // Correct backstress - static STensor3 DB; // increment - DB = (N); // increment - DB *= (kk*Hb*Gamma); // pow(kk,2) CHANGE - DB += q0->_backsig; - DB *= 1/Cx; - DB -= q0->_backsig; - q1->_backsig += DB; - - // Correct Mandel - q1->_ModMandel = devPhi; - q1->_ModMandel += q1->_backsig; - - q1->_ModMandel(0,0) += (ptilde); - q1->_ModMandel(1,1) += (ptilde); - q1->_ModMandel(2,2) += (ptilde); - + // Correct Cx, u, v + 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); + } + Gt = Ge + pow(kk,1.) * Hb/(2.*Cxdev); // pow(kk,2.) DEBUG + Kt = Ke + pow(kk,1.) * Hb/(3.*Cxtr); // pow(kk,2.) DEBUG + u = 1.+6.*Gt*Gamma; + v = 1.+2.*_b*Kt*Gamma; + + // Correct Phi + getIterated_DPhi(T,q0,q1,u,v,Gamma,Cxtr,Cxdev,PhiPr,trXn,devXn,Cepr,Eepr,Kepr,ptilde,devPhi,Phi,N,expGN,dexpAdA, + Dho3,Dho4inv,Dho4_u_inv,Dho4_v_inv, + sigExtra_pr,sigExtra,DsigV_dTrEe,DsigD_dDevEe); + 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; + + // Correct A, B + ThermoViscoElasticPredictor(Ee,q0->_Ee,q0,q1,Ke,Ge,Kde,Gde,DKe,DGe,DKde,DGde,KTsum,GTsum,DKDTsum,DGDTsum,T0,T); //,false); + getTVEdCorKirDT(q0,q1,T0,T); // update dCorKirdT - don't do this probably + // DKDTsum and DGDTsum = sum of bulk/shear moduli derivatives wrt T + + // Correct Extrabranch - update stress + if (_useExtraBranch){ + mlawNonLinearTVE::extraBranchLaw(Ee,T,q0,q1,sigExtra,stiff,NULL,NULL,&DsigV_dTrEe,&DsigD_dDevEe,&DsigV_dT,&DsigD_dT); } + q1->_kirchhoff += sigExtra; + + // 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; + q1->getRefToDissipationActive() = false; } - } + } // 1st if const STensor3& KS = q1->_kirchhoff; - - getModifiedMandel(Ce, q0, q1); // update Mandel - + 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); @@ -1419,8 +1405,24 @@ void mlawNonLinearTVP::predictorCorrector_TVP_nonAssociatedFlow(const STensor3& P(i,j) += Fe(i,k)*S(k,l)*Fpinv(j,l); } - // defo energy + + // Elastic energy and Mullin's effect + q1->_elasticEnergy = mlawNonLinearTVE::freeEnergyMechanical(*q1,T0,T); + + // Mullins Effect + if (_mullinsEffect != NULL && q1->_ipMullinsEffect != NULL){ + mlawNonLinearTVE::calculateMullinsEffectScaler(q0, q1, T); + } + double eta_mullins = 1.; + if (q1->_ipMullinsEffect != NULL){ + eta_mullins = q1->_ipMullinsEffect->getEta(); + P *= eta_mullins; + q1->_elasticEnergy *= eta_mullins; + } + + // 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(); @@ -1429,950 +1431,1443 @@ void mlawNonLinearTVP::predictorCorrector_TVP_nonAssociatedFlow(const STensor3& q1->getRefToPlasticEnergy() += Gamma*dotMSN; // = Dp:Me } - - // fluxT - double KThConT, DKThConDT; mlawNonLinearTVE::getKTHCon(KThConT,T,&DKThConDT); - double J = 1.; - STensor3 Finv(0.); - if (_thermalEstimationPreviousConfig){ // ADD _thermalEstimationPreviousConfig + // fluxT + double KThConT, DKThConDT; + mlawNonLinearTVE::getKTHCon(KThConT,T,&DKThConDT); + double J = 1.; + STensor3 Finv(0.); + if (_thermalEstimationPreviousConfig){ // ADD _thermalEstimationPreviousConfig STensorOperation::inverseSTensor3(F0,Finv); J = STensorOperation::determinantSTensor3(F0); - } - else{ + } + 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(dFpdF); - // STensorOperation::zero(dFpdT); - + } + + 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(dFpdF); + // STensorOperation::zero(dFpdT); + // 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(); + (this->getMacroSolver()->getPathFollowingLocalIncrementType() == pathFollowingManager::DISSIPATION_ENERGY)){ + q1->getRefToIrreversibleEnergy() = q1->plasticEnergy(); } else{ q1->getRefToIrreversibleEnergy() = 0.; } - if (stiff){ - - // dP/dF - - //1. get DtrKeprDCepr and DdevKeprDCepr, also DKeprDCepr - static STensor3 DpDCepr; - static STensor43 DdevKDCepr; - static STensor43 DdevKeprDCepr, DdevMeprDCepr, DKeprDCepr; - static STensor3 DpKeprDCepr, DpMeprDCepr; // K = corKir; pK -> pressure of corKir - STensorOperation::multSTensor3STensor43(_I,DlnDCepr,DpKeprDCepr); - DpKeprDCepr*= (0.5*Ke); - STensorOperation::multSTensor43(_Idev,DlnDCepr,DdevKeprDCepr); - DdevKeprDCepr*= Ge; - - // DKeprDCepr - DKeprDCepr = DdevKeprDCepr; - 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++){ - DKeprDCepr(i,j,k,l) += _I(i,j)*DpKeprDCepr(k,l); - } + if (stiff){ - // initiate here - corrected corKir derivatives wrt Cepr - DpDCepr = DpKeprDCepr; - DdevKDCepr = DdevKeprDCepr; - - //2. get DCeprDCepr and DCeinvprDCepr - static STensor43 DCeprDCepr, DCeinvprDCepr; - DCeprDCepr = _I4; + // dP/dF - 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); - } - - //3. get DtrMeprDCepr and DdevMeprDCepr - static STensor43 DMeprDCepr; - - static STensor3 temp1; - static STensor43 temp2, temp3; - STensorOperation::multSTensor3(Kepr,Ceinvpr,temp1); - - 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++){ - temp2(i,s,k,l) = 0.; - temp3(i,s,k,l) = 0.; - for (int m=0; m<3; m++){ - temp2(i,s,k,l) += _I4(i,m,k,l)*temp1(m,s); - temp3(i,s,k,l) += DKeprDCepr(i,m,k,l)*Ceinvpr(m,s) + Kepr(i,m)*DCeinvprDCepr(m,s,k,l); - } - } - - 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++){ - DMeprDCepr(i,s,k,l) = 0.; - for (int m=0; m<3; m++) - DMeprDCepr(i,s,k,l) += Cepr(i,m)*temp3(m,s,k,l); - } - - DMeprDCepr += temp2; - DMeprDCepr += DKeprDCepr; - DMeprDCepr *= 0.5; - - // Because, TrMepr = TrKepr - DpMeprDCepr = DpKeprDCepr; - - // - STensorOperation::zero(DdevMeprDCepr); - 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++){ - DdevMeprDCepr(i,s,k,l) += DMeprDCepr(i,s,k,l) - _I(i,s)*DpMeprDCepr(k,l); - } - - //4. get DdevphiDCepr and DphiPprDCepr - static STensor3 DphiPprDCepr, DphiPDCepr; - static STensor43 DdevphiprDCepr, DdevphiDCepr; - - STensorOperation::zero(DphiPprDCepr); - STensorOperation::zero(DphiPDCepr); - STensorOperation::zero(DdevphiprDCepr); - STensorOperation::zero(DdevphiDCepr); - - DphiPprDCepr = DpMeprDCepr; - DdevphiprDCepr = DdevMeprDCepr; - - DdevphiDCepr = DdevphiprDCepr; - DdevphiDCepr *= 1./u; - DphiPDCepr = DphiPprDCepr; - DphiPDCepr *= 1./v; - - //5. get DphiEprDCepr from DdevphiDCepr - static STensor3 DphiEDCepr, DphiEDdevPhi; - - STensorOperation::zero(DphiEDdevPhi); - DphiEDdevPhi = devPhi; - DphiEDdevPhi *= 1.5/(PhiEq); - - STensorOperation::multSTensor3STensor43(DphiEDdevPhi,DdevphiDCepr,DphiEDCepr); - - - // 6. to 11. (inside if loop-> Gamma > 0.) - static STensor3 dAdCepr, dfDCepr; - static STensor3 DGDCepr; - static STensor3 DgammaDCepr; - static STensor3 DtrNDCepr; - static STensor43 DdevNDCepr; - static STensor43 dFpDCepr; - static STensor43 dCedCepr, dCeinvdCepr; - static STensor43 dXdCepr; - static STensor3 dTrXdCepr; - - if (Gamma >0){ - // plastic - - //6. get dAdCepr from DdevphiDCepr - 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.*_b*_b*ptilde/(A*3.))*DphiPDCepr(i,j); - dfDCepr(i,j) = -a(1)*DphiPDCepr(i,j); - dAdCepr(i,j) += (6./A)*PhiEq*DphiEDCepr(i,j); - dfDCepr(i,j) += fact*DphiEDCepr(i,j); - } - } - - //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*kk*Gamma*dAdCepr(i,j))/DfDGamma; - DGDCepr(i,j) = (-dfDCepr(i,j)-dfdDgamma*kk*Gamma*dAdCepr(i,j)/(1-kk*Gamma*dAdDgamma)) / (dfdDgamma*kk*(A+Gamma*dAdGamma)/(1.-kk*Gamma*dAdDgamma) + dfdGamma); - } - } + //1. get DtrKeprDCepr and DdevKeprDCepr, also DKeprDCepr + static STensor3 DpDCepr; + static STensor43 DdevKDCepr; + static STensor43 DdevKeprDCepr, DdevMeprDCepr, DKeprDCepr; + static STensor3 DpKeprDCepr, DpMeprDCepr; // K = corKir; pK -> pressure of corKir + STensorOperation::multSTensor3STensor43(_I,DlnDCepr,DpKeprDCepr); + DpKeprDCepr*= (0.5*Ke); + STensorOperation::multSTensor43(_Idev,DlnDCepr,DdevKeprDCepr); + DdevKeprDCepr*= Ge; - for (int i=0; i<3; i++){ - for (int j=0; j<3; j++){ - // DgammaDCepr(i,j) = kk*Gamma*dAdCepr(i,j)+ kk*dDgammaDGamma*DGDCepr(i,j); - DgammaDCepr(i,j) = (kk*Gamma*dAdCepr(i,j)+ (1.*kk*A+kk*Gamma*dAdDgamma)*DGDCepr(i,j))/(1.-kk*Gamma*dAdDgamma); + // DKeprDCepr + DKeprDCepr = DdevKeprDCepr; + 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++){ + DKeprDCepr(i,j,k,l) += _I(i,j)*DpKeprDCepr(k,l); } - } - - //8. update DdevphiDCepr and DphiEDCepr - static STensor3 dCxdCepr, dPxdCepr; - STensorOperation::zero(dPxdCepr); - STensorOperation::zero(dCxdCepr); - dPxdCepr *= m(1); - dCxdCepr = DgammaDCepr; - dCxdCepr *= m(0); - dCxdCepr += dPxdCepr; - - // DphiEDCepr - static STensor3 temp7, temp8, temp9; - STensorOperation::zero(temp7); - STensorOperation::zero(temp8); - STensorOperation::zero(temp9); - - temp7 = dCxdCepr; - temp7 *= (1/3*1/(pow(Cx,2))*trXn/v); - - temp9 = 2/3*_b*Gamma*pow(kk,1)*(-Hb/pow(Cx,2)*dCxdCepr + 1/Cx*dHb*DgammaDCepr); // pow(kk,2) CHANGE - - temp8 = DGDCepr; - temp8 *= (2*_b*(Ke+pow(kk,1)*Hb/(3*Cx))); // pow(kk,2) CHANGE - temp8 += temp9; - temp8 *= (ptildepr + 1/3*trXn*(1-1/Cx)); - temp8 *= 1/pow(v,2); - - DphiPDCepr += temp7; - DphiPDCepr -= temp8; - - // DdevphiDCepr - static STensor43 temp10, temp11; - static STensor3 temp12, temp13, temp14; - // STensorOperation::zero(temp10); - // STensorOperation::zero(temp11); - STensorOperation::zero(temp12); - STensorOperation::zero(temp13); - STensorOperation::zero(temp14); - - temp12 = devXn; - temp12 *= 1/pow(Cx,2); - - STensorOperation::prod(temp12, dCxdCepr, 1., temp10); - temp10 *= 1/u; - - for (int i=0; i<3; i++){ - for (int j=0; j<3; j++){ - temp13(i,j) = devPhipr(i,j) + (1-1/Cx)*devXn(i,j); - temp14(i,j) = 6*DGDCepr(i,j)*( Ge + pow(kk,1)*Hb/(2*Cx) ) + 6*Gamma*pow(kk,1)*(-Hb/(2*pow(Cx,2))*dCxdCepr(i,j) + 1/Cx*dHb*DgammaDCepr(i,j)); // pow(kk,2) CHANGE - } - } - - STensorOperation::prod(temp13, temp14, 1., temp11); - temp11 *= 1/pow(u,2); - - DdevphiDCepr += temp10; - DdevphiDCepr -= temp11; - - //9. get DtrNDCepr DdevNdCepr - DtrNDCepr = DphiPDCepr; - DtrNDCepr *= (2*_b); - - DdevNDCepr = DdevphiDCepr; - DdevNDCepr *= 3; - - // 10. get dFpDCepr and dCeinvdCepr - - // dFpDCepr - static STensor43 temp15; - static STensor3 temp15_tr; - for (int i=0; i<3; i++) - for (int j=0; j<3; j++){ - temp15_tr(i,j) = Gamma/3.*DtrNDCepr(i,j); - for (int k=0; k<3; k++) - for (int l=0; l<3; l++) - temp15(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 EprFp0; - 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++){ - EprFp0(i,j,k,l) = 0.; - for (int s=0; s<3; s++){ - EprFp0(i,j,k,l) += dexpAdA(i,s,k,l)*Fp0(s,j); - } - } - - STensorOperation::multSTensor43(EprFp0,temp15,dFpDCepr); - - - // dCeinvdCepr; Here, A = GN - static STensor43 dexpAdCepr, dexpAinvdCepr; - STensorOperation::multSTensor43(dexpAdA,temp15,dexpAdCepr); - - static STensor3 expGNinv; - STensorOperation::inverseSTensor3(expGN,expGNinv); - - 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++){ - dexpAinvdCepr(i,s,k,l) = 0.; - for (int m=0; m<3; m++) - for (int j=0; j<3; j++) - dexpAinvdCepr(i,s,k,l) -= expGNinv(i,m)*dexpAdCepr(m,j,k,l)*expGNinv(j,s); - } - - 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++){ - dCedCepr(i,s,k,l) = 0.; - for (int m=0; m<3; m++) - for (int j=0; j<3; j++) - dCedCepr(i,s,k,l) += expGNinv(m,i)*_I4(m,j,k,l)*expGNinv(j,s) - expGNinv(m,i)*Cepr(m,j)*dexpAinvdCepr(j,s,k,l) - - dexpAinvdCepr(m,i,k,l)*Cepr(m,j)*expGNinv(j,s); // assuming GN is symmetric - } // This derivative is wrong somehow. Use d()/dF below instead. - - - // 10.1 get dXdCepr - const STensor3 backSig = q1->_backsig; - static double trX; - static STensor3 devX; - STensorOperation::decomposeDevTr(backSig,devX,trX); - - STensorOperation::zero(dXdCepr); - STensorOperation::zero(dTrXdCepr); - for (int i=0; i<3; i++) - for (int j=0; j<3; j++){ - dTrXdCepr(i,j) = pow(kk,1)*Hb*temp15_tr(i,j)/Cx - trX*dCxdCepr(i,j)/Cx; // pow(kk,2) CHANGE - for (int k=0; k<3; k++) - for (int l=0; l<3; l++) - dXdCepr(i,j,k,l) = pow(kk,1)*(Hb*temp15(i,j,k,l) + dHb*Gamma*DgammaDCepr(i,j)*N(k,l))/Cx - q1->_backsig(i,j)*dCxdCepr(k,l)/Cx; - // pow(kk,2) CHANGE - } - - // 11. update DpDCepr, DdevKDCepr - // (DpKeprDCepr DdevKeprDCepr) - // update - for (int i=0; i<3; i++){ - for (int j=0; j<3; j++){ - DpDCepr(i,j) -= Ke*(DGDCepr(i,j)*trN+Gamma*DtrNDCepr(i,j)); - for (int k=0; k<3; k++){ - for (int l=0; l<3; l++){ - DdevKDCepr(i,j,k,l) -= 2.*Ge*(DGDCepr(k,l)*devN(i,j)+Gamma*DdevNDCepr(i,j,k,l)); - } - } - } - } - - } - else{ - // elastic - STensorOperation::zero(DgammaDCepr); - STensorOperation::zero(dFpDCepr); - STensorOperation::zero(DtrNDCepr); - STensorOperation::zero(DdevNDCepr); - STensorOperation::zero(DGDCepr); - STensorOperation::zero(dXdCepr); - STensorOperation::zero(dTrXdCepr); - - // STensorOperation::zero(dCedCepr); - dCedCepr = _I4; // DOUBT _ CHECK - } - + // initiate here - corrected corKir derivatives wrt Cepr + DpDCepr = DpKeprDCepr; + DdevKDCepr = DdevKeprDCepr; + + //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++){ - dCeinvdCepr(i,s,k,l) = 0.; + DCeinvprDCepr(i,s,k,l) = 0.; for (int m=0; m<3; m++) for (int j=0; j<3; j++) - dCeinvdCepr(i,s,k,l) -= Ceinv(i,m)*dCedCepr(m,j,k,l)*Ceinv(j,s); - } - - // 12. get dKcorDcepr - static STensor43 dKcorDcepr; - dKcorDcepr = DdevKDCepr; - 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++){ - dKcorDcepr(i,j,k,l) += _I(i,j)*DpDCepr(k,l); - } - } - } - } - - //13. get CeprToF conversion tensor - static STensor43 CeprToF; - 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); + DCeinvprDCepr(i,s,k,l) -= Ceinvpr(i,m)*_I4(m,j,k,l)*Ceinvpr(j,s); } - } - } - } - - static STensor43 DKcorDF; - STensorOperation::multSTensor43(dKcorDcepr,CeprToF,DKcorDF); - - // 14. get dSdCepr and dSdF; also get dMedCepr and dMedF - // Done below -> need dCedF - - STensor43& dXdF = q1->getRefToDbackStressdF(); - static STensor3 dTrXdF; - STensorOperation::multSTensor43(dXdCepr,CeprToF,dXdF); - // DphiPDCepr - use this for the pressure term in R - // for the pressure term in R + //3. get DtrMeprDCepr and DdevMeprDCepr + static STensor43 DMeprDCepr; + + static STensor3 temp1; + static STensor43 temp2, temp3; + STensorOperation::multSTensor3(Kepr,Ceinvpr,temp1); + for (int i=0; i<3; i++) - for (int j=0; j<3; j++){ - DphiPDF(i,j) = 0.; + for (int s=0; s<3; s++) 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); + temp2(i,s,k,l) = 0.; + temp3(i,s,k,l) = 0.; + for (int m=0; m<3; m++){ + temp2(i,s,k,l) += _I4(i,m,k,l)*temp1(m,s); + temp3(i,s,k,l) += DKeprDCepr(i,m,k,l)*Ceinvpr(m,s) + Kepr(i,m)*DCeinvprDCepr(m,s,k,l); + } } - } - - // 15. get DgammaDF - STensor3& DgammaDF = q1->_DgammaDF; - STensor3& DGammaDF = q1->_DGammaDF; - if (Gamma > 0){ - STensorOperation::multSTensor3STensor43(DgammaDCepr,CeprToF,DgammaDF); - STensorOperation::multSTensor3STensor43(DGDCepr,CeprToF,DGammaDF); - STensorOperation::multSTensor43(dFpDCepr,CeprToF,dFpdF); - } - else{ - STensorOperation::zero(DgammaDF); - STensorOperation::zero(DGammaDF); - // STensorOperation::zero(dFpdF); - } - // 16. Everything else and Tangent - 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.; + DMeprDCepr(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); + DMeprDCepr(i,s,k,l) += Cepr(i,m)*temp3(m,s,k,l); } - 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); - } - + DMeprDCepr += temp2; + DMeprDCepr += DKeprDCepr; + DMeprDCepr *= 0.5; + + // Because, TrMepr = TrKepr + DpMeprDCepr = DpKeprDCepr; + + // + STensorOperation::zero(DdevMeprDCepr); for (int i=0; i<3; i++) - for (int j=0; j<3; j++) + for (int s=0; s<3; s++) 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! + DdevMeprDCepr(i,s,k,l) += DMeprDCepr(i,s,k,l) - _I(i,s)*DpMeprDCepr(k,l); + } + + //3.1 Add predicted tangents for extrabranch (the corrected values are independent so we can put predicted values here) + static STensor3 DsigV_DCepr; + static STensor43 DsigD_DCepr; + if (_useExtraBranch){ + + STensorOperation::multSTensor3STensor43(_I,DlnDCepr,DsigV_DCepr); + DsigV_DCepr *= 0.5*DsigV_dTrEe_pr; + DpDCepr += DsigV_DCepr; + DpMeprDCepr += DsigV_DCepr; // goes to DphiPDCepr + + static STensor43 temp3; + STensorOperation::multSTensor43(DsigD_dDevEe_pr,_Idev,temp3); + STensorOperation::multSTensor43(temp3,DlnDCepr,DsigD_DCepr); + DsigD_DCepr *= 0.5; + DdevKDCepr += DsigD_DCepr; + DdevMeprDCepr += DsigD_DCepr; // goes to DdevphiprDCepr + + // dMedF, dSdF come from dKcorDcepr directly + } + + //4. get DdevphiDCepr and DphiPprDCepr + static STensor3 DphiPprDCepr, DphiPDCepr; + static STensor43 DdevphiprDCepr, DdevphiDCepr; + + DphiPprDCepr = DpMeprDCepr; + DdevphiprDCepr = DdevMeprDCepr; + + DphiPDCepr = DphiPprDCepr; + DphiPDCepr *= 1./v; + DdevphiDCepr = DdevphiprDCepr; + DdevphiDCepr *= 1./u; + + //5. get DphiEprDCepr from DdevphiDCepr + static STensor3 DphiEDCepr, DphiEDdevPhi; + if (PhiEq >0.){ + DphiEDdevPhi = devPhi; + DphiEDdevPhi *= 1.5/(PhiEq); + } + + STensorOperation::multSTensor3STensor43(DphiEDdevPhi,DdevphiDCepr,DphiEDCepr); + + + // 6. to 11. (inside if loop-> Gamma > 0.) + static STensor3 dAdCepr, dfDCepr, dgDCepr; + static STensor3 DGDCepr; + static STensor3 DgammaDCepr; + static STensor3 DtrNDCepr; + static STensor43 DdevNDCepr; + static STensor43 dFpDCepr; + static STensor43 dCedCepr, dCeinvdCepr; + static STensor43 dXdCepr; + static STensor3 dTrXdCepr; + static STensor43 dGammaNdCepr; + + if (Gamma >0.){ + + //6. get dAdCepr from DdevphiDCepr + 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 + static STensor3 DGDCepr_test, DgammaDCepr_test; + for (int i=0; i<3; i++){ + for (int j=0; j<3; j++){ + // DGDCepr(i,j) = (-dfDCepr(i,j)-dfdDgamma*kk*Gamma*dAdCepr(i,j))/DfDGamma; + DGDCepr(i,j) = (-dfDCepr(i,j) + dfdDgamma*dgDCepr(i,j)/dgdDgamma)/(dfdGamma - dfdDgamma*dgdGamma/dgdDgamma); } } - - 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(); - - /* Something wrong with dCedCepr - good luck debugging - * 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++){ - dMedCepr(i,j,k,l) = dKcorDcepr(i,j,k,l); // CHANGED - for (int m=0; m<3; m++) - for (int s=0; s<3; s++) - dMedCepr(i,j,k,l) += dCedCepr(i,m,k,l)*KS(m,s)*Ceinv(s,j) + Ce(i,m)*(dKcorDcepr(m,s,k,l)*Ceinv(s,j) + KS(m,s)*dCeinvdCepr(s,j,k,l)); - // CHECK!! the last terms + + for (int i=0; i<3; i++){ + for (int j=0; j<3; j++){ + // DgammaDCepr(i,j) = kk*Gamma*dAdCepr(i,j)+ dDgammaDGamma*DGDCepr(i,j); + DgammaDCepr(i,j) = (-dgdGamma*DGDCepr(i,j) - dgDCepr(i,j))/dgdDgamma; + } } - dMedCepr *= 0.5; - STensorOperation::multSTensor43(dMedCepr,CeprToF,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++){ - dSdCepr(i,j,k,l) = 0.; - for (int m=0; m<3; m++){ - // dSdCepr(i,j,k,l) += dKcorDcepr(i,m,k,l)*Ceinv(m,j) + KS(i,m)*dCeinvdCepr(m,j,k,l); - // dSdCepr(i,j,k,l) += dCeinvdCepr(i,m,k,l)*KS(m,j) + Ceinv(i,m)*dKcorDcepr(m,j,k,l); - dSdCepr(i,j,k,l) += dCeinvdCepr(i,m,k,l)*MS(m,j) + Ceinv(i,m)*dMedCepr(m,j,k,l); - // KS is corKir - }} - // dSdCepr *= 0.5; - STensorOperation::multSTensor43(dSdCepr,CeprToF,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++){ - dMedF(i,j,k,l) = DKcorDF(i,j,k,l); // CHANGED - for (int m=0; m<3; m++) - for (int s=0; s<3; s++) - dMedF(i,j,k,l) += dCedF(i,m,k,l)*KS(m,s)*Ceinv(s,j) + Ce(i,m)*(DKcorDF(m,s,k,l)*Ceinv(s,j) + KS(m,s)*dCeinvDF(s,j,k,l)); - // CHECK!! the last terms + + //8. update DdevphiDCepr and DphiEDCepr, DphiPDCepr + static STensor3 dCxdevdCepr, dCxtrdCepr; + dCxdevdCepr = DgammaDCepr; + dCxdevdCepr *= dCxdevdDgamma; + dCxtrdCepr = DgammaDCepr; + dCxdevdCepr *= dCxtrdDgamma; + + static STensor3 dudCepr, dvdCepr; + for (int i=0; i<3; i++) + for (int j=0; j<3; j++){ + dudCepr(i,j) = dudDgamma*DgammaDCepr(i,j) + dudGamma*DGDCepr(i,j); + dvdCepr(i,j) = dvdDgamma*DgammaDCepr(i,j) + dvdGamma*DGDCepr(i,j); } - dMedF *= 0.5; - - 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++){ - dSdF(i,j,k,l) = 0.; - for (int m=0; m<3; m++){ - // dSdF(i,j,k,l) += DKcorDF(i,m,k,l)*Ceinv(m,j) + KS(i,m)*dCeinvDF(m,j,k,l); - // dSdF(i,j,k,l) += dCeinvDF(i,m,k,l)*KS(m,j) + Ceinv(i,m)*DKcorDF(m,j,k,l); - dSdF(i,j,k,l) += dCeinvDF(i,m,k,l)*MS(m,j) + Ceinv(i,m)*dMedF(m,j,k,l); - // KS is corKir - }} - // dSdF *= 0.5; - - 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); + //8.0 Do extraBranch stuff + if (_useExtraBranch){ + + // subtract predictor + DphiPprDCepr -= DsigV_DCepr; + DpDCepr -= DsigV_DCepr; + + DdevphiprDCepr -= DsigD_DCepr; + DdevKDCepr -= DsigD_DCepr; + } + + // update DphiPDCepr + STensorOperation::zero(DphiPDCepr); + DphiPDCepr += DphiPprDCepr; + for (int i=0; i<3; i++) + for (int j=0; j<3; j++){ + DphiPDCepr(i,j) += ( -dvdCepr(i,j)*ptilde + 1./3.*trXn/(pow(Cxtr,2.))*dCxtrdCepr(i,j) ); + + if (_useExtraBranch){ + DphiPDCepr(i,j) -= 0.5 * DsigV_dTrEe * 2*_b*DGDCepr(i,j)*ptilde; + for (int k=0; k<3; k++) + for (int l=0; l<3; l++){ + DphiPDCepr(i,j) += 0.5 * DsigV_dTrEe * _I(k,l)*DlnDCepr(k,l,i,j); + } + } + } + if (_useExtraBranch){ + DphiPDCepr *= 1/(v + 0.5*2*_b*Gamma*DsigV_dTrEe); // 0.5 is because of 0.5*DlnDCepr. While, Dho4_v_inv = 1/(v + 2*_b*Gamma*DsigV_dTrEe) + } + else{ + DphiPDCepr *= Dho4_v_inv; // where, Dho4_v_inv = 1/v + } + + + // update DdevphiDCepr, DphiEDCepr + // Use Dho3 for DdevphiDCepr + static STensor43 G2, G3; + getG2Tensor(Cepr,Kepr,expGN,DCeinvprDCepr,DKeprDCepr,G2); + 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++){ + G3(i,j,k,l) = G2(i,j,k,l) + DdevphiprDCepr(i,j,k,l) + devXn(i,j)*dCxdevdCepr(k,l)/(pow(Cxdev,2.)) - devPhi(i,j) * dudCepr(k,l); + for (int p=0; p<3; p++) + for (int q=0; q<3; q++){ + G3(i,j,k,l) += Dho3(i,j,p,q)* ( N(p,q)*DGDCepr(k,l) + 2.*_b*Gamma/3.*_I(p,q)*DphiPDCepr(k,l) ); + + if (_useExtraBranch){ + G3(i,j,k,l) -= 0.5*DsigD_dDevEe(i,j,p,q)*3*devPhi(p,q)*DGDCepr(k,l); + for (int r=0; r<3; r++) + for (int s=0; s<3; s++){ + G3(i,j,k,l) += 0.5*DsigD_dDevEe(i,j,p,q)*_Idev(p,q,r,s)*DlnDCepr(r,s,k,l); + } + } + } + } + + if (_useExtraBranch){ + static STensor43 temp, temp_inv; + 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++){ + temp(i,j,k,l) = u*_I4(i,j,k,l) - 3.*Gamma*Dho3(i,j,k,l) + 0.5*3.*Gamma*DsigD_dDevEe(i,j,k,l); + } + STensorOperation::inverseSTensor43(temp,temp_inv); + STensorOperation::multSTensor43(temp_inv,G3,DdevphiDCepr); + } + else{ + STensorOperation::multSTensor43(Dho4_u_inv,G3,DdevphiDCepr); + } + + STensorOperation::multSTensor3STensor43(DphiEDdevPhi,DdevphiDCepr,DphiEDCepr); + + + //9. get DtrNDCepr DdevNdCepr + DtrNDCepr = DphiPDCepr; + DtrNDCepr *= (2.*_b); + + DdevNDCepr = DdevphiDCepr; + DdevNDCepr *= 3.; + + // 10. get dFpDCepr + + // 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 + static STensor3 DtrXdCepr; + static STensor43 DdevXdCepr; + for (int i=0; i<3; i++) + for (int j=0; j<3; j++){ + DtrXdCepr(i,j) = pow(kk,1.)*dHb*Gamma*trN*DgammaDCepr(i,j) + pow(kk,1.)*Hb*( trN*DGDCepr(i,j) + Gamma*DtrNDCepr(i,j) ) - trX*dCxtrdCepr(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*Gamma*devN(i,j)*DgammaDCepr(k,l) + pow(kk,1.)*Hb*( devN(i,j)*DGDCepr(k,l) + Gamma*DdevNDCepr(i,j,k,l) ) - + devX(i,j)*dCxdevdCepr(k,l) ; // pow(kk,2.) DEBUG + } + } + DdevXdCepr *= 1./Cxdev; + DtrXdCepr *= 1./Cxtr; + + 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 DpDCepr, DdevKDCepr + + //11.0 Correct extraBranch + if (_useExtraBranch){ + + // Dont do it like this + // correct DsigV_DCepr and DsigD_DCepr; Also add to DpDCepr and DdevKDCepr + // STensorOperation::multSTensor3STensor43(_I,DlnDCepr,DsigV_DCepr); + // DsigV_DCepr *= DsigV_dTrEe; + // STensorOperation::multSTensor43(DsigD_dDevEe,DlnDCepr,DsigD_DCepr); + + static STensor43 dDevEe_dCepr; + STensorOperation::zero(DsigV_DCepr); + STensorOperation::zero(DsigD_DCepr); + STensorOperation::zero(dDevEe_dCepr); + + STensorOperation::multSTensor3STensor43(_I,DlnDCepr,DsigV_DCepr); + STensorOperation::multSTensor43(_Idev,DlnDCepr,dDevEe_dCepr); + for (int i=0; i<3; i++) + for (int j=0; j<3; j++){ + DsigV_DCepr(i,j) -= 2*_b*(DGDCepr(i,j)*ptilde + Gamma*DphiPDCepr(i,j)); + for (int k=0; k<3; k++) + for (int l=0; l<3; l++){ + dDevEe_dCepr(i,j,k,l) -= 3*(devPhi(i,j)*DGDCepr(k,l) + Gamma*DdevphiDCepr(i,j,k,l)); + } + } + + DsigV_DCepr *= DsigV_dTrEe*0.5; + STensorOperation::multSTensor43(DsigD_dDevEe,dDevEe_dCepr,DsigD_DCepr); + DsigD_DCepr *= 0.5; + + DpDCepr += DsigV_DCepr; + DdevKDCepr += DsigD_DCepr; + + // dMedF, dSdF come from dKcorDcepr directly + } + + // (DpKeprDCepr DdevKeprDCepr) + for (int i=0; i<3; i++){ + for (int j=0; j<3; j++){ + DpDCepr(i,j) -= Ke*(DGDCepr(i,j)*trN + Gamma*DtrNDCepr(i,j)); + for (int k=0; k<3; k++){ + for (int l=0; l<3; l++){ + DdevKDCepr(i,j,k,l) -= 2.*Ge*(DGDCepr(k,l)*devN(i,j) + Gamma*DdevNDCepr(i,j,k,l)); + } + } + } + } + + } // if Gamma + else{ + // elastic + STensorOperation::zero(DgammaDCepr); + STensorOperation::zero(dFpDCepr); + STensorOperation::zero(DtrNDCepr); + STensorOperation::zero(DdevNDCepr); + STensorOperation::zero(DGDCepr); + STensorOperation::zero(dXdCepr); + STensorOperation::zero(dTrXdCepr); + } + + // 12. get dKcorDcepr + static STensor43 dKcorDcepr; + dKcorDcepr = DdevKDCepr; + 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++){ + dKcorDcepr(i,j,k,l) += _I(i,j)*DpDCepr(k,l); + } + } + } + } + + // 13. get CeprToF conversion tensor + static STensor43 CeprToF; + 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); + } + } + } + } + + static STensor43 DKcorDF; + STensorOperation::multSTensor43(dKcorDcepr,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 + for (int i=0; i<3; i++) + for (int j=0; j<3; j++){ + DphiPDF(i,j) = 0.; + 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; + STensorOperation::zero(DgammaDF); + STensorOperation::zero(DGammaDF); + if (Gamma > 0){ + STensorOperation::multSTensor3STensor43(DgammaDCepr,CeprToF,DgammaDF); + STensorOperation::multSTensor3STensor43(DGDCepr,CeprToF,DGammaDF); + STensorOperation::multSTensor43(dFpDCepr,CeprToF,dFpdF); + } + + // 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); + for (int m=0; m<3; m++) + for (int s=0; s<3; s++) + dMedF(i,j,k,l) += dCedF(i,m,k,l)*KS(m,s)*Ceinv(s,j) + Ce(i,m)*(DKcorDF(m,s,k,l)*Ceinv(s,j) + KS(m,s)*dCeinvDF(s,j,k,l)); + // KS is corKir } - } - } - - + dMedF *= 0.5; + + 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++){ + dSdF(i,j,k,l) = 0.; + for (int m=0; m<3; m++){ + dSdF(i,j,k,l) += dCeinvDF(i,m,k,l)*MS(m,j) + Ceinv(i,m)*dMedF(m,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 dMeprDT, dDevMeprDT, DcorKirDT; static double dpMeprDT; - const STensor3& dKeprDT = q1->getConstRefToDcorKirDT(); + // const STensor3& dKeprDT = q1->_DcorKirDT; // Get the predicted value STensorOperation::zero(dMeprDT); - + static STensor3 temp16, temp17; STensorOperation::multSTensor3(dKeprDT, Ceinvpr, temp16); STensorOperation::multSTensor3(Cepr, temp16, temp17); dMeprDT = 0.5*(dKeprDT + temp17); - + STensorOperation::decomposeDevTr(dMeprDT,dDevMeprDT,dpMeprDT); - // dpMeprDT *= 1/3; WHAT IS THE PROBLEM HERE? WHY DOES IT GIVE ZERO? - dpMeprDT = dMeprDT.trace()/3; - + // dpMeprDT *= 1./3.; WHAT IS THE PROBLEM HERE? WHY DOES IT GIVE ZERO? + dpMeprDT = dMeprDT.trace()/3.; + DcorKirDT = dKeprDT; // update later - + + // 1.1 add extraBranch DsigV_DT, DsigD_DT (these do not need to be corrected) + if (_useExtraBranch){ + + DcorKirDT += DsigD_dT; + for (int i=0; i<3; i++) + for (int j=0; j<3; j++){ + DcorKirDT(i,j) += DsigV_dT*_I(i,j); + } + + dpMeprDT += DsigV_dT; // goes to dPhipprDT + dDevMeprDT += DsigD_dT; // goes to dDevPhiprDT + + // dMedT, dSdT come from DcorKirDT directly + } + // 2. get dPhipprDT and dDevPhiprDT static double dPhipprDT; static STensor3 dDevPhiprDT; - + dPhipprDT = dpMeprDT; dDevPhiprDT = dDevMeprDT; - - // 3. get dCxdT, dGxdT, dKxdT, dXdT - static double dCxdT, dGxdT, dKxdT; - dCxdT = 0.; - if (Hb>0.){dCxdT = 1/(pow(Hb,2))*pow(dHbdT,2)*(T-T0) - 1/Hb*ddHbddT*(T-T0) - 1/Hb*dHbdT;} - dGxdT = DGDTsum + pow(kk,1)/(2*Cx)*dHbdT - (pow(kk,1)*Hb)/(2*pow(Cx,2))*dCxdT; // pow(kk,2) CHANGE - dKxdT = DKDTsum + pow(kk,1)/(3*Cx)*dHbdT - (pow(kk,1)*Hb)/(3*pow(Cx,2))*dCxdT; // pow(kk,2) CHANGE - + + // 3. get dCxdT, dXdT + // need this for DmechsourceDT -> initialise here (X is backStress) - STensor3& dXdT = q1->getRefToDbackStressdT(); + STensor3& dXdT = q1->getRefToDbackStressdT(); STensorOperation::zero(dXdT); - dXdT -= (q1->_backsig)*(dCxdT); - dXdT *= 1/Cx; - + STensor3& dGammaNdT = q1->_dGammaNdT; + STensorOperation::zero(dGammaNdT); + // 4. get dPhiPdT and dDevPhiDT static double dPhiPdT; static STensor3 dDevPhiDT; - STensorOperation::zero(dDevPhiDT); - - static double temp18; - static STensor3 temp19; - - dPhiPdT = dPhipprDT/v + 1/3*trXn/pow(Cx,2)*dCxdT/v; // no correction to this - temp18 = (ptildepr+1/3*trXn*(1-1/Cx))*(2*_b*Gamma*dKxdT)/pow(v,2); // Gamma derivatives will change this - dPhiPdT -= temp18; - - temp19 = (devPhipr+devXn*(1-1/Cx))*(6*Gamma*dGxdT); - temp19 *= 1/pow(u,2); - for (int i=0; i<3; i++){ - for (int j=0; j<3; j++){ - dDevPhiDT(i,j) = (dDevPhiprDT(i,j) + devXn(i,j)/pow(Cx,2)*dCxdT)/u - temp19(i,j); - } - } - + + dPhiPdT = dPhipprDT; + dPhiPdT /= v; + + dDevPhiDT = dDevPhiprDT; + dDevPhiDT *= 1./u; + // 5. get dPhiEdT static double dPhiEdT; STensorOperation::doubleContractionSTensor3(DphiEDdevPhi,dDevPhiDT,dPhiEdT); - + // 6. to 11. (inside if loop-> Gamma > 0.) - static double dAdT, dfdT; + static double dAdT, dfdT, dgdT; static double dGammaDT; static double DgammaDT; static double DtrNdT; static STensor3 DdevNdT; static STensor3 dFpDT; - + double eta(0.),Deta(0.),DetaDT(0.); if (_viscosity != NULL) _viscosity->get(q1->_epspbarre,T,eta,Deta,DetaDT); - double etaOverDt = eta/this->getTimeStep(); + double etaOverDt = eta/this->getTimeStep(); if (Gamma >0){ // plastic - - // 6. get DaDT, dAdT and dfdT + + // 6. get dAdT, dfdT, dgdT fullVector<double> DaDT(3), DDaDTT(3); getYieldCoefficientTempDers(q1,T,DaDT,DDaDTT); - - dAdT = (4.*_b*_b*ptilde/(A*3.))*dPhiPdT + (6./A)*PhiEq*dPhiEdT; - dfdT = DaDT(2)*pow(PhiEq,_n) + a(2)*_n*pow(PhiEq,_n-1)*dPhiEdT - DaDT(1)*ptilde - a(1)*dPhiPdT - DaDT(0); + + 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)); + dfdT -= (DetaDT*Gamma/this->getTimeStep())*_p*pow((eta*Gamma/this->getTimeStep()),(_p-1.)); } - + + dgdT = -kk*Gamma*dAdT; + // 7. get dGammaDT, DgammaDT - // dGammaDT = (-dfdT-dfdDgamma*kk*Gamma*dAdT)/DfDGamma; - dGammaDT = (-dfdT-dfdDgamma*kk*Gamma*dAdT/(1.-kk*Gamma*dAdDgamma))/(dfdDgamma*(1.*kk*A+kk*Gamma*dAdGamma)/(1.-kk*Gamma*dAdDgamma) + dfdGamma); - // DgammaDT = kk*Gamma*dAdT + kk*dDgammaDGamma*dGammaDT; - DgammaDT = (kk*Gamma*dAdT + (1*kk*A+kk*Gamma*dAdDgamma)*dGammaDT)/(1.-kk*Gamma*dAdDgamma); - - // 8.0 update dCxdT, dKxdT, dGxdT - static double dHxdT; - dHxdT = dHbdT + dHb*DgammaDT; - if (Hb>0.){dCxdT = 1/(pow(Hb,2))*pow(dHxdT,2)*(T-T0) - 1/Hb*ddHbddT*(T-T0) - 1/Hb*dHxdT;} // -> assuming this is OK - dGxdT = DGDTsum + pow(kk,1)/(2*Cx)*dHxdT - (pow(kk,1)*Hb)/(2*pow(Cx,2))*dCxdT; // pow(kk,2) CHANGE - dKxdT = DKDTsum + pow(kk,1)/(3*Cx)*dHxdT - (pow(kk,1)*Hb)/(3*pow(Cx,2))*dCxdT; // pow(kk,2) CHANGE - + // double dGammaDT_old = (-dfdT-dfdDgamma*kk*Gamma*dAdT)/DfDGamma; + dGammaDT = (-dfdT + dfdDgamma*dgdT/dgdDgamma)/(dfdGamma - dfdDgamma*dgdGamma/dgdDgamma); + // double DgammaDT_old = kk*Gamma*dAdT + dDgammaDGamma*dGammaDT; + DgammaDT = (-dgdGamma*dGammaDT - dgdT)/dgdDgamma; + + + // 8.0 update dCxdT, dudT, dvdT + static double dCxdevdT, dCxtrdT; + 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 + + static double dudT, dvdT; + dudT = 6.*Gamma*(DGDTsum + pow(kk,1.)/(2.*Cxdev)*(dHbdT) - (pow(kk,1.)*Hb)/(2.*pow(Cxdev,2))*dCxdevdT); // pow(kk,2.) DEBUG + dvdT = 2.*_b*Gamma*(DKDTsum + pow(kk,1.)/(3.*Cxtr)*(dHbdT) - (pow(kk,1.)*Hb)/(3.*pow(Cxtr,2))*dCxtrdT); // pow(kk,2.) DEBUG + + dudT += 6.*dGammaDT*(Ge+pow(kk,1)*Hb/(2.*Cxdev)); // pow(kk,2) DEBUG + dvdT += 2.*_b*dGammaDT*(Ke+pow(kk,1)*Hb/(3.*Cxtr)); // pow(kk,2) DEBUG + // 8. update DdevphiDT and DphiPDT - static double dPxdT, temp18_2; - static STensor3 temp19_2; - - dPxdT = 0.*m(1); - dCxdT += m(0)*DgammaDT; - dCxdT += dPxdT; - - dPhiPdT += temp18; - temp18_2 = (ptildepr+1/3*trXn*(1-1/Cx))*(2*_b*(dGammaDT*(Ke+pow(kk,1)*Hb/(3*Cx)) + Gamma*dKxdT))/pow(v,2); // pow(kk,2) CHANGE - dPhiPdT -= temp18_2; - - dDevPhiDT += temp19; - temp19_2 = (devPhipr+devXn*(1-1/Cx))*(6*(dGammaDT*(Ge+pow(kk,1)*Hb/(2*Cx)) + Gamma*dGxdT)); // pow(kk,2) CHANGE - temp19_2 *= 1/pow(u,2); - dDevPhiDT -= temp19_2; - + dPhiPdT = (dPhipprDT - dvdT*ptilde + 1./3.*trXn/(pow(Cxtr,2.))*dCxtrdT); + if (_useExtraBranch){ + dPhiPdT -= 2*_b*DsigV_dTrEe*dGammaDT*ptilde; + } + dPhiPdT *= Dho4_v_inv; + + static STensor3 G2T, G3T; + getG2TTensor(Cepr,expGN,dKeprDT,G2T); + for (int i=0; i<3; i++) + for (int j=0; j<3; j++){ + G3T(i,j) = G2T(i,j) + dDevPhiprDT(i,j) + devXn(i,j)/pow(Cxdev,2.)*dCxdevdT - dudT*devPhi(i,j); + for (int p=0; p<3; p++) + for (int q=0; q<3; q++){ + G3T(i,j) += Dho3(i,j,p,q)*(dGammaDT*N(p,q) + 2.*_b*Gamma/3.*dPhiPdT*_I(p,q)); + + if (_useExtraBranch){ + G3T(i,j) -= 3*DsigD_dDevEe(i,j,p,q)*dGammaDT*devPhi(p,q); + } + } + } + + STensorOperation::multSTensor3STensor43(G3T,Dho4_u_inv,dDevPhiDT); + // 9. get DtrNdT DdevNdT DtrNdT = dPhiPdT; - DtrNdT *= (2*_b); + DtrNdT *= (2.*_b); DdevNdT = dDevPhiDT; - DdevNdT *= 3; - + DdevNdT *= 3.; + // 10. get dFpdT - static STensor3 temp20; - STensorOperation::zero(temp20); + STensorOperation::zero(dGammaNdT); for (int i=0; i<3; i++) for (int j=0; j<3; j++) - temp20(i,j) += N(i,j)*dGammaDT + Gamma*DdevNdT(i,j) + Gamma/3.*_I(i,j)*DtrNdT; - - static STensor43 EprFp0; + 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++){ - EprFp0(i,j,k,l) = 0.; + CeprFp0(i,j,k,l) = 0.; for (int s=0; s<3; s++){ - EprFp0(i,j,k,l) += dexpAdA(i,s,k,l)*Fp0(s,j); - } - } - - for (int i=0; i<3; i++){ + 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 k=0; k<3; k++) for (int l=0; l<3; l++){ - dFpdT(i,j) += EprFp0(i,j,k,l)*temp20(k,l); + dFpdT(i,j) += CeprFp0(i,j,k,l)*dGammaNdT(k,l); } } - } - } - - // 10.1 dXdT - backstress temperature derivative -> correction - - for (int i=0; i<3; i++){ + + // 10.1 dXdT - backstress temperature derivative -> correction - CHECK!!! + static double DtrXdT; + static STensor3 DdevXdT; + DtrXdT = pow(kk,1.)*Gamma*(dHbdT)*trN + pow(kk,1.)*Hb*(dGammaDT*trN + Gamma*DtrNdT) - dCxtrdT*trX; // pow(kk,2.) DEBUG + for (int i=0; i<3; i++) for (int j=0; j<3; j++){ - dXdT(i,j) += 1/Cx*((pow(kk,1)*(dHbdT*Gamma*N(i,j) + Hb*temp20(i,j)))); // pow(kk,2) CHANGE - } + DdevXdT(i,j) = pow(kk,1.)*Gamma*(dHbdT)*devN(i,j) + pow(kk,1.)*Hb*( dGammaDT*devN(i,j) + Gamma*DdevNdT(i,j) ) - dCxdevdT*devX(i,j) ; // pow(kk,2.) DEBUG } - + DdevXdT *= 1./Cxdev; + DtrXdT *= 1./Cxtr; + + STensorOperation::zero(dXdT); + dXdT = DdevXdT; + dXdT(0,0) = DtrXdT/3.; + dXdT(1,1) = DtrXdT/3.; + dXdT(2,2) = DtrXdT/3.; + // 11. DcorKirDT + + //11.0 Correct extraBranch + if (_useExtraBranch){ + + for (int i=0; i<3; i++) + for (int j=0; j<3; j++){ + DcorKirDT(i,j) -= DsigV_dTrEe*2*_b*(dGammaDT*ptilde + Gamma*dPhiPdT)*_I(i,j); + for (int k=0; k<3; k++) + for (int l=0; l<3; l++){ + DcorKirDT(i,j) -= DsigD_dDevEe(i,j,k,l)*3*(devPhi(k,l)*dGammaDT + Gamma*dDevPhiDT(k,l)); + } + } + + // dMedT, dSdT come from dKcorDcepr directly + } + for (int i=0; i<3; i++){ for (int j=0; j<3; j++){ DcorKirDT(i,j) -= ( DKDTsum*Gamma*trN + Ke*(dGammaDT*trN+Gamma*DtrNdT))*_I(i,j); DcorKirDT(i,j) -= 2.*( DGDTsum*Gamma*devN(i,j) + Ge*(dGammaDT*devN(i,j)+Gamma*DdevNdT(i,j))); } } - + q1->_DcorKirDT = DcorKirDT; // update in IP + + } // if Gamma + else{ + // elastic + STensorOperation::zero(DgammaDT); + STensorOperation::zero(dFpDT); + STensorOperation::zero(DtrNdT); + STensorOperation::zero(DdevNdT); + STensorOperation::zero(dGammaDT); + } + + // 12. get dKcorDT + // done above + + // 13. 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); + } + + // 13.1 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); + for (int k=0; k<3; k++) + for (int l=0; l<3; l++){ + dMeDT(i,j) += dCedT(i,k)*KS(k,l)*Ceinv(l,j) + Ce(i,k)*(DcorKirDT(k,l)*Ceinv(l,j) + KS(k,l)*dCeinvdT(l,j)); + } + } + dMeDT *= 0.5; + + // 14. get dSdT + static STensor3 dSdT; + for (int i=0; i<3; i++) + for (int j=0; j<3; j++){ + dSdT(i,j) = 0.; + for (int m=0; m<3; m++){ + dSdT(i,j) += Ceinv(i,m)*dMeDT(m,j) + dCeinvdT(i,m)*MS(m,j); + } + } + + // 15. 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)); + } + } + + double a100 = 0.; // DEBUG ONLY + + } // stiff + + if(stiff){ + + // 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); + } + } + } + } + } + } + + // thermSrc and MechSrc + + // thermalEnergy + double CpT; + 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.; + + // mechSource + double& Wm_TVP = q1->getRefToMechSrcTVP(); // TVP + double& Wm_TVE = q1->getRefToMechSrcTVE(); // TVE + + mechanicalSource = 0.; + mlawNonLinearTVE::getMechSourceTVE(q0,q1,T0,T,DKDTsum,DGDTsum,_I4,&Wm_TVE); // mechSourceTVE + mechanicalSource += Wm_TVE; + + getMechSourceTVP(F0,F,q0,q1,T0,T,Fepr,Cepr,DphiPDF,&Wm_TVP); + mechanicalSource += Wm_TVP; + + // freeEnergy and elastic energy + double& psiTVM = q1->getRefToFreeEnergyTVM(); + // getFreeEnergyTVM(q0,q1,T0,T,&psiTVM,NULL); + + + if (stiff){ + + // const double& DDpsiTVMdTT_0 = q0->getConstRefToDDFreeEnergyTVMdTT(); + // double& DDpsiTVMdTT = q1->getRefToDDFreeEnergyTVMdTT(); + // getFreeEnergyTVM(q0,q1,T0,T,NULL,NULL,&DDpsiTVMdTT); + // double CpT = -T*DDpsiTVMdTT; + // double CpT_0 = -T0*DDpsiTVMdTT_0; + + // thermal source derivatives + double DCpDT(0.); + mlawNonLinearTVE::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 +/* + // Numerical Derivatives + double T_plus(0.), Wm_TVE_plus(0.), Wm_TVP_plus(0.), dWm_TVEdT_plus(0.), dWm_TVPdT_plus(0.), DKDTsum_plus(0.), DGDTsum_plus(0.); + static STensor3 F_plus, Kepr_plus, Mepr_plus, Ke_plus, Me_plus, N_plus, P_plus, DphiPDF_plus, dWm_TVEdF_plus, dWm_TVPdF_plus; + static STensor43 ddXdTdF_plus; + + static IPNonLinearTVP q_Plus(*q0); + + // Thermal Derivatives + T_plus = T + _perturbationfactor*T0; + + plasticCorrector_TVP(F0,F,q0,&q_Plus,T0,T_plus,Kepr_plus,Mepr_plus,DKDTsum_plus,DGDTsum_plus,Ke_plus,Me_plus,N_plus,P_plus,true,&DphiPDF_plus); + mlawNonLinearTVE::getMechSourceTVE(q0,&q_Plus,T0,T_plus,DKDTsum_plus,DGDTsum_plus,_I4,&Wm_TVE_plus); + mlawNonLinearTVP::getMechSourceTVP(F0,F,q0,q1,T0,T_plus,Fepr,Cepr,DphiPDF_plus,&Wm_TVP_plus); + + dWm_TVEdT_plus = (Wm_TVE_plus-Wm_TVE)/(_perturbationfactor*T0); + dWm_TVPdT_plus = (Wm_TVP_plus-Wm_TVP)/(_perturbationfactor*T0); + + // Deformation Derivatives + for (int i=0; i<3; i++){ + for (int j=0; j<3; j++){ + F_plus = (F); + F_plus(i,j) += _perturbationfactor; + + plasticCorrector_TVP(F0,F_plus,q0,&q_Plus,T0,T,Kepr_plus,Mepr_plus,DKDTsum_plus,DGDTsum_plus,Ke_plus,Me_plus,N_plus,P_plus,true,&DphiPDF_plus); + mlawNonLinearTVE::getMechSourceTVE(q0,&q_Plus,T0,T,DKDTsum_plus,DGDTsum_plus,_I4,&Wm_TVE_plus); + mlawNonLinearTVP::getMechSourceTVP(F0,F_plus,q0,&q_Plus,T0,T,Fepr,Cepr,DphiPDF_plus,&Wm_TVP_plus); // F_plus here doesnt change anything + + dWm_TVEdF_plus(i,j) = (Wm_TVE_plus - Wm_TVE)/_perturbationfactor; + dWm_TVPdF_plus(i,j) = (Wm_TVP_plus - Wm_TVP)/_perturbationfactor; + } + }*/ + + // conversion tensor for mechSourceTVE Terms + static STensor43 DCeDFe, DEeDFe; + 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++){ + DCeDFe(i,j,k,l) = 0.; + for (int p=0; p<3; p++){ + DCeDFe(i,j,k,l) += 2.*F(p,i)*dFedF(p,j,k,l); + } + } + + STensorOperation::multSTensor43(DlnDCe,DCeDFe,DEeDFe); + DEeDFe *= 0.5; + + double& dWmdT_TVE = q1->getRefTodMechSrcTVEdT(); + STensor3& dWmdF_TVE = q1->getRefTodMechSrcTVEdF(); + mlawNonLinearTVE::getMechSourceTVE(q0,q1,T0,T,DKDTsum,DGDTsum,DEeDFe,NULL,&dWmdF_TVE,&dWmdT_TVE); + + double& dWmdT_TVP = q1->getRefTodMechSrcTVPdT(); + STensor3& dWmdF_TVP = q1->getRefTodMechSrcTVPdF(); + getMechSourceTVP(F0,F,q0,q1,T0,T,Fepr,Cepr,DphiPDF,NULL,&dWmdF_TVP,&dWmdT_TVP); + + dmechanicalSourcedT = 0.; + STensorOperation::zero(dmechanicalSourceF); + dmechanicalSourceF += dWmdF_TVE; + dmechanicalSourcedT += dWmdT_TVE; + dmechanicalSourceF += dWmdF_TVP; // dWmdF_TVP; + dmechanicalSourcedT += dWmdT_TVP; // dWmdF_TVP; + + /* + dmechanicalSourceF += dWm_TVEdF_plus; // dWmdF_TVP; + dmechanicalSourceF += dWm_TVPdF_plus; // dWmdF_TVP; + dmechanicalSourcedT += dWm_TVEdT_plus; + dmechanicalSourcedT += dWm_TVPdT_plus; */ + + } +} + +void mlawNonLinearTVP::getG2Tensor(const STensor3& Cepr, const STensor3& Kepr, const STensor3& expGN, + const STensor43& DCeinvprDCepr, const STensor43& DKeprDCepr, STensor43& G2) const{ + + static STensor3 Hinv; + STensorOperation::inverseSTensor3(expGN,Hinv); + + static STensor3 Ceinvpr; + STensorOperation::inverseSTensor3(Cepr,Ceinvpr); + + static STensor43 term1, term2, term3; + + 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.; + term3(i,j,k,l) = 0.; + for (int p=0; p<3; p++) + for (int q=0; q<3; q++){ + term2(i,j,k,l) -= _I4(i,p,k,l)*Kepr(p,q)*Ceinvpr(q,j); + term3(i,j,k,l) -= (Cepr(i,p)*DKeprDCepr(p,q,k,l)*Ceinvpr(q,j) + Cepr(i,p)*Kepr(p,q)*DCeinvprDCepr(q,j,k,l)); + 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)*Kepr(r,s)*Ceinvpr(s,m)*expGN(m,o)*expGN(o,j) + + Hinv(i,p)*Hinv(p,q)*Cepr(q,r)*DKeprDCepr(r,s,k,l)*Ceinvpr(s,m)*expGN(m,o)*expGN(o,j) ); + term2(i,j,k,l) += Hinv(i,p)*Hinv(p,q)*Cepr(q,r)*Kepr(r,s)*DCeinvprDCepr(s,m,k,l)*expGN(m,o)*expGN(o,j); + } + } + } + STensorOperation::zero(G2); + G2 = term1+term2+term3; + G2 *= 0.5; + +} + +void mlawNonLinearTVP::getG2TTensor(const STensor3& Cepr, const STensor3& expGN, const STensor3& dKeprDT, STensor3& G2T) const{ + + static STensor3 Hinv; + STensorOperation::inverseSTensor3(expGN,Hinv); + + static STensor3 Ceinvpr; + STensorOperation::inverseSTensor3(Cepr,Ceinvpr); + + for (int i=0; i<3; i++) + for (int j=0; j<3; j++){ + G2T(i,j) = 0.; + for (int p=0; p<3; p++) + for (int q=0; q<3; q++){ + G2T(i,j) -= Cepr(i,p)*dKeprDT(p,q)*Ceinvpr(q,j); + 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++){ + G2T(i,j) += Hinv(i,p)*Hinv(p,q)*Cepr(q,r)*dKeprDT(r,s)*Ceinvpr(s,m)*expGN(m,o)*expGN(o,j); + } + } } - else{ - // elastic - STensorOperation::zero(DgammaDT); - // STensorOperation::zero(dFpDT); - STensorOperation::zero(DtrNdT); - STensorOperation::zero(DdevNdT); - STensorOperation::zero(dGammaDT); - } - - // 12. get dKcorDT - // done above - - // 13. 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); + G2T *= 0.5; +} + +void mlawNonLinearTVP::getDho3(const double& u, const double& v, const double& Gamma, const STensor3& Cepr, const STensor3& Ceinvpr, const STensor3& Kepr, + const STensor3& expGN, const STensor43& dexpAdA, STensor43& Dho3, STensor43& Dho4inv, STensor43& Dho4_u_inv , double& Dho4_v_inv, + const double* DsigV_dTrEe, const STensor43* DsigD_dDevEe) const{ + + static STensor3 HT, Hinv, HTinv; // H = expGN is a symmetric tensor + STensorOperation::inverseSTensor3(expGN,Hinv); + STensorOperation::transposeSTensor3(expGN,HT); + STensorOperation::transposeSTensor3(Hinv,HTinv); + + static STensor43 dHinvdH; + 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++){ + dHinvdH(i,s,k,l) = 0.; + for (int m=0; m<3; m++) + for (int j=0; j<3; j++){ + dHinvdH(i,s,k,l) -= Hinv(i,m)*_I4(m,j,k,l)*Hinv(j,s); + } } - - STensorOperation::zero(dCedT); - for (int i=0; i<3; i++) - for (int j=0; j<3; j++){ + + static STensor43 dHHdH, dHinvHinvdH; + for (int i=0; i<3; i++) + for (int j=0; j<3; j++) + for (int m=0; m<3; m++) + for (int n=0; n<3; n++){ + dHHdH(i,j,m,n) = 0.5*( _I(i,m)*expGN(j,n) + _I(i,n)*expGN(j,m) + _I(j,n)*expGN(i,m) + _I(j,m)*expGN(i,n)); + dHinvHinvdH(i,j,m,n) = 0.; for (int p=0; p<3; p++){ - dCedT(i,j) += Fe(p,i)*dFedT(p,j) + dFedT(p,i)*Fe(p,j); // This Works! + dHinvHinvdH(i,j,m,n) += dHinvdH(i,p,m,n)*Hinv(p,j) + Hinv(i,p)*dHinvdH(p,j,m,n); } } - 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); - } - - // 13.1 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); - for (int k=0; k<3; k++) - for (int l=0; l<3; l++){ - dMeDT(i,j) += dCedT(i,k)*KS(k,l)*Ceinv(l,j) + Ce(i,k)*(DcorKirDT(k,l)*Ceinv(l,j) + KS(k,l)*dCeinvdT(l,j)); - } - } - dMeDT *= 0.5; - - // 14. get dSdT - static STensor3 dSdT; - for (int i=0; i<3; i++) - for (int j=0; j<3; j++){ - dSdT(i,j) = 0.; - for (int m=0; m<3; m++){ - // dSdT(i,j) += DcorKirDT(i,m)*Ceinv(m,j) + KS(i,m)*dCeinvdT(m,j) + dCeinvdT(i,m)*KS(m,j) + Ceinv(i,m)*DcorKirDT(m,j); - dSdT(i,j) += Ceinv(i,m)*dMeDT(m,j) + dCeinvdT(i,m)*MS(m,j); + static STensor3 CeprKeprCeinvpr; + for (int i=0; i<3; i++) + for (int j=0; j<3; j++){ + CeprKeprCeinvpr(i,j) = 0.; + for (int k=0; k<3; k++) + for (int l=0; l<3; l++){ + CeprKeprCeinvpr(i,j) += Cepr(i,k)*Kepr(k,l)*Ceinvpr(l,j); + } + } + + static STensor43 dDhoHdH; + 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++){ + dDhoHdH(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++) + dDhoHdH(i,j,k,l) += 0.5*(dHinvHinvdH(i,p,k,l)*CeprKeprCeinvpr(p,q)*expGN(r,s)*expGN(s,j) + + Hinv(i,p)*Hinv(p,q)*CeprKeprCeinvpr(q,r)*dHHdH(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++){ + Dho3(i,j,k,l) = 0.; + for (int p=0; p<3; p++) + for (int q=0; q<3; q++) + Dho3(i,j,k,l) += dDhoHdH(i,j,p,q)*dexpAdA(p,q,k,l); } - } - // dSdT *= 0.5; - - // 15. Finally, get dPdT - // static STensor3 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)); + + static STensor43 Dho4, Dho4_u; + static STensor3 Dho4_v; // The implementation below is incorrect + double Dho4_v_scalar_correct = 0.; + STensorOperation::zero(Dho4_u); + STensorOperation::zero(Dho4_v); + for (int i=0; i<3; i++) + for (int j=0; j<3; j++){ + Dho4_v(i,j) += v*_I(i,j); + for (int k=0; k<3; k++) + for (int l=0; l<3; l++){ + + Dho4(i,j,k,l) = 0.; + Dho4_u(i,j,k,l) += u*_I4(i,j,k,l) - 3.*Gamma*Dho3(i,j,k,l); + Dho4_v(i,j) -= 2.*_b/3.*Gamma*Dho3(i,j,k,l)*_I(k,l); + + if (_useExtraBranch){ + Dho4_u(i,j,k,l) += 3.*Gamma* (*DsigD_dDevEe)(i,j,k,l); } - } - - } - - if(stiff){ - // TVP - flux, thermalEnergy, thermalSource - if (!_thermalEstimationPreviousConfig){ + for (int p=0; p<3; p++) + for (int q=0; q<3; q++){ + Dho4(i,j,k,l) += (u*_I4(i,j,p,q) - 3.*Gamma*Dho3(i,j,p,q))*_Idev(p,q,k,l) + (v*_I4(i,j,p,q) - 2.*_b/3.*Gamma*Dho3(i,j,p,q))*(_I4(p,q,k,l) -_Idev(p,q,k,l)); - 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); - } - } + if (_useExtraBranch){ + Dho4(i,j,k,l) += ( 3.*Gamma* (*DsigD_dDevEe)(i,j,p,q) )*_Idev(p,q,k,l) + (2.*_b*Gamma*(*DsigV_dTrEe)*_I4(i,j,p,q))*(_I4(p,q,k,l) -_Idev(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++){ - 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); - } - } } } } + + + STensorOperation::inverseSTensor43(Dho4,Dho4inv); + STensorOperation::inverseSTensor43(Dho4_u,Dho4_u_inv); + // STensorOperation::inverseSTensor3(Dho4_v,Dho4_v_inv); + + Dho4_v_scalar_correct = v; + if (_useExtraBranch){ + Dho4_v_scalar_correct += 2.*_b*Gamma* (*DsigV_dTrEe); } + if(abs(Dho4_v_scalar_correct)>0.){ + Dho4_v_inv = 1./Dho4_v_scalar_correct; + } + +} + +void mlawNonLinearTVP::getIterated_DPhi(const double& T, const IPNonLinearTVP *q0, IPNonLinearTVP *q1, + const double& u, const double& v, const double& Gamma, const double& Cxtr, const double& Cxdev, const STensor3& Phipr, + const double& trXn, const STensor3& devXn, const STensor3& Cepr, const STensor3& Eepr, const STensor3& Kepr, + double& ptilde, STensor3& devPhi, + STensor3& Phi, STensor3& N, STensor3& expGN, STensor43& dexpAdA, + STensor43& Dho3, STensor43& Dho4inv, STensor43& Dho4_u_inv , double& Dho4_v_inv, + STensor3& sigExtra_pr, STensor3& sigExtra, double& DsigV_dTrEe, STensor43& DsigD_dDevEe) const{ + + static STensor3 Hinv, GammaN; + static STensor3 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); + } + } - // thermSrc and MechSrc + // Initialise D + static STensor3 D; + for (int i=0; i<3; i++) + for (int j=0; j<3; j++){ + D(i,j) = 0.; + for (int k=0; k<3; k++) + for (int l=0; l<3; l++){ + D(i,j) += 0.5*( Ce(i,k)*Kepr(k,l)*Ceinv(l,j) - Cepr(i,k)*Kepr(k,l)*Ceinvpr(l,j) ); + } + } - // thermalEnergy - double CpT; - if (stiff){ - double& DDpsiTVMdTT = q1->getRefToDDFreeEnergyTVMdTT(); - getFreeEnergyTVM(q0,q1,T0,T,NULL,NULL,&DDpsiTVMdTT); - // CpT = -T*DDpsiTVMdTT; - getCp(CpT,T); + // Initialise J + static STensor3 J, J_constant; + STensorOperation::zero(J); + STensorOperation::zero(J_constant); + for (int i=0; i<3; i++){ + for (int j=0; j<3; j++){ + J_constant(i,j) += Phipr(i,j) + 1./3.*trXn*(1.-1./Cxtr)*_I(i,j) + devXn(i,j)*(1.-1./Cxdev); + J(i,j) += devPhi(i,j)*u + ptilde*_I(i,j)*v - D(i,j); } - else{ - getCp(CpT,T); + } + if (_useExtraBranch){ + J_constant -= sigExtra_pr; + } + J -= J_constant; + + // Initialise Extra Branch, save sigExtra_pr + static STensor3 Ee; + DsigV_dTrEe = 0.; + STensorOperation::zero(Ee); + STensorOperation::zero(DsigD_dDevEe); + if (_useExtraBranch){ + for (int i=0; i<3; i++) + for (int j=0; j<3; j++){ + Ee(i,j) = Eepr(i,j) - Gamma*N(i,j); + } + mlawNonLinearTVE::extraBranchLaw(Ee,T,q0,q1,sigExtra,true,NULL,NULL,&DsigV_dTrEe,&DsigD_dDevEe); + J -= sigExtra; } - q1->_thermalEnergy = CpT*T; - - // thermalSource - if (this->getTimeStep() > 0.){ - thermalSource = -CpT*(T-T0)/this->getTimeStep(); + // Initialise J_tol + double J_tol = 0.; + for (int i=0; i<3; i++){ + for (int j=0; j<3; j++){ + J_tol += abs(J(i,j)) ; } - else - thermalSource = 0.; + } - // mechSourceTVP - double& Wm = q1->getRefToMechSrcTVP(); - double& Wm_TVE = q1->getRefToMechSrcTVE(); + // Initialise Dho3, Dho4inv + getDho3(u,v,Gamma,Cepr,Ceinvpr,Kepr,expGN,dexpAdA,Dho3,Dho4inv,Dho4_u_inv,Dho4_v_inv,&DsigV_dTrEe,&DsigD_dDevEe); - mechanicalSource = 0.; - mlawNonLinearTVE::getMechSourceTVE(q0,q1,T0,T,DKDTsum,DGDTsum,_I4,&Wm_TVE); // mechSourceTVE - mechanicalSource += Wm_TVE; // DEBUGGING + // Initialise DPhi + static STensor3 DPhi; - getMechSourceTVP(q0,q1,T0,T,dFpdT,dFpdF,DphiPDF,&Wm); - mechanicalSource += Wm; // DEBUGGING + // Initialise numerical quantities + static STensor3 Phi_plus, J_plus, devPhi_plus; + double pPhi_plus, perturbation_factor; + static STensor43 dJdPhi_plus, dJdPhi_plus_inv; - // freeEnergy and elastic energy - double& psiTVM = q1->getRefToFreeEnergyTVM(); - getFreeEnergyTVM(q0,q1,T0,T,&psiTVM,NULL); + int ite = 0; + int maxite = 1000; - q1->_elasticEnergy = mlawNonLinearTVE::freeEnergyMechanical(*q1,T); // deformationEnergy(*q1,T); + double tol = 1e-9; + while (fabs(J_tol) > tol or ite <1){ + + /* + // numerical Dho4inv (Jacobian dJ/dPhi) + perturbation_factor = _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*perturbation_factor; + Phi_plus(j,i) += 0.5*perturbation_factor; + STensorOperation::decomposeDevTr(Phi_plus,devPhi_plus,pPhi_plus); + pPhi_plus = Phi_plus.trace()/3; + for (int k=0; k<3; k++){ + for (int l=0; l<3; l++){ + J_plus(k,l) = devPhi_plus(k,l)*u + pPhi_plus*_I(k,l)*v - D(k,l) - J_constant(k,l) - sigExtra(k,l); + dJdPhi_plus(k,l,i,j) = (J_plus(k,l) - J(k,l))/(perturbation_factor); + } + } + } + } + STensorOperation::inverseSTensor43(dJdPhi_plus,dJdPhi_plus_inv);*/ -if (stiff){ + // 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) -= Dho4inv(i,j,k,l)*J(k,l); + } + } - const double& DDpsiTVMdTT_0 = q0->getConstRefToDDFreeEnergyTVMdTT(); - double& DDpsiTVMdTT = q1->getRefToDDFreeEnergyTVMdTT(); - getFreeEnergyTVM(q0,q1,T0,T,NULL,NULL,&DDpsiTVMdTT); - // double CpT = -T*DDpsiTVMdTT; - // double CpT_0 = -T0*DDpsiTVMdTT_0; + // update devPhi + for (int i=0; i<3; i++){ + for (int j=0; j<3; j++){ + Phi(i,j) += DPhi(i,j); + } + } - // thermal source derivatives - double DCpDT(0.); - mlawNonLinearTVE::getCp(CpT,T,&DCpDT); - static STensor3 DCpDF; - STensorOperation::zero(DCpDF); // CHANGE for DCpDF + // update devPhi, ptilde + STensorOperation::decomposeDevTr(Phi,devPhi,ptilde); + ptilde = Phi.trace()/3; - if (this->getTimeStep() > 0){ - dthermalSourcedT = -DCpDT*(T-T0)/this->getTimeStep() - CpT/this->getTimeStep(); - // dthermalSourcedT = -CpT/this->getTimeStep() - (CpT-CpT_0)/this->getTimeStep(); // thermalSource = -CpT*(T-T0)/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); - } + // 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); - // mechSourceTVP derivatives + // 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); + } + } - // conversion tensor for mechSourceTVE Terms - static STensor43 DCeDFe, DEeDFe; - 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++){ - DCeDFe(i,j,k,l) = 0.; - for (int p=0; p<3; p++){ - DCeDFe(i,j,k,l) += 2*F(p,i)*dFedF(p,j,k,l); + // update D + for (int i=0; i<3; i++) + for (int j=0; j<3; j++){ + D(i,j) = 0.; + for (int k=0; k<3; k++) + for (int l=0; l<3; l++){ + D(i,j) += 0.5*( Ce(i,k)*Kepr(k,l)*Ceinv(l,j) - Cepr(i,k)*Kepr(k,l)*Ceinvpr(l,j) ); } } - STensorOperation::multSTensor43(DlnDCe,DCeDFe,DEeDFe); - DEeDFe *= 0.5; - double& dWmdT_TVE = q1->getRefTodMechSrcTVEdT(); - STensor3& dWmdF_TVE = q1->getRefTodMechSrcTVEdF(); - mlawNonLinearTVE::getMechSourceTVE(q0,q1,T0,T,DKDTsum,DGDTsum,DEeDFe,NULL,&dWmdF_TVE,&dWmdT_TVE); + // update J + STensorOperation::zero(J); + for (int i=0; i<3; i++){ + for (int j=0; j<3; j++){ + J(i,j) += devPhi(i,j)*u + ptilde*_I(i,j)*v - D(i,j); + } + } + J -= J_constant; + + // update Extra Branch + STensorOperation::zero(Ee); + STensorOperation::zero(sigExtra); + STensorOperation::zero(DsigD_dDevEe); + if (_useExtraBranch){ + for (int i=0; i<3; i++) + for (int j=0; j<3; j++){ + Ee(i,j) = Eepr(i,j) - Gamma*N(i,j); + } + mlawNonLinearTVE::extraBranchLaw(Ee,T,q0,q1,sigExtra,true,NULL,NULL,&DsigV_dTrEe,&DsigD_dDevEe); + J -= sigExtra; + } + + // update Dho3, Dho4inv + getDho3(u,v,Gamma,Cepr,Ceinvpr,Kepr,expGN,dexpAdA,Dho3,Dho4inv,Dho4_u_inv,Dho4_v_inv,&DsigV_dTrEe,&DsigD_dDevEe); + + // 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)); + } + }*/ + + J_tol = J.norm0(); + J_tol/=(_K+_G); + + ite++; - dmechanicalSourcedT = 0.; - STensorOperation::zero(dmechanicalSourceF); - dmechanicalSourceF += dWmdF_TVE; // DEBUGGING - dmechanicalSourcedT += dWmdT_TVE; // DEBUGGING + //if (ite> maxite-5) + // Msg::Info("it = %d, tol %e, J_tol = %e, Gamma = %e",ite,tol,J_tol,Gamma); - double& dWmdT = q1->getRefTodMechSrcTVPdT(); - STensor3& dWmdF = q1->getRefTodMechSrcTVPdF(); + if (fabs(J_tol) <_tol) break; - getMechSourceTVP(q0,q1,T0,T,dFpdT,dFpdF,DphiPDF,NULL,&dWmdF,&dWmdT); + if(ite > maxite){ + Msg::Error("No convergence for iterated Phi mlawNonLinearTVP nonAssociatedFlow Maxwell iter = %d, J_tol = %e!!",ite,J_tol); + Phi(0,0) = Phi(1,1) = Phi(2,2) = sqrt(-1.); + return; + } + } // while - dmechanicalSourceF += dWmdF; // DEBUGGING - dmechanicalSourcedT += dWmdT; // DEBUGGING } -}; - void mlawNonLinearTVP::predictorCorrector_TVP_AssociatedFlow(const STensor3& F, const IPNonLinearTVP *q0, IPNonLinearTVP *q1, STensor3&P, const bool stiff, STensor43& Tangent, STensor43& dFedF, STensor43& dFpdF, const double T0, const double T) const{ - // compute elastic predictor + // compute elastic predictor STensor3& Fp1 = q1->_Fp; const STensor3& Fp0 = q0->_Fp; @@ -2403,7 +2898,7 @@ void mlawNonLinearTVP::predictorCorrector_TVP_AssociatedFlow(const STensor3& F, if(!ok) { P(0,0) = P(1,1) = P(2,2) = sqrt(-1.); - return; + return; } Ee *= 0.5; DlnDCe = DlnDCepr; @@ -2412,7 +2907,7 @@ void mlawNonLinearTVP::predictorCorrector_TVP_AssociatedFlow(const STensor3& F, // 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.; - 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,Kde,Gde,DKe,DGe,DKde,DGde,KTsum,GTsum,DKDTsum,DGDTsum,T0,T); static STensor3 devKpr; // dev corotational kirchoff stress predictor static double ppr; // pressure predictor @@ -2586,12 +3081,12 @@ void mlawNonLinearTVP::predictorCorrector_TVP_AssociatedFlow(const STensor3& F, if(!ok) { P(0,0) = P(1,1) = P(2,2) = sqrt(-1.); - return; + return; } Ee *= 0.5; - // - 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,Kde,Gde,DKe,DGe,DKde,DGde,KTsum,GTsum,DKDTsum,DGDTsum,T0,T,false); } else{ q1->getRefToDissipationActive() = false; @@ -2644,4 +3139,137 @@ void mlawNonLinearTVP::predictorCorrector_TVP_AssociatedFlow(const STensor3& F, if (stiff){ // FILL THIS } -}; +}; + +// Old IsotropicHardeningForce formulation +void mlawNonLinearTVP::getIsotropicHardeningForce(const IPNonLinearTVP *q0, IPNonLinearTVP *q1, const double T0, const double& T, + const STensor3& DphiPDF, std::vector<double>* ddRdTT, std::vector<STensor3>* ddRdFdT) const{ + + const double& Gamma_0 = q0->_Gamma; + const double& Gamma = q1->_Gamma; + const double& DgammaDT = q1->_DgammaDT; + const double& dGammaDT_0 = q0->_DGammaDT; + const double& dGammaDT = q1->_DGammaDT; // = 0. for debugging //DEBUGGING + const STensor3& DgammaDF = q1->_DgammaDF; + const STensor3& DGammaDF = q1->_DGammaDF; + const double& gamma0 = q0->_epspbarre; + const double& gamma1 = q1->_epspbarre; + + static STensor3 devMe, devX1, dDevXdT, dDevMeDT; + static double pMe, pX1, dpXdT, dpMeDT; + static double pMe_0, pX1_0, dpXdT_0, dpMeDT_0; + + STensorOperation::decomposeDevTr(q1->_ModMandel,devMe,pMe); + STensorOperation::decomposeDevTr(q0->_ModMandel,devMe,pMe_0); + STensorOperation::decomposeDevTr(q1->_backsig,devX1,pX1); + STensorOperation::decomposeDevTr(q0->_backsig,devX1,pX1_0); + STensorOperation::decomposeDevTr(q1->_DbackSigDT,dDevXdT,dpXdT); + STensorOperation::decomposeDevTr(q0->_DbackSigDT,dDevXdT,dpXdT_0); + STensorOperation::decomposeDevTr(q1->_DModMandelDT,dDevMeDT,dpMeDT); + STensorOperation::decomposeDevTr(q0->_DModMandelDT,dDevMeDT,dpMeDT_0); + + pMe /= 3.; pX1 /= 3.; dpMeDT /= 3.; dpXdT /= 3.; + pMe_0 /= 3.; pX1_0 /= 3.; dpMeDT_0 /= 3.; dpXdT_0 /= 3.; + + // dpMeDT = 0.; dpXdT = 0.; // for debugging only //DEBUGGING + + // get R + double eta(0.),Deta(0.),DetaDT(0.),DDetaDTT(0.),DDetaDT(0.); + fullVector<double> a(3), Da(3), DaDT(3), DDaDTT(3), DDaDT(3); + getYieldCoefficients(q1,a); + getYieldCoefficientDerivatives(q1,q1->_nup,Da); + getYieldCoefficientTempDers(q1,T,DaDT,DDaDTT); + + if (_viscosity != NULL) + _viscosity->get(q1->_epspbarre,T,eta,Deta,DetaDT,DDetaDTT,DDetaDT); + double etaOverDt = eta/this->getTimeStep(); + double viscoTerm = etaOverDt*Gamma; + + const std::vector<double>& R0 = q0->_IsoHardForce; + std::vector<double>& R = q1->_IsoHardForce; + const std::vector<double>& dRdT_0 = q0->_dIsoHardForcedT; + std::vector<double>& dRdT = q1->_dIsoHardForcedT; + R.resize(3,0.); + dRdT.resize(3,0.); + + double sigc(0.), Hc(0.), dsigcdT(0.), ddsigcdTT(0.); + sigc = q1->_ipCompression->getR(); + Hc = q1->_ipCompression->getDR(); + dsigcdT = q1->_ipCompression->getDRDT(); + ddsigcdTT = q1->_ipCompression->getDDRDTT(); + + R[0] = sigc * a(1) * (pMe-pX1); + dRdT[0] = dsigcdT*a(1)*(pMe-pX1) + sigc*( DaDT(1)*(pMe-pX1) + a(1)*(dpMeDT-dpXdT) ); + R[1] = sigc * a(0); + dRdT[1] = dsigcdT * a(0) + sigc * DaDT(0) ; + if (Gamma>0. and etaOverDt>0.){ + R[2] = sigc * pow(eta*Gamma/this->getTimeStep(),_p) ; + dRdT[2] = dsigcdT * pow(eta*Gamma/this->getTimeStep(),_p) + + sigc * _p*pow(eta*Gamma/this->getTimeStep(),_p-1)*(DetaDT*Gamma + eta*dGammaDT)/this->getTimeStep() ; + } + + // dRdF + const std::vector<STensor3>& dRdF_0 = q0->_dIsoHardForcedF; + std::vector<STensor3>& dRdF = q1->_dIsoHardForcedF; + dRdF.resize(3,0.); + + for (int i=0; i<3; i++) + for (int j=0; j<3; j++){ + dRdF[0](i,j) = Hc*DgammaDF(i,j)*a(1)*(pMe-pX1) + sigc*( Da(1)*DgammaDF(i,j)*(pMe-pX1) + a(1)*DphiPDF(i,j) ); + dRdF[1](i,j) = Hc*DgammaDF(i,j)*a(0) + sigc*Da(0)*DgammaDF(i,j); + } + + if (Gamma>0 and etaOverDt>0){ + for (int i=0; i<3; i++) + for (int j=0; j<3; j++){ + dRdF[2](i,j) = Hc*DgammaDF(i,j) *pow(eta*Gamma/this->getTimeStep(),_p) + + sigc* _p*pow(eta*Gamma/this->getTimeStep(),_p-1)*(Deta*DgammaDF(i,j) *Gamma + eta* DGammaDF(i,j))/this->getTimeStep() ; + } + } + + // ddRdTT + double delT = T-T0; + if(ddRdTT!=NULL){ + + ddRdTT->at(0) = ddsigcdTT *a(1)*(pMe-pX1) + 2.*dsigcdT *( DaDT(1)*(pMe-pX1) + a(1)*(dpMeDT-dpXdT) ) + sigc*( DDaDTT(1)*(pMe-pX1) + 2.*DaDT(1)*(dpMeDT-dpXdT) ); + ddRdTT->at(1) = ddsigcdTT *a(0) + 2.*dsigcdT *DaDT(0) + sigc* DDaDTT(0) ; + + if (Gamma>0 and etaOverDt>0){ + ddRdTT->at(2) = ddsigcdTT * pow(eta*Gamma/this->getTimeStep(),_p) + + 2.*dsigcdT *_p*pow(eta*Gamma/this->getTimeStep(),_p-1)*(DetaDT*Gamma + eta*dGammaDT)/this->getTimeStep() + + sigc* _p*(_p-1)*pow(eta*Gamma/this->getTimeStep(),_p-2)*pow( ((DetaDT*Gamma + eta*dGammaDT)/this->getTimeStep()) ,2) + + sigc* _p*pow(eta*Gamma/this->getTimeStep(),_p-1)* (DDetaDTT*Gamma + 2.*DetaDT*dGammaDT )/this->getTimeStep() ; + } + + if (delT>1e-10){ + double DphiPDT = dpMeDT- dpXdT; + double DDphiPDTT = 0.; // (DphiPDT - (trMe-trMe_0+trX1_0-trX1)/delT)/delT; // 2*DphiPDT/delT - 2*(trMe-trMe_0+trX1_0-trX1)/pow(delT,2); // DEBUGGING + ddRdTT->at(0) += sigc * a(1) * DDphiPDTT ; + + if (Gamma>0 and etaOverDt>0){ + double DDGammaDTT = 0.; // 2*dGammaDT/delT - 2*(Gamma-Gamma_0)/pow(delT,2); // DEBUGGING + ddRdTT->at(2) += sigc* _p*pow(eta*Gamma/this->getTimeStep(),_p-1)*(eta*DDGammaDTT)/this->getTimeStep() ; + } + } + q1->_ddIsoHardForcedTT = *ddRdTT; + } + // ddRdTT = 2*dRdT/(T-T0) - 2*(R-R0)/pow((T-T0),2); // ddGammaDTT is very difficult to estimate + + // ddRdTF + if(ddRdFdT!=NULL){ + /* + for (int i=0; i<3; i++) + for (int j=0; j<3; j++){ + ddRdFdT->at(0)(i,j) = 0.; + }*/ + + for (int k=0; k<3; k++){ + STensorOperation::zero(ddRdFdT->at(k)); + if(delT>1e-10){ + ddRdFdT->at(k) = dRdF[k]; + ddRdFdT->at(k) -= dRdF_0[k]; + ddRdFdT->at(k) *= 1/delT; + } + } + } +}; diff --git a/NonLinearSolver/materialLaw/mlawNonLinearTVP.h b/NonLinearSolver/materialLaw/mlawNonLinearTVP.h index 922286a716d4ae3e6cbc8f83a340f0379460d07f..7fa218150b02500b05062c5f48756da85281c148 100644 --- a/NonLinearSolver/materialLaw/mlawNonLinearTVP.h +++ b/NonLinearSolver/materialLaw/mlawNonLinearTVP.h @@ -19,6 +19,9 @@ class mlawNonLinearTVP : public mlawNonLinearTVE{ protected: // double _tol; // for plasticity convergence double _TaylorQuineyFactor; // for heat conversion + bool _TaylorQuineyFlag; + double _PolyOrderChaboche; // polynomial order of Chaboche Coeffs + fullVector<double> _PolyCoeffsChaboche; // coeff of polymonial _coefficients(0)+_coefficients(1)*eps+... scalarFunction* _temFunc_Sy0; // temperature dependence of initial yield stress scalarFunction* _temFunc_H; // temperature dependence of hardening stress @@ -32,19 +35,46 @@ class mlawNonLinearTVP : public mlawNonLinearTVE{ virtual void hardening(const IPNonLinearTVP* q0, IPNonLinearTVP* q1, const double& T) const; virtual void getModifiedMandel(const STensor3& C, const IPNonLinearTVP *q0_, IPNonLinearTVP *q1) const; virtual void checkCommutavity(STensor3& commuteCheck, const STensor3& Ce, const STensor3& S, const IPNonLinearTVP *q1) const; - virtual void getChabocheCoeffs(fullVector<double>& coeffs, const double& opt, const IPNonLinearTVP *q1) const; + virtual void getChabocheCoeffs(fullVector<double>& coeffs, const double& opt, const IPNonLinearTVP *q1, std::vector<double>* dcoeffs=NULL) const; virtual void getPlasticPotential(const double& phiP, const double& phiE, double& Px) const; virtual void getYieldCoefficientTempDers(const IPNonLinearTVP *q1, const double& T, fullVector<double>& DcoeffsDT, fullVector<double>& DDcoeffsDTT) const; + + virtual void getIsotropicHardeningForce(const IPNonLinearTVP *q0, IPNonLinearTVP *q1, const double T0, const double& T, + double* ddRdTT = NULL, STensor3* ddRdFdT = NULL) const; virtual void getIsotropicHardeningForce(const IPNonLinearTVP *q0, IPNonLinearTVP *q1, const double T0, const double& T, const STensor3& DphiPDF, std::vector<double>* ddRdTT = NULL, std::vector<STensor3>* ddRdFdT = NULL) const; - virtual void getMechSourceTVP(const IPNonLinearTVP *q0, IPNonLinearTVP *q1, const double T0, const double& T, - const STensor3& dFpdT, const STensor43& dFpdF, const STensor3& DphiPDF, - double *Wm = NULL, STensor3 *dWmdF = NULL, double *dWmdT = NULL) const; + virtual void getMechSourceTVP(const STensor3& F0, const STensor3& F, const IPNonLinearTVP *q0, IPNonLinearTVP *q1, + const double T0, const double& T, const STensor3& Fepr, const STensor3& Cepr, + const STensor3& DphiPDF, double *Wm = NULL, STensor3 *dWmdF = NULL, double *dWmdT = NULL) const; virtual void getFreeEnergyTVM(const IPNonLinearTVP *q0, IPNonLinearTVP *q1, const double& T0, const double& T, double *psiTVM = NULL, double *DpsiTVMdT = NULL, double *DDpsiTVMdTT = NULL) const; - + + virtual void getIterated_DPhi(const double& T, const IPNonLinearTVP *q0, IPNonLinearTVP *q1, + const double& u, const double& v, const double& Gamma, const double& Cxtr, const double& Cxdev, const STensor3& Phipr, + const double& trXn, const STensor3& devXn, const STensor3& Cepr, const STensor3& Eepr, const STensor3& Kepr, + double& ptilde, STensor3& devPhi, + STensor3& Phi, STensor3& N, STensor3& expGN, STensor43& dexpAdA, + STensor43& Dho3, STensor43& Dho4inv, STensor43& Dho4_u_inv, double& Dho4_v_inv, + STensor3& sigExtra_pr, STensor3& sigExtra, double& DsigV_dTrEe, STensor43& DsigD_dDevEe) const; + + virtual void getDho3(const double& u, const double& v, const double& Gamma, const STensor3& Cepr, const STensor3& Ceinvpr, const STensor3& Kepr, + const STensor3& expGN, const STensor43& dexpAdA, STensor43& Dho3, STensor43& Dho4inv, + STensor43& Dho4_u_inv, double& Dho4_v_inv, const double* DsigV_dTrEe = NULL, const STensor43* DsigD_dDevEe = NULL) const; + + virtual void getG2Tensor(const STensor3& Cepr, const STensor3& Kepr, const STensor3& expGN, + const STensor43& DCeinvprDCepr, const STensor43& DKeprDCepr, STensor43& G2) const; + + virtual void getG2TTensor(const STensor3& Cepr, const STensor3& expGN, const STensor3& dKeprDT, STensor3& G2T) const; + + + virtual void plasticCorrector_TVP(const STensor3& F0, const STensor3& F, const IPNonLinearTVP *q0, IPNonLinearTVP *q1, const double T0, const double T, + STensor3& Kepr, STensor3& Mepr, + double& DKDTsum, double& DGDTsum, + STensor3& corKir_e, STensor3& Me, STensor3& N, STensor3& P, + const bool stiff = false, STensor3 *DphiPDF = NULL) const{}; + virtual void predictorCorrector_TVP_nonAssociatedFlow(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, @@ -61,7 +91,7 @@ class mlawNonLinearTVP : public mlawNonLinearTVE{ double &mechanicalSource, // mechanical source--> convert to heat double &dmechanicalSourcedT, STensor3 &dmechanicalSourceF) const; - + virtual void predictorCorrector_TVP_AssociatedFlow(const STensor3& F, const IPNonLinearTVP *q0_, IPNonLinearTVP *q1, STensor3&P, const bool stiff, STensor43& Tangent, STensor43& dFedF, STensor43& dFpdF, const double T0, const double T1) const; @@ -152,6 +182,9 @@ class mlawNonLinearTVP : public mlawNonLinearTVE{ virtual void setIsotropicHardeningCoefficients(const double HR1, const double HR2, const double HR3); + virtual void setPolynomialOrderChabocheCoeffs(const int order); + virtual void setPolynomialCoeffsChabocheCoeffs(const int i, const double val); + void setTemperatureFunction_InitialYieldStress(const scalarFunction& Tfunc){ if (_temFunc_Sy0 != NULL) delete _temFunc_Sy0; _temFunc_Sy0 = Tfunc.clone(); @@ -174,7 +207,7 @@ class mlawNonLinearTVP : public mlawNonLinearTVE{ // _viscosity->setTemperatureFunction(Tfunc); } - void setTaylorQuineyFactor(const double f){_TaylorQuineyFactor = f;}; + void setTaylorQuineyFactor(const double f, const bool flag){_TaylorQuineyFactor = f; _TaylorQuineyFlag = flag;}; virtual matname getType() const{return materialLaw::nonlinearTVP;} virtual void createIPState(IPStateBase* &ips, bool hasBodyForce, const bool* state_=NULL,const MElement *ele=NULL, @@ -225,4 +258,1100 @@ class mlawNonLinearTVP : public mlawNonLinearTVE{ #endif // SWIG }; -#endif //mlawNonLinearTVP \ No newline at end of file +#endif //mlawNonLinearTVP + +/* +void mlawNonLinearTVP::plasticCorrector_TVP(const STensor3& F0, const STensor3& F, const IPNonLinearTVP *q0, IPNonLinearTVP *q1, const double T0, const double T, + STensor3& Kepr, STensor3& Mepr, double& DKDTsum, double& DGDTsum, + STensor3& corKir_e, STensor3& Me, STensor3& N, STensor3& P, + const bool stiff, STensor3 *DphiPDF) const{ + + +// compute elastic predictor + STensor3& Fp1 = q1->_Fp; + const STensor3& Fp0 = q0->_Fp; + + // 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->hardening(q0,q1,T); + static fullVector<double> a(3), Da(3); // yield coefficients and derivatives in respect to plastic deformation + this->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->getDR(); // kinematic hardening parameter + dHb = q1->_ipKinematic->getDDR(); // kinematic hardening parameter derivative (dHb/dgamma) + dHbdT = Hb * q1->_ipKinematic->getDRDT(); // make sure to normalise DRDT while defining in python file //NEW + ddHbddT = Hb * q1->_ipKinematic->getDDRDTT(); + } + + 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; + + STensor3& Ee = q1->_Ee; + 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 + double Ke, Ge = 0.; double Kde, Gde = 0.; double KTsum, GTsum = 0.; + double DKe, DGe = 0.; double DKde, DGde = 0.; // double DKDTsum, DGDTsum = 0.; + ThermoViscoElasticPredictor(Ee,q0->_Ee,q0,q1,Ke,Ge,Kde,Gde,DKe,DGe,DKde,DGde,KTsum,GTsum,DKDTsum,DGDTsum,T0,T); + getTVEdCorKirDT(q0,q1,T0,T); + + // additional branch - update predictor + double DsigV_dTrEe_pr(0.), DsigV_dTrEe(0.); + static STensor3 sigExtra_pr, sigExtra, DsigExtraDT_pr, DsigExtraDT; + static STensor43 DsigD_dDevEe_pr, DsigD_dDevEe; + STensorOperation::zero(sigExtra_pr); + STensorOperation::zero(sigExtra); + STensorOperation::zero(DsigExtraDT_pr); + STensorOperation::zero(DsigExtraDT); + STensorOperation::zero(DsigD_dDevEe_pr); + STensorOperation::zero(DsigD_dDevEe); + if (_useExtraBranch){ + mlawNonLinearTVE::extraBranchLaw(Ee,T,q0,q1,sigExtra_pr,stiff,NULL,&DsigExtraDT_pr, &DsigV_dTrEe_pr, &DsigD_dDevEe_pr); + } + q1->_kirchhoff += sigExtra_pr; + q1->_DcorKirDT += DsigExtraDT_pr; + + const STensor3& dKeprDT = q1->_DcorKirDT; // Get the predicted value + + // Initialise Dho + static STensor43 Dho3, Dho4inv, Dho4_u_inv; // This will be the final important tensor. + double Dho4_v_inv(0.); + + // Get Mepr + // static STensor3 Me, Mepr, Kepr; // Ke is corKir + 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,devPhi; // effective dev stress predictor + static double ptildepr,ptilde; + 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 + // double Gamma = 0.; + double& Gamma = q1->_Gamma; // flow rule parameter + Gamma = 0.; + double dDgammaDGamma = 0.; + double Dgamma = 0.; // eqplastic strain + static fullVector<double> m(2); + getChabocheCoeffs(m,0,q1); + + double DfDGamma = 0.; + double dfdDgamma(0.), dfdGamma(0.); + double dAdDgamma(0.), dAdGamma(0.); + double u = 1.; + double v = 1.; + + // Initialise Cx, Gt, Kt + 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.), dudDgamma(0.), dvdDgamma(0.), dudGamma(0.), dvdGamma(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); + } + double Gt = Ge + pow(kk,1.) * Hb/(2.*Cxdev); // pow(kk,2) DEBUG + double Kt = Ke + pow(kk,1.) * Hb/(3.*Cxtr); // pow(kk,2) DEBUG + + // Initialise ptilde and devPhi (phi) + ptilde = ptildepr; // current effective pressure -> first invariant + devPhi = devPhipr; + + // Initialise the rest + getDho3(u,v,Gamma,Cepr,Ceinvpr,Kepr,expGN,dexpAdA,Dho3,Dho4inv,Dho4_u_inv,Dho4_v_inv); + + 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; + + // Test + double Dgammma_test = 0.; + + // 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, dudDgamma dvdDgamma, dudGamma, dvdGamma + 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 + + dudDgamma = 6.*Gamma*( pow(kk,1.)/(2.*Cxdev)*dHb - (pow(kk,1.)*Hb)/(2.*pow(Cxdev,2.))*dCxdevdDgamma ); // pow(kk,2.) DEBUG + dvdDgamma = 2.*_b*Gamma*( pow(kk,1.)/(3.*Cxtr)*dHb - (pow(kk,1.)*Hb)/(3.*pow(Cxtr,2.))*dCxtrdDgamma ); // pow(kk,2.) DEBUG + + dudGamma = 6.*(Ge + pow(kk,1.)*Hb/(2.*Cxdev)); // pow(kk,2.) DEBUG + dvdGamma = 2.*_b*(Ke + pow(kk,1.)*Hb/(3.*Cxtr)); // pow(kk,2.) DEBUG + + // Get Hp = dPhiPdDgamma, dPhiPdGamma + double Hp = (1./3.*trXn/(pow(Cxtr,2.))*dCxtrdDgamma - ptilde*dvdDgamma)/v; + double dPhiPdGamma = - ptilde*dvdGamma/v; + + // Get He = dPhiEdGamma + // Get DdevPhidGamma + STensor3 DdevPhidDgamma, DdevPhidDgamma_RHS; + STensor3 DdevPhidGamma, DdevPhidGamma_RHS; + for (int i=0; i<3; i++) + for (int j=0; j<3; j++){ + DdevPhidDgamma_RHS(i,j) = devXn(i,j)/(pow(Cxdev,2.))*dCxdevdDgamma - dudDgamma*devPhi(i,j); + DdevPhidGamma_RHS(i,j) = -dudGamma*devPhi(i,j); + for (int k=0; k<3; k++) + for (int l=0; l<3; l++){ + DdevPhidDgamma_RHS(i,j) += (2.*_b/3.)*Gamma*Dho3(i,j,k,l)*_I(k,l)*Hp; //ADD + + DdevPhidGamma_RHS(i,j) += (2.*_b/3.)*Gamma*Dho3(i,j,k,l)*_I(k,l)*dPhiPdGamma; //ADD + + DdevPhidGamma_RHS(i,j) += Dho3(i,j,k,l)*N(k,l); + } + } + for (int i=0; i<3; i++) + for (int j=0; j<3; j++){ + DdevPhidGamma(i,j) = 0.; + DdevPhidGamma(i,j) = 0.; + for (int k=0; k<3; k++) + for (int l=0; l<3; l++){ + DdevPhidDgamma(i,j) += Dho4_u_inv(i,j,k,l)*DdevPhidDgamma_RHS(k,l); + DdevPhidGamma(i,j) += Dho4_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 = kk*(A+Gamma*dAdGamma); // mistake in the paper (VD 2016) + + this->getYieldCoefficientDerivatives(q1,q1->_nup,Da); + + // DEBUG FLE + double a0 = a(0); + double a1 = a(1); + double a2 = a(2); + double da0 = Da(0); + double da1 = Da(1); + double da2 = Da(2); + + 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!! WHY?? + + 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 + updateEqPlasticDeformation(q1,q0,q1->_nup,Dgamma); + hardening(q0,q1,T); + getYieldCoefficients(q1,a); + if (q1->_ipKinematic != NULL){ + Hb = q1->_ipKinematic->getDR(); // kinematic hardening parameter + dHb = q1->_ipKinematic->getDDR(); // kinematic hardening parameter derivative (dHb/dgamma ??) + dHbdT = Hb * q1->_ipKinematic->getDRDT(); // make sure to normalise DRDT while defining in python file //NEW + ddHbddT = Hb * q1->_ipKinematic->getDDRDTT(); + } + //a.print("a update"); + + // Update Cx, u, v + 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); + } + Gt = Ge + pow(kk,1.) * Hb/(2.*Cxdev); // pow(kk,2) DEBUG + Kt = Ke + pow(kk,1.) * Hb/(3.*Cxtr); // pow(kk,2) DEBUG + u = 1.+6.*Gt*Gamma; + v = 1.+2.*_b*Kt*Gamma; + + // Update Phi + // ptilde = ptildepr + 1/3*trXn*(1-1/Cxtr); + // ptilde /= v; + getIterated_DPhi(T,q0,q1,u,v,Gamma,Cxtr,Cxdev,PhiPr,trXn,devXn,Cepr,Eepr,Kepr,ptilde,devPhi,Phi,N,expGN,dexpAdA,Dho3,Dho4inv,Dho4_u_inv,Dho4_v_inv, + sigExtra,DsigV_dTrEe,DsigD_dDevEe); + PhiEq = sqrt(1.5*devPhi.dotprod()); + + // Update A + A = sqrt(6.*PhiEq*PhiEq+4.*_b*_b/3.*ptilde*ptilde); + + Dgamma = kk*Gamma*A; + 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, u, v + 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); + } + Gt = Ge + pow(kk,1.) * Hb/(2.*Cxdev); // pow(kk,2.) DEBUG + Kt = Ke + pow(kk,1.) * Hb/(3.*Cxtr); // pow(kk,2.) DEBUG + u = 1.+6.*Gt*Gamma; + v = 1.+2.*_b*Kt*Gamma; + + // Correct Phi + // ptilde = ptildepr + 1/3*trXn*(1-1/Cxtr); + // ptilde /= v; + getIterated_DPhi(T,q0,q1,u,v,Gamma,Cxtr,Cxdev,PhiPr,trXn,devXn,Cepr,Eepr,Kepr,ptilde,devPhi,Phi,N,expGN,dexpAdA,Dho3,Dho4inv,Dho4_u_inv,Dho4_v_inv, + sigExtra,DsigV_dTrEe,DsigD_dDevEe); + 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); + 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; + + // Correct A, B + ThermoViscoElasticPredictor(Ee,q0->_Ee,q0,q1,Ke,Ge,Kde,Gde,DKe,DGe,DKde,DGde,KTsum,GTsum,DKDTsum,DGDTsum,T0,T); //,false); + getTVEdCorKirDT(q0,q1,T0,T); // update dCorKirdT - don't do this probably + // DKDTsum and DGDTsum = sum of bulk/shear moduli derivatives wrt T + + // Correct Extrabranch - update stress + if (_useExtraBranch){ + mlawNonLinearTVE::extraBranchLaw(Ee,T,q0,q1,sigExtra_pr,stiff,NULL,&DsigExtraDT,&DsigV_dTrEe,&DsigD_dDevEe); + } + q1->_kirchhoff += sigExtra_pr; + q1->_DcorKirDT += DsigExtraDT_pr; + + // 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; + } + } // 1st if + + corKir_e = q1->_kirchhoff; + const STensor3& KS = q1->_kirchhoff; + // const STensor3& DcorKirDT_TVEcorrection = q1->_DcorKirDT; // Get the corrected value directly from TVE + 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); + } + +if (stiff){ + + // DECLARE UNDECLARED HERE + static STensor3 dFpdT; + static STensor43 dFpdF, dFedF; + STensorOperation::zero(dFpdT); + STensorOperation::zero(dFpdF); + STensorOperation::zero(dFedF); + + // dP/dF + + //1. get DtrKeprDCepr and DdevKeprDCepr, also DKeprDCepr + static STensor3 DpDCepr; + static STensor43 DdevKDCepr; + static STensor43 DdevKeprDCepr, DdevMeprDCepr, DKeprDCepr; + static STensor3 DpKeprDCepr, DpMeprDCepr; // K = corKir; pK -> pressure of corKir + STensorOperation::multSTensor3STensor43(_I,DlnDCepr,DpKeprDCepr); + DpKeprDCepr*= (0.5*Ke); + STensorOperation::multSTensor43(_Idev,DlnDCepr,DdevKeprDCepr); + DdevKeprDCepr*= Ge; + + // DKeprDCepr + DKeprDCepr = DdevKeprDCepr; + 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++){ + DKeprDCepr(i,j,k,l) += _I(i,j)*DpKeprDCepr(k,l); + } + + // initiate here - corrected corKir derivatives wrt Cepr + DpDCepr = DpKeprDCepr; + DdevKDCepr = DdevKeprDCepr; + + //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); + } + + //3. get DtrMeprDCepr and DdevMeprDCepr + static STensor43 DMeprDCepr; + + static STensor3 temp1; + static STensor43 temp2, temp3; + STensorOperation::multSTensor3(Kepr,Ceinvpr,temp1); + + 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++){ + temp2(i,s,k,l) = 0.; + temp3(i,s,k,l) = 0.; + for (int m=0; m<3; m++){ + temp2(i,s,k,l) += _I4(i,m,k,l)*temp1(m,s); + temp3(i,s,k,l) += DKeprDCepr(i,m,k,l)*Ceinvpr(m,s) + Kepr(i,m)*DCeinvprDCepr(m,s,k,l); + } + } + + 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++){ + DMeprDCepr(i,s,k,l) = 0.; + for (int m=0; m<3; m++) + DMeprDCepr(i,s,k,l) += Cepr(i,m)*temp3(m,s,k,l); + } + + DMeprDCepr += temp2; + DMeprDCepr += DKeprDCepr; + DMeprDCepr *= 0.5; + + // Because, TrMepr = TrKepr + DpMeprDCepr = DpKeprDCepr; + + // + STensorOperation::zero(DdevMeprDCepr); + 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++){ + DdevMeprDCepr(i,s,k,l) += DMeprDCepr(i,s,k,l) - _I(i,s)*DpMeprDCepr(k,l); + } + + //4. get DdevphiDCepr and DphiPprDCepr + static STensor3 DphiPprDCepr, DphiPDCepr; + static STensor43 DdevphiprDCepr, DdevphiDCepr; + + DphiPprDCepr = DpMeprDCepr; + DdevphiprDCepr = DdevMeprDCepr; + + DphiPDCepr = DphiPprDCepr; + DphiPDCepr *= 1./v; + DdevphiDCepr = DdevphiprDCepr; + DdevphiDCepr *= 1./u; + + //5. get DphiEprDCepr from DdevphiDCepr + static STensor3 DphiEDCepr, DphiEDdevPhi; + if (PhiEq >0.){ + DphiEDdevPhi = devPhi; + DphiEDdevPhi *= 1.5/(PhiEq); + } + + STensorOperation::multSTensor3STensor43(DphiEDdevPhi,DdevphiDCepr,DphiEDCepr); + + // 6. to 11. (inside if loop-> Gamma > 0.) + static STensor3 dAdCepr, dfDCepr, dgDCepr; + static STensor3 DGDCepr; + static STensor3 DgammaDCepr; + static STensor3 DtrNDCepr; + static STensor43 DdevNDCepr; + static STensor43 dFpDCepr; + static STensor43 dCedCepr, dCeinvdCepr; + static STensor43 dXdCepr; + static STensor3 dTrXdCepr; + static STensor43 dGammaNdCepr; + + if (Gamma >0.){ + + //6. get dAdCepr from DdevphiDCepr + 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 + static STensor3 DGDCepr_test, DgammaDCepr_test; + 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); + } + } + + for (int i=0; i<3; i++){ + for (int j=0; j<3; j++){ + DgammaDCepr(i,j) = (-dgdGamma*DGDCepr(i,j) - dgDCepr(i,j))/dgdDgamma; + } + } + + //8. update DdevphiDCepr and DphiEDCepr, DphiPDCepr + static STensor3 dCxdevdCepr, dCxtrdCepr; + dCxdevdCepr = DgammaDCepr; + dCxdevdCepr *= dCxdevdDgamma; + dCxtrdCepr = DgammaDCepr; + dCxdevdCepr *= dCxtrdDgamma; + + static STensor3 dudCepr, dvdCepr; + for (int i=0; i<3; i++) + for (int j=0; j<3; j++){ + dudCepr(i,j) = dudDgamma*DgammaDCepr(i,j) + dudGamma*DGDCepr(i,j); + dvdCepr(i,j) = dvdDgamma*DgammaDCepr(i,j) + dvdGamma*DGDCepr(i,j); + } + + // update DphiPDCepr + for (int i=0; i<3; i++) + for (int j=0; j<3; j++){ + DphiPDCepr(i,j) += ( -dvdCepr(i,j)*ptilde + 1./3.*trXn/(pow(Cxtr,2.))*dCxtrdCepr(i,j) )/v; + } + + // update DdevphiDCepr, DphiEDCepr + // Use Dho for DdevphiDCepr + static STensor43 G2, G3; + getG2Tensor(Cepr,Kepr,expGN,DCeinvprDCepr,DKeprDCepr,G2); + 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++){ + G3(i,j,k,l) = G2(i,j,k,l) + DdevphiprDCepr(i,j,k,l) + devXn(i,j)*dCxdevdCepr(k,l)/(pow(Cxdev,2.)) - devPhi(i,j) * dudCepr(k,l); + for (int p=0; p<3; p++) + for (int q=0; q<3; q++) + G3(i,j,k,l) += Dho3(i,j,p,q)* ( N(p,q)*DGDCepr(k,l) + 2.*_b*Gamma/3.*_I(p,q)*DphiPDCepr(k,l) ); + } + + STensorOperation::multSTensor43(Dho4_u_inv,G3,DdevphiDCepr); + STensorOperation::multSTensor3STensor43(DphiEDdevPhi,DdevphiDCepr,DphiEDCepr); + + + //9. get DtrNDCepr DdevNdCepr + DtrNDCepr = DphiPDCepr; + DtrNDCepr *= (2.*_b); + + DdevNDCepr = DdevphiDCepr; + DdevNDCepr *= 3.; + + // 10. get dFpDCepr + + // 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 + static STensor3 DtrXdCepr; + static STensor43 DdevXdCepr; + for (int i=0; i<3; i++) + for (int j=0; j<3; j++){ + DtrXdCepr(i,j) = pow(kk,1.)*dHb*Gamma*trN*DgammaDCepr(i,j) + pow(kk,1.)*Hb*( trN*DGDCepr(i,j) + Gamma*DtrNDCepr(i,j) ) - trX*dCxtrdCepr(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*Gamma*devN(i,j)*DgammaDCepr(k,l) + pow(kk,1.)*Hb*( devN(i,j)*DGDCepr(k,l) + Gamma*DdevNDCepr(i,j,k,l) ) - + devX(i,j)*dCxdevdCepr(k,l) ; // pow(kk,2.) DEBUG + } + } + DdevXdCepr *= 1./Cxdev; + DtrXdCepr *= 1./Cxtr; + + 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 DpDCepr, DdevKDCepr + // (DpKeprDCepr DdevKeprDCepr) + for (int i=0; i<3; i++){ + for (int j=0; j<3; j++){ + DpDCepr(i,j) -= Ke*(DGDCepr(i,j)*trN + Gamma*DtrNDCepr(i,j)); + for (int k=0; k<3; k++){ + for (int l=0; l<3; l++){ + DdevKDCepr(i,j,k,l) -= 2.*Ge*(DGDCepr(k,l)*devN(i,j) + Gamma*DdevNDCepr(i,j,k,l)); + } + } + } + } + + } // if Gamma + else{ + // elastic + STensorOperation::zero(DgammaDCepr); + STensorOperation::zero(dFpDCepr); + STensorOperation::zero(DtrNDCepr); + STensorOperation::zero(DdevNDCepr); + STensorOperation::zero(DGDCepr); + STensorOperation::zero(dXdCepr); + STensorOperation::zero(dTrXdCepr); + } + + // 12. get dKcorDcepr + static STensor43 dKcorDcepr; + dKcorDcepr = DdevKDCepr; + 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++){ + dKcorDcepr(i,j,k,l) += _I(i,j)*DpDCepr(k,l); + } + } + } + } + + // 13. get CeprToF conversion tensor + static STensor43 CeprToF; + 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); + } + } + } + } + + static STensor43 DKcorDF; + STensorOperation::multSTensor43(dKcorDcepr,CeprToF,DKcorDF); + + // 14. get dSdCepr and dSdF; also get dMedCepr and dMedF + // Done below -> need dCedF + + 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 + if(DphiPDF!=NULL){ + STensor3 _DphiPDF(0.); + for (int i=0; i<3; i++) + for (int j=0; j<3; j++){ + _DphiPDF(i,j) = 0.; + 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); + } + } + *DphiPDF = _DphiPDF; + } + // 15. get DgammaDF + STensor3& DgammaDF = q1->_DgammaDF; + STensor3& DGammaDF = q1->_DGammaDF; + STensorOperation::zero(DgammaDF); + STensorOperation::zero(DGammaDF); + if (Gamma > 0){ + STensorOperation::multSTensor3STensor43(DgammaDCepr,CeprToF,DgammaDF); + STensorOperation::multSTensor3STensor43(DGDCepr,CeprToF,DGammaDF); + STensorOperation::multSTensor43(dFpDCepr,CeprToF,dFpdF); + } + + // 16. Everything else + 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); + for (int m=0; m<3; m++) + for (int s=0; s<3; s++) + dMedF(i,j,k,l) += dCedF(i,m,k,l)*KS(m,s)*Ceinv(s,j) + Ce(i,m)*(DKcorDF(m,s,k,l)*Ceinv(s,j) + KS(m,s)*dCeinvDF(s,j,k,l)); + // KS is corKir + } + dMedF *= 0.5; + + // dP/dT + + // 1. get dMeprDT from dKeprDT -> DcorKirprDT from TVE + static STensor3 dMeprDT, dDevMeprDT, DcorKirDT; + static double dpMeprDT; + // const STensor3& dKeprDT = q1->getConstRefToDcorKirDT(); // Predictor DcorKirDT + STensorOperation::zero(dMeprDT); + + static STensor3 temp16, temp17; + STensorOperation::multSTensor3(dKeprDT, Ceinvpr, temp16); + STensorOperation::multSTensor3(Cepr, temp16, temp17); + + dMeprDT = 0.5*(dKeprDT + temp17); + + STensorOperation::decomposeDevTr(dMeprDT,dDevMeprDT,dpMeprDT); + dpMeprDT = dMeprDT.trace()/3.; + + DcorKirDT = dKeprDT; // update later + + // 2. get dPhipprDT and dDevPhiprDT + static double dPhipprDT; + static STensor3 dDevPhiprDT; + + dPhipprDT = dpMeprDT; + dDevPhiprDT = dDevMeprDT; + + // 3. get dXdT + // need this for DmechsourceDT -> initialise here (X is backStress) + STensor3& dXdT = q1->getRefToDbackStressdT(); + STensorOperation::zero(dXdT); + STensor3& dGammaNdT = q1->_dGammaNdT; + STensorOperation::zero(dGammaNdT); + + // 4. get dPhiPdT and dDevPhiDT + static double dPhiPdT; + static STensor3 dDevPhiDT; + + dPhiPdT = dPhipprDT; + dPhiPdT /= v; + + dDevPhiDT = dDevPhiprDT; + dDevPhiDT *= 1./u; + + // 5. get dPhiEdT + static double dPhiEdT; + STensorOperation::doubleContractionSTensor3(DphiEDdevPhi,dDevPhiDT,dPhiEdT); + + // 6. to 11. (inside if loop-> Gamma > 0.) + static double dAdT, dfdT, dgdT; + static double dGammaDT; + static double DgammaDT; + static double DtrNdT; + static STensor3 DdevNdT; + static STensor3 dFpDT; + + double 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 + + // 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; + + // 8.0 update dCxdT, dudT, dvdT + static double dCxdevdT, dCxtrdT; + 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 + + static double dudT, dvdT; + dudT = 6.*Gamma*(DGDTsum + pow(kk,1.)/(2.*Cxdev)*(dHbdT) - (pow(kk,1.)*Hb)/(2.*pow(Cxdev,2))*dCxdevdT); // pow(kk,2.) DEBUG + dvdT = 2.*_b*Gamma*(DKDTsum + pow(kk,1.)/(3.*Cxtr)*(dHbdT) - (pow(kk,1.)*Hb)/(3.*pow(Cxtr,2))*dCxtrdT); // pow(kk,2.) DEBUG + + dudT += 6.*dGammaDT*(Ge+pow(kk,1)*Hb/(2.*Cxdev)); // pow(kk,2) DEBUG + dvdT += 2.*_b*dGammaDT*(Ke+pow(kk,1)*Hb/(3.*Cxtr)); // pow(kk,2) DEBUG + + // 8. update DdevphiDT and DphiPDT + dPhiPdT = (dPhipprDT - dvdT*ptilde + 1./3.*trXn/(pow(Cxtr,2.))*dCxtrdT)/v; + + static STensor3 G2T, G3T; + getG2TTensor(Cepr,expGN,dKeprDT,G2T); + for (int i=0; i<3; i++) + for (int j=0; j<3; j++){ + G3T(i,j) = G2T(i,j) + dDevPhiprDT(i,j) + devXn(i,j)/pow(Cxdev,2.)*dCxdevdT - dudT*devPhi(i,j); + for (int p=0; p<3; p++) + for (int q=0; q<3; q++) + G3T(i,j) += Dho3(i,j,p,q)*(dGammaDT*N(p,q) + 2.*_b*Gamma/3.*dPhiPdT*_I(p,q)); + } + + STensorOperation::multSTensor3STensor43(G3T,Dho4_u_inv,dDevPhiDT); + + // 9. get DtrNdT DdevNdT + DtrNdT = dPhiPdT; + DtrNdT *= (2.*_b); + + DdevNdT = dDevPhiDT; + DdevNdT *= 3.; + + // 10. get dFpdT + 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); + } + } + + // 10.1 dXdT - backstress temperature derivative -> correction - CHECK!!! + static double DtrXdT; + static STensor3 DdevXdT; + DtrXdT = pow(kk,1.)*Gamma*(dHbdT)*trN + pow(kk,1.)*Hb*(dGammaDT*trN + Gamma*DtrNdT) - dCxtrdT*trX; // pow(kk,2.) DEBUG + for (int i=0; i<3; i++) + for (int j=0; j<3; j++){ + DdevXdT(i,j) = pow(kk,1.)*Gamma*(dHbdT)*devN(i,j) + pow(kk,1.)*Hb*( dGammaDT*devN(i,j) + Gamma*DdevNdT(i,j) ) - dCxdevdT*devX(i,j) ; // pow(kk,2.) DEBUG + } + DdevXdT *= 1./Cxdev; + DtrXdT *= 1./Cxtr; + + STensorOperation::zero(dXdT); + dXdT = DdevXdT; + dXdT(0,0) = DtrXdT/3.; + dXdT(1,1) = DtrXdT/3.; + dXdT(2,2) = DtrXdT/3.; + + // 11. DcorKirDT + for (int i=0; i<3; i++){ + for (int j=0; j<3; j++){ + DcorKirDT(i,j) -= ( DKDTsum*Gamma*trN + Ke*(dGammaDT*trN+Gamma*DtrNdT))*_I(i,j); + DcorKirDT(i,j) -= 2.*( DGDTsum*Gamma*devN(i,j) + Ge*(dGammaDT*devN(i,j)+Gamma*DdevNdT(i,j))); + } + } + q1->_DcorKirDT = DcorKirDT; // Update in IP for mechSrcTVE + + } // if Gamma + else{ + // elastic + STensorOperation::zero(DgammaDT); + // STensorOperation::zero(dFpDT); + STensorOperation::zero(DtrNdT); + STensorOperation::zero(DdevNdT); + STensorOperation::zero(dGammaDT); + } + + // 12. get dKcorDT + // done above + + // 13. 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); + } + + // 13.1 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); + for (int k=0; k<3; k++) + for (int l=0; l<3; l++){ + dMeDT(i,j) += dCedT(i,k)*KS(k,l)*Ceinv(l,j) + Ce(i,k)*(DcorKirDT(k,l)*Ceinv(l,j) + KS(k,l)*dCeinvdT(l,j)); + } + } + dMeDT *= 0.5; + + } // stiff + +};*/ \ No newline at end of file diff --git a/NonLinearSolver/materialLaw/mullinsEffect.cpp b/NonLinearSolver/materialLaw/mullinsEffect.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9d85d26768ca6df91f1874dc3648ba169dfc13a9 --- /dev/null +++ b/NonLinearSolver/materialLaw/mullinsEffect.cpp @@ -0,0 +1,539 @@ +// +// Description: Define mullins effect for softening in polymers in (pseudo-)hyperelastic regime +// +// +// Author: <Ujwal Kishore J.>, (C) 2023 +// +// Copyright: See COPYING file that comes with this distribution +// +// +#include "mullinsEffect.h" + +mullinsEffect::mullinsEffect(const int num,const bool init): _num(num), _initialized(init){} + +mullinsEffect::mullinsEffect(const mullinsEffect &source) +{ + _num = source._num; + _initialized = source._initialized; +} + +mullinsEffect& mullinsEffect::operator=(const mullinsEffect &source) +{ + _num = source._num; + _initialized = source._initialized; + return *this; +} + + +negativeExponentialScaler::negativeExponentialScaler(const int num, double r, double m, bool init): + mullinsEffect(num,init),_r(r),_m(m){ + + _temFunc_r= new constantScalarFunction(1.); + _temFunc_m= new constantScalarFunction(1.); +}; + +negativeExponentialScaler::negativeExponentialScaler(const negativeExponentialScaler& src): + mullinsEffect(src), _r(src._r), _m(src._m){ + + _temFunc_r = NULL; + if (src._temFunc_r != NULL){ + _temFunc_r = src._temFunc_r->clone(); + } + + _temFunc_m = NULL; + if (src._temFunc_m != NULL){ + _temFunc_m = src._temFunc_m->clone(); + } +}; + +negativeExponentialScaler& negativeExponentialScaler::operator =(const mullinsEffect& src){ + mullinsEffect::operator=(src); + const negativeExponentialScaler* psrc = dynamic_cast<const negativeExponentialScaler*>(&src); + if(psrc != NULL) + { + _r = psrc->_r; + _m = psrc->_m; + + if (psrc->_temFunc_r != NULL){ + if (_temFunc_r != NULL){ + _temFunc_r->operator=(*psrc->_temFunc_r); + } + else{ + _temFunc_r = psrc->_temFunc_r->clone(); + } + } + + if (psrc->_temFunc_m != NULL){ + if (_temFunc_m != NULL){ + _temFunc_m->operator=(*psrc->_temFunc_m); + } + else{ + _temFunc_m = psrc->_temFunc_m->clone(); + } + } + } + return *this; +}; + +negativeExponentialScaler::~negativeExponentialScaler(){ + if (_temFunc_r != NULL) {delete _temFunc_r; _temFunc_r = NULL;}; + if (_temFunc_m != NULL) {delete _temFunc_m; _temFunc_m = NULL;}; +}; + +void negativeExponentialScaler::setTemperatureFunction_r(const scalarFunction& Tfunc){ + if (_temFunc_r != NULL) delete _temFunc_r; + _temFunc_r = Tfunc.clone(); +} + +void negativeExponentialScaler::setTemperatureFunction_m(const scalarFunction& Tfunc){ + if (_temFunc_m != NULL) delete _temFunc_m; + _temFunc_m = Tfunc.clone(); +} + +void negativeExponentialScaler::createIPVariable(IPMullinsEffect* &ipv) const +{ + if(ipv != NULL) delete ipv; + ipv = new IPMullinsEffect(); +} + +void negativeExponentialScaler::mullinsEffectScaling(double _psi0, double _psi, const IPMullinsEffect &ipvprev, IPMullinsEffect &ipv) const{ + + // 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 _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.; + } + + ipv.set(eta,DetaDpsi_cap,DDetaDpsipsi,DetaDT,DDetaDTT); + ipv.setPsiMax(_psi_max); +} + +void negativeExponentialScaler::mullinsEffectScaling(double _psi0, double _psi, const IPMullinsEffect &ipvprev, IPMullinsEffect &ipv, const double T) const{ + + double r = _r*_temFunc_r->getVal(T); + double m = _m*_temFunc_m->getVal(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 _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.; + } + + /* + 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); + ipv.setPsiMax(_psi_max); +} + +mullinsEffect *negativeExponentialScaler::clone() const +{ + return new negativeExponentialScaler(*this); +} + +// ############# + +linearScaler::linearScaler(const int num, double r, bool init): + mullinsEffect(num,init),_r(r){ + + _temFunc_r= new constantScalarFunction(1.); +}; + +linearScaler::linearScaler(const linearScaler& src): + mullinsEffect(src), _r(src._r){ + + _temFunc_r = NULL; + if (src._temFunc_r != NULL){ + _temFunc_r = src._temFunc_r->clone(); + } +}; + +linearScaler& linearScaler::operator =(const mullinsEffect& src){ + mullinsEffect::operator=(src); + const linearScaler* psrc = dynamic_cast<const linearScaler*>(&src); + if(psrc != NULL) + { + _r = psrc->_r; + + if (psrc->_temFunc_r != NULL){ + if (_temFunc_r != NULL){ + _temFunc_r->operator=(*psrc->_temFunc_r); + } + else{ + _temFunc_r = psrc->_temFunc_r->clone(); + } + } + } + return *this; +}; + +linearScaler::~linearScaler(){ + if (_temFunc_r != NULL) {delete _temFunc_r; _temFunc_r = NULL;}; +}; + +void linearScaler::setTemperatureFunction_r(const scalarFunction& Tfunc){ + if (_temFunc_r != NULL) delete _temFunc_r; + _temFunc_r = Tfunc.clone(); +} + +void linearScaler::createIPVariable(IPMullinsEffect* &ipv) const +{ + if(ipv != NULL) delete ipv; + ipv = new IPMullinsEffect(); +} + +void linearScaler::mullinsEffectScaling(double _psi0, double _psi, const IPMullinsEffect &ipvprev, IPMullinsEffect &ipv) const{ + + // 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 _psi_max = std::max(_psi,_psi_max0); + Msg::Error(" Inside mullinsEffectScaling, _psi = %e, _psi_max = %e !!", _psi, _psi_max); + + eta = (1-_r)/(1-_r*psi_cap/_psi_max); + + ipv.set(eta,DetaDpsi_cap,DDetaDpsipsi,DetaDT,DDetaDTT); + ipv.setPsiMax(_psi_max); +} + +void linearScaler::mullinsEffectScaling(double _psi0, double _psi, const IPMullinsEffect &ipvprev, IPMullinsEffect &ipv, const double T) const{ + + double r = _r*_temFunc_r->getVal(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 _psi_max = std::max(_psi,_psi_max0); + Msg::Error(" Inside mullinsEffectScaling, _psi = %e, _psi_max = %e !!", _psi, _psi_max); + + eta = (1-_r)/(1-_r*psi_cap/_psi_max); + + ipv.set(eta,DetaDpsi_cap,DDetaDpsipsi,DetaDT,DDetaDTT); + ipv.setPsiMax(_psi_max); +} + +mullinsEffect *linearScaler::clone() const +{ + return new linearScaler(*this); +} + +// ###### + +positiveExponentialScaler::positiveExponentialScaler(const int num, double r, double m, bool init): + mullinsEffect(num,init),_r(r),_m(m){ + + _temFunc_r= new constantScalarFunction(1.); + _temFunc_m= new constantScalarFunction(1.); +}; + +positiveExponentialScaler::positiveExponentialScaler(const positiveExponentialScaler& src): + mullinsEffect(src), _r(src._r), _m(src._m){ + + _temFunc_r = NULL; + if (src._temFunc_r != NULL){ + _temFunc_r = src._temFunc_r->clone(); + } + + _temFunc_m = NULL; + if (src._temFunc_m != NULL){ + _temFunc_m = src._temFunc_m->clone(); + } +}; + +positiveExponentialScaler& positiveExponentialScaler::operator =(const mullinsEffect& src){ + mullinsEffect::operator=(src); + const positiveExponentialScaler* psrc = dynamic_cast<const positiveExponentialScaler*>(&src); + if(psrc != NULL) + { + _r = psrc->_r; + _m = psrc->_m; + + if (psrc->_temFunc_r != NULL){ + if (_temFunc_r != NULL){ + _temFunc_r->operator=(*psrc->_temFunc_r); + } + else{ + _temFunc_r = psrc->_temFunc_r->clone(); + } + } + + if (psrc->_temFunc_m != NULL){ + if (_temFunc_m != NULL){ + _temFunc_m->operator=(*psrc->_temFunc_m); + } + else{ + _temFunc_m = psrc->_temFunc_m->clone(); + } + } + } + return *this; +}; + +positiveExponentialScaler::~positiveExponentialScaler(){ + if (_temFunc_r != NULL) {delete _temFunc_r; _temFunc_r = NULL;}; + if (_temFunc_m != NULL) {delete _temFunc_m; _temFunc_m = NULL;}; +}; + +void positiveExponentialScaler::setTemperatureFunction_r(const scalarFunction& Tfunc){ + if (_temFunc_r != NULL) delete _temFunc_r; + _temFunc_r = Tfunc.clone(); +} + +void positiveExponentialScaler::setTemperatureFunction_m(const scalarFunction& Tfunc){ + if (_temFunc_m != NULL) delete _temFunc_m; + _temFunc_m = Tfunc.clone(); +} + +void positiveExponentialScaler::createIPVariable(IPMullinsEffect* &ipv) const +{ + if(ipv != NULL) delete ipv; + ipv = new IPMullinsEffect(); +} + +void positiveExponentialScaler::mullinsEffectScaling(double _psi0, double _psi, const IPMullinsEffect &ipvprev, IPMullinsEffect &ipv) const{ + + // 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 _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 = (_m*(1.-eta*psi_cap/_psi_max)); // 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*exp(Term)*psi_cap/_psi_max; + Deta = - f/DfDeta; + + if (eta + Deta > 1.){ + eta = 0.99; // NR + } + else + eta += Deta; + + Msg::Error(" Inside iterator: ite = %d, f = %e, DfDeta = %e, Deta = %e, eta = %e !!", ite, f, DfDeta, Deta, eta); + + Term = (_m*(1.-eta*psi_cap/_psi_max)); + 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; + } + } + + // eta = 1+_r*(1-exp(_m*(1 - psi_cap/_psi_max))); + + Dpsi_maxDpsi_cap = 0.; + + // DetaDpsi_cap = ; + } + else{ + eta = 1.; + DetaDpsi_cap = 0.; + } + + ipv.set(eta,DetaDpsi_cap,DDetaDpsipsi,DetaDT,DDetaDTT); + ipv.setPsiMax(_psi_max); +} + +void positiveExponentialScaler::mullinsEffectScaling(double _psi0, double _psi, const IPMullinsEffect &ipvprev, IPMullinsEffect &ipv, const double T) const{ + + double r = _r*_temFunc_r->getVal(T); + double m = _m*_temFunc_m->getVal(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 _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; + + 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; + } + } + // eta = 1+_r*(1-exp(_m*(1 - psi_cap/_psi_max))); + 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.; + } + + ipv.set(eta,DetaDpsi_cap,DDetaDpsipsi,DetaDT,DDetaDTT); + ipv.setPsiMax(_psi_max); +} + +mullinsEffect *positiveExponentialScaler::clone() const +{ + return new positiveExponentialScaler(*this); +} + +// ############# \ No newline at end of file diff --git a/NonLinearSolver/materialLaw/mullinsEffect.h b/NonLinearSolver/materialLaw/mullinsEffect.h new file mode 100644 index 0000000000000000000000000000000000000000..6ff7b654ce864354742f0bf5db9119f5abf5e29f --- /dev/null +++ b/NonLinearSolver/materialLaw/mullinsEffect.h @@ -0,0 +1,148 @@ +// +// Description: Define mullins effect for softening in polymers in (pseudo-)hyperelastic regime +// +// +// Author: <Ujwal Kishore J.>, (C) 2023 +// +// Copyright: See COPYING file that comes with this distribution +// +// +#ifndef MULLINSEFFECT_H_ +#define MULLINSEFFECT_H_ + +#include "ipMullinsEffect.h" +#include "fullMatrix.h" +#include "scalarFunction.h" + +class mullinsEffect { + public: + enum scalingFunction{negativeExponentialScaler,linearScaler,positiveExponentialScaler}; + + protected: + int _num; // number of law (must be unique !) + bool _initialized; // to initialize law + + public: + #ifndef SWIG + mullinsEffect(const int num, const bool init=true); + virtual ~mullinsEffect(){} + mullinsEffect(const mullinsEffect &source); + virtual mullinsEffect& operator=(const mullinsEffect &source); + virtual int getNum() const{return _num;} + virtual scalingFunction getType() const=0; + virtual void createIPVariable(IPMullinsEffect* &ipv) const=0; + virtual void initLaws(const std::map<int,mullinsEffect*> &maplaw)=0; + virtual const bool isInitialized() {return _initialized;} + virtual void mullinsEffectScaling(double _psi0, double _psi, const IPMullinsEffect &ipvprev, IPMullinsEffect &ipv) const=0; + virtual void mullinsEffectScaling(double _psi0, double _psi, const IPMullinsEffect &ipvprev, IPMullinsEffect &ipv, const double T) const=0; + virtual mullinsEffect * clone() const=0; + #endif + +}; + +// eta = 1 - r* ( 1 - exp(-sqrt(m*(psi_max-psi))) ) -> Ricker et al, 2021 (modified Zuniga, 2005) +class negativeExponentialScaler : public mullinsEffect{ + #ifndef SWIG + protected: + double _r; + double _m; + scalarFunction* _temFunc_r; + scalarFunction* _temFunc_m; + #endif // SWIG + + public: + negativeExponentialScaler(const int num, double r, double m, bool init = true); + void setTemperatureFunction_r(const scalarFunction& Tfunc); + void setTemperatureFunction_m(const scalarFunction& Tfunc); + #ifndef SWIG + virtual ~negativeExponentialScaler(); + negativeExponentialScaler(const negativeExponentialScaler& src); + virtual negativeExponentialScaler& operator =(const mullinsEffect& src); + virtual scalingFunction getType() const{return mullinsEffect::negativeExponentialScaler; }; + virtual void createIPVariable(IPMullinsEffect* &ipv) const; + virtual void initLaws(const std::map<int,mullinsEffect*> &maplaw) {}; //nothing now, we will see if we use the mapping + virtual void mullinsEffectScaling(double _psi0, double _psi, const IPMullinsEffect &ipvprev, IPMullinsEffect &ipv) const; + virtual void mullinsEffectScaling(double _psi0, double _psi, const IPMullinsEffect &ipvprev, IPMullinsEffect &ipv, const double T) const; + virtual mullinsEffect * clone() const; + #endif // SWIG +}; + +// eta = 1 - r* ( 1 - psi/psi_max ) -> linear +class linearScaler : public mullinsEffect{ + #ifndef SWIG + protected: + double _r; + scalarFunction* _temFunc_r; + #endif // SWIG + + public: + linearScaler(const int num, double r, bool init = true); + void setTemperatureFunction_r(const scalarFunction& Tfunc); + #ifndef SWIG + virtual ~linearScaler(); + linearScaler(const linearScaler& src); + virtual linearScaler& operator =(const mullinsEffect& src); + virtual scalingFunction getType() const{return mullinsEffect::linearScaler; }; + virtual void createIPVariable(IPMullinsEffect* &ipv) const; + virtual void initLaws(const std::map<int,mullinsEffect*> &maplaw) {}; //nothing now, we will see if we use the mapping + virtual void mullinsEffectScaling(double _psi0, double _psi, const IPMullinsEffect &ipvprev, IPMullinsEffect &ipv) const; + virtual void mullinsEffectScaling(double _psi0, double _psi, const IPMullinsEffect &ipvprev, IPMullinsEffect &ipv, const double T) const; + virtual mullinsEffect * clone() const; + #endif // SWIG +}; + +// eta = 1 + r* ( 1 - exp((m*(1-psi/psi_max))) ) +class positiveExponentialScaler : public mullinsEffect{ + #ifndef SWIG + protected: + double _r; + double _m; + scalarFunction* _temFunc_r; + scalarFunction* _temFunc_m; + #endif // SWIG + + public: + positiveExponentialScaler(const int num, double r, double m, bool init = true); + void setTemperatureFunction_r(const scalarFunction& Tfunc); + void setTemperatureFunction_m(const scalarFunction& Tfunc); + #ifndef SWIG + virtual ~positiveExponentialScaler(); + positiveExponentialScaler(const positiveExponentialScaler& src); + virtual positiveExponentialScaler& operator =(const mullinsEffect& src); + virtual scalingFunction getType() const{return mullinsEffect::positiveExponentialScaler; }; + virtual void createIPVariable(IPMullinsEffect* &ipv) const; + virtual void initLaws(const std::map<int,mullinsEffect*> &maplaw) {}; //nothing now, we will see if we use the mapping + virtual void mullinsEffectScaling(double _psi0, double _psi, const IPMullinsEffect &ipvprev, IPMullinsEffect &ipv) const; + virtual void mullinsEffectScaling(double _psi0, double _psi, const IPMullinsEffect &ipvprev, IPMullinsEffect &ipv, const double T) const; + virtual mullinsEffect * clone() const; + #endif // SWIG +}; +/* +// eta = 1 + r* ( 1 - exp((m*(1-psi))) ) +class arbitraryScaler : public mullinsEffect{ + #ifndef SWIG + protected: + double _r; + double _m; + scalarFunction* _temFunc_r; + scalarFunction* _temFunc_m; + #endif // SWIG + + public: + positiveExponentialScaler(const int num, double r, double m, bool init = true); + void setTemperatureFunction_r(const scalarFunction& Tfunc); + void setTemperatureFunction_m(const scalarFunction& Tfunc); + #ifndef SWIG + virtual ~positiveExponentialScaler(); + positiveExponentialScaler(const positiveExponentialScaler& src); + virtual positiveExponentialScaler& operator =(const mullinsEffect& src); + virtual scalingFunction getType() const{return mullinsEffect::positiveExponentialScaler; }; + virtual void createIPVariable(IPMullinsEffect* &ipv) const; + virtual void initLaws(const std::map<int,mullinsEffect*> &maplaw) {}; //nothing now, we will see if we use the mapping + virtual void mullinsEffectScaling(double _psi0, double _psi, const IPMullinsEffect &ipvprev, IPMullinsEffect &ipv) const; + virtual void mullinsEffectScaling(double _psi0, double _psi, const IPMullinsEffect &ipvprev, IPMullinsEffect &ipv, const double T) const; + virtual mullinsEffect * clone() const; + #endif // SWIG +};*/ + +#endif // MULLINSEFFECT_H_ diff --git a/NonLinearSolver/materialLaw/viscosityLaw.cpp b/NonLinearSolver/materialLaw/viscosityLaw.cpp index bc7aa3c5aafd3d89a3c65a48a8e177ed3a468348..7b94b7413cf96da803d38ab64b52df9811f04995 100644 --- a/NonLinearSolver/materialLaw/viscosityLaw.cpp +++ b/NonLinearSolver/materialLaw/viscosityLaw.cpp @@ -73,6 +73,14 @@ void constantViscosityLaw::get(const double p, const double T, double& R, double ddRdTT = _eta0*_temFunc->getDoubleDiff(T); }; +void constantViscosityLaw::get(const double p, const double T, double& R, double& dR, double& dRdT, double& ddRdTT, double& ddRdT) const { + R = _eta0*_temFunc->getVal(T); + dR = 0.; + dRdT = _eta0*_temFunc->getDiff(T); + ddRdTT = _eta0*_temFunc->getDoubleDiff(T); + ddRdT = 0.; +}; + saturatePowerViscosityLaw::saturatePowerViscosityLaw(const int num, const double eta0, const double q, const bool init): viscosityLaw(num,init), _eta0(eta0), _q(q){ _temFunc_eta0 = new constantScalarFunction(1.); @@ -197,6 +205,37 @@ void saturatePowerViscosityLaw::get(const double p, const double T, double& R, d }; +void saturatePowerViscosityLaw::get(const double p, const double T, double& R, double& dR, double& dRdT, double& ddRdTT, double& ddRdT) const{ + + double eta = _eta0*_temFunc_eta0->getVal(T); + double DetaDT = _eta0*_temFunc_eta0->getDiff(T); + double DDetaDTT = _eta0*_temFunc_eta0->getDoubleDiff(T); + double q = _q*_temFunc_q->getVal(T); + double DqDT = _q*_temFunc_q->getDiff(T); + double DDqDTT = _q*_temFunc_q->getDoubleDiff(T); + + R = eta * pow(p,q); + if(p <1.e-6 and q < 1.) + { + R = eta * pow(1.e-6,q)*(p/1.e-6); + dR = eta * pow(1.e-6,q) /1.e-6; + dRdT = DetaDT * pow(1.e-6,q)*(p/1.e-6) + eta * pow(1.e-6,_q)*(p/1.e-6)*DqDT*log(1.e-6); + ddRdTT = DDetaDTT * pow(1.e-6,q)*(p/1.e-6) + 2*DetaDT * pow(1.e-6,_q)*(p/1.e-6)*DqDT*log(1.e-6) + + eta*(p/1.e-6)*pow(1.e-6,_q)*(pow(log(1.e-6)*DqDT,2) + log(1.e-6)*DDqDTT); + ddRdT = DetaDT * pow(1.e-6,q) /1.e-6; + } + else + { + R = eta * pow(p,q); + dR = eta * pow(p,q-1.) * q; + dRdT = DetaDT * pow(p,q) + eta *pow(p,_q)*DqDT*log(p); + ddRdTT = DDetaDTT * pow(p,q) + 2*DetaDT*pow(p,_q)*DqDT*log(p) + + eta*pow(p,_q)*(pow(log(p)*DqDT,2) + log(p)*DDqDTT); + ddRdT = DetaDT * pow(p,q-1.) * q + eta * (DqDT*pow(p,q-1.) + q*pow(p,q-1.)*DqDT*log(p)); + } + +}; + saturateSinhViscosityLaw::saturateSinhViscosityLaw(const int num, const double eta0, const double eta1, const double g0, const bool init): viscosityLaw(num,init),_eta0(eta0),_eta1(eta1),_g0(g0){ _temFunc_eta0 = new constantScalarFunction(1.); @@ -318,4 +357,22 @@ void saturateSinhViscosityLaw::get(const double p, const double T, double& R, do dRdT = 0.; // correct it yourselves ddRdTT = 0.; // correct it yourselves } +}; +void saturateSinhViscosityLaw::get(const double p, const double T, double& R, double& dR, double& dRdT, double& ddRdTT, double& ddRdT) const{ + double pa = p/_g0; + if (pa< 1e-6){ + R = _eta0; + dR = 0.; + dRdT = 0.; // correct it by yourselves + ddRdTT = 0.; // correct it by yourselves + ddRdT = 0.; // correct it by yourselves + } + else + { + R = _eta1 + (_eta0-_eta1)*pa/sinh(pa); + dR = (_eta0-_eta1)*(1./sinh(pa) - (pa*cosh(pa))/(sinh(pa)*sinh(pa)))/_g0 ; + dRdT = 0.; // correct it yourselves + ddRdTT = 0.; // correct it yourselves + ddRdT = 0.; // correct it yourselves + } }; \ No newline at end of file diff --git a/NonLinearSolver/materialLaw/viscosityLaw.h b/NonLinearSolver/materialLaw/viscosityLaw.h index 3ba88cc9eba7795565a0bb721ad9492c0d1bfc59..977081ee6e5416ebd686684dfe235bab0dcbc245 100644 --- a/NonLinearSolver/materialLaw/viscosityLaw.h +++ b/NonLinearSolver/materialLaw/viscosityLaw.h @@ -29,6 +29,7 @@ class viscosityLaw { virtual void get(const double p, double& R, double& dR) const = 0; virtual void get(const double p, const double T, double& R, double& dR, double& dRdT) const = 0; virtual void get(const double p, const double T, double& R, double& dR, double& dRdT, double& ddRdTT) const = 0; + virtual void get(const double p, const double T, double& R, double& dR, double& dRdT, double& ddRdTT, double& ddRdT) const = 0; virtual viscosityLaw* clone() const = 0; #endif // SWIG }; @@ -48,6 +49,7 @@ class constantViscosityLaw : public viscosityLaw{ virtual void get(const double p, double& R, double& dR) const{R = _eta0; dR = 0.;}; virtual void get(const double p, const double T, double& R, double& dR, double& dRdT) const; virtual void get(const double p, const double T, double& R, double& dR, double& dRdT, double& ddRdTT) const; + virtual void get(const double p, const double T, double& R, double& dR, double& dRdT, double& ddRdTT, double& ddRdT) const; virtual viscosityLaw* clone() const {return new constantViscosityLaw(*this);}; #endif // SWIG }; @@ -70,6 +72,7 @@ class saturatePowerViscosityLaw : public viscosityLaw{ virtual void get(const double p, double& R, double& dR) const; virtual void get(const double p, const double T, double& R, double& dR, double& dRdT) const; virtual void get(const double p, const double T, double& R, double& dR, double& dRdT, double& ddRdTT) const; + virtual void get(const double p, const double T, double& R, double& dR, double& dRdT, double& ddRdTT, double& ddRdT) const; virtual viscosityLaw* clone() const {return new saturatePowerViscosityLaw(*this);}; #endif // SWIG }; @@ -97,6 +100,7 @@ class saturateSinhViscosityLaw : public viscosityLaw{ virtual void get(const double p, double& R, double& dR) const; virtual void get(const double p, const double T, double& R, double& dR, double& dRdT) const; virtual void get(const double p, const double T, double& R, double& dR, double& dRdT, double& ddRdTT) const; + virtual void get(const double p, const double T, double& R, double& dR, double& dRdT, double& ddRdTT, double& ddRdT) const; virtual viscosityLaw* clone() const {return new saturateSinhViscosityLaw(*this);}; #endif // SWIG }; diff --git a/NonLinearSolver/nlmechsolpy.i b/NonLinearSolver/nlmechsolpy.i index 4370ab66e1fde7031bca507a0c3a56c700ec79e8..99fca14ad7f8e591b61bd716a4917a90fcd0bb26 100644 --- a/NonLinearSolver/nlmechsolpy.i +++ b/NonLinearSolver/nlmechsolpy.i @@ -15,6 +15,7 @@ #include "j2IsotropicHardening.h" #include "kinematicHardening.h" #include "viscosityLaw.h" + #include "mullinsEffect.h" #include "CLengthLaw.h" #include "NucleationLaw.h" #include "nucleationCriterionLaw.h" @@ -84,6 +85,7 @@ %nodefaultctor J2IsotropicHardening; %nodefaultctor kinematicHardening; %nodefaultctor viscosityLaw; +%nodefaultctor mullinsEffect; %nodefaultctor RateFailureLaw; %nodefaultctor CLengthLaw; %nodefaultctor DamageLaw; @@ -164,6 +166,7 @@ %include "j2IsotropicHardening.h" %include "kinematicHardening.h" %include "viscosityLaw.h" +%include "mullinsEffect.h" %include "CLengthLaw.h" %include "NucleationLaw.h" %include "nucleationCriterionLaw.h" diff --git a/NonLinearSolver/nlsolver/scalarFunction.h b/NonLinearSolver/nlsolver/scalarFunction.h index 94ee94541c0d4f5afee402805e59385f04056510..036483209c26c0123296cca7a4cef03806d3b329 100644 --- a/NonLinearSolver/nlsolver/scalarFunction.h +++ b/NonLinearSolver/nlsolver/scalarFunction.h @@ -574,6 +574,38 @@ class negExpWLFshiftFactor : public scalarFunction #endif // SWIG }; +// function y = exp(- C(x-Tref) ) +class negativeExponentialFunction : public scalarFunction +{ + protected: + double _C, _Tref; + + public: + negativeExponentialFunction(double C, double Tref) : scalarFunction(),_C(C),_Tref(Tref){} + #ifndef SWIG + negativeExponentialFunction(const negativeExponentialFunction& src) : _C(src._C),_Tref(src._Tref){} + virtual negativeExponentialFunction& operator = (const scalarFunction& src){ + scalarFunction::operator=(src); + const negativeExponentialFunction* psrc = dynamic_cast<const negativeExponentialFunction*>(&src); + if (psrc!= NULL){ + _C = psrc->_C; + _Tref = psrc->_Tref; + } + return *this; + } + virtual ~negativeExponentialFunction(){}; + virtual double getVal(const double x) const { + return exp(-_C*(x-_Tref)); + }; + virtual double getDiff(const double x) const { + return (-_C*exp(-_C*(x-_Tref))); + }; + virtual double getDoubleDiff(const double x) const { + return (pow(_C,2)*exp(-_C*(x-_Tref))); + }; + virtual scalarFunction* clone() const {return new negativeExponentialFunction(*this);}; + #endif // SWIG +}; #endif // SCALARFUNCTION_H_ diff --git a/NonLinearSolver/nlsolver/timeFunction.h b/NonLinearSolver/nlsolver/timeFunction.h index 7c72ae9ce19abe20603c34b45b95b081e7f83665..112852d63ce00aa8da6c4803230874fab397ee1d 100644 --- a/NonLinearSolver/nlsolver/timeFunction.h +++ b/NonLinearSolver/nlsolver/timeFunction.h @@ -62,6 +62,24 @@ class sinusoidalFunctionTime : public simpleFunctionTime<double>{ }; #endif // SWIG }; + +//f = Asin(wt+phi) +class sinusoidalwithPhaseAngleFunctionTime : public simpleFunctionTime<double>{ + protected: + double _A; + double _w; + double _phi; + + public: + sinusoidalwithPhaseAngleFunctionTime(const double A, const double w, const double phi):simpleFunctionTime<double>(),_A(A),_w(w),_phi(phi){}; + #ifndef SWIG + virtual ~sinusoidalwithPhaseAngleFunctionTime(){}; + virtual double operator () (double x, double y, double z) const{ + return _A*sin(_w*time+_phi); + }; + #endif // SWIG +}; + //f = A(1-cos(wt)) class cosinusoidalFunctionTime : public simpleFunctionTime<double>{ protected: diff --git a/dG3D/README.txt b/dG3D/README.txt index 89b4b36521a5927217786a965b6bfec0dd31e804..be574cf38c9132b1c0fc1b8e0e254b5f1345eb7d 100644 --- a/dG3D/README.txt +++ b/dG3D/README.txt @@ -44,9 +44,9 @@ git clone https://username@gitlab.onelab.info/cm3/cm3Libraries.git cm3Libraries cd $CM3_DIR/cm3Libraries/dG3D && mkdir release && cd release # configuring -cmake -DCMAKE_BUILD_TYPE=Release \ (ccmake ..) +cmake -DCMAKE_BUILD_TYPE=Release \ -DENABLE_MPI=ON \ --DENABLE_FLTK=OFF \ +-DENABLE_FLTK=ON \ -DENABLE_EIGEN=OFF \ -DENABLE_BLAS_LAPACK=ON \ -DENABLE_PETSC=ON \ @@ -55,6 +55,8 @@ cmake -DCMAKE_BUILD_TYPE=Release \ (ccmake ..) -DPETSC_DIR=$PETSC_DIR \ -DPETSC_ARCH=$PETSC_ARCH .. +otherwise use "ccmake .." and configure manually + # if there are conflicts with python library, include directory # python include dir and library must be found export PYTHON_INCLUDE_DIR=path-to-python-include diff --git a/dG3D/benchmarks/nonLinearTVE_uniaxial/runTVE.py b/dG3D/benchmarks/nonLinearTVE_uniaxial/runTVE.py index 7f23125ba483929747a12350dcb24d4bfcb6aef1..5f68be1b5651b1380a1151508ddfdb1d1b8a390a 100644 --- a/dG3D/benchmarks/nonLinearTVE_uniaxial/runTVE.py +++ b/dG3D/benchmarks/nonLinearTVE_uniaxial/runTVE.py @@ -2,7 +2,7 @@ from gmshpy import * from dG3Dpy import* -#from dG3DpyDebug import* +# from dG3DpyDebug import* from math import* import csv import numpy as np @@ -71,6 +71,7 @@ law1.setTestOption(3) law1.setShiftFactorConstantsWLF(C1,C2) law1.setReferenceTemperature(Tref) law1.setTempFuncOption(0) + law1.setViscoElasticNumberOfElement(N) if N > 0: for i in range(1, N+1): @@ -78,7 +79,7 @@ if N > 0: law1.setTemperatureFunction_ThermalDilationCoefficient(Alpha_tempfunc) law1.setTemperatureFunction_ThermalConductivity(KThCon_tempfunc) -law1.setTemperatureFunction_SpecificHeat(Cp_tempfunc) +# law1.setTemperatureFunction_SpecificHeat(Cp_tempfunc) # geometry geofile = "line.geo" @@ -159,7 +160,7 @@ else: # mysolver.displacementBC("Node",2,0,7e-2*L) mysolver.initialBC("Volume","Position",11,3,Tinitial) fT = LinearFunctionTime(0,Tinitial,ftime,Tinitial); # Linear Displacement with time -# mysolver.displacementBC("Volume",11,3,fT) +mysolver.displacementBC("Volume",11,3,fT) """ mysolver.internalPointBuildView("P_xx",IPField.P_XX, 1, 1) diff --git a/dG3D/benchmarks/nonLinearTVP_cube/cubeTVP.py b/dG3D/benchmarks/nonLinearTVP_cube/cubeTVP.py index d08bc850856e0655378442db67e8a6bd97189f23..c20fae26819beec7b17fe0069c9de5cb11e84eeb 100644 --- a/dG3D/benchmarks/nonLinearTVP_cube/cubeTVP.py +++ b/dG3D/benchmarks/nonLinearTVP_cube/cubeTVP.py @@ -26,16 +26,16 @@ relSpec[0:N+1] *= 1e-6 # convert to MPa # material law lawnum = 11 # unique number of law -E = relSpec[0] #MPa -nu = 0.3 #0.33 +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 = 7850e-9 #905e-12 # Bulk mass 905 kg/m3 -> 905e-12 tonne/mm3 +rho = 7850e-12 #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 + 70 # K +Tinitial = 273.15 + 20 # K C1 = 136.17201827 C2 = 256.58268053 # K @@ -55,30 +55,46 @@ KThCon_R = 1.5*0.12 k_gibson = 3.36435338e-02 m_gibson = 0.0 Tg = Tref -E_tempfunc = GlassTransitionScalarFunction(1, E_R/E_G, Tg, k_gibson, m_gibson, 0) # can't be used Alpha_tempfunc = GlassTransitionScalarFunction(1, Alpha_R/Alpha_G, Tg, k_gibson, m_gibson, 0) Cp_tempfunc = GlassTransitionScalarFunction(1, Cp_R/Cp_G, Tg, k_gibson, m_gibson, 0) KThCon_tempfunc = GlassTransitionScalarFunction(1, KThCon_R/KThCon_G, Tg, k_gibson, m_gibson, 0) ShiftFactor_tempfunc = negExpWLFshiftFactor(C1,C2,Tref) -sy0c = 10. #MPa -hc = 300. +C = 0.0228422 +# sy0c = 6.02534075/0.78 +negExp_tempfunc = negativeExponentialFunction(C,Tref) -sy0t = sy0c*0.78 -ht = 300. +a = -0.9/(90.) +x0 = 273.15-20 +linear_tempfunc = linearScalarFunction(x0,0.9,a) -hardenc = LinearExponentialJ2IsotropicHardening(1, sy0c, hc, 0., 10.) -hardent = LinearExponentialJ2IsotropicHardening(2, sy0t, ht, 0., 10.) +sy0c = 5.75/0.78 #MPa +hc = 30. +sy0t = sy0c*0.78 +ht = 30. + +hardenc = LinearExponentialJ2IsotropicHardening(1, sy0c, hc, 48., 200) +hardent = LinearExponentialJ2IsotropicHardening(2, sy0t, ht, 48., 200) +hardenc.setTemperatureFunction_h1(negExp_tempfunc) +hardenc.setTemperatureFunction_h2(negExp_tempfunc) +# hardenc.setTemperatureFunction_hexp(ShiftFactor_tempfunc) +hardent.setTemperatureFunction_h1(negExp_tempfunc) +hardent.setTemperatureFunction_h2(negExp_tempfunc) +# hardent.setTemperatureFunction_hexp(ShiftFactor_tempfunc) + +# hardenk = exponentialKinematicHardeningLaw(3,10000,100,1000) hardenk = PolynomialKinematicHardening(3,1) -hardenk.setCoefficients(1,370) +hardenk.setCoefficients(1,370.) +hardenk.setCoefficients(2,200.) +# hardenk.setTemperatureFunction_K(negExp_tempfunc) -law1 = NonLinearTVPDG3DMaterialLaw(lawnum,rho,E,nu,1e-6,Tinitial,Alpha,KThCon,Cp) # ,True,1e-8) +# law1 = NonLinearTVEDG3DMaterialLaw(lawnum,rho,E,nu,Tinitial,Alpha,KThCon,Cp) +law1 = NonLinearTVPDG3DMaterialLaw(lawnum,rho,E,nu,1e-6,Tinitial,Alpha,KThCon,Cp) #,True,1e-8) law1.setCompressionHardening(hardenc) law1.setTractionHardening(hardent) law1.setKinematicHardening(hardenk) - law1.setStrainOrder(11) law1.setYieldPowerFactor(3.5) @@ -91,24 +107,27 @@ law1.setShiftFactorConstantsWLF(C1,C2) law1.setReferenceTemperature(Tref) law1.setTempFuncOption(0) + law1.setViscoElasticNumberOfElement(N) if N > 0: for i in range(1, N+1): law1.setViscoElasticData(i, relSpec[i], relSpec[i+N]) + law1.setTemperatureFunction_ThermalDilationCoefficient(Alpha_tempfunc) law1.setTemperatureFunction_ThermalConductivity(KThCon_tempfunc) -law1.setTemperatureFunction_SpecificHeat(Cp_tempfunc) +# law1.setTemperatureFunction_SpecificHeat(Cp_tempfunc) eta = constantViscosityLaw(1,3e4) #(1,3e4) -law1.setViscosityEffect(eta,0.15) # 0.21) +law1.setViscosityEffect(eta,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) +nstep = 1000 # number of step (used only if soltype=1) ftime = 1 # 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) @@ -122,7 +141,8 @@ geofile = "cube.geo" # "line.geo" meshfile = "cube.msh" # "line.msh" nfield = 29 -pertLaw1 = dG3DMaterialLawWithTangentByPerturbation(law1,1e-8*(Tinitial)) # use with _pert*T0 (b/c In tangent_by_perturbation_TVP u use _pert*T0) +pertFactor = 1e-8 #*Tinitial +pertLaw1 = dG3DMaterialLawWithTangentByPerturbation(law1,pertFactor) # use with _pert*T0 (b/c In tangent_by_perturbation_TVP u use _pert*T0) ThermoMechanicsEqRatio = 1.e1 # setConstitutiveExtraDofDiffusionEqRatio(ThermoMechanicsEqRatio); WHAT is this parameter? thermalSource = True mecaSource = True @@ -130,11 +150,12 @@ myfield1 = ThermoMechanicsDG3DDomain(1000,nfield,space1,lawnum,fullDg,ThermoMech myfield1.setConstitutiveExtraDofDiffusionAccountSource(thermalSource,mecaSource) myfield1.stabilityParameters(beta1) myfield1.ThermoMechanicsStabilityParameters(beta1,bool(1)) # Added +# myfield1 = dG3D1DDomain(11,11,space1,lawnum, False) #for non local # creation of Solver mysolver = nonLinearMechSolver(1000) -mysolver.createModel(geofile,meshfile,3,1) +mysolver.createModel(geofile,meshfile,3,2) mysolver.loadModel(meshfile) mysolver.addDomain(myfield1) mysolver.addMaterialLaw(law1) @@ -145,42 +166,36 @@ mysolver.snlData(nstep,ftime,tol) mysolver.stepBetweenArchiving(nstepArch) # BCs -umax = 0.001 +umax = 0.1e-2 fu_L = LinearFunctionTime(0,0,ftime,umax); # Linear Displacement with time -fu_L_2 = LinearFunctionTime(0,0,ftime,2*umax); -fu_L_3 = LinearFunctionTime(0,0,ftime,0.6*umax); -mysolver.displacementBC("Face",30,0,0.) # face x = 0 - Left Face fixed -mysolver.displacementBC("Face",31,0,fu_L) # face x = L - Right Face displaced - compression direction -mysolver.displacementBC("Face",31,1,fu_L_2) -mysolver.displacementBC("Face",31,1,fu_L_3) -mysolver.displacementBC("Face",34,1,0.) # face y = 0 -mysolver.displacementBC("Face",32,2,0.) # face z = 0 +mysolver.displacementBC("Face",30,0,0.) # face x = 0 - Left Face fixed +mysolver.displacementBC("Face",31,0,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) -qmax = 0 #5.19e5 # Heat Flux in kN(ms)⁻¹(mm)⁻¹ [5.19e-1 W/m²] +qmax = 1e+1 #5.19e5 # Heat Flux in kN(ms)⁻¹(mm)⁻¹ [5.19e-1 W/m²] fq_L = LinearFunctionTime(0,0,ftime,qmax); # Linear Flux with time # mysolver.scalarFluxBC("Face",31,3,fq_L) -fT = LinearFunctionTime(0,Tinitial,ftime,70+Tinitial); # Linear Displacement with time -# fT = LinearFunctionTime(0,Tinitial,ftime,Tinitial); # Linear Displacement with time -mysolver.displacementBC("Volume",nfield,3,fT) +# fT = LinearFunctionTime(0,Tinitial,ftime,70+Tinitial); # Linear Displacement with time +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, 1); -mysolver.internalPointBuildView("svm",IPField.SVM, 1, 1) -mysolver.internalPointBuildView("sig_xx",IPField.SIG_XX, 1, 1) -mysolver.internalPointBuildView("sig_yy",IPField.SIG_YY, 1, 1) -mysolver.internalPointBuildView("sig_zz",IPField.SIG_ZZ, 1, 1) -mysolver.internalPointBuildView("sig_xy",IPField.SIG_XY, 1, 1) -mysolver.internalPointBuildView("sig_yz",IPField.SIG_YZ, 1, 1) -mysolver.internalPointBuildView("sig_xz",IPField.SIG_XZ, 1, 1) -mysolver.internalPointBuildView("epl",IPField.PLASTICSTRAIN, 1, 1) -mysolver.internalPointBuildView("temperature",IPField.TEMPERATURE, 1, 1) -mysolver.internalPointBuildView("qx",IPField.THERMALFLUX_X, 1, 1) -mysolver.internalPointBuildView("qy",IPField.THERMALFLUX_Y, 1, 1) -mysolver.internalPointBuildView("qz",IPField.THERMALFLUX_Z, 1, 1) +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("epl",IPField.PLASTICSTRAIN, 1, nstepArch) +mysolver.internalPointBuildView("temperature",IPField.TEMPERATURE, 1, nstepArch) +mysolver.internalPointBuildView("qx",IPField.THERMALFLUX_X, 1, nstepArch) +mysolver.internalPointBuildView("qy",IPField.THERMALFLUX_Y, 1, nstepArch) +mysolver.internalPointBuildView("qz",IPField.THERMALFLUX_Z, 1, nstepArch) # Print/Archive History Outputs diff --git a/dG3D/benchmarks/nonLinearTVP_uniaxial/runTVP.py b/dG3D/benchmarks/nonLinearTVP_uniaxial/runTVP.py index 9d739b6f2310d7c14911c6bbb8e6302f56f145d2..67b08e6cb70004201861a73d0dad108e515341fb 100644 --- a/dG3D/benchmarks/nonLinearTVP_uniaxial/runTVP.py +++ b/dG3D/benchmarks/nonLinearTVP_uniaxial/runTVP.py @@ -245,4 +245,4 @@ mysolver.archivingAverageValue(IPField.F_XX) mysolver.solve() check = TestCheck() -check.equal(-3.089706e+01,mysolver.getArchivedForceOnPhysicalGroup("Node", 1, 0),1.e-4) +check.equal(-3.093203e+01,mysolver.getArchivedForceOnPhysicalGroup("Node", 1, 0),1.e-4) diff --git a/dG3D/benchmarks/powerYieldViscoElastoPlastic/cylinder.py b/dG3D/benchmarks/powerYieldViscoElastoPlastic/cylinder.py index 235e187dae9ecefbd17d88bfec3a716d21e51a8a..be503f1fb1a242c7d61ce258ba3ce1f025ad52d3 100644 --- a/dG3D/benchmarks/powerYieldViscoElastoPlastic/cylinder.py +++ b/dG3D/benchmarks/powerYieldViscoElastoPlastic/cylinder.py @@ -2,6 +2,7 @@ from gmshpy import * from dG3Dpy import* +# from dG3DpyDebug import* from math import* #script to launch PBC problem with a python script @@ -95,7 +96,7 @@ mysolver.displacementBC('Face',4,0,0.) mysolver.displacementBC('Face',1,0,0) mysolver.displacementBC('Face',1,1,0) -mysolver.displacementBC('Face',2,2,1.) +mysolver.displacementBC('Face',2,2,10.) # build view mysolver.internalPointBuildView("Strain_xx",IPField.STRAIN_XX, 1, 1); diff --git a/dG3D/src/dG3DIPVariable.cpp b/dG3D/src/dG3DIPVariable.cpp index e70aeb7737e9a65502beffa03e1032a7e09d5342..9bb8fff93510130c1ef56e3152685b1d852d9223 100644 --- a/dG3D/src/dG3DIPVariable.cpp +++ b/dG3D/src/dG3DIPVariable.cpp @@ -2359,6 +2359,8 @@ double HyperViscoElasticdG3DIPVariable::get(const int i) const { return _ipViscoElastic->_Ee(2,2); } + else if (i == IPField::hyperElastic_BulkScalar){return _ipViscoElastic->getConstRefToElasticBulkPropertyScaleFactor();} + else if (i == IPField::hyperElastic_ShearScalar){return _ipViscoElastic->getConstRefToElasticShearPropertyScaleFactor();} else if (i == IPField::Eve1_XX) { if (_ipViscoElastic->_A.size() > 0) @@ -2432,6 +2434,30 @@ double HyperViscoElasticdG3DIPVariable::get(const int i) const return _ipViscoElastic->_A[1](2,2) + _ipViscoElastic->_B[1]/3.; else return 0.; } + else if (i == IPField::corKir_XX) + { + return _ipViscoElastic->_kirchhoff(0,0); + } + else if (i == IPField::corKir_XY) + { + return _ipViscoElastic->_kirchhoff(0,1); + } + else if (i == IPField::corKir_XZ) + { + return _ipViscoElastic->_kirchhoff(0,2); + } + 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 { return dG3DIPVariable::get(i); @@ -2508,6 +2534,8 @@ double HyperViscoElastoPlasticdG3DIPVariable::get(const int comp) const { return _ipViscoElastoPlastic->_Ee(2,2); } + else if (comp == IPField::hyperElastic_BulkScalar){return _ipViscoElastoPlastic->getConstRefToElasticBulkPropertyScaleFactor();} + else if (comp == IPField::hyperElastic_ShearScalar){return _ipViscoElastoPlastic->getConstRefToElasticShearPropertyScaleFactor();} else if (comp == IPField::Eve1_XX) { if (_ipViscoElastoPlastic->_A.size() >0) @@ -2580,6 +2608,30 @@ double HyperViscoElastoPlasticdG3DIPVariable::get(const int comp) const return _ipViscoElastoPlastic->_A[1](2,2) + _ipViscoElastoPlastic->_B[1]/3.; else return 0.; } + else if (comp == IPField::corKir_XX) + { + return _ipViscoElastoPlastic->_kirchhoff(0,0); + } + else if (comp == IPField::corKir_XY) + { + return _ipViscoElastoPlastic->_kirchhoff(0,1); + } + else if (comp == IPField::corKir_XZ) + { + return _ipViscoElastoPlastic->_kirchhoff(0,2); + } + else if (comp == IPField::corKir_YY) + { + return _ipViscoElastoPlastic->_kirchhoff(1,1); + } + else if (comp == IPField::corKir_YZ) + { + return _ipViscoElastoPlastic->_kirchhoff(1,2); + } + else if (comp == IPField::corKir_ZZ) + { + return _ipViscoElastoPlastic->_kirchhoff(2,2); + } else if(comp == IPField::PLASTICSTRAIN) { return _ipViscoElastoPlastic->getConstRefToEqPlasticStrain(); @@ -5672,7 +5724,8 @@ NonLinearTVEDG3DIPVariable::NonLinearTVEDG3DIPVariable(const mlawNonLinearTVE& v _ipViscoElastic = new IPNonLinearTVE(viscoLaw.getConstRefToCompressionHardening(), viscoLaw.getConstRefToTractionHardening(), viscoLaw.getConstRefToKinematicHardening(), - viscoLaw.getViscoElasticNumberOfElement()); + viscoLaw.getViscoElasticNumberOfElement(), + viscoLaw.getConstRefToMullinsEffect()); this->getRefToTemperature()=Tinitial; }; @@ -5741,6 +5794,27 @@ double NonLinearTVEDG3DIPVariable::get(const int i) const{ else if (i == IPField::Ee_YY){return _ipViscoElastic->_Ee(1,1);} else if (i == IPField::Ee_YZ){return _ipViscoElastic->_Ee(1,2);} else if (i == IPField::Ee_ZZ){return _ipViscoElastic->_Ee(2,2);} + else if (i == IPField::corKir_XX){return _ipViscoElastic->_kirchhoff(0,0);} + else if (i == IPField::corKir_XY){return _ipViscoElastic->_kirchhoff(0,1);} + else if (i == IPField::corKir_XZ){return _ipViscoElastic->_kirchhoff(0,2);} + 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::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);} + else if (i == IPField::corKirExtra_XY){return _ipViscoElastic->_corKirExtra(0,1);} + else if (i == IPField::corKirExtra_XZ){return _ipViscoElastic->_corKirExtra(0,2);} + else if (i == IPField::corKirExtra_YY){return _ipViscoElastic->_corKirExtra(1,1);} + else if (i == IPField::corKirExtra_YZ){return _ipViscoElastic->_corKirExtra(1,2);} + else if (i == IPField::corKirExtra_ZZ){return _ipViscoElastic->_corKirExtra(2,2);} + else if (i == IPField::Tr_corKir_Inf){return _ipViscoElastic->_trCorKirinf_TVE;} + else if (i == IPField::Dev_corKir_Inf_XX){return _ipViscoElastic->_devCorKirinf_TVE(0,0);} + else if (i == IPField::Dev_corKir_Inf_XY){return _ipViscoElastic->_devCorKirinf_TVE(0,1);} + else if (i == IPField::Dev_corKir_Inf_XZ){return _ipViscoElastic->_devCorKirinf_TVE(0,2);} + else if (i == IPField::Dev_corKir_Inf_YY){return _ipViscoElastic->_devCorKirinf_TVE(1,1);} + else if (i == IPField::Dev_corKir_Inf_YZ){return _ipViscoElastic->_devCorKirinf_TVE(1,2);} + else if (i == IPField::Dev_corKir_Inf_ZZ){return _ipViscoElastic->_devCorKirinf_TVE(2,2);} else if (i == IPField::Eve1_XX){ if (_ipViscoElastic->_A.size() > 0) return _ipViscoElastic->_A[0](0,0) + _ipViscoElastic->_B[0]/3.; @@ -5810,6 +5884,18 @@ double NonLinearTVEDG3DIPVariable::get(const int i) const{ else if (i == IPField::THERMALFLUX_Z){return getConstRefToFlux()[0](2);} else if (i == IPField::FIELD_SOURCE){return getConstRefToFieldSource()(0);} else if (i == IPField::MECHANICAL_SOURCE){return getConstRefToMechanicalSource()(0);} + else if (i == IPField::DEFO_ENERGY) + { + return _ipViscoElastic->_elasticEnergy; + } + else if (i == IPField::MAX_DEFO_ENERGY) + { + return _ipViscoElastic->_psiMax; + } + else if (i == IPField::MULLINS_DAMAGE) + { + return _ipViscoElastic->_mullinsDamage; + } else { @@ -5846,7 +5932,8 @@ NonLinearTVPDG3DIPVariable::NonLinearTVPDG3DIPVariable(const mlawNonLinearTVP& v _ipViscoElastoPlastic = new IPNonLinearTVP(viscoEPLaw.getConstRefToCompressionHardening(), viscoEPLaw.getConstRefToTractionHardening(), viscoEPLaw.getConstRefToKinematicHardening(), - viscoEPLaw.getViscoElasticNumberOfElement()); + viscoEPLaw.getViscoElasticNumberOfElement(), + viscoEPLaw.getConstRefToMullinsEffect()); this->getRefToTemperature()=Tinitial; }; @@ -5886,6 +5973,27 @@ double NonLinearTVPDG3DIPVariable::get(const int i) const{ else if (i == IPField::Ee_YY){return _ipViscoElastoPlastic->_Ee(1,1);} else if (i == IPField::Ee_YZ){return _ipViscoElastoPlastic->_Ee(1,2);} else if (i == IPField::Ee_ZZ){return _ipViscoElastoPlastic->_Ee(2,2);} + else if (i == IPField::corKir_XX){return _ipViscoElastoPlastic->_kirchhoff(0,0);} + else if (i == IPField::corKir_XY){return _ipViscoElastoPlastic->_kirchhoff(0,1);} + else if (i == IPField::corKir_XZ){return _ipViscoElastoPlastic->_kirchhoff(0,2);} + 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::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);} + else if (i == IPField::corKirExtra_XY){return _ipViscoElastoPlastic->_corKirExtra(0,1);} + else if (i == IPField::corKirExtra_XZ){return _ipViscoElastoPlastic->_corKirExtra(0,2);} + else if (i == IPField::corKirExtra_YY){return _ipViscoElastoPlastic->_corKirExtra(1,1);} + else if (i == IPField::corKirExtra_YZ){return _ipViscoElastoPlastic->_corKirExtra(1,2);} + else if (i == IPField::corKirExtra_ZZ){return _ipViscoElastoPlastic->_corKirExtra(2,2);} + else if (i == IPField::Tr_corKir_Inf){return _ipViscoElastoPlastic->_trCorKirinf_TVE;} + else if (i == IPField::Dev_corKir_Inf_XX){return _ipViscoElastoPlastic->_devCorKirinf_TVE(0,0);} + else if (i == IPField::Dev_corKir_Inf_XY){return _ipViscoElastoPlastic->_devCorKirinf_TVE(0,1);} + else if (i == IPField::Dev_corKir_Inf_XZ){return _ipViscoElastoPlastic->_devCorKirinf_TVE(0,2);} + else if (i == IPField::Dev_corKir_Inf_YY){return _ipViscoElastoPlastic->_devCorKirinf_TVE(1,1);} + else if (i == IPField::Dev_corKir_Inf_YZ){return _ipViscoElastoPlastic->_devCorKirinf_TVE(1,2);} + else if (i == IPField::Dev_corKir_Inf_ZZ){return _ipViscoElastoPlastic->_devCorKirinf_TVE(2,2);} else if (i == IPField::Eve1_XX){ if (_ipViscoElastoPlastic->_A.size() > 0) return _ipViscoElastoPlastic->_A[0](0,0) + _ipViscoElastoPlastic->_B[0]/3.; @@ -6011,7 +6119,18 @@ double NonLinearTVPDG3DIPVariable::get(const int i) const{ { return _ipViscoElastoPlastic->getConstRefToKinematicHardening().getR(); } - + else if (i == IPField::DEFO_ENERGY) + { + return _ipViscoElastoPlastic->_elasticEnergy; + } + else if (i == IPField::MAX_DEFO_ENERGY) + { + return _ipViscoElastoPlastic->_psiMax; + } + else if (i == IPField::MULLINS_DAMAGE) + { + return _ipViscoElastoPlastic->_mullinsDamage; + } else { return dG3DIPVariable::get(i); diff --git a/dG3D/src/dG3DMaterialLaw.cpp b/dG3D/src/dG3DMaterialLaw.cpp index 4cd09386362101060a703d602e19d0764ecb777e..f2aa0c7900b3a1e0b08a5aba9d510f08f8e0b8bf 100644 --- a/dG3D/src/dG3DMaterialLaw.cpp +++ b/dG3D/src/dG3DMaterialLaw.cpp @@ -246,7 +246,7 @@ void dG3DMaterialLawWithTangentByPerturbation::stress(IPVariable* ipv, const IPV _stressLaw->stress(ipvcur,ipvprev,false,checkfrac,dTangent); -#if 0 +#if 1 _stressLaw->stress(ipvcur,ipvprev,true,checkfrac,dTangent); ipvcur->getConstRefToDeformationGradient().print("F Analytique"); // FLE ipvcur->getConstRefToFirstPiolaKirchhoffStress().print("P Analytique"); // FLE @@ -288,6 +288,7 @@ void dG3DMaterialLawWithTangentByPerturbation::stress(IPVariable* ipv, const IPV Msg::Info("dEMFieldSource dp Analytique: %e",ipvcur->getConstRefTodEMFieldSourcedNonLocalVariable()(j,i)); } } + /* for (int i=0; i< numExtraDof; i++) { Msg::Info("Field Analytique: %e",ipvcur->getConstRefToField(i)); // FLE @@ -298,8 +299,9 @@ void dG3DMaterialLawWithTangentByPerturbation::stress(IPVariable* ipv, const IPV ipvcur->getConstRefTodFieldSourcedF()[i].print("d Field source dF Analytique"); ipvcur->getConstRefTodMechanicalSourcedF()[i].print("d Mechanical source dF Analytique"); ipvcur->getConstRefTodPdField()[i].print("dP d Field Analytique"); - ipvcur->getConstRefTodEMFieldSourcedF()[i].print("dEMFieldSource dF Analytique"); - + // ipvcur->getConstRefTodEMFieldSourcedF()[i].print("dEMFieldSource dF Analytique"); + + for (int k=0; k< numExtraDof; k++) { ipvcur->getConstRefTodFluxdField()[k][i].print("dFludx dField Analytique"); @@ -308,11 +310,11 @@ void dG3DMaterialLawWithTangentByPerturbation::stress(IPVariable* ipv, const IPV ipvcur->getConstRefTodFluxdGradField()[k][i].print("d Flux d GradField Analytique"); Msg::Info("d thermal source d Grad field Analytique: %e",ipvcur->getConstRefTodFieldSourcedGradField()[k][i]); Msg::Info("d thermal source d Grad field Analytique: %e",ipvcur->getRefTodMechanicalSourcedGradField()[k][i]); - Msg::Info("dEMFieldSource dField Analytique: %e",ipvcur->getConstRefTodEMFieldSourcedField()(k,i)); - ipvcur->getConstRefTodEMFieldSourcedGradField()[k][i].print("dEMFieldSource dGradField Analytique"); + // Msg::Info("dEMFieldSource dField Analytique: %e",ipvcur->getConstRefTodEMFieldSourcedField()(k,i)); + // ipvcur->getConstRefTodEMFieldSourcedGradField()[k][i].print("dEMFieldSource dGradField Analytique"); } - for (unsigned int k = 0; k < numCurlDof; ++k) + /*for (unsigned int k = 0; k < numCurlDof; ++k) { ipvcur->getConstRefTodFluxdVectorPotential()[i][k].print("dFlux dMagneticVectorPotential Analytique"); ipvcur->getConstRefTodFluxdVectorCurl()[i][k].print("dFlux dMagneticVectorCurl Analytique"); @@ -328,7 +330,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"); @@ -614,7 +616,7 @@ void dG3DMaterialLawWithTangentByPerturbation::stress(IPVariable* ipv, const IPV } } -#if 0 +#if 1 ipvcur->getConstRefToDeformationGradient().print("F Numerique"); // FLE ipvcur->getConstRefToFirstPiolaKirchhoffStress().print("P Numerique"); // FLE ipvcur->getConstRefToTangentModuli().print("dPdE Numerique"); @@ -653,7 +655,8 @@ void dG3DMaterialLawWithTangentByPerturbation::stress(IPVariable* ipv, const IPV Msg::Info("dEMFieldSource dp Numerique: %e",ipvcur->getConstRefTodEMFieldSourcedNonLocalVariable()(j,i)); } } - for (int i=0; i< numExtraDof; i++) + + /*for (int i=0; i< numExtraDof; i++) { Msg::Info("Field Numerique: %e",ipvcur->getConstRefToField(i)); // FLE ipvcur->getConstRefToFlux()[i].print("Flux Numerique"); // FLE @@ -663,7 +666,8 @@ void dG3DMaterialLawWithTangentByPerturbation::stress(IPVariable* ipv, const IPV ipvcur->getConstRefTodFieldSourcedF()[i].print("d Field source dF Numerique"); ipvcur->getConstRefTodMechanicalSourcedF()[i].print("d Mechanical source dF Numerique"); ipvcur->getConstRefTodPdField()[i].print("dP d Field Numerique"); - ipvcur->getConstRefTodEMFieldSourcedF()[i].print("dEMFieldSource dF Numerique"); + // ipvcur->getConstRefTodEMFieldSourcedF()[i].print("dEMFieldSource dF Numerique"); + for (int k=0; k< numExtraDof; k++) { ipvcur->getConstRefTodFluxdField()[k][i].print("dFludx dField Numerique"); @@ -672,11 +676,10 @@ void dG3DMaterialLawWithTangentByPerturbation::stress(IPVariable* ipv, const IPV ipvcur->getConstRefTodFluxdGradField()[k][i].print("d Flux d GradField Numerique"); Msg::Info("d thermal source d Grad field Numerique: %e",ipvcur->getConstRefTodFieldSourcedGradField()[k][i]); Msg::Info("d thermal source d Grad field Numerique: %e",ipvcur->getRefTodMechanicalSourcedGradField()[k][i]); - - Msg::Info("dEMFieldSource dField Numerique: %e",ipvcur->getConstRefTodEMFieldSourcedField()(k,i)); - ipvcur->getConstRefTodEMFieldSourcedGradField()[k][i].print("dEMFieldSource dGradField Numerique"); + // Msg::Info("dEMFieldSource dField Numerique: %e",ipvcur->getConstRefTodEMFieldSourcedField()(k,i)); + // ipvcur->getConstRefTodEMFieldSourcedGradField()[k][i].print("dEMFieldSource dGradField Numerique"); } - + /* for (unsigned int k = 0; k < numCurlDof; ++k) { ipvcur->getConstRefTodFluxdVectorPotential()[i][k].print("dFlux dMagneticVectorPotential Numerique"); @@ -693,7 +696,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 @@ -9447,6 +9450,9 @@ void NonLinearTVEDG3DMaterialLaw::setTemperatureFunction_ThermalConductivity(con void NonLinearTVEDG3DMaterialLaw::setTemperatureFunction_SpecificHeat(const scalarFunction& Tfunc){ _viscoLaw.setTemperatureFunction_SpecificHeat(Tfunc); }; +void NonLinearTVEDG3DMaterialLaw::setTemperatureFunction_ElasticCorrection(const scalarFunction& Tfunc){ + _viscoLaw.setTemperatureFunction_ElasticCorrection(Tfunc); +}; void NonLinearTVEDG3DMaterialLaw::setTemperatureFunction_BranchBulkModuli(const scalarFunction& Tfunc, int i){ _viscoLaw.setTemperatureFunction_BranchBulkModuli(Tfunc,i); }; @@ -9456,6 +9462,15 @@ void NonLinearTVEDG3DMaterialLaw::setTemperatureFunction_BranchShearModuli(const void NonLinearTVEDG3DMaterialLaw::setTemperatureFunction_BranchThermalDilationCoefficient(const scalarFunction& Tfunc, int i){ _viscoLaw.setTemperatureFunction_BranchThermalDilationCoefficient(Tfunc,i); }; +void NonLinearTVEDG3DMaterialLaw::setMullinsEffect(const mullinsEffect& mullins){ + _viscoLaw.setMullinsEffect(mullins); +}; +void NonLinearTVEDG3DMaterialLaw::useExtraBranchBool(const bool useExtraBranch){ + _viscoLaw.useExtraBranchBool(useExtraBranch); +}; +void NonLinearTVEDG3DMaterialLaw::setVolumeCorrection(double _vc, double _xivc, double _zetavc, double _dc, double _thetadc, double _pidc){ + _viscoLaw.setVolumeCorrection(_vc,_xivc,_zetavc,_dc,_thetadc,_pidc); +}; // Added extra argument in the NonLinearTVEDG3DIPVariable contructor - Tinitial (added from LinearThermoMech) void NonLinearTVEDG3DMaterialLaw::createIPState(IPStateBase* &ips, bool hasBodyForce, const bool* state_,const MElement *ele, const int nbFF_, const IntPt *GP, const int gpt) const @@ -9632,6 +9647,12 @@ void NonLinearTVPDG3DMaterialLaw::setViscoElasticData(const std::string filename void NonLinearTVPDG3DMaterialLaw::setIsotropicHardeningCoefficients(const double HR1, const double HR2, const double HR3){ _viscoLaw.setIsotropicHardeningCoefficients(HR1,HR2,HR3); }; +void NonLinearTVPDG3DMaterialLaw::setPolynomialOrderChabocheCoeffs(const int order){ + _viscoLaw.setPolynomialOrderChabocheCoeffs(order); +}; +void NonLinearTVPDG3DMaterialLaw::setPolynomialCoeffsChabocheCoeffs(const int i, const double val){ + _viscoLaw.setPolynomialCoeffsChabocheCoeffs(i,val); +}; void NonLinearTVPDG3DMaterialLaw::setReferenceTemperature(const double Tref){ _viscoLaw.setReferenceTemperature(Tref); @@ -9663,6 +9684,9 @@ void NonLinearTVPDG3DMaterialLaw::setTemperatureFunction_ThermalConductivity(con void NonLinearTVPDG3DMaterialLaw::setTemperatureFunction_SpecificHeat(const scalarFunction& Tfunc){ _viscoLaw.setTemperatureFunction_SpecificHeat(Tfunc); }; +void NonLinearTVPDG3DMaterialLaw::setTemperatureFunction_ElasticCorrection(const scalarFunction& Tfunc){ + _viscoLaw.setTemperatureFunction_ElasticCorrection(Tfunc); +}; void NonLinearTVPDG3DMaterialLaw::setTemperatureFunction_BranchBulkModuli(const scalarFunction& Tfunc, int i){ _viscoLaw.setTemperatureFunction_BranchBulkModuli(Tfunc,i); }; @@ -9685,6 +9709,9 @@ void NonLinearTVPDG3DMaterialLaw::setKinematicHardening(const kinematicHardening void NonLinearTVPDG3DMaterialLaw::setViscosityEffect(const viscosityLaw& v, const double p){ _viscoLaw.setViscosityEffect(v,p); }; +void NonLinearTVPDG3DMaterialLaw::setMullinsEffect(const mullinsEffect& mullins){ + _viscoLaw.setMullinsEffect(mullins); +}; void NonLinearTVPDG3DMaterialLaw::setYieldPowerFactor(const double n){ _viscoLaw.setPowerFactor(n); @@ -9699,8 +9726,8 @@ void NonLinearTVPDG3DMaterialLaw::setNonAssociatedFlow(const bool flag){ _viscoLaw.setNonAssociatedFlow(flag); }; -void NonLinearTVPDG3DMaterialLaw::setTaylorQuineyFactor(const double f){ - _viscoLaw.setTaylorQuineyFactor(f); +void NonLinearTVPDG3DMaterialLaw::setTaylorQuineyFactor(const double f, const bool flag){ + _viscoLaw.setTaylorQuineyFactor(f, flag); }; void NonLinearTVPDG3DMaterialLaw::setTemperatureFunction_InitialYieldStress(const scalarFunction& Tfunc){ _viscoLaw.setTemperatureFunction_InitialYieldStress(Tfunc); @@ -9714,6 +9741,13 @@ void NonLinearTVPDG3DMaterialLaw::setTemperatureFunction_KinematicHardening(cons void NonLinearTVPDG3DMaterialLaw::setTemperatureFunction_Viscosity(const scalarFunction& Tfunc){ _viscoLaw.setTemperatureFunction_Viscosity(Tfunc); }; +void NonLinearTVPDG3DMaterialLaw::useExtraBranchBool(const bool useExtraBranch){ + _viscoLaw.useExtraBranchBool(useExtraBranch); +}; +void NonLinearTVPDG3DMaterialLaw::setVolumeCorrection(double _vc, double _xivc, double _zetavc, double _dc, double _thetadc, double _pidc){ + _viscoLaw.setVolumeCorrection(_vc,_xivc,_zetavc,_dc,_thetadc,_pidc); +}; + // Added extra argument in the NonLinearTVEDG3DIPVariable contructor - Tinitial (added from LinearThermoMech) void NonLinearTVPDG3DMaterialLaw::createIPState(IPStateBase* &ips, bool hasBodyForce, const bool* state_,const MElement *ele, const int nbFF_, const IntPt *GP, const int gpt) const diff --git a/dG3D/src/dG3DMaterialLaw.h b/dG3D/src/dG3DMaterialLaw.h index f4898ebee8f81f60a19531c141e5fab440a2edd8..8ba7f7a811c68766aab277f03e5bb7f2cfd7fcee 100644 --- a/dG3D/src/dG3DMaterialLaw.h +++ b/dG3D/src/dG3DMaterialLaw.h @@ -56,6 +56,7 @@ #include "mlawNonLinearTVM.h" #include "mlawNonLinearTVE.h" #include "mlawNonLinearTVP.h" +#include "mullinsEffect.h" #endif #if defined(HAVE_TORCH) #include <torch/torch.h> @@ -3167,20 +3168,25 @@ class NonLinearTVEDG3DMaterialLaw : public dG3DMaterialLaw{ // public Material 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 setVolumeCorrection(double _vc, double _xivc, double _zetavc, double _dc, double _thetadc, double _pidc); 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 useExtraBranchBool(const bool useExtraBranch); 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(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 setMullinsEffect(const mullinsEffect& mullins); // For now use these Scalars - Fix by directly adding to constructor /* void setThermalExpansionCoefficient(const double Alpha); // Fix this - for both scalar and tensor @@ -3255,6 +3261,8 @@ class NonLinearTVPDG3DMaterialLaw : public dG3DMaterialLaw{ // public Material 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); @@ -3266,21 +3274,25 @@ class NonLinearTVPDG3DMaterialLaw : public dG3DMaterialLaw{ // public Material void setTemperatureFunction_ThermalDilationCoefficient(const scalarFunction& Tfunc); void setTemperatureFunction_ThermalConductivity(const scalarFunction& Tfunc); void setTemperatureFunction_SpecificHeat(const scalarFunction& Tfunc); + void setTemperatureFunction_ElasticCorrection(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 setVolumeCorrection(double _vc, double _xivc, double _zetavc, double _dc, double _thetadc, double _pidc); 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); + 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);