From 9ccf290f997da49e390529d5d3008b3fb006acfd Mon Sep 17 00:00:00 2001
From: FLE_Knight <ujwalkishore.jinaga@mail.polimi.it>
Date: Thu, 5 Dec 2024 10:21:21 +0100
Subject: [PATCH 01/19] Added 1 modified class for tempGrad derivatives in
 Network Interactions, working on Interaction Mechanisms. Added ref and
 constRef functions in ipFiniteStrain.h

---
 .../internalPoints/ipFiniteStrain.h           |  53 ++++++
 .../modelReduction/NetworkInteraction.cpp     | 142 ++++++++++++++++
 .../modelReduction/NetworkInteraction.h       | 160 +++++++++++++++++-
 3 files changed, 354 insertions(+), 1 deletion(-)

diff --git a/NonLinearSolver/internalPoints/ipFiniteStrain.h b/NonLinearSolver/internalPoints/ipFiniteStrain.h
index b5dc338a7..a09d0cc17 100644
--- a/NonLinearSolver/internalPoints/ipFiniteStrain.h
+++ b/NonLinearSolver/internalPoints/ipFiniteStrain.h
@@ -76,6 +76,59 @@ class ipFiniteStrain : public IPVariableMechanics{
     virtual const SVector3 &getConstRefToJump() const=0;
     virtual SVector3 &getRefToJump()=0;
 
+    // FLE
+    //extraDof
+    virtual int getNumConstitutiveExtraDofDiffusionVariable() const=0;
+    virtual double getConstRefToField(const int idex) const=0;
+    virtual double  &getRefToField(const int idex)=0;
+    virtual const std::vector<SVector3>  &getConstRefToGradField() const=0;
+    virtual std::vector<SVector3>  &getRefToGradField()=0;
+    virtual const std::vector<SVector3>  &getConstRefToFlux() const=0;
+    virtual std::vector<SVector3>  &getRefToFlux()=0;
+
+    virtual const std::vector<STensor3>  &getConstRefTodPdField() const=0;
+    virtual std::vector<STensor3>  &getRefTodPdField()=0;
+    virtual const std::vector<STensor33>  &getConstRefTodPdGradField() const=0;
+    virtual std::vector<STensor33>  &getRefTodPdGradField()=0;
+    virtual const std::vector<std::vector<STensor3> >  &getConstRefTodFluxdGradField() const=0;
+    virtual std::vector<std::vector<STensor3> >  &getRefTodFluxdGradField()=0;
+    virtual const std::vector<std::vector<SVector3> >  &getConstRefTodFluxdField() const=0;
+    virtual std::vector<std::vector<SVector3> >  &getRefTodFluxdField()=0;
+    virtual const std::vector<STensor33>  &getConstRefTodFluxdF() const=0;
+    virtual std::vector<STensor33>   &getRefTodFluxdF()=0;
+
+    virtual const std::vector<std::vector<const STensor3*> > &getConstRefToLinearK() const =0;
+    virtual void setConstRefToLinearK(const STensor3 &eT, int i, int j) =0;
+    virtual const std::vector<std::vector<std::vector<STensor3> > >  &getConstRefTodLinearKdField() const=0;
+    virtual std::vector<std::vector<std::vector<STensor3> > >  &getRefTodLinearKdField()=0;
+    virtual const std::vector< std::vector<STensor43> >  &getConstRefTodLinearKdF() const=0;
+    virtual std::vector< std::vector<STensor43> >  &getRefTodLinearKdF()=0;
+
+    virtual const std::vector< std::vector<STensor43> >  &getConstRefTodFluxdGradFielddF() const=0;
+    virtual std::vector<std::vector<STensor43> >  &getRefTodFluxdGradFielddF()=0;
+    virtual const std::vector<std::vector<std::vector<STensor3> > >  &getConstRefTodFluxdGradFielddField() const=0;
+    virtual std::vector<std::vector<std::vector<STensor3> > >  &getRefTodFluxdGradFielddField()=0;
+    virtual const fullVector<double>  &getConstRefToFieldSource() const=0;
+    virtual fullVector<double>  &getRefToFieldSource()=0;
+    virtual const fullMatrix<double>  &getConstRefTodFieldSourcedField() const=0;
+    virtual fullMatrix<double>  &getRefTodFieldSourcedField()=0;
+    virtual const std::vector<std::vector<SVector3> >  &getConstRefTodFieldSourcedGradField() const=0;
+    virtual std::vector<std::vector<SVector3> >  &getRefTodFieldSourcedGradField()=0;
+    virtual const std::vector<STensor3>  &getConstRefTodFieldSourcedF() const=0;
+    virtual std::vector<STensor3>  &getRefTodFieldSourcedF()=0;
+    virtual const fullVector<double>  &getConstRefToMechanicalSource() const=0;
+    virtual fullVector<double>  &getRefToMechanicalSource()=0;
+    virtual const fullMatrix<double>  &getConstRefTodMechanicalSourcedField() const=0;
+    virtual fullMatrix<double>  &getRefTodMechanicalSourcedField()=0;
+    virtual const std::vector<std::vector<SVector3> >  &getConstRefTodMechanicalSourcedGradField() const=0;
+    virtual std::vector<std::vector<SVector3> >  &getRefTodMechanicalSourcedGradField()=0;
+    virtual const std::vector<STensor3>  &getConstRefTodMechanicalSourcedF() const=0;
+    virtual std::vector<STensor3>  &getRefTodMechanicalSourcedF()=0;
+
+    virtual const fullVector<double>  &getConstRefToExtraDofFieldCapacityPerUnitField() const=0;
+    virtual fullVector<double>  &getRefToExtraDofFieldCapacityPerUnitField()=0;
+    // FLE
+    
     virtual bool hasBodyForceForHO() const =0;
     virtual const STensor33 &getConstRefToGM()const=0;
     virtual STensor33 &getRefToGM()=0;
diff --git a/NonLinearSolver/modelReduction/NetworkInteraction.cpp b/NonLinearSolver/modelReduction/NetworkInteraction.cpp
index dcfc63fc2..755d286b0 100644
--- a/NonLinearSolver/modelReduction/NetworkInteraction.cpp
+++ b/NonLinearSolver/modelReduction/NetworkInteraction.cpp
@@ -408,6 +408,148 @@ void InteractionMechanism::getDInducedStrainDCoefficient(int nodeId, STensor3& D
 };
 
 
+// FLE
+const double& InteractionMechanismExtraDOF::getConstRefToIncompatibleExtraDOF(const IPStateBase::whichState ws) const
+{
+  if (ws == IPStateBase::current)
+  {
+    return tcur;
+  }
+  else if (ws == IPStateBase::previous)
+  {
+    return tprev;
+  }
+  else if (ws == IPStateBase::initial)
+  {
+    return tinit;
+  }
+  else
+  {
+    Msg::Error("state %s has not been defined in InteractionMechanism::getConstRefToIncompatibleExtraDOF",ws);
+    Msg::Exit(0);
+  }
+};
+
+double& InteractionMechanismExtraDOF::getRefToIncompatibleExtraDOF(const IPStateBase::whichState ws)
+{
+  if (ws == IPStateBase::current)
+  {
+    return tcur;
+  }
+  else if (ws == IPStateBase::previous)
+  {
+    return tprev;
+  }
+  else if (ws == IPStateBase::initial)
+  {
+    return tinit;
+  }
+  else
+  {
+    Msg::Error("state %s has not been defined in InteractionMechanism::getRefToIncompatibleExtraDOF",ws);
+    Msg::Exit(0);
+  }
+};
+
+void InteractionMechanismExtraDOF::resetIncompatibleExtraDOF()
+{
+  tcur = 0.; tprev = 0.; tinit = 0.;
+};
+
+void InteractionMechanismExtraDOF::nextStepExtraDOF()
+{
+  tprev = tcur;
+};
+void InteractionMechanismExtraDOF::resetToPreviousStepExtraDOF()
+{
+  tcur = tprev;
+};
+
+void InteractionMechanismExtraDOF::copyExtraDOF(const IPStateBase::whichState ws1, const IPStateBase::whichState ws2)
+{
+  getRefToIncompatibleExtraDOF(ws2) = getRefToIncompatibleExtraDOF(ws1);
+};
+
+void InteractionMechanismExtraDOF::getInducedExtraDOFGrad(int nodeId, SVector3& Hi) const
+{
+  std::map<int,double>::const_iterator itF = coefficients.find(nodeId);
+  if (itF != coefficients.end())
+  {
+    static SVector3 direction;
+    getDirection(direction);
+    double alpha = itF->second;
+    for (int i=0; i<3; i++)
+    {
+        Hi(i) = alpha*tcur*direction(i);
+    }
+  }
+  else
+  {
+    Hi = 0.;
+  }
+};
+
+void InteractionMechanismExtraDOF::getDInducedExtraDOFGradDa(int nodeId, SVector3& DHiDt) const
+{
+  std::map<int,double>::const_iterator itF = coefficients.find(nodeId);
+  if (itF != coefficients.end())
+  {
+    static SVector3 direction;
+    getDirection(direction);
+    double alpha = itF->second;
+    for (int r=0; r<3; r++)
+    {
+      DHiDt(r) = direction(r)*alpha;
+    }
+  }
+  else
+  {
+    DHiDt = 0.;
+  }
+};
+
+void InteractionMechanismExtraDOF::getDInducedExtraDOFGradDDirection(int nodeId, STensor3& DHiDdir) const
+{
+  std::map<int,double>::const_iterator itF = coefficients.find(nodeId);
+  if (itF != coefficients.end())
+  {
+    static STensor3 I(1.);
+    double alpha = itF->second;
+    for (int r=0; r<3; r++)
+    {
+      for (int c=0; c<3; c++)
+      {
+          DHiDdir(r,c) = alpha*tcur*I(r,c);
+      }
+    };
+  }
+  else
+  {
+    STensorOperation::zero(DHiDdir);
+  }
+};
+
+void InteractionMechanismExtraDOF::getDInducedExtraDOFGradDCoefficient(int nodeId, SVector3& DHiDalpha) const
+{
+  std::map<int,double>::const_iterator itF = coefficients.find(nodeId);
+  if (itF != coefficients.end())
+  {
+    static SVector3 direction;
+    getDirection(direction);
+    double alpha = itF->second;
+    for (int r=0; r<3; r++)
+    {
+        DHiDalpha(r) = tcur*direction(r);
+    };
+  }
+  else
+  {
+    DHiDalpha = 0.;
+  }
+};
+
+// FLE
+
 
 NetworkInteraction::NetworkInteraction(int tag): _tag(tag)
 {
diff --git a/NonLinearSolver/modelReduction/NetworkInteraction.h b/NonLinearSolver/modelReduction/NetworkInteraction.h
index a73737982..57f508372 100644
--- a/NonLinearSolver/modelReduction/NetworkInteraction.h
+++ b/NonLinearSolver/modelReduction/NetworkInteraction.h
@@ -78,6 +78,37 @@ class InteractionMechanism
     #endif //SWIG
 };
 
+// FLE
+class InteractionMechanismExtraDOF: public InteractionMechanism  // for tempGrad
+{
+  protected:
+    #ifndef SWIG 
+    double tcur, tprev, tinit; // incompatible temperature scalar
+    #endif //SWIG
+  public:
+    InteractionMechanismExtraDOF():InteractionMechanism(),tcur(),tprev(),tinit(){}
+    
+    #ifndef SWIG
+    InteractionMechanismExtraDOF(const InteractionMechanismExtraDOF& src): InteractionMechanism(src),tcur(src.tcur),tprev(src.tprev),tinit(src.tinit){}
+    InteractionMechanismExtraDOF* clone() const {return new InteractionMechanismExtraDOF(*this);}
+    ~InteractionMechanismExtraDOF(){}
+
+    const double& getConstRefToIncompatibleExtraDOF(const IPStateBase::whichState ws) const;
+    double& getRefToIncompatibleExtraDOF(const IPStateBase::whichState ws);
+  
+    void nextStepExtraDOF();
+    void resetIncompatibleExtraDOF();
+    void resetToPreviousStepExtraDOF();
+    void copyExtraDOF(const IPStateBase::whichState ws1, const IPStateBase::whichState ws2);
+    // induce tempGrad from interaction
+    void getInducedExtraDOFGrad(int nodeIndex, SVector3& Hi) const;
+    void getDInducedExtraDOFGradDa(int nodeIndex, SVector3& DHiDt) const;
+    void getDInducedExtraDOFGradDDirection(int nodeIndex, STensor3& DHiDdir) const;
+    void getDInducedExtraDOFGradDCoefficient(int nodeIndex, SVector3& DHiDalpha) const;
+    #endif //SWIG
+};
+// FLE
+
 class NetworkInteraction
 {
   #ifndef SWIG
@@ -175,7 +206,7 @@ class NetworkInteraction
     //
     const STensor3& getStress(const MaterialNode* node) const;
     const STensor3& getDeformationGradient(const MaterialNode* node) const;
-    const STensor43& getTangent(const MaterialNode* node ) const;
+    const STensor43& getTangent(const MaterialNode* node ) const; // dPdF
     void getStress(STensor3& P) const;
     void getDeformationGradientPhase(int phaseIndex, STensor3& F) const;
     //
@@ -209,6 +240,133 @@ class NetworkInteraction
     #endif //SWIG
 };
 
+// FLE
+/*
+class NetworkInteractionExtraDOF : public NetworkInteraction
+{
+  public:
+    NetworkInteractionExtraDOF();
+    NetworkInteractionExtraDOF(const NetworkInteraction& src);
+    NetworkInteractionExtraDOF* clone() const {return new NetworkInteractionExtraDOF(*this);};
+    ~NetworkInteractionExtraDOF();
+
+    int getTag() const;
+    void clearData();
+    void getInteractionFromTree(const Tree& T,  bool standardize=true);
+
+    void resetIncompatibleExtraDOF();
+
+    void copyFrom(const NetworkInteraction& src);
+    void mergeNodesInteraction(InteractionMechanism& ie, const std::vector<int>& allNodes) const;
+    void mergeNodesAllInteractions(const std::vector<int>& allNodes);
+    void mergeNodes(int phaseIndex,  // phase index 
+                    int numberNodes,  // only interactions with numberNodes nodes
+                    NetworkInteraction& newInteraction);
+
+    int getNumberOfMaterialNodes() const;
+    int getDimension() const;
+    double getTotalWeight() const;
+    double getTotalWeightPhase(int iphase) const;
+    void getTotalWeightAllPhases(std::map<int, double>& allPhase) const;
+    void getPhaseFractions(std::map<int, double>& allPhase) const;
+    double getPhaseFraction(int phase) const;
+    int getPhaseIndex(int nodeId) const;
+    double getWeight(const MaterialNode* node) const;
+    double getWeight(int nodeId) const;
+    void getWeights(const InteractionMechanism* im, std::vector<double>& allWeights) const;
+    double get(int comp, int eleVal) const;
+    double getPerPhase(int phaseIndex, int comp, int eleVal) const;
+    
+    void saveDataToFile(std::string filename) const;
+    void loadDataFromFile(std::string filename);
+    void loadCohesiveDataFromFile(std::string filename);
+    void convertToLinearActivation(std::string outputFileName);
+    void createInteractionFromPairsData(std::string filename, int dim, std::string affunc="relu");
+    void createInteractionFullByDivison(int numPhases, int nodePerPhase, int numInteraction, int dim, std::string affunc="relu");
+    void initializeRandomFullInteraction(int numberMaterialNodes, int numberInteractions, int dim,
+                                         const fullVector<double>& phaseFraction, const std::string affunc="relu",
+                                        bool rand=true);
+                                        
+    void createTreeBasedFullInteraction(int Nlayers, int nodePerPhaseFullInteraction, 
+                                        int numFullInteraction, int dim,
+                                         const fullVector<double>& phaseFraction, 
+                                         const std::string affunc="relu",
+                                        bool rand=true, bool triple=false);
+    void initializeRandomPointwiseInteraction(int numberMaterialNodes, int numPhases, int dim, bool rand=true, std::string affunc="relu");
+    void normalizeWeights(std::string newaffunc="linear");
+    void standardizeInteractionDirections();
+    void normalizeAllInteractionCoefficients();
+    bool reInitialize();
+    bool checkValidity(bool message=true) const;
+    
+    #ifndef SWIG
+    void getMaterialNodesByMaterialIndex(int matIndex, std::vector<const MaterialNode*>& allNode) const;
+    void getMaterialNodesByMaterialIndex(int matIndex, std::vector<MaterialNode*>& allNode);
+    MaterialNodeContainer& getMaterialNodeContainer(){return _allMaterialNodes;}
+    const MaterialNodeContainer& getMaterialNodeContainer() const {return _allMaterialNodes;}
+    InteractionContainer& getInteractionContainer() {return _allInteractions;};
+    const InteractionContainer& getInteractionContainer() const {return _allInteractions;};
+    NodeMapContainer& getNodeMapContainer() {return _nodeInteractionMap;}
+    const NodeMapContainer& getNodeMapContainer() const {return _nodeInteractionMap;}
+    
+    void getAllMaterialNodes(std::vector<const MaterialNode*>& allNode) const;
+    void getAllMaterialNodesForMat(int matNum, std::vector<const MaterialNode*>& allNode) const;
+    void getAllMaterialNodes(std::vector<MaterialNode*>& allNode);
+    
+    MaterialNode* getMaterialNode(const int number);
+    const MaterialNode* getMaterialNode(const int number) const;
+    void getAllMaterialNodeIds(std::vector<int>& allIds) const;
+    void getAllMaterialNodeIdsForMat(int matNum, std::vector<int>& allIds) const;
+    void getNumberMaterialNodesPerMat(std::map<int, int>& nodePerMat) const;
+    
+    const std::vector<const InteractionMechanism*>* getInteractionsForNode(const MaterialNode* node) const;
+
+    void getDHDExtraDOF(const MaterialNode* node, std::vector<SVector3>& DHiDt) const;
+    void getDHDNormal(const MaterialNode* node, std::vector<STensor3>& DHiDn) const;
+    void getDHDCoefficient(const MaterialNode* node, std::vector<SVector3>& DHiDalpha) const;
+    
+    void getDfluxDIncompatibleExtraDOF(const MaterialNode* node, std::vector<SVector3>& DqiDt) const;
+    void getDfluxDNormal(const MaterialNode* node, std::vector<STensor3>& DqiDn) const;
+    void getDfluxDCoefficient(const MaterialNode* node, std::vector<SVector3>& DqiDalpha) const;
+    //
+    const STensor3& getFlux(const MaterialNode* node) const;
+    const STensor3& getExtraDOFGrad(const MaterialNode* node) const;
+    const STensor43& getTangent(const MaterialNode* node ) const; // dqDGradT // CHECK
+    void getFlux(SVector3& q) const;
+    void getExtraDOFGradientPhase(int phaseIndex, SVector3& H) const;
+    //
+    void nextStep();
+    void resetToPreviousStep();
+    void copy(const IPStateBase::whichState ws1, const IPStateBase::whichState ws2);
+    //
+    // linear term for im with respect to jm
+    void getDLinearTermDCoefficient(const InteractionMechanism* im, const InteractionMechanism* jm, fullMatrix<double>& mat) const;
+    // linear term for im with respect to jm
+    void getDLinearTermDNormalVars(const InteractionMechanism* im, const InteractionMechanism* jm, fullMatrix<double>& mat) const;
+    // with repsecto to material weights
+    void getDLinearTermDWeights(const InteractionMechanism* im, std::vector<int>& materialIds, fullMatrix<double>& DvecDWeights) const;
+    //
+    void computeLocalDeformationGradient(const STensor3& Fmacro);
+    // get force
+    void getLinearTerm(const InteractionMechanism* im, fullVector<double>& vec) const;
+    // get DforceDa
+    void getBilinearTerm(const InteractionMechanism* im, std::vector<const InteractionMechanism*>& others, fullMatrix<double>& mat) const;    
+    // get DforceDFbar
+    void getTangentTerm(const InteractionMechanism* im, fullMatrix<double>& mat) const;
+    //
+    void getLinearInterfaceTerm(const MaterialNode* node, fullVector<double>& vec) const;
+    //
+    void getBiLinearInterfaceTerm(const MaterialNode* node, fullMatrix<double>& mat) const;
+    //
+    void getBilinearCrossTermBulkInterface(const InteractionMechanism* im, std::vector<const MaterialNode*>& materialNodes, fullMatrix<double>& mat) const;
+    //
+    void getBilinearCrossTermInterfaceBulk(const MaterialNode* node, std::vector<const InteractionMechanism*>& others, 
+                                     fullMatrix<double>& mat) const;
+    #endif //SWIG
+};
+*/
+
+// FLE
 
 class CoefficientReduction
 {
-- 
GitLab


From a964b113e1c68eb417df8142b6d8b7a9435d2065 Mon Sep 17 00:00:00 2001
From: FLE_Knight <ujwalkishore.jinaga@mail.polimi.it>
Date: Fri, 6 Dec 2024 11:52:45 +0100
Subject: [PATCH 02/19] Only declared, prepared to me defined

---
 NonLinearSolver/modelReduction/NetworkInteraction.h | 2 --
 1 file changed, 2 deletions(-)

diff --git a/NonLinearSolver/modelReduction/NetworkInteraction.h b/NonLinearSolver/modelReduction/NetworkInteraction.h
index 57f508372..943111e6b 100644
--- a/NonLinearSolver/modelReduction/NetworkInteraction.h
+++ b/NonLinearSolver/modelReduction/NetworkInteraction.h
@@ -241,7 +241,6 @@ class NetworkInteraction
 };
 
 // FLE
-/*
 class NetworkInteractionExtraDOF : public NetworkInteraction
 {
   public:
@@ -364,7 +363,6 @@ class NetworkInteractionExtraDOF : public NetworkInteraction
                                      fullMatrix<double>& mat) const;
     #endif //SWIG
 };
-*/
 
 // FLE
 
-- 
GitLab


From 8ed20cafbdaafb879dfa7dfaea1b11b70f131e09 Mon Sep 17 00:00:00 2001
From: FLE_Knight <ujwalkishore.jinaga@uliege.be>
Date: Mon, 6 Jan 2025 21:32:29 +0100
Subject: [PATCH 03/19] [NEW FEATURES] - Multiple changes made to
 computeWithMaterialLaw, dG3DIPVariable to accomodate temperature-dependent
 DMN

---
 NonLinearSolver/internalPoints/ipField.cpp |   5 +-
 NonLinearSolver/internalPoints/ipField.h   |   2 +-
 dG3D/src/computeWithMaterialLaw.cpp        |  86 ++++-
 dG3D/src/computeWithMaterialLaw.h          |   8 +-
 dG3D/src/dG3DIPVariable.cpp                | 399 ++++++++++++++-------
 dG3D/src/dG3DIPVariable.h                  | 124 ++++---
 dG3D/src/dG3DMaterialLaw.cpp               |  19 +-
 dG3D/src/dG3DMaterialLaw.h                 |  55 ++-
 8 files changed, 513 insertions(+), 185 deletions(-)

diff --git a/NonLinearSolver/internalPoints/ipField.cpp b/NonLinearSolver/internalPoints/ipField.cpp
index 145e91337..8dbb9727d 100644
--- a/NonLinearSolver/internalPoints/ipField.cpp
+++ b/NonLinearSolver/internalPoints/ipField.cpp
@@ -691,7 +691,10 @@ std::string IPField::ToString(const int i){
   else if (i == TEMPERATURE) return "TEMPERATURE";
   else if (i == THERMALFLUX_X) return "THERMALFLUX_X";
   else if (i == THERMALFLUX_Y) return "THERMALFLUX_Y";
-  else if (i == THERMALFLUX_Z) return "THERMALFLUX_Z";
+  else if (i == THERMALFLUX_Z) return "THERMALFLUX_Z"; 
+  else if (i == TEMP_GRAD_X) return "TEMP_GRAD_X";
+  else if (i == TEMP_GRAD_Y) return "TEMP_GRAD_Y";
+  else if (i == TEMP_GRAD_Z) return "TEMP_GRAD_Z";
   else if (i == THERMALSOURCE) return "THERMALSOURCE";
   else if (i == VOLTAGE) return "VOLTAGE";
   else if (i == ELECTRICALFLUX_X) return "ELECTRICALFLUX_X";
diff --git a/NonLinearSolver/internalPoints/ipField.h b/NonLinearSolver/internalPoints/ipField.h
index bfb243511..e50f20653 100644
--- a/NonLinearSolver/internalPoints/ipField.h
+++ b/NonLinearSolver/internalPoints/ipField.h
@@ -260,7 +260,7 @@ class IPField : public elementsField {
                     ISO_YIELD,ISO_YIELD_TENSILE, ISO_YIELD_COMPRESSION, ISO_YIELD_SHEAR,KIN_YIELD,
                     MTX_SVM,MTX_SIG_XX,MTX_SIG_YY,MTX_SIG_ZZ,MTX_SIG_XY,MTX_SIG_YZ,MTX_SIG_XZ,
                     INC_SVM,INC_SIG_XX,INC_SIG_YY,INC_SIG_ZZ,INC_SIG_XY,INC_SIG_YZ,INC_SIG_XZ,
-                    TEMPERATURE,THERMALFLUX_X,THERMALFLUX_Y,THERMALFLUX_Z,THERMALSOURCE,
+                    TEMPERATURE,THERMALFLUX_X,THERMALFLUX_Y,THERMALFLUX_Z,THERMALSOURCE,TEMP_GRAD_X,TEMP_GRAD_Y,TEMP_GRAD_Z,
                     VOLTAGE,ELECTRICALFLUX_X,ELECTRICALFLUX_Y,ELECTRICALFLUX_Z,ELECTRICALSOURCE,
                     LOCAL_POROSITY, NONLOCAL_POROSITY, CORRECTED_POROSITY, YIELD_POROSITY,
                     NUCLEATED_POROSITY_TOT, NUCLEATED_POROSITY_0, NUCLEATED_POROSITY_1, NUCLEATED_POROSITY_2,
diff --git a/dG3D/src/computeWithMaterialLaw.cpp b/dG3D/src/computeWithMaterialLaw.cpp
index e5cb775c1..dd8fb5408 100644
--- a/dG3D/src/computeWithMaterialLaw.cpp
+++ b/dG3D/src/computeWithMaterialLaw.cpp
@@ -13,8 +13,8 @@
 #include "nonLinearMechSolver.h"
 #include "STensorOperations.h"
 
-computeMaterialLaw::computeMaterialLaw(dG3DMaterialLaw& mlaw): _materialLaw(&mlaw), _ips(NULL), _step(0)
-{
+computeMaterialLaw::computeMaterialLaw(dG3DMaterialLaw& mlaw, bool flag_isothermal): _materialLaw(&mlaw), _ips(NULL), _step(0), 
+_flag_isothermal(flag_isothermal){
   static nonLinearMechSolver solver(1000);
   _materialLaw->setMacroSolver(&solver);
   static bool state = true;
@@ -78,6 +78,42 @@ void computeMaterialLaw::setDeformationGradient(int i, int j, double val)
   F(i,j) = val;
 }
 
+void computeMaterialLaw::setTemperatureGradient(int i, int j, double val)
+{
+  if (!_flag_isothermal){
+    // store current for next step
+  ThermoMechanicsDG3DIPVariableBase* dgip = dynamic_cast<ThermoMechanicsDG3DIPVariableBase*>(_ips->getState(IPStateBase::current));
+  if (!dgip)
+  {
+    Msg::Error("ThermoMechanicsDG3DIPVariableBase must be created from material law computeMaterialLaw::setTemperatureGradient");
+    Msg::Exit(0);
+  }
+  SVector3& H = dgip->getRefToGradT();
+  H(i) = val;
+  }
+  else{
+    Msg::Error("computeMaterialLaw::setTemperatureGradient can be activated only if flag_isothermal is set to false in the constructor.");
+  }
+}
+
+void computeMaterialLaw::setTemperature(double val)
+{
+  if (!_flag_isothermal){
+    // store current for next step
+  ThermoMechanicsDG3DIPVariableBase* dgip = dynamic_cast<ThermoMechanicsDG3DIPVariableBase*>(_ips->getState(IPStateBase::current));
+  if (!dgip)
+  {
+    Msg::Error("ThermoMechanicsDG3DIPVariableBase must be created from material law computeMaterialLaw::setTemperature");
+    Msg::Exit(0);
+  }
+  double& T = dgip->getRefToTemperature();
+  T = val;
+  }
+  else{
+    Msg::Error("computeMaterialLaw::setTemperature can be activated only if flag_isothermal is set to false in the constructor.");
+  }
+}
+
 void computeMaterialLaw::setTime(double t, double dt)
 {
   _materialLaw->setTime(t,dt);
@@ -139,10 +175,6 @@ void computeMaterialLaw::computeStressState_PlaneStrainUniaxialStress( char* NoZ
 };
 
 
-
-
-
-
 double computeMaterialLaw::getTime() const
 {
   return _materialLaw->getTime();
@@ -397,6 +429,22 @@ void computeMaterialLaw::getStress(std::vector<double>& Pstress){
     }
 } 
 
+void computeMaterialLaw::getHeatFlux(std::vector<double>& Qstress){
+  if(!_flag_isothermal){
+    IPVariable* ipvcur = _ips->getState(IPStateBase::current);
+    static SVector3 Q;
+    Q(0) = ipvcur->get(IPField::THERMALFLUX_X);
+    Q(1) = ipvcur->get(IPField::THERMALFLUX_Y);
+    Q(2) = ipvcur->get(IPField::THERMALFLUX_Z);
+    for(int i=0; i<3; i++){
+      Qstress.push_back(Q(i));
+    }
+  }
+  else{
+    Msg::Error("computeMaterialLaw::getHeatFlux can be used only if flag_isothermal is set to false in the constructor.");
+  }
+} 
+
 void computeMaterialLaw::getDeformationGradient(std::vector<double>& Fstrain){
     IPVariable* ipvcur = _ips->getState(IPStateBase::current);
     static STensor3 F;
@@ -416,6 +464,32 @@ void computeMaterialLaw::getDeformationGradient(std::vector<double>& Fstrain){
     }
 }   
 
+void computeMaterialLaw::getTemperatureGradient(std::vector<double>& Hstrain){
+  if(!_flag_isothermal){
+    IPVariable* ipvcur = _ips->getState(IPStateBase::current);
+    static SVector3 H;
+    H(0) = ipvcur->get(IPField::TEMP_GRAD_X);
+    H(1) = ipvcur->get(IPField::TEMP_GRAD_Y);
+    H(2) = ipvcur->get(IPField::TEMP_GRAD_Z);
+    for(int i=0; i<3; i++){
+      Hstrain.push_back(H(i));
+    }
+  }
+  else{
+    Msg::Error("computeMaterialLaw::getTemperatureGradient can be used only if flag_isothermal is set to false in the constructor.");
+  }
+}  
+
+void computeMaterialLaw::getTemperature(double& T){
+  if(!_flag_isothermal){
+    IPVariable* ipvcur = _ips->getState(IPStateBase::current);
+    T = ipvcur->get(IPField::TEMPERATURE);
+  }
+  else{
+    Msg::Error("computeMaterialLaw::getTemperatureGradient can be used only if flag_isothermal is set to false in the constructor.");
+  }
+}  
+
 void computeMaterialLaw::getParameterDerivative(std::vector< fullMatrix<double> >& dPdPn, std::vector< fullMatrix<double> >&dPdPv) const{
   const IPVariable* ipvcur = _ips->getState(IPStateBase::current);
   _materialLaw->getParameterDerivative(ipvcur, dPdPn, dPdPv);  
diff --git a/dG3D/src/computeWithMaterialLaw.h b/dG3D/src/computeWithMaterialLaw.h
index 1d1ece95b..aff11f5bf 100644
--- a/dG3D/src/computeWithMaterialLaw.h
+++ b/dG3D/src/computeWithMaterialLaw.h
@@ -24,12 +24,15 @@ class computeMaterialLaw
     dG3DMaterialLaw* _materialLaw;
     IPStateBase* _ips;
     int _step;
+    bool _flag_isothermal;
     #endif //SWIG
   public:
-    computeMaterialLaw(dG3DMaterialLaw& mlaw);
+    computeMaterialLaw(dG3DMaterialLaw& mlaw, bool flag_isothermal = true);
     virtual ~computeMaterialLaw();
     void resetState(dG3DMaterialLaw& mlaw);
     void setDeformationGradient(int i, int, double val);
+    void setTemperatureGradient(int i, int j, double val);
+    void setTemperature(double val);
     void setTime(double t, double dt);
     void nextStep();
     void computeStressState(bool stiff=false);
@@ -40,7 +43,10 @@ class computeMaterialLaw
     double getTime() const;
     double getTimeStep() const;
     void getStress(std::vector<double>& Pstress);
+    void getHeatFlux(std::vector<double>& Qstress);
     void getDeformationGradient(std::vector<double>& Fstrain);
+    void getTemperatureGradient(std::vector<double>& Hstrain);
+    void getTemperature(double& T);
     void getParameterDerivative(std::vector< fullMatrix<double> >& dPdPn, std::vector< fullMatrix<double> >&dPdPv) const;
     void reset_Parameter(dG3DMaterialLaw& mlaw, std::vector<std::vector<double>>& Para_Norm, std::vector<std::vector<double>>& Para_Wt, const double Vf=0.0);
     void reset_Parameter(dG3DMaterialLaw& mlaw, const char* Para);
diff --git a/dG3D/src/dG3DIPVariable.cpp b/dG3D/src/dG3DIPVariable.cpp
index d29ab2917..ac9c8b699 100644
--- a/dG3D/src/dG3DIPVariable.cpp
+++ b/dG3D/src/dG3DIPVariable.cpp
@@ -2165,134 +2165,6 @@ double ANNBasedDG3DIPVariable::get(const int comp) const
   }
 }
 
-
-StochDMNDG3DIPVariable::StochDMNDG3DIPVariable(const int NRoot,const int NInterface, const bool createBodyForceHO, const bool oninter):
-    dG3DIPVariable(createBodyForceHO, oninter), _NRoot(NRoot), _NInterface(NInterface), _IPVector(NRoot,NULL){
-    bool resizeFlag;
-    int entryFP = 9*_NRoot;
-    int entry_a = 3*_NInterface;
-    resizeFlag = Fvec.resize(entryFP, true);
-    resizeFlag = Pvec.resize(entryFP, true);
-    resizeFlag = a.resize(entry_a, true);
- }
-
-StochDMNDG3DIPVariable::StochDMNDG3DIPVariable(const StochDMNDG3DIPVariable& src):
-  dG3DIPVariable(src), _NRoot(src._NRoot), Fvec(src.Fvec), Pvec(src.Pvec), a(src.a),_IPVector(src._NRoot,NULL){
-    for (int j=0; j< src._NRoot; j++){
-      if (src._IPVector[j] != NULL){
-        _IPVector[j] = src._IPVector[j]->clone();
-      }
-    }
-  }
-
-
-StochDMNDG3DIPVariable& StochDMNDG3DIPVariable::operator =(const IPVariable& src)
-{
-  dG3DIPVariable::operator=(src);
-  const StochDMNDG3DIPVariable* psrc = dynamic_cast<const StochDMNDG3DIPVariable*>(&src);
-  if (psrc!=NULL)
-  {
-    _NRoot = psrc->_NRoot;
-    Fvec = psrc->Fvec;
-    Pvec = psrc->Pvec;
-    a = psrc->a;
-    for (int j=0; j< _NRoot; j++)
-    {
-      if ((_IPVector[j]!=NULL) and (psrc->_IPVector[j] != NULL))
-      {
-        _IPVector[j]->operator =(*(psrc->_IPVector[j]));
-      }
-      else
-      {
-        Msg::Error("cannot perform equal operator in StochDMNDG3DIPVariable::operator =");
-      }
-    }
-  }
-  return *this;
-}
-
-StochDMNDG3DIPVariable::~StochDMNDG3DIPVariable()
-{
-  for (int j=0; j< _NRoot; j++)
-  {
-    if (_IPVector[j] != NULL)
-    {
-      delete _IPVector[j];
-    }
-  }
-}
-
-void StochDMNDG3DIPVariable::addIPv(int loc, IPVariable* ipv)
-{
-  _IPVector[loc] = ipv;
-}
-
-double StochDMNDG3DIPVariable::get(const int comp) const
-{
-  if (comp == IPField::DEFO_ENERGY ||
-      comp == IPField::PLASTIC_ENERGY ||
-      comp == IPField::DAMAGE_ENERGY ||
-      comp == IPField::DAMAGE )
-  {
-    double v = 0;
-    for (int j=0; j< _NRoot; j++)
-    {
-      v += _IPVector[j]->get(comp);
-    }
-    return v;
-  }
-  else
-  {
-    return dG3DIPVariable::get(comp);
-  }
-};
-
-
-void StochDMNDG3DIPVariable::restart()
-{
-  dG3DIPVariable::restart();
-  restartManager::restart(_NRoot);
-  restartManager::restart(Fvec.getDataPtr(),9*_NRoot);
-  restartManager::restart(Pvec.getDataPtr(),9*_NRoot);
-  restartManager::restart(a.getDataPtr(),3*_NInterface);
-  restartManager::restart(_IPVector);
-  for (int j=0; j< _NRoot; j++){
-    _IPVector[j]->restart();
-  }
-};
-
-
-
-double StochDMNDG3DIPVariable::defoEnergy() const
-{
-  double v = 0;
-  for (int j=0; j< _NRoot; j++)
-  {
-    v += dynamic_cast<const dG3DIPVariableBase*>(_IPVector[j])->defoEnergy();
-  }
-  return v;
-}
-double StochDMNDG3DIPVariable::plasticEnergy() const
-{
-  double v = 0;
-  for (int j=0; j< _NRoot; j++)
-  {
-    v += dynamic_cast<const dG3DIPVariableBase*>(_IPVector[j])->plasticEnergy();
-  }
-  return v;
-}
-double StochDMNDG3DIPVariable::damageEnergy() const
-{
-  double v = 0;
-  for (int j=0; j< _NRoot; j++)
-  {
-    v += dynamic_cast<const dG3DIPVariableBase*>(_IPVector[j])->damageEnergy();
-  }
-  return v;
-}
-
-
-
 //torchANNBasedDG3DIPVariable::torchANNBasedDG3DIPVariable(const int n, const double initial_h, const bool createBodyForceHO, const bool oninter):
 //                 dG3DIPVariable(createBodyForceHO, oninter), _n(n), _initial_h(initial_h), restart_internalVars(1,n), _kinematicVariables(1,6)
 //{
@@ -4156,6 +4028,15 @@ double ThermoMechanicsDG3DIPVariableBase::get(const int i) const
   else if (i == IPField::MECHANICAL_SOURCE){
     return getConstRefToMechanicalSource()(0);
   }
+  else if (i == IPField::TEMP_GRAD_X){
+    return getConstRefToGradField()[0](0);
+  }
+  else if (i == IPField::TEMP_GRAD_Y){
+    return getConstRefToGradField()[0](1);
+  }
+  else if (i == IPField::TEMP_GRAD_Z){
+    return getConstRefToGradField()[0](2);
+  }
   else
   {
     return dG3DIPVariable::get(i);
@@ -4168,6 +4049,266 @@ void ThermoMechanicsDG3DIPVariableBase::restart()
   return;
 }
 
+StochDMNDG3DIPVariable::StochDMNDG3DIPVariable(const int NRoot,const int NInterface, const bool createBodyForceHO, const bool oninter):
+    dG3DIPVariable(createBodyForceHO, oninter), _NRoot(NRoot), _NInterface(NInterface), _IPVector(NRoot,NULL){
+    bool resizeFlag;
+    int entryFP = 9*_NRoot;
+    int entry_a = 3*_NInterface;
+    resizeFlag = Fvec.resize(entryFP, true);
+    resizeFlag = Pvec.resize(entryFP, true);
+    resizeFlag = a.resize(entry_a, true);
+ }
+
+StochDMNDG3DIPVariable::StochDMNDG3DIPVariable(const StochDMNDG3DIPVariable& src):
+  dG3DIPVariable(src), _NRoot(src._NRoot), Fvec(src.Fvec), Pvec(src.Pvec), a(src.a),_IPVector(src._NRoot,NULL){
+    for (int j=0; j< src._NRoot; j++){
+      if (src._IPVector[j] != NULL){
+        _IPVector[j] = src._IPVector[j]->clone();
+      }
+    }
+  }
+
+
+StochDMNDG3DIPVariable& StochDMNDG3DIPVariable::operator =(const IPVariable& src)
+{
+  dG3DIPVariable::operator=(src);
+  const StochDMNDG3DIPVariable* psrc = dynamic_cast<const StochDMNDG3DIPVariable*>(&src);
+  if (psrc!=NULL)
+  {
+    _NRoot = psrc->_NRoot;
+    Fvec = psrc->Fvec;
+    Pvec = psrc->Pvec;
+    a = psrc->a;
+    for (int j=0; j< _NRoot; j++)
+    {
+      if ((_IPVector[j]!=NULL) and (psrc->_IPVector[j] != NULL))
+      {
+        _IPVector[j]->operator =(*(psrc->_IPVector[j]));
+      }
+      else
+      {
+        Msg::Error("cannot perform equal operator in StochDMNDG3DIPVariable::operator =");
+      }
+    }
+  }
+  return *this;
+}
+
+StochDMNDG3DIPVariable::~StochDMNDG3DIPVariable()
+{
+  for (int j=0; j< _NRoot; j++)
+  {
+    if (_IPVector[j] != NULL)
+    {
+      delete _IPVector[j];
+    }
+  }
+}
+
+void StochDMNDG3DIPVariable::addIPv(int loc, IPVariable* ipv)
+{
+  _IPVector[loc] = ipv;
+}
+
+double StochDMNDG3DIPVariable::get(const int comp) const
+{
+  if (comp == IPField::DEFO_ENERGY ||
+      comp == IPField::PLASTIC_ENERGY ||
+      comp == IPField::DAMAGE_ENERGY ||
+      comp == IPField::DAMAGE )
+  {
+    double v = 0;
+    for (int j=0; j< _NRoot; j++)
+    {
+      v += _IPVector[j]->get(comp);
+    }
+    return v;
+  }
+  else
+  {
+    return dG3DIPVariable::get(comp);
+  }
+};
+
+
+void StochDMNDG3DIPVariable::restart()
+{
+  dG3DIPVariable::restart();
+  restartManager::restart(_NRoot);
+  restartManager::restart(Fvec.getDataPtr(),9*_NRoot);
+  restartManager::restart(Pvec.getDataPtr(),9*_NRoot);
+  restartManager::restart(a.getDataPtr(),3*_NInterface);
+  restartManager::restart(_IPVector);
+  for (int j=0; j< _NRoot; j++){
+    _IPVector[j]->restart();
+  }
+};
+
+
+
+double StochDMNDG3DIPVariable::defoEnergy() const
+{
+  double v = 0;
+  for (int j=0; j< _NRoot; j++)
+  {
+    v += dynamic_cast<const dG3DIPVariableBase*>(_IPVector[j])->defoEnergy();
+  }
+  return v;
+}
+double StochDMNDG3DIPVariable::plasticEnergy() const
+{
+  double v = 0;
+  for (int j=0; j< _NRoot; j++)
+  {
+    v += dynamic_cast<const dG3DIPVariableBase*>(_IPVector[j])->plasticEnergy();
+  }
+  return v;
+}
+double StochDMNDG3DIPVariable::damageEnergy() const
+{
+  double v = 0;
+  for (int j=0; j< _NRoot; j++)
+  {
+    v += dynamic_cast<const dG3DIPVariableBase*>(_IPVector[j])->damageEnergy();
+  }
+  return v;
+}
+
+// FLE
+StochTMDMNDG3DIPVariable::StochTMDMNDG3DIPVariable(const int NRoot,const int NInterface, const bool createBodyForceHO, const bool oninter):
+    ThermoMechanicsDG3DIPVariableBase(createBodyForceHO, oninter), _NRoot(NRoot), _NInterface(NInterface), _IPVector(NRoot,NULL){
+    bool resizeFlag;
+    int entryFHPQ = 12*_NRoot;
+    int entry_ab = 4*_NInterface;
+    resizeFlag = FHvec.resize(entryFHPQ, true);
+    resizeFlag = PQvec.resize(entryFHPQ, true);
+    resizeFlag = ab.resize(entry_ab, true);
+ }
+
+StochTMDMNDG3DIPVariable::StochTMDMNDG3DIPVariable(const StochTMDMNDG3DIPVariable& src): ThermoMechanicsDG3DIPVariableBase(src), 
+    _NRoot(src._NRoot), FHvec(src.FHvec), PQvec(src.PQvec), ab(src.ab), _IPVector(src._NRoot,NULL){
+    for (int j=0; j< src._NRoot; j++){
+      if (src._IPVector[j] != NULL){
+        _IPVector[j] = src._IPVector[j]->clone();
+      }
+    }
+  }
+
+StochTMDMNDG3DIPVariable& StochTMDMNDG3DIPVariable::operator =(const IPVariable& src)
+{
+  ThermoMechanicsDG3DIPVariableBase::operator=(src);
+  const StochTMDMNDG3DIPVariable* psrc = dynamic_cast<const StochTMDMNDG3DIPVariable*>(&src);
+  if (psrc!=NULL)
+  {
+    _NRoot = psrc->_NRoot;
+    FHvec = psrc->FHvec;
+    PQvec = psrc->PQvec;
+    ab = psrc->ab;
+    for (int j=0; j< _NRoot; j++)
+    {
+      if ((_IPVector[j]!=NULL) and (psrc->_IPVector[j] != NULL))
+      {
+        _IPVector[j]->operator =(*(psrc->_IPVector[j]));
+      }
+      else
+      {
+        Msg::Error("cannot perform equal operator in StochTMDMNDG3DIPVariable::operator =");
+      }
+    }
+  }
+  return *this;
+}
+
+StochTMDMNDG3DIPVariable::~StochTMDMNDG3DIPVariable()
+{
+  for (int j=0; j< _NRoot; j++)
+  {
+    if (_IPVector[j] != NULL)
+    {
+      delete _IPVector[j];
+    }
+  }
+}
+
+void StochTMDMNDG3DIPVariable::addIPv(int loc, IPVariable* ipv)
+{
+  _IPVector[loc] = ipv;
+}
+
+double StochTMDMNDG3DIPVariable::get(const int comp) const
+{
+  if (comp == IPField::DEFO_ENERGY ||
+      comp == IPField::PLASTIC_ENERGY ||
+      comp == IPField::DAMAGE_ENERGY ||
+      comp == IPField::DAMAGE ||
+      comp == IPField::_thermalEnergy)
+  {
+    double v = 0;
+    for (int j=0; j< _NRoot; j++)
+    {
+      v += _IPVector[j]->get(comp);
+    }
+    return v;
+  }
+  else
+  {
+    return ThermoMechanicsDG3DIPVariableBase::get(comp);
+  }
+};
+
+void StochTMDMNDG3DIPVariable::restart()
+{
+  ThermoMechanicsDG3DIPVariableBase::restart();
+  restartManager::restart(_NRoot);
+  restartManager::restart(FHvec.getDataPtr(),12*_NRoot);
+  restartManager::restart(PQvec.getDataPtr(),12*_NRoot);
+  restartManager::restart(ab.getDataPtr(),4*_NInterface);
+  restartManager::restart(_IPVector);
+  for (int j=0; j< _NRoot; j++){
+    _IPVector[j]->restart();
+  }
+};
+
+double StochTMDMNDG3DIPVariable::defoEnergy() const
+{
+  double v = 0;
+  for (int j=0; j< _NRoot; j++)
+  {
+    v += dynamic_cast<const ThermoMechanicsDG3DIPVariableBase*>(_IPVector[j])->defoEnergy();
+  }
+  return v;
+}
+double StochTMDMNDG3DIPVariable::plasticEnergy() const
+{
+  double v = 0;
+  for (int j=0; j< _NRoot; j++)
+  {
+    v += dynamic_cast<const ThermoMechanicsDG3DIPVariableBase*>(_IPVector[j])->plasticEnergy();
+  }
+  return v;
+}
+double StochTMDMNDG3DIPVariable::damageEnergy() const
+{
+  double v = 0;
+  for (int j=0; j< _NRoot; j++)
+  {
+    v += dynamic_cast<const ThermoMechanicsDG3DIPVariableBase*>(_IPVector[j])->damageEnergy();
+  }
+  return v;
+}
+
+double StochTMDMNDG3DIPVariable::thermalEnergy() const
+{
+  double v = 0;
+  for (int j=0; j< _NRoot; j++)
+  {
+    v += dynamic_cast<const ThermoMechanicsDG3DIPVariableBase*>(_IPVector[j])->getInternalEnergyExtraDofDiffusion();
+  }
+  return v;
+}
+
+// FLE
+
 LinearThermoMechanicsDG3DIPVariable::LinearThermoMechanicsDG3DIPVariable(double tinitial, const bool createBodyForceHO, const bool oninter) :
                                    ThermoMechanicsDG3DIPVariableBase(createBodyForceHO, oninter)
 {
@@ -6094,6 +6235,7 @@ double NonLinearTVMDG3DIPVariable::get(const int i) const{
   else if (i == IPField::PRESSURE){return _ipViscoElastic->_pressure;}
   else if (i == IPField::viscousDissipatedEnergy){return _ipViscoElastic->_viscousDissipatedEnergy;}
   else if (i == IPField::mullinsDissipatedEnergy){return _ipViscoElastic->_mullinsDissipatedEnergy;}
+  else if (i == IPField::_thermalEnergy){return _ipViscoElastic->_thermalEnergy;}
   else if (i == IPField::Eve1_XX){
     if (_ipViscoElastic->_A.size() > 0)
       return _ipViscoElastic->_A[0](0,0) + _ipViscoElastic->_B[0]/3.;
@@ -6286,6 +6428,7 @@ double NonLinearTVPDG3DIPVariable::get(const int i) const{
   else if (i == IPField::Dev_corKir_Inf_ZZ){return _ipViscoElastoPlastic->_devCorKirinf_TVE(2,2);}
   else if (i == IPField::viscousDissipatedEnergy){return _ipViscoElastoPlastic->_viscousDissipatedEnergy;}
   else if (i == IPField::mullinsDissipatedEnergy){return _ipViscoElastoPlastic->_mullinsDissipatedEnergy;}
+  else if (i == IPField::_thermalEnergy){return _ipViscoElastoPlastic->_thermalEnergy;}
   else if (i == IPField::Eve1_XX){
     if (_ipViscoElastoPlastic->_A.size() > 0)
       return _ipViscoElastoPlastic->_A[0](0,0) + _ipViscoElastoPlastic->_B[0]/3.;
diff --git a/dG3D/src/dG3DIPVariable.h b/dG3D/src/dG3DIPVariable.h
index 1b4ae3806..cc6f4f127 100644
--- a/dG3D/src/dG3DIPVariable.h
+++ b/dG3D/src/dG3DIPVariable.h
@@ -2395,48 +2395,6 @@ class ANNBasedDG3DIPVariable :public dG3DIPVariable
     virtual void restart();
 };
 
-
-class StochDMNDG3DIPVariable : public dG3DIPVariable
-{
-  protected:
-    int _NRoot, _NInterface;
-    std::vector<IPVariable*> _IPVector;
-    fullVector<double> Fvec;
-    fullVector<double> Pvec;
-    fullVector<double> a;
-
- public:
-    StochDMNDG3DIPVariable(const int NRoot,const int NInterface, const bool createBodyForceHO, const bool oninter);
-    StochDMNDG3DIPVariable(const StochDMNDG3DIPVariable& src);
-    virtual StochDMNDG3DIPVariable& operator =(const IPVariable& src);
-    virtual ~StochDMNDG3DIPVariable();
-
-    void InitializeFluctuationVector() {a.setAll(0.0);};
-    virtual double defoEnergy() const;
-    virtual double plasticEnergy() const;
-    virtual double damageEnergy() const;
-
-    void addIPv(int i, IPVariable* ipv);
-    IPVariable* getIPv(int i) {return _IPVector[i];};
-    const IPVariable* getIPv(int i) const {return _IPVector[i];};
-
-    virtual double get(const int comp) const;
-    virtual fullVector<double>& getRefToDeformationGradientVect() {return Fvec;};
-    virtual const fullVector<double>&  getConstRefToDeformationGradientVect() const {return Fvec;};
-    virtual fullVector<double>& getRefToFirstPiolaKirchhoffStressVect() {return Pvec;};
-    virtual const fullVector<double>& getConstRefToFirstPiolaKirchhoffStressVect() const {return Pvec;};
-    virtual fullVector<double>& getRefToInterfaceFluctuationVect() {return a;};
-    virtual const fullVector<double>& getConstRefToInterfaceFluctuationVect() const {return a;};
-
-
-
-    virtual IPVariable* getInternalData() {return NULL;};
-    virtual const IPVariable* getInternalData()  const {return NULL;};
-    virtual IPVariable* clone() const {return new StochDMNDG3DIPVariable(*this);};
-    virtual void restart();
-};
-
-
 class torchANNBasedDG3DIPVariable :public dG3DIPVariable
 {
   protected:
@@ -3476,6 +3434,88 @@ class ThermoMechanicsDG3DIPVariableBase : public dG3DIPVariable, public extraDof
   virtual void restart();
 };
 
+class StochDMNDG3DIPVariable : public dG3DIPVariable
+{
+  protected:
+    int _NRoot, _NInterface;
+    std::vector<IPVariable*> _IPVector;
+    fullVector<double> Fvec;
+    fullVector<double> Pvec;
+    fullVector<double> a;
+
+ public:
+    StochDMNDG3DIPVariable(const int NRoot,const int NInterface, const bool createBodyForceHO, const bool oninter);
+    StochDMNDG3DIPVariable(const StochDMNDG3DIPVariable& src);
+    virtual StochDMNDG3DIPVariable& operator =(const IPVariable& src);
+    virtual ~StochDMNDG3DIPVariable();
+
+    void InitializeFluctuationVector() {a.setAll(0.0);};
+    virtual double defoEnergy() const;
+    virtual double plasticEnergy() const;
+    virtual double damageEnergy() const;
+
+    void addIPv(int i, IPVariable* ipv);
+    IPVariable* getIPv(int i) {return _IPVector[i];};
+    const IPVariable* getIPv(int i) const {return _IPVector[i];};
+
+    virtual double get(const int comp) const;
+    virtual fullVector<double>& getRefToDeformationGradientVect() {return Fvec;};
+    virtual const fullVector<double>&  getConstRefToDeformationGradientVect() const {return Fvec;};
+    virtual fullVector<double>& getRefToFirstPiolaKirchhoffStressVect() {return Pvec;};
+    virtual const fullVector<double>& getConstRefToFirstPiolaKirchhoffStressVect() const {return Pvec;};
+    virtual fullVector<double>& getRefToInterfaceFluctuationVect() {return a;};
+    virtual const fullVector<double>& getConstRefToInterfaceFluctuationVect() const {return a;};
+
+    virtual IPVariable* getInternalData() {return NULL;};
+    virtual const IPVariable* getInternalData()  const {return NULL;};
+    virtual IPVariable* clone() const {return new StochDMNDG3DIPVariable(*this);};
+    virtual void restart();
+};
+
+// FLE
+class StochTMDMNDG3DIPVariable : public ThermoMechanicsDG3DIPVariableBase 
+{
+  protected:
+    int _NRoot, _NInterface;
+    std::vector<IPVariable*> _IPVector;
+
+    // combined vectors
+    fullVector<double> FHvec; // F- defo, H -tempGrad
+    fullVector<double> PQvec; // P- 1st PK, Q-heatFlux
+    fullVector<double> ab;  // a- disp, b-temp
+
+  public:
+    StochTMDMNDG3DIPVariable(const int NRoot,const int NInterface, const bool createBodyForceHO, const bool oninter);
+    StochTMDMNDG3DIPVariable(const StochTMDMNDG3DIPVariable& src);
+    virtual StochTMDMNDG3DIPVariable& operator =(const IPVariable& src);
+    virtual ~StochTMDMNDG3DIPVariable();
+
+    void InitializeFluctuationVector() {ab.setAll(0.0);};
+    virtual double defoEnergy() const;
+    virtual double plasticEnergy() const;
+    virtual double damageEnergy() const;
+    virtual double thermalEnergy() const;
+    virtual double getInternalEnergyExtraDofDiffusion() const {return this->thermalEnergy();};
+
+    void addIPv(int i, IPVariable* ipv);
+    IPVariable* getIPv(int i) {return _IPVector[i];};
+    const IPVariable* getIPv(int i) const {return _IPVector[i];};
+
+    virtual double get(const int comp) const;
+    virtual fullVector<double>& getRefToCombinedGradientVect() {return FHvec;};
+    virtual const fullVector<double>&  getConstRefToCombinedGradientVect() const {return FHvec;};
+    virtual fullVector<double>& getRefToCombinedStressVect() {return PQvec;};
+    virtual const fullVector<double>& getConstRefToCombinedStressVect() const {return PQvec;};
+    virtual fullVector<double>& getRefToCombinedInterfaceFluctuationVect() {return ab;};
+    virtual const fullVector<double>& getConstRefToCombinedInterfaceFluctuationVect() const {return ab;};
+
+    virtual IPVariable* getInternalData() {return NULL;};
+    virtual const IPVariable* getInternalData()  const {return NULL;};
+    virtual IPVariable* clone() const {return new StochTMDMNDG3DIPVariable(*this);};
+    virtual void restart();
+};
+// FLE
+
 
 class LinearThermoMechanicsDG3DIPVariable : public ThermoMechanicsDG3DIPVariableBase
 {
diff --git a/dG3D/src/dG3DMaterialLaw.cpp b/dG3D/src/dG3DMaterialLaw.cpp
index e1772dcaa..94fe33049 100644
--- a/dG3D/src/dG3DMaterialLaw.cpp
+++ b/dG3D/src/dG3DMaterialLaw.cpp
@@ -3596,7 +3596,7 @@ double torchANNBasedDG3DMaterialLaw::soundSpeed() const
 StochDMNDG3DMaterialLaw::StochDMNDG3DMaterialLaw(const int num, const double rho, const double E,const double nu, const char *ParaFile,const bool porous,const double tol):
   dG3DMaterialLaw(num,rho,false),_porous(porous),_tol(tol){
 
-  read_parameter(ParaFile);
+  read_parameter(ParaFile); 
   fill_Matrices();         
 }
 
@@ -3707,6 +3707,9 @@ void StochDMNDG3DMaterialLaw::checkInternalState(IPVariable* ipv, const IPVariab
 }
 
 void StochDMNDG3DMaterialLaw::pos_kids(const int pos, const int level, int& pos0, int& pos1) const {
+
+  // code to calculate positions of child nodes using given "pos" and "level"
+
   if(!_Modified_DMN or level<_TotalLevel-2 ){
       pos0 = 2*pos+1;
       pos1 = 2*pos+2;
@@ -3725,6 +3728,9 @@ void StochDMNDG3DMaterialLaw::pos_kids(const int pos, const int level, int& pos0
 
 
 void StochDMNDG3DMaterialLaw::TwoPhasesInteract(const STensor43& C0, const STensor43& C1, fullMatrix<double> &mat, const int pos, const int level){
+
+  // code to calculate interaction between two phases
+
   double n0 = _Para_Norm[pos][0];
   double n1 = _Para_Norm[pos][1];
   double n2 = _Para_Norm[pos][2];
@@ -3852,6 +3858,9 @@ void StochDMNDG3DMaterialLaw::setMacroSolver(const nonLinearMechSolver* sv){
 }
          
 void StochDMNDG3DMaterialLaw::fill_NLocal(const int pos, double N[][3])const{
+
+  // code to fill a matrix related to local normals
+
   double n0 = _Para_Norm[pos][0];
   double n1 = _Para_Norm[pos][1];
   double n2 = _Para_Norm[pos][2];
@@ -3874,6 +3883,9 @@ void StochDMNDG3DMaterialLaw::fill_NLocal(const int pos, double N[][3])const{
 
 
 void StochDMNDG3DMaterialLaw::fill_W_WI(const int pos, const int level, double W[][2]){
+
+  // code to fill a matrix related to weights and interfaces
+
   double VI = _VI[pos];
   double Wtmp0 = _Para_Wt[pos][0];
   double Wtmp1 = _Para_Wt[pos][1];
@@ -3892,7 +3904,8 @@ void StochDMNDG3DMaterialLaw::fill_W_WI(const int pos, const int level, double W
 
 
 // fill the matrices which keep the topological information
-void  StochDMNDG3DMaterialLaw::fill_Matrices(){    
+void  StochDMNDG3DMaterialLaw::fill_Matrices(){  
+
   double Norm[9][3];
   double W_WI[2][2];
   int pos0=0;
@@ -4313,6 +4326,7 @@ void StochDMNDG3DMaterialLaw::stress(IPVariable*ipv, const IPVariable*ipvprev, c
         Jacobian.invertInPlace();
       }
       else{
+        // What is this? HOw does the following update the jacobian?
         _NTV.mult(Pvec, Res_node);
         Res_node_t.scale(-1.0);
         Res_node_t.axpy(Res_node, 1.0);
@@ -4335,6 +4349,7 @@ void StochDMNDG3DMaterialLaw::stress(IPVariable*ipv, const IPVariable*ipvprev, c
           }
         }
         stiff_loc = true;
+        // What?
       }
 
       Res_node_t = Res_node;
diff --git a/dG3D/src/dG3DMaterialLaw.h b/dG3D/src/dG3DMaterialLaw.h
index d0e2f83ae..fec86adf5 100644
--- a/dG3D/src/dG3DMaterialLaw.h
+++ b/dG3D/src/dG3DMaterialLaw.h
@@ -697,13 +697,13 @@ class StochDMNDG3DMaterialLaw : public dG3DMaterialLaw{
     int _NRoot;
     int _NInterface;
     int _N_Node;
-    int _NPara_Wt;
-    int _NPara_Norm;
+    int _NPara_Wt; 
+    int _NPara_Norm; 
     int _Dim;
     double _Vf;
     double _tol;    
-    std::vector<SPoint2> _Para_Wt;
-    std::vector<SPoint3> _Para_Norm; 
+    std::vector<SPoint2> _Para_Wt;  // vector of weights
+    std::vector<SPoint3> _Para_Norm; // vector of normals
     fullMatrix<double> _ParaAngle;   
     std::vector<dG3DMaterialLaw*> _mapLaw;
     fullMatrix<double> _Nv;
@@ -767,6 +767,53 @@ class StochDMNDG3DMaterialLaw : public dG3DMaterialLaw{
     #endif //SWIG
  };   
 
+// FLE
+/*
+class StochTMDMNDG3DMaterialLaw : public StochTMDMNDG3DMaterialLaw{
+  protected:
+    #ifndef SWIG
+
+    #endif //SWIG
+  public:
+    StochTMDMNDG3DMaterialLaw(const int num, const double rho, const double E,const double nu, const char *ParaFile,const bool porous,const double tol=1e-6);
+    void addLaw(dG3DMaterialLaw* law);
+    #ifndef SWIG
+    StochTMDMNDG3DMaterialLaw(const StochTMDMNDG3DMaterialLaw &source);
+    virtual ~StochTMDMNDG3DMaterialLaw();
+
+    virtual void setTime(const double t,const double dtime);
+    virtual materialLaw::matname getType() const {return materialLaw::StochDMN;}
+
+    virtual void createIPState(IPStateBase* &ips, bool hasBodyForce, const bool* state_=NULL,const MElement *ele=NULL, const int nbFF_=0, const IntPt *GP=NULL, const int gpt = 0) const;
+    virtual void createIPVariable(IPVariable* &ipv, bool hasBodyForce, const MElement *ele, const int nbFF_, const IntPt *GP, const int gpt) const;
+    virtual void initialIPVariable(IPVariable* ipv, bool stiff);   
+    virtual void initLaws(const std::map<int,materialLaw*> &maplaw);
+    virtual double scaleFactor() const {return 1.;};
+    virtual double soundSpeed() const {return 0.;};
+    virtual materialLaw* clone() const {return new StochTMDMNDG3DMaterialLaw(*this);};
+    virtual void stress(IPVariable*ipv, const IPVariable*ipvprev, const bool stiff=true, const bool checkfrac=true, const bool dTangent=false);
+
+    virtual void checkInternalState(IPVariable* ipv, const IPVariable* ipvprev) const;
+    virtual bool withEnergyDissipation() const {return false;};
+    virtual const materialLaw *getConstNonLinearSolverMaterialLaw() const
+    {
+      Msg::Error("getConstNonLinearSolverMaterialLaw in  StochTMDMNDG3DMaterialLaw does not exist");
+      return NULL;
+    }
+    virtual materialLaw *getNonLinearSolverMaterialLaw()
+    {
+      Msg::Error("getNonLinearSolverMaterialLaw in  StochTMDMNDG3DMaterialLaw does not exist");
+      return NULL;
+    }
+    virtual void setMacroSolver(const nonLinearMechSolver* sv);
+    virtual void getParameterDerivative(const IPVariable*ipv, std::vector< fullMatrix<double> >& dPdPn, std::vector< fullMatrix<double> >&dPdPv) const;
+    virtual void reset_Parameter(std::vector<std::vector<double>>& Para_Norm, std::vector<std::vector<double>>& Para_Wt, const double Vf = 0.0);
+    virtual void reset_Parameter(const char* Para);
+    #endif //SWIG
+ }; 
+ */
+// FLE
+
 class J2SmallStrainDG3DMaterialLaw : public dG3DMaterialLaw
 {
  protected:
-- 
GitLab


From 8e66efcdc3435fb2c0a808df8a20ba146c22a3f8 Mon Sep 17 00:00:00 2001
From: FLE_Knight <ujwalkishore.jinaga@uliege.be>
Date: Fri, 10 Jan 2025 22:10:18 +0100
Subject: [PATCH 04/19] [NEW FEATURES] Added several member functions in TMDMN.
 The matrices are yet to be debugged. Para_alpha has to be implemented

---
 dG3D/src/dG3DMaterialLaw.cpp | 869 ++++++++++++++++++++++++++++++++++-
 dG3D/src/dG3DMaterialLaw.h   |  23 +-
 2 files changed, 880 insertions(+), 12 deletions(-)

diff --git a/dG3D/src/dG3DMaterialLaw.cpp b/dG3D/src/dG3DMaterialLaw.cpp
index 94fe33049..27248d835 100644
--- a/dG3D/src/dG3DMaterialLaw.cpp
+++ b/dG3D/src/dG3DMaterialLaw.cpp
@@ -3592,7 +3592,7 @@ double torchANNBasedDG3DMaterialLaw::soundSpeed() const
 };
 
 
-
+// FLE
 StochDMNDG3DMaterialLaw::StochDMNDG3DMaterialLaw(const int num, const double rho, const double E,const double nu, const char *ParaFile,const bool porous,const double tol):
   dG3DMaterialLaw(num,rho,false),_porous(porous),_tol(tol){
 
@@ -5065,7 +5065,872 @@ void StochDMNDG3DMaterialLaw::setTime(const double t,const double dtime){
   }
 }
 
-//
+// FLE
+StochTMDMNDG3DMaterialLaw::StochTMDMNDG3DMaterialLaw(const int num, const double rho, const double E,const double nu, const char *ParaFile,
+      const bool porous, const bool flag_isothermal, const bool flag_microTempFixed, const double tol):
+      StochDMNDG3DMaterialLaw(num,rho,E,nu,ParaFile,porous,tol),_flag_isothermal(flag_isothermal),_flag_microTempFixed(flag_microTempFixed){
+
+  if (_flag_isothermal && _flag_microTempFixed){
+    _col_Di = 9; _row_Di = 3;
+  }
+  else if(!_flag_isothermal && _flag_microTempFixed){
+    _col_Di = 12; _row_Di = 4;
+  }
+  else if(!_flag_isothermal && !_flag_microTempFixed){
+    _col_Di = 13; _row_Di = 5;
+  }
+  else{
+    Msg::Error("This combination of flags doesn't exist. Redefine in the constructor.");
+  }
+
+  StochTMDMNDG3DMaterialLaw::read_parameter(ParaFile); 
+  StochTMDMNDG3DMaterialLaw::fill_Matrices();         
+}
+
+StochTMDMNDG3DMaterialLaw::StochTMDMNDG3DMaterialLaw(const StochTMDMNDG3DMaterialLaw &src): StochDMNDG3DMaterialLaw(src), 
+    _col_Di(src._col_Di), _row_Di(src._row_Di), _flag_isothermal(src._flag_isothermal), _flag_microTempFixed(src._flag_microTempFixed), _Para_Alpha(src._Para_Alpha){}
+
+StochTMDMNDG3DMaterialLaw::~StochTMDMNDG3DMaterialLaw(){};
+
+void StochTMDMNDG3DMaterialLaw::createIPState(IPStateBase* &ips, bool hasBodyForce, const bool* state_,const MElement *ele, const int nbFF_, const IntPt *GP, const int gpt) const{
+      // check interface element
+  bool inter=true;
+  const MInterfaceElement *iele = dynamic_cast<const MInterfaceElement*>(ele);
+  if(iele==NULL) inter=false;
+    IPVariable* ipvi = new  StochTMDMNDG3DIPVariable(_NRoot, _NInterface, hasBodyForce,inter);
+    IPVariable* ipv1 = new  StochTMDMNDG3DIPVariable(_NRoot, _NInterface, hasBodyForce,inter);
+    IPVariable* ipv2 = new  StochTMDMNDG3DIPVariable(_NRoot, _NInterface, hasBodyForce,inter);
+
+    StochTMDMNDG3DIPVariable* ipvi_root = static_cast<StochTMDMNDG3DIPVariable*>(ipvi);
+    StochTMDMNDG3DIPVariable* ipv1_root = static_cast<StochTMDMNDG3DIPVariable*>(ipv1);
+    StochTMDMNDG3DIPVariable* ipv2_root = static_cast<StochTMDMNDG3DIPVariable*>(ipv2);
+    for (int i=0; i< _NRoot; i++){
+      int mat_IP = 0;
+      IPStateBase* ips_i = NULL;
+      if(_Modified_DMN){
+        if(i%3 == 1) mat_IP = 1;
+      }
+      else{
+         mat_IP = i%2;
+      }
+      if(_porous) mat_IP=0;
+      _mapLaw[mat_IP]->createIPState(ips_i, hasBodyForce, state_, ele, nbFF_, GP, gpt);
+      std::vector<IPVariable*> ip_all;
+      ips_i->getAllIPVariable(ip_all);
+      ipvi_root->addIPv(i, ip_all[0]);
+      ipv1_root->addIPv(i, ip_all[1]);
+      ipv2_root->addIPv(i, ip_all[2]);
+    }
+    if(ips != NULL) delete ips;
+      ips = new IP3State(state_,ipvi,ipv1,ipv2);
+}
+
+void StochTMDMNDG3DMaterialLaw::createIPVariable(IPVariable* &ipv, bool hasBodyForce, const MElement *ele, const int nbFF_, const IntPt *GP, const int gpt) const {
+  if(ipv !=NULL) delete ipv;
+  bool inter=true;
+  const MInterfaceElement *iele = dynamic_cast<const MInterfaceElement*>(ele);
+  if(iele == NULL){
+    inter=false;
+  }
+  ipv = new  StochTMDMNDG3DIPVariable(_NRoot, _NInterface, hasBodyForce,inter);
+  StochTMDMNDG3DIPVariable* ipv_root = static_cast<StochTMDMNDG3DIPVariable*>(ipv);
+  for (int i=0; i< _NRoot; i++){
+    IPVariable* ipv_i = NULL;
+    int mat_IP =0;
+    if(_Modified_DMN){
+      if(i%3 == 1) mat_IP = 1;
+    }
+    else{
+       mat_IP = i%2;
+    }
+    if(_porous) mat_IP=0;
+    _mapLaw[mat_IP]->createIPVariable(ipv_i, hasBodyForce, ele, nbFF_, GP, gpt);
+    ipv_root->addIPv(i, ipv_i);
+  }
+};
+
+void StochTMDMNDG3DMaterialLaw::initialIPVariable(IPVariable* ipv, bool stiff){
+  StochTMDMNDG3DIPVariable* ipv_all = dynamic_cast<StochTMDMNDG3DIPVariable*>(ipv);
+  ipv_all->InitializeFluctuationVector();
+  if (ipv_all == NULL){
+    Msg::Error("StochTMDMNDG3DIPVariable must be used in StochTMDMNDG3DMaterialLaw::initialIPVariable");
+  }
+  for (int i=0; i< _NRoot; i++){
+    IPVariable* ipv_i = ipv_all->getIPv(i);
+    int mat_IP =0;
+    if(_Modified_DMN){
+      if(i%3 == 1) mat_IP = 1;
+    }
+    else{
+        mat_IP = i%2;
+    }
+    if(_porous) mat_IP=0;
+    _mapLaw[mat_IP]->initialIPVariable(ipv_i, stiff);
+  }
+}
+
+void StochTMDMNDG3DMaterialLaw::checkInternalState(IPVariable* ipv, const IPVariable* ipvprev) const{
+  StochTMDMNDG3DIPVariable* ipv_all = dynamic_cast<StochTMDMNDG3DIPVariable*>(ipv);
+  const StochTMDMNDG3DIPVariable* ipvprev_all = dynamic_cast<const StochTMDMNDG3DIPVariable*>(ipvprev);
+  if (ipv_all == NULL){
+    Msg::Error("StochTMDMNDG3DIPVariable must be used in StochTMDMNDG3DMaterialLaw::checkInternalState");
+  }
+  for (int i=0; i< _NRoot; i++){
+    IPVariable* ipv_i = ipv_all->getIPv(i);
+    const IPVariable* ipvprev_i = ipvprev_all->getIPv(i);
+    int mat_IP = 0;
+    if(_Modified_DMN){
+      if(i%3 == 1) mat_IP = 1;
+    }
+    else{
+       mat_IP = i%2;
+    }
+    if(_porous) mat_IP=0;
+    _mapLaw[mat_IP]->checkInternalState(ipv_i, ipvprev_i);
+  }
+}
+
+void StochTMDMNDG3DMaterialLaw::setMacroSolver(const nonLinearMechSolver* sv){
+   dG3DMaterialLaw::setMacroSolver(sv);
+    for (std::vector<dG3DMaterialLaw*>::iterator ite = _mapLaw.begin(); ite!= _mapLaw.end(); ite++){
+      (*ite)->setMacroSolver(sv);
+    }
+}
+
+void StochTMDMNDG3DMaterialLaw::fill_NLocal(const int pos, std::vector<std::vector<double>> N)const{
+
+  // code to fill a matrix related to local normals
+
+  double n0 = _Para_Norm[pos][0];
+  double n1 = _Para_Norm[pos][1];
+  double n2 = _Para_Norm[pos][2];
+
+  if (_flag_isothermal && _flag_microTempFixed){
+    N.resize(_col_Di);
+    for(auto& row : N)
+      row.resize(_row_Di,0.);
+    N[0][0] = n0; N[1][1] = n0; N[2][2] = n0;
+    N[3][0] = n1; N[4][1] = n1; N[5][2] = n1;
+    N[6][0] = n2; N[7][1] = n2; N[8][2] = n2;
+  }
+  else if(!_flag_isothermal && _flag_microTempFixed){
+    N.resize(_col_Di);
+    for(auto& row : N)
+      row.resize(_row_Di,0.);
+    N[0][0] = n0; N[1][1] = n0; N[2][2] = n0;  N[3][3] = n0;
+    N[4][0] = n1; N[5][1] = n1; N[6][2] = n1;  N[7][3] = n1;
+    N[8][0] = n2; N[9][1] = n2; N[10][2] = n2; N[11][3] = n2; 
+  }
+  else if(!_flag_isothermal && !_flag_microTempFixed){
+    N.resize(_col_Di);
+    for(auto& row : N)
+      row.resize(_row_Di,0.);
+    N[0][0] = n0; N[1][1] = n0; N[2][2] = n0;  N[3][3] = n0;
+    N[4][0] = n1; N[5][1] = n1; N[6][2] = n1;  N[7][3] = n1;
+    N[8][0] = n2; N[9][1] = n2; N[10][2] = n2; N[11][3] = n2; 
+    N[13][4] = 1.;
+  }
+  else{
+    Msg::Error("This combination of flags doesn't exist. Redefine in the constructor.");
+  }
+}
+
+void StochTMDMNDG3DMaterialLaw::pos_kids(const int pos, const int level, int& pos0, int& pos1) const {
+
+  // code to calculate positions of child nodes using given "pos" and "level"
+
+  if(!_Modified_DMN or level<_TotalLevel-2 ){
+      pos0 = 2*pos+1;
+      pos1 = 2*pos+2;
+  }
+  else if(level ==_TotalLevel-2){
+    pos0 = pos + pow(2, level);
+    int k = pos - (pow(2, level)-1);
+    pos1 =  int(3*pow(2, level)-1) + k*3+2; // CHECK
+  }
+  else if(level==_TotalLevel-1){
+    int k = pos - (pow(2, level)-1);
+    pos0 = int(3*pow(2, level-1)-1) +k*3; // CHECK
+    pos1 = pos0+1;
+  }
+}
+
+// fill the matrices which keep the topological information
+void StochTMDMNDG3DMaterialLaw::fill_Matrices(){  
+
+  std::vector<std::vector<double>> Norm;   // double Norm[9][3];
+  double W_WI[2][2];
+  int pos0=0;
+  int pos1=0;
+  int k, node;
+  int Col_start, Col_start0, Col_start1, Row_start, Row_start0, Row_start1;
+  double tmp;
+
+  // set the size of rows and cols in Di matrix
+  int col = _col_Di; // = 9;
+
+  for(int i=0; i <_N_Node; i++){
+    _VA.push_back(1.0); // Vector for position of nodes for Stress
+  }
+  // fill matrix for equilibrium of interface
+  _VI.push_back(_Vf);
+  int l = -1;
+  for(int pos=0; pos <_NInterface; pos++){
+    if(pos == int(pow(2,l+1)-1)) l +=1; // if its the first position (interface) of every level, l+=1
+    fill_NLocal(pos,Norm);  // size of Norm depends on the flags set inside this function
+    pos_kids(pos, l, pos0, pos1);
+    Row_start = pos*_row_Di; // 3;
+    Col_start0 = (pos0-1)*col;
+    Col_start1 = (pos1-1)*col;
+
+    double S_ba = 1.0;
+    if(l ==_TotalLevel-1 and _porous) S_ba = _Para_Wt[pos][1];
+    // information of interface norm
+    for(int nc=0; nc<col;nc++){
+      for(int nr=0; nr<_row_Di; nr++){
+        _NT.set(Row_start+nr, Col_start0+nc, Norm[nc][nr]);
+        _NT.set(Row_start+nr, Col_start1+nc,-S_ba*Norm[nc][nr]);
+      }
+    }
+
+    if(l ==_TotalLevel-1){
+      if(_porous){
+        _VA[pos0] = (1.0-_VI[pos])*_Para_Wt[pos][0];
+        _VA[pos1] = (1.0-_VI[pos])*(1.0-_Para_Wt[pos][0]);
+      }
+      else{
+        _VA[pos0] = 1.0-_VI[pos];
+        _VA[pos1] = _VI[pos];
+      }
+    }
+    else if(_Modified_DMN and l ==_TotalLevel-2){
+      StochDMNDG3DMaterialLaw::fill_W_WI(pos,l,W_WI);
+      _VA[pos0] = W_WI[0][0];
+      _VA[pos1] = W_WI[0][1];
+      _VI.push_back(W_WI[1][0]);
+    }
+    else{
+      StochDMNDG3DMaterialLaw::fill_W_WI(pos,l,W_WI);
+      _VA[pos0] = W_WI[0][0];
+      _VA[pos1] = W_WI[0][1];
+      _VI.push_back(W_WI[1][0]);
+      _VI.push_back(W_WI[1][1]);
+    }
+    //information of homogenous strain to local strain
+    Col_start = pos*_row_Di; // *3
+    if(!_Modified_DMN or l< _TotalLevel-2){
+      k = int(pow(2,l));
+      node = _NRoot/k/2;
+      int i = pos-int(pow(2,l))+1;
+      for(int r=0; r<node; r++){
+        Row_start0 = (i*2*node+r)*col;
+        Row_start1 = (i*2*node+r+node)*col;
+        for(int nr=0; nr<col;nr++){
+          for(int nc=0; nc<_row_Di;nc++){
+            _Nv.set(Row_start0+nr, Col_start+nc,Norm[nr][nc]/_VA[pos0]);
+            _Nv.set(Row_start1+nr, Col_start+nc,-S_ba*Norm[nr][nc]/_VA[pos1]);
+          }
+        }
+      }
+    }
+    else if(l == _TotalLevel-2){
+      node = _row_Di; // 3;
+      int i = pos-int(pow(2,l))+1;
+      for(int r=0; r<2; r++){
+        Row_start0 = (i*node+r)*col;
+        for(int nr=0; nr<col;nr++){
+          for(int nc=0; nc<_row_Di; nc++){
+            _Nv.set(Row_start0+nr, Col_start+nc,Norm[nr][nc]/_VA[pos0]);
+          }
+        }
+      }
+      Row_start1 = (i*node+2)*col;
+      for(int nr=0; nr<col;nr++){
+        for(int nc=0; nc<_row_Di; nc++){
+          _Nv.set(Row_start1+nr, Col_start+nc,-S_ba*Norm[nr][nc]/_VA[pos1]);
+        }
+      }
+    }
+    else if(l == _TotalLevel-1){
+      node = _row_Di; // 3;
+      int i = pos-int(pow(2,l))+1;
+      Row_start0 = (i*node)*col;
+      Row_start1 = (i*node+1)*col;
+      for(int nr=0; nr<col;nr++){
+        for(int nc=0; nc<_row_Di; nc++){
+          _Nv.set(Row_start0+nr, Col_start+nc,Norm[nr][nc]/_VA[pos0]);
+          _Nv.set(Row_start1+nr, Col_start+nc,-S_ba*Norm[nr][nc]/_VA[pos1]);
+        }
+      }
+    }
+   }
+
+ // information of voulme fraction to stress on node
+  Row_start = col*(_N_Node-1-_NRoot);
+  for(int nc=0; nc<col*_NRoot; nc++){
+    _V.set(Row_start+nc,nc,1.0);
+  }
+
+  l = _TotalLevel-1;
+  for(int pos = _NInterface-1; pos > 0; pos--){
+    if(pos == int(pow(2,l)-2)) l -=1;
+    pos_kids(pos, l, pos0, pos1);
+    Row_start = (pos-1)*col;
+    Row_start0 = (pos0-1)*col;
+    Row_start1 = (pos1-1)*col;
+    for(int nr=0; nr<col;nr++){
+      for(int nc=0; nc<col*_NRoot ; nc++){
+        tmp = _VA[pos0]*_V(Row_start0+nr,nc) + _VA[pos1]*_V(Row_start1+nr,nc);
+        _V.set(Row_start+nr,nc, tmp);
+      }
+    }
+  }
+  _NT.mult(_V, _NTV);
+
+  for(int i=0; i<col*_NRoot;i++){
+    _I(i, i%col) = 1.0;
+  }
+}
+ // end fill_matrices
+
+// read parameter from input file
+void StochTMDMNDG3DMaterialLaw::read_parameter(const char *ParaFile){
+
+  double sin0, cos0, sin1, cos1;
+  int Model;
+  FILE *Para = fopen(ParaFile, "r");
+  if ( Para != NULL ){
+    int okf = fscanf(Para, "%d\n", &Model);
+    _Modified_DMN = static_cast<bool>(Model);
+
+    okf = fscanf(Para, "%d %d\n", &_Dim, &_TotalLevel);
+
+    bool resizeFlag;
+    if(_Modified_DMN){
+       _NRoot = int(pow(2,(_TotalLevel-2))*3); // CHECK THIS FLAG
+    }
+    else{
+      _NRoot = int(pow(2,_TotalLevel));
+    }
+    _NInterface = _NRoot-1;
+    _N_Node = _NRoot + _NInterface;
+
+    int row = _col_Di*_NRoot;
+    int col = _row_Di*_NInterface;
+    resizeFlag = _Nv.resize(row, col, true);
+
+    resizeFlag = _I.resize(row, _col_Di, true);
+
+    row = _col_Di*(_N_Node-1);
+    col = _col_Di*_NRoot;
+    resizeFlag = _V.resize(row, col, true);
+        
+    row = _row_Di*_NInterface;        
+    resizeFlag = _NTV.resize(row, col, true);  
+    
+    resizeFlag = _NT.resize(_row_Di*_NInterface, _col_Di*(_N_Node-1), true);            
+        
+    okf = fscanf(Para, "%lf\n", &_Vf);
+
+    _NPara_Norm = _NInterface;
+    
+    resizeFlag = _C.resize(_col_Di*_NRoot,_col_Di*_NRoot,true);
+    resizeFlag = Jacobian.resize(_row_Di*_NInterface, _row_Di*_NInterface,true); 
+    
+    _ParaAngle.resize(_NInterface,2,true);
+        
+    double ParaN[2];
+    double Pi(3.14159265359);        
+    SPoint3 Para_Norm;
+    SPoint2 Para_Wt;
+
+    if(_Dim==2){
+      ParaN[1] = 0.0;
+      sin1 = sin(Pi*ParaN[1]);
+      cos1 = cos(Pi*ParaN[1]);
+      for(int i=0;i<_NInterface;i++){          
+        okf = fscanf(Para, "%lf\n", &ParaN[0]);
+        sin0 = sin(2.0*Pi*ParaN[0]);
+        cos0 = cos(2.0*Pi*ParaN[0]);
+        Para_Norm[0] = cos1*sin0;
+        Para_Norm[1] = cos1*cos0;
+        Para_Norm[2] = sin1;
+        _Para_Norm.push_back(Para_Norm); 
+        _ParaAngle(i,0) =  ParaN[0];
+      }
+    }
+
+    else if(_Dim==3){
+      for(int i=0;i<_NInterface;i++){
+        okf = fscanf(Para, "%lf %lf\n", &ParaN[0],  &ParaN[1]);
+        sin0 = sin(2.0*Pi*ParaN[0]);
+        cos0 = cos(2.0*Pi*ParaN[0]);
+        sin1 = sin(Pi*ParaN[1]);
+        cos1 = cos(Pi*ParaN[1]);
+        Para_Norm[0] = cos1*sin0;
+        Para_Norm[1] = cos1*cos0;
+        Para_Norm[2] = sin1;
+        _Para_Norm.push_back(Para_Norm); 
+        _ParaAngle(i,0) =  ParaN[0];
+        _ParaAngle(i,1) =  ParaN[1]; 
+      }  
+    }       
+        
+    if(_porous){
+      _NPara_Wt = _NInterface;
+    }
+    else{
+      _NPara_Wt = int(pow(2,(_TotalLevel-1)))-1;
+    }
+    for(int i=0;i<_NPara_Wt;i++){
+      okf = fscanf(Para, "%lf %lf\n", &Para_Wt[0],  &Para_Wt[1]);
+      _Para_Wt.push_back(Para_Wt);
+    }
+  }
+  Msg::Info("Finish reading parameter file, Model = %d, level = %d, Dim = %d, NRoot = %d",Model, _TotalLevel, _Dim, _NRoot);
+}
+   // end of read_parameter
+
+void StochTMDMNDG3DMaterialLaw::reset_Parameter(std::vector<std::vector<double>>& Para_Norm, std::vector<std::vector<double>>& Para_Wt, std::vector<double>& Para_Alpha, const double Vf){
+    
+  double sin0, cos0, sin1,cos1; 
+  double Pi(3.14159265359);
+  if(_Dim==2){
+    sin1 = 0.0;
+    cos1 = 1.0;
+    for(int i=0;i<_NInterface;i++){          
+      sin0 = sin(2.0*Pi*Para_Norm[i][0]);
+      cos0 = cos(2.0*Pi*Para_Norm[i][0]);
+      _Para_Norm[i][0] = cos1*sin0;
+      _Para_Norm[i][1] = cos1*cos0;
+      _Para_Norm[i][2] = sin1;
+      _ParaAngle(i,0) =  Para_Norm[i][0];
+    }  
+  }
+  else if(_Dim==3){          
+    for(int i=0;i<_NInterface;i++){          
+      sin0 = sin(2.0*Pi*Para_Norm[i][0]);
+      cos0 = cos(2.0*Pi*Para_Norm[i][0]);
+      sin1 = sin(Pi*Para_Norm[i][1]);
+      cos1 = cos(Pi*Para_Norm[i][1]);
+      _Para_Norm[i][0] = cos1*sin0;
+      _Para_Norm[i][1] = cos1*cos0;
+      _Para_Norm[i][2] = sin1;
+      _ParaAngle(i,0) =  Para_Norm[i][0];
+      _ParaAngle(i,1) =  Para_Norm[i][1]; 
+    }  
+  }       
+        
+  if(_porous){
+    _NPara_Wt = _NInterface;
+  }  
+  else{  
+    _NPara_Wt = int(pow(2,(_TotalLevel-1)))-1;
+  }
+  for(int i=0;i<_NPara_Wt;i++){          
+    _Para_Wt[i][0] = Para_Wt[i][0]; 
+    _Para_Wt[i][1] = Para_Wt[i][1]; 
+  }      
+  for(int i=0;i<Para_Alpha.size();i++){          
+    _Para_Alpha[i] = _Para_Alpha[i]; 
+    _Para_Alpha[i] = _Para_Alpha[i]; 
+  } 
+  _VA.clear();
+  _VI.clear();
+  _Nv.setAll(0.0);
+  _NTV.setAll(0.0);
+  _NT.setAll(0.0);
+  _V.setAll(0.0);
+  _I.setAll(0.0);
+  _C.setAll(0.0);
+  Jacobian.setAll(0.0);
+  if(Vf!= 0.0){
+    _Vf = Vf;
+  }
+  StochTMDMNDG3DMaterialLaw::fill_Matrices();     
+  //Msg::Info("Finish update parameters of DMN ");       
+}    
+
+void StochTMDMNDG3DMaterialLaw::reset_Parameter(const char* Para){
+  _VA.clear();
+  _VI.clear();
+  _Para_Norm.clear();
+  _Para_Wt.clear();
+  _Para_Alpha.clear();
+  StochTMDMNDG3DMaterialLaw::read_parameter(Para);
+  StochTMDMNDG3DMaterialLaw::fill_Matrices();
+}
+
+void StochTMDMNDG3DMaterialLaw::stress(IPVariable*ipv, const IPVariable*ipvprev, const bool stiff, const bool checkfrac, const bool dTangent){
+   
+   // get ipvariable 
+  StochTMDMNDG3DIPVariable* ipvcur = static_cast<StochTMDMNDG3DIPVariable*>(ipv);
+  const StochTMDMNDG3DIPVariable* ipv_prev = static_cast<const StochTMDMNDG3DIPVariable*>(ipvprev);
+  const STensor3& F = ipvcur->getConstRefToDeformationGradient();
+  const SVector3& H = ipvcur->getConstRefToGradT();
+  const double T    = ipvcur->getConstRefToTemperature();
+
+  STensor3& P = ipvcur->getRefToFirstPiolaKirchhoffStress(); STensorOperation::zero(P);
+  SVector3& Q = ipvcur->getRefToThermalFlux(); STensorOperation::zero(Q);
+  double& w   = ipvcur->getRefToThermalSource();
+  double& Cp         = ipvcur->getRefToExtraDofFieldCapacityPerUnitField()(0);
+  double& mechSource = ipvcur->getRefToMechanicalSource()(0);
+
+  STensor43& L       = ipvcur->getRefToTangentModuli(); STensorOperation::zero(L);
+  STensor3& dPdT     = ipvcur->getRefTodPdT(); STensorOperation::zero(dPdT);
+  STensor3& dqdgradT = ipvcur->getRefTodThermalFluxdGradT(); STensorOperation::zero(dqdgradT);
+  SVector3& dqdT     = ipvcur->getRefTodThermalFluxdT(); STensorOperation::zero(dqdT);
+  STensor33& dqdF    = ipvcur->getRefTodThermalFluxdF(); STensorOperation::zero(dqdF);
+  double& dwdt       = ipvcur->getRefTodThermalSourcedField();
+  STensor3& dwdf     = ipvcur->getRefTodThermalSourcedF(); STensorOperation::zero(dwdf);
+  double& dmechSourcedt = ipvcur->getRefTodMechanicalSourcedField()(0,0);
+  STensor3& dmechSourcedf = ipvcur->getRefTodMechanicalSourcedF()[0]; STensorOperation::zero(dmechSourcedf);
+  double dCpdT(0.);
+  STensor3 dCpdF; STensorOperation::zero(dCpdF);
+  STensor33 dPdgradT; STensorOperation::zero(dPdgradT);
+
+
+  double C_hom[_col_Di][_col_Di]; // static
+  double P_hom[_col_Di]; //static
+  // std::vector<double> P_hom;
+
+  // fullVector<double>& Fvec = ipvcur->getRefToDeformationGradientVect();
+  // fullVector<double>& Pvec = ipvcur->getRefToFirstPiolaKirchhoffStressVect();
+  // fullVector<double>& a_cur = ipvcur->getRefToInterfaceFluctuationVect();
+
+  fullVector<double>& FHvec = ipvcur->getRefToCombinedGradientVect();
+  fullVector<double>& PQvec = ipvcur->getRefToCombinedStressVect();
+  fullVector<double>& ab_cur = ipvcur->getRefToCombinedInterfaceFluctuationVect();
+
+  // Pvec.setAll(0.0); 
+  PQvec.setAll(0.0);
+  static fullVector<double> Res_node_t(_row_Di*_NInterface);
+  static fullVector<double> Res_node(_row_Di*_NInterface);
+  static fullVector<double> a_step(_row_Di*_NInterface);
+  static fullMatrix<double> NTVC(_row_Di*_NInterface, _col_Di*_NRoot);
+  static fullMatrix<double> Jacobian_inv(_row_Di*_NInterface, _row_Di*_NInterface); 
+  static fullMatrix<double> Modify_Jacobian(_row_Di*_NInterface, _row_Di*_NInterface); 
+  static fullMatrix<double> tmp(_col_Di*_NRoot, _col_Di); 
+  static fullMatrix<double> dRdF(_row_Di*_NInterface, _col_Di); 
+  static fullMatrix<double> dadF(_row_Di*_NInterface, _col_Di); 
+    
+  Res_node_t.setAll(0.0);
+  Res_node.setAll(0.0);
+  a_step.setAll(0.0);
+  _C.setAll(0.0);
+  NTVC.setAll(0.0); 
+  Jacobian.setAll(0.0);
+  dRdF.setAll(0.0);
+  dadF.setAll(0.0);
+  tmp.setAll(0.0);
+  int ite = 0;
+  double r = 1.0;
+  bool last = false;
+  int pos_start = _N_Node-_NRoot;
+  int max_iter= 15;
+  bool stiff_loc = true;
+
+
+  while( (r>_tol and ite < max_iter) or last){
+  //  if((1+ite)%5 == 0) stiff_loc=false;
+    ite +=1;
+    _Nv.mult(ab_cur, FHvec);
+    for(int i=0; i<_NRoot; i++){
+      if (_VA[pos_start+i] > 1.e-6){
+        ThermoMechanicsDG3DIPVariableBase* ipv_i = dynamic_cast<ThermoMechanicsDG3DIPVariableBase*>(ipvcur->getIPv(i));
+        const ThermoMechanicsDG3DIPVariableBase* ipvprev_i = dynamic_cast<const ThermoMechanicsDG3DIPVariableBase*>(ipv_prev->getIPv(i));
+
+        STensor3& Floc = ipv_i->getRefToDeformationGradient();
+        SVector3& Hloc = ipv_i->getRefToGradT();
+        double& Tloc   = ipv_i->getRefToTemperature();
+
+        if (_flag_isothermal && _flag_microTempFixed){
+          Tloc = T;
+          Hloc = H;
+          for(int m=0; m<3; m++){
+            for(int n=0; n<3; n++){
+              Floc(m,n) = F(m,n) + FHvec(i*_col_Di + m + n*_row_Di);
+            }
+          }
+        }
+        else if(!_flag_isothermal && _flag_microTempFixed){
+          Tloc = T;
+          for(int m=0; m<3; m++){
+            Hloc(m) = H(m) + FHvec(i*_col_Di+ (m+1)*_row_Di-1);
+            for(int n=0; n<3; n++){
+              Floc(m,n) = F(m,n) + FHvec(i*_col_Di + m + n*_row_Di);
+            }
+          }
+        }
+        else if(!_flag_isothermal && !_flag_microTempFixed){
+          Tloc = T + FHvec((i+1)*_col_Di-1);
+          for(int m=0; m<3; m++){
+            Hloc(m) = H(m) + FHvec(i*_col_Di+ (m+1)*(_row_Di-1)-1);  
+            for(int n=0; n<3; n++){
+              Floc(m,n) = F(m,n) + FHvec(i*_col_Di + m + n*(_row_Di-1));
+            }
+          }
+        }
+        else{
+          Msg::Error("This combination of flags doesn't exist. Redefine in the constructor.");
+        }
+
+        int mat_IP = 0;
+        if(_Modified_DMN){
+          if(i%3 == 1) mat_IP = 1; // CHECK THIS FLAG
+        }
+        else{
+           mat_IP = i%2;
+        }
+
+        if(_porous) mat_IP=0;
+        _mapLaw[mat_IP]->stress(ipv_i, ipvprev_i, stiff_loc, checkfrac, dTangent);
+        const STensor3& P_i        = ipv_i->getConstRefToFirstPiolaKirchhoffStress();
+        const SVector3& Q_i        = ipv_i->getConstRefToThermalFlux();
+        const double& w_i          = ipv_i->getConstRefToThermalSource();
+        const double& Cp_i         = ipv_i->getConstRefToExtraDofFieldCapacityPerUnitField()(0);
+        const double& mechSource_i = ipv_i->getConstRefToMechanicalSource()(0);
+
+        if (_flag_isothermal && _flag_microTempFixed){
+          for(int m=0; m<3; m++){
+            for(int n=0; n<3; n++){
+              PQvec(i*_col_Di + m + n*_row_Di) = P_i(m,n);
+            }
+          }
+        }
+        else if(!_flag_isothermal && _flag_microTempFixed){
+          for(int m=0; m<3; m++){
+            PQvec(i*_col_Di + (m+1)*_row_Di-1) = Q_i(m);
+            for(int n=0; n<3; n++){
+              PQvec(i*_col_Di + m + n*_row_Di) = P_i(m,n); 
+            }
+          }
+        }
+        else if(!_flag_isothermal && !_flag_microTempFixed){
+          PQvec((i+1)*_col_Di-1) = Cp_i;
+          for(int m=0; m<3; m++){
+            PQvec(i*_col_Di + (m+1)*(_row_Di-1)-1) = Q_i(m);
+            for(int n=0; n<3; n++){
+              PQvec(i*_col_Di + m + n*(_row_Di-1)) = P_i(m,n); 
+            }
+          }
+        }
+        else{
+          Msg::Error("This combination of flags doesn't exist. Redefine in the constructor.");
+        }
+
+
+        if(stiff_loc){
+          const STensor43& L_i       = ipv_i->getConstRefToTangentModuli();
+          const STensor3& dPdT_i     = ipv_i->getRefTodPdT();
+          const STensor3& dqdgradT_i = ipv_i->getRefTodThermalFluxdGradT(); 
+          const SVector3& dqdT_i     = ipv_i->getRefTodThermalFluxdT();
+          const STensor33& dqdF_i    = ipv_i->getRefTodThermalFluxdF(); 
+          // const double& dwdt_i       = ipv_i->getRefTodThermalSourcedField();
+          // const STensor3& dwdf_i     = ipv_i->getRefTodThermalSourcedF(); STensorOperation::zero(dwdf);
+          // const double& dmechSourcedt_i = ipv_i->getRefTodMechanicalSourcedField()(0,0);
+          // const STensor3& dmechSourcedf_i = ipv_i->getRefTodMechanicalSourcedF()[0]; 
+          
+          // CHECK with python AND DEBUG the tangents
+          if (_flag_isothermal && _flag_microTempFixed){
+            for(int m=0; m<3; m++)
+              for(int n=0; n<3; n++)
+                for(int k=0; k<3; k++)
+                  for(int l=0; l<3; l++)  
+                    _C(i*_col_Di+m+_row_Di*n, i*_col_Di+k+_row_Di*l) = L_i(m,n,k,l);
+          }
+          else if(!_flag_isothermal && _flag_microTempFixed){
+            for(int m=0; m<3; m++)
+              for(int n=0; n<3; n++){
+                _C(i*_col_Di + (m+1)*_row_Di-1, i*_col_Di + (n+1)*_row_Di-1) = dqdgradT_i(m,n);
+                for(int k=0; k<3; k++){
+                  _C(i*_col_Di + (m+1)*_row_Di-1, i*_col_Di+n+_row_Di*k) = dqdF_i(m,n,k);
+                  // _C(i*_col_Di+m+_row_Di*n, i*_col_Di + (k+1)*_row_Di-1) = 0.;
+                  for(int l=0; l<3; l++)  
+                    _C(i*_col_Di+m+_row_Di*n, i*_col_Di+k+_row_Di*l) = L_i(m,n,k,l);
+                }    
+              }
+          }
+          else if(!_flag_isothermal && !_flag_microTempFixed){
+            for(int m=0; m<3; m++){
+              _C(i*_col_Di + (m+1)*(_row_Di-1)-1, (i+1)*_col_Di-1) = dqdT_i(m);
+              for(int n=0; n<3; n++){
+                _C(i*_col_Di + (m+1)*(_row_Di-1)-1, i*_col_Di + (n+1)*(_row_Di-1)-1) = dqdgradT_i(m,n);
+                _C(i*_col_Di + m + n*(_row_Di-1), (i+1)*_col_Di-1) = dPdT_i(m,n);
+                for(int k=0; k<3; k++){
+                  _C(i*_col_Di + (m+1)*(_row_Di-1)-1, i*_col_Di+n+(_row_Di-1)*k) = dqdF_i(m,n,k);
+                  // _C(i*_col_Di+m+(_row_Di-1)*n, i*_col_Di + (k+1)*(_row_Di-1)-1) = 0.;
+                  for(int l=0; l<3; l++)  
+                    _C(i*_col_Di+m+(_row_Di-1)*n, i*_col_Di+k+(_row_Di-1)*l) = L_i(m,n,k,l);
+                }    
+              }
+            }
+          }
+
+
+        }
+      }
+    }
+
+    _NTV.mult(PQvec, Res_node);
+    r = Res_node.norm()/_NInterface;
+
+    if(r<_tol){
+      if(last or stiff_loc){
+        _NTV.mult(_C, NTVC);
+        NTVC.mult(_Nv, Jacobian);
+        Jacobian.invertInPlace();
+        break;
+      }
+      else{
+        last = true;
+        stiff_loc = true;
+      }  
+    } 
+            
+    else{         
+      if(stiff_loc){         
+        _NTV.mult(_C, NTVC);
+        NTVC.mult(_Nv, Jacobian);
+        Jacobian.invertInPlace();
+      }
+      else{
+        // What is this? HOw does the following update the jacobian?
+        _NTV.mult(PQvec, Res_node);
+        Res_node_t.scale(-1.0);
+        Res_node_t.axpy(Res_node, 1.0);
+
+        double Rho = 1.0/(Res_node_t*a_step);
+        Modify_Jacobian.setAll(0.0);
+        for(int i =0; i<3*_NInterface; i++){
+          Modify_Jacobian(i,i) = 1.0;
+          for(int j =0; j<3*_NInterface; j++){
+            Modify_Jacobian(i,j) -= a_step(i)*Res_node_t(j)*Rho;
+          }
+        }
+        Modify_Jacobian.mult(Jacobian,Jacobian_inv);
+        Modify_Jacobian.transposeInPlace();
+        Jacobian_inv.mult(Modify_Jacobian,Jacobian);
+
+        for(int i =0; i<3*_NInterface; i++){
+          for(int j =0; j<3*_NInterface; j++){
+            Jacobian(i,j) += a_step(i)*a_step(j)*Rho;
+          }
+        }
+        stiff_loc = true;
+        // What?
+      }
+
+      Res_node_t = Res_node;
+      Jacobian.mult(Res_node, a_step);
+      a_step.scale(-1.0);
+      ab_cur.axpy(a_step, 1.0);
+    }
+  }
+  Jacobian.scale(-1.0);
+
+  if(r>_tol){
+    Msg::Error("DMN residual (= %lf) did n't converge to tolenerce after %d iteration",r,ite);
+    return;
+  }
+  else{
+    for(int m=0;m<_col_Di;m++){
+      P_hom[m] = 0.0;
+      for(int i=0;i<_NRoot;i++){
+        P_hom[m] += (_VA[1]*_V(m, _col_Di*i+m) + _VA[2]*_V(_col_Di+m, _col_Di*i+m)) *PQvec(_col_Di*i+m); // CHECK
+      }
+    }
+    if (_flag_isothermal && _flag_microTempFixed){
+      for(int i=0;i<3;i++){
+        for(int j=0;j<3;j++){
+          P(i,j) = P_hom[i+_row_Di*j]; // CHECK
+        }
+      }
+    }
+    else if(!_flag_isothermal && _flag_microTempFixed){
+      for(int i=0;i<3;i++){
+        Q(i) = P_hom[(i+1)*_row_Di-1];
+        for(int j=0;j<3;j++){
+          P(i,j) = P_hom[i+_row_Di*j]; // CHECK
+        }
+      }
+    }
+    else if(!_flag_isothermal && !_flag_microTempFixed){
+      Cp = P_hom[_col_Di-1];
+      for(int i=0;i<3;i++){
+        Q(i) = P_hom[(i+1)*(_row_Di-1)-1];
+        for(int j=0;j<3;j++){
+          P(i,j) = P_hom[i+(_row_Di-1)*j]; // CHECK
+        }
+      }  
+    }
+
+    if(stiff){
+      NTVC.mult(_I, dRdF);
+      Jacobian.mult(dRdF, dadF);
+      _Nv.mult(dadF, tmp);
+      tmp.add(_I);
+
+      for(int m=0;m<_col_Di;m++){
+        for(int n=0;n<_col_Di;n++){
+          C_hom[m][n] = 0.0;
+          for(int i=0;i<_NRoot;i++){
+            for(int j=0;j< _col_Di*_NRoot;j++){
+              C_hom[m][n] += (_VA[1]*_V(m,m+_col_Di*i) + _VA[2]*_V(_col_Di+m,m+_col_Di*i))*_C(m+_col_Di*i,j)*tmp(j,n); // CHECK
+            }
+          }
+        }
+      }
+
+      if (_flag_isothermal && _flag_microTempFixed){
+        for(int m=0; m<3; m++)
+          for(int n=0; n<3; n++)
+            for(int k=0; k<3; k++)
+              for(int l=0; l<3; l++)  
+                L(m,n,k,l) = C_hom[m+_row_Di*n][k+_row_Di*l];
+      }
+      else if(!_flag_isothermal && _flag_microTempFixed){
+        for(int m=0; m<3; m++)
+          for(int n=0; n<3; n++){
+            dqdgradT(m,n) = C_hom[(m+1)*_row_Di-1][(n+1)*_row_Di-1];
+              for(int k=0; k<3; k++){
+                dqdF(m,n,k) = C_hom[(m+1)*_row_Di-1][n+_row_Di*k];
+                // dPdgradT(m,n,l) = C_hom[m+_row_Di*n][(k+1)*_row_Di-1]; // 0.
+                for(int l=0; l<3; l++)  
+                  L(m,n,k,l) = C_hom[m+_row_Di*n][k+_row_Di*l];
+              }    
+            }
+      }
+      else if(!_flag_isothermal && !_flag_microTempFixed){
+        for(int m=0; m<3; m++){
+          dqdT(m) = C_hom[(m+1)*(_row_Di-1)-1][_col_Di-1];
+          for(int n=0; n<3; n++){
+            dqdgradT(m,n) = C_hom[(m+1)*(_row_Di-1)-1][(n+1)*(_row_Di-1)-1];
+            dPdT(m,n) = C_hom[m + n*(_row_Di-1)][_col_Di-1];
+            for(int k=0; k<3; k++){
+              dqdF(m,n,k) = C_hom[(m+1)*(_row_Di-1)-1][n+(_row_Di-1)*k];
+              // C_hom[m+(_row_Di-1)*n][(k+1)*(_row_Di-1)-1] = 0.;
+              for(int l=0; l<3; l++)  
+                L(m,n,k,l) = C_hom[m+(_row_Di-1)*n][k+(_row_Di-1)*l];
+              }    
+            }
+        }
+      }
+    }
+  }
+  ipvcur->setRefToDGElasticTangentModuli(this->elasticStiffness);
+} 
+
+void StochTMDMNDG3DMaterialLaw::setTime(const double t,const double dtime){
+  dG3DMaterialLaw::setTime(t,dtime);
+  for (std::vector<dG3DMaterialLaw*>::iterator it = _mapLaw.begin(); it != _mapLaw.end(); it++) {
+    (*it)->setTime(t,dtime);
+  }
+}
+
+// end of stress
+
+// 
 J2SmallStrainDG3DMaterialLaw::J2SmallStrainDG3DMaterialLaw(const int num,const double rho,
                                    double E,const double nu,const double sy0,const double h,
                                    const double tol,const bool tangentByPert, const double pert) : dG3DMaterialLaw(num,rho,true),
diff --git a/dG3D/src/dG3DMaterialLaw.h b/dG3D/src/dG3DMaterialLaw.h
index fec86adf5..6f845d6ca 100644
--- a/dG3D/src/dG3DMaterialLaw.h
+++ b/dG3D/src/dG3DMaterialLaw.h
@@ -692,7 +692,7 @@ class StochDMNDG3DMaterialLaw : public dG3DMaterialLaw{
   protected:
     #ifndef SWIG
     bool _porous;
-    bool _Modified_DMN;
+    bool _Modified_DMN;  // What is this flag?
     int _TotalLevel;
     int _NRoot;
     int _NInterface;
@@ -768,15 +768,21 @@ class StochDMNDG3DMaterialLaw : public dG3DMaterialLaw{
  };   
 
 // FLE
-/*
-class StochTMDMNDG3DMaterialLaw : public StochTMDMNDG3DMaterialLaw{
+class StochTMDMNDG3DMaterialLaw : public StochDMNDG3DMaterialLaw{
   protected:
     #ifndef SWIG
-
+    int _col_Di, _row_Di;
+    bool _flag_isothermal;
+    bool _flag_microTempFixed;
+    std::vector<double> _Para_Alpha; // vector of coefficients 
+    void fill_Matrices();
+    void read_parameter(const char *ParaFile);
+    void fill_NLocal(const int pos,  std::vector<std::vector<double>> N)const;
+    void pos_kids(const int pos, const int level, int& pos0, int& pos1) const;
     #endif //SWIG
   public:
-    StochTMDMNDG3DMaterialLaw(const int num, const double rho, const double E,const double nu, const char *ParaFile,const bool porous,const double tol=1e-6);
-    void addLaw(dG3DMaterialLaw* law);
+    StochTMDMNDG3DMaterialLaw(const int num, const double rho, const double E,const double nu, const char *ParaFile,
+                      const bool porous, const bool flag_isothermal, const bool flag_microTempFixed, const double tol=1e-6);
     #ifndef SWIG
     StochTMDMNDG3DMaterialLaw(const StochTMDMNDG3DMaterialLaw &source);
     virtual ~StochTMDMNDG3DMaterialLaw();
@@ -787,7 +793,6 @@ class StochTMDMNDG3DMaterialLaw : public StochTMDMNDG3DMaterialLaw{
     virtual void createIPState(IPStateBase* &ips, bool hasBodyForce, const bool* state_=NULL,const MElement *ele=NULL, const int nbFF_=0, const IntPt *GP=NULL, const int gpt = 0) const;
     virtual void createIPVariable(IPVariable* &ipv, bool hasBodyForce, const MElement *ele, const int nbFF_, const IntPt *GP, const int gpt) const;
     virtual void initialIPVariable(IPVariable* ipv, bool stiff);   
-    virtual void initLaws(const std::map<int,materialLaw*> &maplaw);
     virtual double scaleFactor() const {return 1.;};
     virtual double soundSpeed() const {return 0.;};
     virtual materialLaw* clone() const {return new StochTMDMNDG3DMaterialLaw(*this);};
@@ -806,12 +811,10 @@ class StochTMDMNDG3DMaterialLaw : public StochTMDMNDG3DMaterialLaw{
       return NULL;
     }
     virtual void setMacroSolver(const nonLinearMechSolver* sv);
-    virtual void getParameterDerivative(const IPVariable*ipv, std::vector< fullMatrix<double> >& dPdPn, std::vector< fullMatrix<double> >&dPdPv) const;
-    virtual void reset_Parameter(std::vector<std::vector<double>>& Para_Norm, std::vector<std::vector<double>>& Para_Wt, const double Vf = 0.0);
     virtual void reset_Parameter(const char* Para);
+    virtual void reset_Parameter(std::vector<std::vector<double>>& Para_Norm, std::vector<std::vector<double>>& Para_Wt, std::vector<double>& Para_Alpha, const double Vf);
     #endif //SWIG
  }; 
- */
 // FLE
 
 class J2SmallStrainDG3DMaterialLaw : public dG3DMaterialLaw
-- 
GitLab


From 82f1ba4dfac35fd416971224b7fc8211a5d44783 Mon Sep 17 00:00:00 2001
From: FLE_Knight <ujwalkishore.jinaga@uliege.be>
Date: Sat, 11 Jan 2025 17:37:27 +0100
Subject: [PATCH 05/19] [NEW PATCH] The risizing of FHvec and PQvec needs a fix

---
 dG3D/src/dG3DMaterialLaw.cpp | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/dG3D/src/dG3DMaterialLaw.cpp b/dG3D/src/dG3DMaterialLaw.cpp
index 27248d835..1d8317f54 100644
--- a/dG3D/src/dG3DMaterialLaw.cpp
+++ b/dG3D/src/dG3DMaterialLaw.cpp
@@ -5602,6 +5602,11 @@ void StochTMDMNDG3DMaterialLaw::stress(IPVariable*ipv, const IPVariable*ipvprev,
   fullVector<double>& PQvec = ipvcur->getRefToCombinedStressVect();
   fullVector<double>& ab_cur = ipvcur->getRefToCombinedInterfaceFluctuationVect();
 
+  bool resizeFlag; // CHECK THIS, IP definition is different
+  resizeFlag = FHvec.resize(_col_Di, true);
+  resizeFlag = PQvec.resize(_col_Di, true);
+  resizeFlag = ab_cur.resize(_row_Di, true);
+
   // Pvec.setAll(0.0); 
   PQvec.setAll(0.0);
   static fullVector<double> Res_node_t(_row_Di*_NInterface);
-- 
GitLab


From 5ad28b82d61befc606a137b414f69018ebb1c473 Mon Sep 17 00:00:00 2001
From: FLE_Knight <ujwalkishore.jinaga@uliege.be>
Date: Mon, 13 Jan 2025 15:56:06 +0100
Subject: [PATCH 06/19] [NEW FEATURE] Added simple columnwise stacking for
 PQvec and FHvec, and their tangents.

---
 dG3D/src/dG3DMaterialLaw.cpp | 107 +++++++++++++++++++++++------------
 1 file changed, 71 insertions(+), 36 deletions(-)

diff --git a/dG3D/src/dG3DMaterialLaw.cpp b/dG3D/src/dG3DMaterialLaw.cpp
index 1d8317f54..e6868d781 100644
--- a/dG3D/src/dG3DMaterialLaw.cpp
+++ b/dG3D/src/dG3DMaterialLaw.cpp
@@ -5217,18 +5217,28 @@ void StochTMDMNDG3DMaterialLaw::fill_NLocal(const int pos, std::vector<std::vect
     N.resize(_col_Di);
     for(auto& row : N)
       row.resize(_row_Di,0.);
-    N[0][0] = n0; N[1][1] = n0; N[2][2] = n0;  N[3][3] = n0;
-    N[4][0] = n1; N[5][1] = n1; N[6][2] = n1;  N[7][3] = n1;
-    N[8][0] = n2; N[9][1] = n2; N[10][2] = n2; N[11][3] = n2; 
+    // N[0][0] = n0; N[1][1] = n0; N[2][2] = n0;  N[3][3] = n0;
+    // N[4][0] = n1; N[5][1] = n1; N[6][2] = n1;  N[7][3] = n1;
+    // N[8][0] = n2; N[9][1] = n2; N[10][2] = n2; N[11][3] = n2; 
+    N[0][0] = n0; N[1][1] = n0; N[2][2] = n0;
+    N[3][0] = n1; N[4][1] = n1; N[5][2] = n1;
+    N[6][0] = n2; N[7][1] = n2; N[8][2] = n2;
+    N[9][3] = n0; N[10][3] = n1; N[11][3] = n2;
   }
   else if(!_flag_isothermal && !_flag_microTempFixed){
     N.resize(_col_Di);
     for(auto& row : N)
       row.resize(_row_Di,0.);
-    N[0][0] = n0; N[1][1] = n0; N[2][2] = n0;  N[3][3] = n0;
-    N[4][0] = n1; N[5][1] = n1; N[6][2] = n1;  N[7][3] = n1;
-    N[8][0] = n2; N[9][1] = n2; N[10][2] = n2; N[11][3] = n2; 
-    N[13][4] = 1.;
+    // N[0][0] = n0; N[1][1] = n0; N[2][2] = n0;  N[3][3] = n0;
+    // N[4][0] = n1; N[5][1] = n1; N[6][2] = n1;  N[7][3] = n1;
+    // N[8][0] = n2; N[9][1] = n2; N[10][2] = n2; N[11][3] = n2; 
+    // N[12][4] = 1.;
+
+    N[0][0] = n0; N[1][1] = n0; N[2][2] = n0;
+    N[3][0] = n1; N[4][1] = n1; N[5][2] = n1;
+    N[6][0] = n2; N[7][1] = n2; N[8][2] = n2;
+    N[9][3] = n0; N[10][3] = n1; N[11][3] = n2;
+    N[12][4] = 1.;
   }
   else{
     Msg::Error("This combination of flags doesn't exist. Redefine in the constructor.");
@@ -5661,18 +5671,22 @@ void StochTMDMNDG3DMaterialLaw::stress(IPVariable*ipv, const IPVariable*ipvprev,
         else if(!_flag_isothermal && _flag_microTempFixed){
           Tloc = T;
           for(int m=0; m<3; m++){
-            Hloc(m) = H(m) + FHvec(i*_col_Di+ (m+1)*_row_Di-1);
+            // Hloc(m) = H(m) + FHvec(i*_col_Di+ (m+1)*_row_Di-1);
+            Hloc(m) = H(m) + FHvec(i*_col_Di+ 9+m);
             for(int n=0; n<3; n++){
-              Floc(m,n) = F(m,n) + FHvec(i*_col_Di + m + n*_row_Di);
+              // Floc(m,n) = F(m,n) + FHvec(i*_col_Di + m + n*_row_Di);
+              Floc(m,n) = F(m,n) + FHvec(i*_col_Di + m + n*3);
             }
           }
         }
         else if(!_flag_isothermal && !_flag_microTempFixed){
           Tloc = T + FHvec((i+1)*_col_Di-1);
           for(int m=0; m<3; m++){
-            Hloc(m) = H(m) + FHvec(i*_col_Di+ (m+1)*(_row_Di-1)-1);  
+            // Hloc(m) = H(m) + FHvec(i*_col_Di+ (m+1)*(_row_Di-1)-1);  
+            Hloc(m) = H(m) + FHvec(i*_col_Di+ 9+m);
             for(int n=0; n<3; n++){
-              Floc(m,n) = F(m,n) + FHvec(i*_col_Di + m + n*(_row_Di-1));
+              // Floc(m,n) = F(m,n) + FHvec(i*_col_Di + m + n*(_row_Di-1));
+              Floc(m,n) = F(m,n) + FHvec(i*_col_Di + m + n*3);
             }
           }
         }
@@ -5705,18 +5719,22 @@ void StochTMDMNDG3DMaterialLaw::stress(IPVariable*ipv, const IPVariable*ipvprev,
         }
         else if(!_flag_isothermal && _flag_microTempFixed){
           for(int m=0; m<3; m++){
-            PQvec(i*_col_Di + (m+1)*_row_Di-1) = Q_i(m);
+            // PQvec(i*_col_Di + (m+1)*_row_Di-1) = Q_i(m);
+            PQvec(i*_col_Di+ 9+m) = Q_i(m);
             for(int n=0; n<3; n++){
-              PQvec(i*_col_Di + m + n*_row_Di) = P_i(m,n); 
+              // PQvec(i*_col_Di + m + n*_row_Di) = P_i(m,n); 
+              PQvec(i*_col_Di + m + n*3) = P_i(m,n);
             }
           }
         }
         else if(!_flag_isothermal && !_flag_microTempFixed){
           PQvec((i+1)*_col_Di-1) = Cp_i;
           for(int m=0; m<3; m++){
-            PQvec(i*_col_Di + (m+1)*(_row_Di-1)-1) = Q_i(m);
+            // PQvec(i*_col_Di + (m+1)*(_row_Di-1)-1) = Q_i(m);
+            PQvec(i*_col_Di+ 9+m) = Q_i(m);
             for(int n=0; n<3; n++){
-              PQvec(i*_col_Di + m + n*(_row_Di-1)) = P_i(m,n); 
+              // PQvec(i*_col_Di + m + n*(_row_Di-1)) = P_i(m,n); 
+              PQvec(i*_col_Di + m + n*3) = P_i(m,n);
             }
           }
         }
@@ -5747,12 +5765,15 @@ void StochTMDMNDG3DMaterialLaw::stress(IPVariable*ipv, const IPVariable*ipvprev,
           else if(!_flag_isothermal && _flag_microTempFixed){
             for(int m=0; m<3; m++)
               for(int n=0; n<3; n++){
-                _C(i*_col_Di + (m+1)*_row_Di-1, i*_col_Di + (n+1)*_row_Di-1) = dqdgradT_i(m,n);
+                // _C(i*_col_Di + (m+1)*_row_Di-1, i*_col_Di + (n+1)*_row_Di-1) = dqdgradT_i(m,n);
+                _C(i*_col_Di + 9+m, i*_col_Di + 9+m) = dqdgradT_i(m,n);
                 for(int k=0; k<3; k++){
-                  _C(i*_col_Di + (m+1)*_row_Di-1, i*_col_Di+n+_row_Di*k) = dqdF_i(m,n,k);
-                  // _C(i*_col_Di+m+_row_Di*n, i*_col_Di + (k+1)*_row_Di-1) = 0.;
+                  // _C(i*_col_Di + (m+1)*_row_Di-1, i*_col_Di+n+_row_Di*k) = dqdF_i(m,n,k);
+                  // _C(i*_col_Di+m+_row_Di*n, i*_col_Di + (k+1)*_row_Di-1) = 0.; // This is for dPdgradT_i
+                  _C(i*_col_Di + 9+m, i*_col_Di+n+3*k) = dqdF_i(m,n,k);
                   for(int l=0; l<3; l++)  
-                    _C(i*_col_Di+m+_row_Di*n, i*_col_Di+k+_row_Di*l) = L_i(m,n,k,l);
+                    // _C(i*_col_Di+m+_row_Di*n, i*_col_Di+k+_row_Di*l) = L_i(m,n,k,l);
+                    _C(i*_col_Di+m+3*n, i*_col_Di+k+3*l) = L_i(m,n,k,l);
                 }    
               }
           }
@@ -5760,13 +5781,17 @@ void StochTMDMNDG3DMaterialLaw::stress(IPVariable*ipv, const IPVariable*ipvprev,
             for(int m=0; m<3; m++){
               _C(i*_col_Di + (m+1)*(_row_Di-1)-1, (i+1)*_col_Di-1) = dqdT_i(m);
               for(int n=0; n<3; n++){
-                _C(i*_col_Di + (m+1)*(_row_Di-1)-1, i*_col_Di + (n+1)*(_row_Di-1)-1) = dqdgradT_i(m,n);
-                _C(i*_col_Di + m + n*(_row_Di-1), (i+1)*_col_Di-1) = dPdT_i(m,n);
+                // _C(i*_col_Di + (m+1)*(_row_Di-1)-1, i*_col_Di + (n+1)*(_row_Di-1)-1) = dqdgradT_i(m,n);
+                // _C(i*_col_Di + m + n*(_row_Di-1), (i+1)*_col_Di-1) = dPdT_i(m,n);
+                _C(i*_col_Di + 9+m, i*_col_Di + 9+m) = dqdgradT_i(m,n);
+                _C(i*_col_Di + m + 3*n, (i+1)*_col_Di-1) = dPdT_i(m,n);
                 for(int k=0; k<3; k++){
-                  _C(i*_col_Di + (m+1)*(_row_Di-1)-1, i*_col_Di+n+(_row_Di-1)*k) = dqdF_i(m,n,k);
-                  // _C(i*_col_Di+m+(_row_Di-1)*n, i*_col_Di + (k+1)*(_row_Di-1)-1) = 0.;
+                  // _C(i*_col_Di + (m+1)*(_row_Di-1)-1, i*_col_Di+n+(_row_Di-1)*k) = dqdF_i(m,n,k);
+                  // _C(i*_col_Di+m+(_row_Di-1)*n, i*_col_Di + (k+1)*(_row_Di-1)-1) = 0.; // This is for dPdgradT_i
+                  _C(i*_col_Di + 9+m, i*_col_Di+n+3*k) = dqdF_i(m,n,k);
                   for(int l=0; l<3; l++)  
-                    _C(i*_col_Di+m+(_row_Di-1)*n, i*_col_Di+k+(_row_Di-1)*l) = L_i(m,n,k,l);
+                    // _C(i*_col_Di+m+(_row_Di-1)*n, i*_col_Di+k+(_row_Di-1)*l) = L_i(m,n,k,l);
+                    _C(i*_col_Di+m+3*n, i*_col_Di+k+3*l) = L_i(m,n,k,l);
                 }    
               }
             }
@@ -5854,18 +5879,22 @@ void StochTMDMNDG3DMaterialLaw::stress(IPVariable*ipv, const IPVariable*ipvprev,
     }
     else if(!_flag_isothermal && _flag_microTempFixed){
       for(int i=0;i<3;i++){
-        Q(i) = P_hom[(i+1)*_row_Di-1];
+        // Q(i) = P_hom[(i+1)*_row_Di-1];
+        Q(i) = P_hom[9+i];
         for(int j=0;j<3;j++){
-          P(i,j) = P_hom[i+_row_Di*j]; // CHECK
+          // P(i,j) = P_hom[i+_row_Di*j]; // CHECK
+          P(i,j) = P_hom[i+3*j]; // CHECK
         }
       }
     }
     else if(!_flag_isothermal && !_flag_microTempFixed){
       Cp = P_hom[_col_Di-1];
       for(int i=0;i<3;i++){
-        Q(i) = P_hom[(i+1)*(_row_Di-1)-1];
+        // Q(i) = P_hom[(i+1)*(_row_Di-1)-1];
+        Q(i) = P_hom[9+i];
         for(int j=0;j<3;j++){
-          P(i,j) = P_hom[i+(_row_Di-1)*j]; // CHECK
+          // P(i,j) = P_hom[i+(_row_Di-1)*j]; // CHECK
+          P(i,j) = P_hom[i+3*j]; // CHECK
         }
       }  
     }
@@ -5897,12 +5926,15 @@ void StochTMDMNDG3DMaterialLaw::stress(IPVariable*ipv, const IPVariable*ipvprev,
       else if(!_flag_isothermal && _flag_microTempFixed){
         for(int m=0; m<3; m++)
           for(int n=0; n<3; n++){
-            dqdgradT(m,n) = C_hom[(m+1)*_row_Di-1][(n+1)*_row_Di-1];
+            // dqdgradT(m,n) = C_hom[(m+1)*_row_Di-1][(n+1)*_row_Di-1];
+            dqdgradT(m,n) = C_hom[9+m][9+n];
               for(int k=0; k<3; k++){
-                dqdF(m,n,k) = C_hom[(m+1)*_row_Di-1][n+_row_Di*k];
-                // dPdgradT(m,n,l) = C_hom[m+_row_Di*n][(k+1)*_row_Di-1]; // 0.
+                // dqdF(m,n,k) = C_hom[(m+1)*_row_Di-1][n+_row_Di*k];
+                dqdF(m,n,k) = C_hom[9+m][n+3*k];
+                // dPdgradT(m,n,l) = C_hom[m+_row_Di*n][(k+1)*_row_Di-1]; // 0. This is for dPdgradT
                 for(int l=0; l<3; l++)  
-                  L(m,n,k,l) = C_hom[m+_row_Di*n][k+_row_Di*l];
+                  // L(m,n,k,l) = C_hom[m+_row_Di*n][k+_row_Di*l];
+                  L(m,n,k,l) = C_hom[m+3*n][k+3*l];
               }    
             }
       }
@@ -5910,13 +5942,16 @@ void StochTMDMNDG3DMaterialLaw::stress(IPVariable*ipv, const IPVariable*ipvprev,
         for(int m=0; m<3; m++){
           dqdT(m) = C_hom[(m+1)*(_row_Di-1)-1][_col_Di-1];
           for(int n=0; n<3; n++){
-            dqdgradT(m,n) = C_hom[(m+1)*(_row_Di-1)-1][(n+1)*(_row_Di-1)-1];
+            // dqdgradT(m,n) = C_hom[(m+1)*(_row_Di-1)-1][(n+1)*(_row_Di-1)-1];
             dPdT(m,n) = C_hom[m + n*(_row_Di-1)][_col_Di-1];
+            dqdgradT(m,n) = C_hom[9+m][9+n];
             for(int k=0; k<3; k++){
-              dqdF(m,n,k) = C_hom[(m+1)*(_row_Di-1)-1][n+(_row_Di-1)*k];
-              // C_hom[m+(_row_Di-1)*n][(k+1)*(_row_Di-1)-1] = 0.;
+              // dqdF(m,n,k) = C_hom[(m+1)*(_row_Di-1)-1][n+(_row_Di-1)*k];
+              dqdF(m,n,k) = C_hom[9+m][n+3*k];
+              // C_hom[m+(_row_Di-1)*n][(k+1)*(_row_Di-1)-1] = 0.; This is for dPdgradT
               for(int l=0; l<3; l++)  
-                L(m,n,k,l) = C_hom[m+(_row_Di-1)*n][k+(_row_Di-1)*l];
+                // L(m,n,k,l) = C_hom[m+(_row_Di-1)*n][k+(_row_Di-1)*l];
+                L(m,n,k,l) = C_hom[m+3*n][k+3*l];
               }    
             }
         }
-- 
GitLab


From 6fe88771ed6bf95efb3224af3f4a49d29c7a704d Mon Sep 17 00:00:00 2001
From: FLE_Knight <ujwalkishore.jinaga@uliege.be>
Date: Mon, 13 Jan 2025 16:58:52 +0100
Subject: [PATCH 07/19] [NEW PATCH] Lacking definition of FIELD_CAPACITY in
 ThermoMechanicsDG3DIPVariableBase is now fixed. Must be checked on Material
 law level

---
 dG3D/src/computeWithMaterialLaw.cpp | 17 +++++++++++++----
 dG3D/src/computeWithMaterialLaw.h   |  6 ++++--
 dG3D/src/dG3DIPVariable.cpp         |  3 +++
 3 files changed, 20 insertions(+), 6 deletions(-)

diff --git a/dG3D/src/computeWithMaterialLaw.cpp b/dG3D/src/computeWithMaterialLaw.cpp
index dd8fb5408..df5aeaa61 100644
--- a/dG3D/src/computeWithMaterialLaw.cpp
+++ b/dG3D/src/computeWithMaterialLaw.cpp
@@ -13,8 +13,8 @@
 #include "nonLinearMechSolver.h"
 #include "STensorOperations.h"
 
-computeMaterialLaw::computeMaterialLaw(dG3DMaterialLaw& mlaw, bool flag_isothermal): _materialLaw(&mlaw), _ips(NULL), _step(0), 
-_flag_isothermal(flag_isothermal){
+computeMaterialLaw::computeMaterialLaw(dG3DMaterialLaw& mlaw, bool flag_isothermal, bool flag_microTempFixed): _materialLaw(&mlaw), 
+_ips(NULL), _step(0), _flag_isothermal(flag_isothermal), _flag_microTempFixed(flag_microTempFixed){
   static nonLinearMechSolver solver(1000);
   _materialLaw->setMacroSolver(&solver);
   static bool state = true;
@@ -78,7 +78,7 @@ void computeMaterialLaw::setDeformationGradient(int i, int j, double val)
   F(i,j) = val;
 }
 
-void computeMaterialLaw::setTemperatureGradient(int i, int j, double val)
+void computeMaterialLaw::setTemperatureGradient(int i, double val)
 {
   if (!_flag_isothermal){
     // store current for next step
@@ -144,7 +144,6 @@ void computeMaterialLaw::computeStressState_uniaxialStress(bool stiff)
   }
 };
 
-
 void computeMaterialLaw::computeStressState_PlaneStrainUniaxialStress( char* NoZeroPlane, bool stiff )
 {
   IPVariable* ipvcur = _ips->getState(IPStateBase::current);
@@ -445,6 +444,16 @@ void computeMaterialLaw::getHeatFlux(std::vector<double>& Qstress){
   }
 } 
 
+void computeMaterialLaw::get3rdDependentVariable(double& Cstress){
+  if(!_flag_microTempFixed){
+    IPVariable* ipvcur = _ips->getState(IPStateBase::current);
+    Cstress = ipvcur->get(IPField::FIELD_CAPACITY); // specific heat
+  }
+  else{
+    Msg::Error("computeMaterialLaw::get3rdDependentVariable can be used only if _flag_microTempFixed is set to false in the constructor.");
+  }
+};
+
 void computeMaterialLaw::getDeformationGradient(std::vector<double>& Fstrain){
     IPVariable* ipvcur = _ips->getState(IPStateBase::current);
     static STensor3 F;
diff --git a/dG3D/src/computeWithMaterialLaw.h b/dG3D/src/computeWithMaterialLaw.h
index aff11f5bf..de66420e1 100644
--- a/dG3D/src/computeWithMaterialLaw.h
+++ b/dG3D/src/computeWithMaterialLaw.h
@@ -25,13 +25,14 @@ class computeMaterialLaw
     IPStateBase* _ips;
     int _step;
     bool _flag_isothermal;
+    bool _flag_microTempFixed;
     #endif //SWIG
   public:
-    computeMaterialLaw(dG3DMaterialLaw& mlaw, bool flag_isothermal = true);
+    computeMaterialLaw(dG3DMaterialLaw& mlaw, bool flag_isothermal = true, bool flag_microTempFixed = true);
     virtual ~computeMaterialLaw();
     void resetState(dG3DMaterialLaw& mlaw);
     void setDeformationGradient(int i, int, double val);
-    void setTemperatureGradient(int i, int j, double val);
+    void setTemperatureGradient(int i, double val);
     void setTemperature(double val);
     void setTime(double t, double dt);
     void nextStep();
@@ -44,6 +45,7 @@ class computeMaterialLaw
     double getTimeStep() const;
     void getStress(std::vector<double>& Pstress);
     void getHeatFlux(std::vector<double>& Qstress);
+    void get3rdDependentVariable(double& Cstress);
     void getDeformationGradient(std::vector<double>& Fstrain);
     void getTemperatureGradient(std::vector<double>& Hstrain);
     void getTemperature(double& T);
diff --git a/dG3D/src/dG3DIPVariable.cpp b/dG3D/src/dG3DIPVariable.cpp
index ac9c8b699..781146f81 100644
--- a/dG3D/src/dG3DIPVariable.cpp
+++ b/dG3D/src/dG3DIPVariable.cpp
@@ -4037,6 +4037,9 @@ double ThermoMechanicsDG3DIPVariableBase::get(const int i) const
   else if (i == IPField::TEMP_GRAD_Z){
     return getConstRefToGradField()[0](2);
   }
+  else if (i == IPField::FIELD_CAPACITY){
+    return getConstitutiveExtraDofFieldCapacityPerUnitField(0);
+  }
   else
   {
     return dG3DIPVariable::get(i);
-- 
GitLab


From 043642cc2f63dd4b74cb161a7efd4f01753c1e31 Mon Sep 17 00:00:00 2001
From: FLE_Knight <ujwalkishore.jinaga@uliege.be>
Date: Fri, 17 Jan 2025 17:05:44 +0100
Subject: [PATCH 08/19] [NEW DEPRECATION ALERT] Flag microTempFixed is not
 functional. Requires either 2nd order homogenisation based interaction
 mappings or a parameter based on the length scale in the DMN.

---
 NonLinearSolver/modelReduction/NetworkInteraction.h | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/NonLinearSolver/modelReduction/NetworkInteraction.h b/NonLinearSolver/modelReduction/NetworkInteraction.h
index 943111e6b..309890b95 100644
--- a/NonLinearSolver/modelReduction/NetworkInteraction.h
+++ b/NonLinearSolver/modelReduction/NetworkInteraction.h
@@ -240,6 +240,7 @@ class NetworkInteraction
     #endif //SWIG
 };
 
+/*
 // FLE
 class NetworkInteractionExtraDOF : public NetworkInteraction
 {
@@ -363,7 +364,7 @@ class NetworkInteractionExtraDOF : public NetworkInteraction
                                      fullMatrix<double>& mat) const;
     #endif //SWIG
 };
-
+*/
 // FLE
 
 class CoefficientReduction
-- 
GitLab


From f9c51af504428016178ce008960a84115d00ccef Mon Sep 17 00:00:00 2001
From: FLE_Knight <ujwalkishore.jinaga@uliege.be>
Date: Fri, 31 Jan 2025 13:55:43 +0100
Subject: [PATCH 09/19] [NEW FEATURE] Minor Corrections to TMDMN tangents. More
 to come.

---
 dG3D/src/dG3DIPVariable.cpp  |  9 ++++++++-
 dG3D/src/dG3DIPVariable.h    |  7 +++++++
 dG3D/src/dG3DMaterialLaw.cpp | 31 +++++++++++++++++++++----------
 3 files changed, 36 insertions(+), 11 deletions(-)

diff --git a/dG3D/src/dG3DIPVariable.cpp b/dG3D/src/dG3DIPVariable.cpp
index 781146f81..ae69b7989 100644
--- a/dG3D/src/dG3DIPVariable.cpp
+++ b/dG3D/src/dG3DIPVariable.cpp
@@ -4186,10 +4186,14 @@ StochTMDMNDG3DIPVariable::StochTMDMNDG3DIPVariable(const int NRoot,const int NIn
     resizeFlag = FHvec.resize(entryFHPQ, true);
     resizeFlag = PQvec.resize(entryFHPQ, true);
     resizeFlag = ab.resize(entry_ab, true);
+    resizeFlag = Cpvec.resize(_NRoot, true);
+    resizeFlag = thermSrcvec.resize(_NRoot, true);
+    resizeFlag = mechSrcvec.resize(_NRoot, true);
  }
 
 StochTMDMNDG3DIPVariable::StochTMDMNDG3DIPVariable(const StochTMDMNDG3DIPVariable& src): ThermoMechanicsDG3DIPVariableBase(src), 
-    _NRoot(src._NRoot), FHvec(src.FHvec), PQvec(src.PQvec), ab(src.ab), _IPVector(src._NRoot,NULL){
+    _NRoot(src._NRoot), FHvec(src.FHvec), PQvec(src.PQvec), ab(src.ab), Cpvec(src.Cpvec), 
+    thermSrcvec(src.thermSrcvec), mechSrcvec(src.mechSrcvec), _IPVector(src._NRoot,NULL){
     for (int j=0; j< src._NRoot; j++){
       if (src._IPVector[j] != NULL){
         _IPVector[j] = src._IPVector[j]->clone();
@@ -4207,6 +4211,9 @@ StochTMDMNDG3DIPVariable& StochTMDMNDG3DIPVariable::operator =(const IPVariable&
     FHvec = psrc->FHvec;
     PQvec = psrc->PQvec;
     ab = psrc->ab;
+    Cpvec = psrc->Cpvec;
+    thermSrcvec = psrc->thermSrcvec;
+    mechSrcvec = psrc->mechSrcvec;
     for (int j=0; j< _NRoot; j++)
     {
       if ((_IPVector[j]!=NULL) and (psrc->_IPVector[j] != NULL))
diff --git a/dG3D/src/dG3DIPVariable.h b/dG3D/src/dG3DIPVariable.h
index cc6f4f127..133c1e4eb 100644
--- a/dG3D/src/dG3DIPVariable.h
+++ b/dG3D/src/dG3DIPVariable.h
@@ -3483,6 +3483,7 @@ class StochTMDMNDG3DIPVariable : public ThermoMechanicsDG3DIPVariableBase
     fullVector<double> FHvec; // F- defo, H -tempGrad
     fullVector<double> PQvec; // P- 1st PK, Q-heatFlux
     fullVector<double> ab;  // a- disp, b-temp
+    fullVector<double> Cpvec, thermSrcvec, mechSrcvec; 
 
   public:
     StochTMDMNDG3DIPVariable(const int NRoot,const int NInterface, const bool createBodyForceHO, const bool oninter);
@@ -3508,6 +3509,12 @@ class StochTMDMNDG3DIPVariable : public ThermoMechanicsDG3DIPVariableBase
     virtual const fullVector<double>& getConstRefToCombinedStressVect() const {return PQvec;};
     virtual fullVector<double>& getRefToCombinedInterfaceFluctuationVect() {return ab;};
     virtual const fullVector<double>& getConstRefToCombinedInterfaceFluctuationVect() const {return ab;};
+    virtual fullVector<double>& getRefToCpVect() {return Cpvec;};
+    virtual const fullVector<double>&  getConstRefToCpVect() const {return Cpvec;};
+    virtual fullVector<double>& getRefToThermalSourceVect() {return thermSrcvec;};
+    virtual const fullVector<double>&  getConstRefToThermalSourceVect() const {return thermSrcvec;};
+    virtual fullVector<double>& getRefToMechSourceVect() {return mechSrcvec;};
+    virtual const fullVector<double>&  getConstRefToMechSourceVect() const {return mechSrcvec;};
 
     virtual IPVariable* getInternalData() {return NULL;};
     virtual const IPVariable* getInternalData()  const {return NULL;};
diff --git a/dG3D/src/dG3DMaterialLaw.cpp b/dG3D/src/dG3DMaterialLaw.cpp
index e6868d781..bf80baaab 100644
--- a/dG3D/src/dG3DMaterialLaw.cpp
+++ b/dG3D/src/dG3DMaterialLaw.cpp
@@ -5611,14 +5611,20 @@ void StochTMDMNDG3DMaterialLaw::stress(IPVariable*ipv, const IPVariable*ipvprev,
   fullVector<double>& FHvec = ipvcur->getRefToCombinedGradientVect();
   fullVector<double>& PQvec = ipvcur->getRefToCombinedStressVect();
   fullVector<double>& ab_cur = ipvcur->getRefToCombinedInterfaceFluctuationVect();
-
-  bool resizeFlag; // CHECK THIS, IP definition is different
-  resizeFlag = FHvec.resize(_col_Di, true);
-  resizeFlag = PQvec.resize(_col_Di, true);
-  resizeFlag = ab_cur.resize(_row_Di, true);
+  fullVector<double>& Cpvec = ipvcur->getRefToCpVect();
+  fullVector<double>& thermSrcvec = ipvcur->getRefToThermalSourceVect();
+  fullVector<double>& mechSrcvec = ipvcur->getRefToMechSourceVect();
+
+  // Check this implementation through IP
+  /*
+  bool resizeFlag; // CHECK THIS, IP definition is different - ADJUST IP
+  resizeFlag = FHvec.resize(_col_Di*_NRoot, true);
+  resizeFlag = PQvec.resize(_col_Di*_NRoot, true);
+  resizeFlag = ab_cur.resize(_row_Di*_NInterface, true);
+  */
 
   // Pvec.setAll(0.0); 
-  PQvec.setAll(0.0);
+  PQvec.setAll(0.0); Cpvec.setAll(0.0); thermSrcvec.setAll(0.0); mechSrcvec.setAll(0.0); 
   static fullVector<double> Res_node_t(_row_Di*_NInterface);
   static fullVector<double> Res_node(_row_Di*_NInterface);
   static fullVector<double> a_step(_row_Di*_NInterface);
@@ -5711,6 +5717,7 @@ void StochTMDMNDG3DMaterialLaw::stress(IPVariable*ipv, const IPVariable*ipvprev,
         const double& mechSource_i = ipv_i->getConstRefToMechanicalSource()(0);
 
         if (_flag_isothermal && _flag_microTempFixed){
+          Cpvec(i) = Cp_i; thermSrcvec(i) = w_i; mechSrcvec(i) = mechSource_i;
           for(int m=0; m<3; m++){
             for(int n=0; n<3; n++){
               PQvec(i*_col_Di + m + n*_row_Di) = P_i(m,n);
@@ -5718,6 +5725,7 @@ void StochTMDMNDG3DMaterialLaw::stress(IPVariable*ipv, const IPVariable*ipvprev,
           }
         }
         else if(!_flag_isothermal && _flag_microTempFixed){
+          Cpvec(i) = Cp_i; thermSrcvec(i) = w_i; mechSrcvec(i) = mechSource_i;
           for(int m=0; m<3; m++){
             // PQvec(i*_col_Di + (m+1)*_row_Di-1) = Q_i(m);
             PQvec(i*_col_Di+ 9+m) = Q_i(m);
@@ -5728,6 +5736,7 @@ void StochTMDMNDG3DMaterialLaw::stress(IPVariable*ipv, const IPVariable*ipvprev,
           }
         }
         else if(!_flag_isothermal && !_flag_microTempFixed){
+          thermSrcvec(i) = w_i; mechSrcvec(i) = mechSource_i;
           PQvec((i+1)*_col_Di-1) = Cp_i;
           for(int m=0; m<3; m++){
             // PQvec(i*_col_Di + (m+1)*(_row_Di-1)-1) = Q_i(m);
@@ -5749,10 +5758,10 @@ void StochTMDMNDG3DMaterialLaw::stress(IPVariable*ipv, const IPVariable*ipvprev,
           const STensor3& dqdgradT_i = ipv_i->getRefTodThermalFluxdGradT(); 
           const SVector3& dqdT_i     = ipv_i->getRefTodThermalFluxdT();
           const STensor33& dqdF_i    = ipv_i->getRefTodThermalFluxdF(); 
-          // const double& dwdt_i       = ipv_i->getRefTodThermalSourcedField();
-          // const STensor3& dwdf_i     = ipv_i->getRefTodThermalSourcedF(); STensorOperation::zero(dwdf);
-          // const double& dmechSourcedt_i = ipv_i->getRefTodMechanicalSourcedField()(0,0);
-          // const STensor3& dmechSourcedf_i = ipv_i->getRefTodMechanicalSourcedF()[0]; 
+          const double& dwdt_i       = ipv_i->getRefTodThermalSourcedField();
+          const STensor3& dwdf_i     = ipv_i->getRefTodThermalSourcedF(); STensorOperation::zero(dwdf);
+          const double& dmechSourcedt_i = ipv_i->getRefTodMechanicalSourcedField()(0,0);
+          const STensor3& dmechSourcedf_i = ipv_i->getRefTodMechanicalSourcedF()[0]; 
           
           // CHECK with python AND DEBUG the tangents
           if (_flag_isothermal && _flag_microTempFixed){
@@ -5871,7 +5880,9 @@ void StochTMDMNDG3DMaterialLaw::stress(IPVariable*ipv, const IPVariable*ipvprev,
       }
     }
     if (_flag_isothermal && _flag_microTempFixed){
+      // Cp = 
       for(int i=0;i<3;i++){
+        Q(i) = 0.;
         for(int j=0;j<3;j++){
           P(i,j) = P_hom[i+_row_Di*j]; // CHECK
         }
-- 
GitLab


From 0e11b82409a66e870cd8230975e12f71a526dcf8 Mon Sep 17 00:00:00 2001
From: FLE_Knight <ujwalkishore.jinaga@uliege.be>
Date: Mon, 3 Feb 2025 17:46:50 +0100
Subject: [PATCH 10/19] [NEW PATCH] The IPvariable for TMDMN has been fixed.
 Corresponding changes have been made to dG3DMaterialLaw.cpp

---
 dG3D/src/dG3DIPVariable.cpp  | 23 +++++++++++++++++------
 dG3D/src/dG3DIPVariable.h    |  4 ++--
 dG3D/src/dG3DMaterialLaw.cpp | 25 ++++++-------------------
 3 files changed, 25 insertions(+), 27 deletions(-)

diff --git a/dG3D/src/dG3DIPVariable.cpp b/dG3D/src/dG3DIPVariable.cpp
index ae69b7989..718dc3f54 100644
--- a/dG3D/src/dG3DIPVariable.cpp
+++ b/dG3D/src/dG3DIPVariable.cpp
@@ -4063,7 +4063,7 @@ StochDMNDG3DIPVariable::StochDMNDG3DIPVariable(const int NRoot,const int NInterf
  }
 
 StochDMNDG3DIPVariable::StochDMNDG3DIPVariable(const StochDMNDG3DIPVariable& src):
-  dG3DIPVariable(src), _NRoot(src._NRoot), Fvec(src.Fvec), Pvec(src.Pvec), a(src.a),_IPVector(src._NRoot,NULL){
+  dG3DIPVariable(src), _NRoot(src._NRoot), _NInterface(src._NInterface), Fvec(src.Fvec), Pvec(src.Pvec), a(src.a),_IPVector(src._NRoot,NULL){
     for (int j=0; j< src._NRoot; j++){
       if (src._IPVector[j] != NULL){
         _IPVector[j] = src._IPVector[j]->clone();
@@ -4079,6 +4079,7 @@ StochDMNDG3DIPVariable& StochDMNDG3DIPVariable::operator =(const IPVariable& src
   if (psrc!=NULL)
   {
     _NRoot = psrc->_NRoot;
+    _NInterface = psrc->_NInterface;
     Fvec = psrc->Fvec;
     Pvec = psrc->Pvec;
     a = psrc->a;
@@ -4138,6 +4139,7 @@ void StochDMNDG3DIPVariable::restart()
 {
   dG3DIPVariable::restart();
   restartManager::restart(_NRoot);
+  restartManager::restart(_NInterface);
   restartManager::restart(Fvec.getDataPtr(),9*_NRoot);
   restartManager::restart(Pvec.getDataPtr(),9*_NRoot);
   restartManager::restart(a.getDataPtr(),3*_NInterface);
@@ -4178,11 +4180,13 @@ double StochDMNDG3DIPVariable::damageEnergy() const
 }
 
 // FLE
-StochTMDMNDG3DIPVariable::StochTMDMNDG3DIPVariable(const int NRoot,const int NInterface, const bool createBodyForceHO, const bool oninter):
-    ThermoMechanicsDG3DIPVariableBase(createBodyForceHO, oninter), _NRoot(NRoot), _NInterface(NInterface), _IPVector(NRoot,NULL){
+StochTMDMNDG3DIPVariable::StochTMDMNDG3DIPVariable(const int NRoot,const int NInterface, const int col_Di, const int row_Di,
+                     const bool createBodyForceHO, const bool oninter):
+    ThermoMechanicsDG3DIPVariableBase(createBodyForceHO, oninter), _NRoot(NRoot), _NInterface(NInterface),
+    _col_Di(col_Di), _row_Di(row_Di), _IPVector(NRoot,NULL){
     bool resizeFlag;
-    int entryFHPQ = 12*_NRoot;
-    int entry_ab = 4*_NInterface;
+    int entryFHPQ = _col_Di*_NRoot;
+    int entry_ab = _row_Di*_NInterface;
     resizeFlag = FHvec.resize(entryFHPQ, true);
     resizeFlag = PQvec.resize(entryFHPQ, true);
     resizeFlag = ab.resize(entry_ab, true);
@@ -4192,7 +4196,8 @@ StochTMDMNDG3DIPVariable::StochTMDMNDG3DIPVariable(const int NRoot,const int NIn
  }
 
 StochTMDMNDG3DIPVariable::StochTMDMNDG3DIPVariable(const StochTMDMNDG3DIPVariable& src): ThermoMechanicsDG3DIPVariableBase(src), 
-    _NRoot(src._NRoot), FHvec(src.FHvec), PQvec(src.PQvec), ab(src.ab), Cpvec(src.Cpvec), 
+    _NRoot(src._NRoot), _NInterface(src._NInterface), _col_Di(src._col_Di), _row_Di(src._row_Di),
+    FHvec(src.FHvec), PQvec(src.PQvec), ab(src.ab), Cpvec(src.Cpvec), 
     thermSrcvec(src.thermSrcvec), mechSrcvec(src.mechSrcvec), _IPVector(src._NRoot,NULL){
     for (int j=0; j< src._NRoot; j++){
       if (src._IPVector[j] != NULL){
@@ -4208,6 +4213,9 @@ StochTMDMNDG3DIPVariable& StochTMDMNDG3DIPVariable::operator =(const IPVariable&
   if (psrc!=NULL)
   {
     _NRoot = psrc->_NRoot;
+    _NInterface = psrc->_NInterface;
+    _col_Di = psrc->_col_Di;
+    _row_Di = psrc->_row_Di;
     FHvec = psrc->FHvec;
     PQvec = psrc->PQvec;
     ab = psrc->ab;
@@ -4270,6 +4278,9 @@ void StochTMDMNDG3DIPVariable::restart()
 {
   ThermoMechanicsDG3DIPVariableBase::restart();
   restartManager::restart(_NRoot);
+  restartManager::restart(_NInterface);
+  restartManager::restart(_col_Di);
+  restartManager::restart(_row_Di);
   restartManager::restart(FHvec.getDataPtr(),12*_NRoot);
   restartManager::restart(PQvec.getDataPtr(),12*_NRoot);
   restartManager::restart(ab.getDataPtr(),4*_NInterface);
diff --git a/dG3D/src/dG3DIPVariable.h b/dG3D/src/dG3DIPVariable.h
index 133c1e4eb..e4d6895e9 100644
--- a/dG3D/src/dG3DIPVariable.h
+++ b/dG3D/src/dG3DIPVariable.h
@@ -3476,7 +3476,7 @@ class StochDMNDG3DIPVariable : public dG3DIPVariable
 class StochTMDMNDG3DIPVariable : public ThermoMechanicsDG3DIPVariableBase 
 {
   protected:
-    int _NRoot, _NInterface;
+    int _NRoot, _NInterface, _col_Di, _row_Di;
     std::vector<IPVariable*> _IPVector;
 
     // combined vectors
@@ -3486,7 +3486,7 @@ class StochTMDMNDG3DIPVariable : public ThermoMechanicsDG3DIPVariableBase
     fullVector<double> Cpvec, thermSrcvec, mechSrcvec; 
 
   public:
-    StochTMDMNDG3DIPVariable(const int NRoot,const int NInterface, const bool createBodyForceHO, const bool oninter);
+    StochTMDMNDG3DIPVariable(const int NRoot, const int NInterface, const int col_Di, const int row_Di, const bool createBodyForceHO, const bool oninter);
     StochTMDMNDG3DIPVariable(const StochTMDMNDG3DIPVariable& src);
     virtual StochTMDMNDG3DIPVariable& operator =(const IPVariable& src);
     virtual ~StochTMDMNDG3DIPVariable();
diff --git a/dG3D/src/dG3DMaterialLaw.cpp b/dG3D/src/dG3DMaterialLaw.cpp
index bf80baaab..e0d08752f 100644
--- a/dG3D/src/dG3DMaterialLaw.cpp
+++ b/dG3D/src/dG3DMaterialLaw.cpp
@@ -5097,9 +5097,9 @@ void StochTMDMNDG3DMaterialLaw::createIPState(IPStateBase* &ips, bool hasBodyFor
   bool inter=true;
   const MInterfaceElement *iele = dynamic_cast<const MInterfaceElement*>(ele);
   if(iele==NULL) inter=false;
-    IPVariable* ipvi = new  StochTMDMNDG3DIPVariable(_NRoot, _NInterface, hasBodyForce,inter);
-    IPVariable* ipv1 = new  StochTMDMNDG3DIPVariable(_NRoot, _NInterface, hasBodyForce,inter);
-    IPVariable* ipv2 = new  StochTMDMNDG3DIPVariable(_NRoot, _NInterface, hasBodyForce,inter);
+    IPVariable* ipvi = new  StochTMDMNDG3DIPVariable(_NRoot, _NInterface, _col_Di, _row_Di, hasBodyForce,inter);
+    IPVariable* ipv1 = new  StochTMDMNDG3DIPVariable(_NRoot, _NInterface, _col_Di, _row_Di, hasBodyForce,inter);
+    IPVariable* ipv2 = new  StochTMDMNDG3DIPVariable(_NRoot, _NInterface, _col_Di, _row_Di, hasBodyForce,inter);
 
     StochTMDMNDG3DIPVariable* ipvi_root = static_cast<StochTMDMNDG3DIPVariable*>(ipvi);
     StochTMDMNDG3DIPVariable* ipv1_root = static_cast<StochTMDMNDG3DIPVariable*>(ipv1);
@@ -5132,7 +5132,7 @@ void StochTMDMNDG3DMaterialLaw::createIPVariable(IPVariable* &ipv, bool hasBodyF
   if(iele == NULL){
     inter=false;
   }
-  ipv = new  StochTMDMNDG3DIPVariable(_NRoot, _NInterface, hasBodyForce,inter);
+  ipv = new  StochTMDMNDG3DIPVariable(_NRoot, _NInterface, _col_Di, _row_Di, hasBodyForce,inter);
   StochTMDMNDG3DIPVariable* ipv_root = static_cast<StochTMDMNDG3DIPVariable*>(ipv);
   for (int i=0; i< _NRoot; i++){
     IPVariable* ipv_i = NULL;
@@ -5600,30 +5600,17 @@ void StochTMDMNDG3DMaterialLaw::stress(IPVariable*ipv, const IPVariable*ipvprev,
   STensor33 dPdgradT; STensorOperation::zero(dPdgradT);
 
 
-  double C_hom[_col_Di][_col_Di]; // static
+  double C_hom[_col_Di][_col_Di]; // static // The tangent is combined with thermal tangents.
   double P_hom[_col_Di]; //static
   // std::vector<double> P_hom;
 
-  // fullVector<double>& Fvec = ipvcur->getRefToDeformationGradientVect();
-  // fullVector<double>& Pvec = ipvcur->getRefToFirstPiolaKirchhoffStressVect();
-  // fullVector<double>& a_cur = ipvcur->getRefToInterfaceFluctuationVect();
-
   fullVector<double>& FHvec = ipvcur->getRefToCombinedGradientVect();
   fullVector<double>& PQvec = ipvcur->getRefToCombinedStressVect();
   fullVector<double>& ab_cur = ipvcur->getRefToCombinedInterfaceFluctuationVect();
   fullVector<double>& Cpvec = ipvcur->getRefToCpVect();
   fullVector<double>& thermSrcvec = ipvcur->getRefToThermalSourceVect();
   fullVector<double>& mechSrcvec = ipvcur->getRefToMechSourceVect();
-
-  // Check this implementation through IP
-  /*
-  bool resizeFlag; // CHECK THIS, IP definition is different - ADJUST IP
-  resizeFlag = FHvec.resize(_col_Di*_NRoot, true);
-  resizeFlag = PQvec.resize(_col_Di*_NRoot, true);
-  resizeFlag = ab_cur.resize(_row_Di*_NInterface, true);
-  */
-
-  // Pvec.setAll(0.0); 
+ 
   PQvec.setAll(0.0); Cpvec.setAll(0.0); thermSrcvec.setAll(0.0); mechSrcvec.setAll(0.0); 
   static fullVector<double> Res_node_t(_row_Di*_NInterface);
   static fullVector<double> Res_node(_row_Di*_NInterface);
-- 
GitLab


From b461098307d430ba9a3328a0b6500ea6ea94d193 Mon Sep 17 00:00:00 2001
From: FLE_Knight <ujwalkishore.jinaga@uliege.be>
Date: Tue, 4 Mar 2025 17:45:30 +0100
Subject: [PATCH 11/19] [NEW FIX] Averaged specific heat fixed in TMDMN

---
 dG3D/src/dG3DMaterialLaw.cpp | 118 +++++++++++++++++++----------------
 1 file changed, 64 insertions(+), 54 deletions(-)

diff --git a/dG3D/src/dG3DMaterialLaw.cpp b/dG3D/src/dG3DMaterialLaw.cpp
index e0d08752f..89e955542 100644
--- a/dG3D/src/dG3DMaterialLaw.cpp
+++ b/dG3D/src/dG3DMaterialLaw.cpp
@@ -3884,12 +3884,12 @@ void StochDMNDG3DMaterialLaw::fill_NLocal(const int pos, double N[][3])const{
 
 void StochDMNDG3DMaterialLaw::fill_W_WI(const int pos, const int level, double W[][2]){
 
-  // code to fill a matrix related to weights and interfaces
+  // code to fill a matrix related to weights and interfaces -> For composite nodes?
 
-  double VI = _VI[pos];
+  double VI = _VI[pos]; // V0 = 1 - VI
   double Wtmp0 = _Para_Wt[pos][0];
   double Wtmp1 = _Para_Wt[pos][1];
-  double WA = Wtmp0*(1.0-VI)+ Wtmp1*VI;
+  double WA = Wtmp0*(1.0-VI)+ Wtmp1*VI; // Eq. 39 in Ling's draft
 
   for(int i=0; i<2; i++){
     for(int j=0; j<2; j++){
@@ -3898,8 +3898,8 @@ void StochDMNDG3DMaterialLaw::fill_W_WI(const int pos, const int level, double W
   }
   W[0][0]= WA;
   W[0][1]= 1.0-WA;
-  W[1][0]= (Wtmp1*VI)/WA;
-  W[1][1]= ((1.0-Wtmp1)*VI)/(1.0-WA);
+  W[1][0]= (Wtmp1*VI)/WA; // Eq. 40 in Ling's draft, v_1A
+  W[1][1]= ((1.0-Wtmp1)*VI)/(1.0-WA); // Eq. 40 in Ling's draft, v_1B
 }
 
 
@@ -4011,7 +4011,7 @@ void  StochDMNDG3DMaterialLaw::fill_Matrices(){
     }
    }
 
- // information of voulme fraction to stress on node
+ // information of volume fraction to stress on node
   Row_start = col*(_N_Node-1-_NRoot);
   for(int nc=0; nc<col*_NRoot; nc++){
     _V.set(Row_start+nc,nc,1.0);
@@ -4303,13 +4303,13 @@ void StochDMNDG3DMaterialLaw::stress(IPVariable*ipv, const IPVariable*ipvprev, c
       }
     }
 
-    _NTV.mult(Pvec, Res_node);
+    _NTV.mult(Pvec, Res_node); // Eq 60 in Ling's draft, Res_node = residual at the node
     r = Res_node.norm()/_NInterface;
 
     if(r<_tol){
       if(last or stiff_loc){
         _NTV.mult(_C, NTVC);
-        NTVC.mult(_Nv, Jacobian);
+        NTVC.mult(_Nv, Jacobian); // Eq 65 in Ling's draft
         Jacobian.invertInPlace();
         break;
       }
@@ -4326,7 +4326,7 @@ void StochDMNDG3DMaterialLaw::stress(IPVariable*ipv, const IPVariable*ipvprev, c
         Jacobian.invertInPlace();
       }
       else{
-        // What is this? HOw does the following update the jacobian?
+        // What is this? How does the following update the jacobian?
         _NTV.mult(Pvec, Res_node);
         Res_node_t.scale(-1.0);
         Res_node_t.axpy(Res_node, 1.0);
@@ -4379,7 +4379,7 @@ void StochDMNDG3DMaterialLaw::stress(IPVariable*ipv, const IPVariable*ipvprev, c
 
     if(stiff){
       NTVC.mult(_I, dRdF);
-      Jacobian.mult(dRdF, dadF);
+      Jacobian.mult(dRdF, dadF); // Eq. 68 in Ling's draft
       _Nv.mult(dadF, tmp);
       tmp.add(_I);
 
@@ -4388,7 +4388,7 @@ void StochDMNDG3DMaterialLaw::stress(IPVariable*ipv, const IPVariable*ipvprev, c
           C_hom[m][n] = 0.0;
           for(int i=0;i<_NRoot;i++){
             for(int j=0;j< 9*_NRoot;j++){
-              C_hom[m][n] += (_VA[1]*_V(m,m+9*i) + _VA[2]*_V(9+m,m+9*i))*_C(m+9*i,j)*tmp(j,n);
+              C_hom[m][n] += (_VA[1]*_V(m,m+9*i) + _VA[2]*_V(9+m,m+9*i))*_C(m+9*i,j)*tmp(j,n); // Eq. 70 in Ling's draft
             }
           }
         }
@@ -4408,7 +4408,7 @@ void StochDMNDG3DMaterialLaw::stress(IPVariable*ipv, const IPVariable*ipvprev, c
   ipvcur->setRefToDGElasticTangentModuli(this->elasticStiffness);
 } 
 // end of stress
-// Compute derivatives repect to DMN parameters at trainning satge
+// Compute derivatives respect to DMN parameters at training satge
 void StochDMNDG3DMaterialLaw::getdVAdP(std::vector< std::vector <SPoint2> >& dVAdPv) const{
   int pos0, pos1;
   static std::vector< std::vector <SPoint2> > dVIdPv;
@@ -5069,14 +5069,15 @@ void StochDMNDG3DMaterialLaw::setTime(const double t,const double dtime){
 StochTMDMNDG3DMaterialLaw::StochTMDMNDG3DMaterialLaw(const int num, const double rho, const double E,const double nu, const char *ParaFile,
       const bool porous, const bool flag_isothermal, const bool flag_microTempFixed, const double tol):
       StochDMNDG3DMaterialLaw(num,rho,E,nu,ParaFile,porous,tol),_flag_isothermal(flag_isothermal),_flag_microTempFixed(flag_microTempFixed){
-
+  
+  // Meanings of _col_Di and _row_Di are interchanged in this class.
   if (_flag_isothermal && _flag_microTempFixed){
     _col_Di = 9; _row_Di = 3;
   }
   else if(!_flag_isothermal && _flag_microTempFixed){
     _col_Di = 12; _row_Di = 4;
   }
-  else if(!_flag_isothermal && !_flag_microTempFixed){
+  else if(!_flag_isothermal && !_flag_microTempFixed){ // Deprecated option - Impossible to implement without length scale.
     _col_Di = 13; _row_Di = 5;
   }
   else{
@@ -5097,9 +5098,9 @@ void StochTMDMNDG3DMaterialLaw::createIPState(IPStateBase* &ips, bool hasBodyFor
   bool inter=true;
   const MInterfaceElement *iele = dynamic_cast<const MInterfaceElement*>(ele);
   if(iele==NULL) inter=false;
-    IPVariable* ipvi = new  StochTMDMNDG3DIPVariable(_NRoot, _NInterface, _col_Di, _row_Di, hasBodyForce,inter);
-    IPVariable* ipv1 = new  StochTMDMNDG3DIPVariable(_NRoot, _NInterface, _col_Di, _row_Di, hasBodyForce,inter);
-    IPVariable* ipv2 = new  StochTMDMNDG3DIPVariable(_NRoot, _NInterface, _col_Di, _row_Di, hasBodyForce,inter);
+    IPVariable* ipvi = new StochTMDMNDG3DIPVariable(_NRoot, _NInterface, _col_Di, _row_Di, hasBodyForce,inter);
+    IPVariable* ipv1 = new StochTMDMNDG3DIPVariable(_NRoot, _NInterface, _col_Di, _row_Di, hasBodyForce,inter);
+    IPVariable* ipv2 = new StochTMDMNDG3DIPVariable(_NRoot, _NInterface, _col_Di, _row_Di, hasBodyForce,inter);
 
     StochTMDMNDG3DIPVariable* ipvi_root = static_cast<StochTMDMNDG3DIPVariable*>(ipvi);
     StochTMDMNDG3DIPVariable* ipv1_root = static_cast<StochTMDMNDG3DIPVariable*>(ipv1);
@@ -5277,7 +5278,7 @@ void StochTMDMNDG3DMaterialLaw::fill_Matrices(){
   double tmp;
 
   // set the size of rows and cols in Di matrix
-  int col = _col_Di; // = 9;
+  int col = _col_Di; // = 9, 12;
 
   for(int i=0; i <_N_Node; i++){
     _VA.push_back(1.0); // Vector for position of nodes for Stress
@@ -5289,7 +5290,7 @@ void StochTMDMNDG3DMaterialLaw::fill_Matrices(){
     if(pos == int(pow(2,l+1)-1)) l +=1; // if its the first position (interface) of every level, l+=1
     fill_NLocal(pos,Norm);  // size of Norm depends on the flags set inside this function
     pos_kids(pos, l, pos0, pos1);
-    Row_start = pos*_row_Di; // 3;
+    Row_start = pos*_row_Di; // 3, 4;
     Col_start0 = (pos0-1)*col;
     Col_start1 = (pos1-1)*col;
 
@@ -5303,7 +5304,7 @@ void StochTMDMNDG3DMaterialLaw::fill_Matrices(){
       }
     }
 
-    if(l ==_TotalLevel-1){
+    if(l ==_TotalLevel-1){ // Last level
       if(_porous){
         _VA[pos0] = (1.0-_VI[pos])*_Para_Wt[pos][0];
         _VA[pos1] = (1.0-_VI[pos])*(1.0-_Para_Wt[pos][0]);
@@ -5313,13 +5314,13 @@ void StochTMDMNDG3DMaterialLaw::fill_Matrices(){
         _VA[pos1] = _VI[pos];
       }
     }
-    else if(_Modified_DMN and l ==_TotalLevel-2){
+    else if(_Modified_DMN and l ==_TotalLevel-2){ // Composite nodes - 2nd last level
       StochDMNDG3DMaterialLaw::fill_W_WI(pos,l,W_WI);
       _VA[pos0] = W_WI[0][0];
       _VA[pos1] = W_WI[0][1];
-      _VI.push_back(W_WI[1][0]);
+      _VI.push_back(W_WI[1][0]); // Collect v_1A for all composite nodes
     }
-    else{
+    else{ // Composite nodes - all other levels
       StochDMNDG3DMaterialLaw::fill_W_WI(pos,l,W_WI);
       _VA[pos0] = W_WI[0][0];
       _VA[pos1] = W_WI[0][1];
@@ -5327,7 +5328,7 @@ void StochTMDMNDG3DMaterialLaw::fill_Matrices(){
       _VI.push_back(W_WI[1][1]);
     }
     //information of homogenous strain to local strain
-    Col_start = pos*_row_Di; // *3
+    Col_start = pos*_row_Di; // *3, 4 // Note that the meanings of _row_Di and _col_Di have been swapped
     if(!_Modified_DMN or l< _TotalLevel-2){
       k = int(pow(2,l));
       node = _NRoot/k/2;
@@ -5375,7 +5376,7 @@ void StochTMDMNDG3DMaterialLaw::fill_Matrices(){
     }
    }
 
- // information of voulme fraction to stress on node
+ // information of volume fraction to stress on node
   Row_start = col*(_N_Node-1-_NRoot);
   for(int nc=0; nc<col*_NRoot; nc++){
     _V.set(Row_start+nc,nc,1.0);
@@ -5449,7 +5450,7 @@ void StochTMDMNDG3DMaterialLaw::read_parameter(const char *ParaFile){
     
     _ParaAngle.resize(_NInterface,2,true);
         
-    double ParaN[2];
+    double ParaN[2]; // W_alpha and w_beta -> Eq. 37 in Ling's draft
     double Pi(3.14159265359);        
     SPoint3 Para_Norm;
     SPoint2 Para_Wt;
@@ -5601,8 +5602,9 @@ void StochTMDMNDG3DMaterialLaw::stress(IPVariable*ipv, const IPVariable*ipvprev,
 
 
   double C_hom[_col_Di][_col_Di]; // static // The tangent is combined with thermal tangents.
-  double P_hom[_col_Di]; //static
-  // std::vector<double> P_hom;
+  double PQ_hom[_col_Di]; //static
+  double Cp_hom(0.), thermSrc_hom(0.), mechSource_hom(0.);
+  // std::vector<double> PQ_hom;
 
   fullVector<double>& FHvec = ipvcur->getRefToCombinedGradientVect();
   fullVector<double>& PQvec = ipvcur->getRefToCombinedStressVect();
@@ -5624,7 +5626,7 @@ void StochTMDMNDG3DMaterialLaw::stress(IPVariable*ipv, const IPVariable*ipvprev,
     
   Res_node_t.setAll(0.0);
   Res_node.setAll(0.0);
-  a_step.setAll(0.0);
+  ab_step.setAll(0.0);
   _C.setAll(0.0);
   NTVC.setAll(0.0); 
   Jacobian.setAll(0.0);
@@ -5750,7 +5752,6 @@ void StochTMDMNDG3DMaterialLaw::stress(IPVariable*ipv, const IPVariable*ipvprev,
           const double& dmechSourcedt_i = ipv_i->getRefTodMechanicalSourcedField()(0,0);
           const STensor3& dmechSourcedf_i = ipv_i->getRefTodMechanicalSourcedF()[0]; 
           
-          // CHECK with python AND DEBUG the tangents
           if (_flag_isothermal && _flag_microTempFixed){
             for(int m=0; m<3; m++)
               for(int n=0; n<3; n++)
@@ -5762,7 +5763,7 @@ void StochTMDMNDG3DMaterialLaw::stress(IPVariable*ipv, const IPVariable*ipvprev,
             for(int m=0; m<3; m++)
               for(int n=0; n<3; n++){
                 // _C(i*_col_Di + (m+1)*_row_Di-1, i*_col_Di + (n+1)*_row_Di-1) = dqdgradT_i(m,n);
-                _C(i*_col_Di + 9+m, i*_col_Di + 9+m) = dqdgradT_i(m,n);
+                _C(i*_col_Di + 9+m, i*_col_Di + 9+n) = dqdgradT_i(m,n);
                 for(int k=0; k<3; k++){
                   // _C(i*_col_Di + (m+1)*_row_Di-1, i*_col_Di+n+_row_Di*k) = dqdF_i(m,n,k);
                   // _C(i*_col_Di+m+_row_Di*n, i*_col_Di + (k+1)*_row_Di-1) = 0.; // This is for dPdgradT_i
@@ -5812,8 +5813,7 @@ void StochTMDMNDG3DMaterialLaw::stress(IPVariable*ipv, const IPVariable*ipvprev,
         last = true;
         stiff_loc = true;
       }  
-    } 
-            
+    }       
     else{         
       if(stiff_loc){         
         _NTV.mult(_C, NTVC);
@@ -5821,17 +5821,17 @@ void StochTMDMNDG3DMaterialLaw::stress(IPVariable*ipv, const IPVariable*ipvprev,
         Jacobian.invertInPlace();
       }
       else{
-        // What is this? HOw does the following update the jacobian?
+        // What is this? How does the following update the jacobian?
         _NTV.mult(PQvec, Res_node);
         Res_node_t.scale(-1.0);
         Res_node_t.axpy(Res_node, 1.0);
 
-        double Rho = 1.0/(Res_node_t*a_step);
+        double Rho = 1.0/(Res_node_t*ab_step);
         Modify_Jacobian.setAll(0.0);
         for(int i =0; i<3*_NInterface; i++){
           Modify_Jacobian(i,i) = 1.0;
           for(int j =0; j<3*_NInterface; j++){
-            Modify_Jacobian(i,j) -= a_step(i)*Res_node_t(j)*Rho;
+            Modify_Jacobian(i,j) -= ab_step(i)*Res_node_t(j)*Rho;
           }
         }
         Modify_Jacobian.mult(Jacobian,Jacobian_inv);
@@ -5840,7 +5840,7 @@ void StochTMDMNDG3DMaterialLaw::stress(IPVariable*ipv, const IPVariable*ipvprev,
 
         for(int i =0; i<3*_NInterface; i++){
           for(int j =0; j<3*_NInterface; j++){
-            Jacobian(i,j) += a_step(i)*a_step(j)*Rho;
+            Jacobian(i,j) += ab_step(i)*ab_step(j)*Rho;
           }
         }
         stiff_loc = true;
@@ -5848,56 +5848,66 @@ void StochTMDMNDG3DMaterialLaw::stress(IPVariable*ipv, const IPVariable*ipvprev,
       }
 
       Res_node_t = Res_node;
-      Jacobian.mult(Res_node, a_step);
-      a_step.scale(-1.0);
-      ab_cur.axpy(a_step, 1.0);
+      Jacobian.mult(Res_node, ab_step);
+      ab_step.scale(-1.0);
+      ab_cur.axpy(ab_step, 1.0);
     }
   }
   Jacobian.scale(-1.0);
 
   if(r>_tol){
-    Msg::Error("DMN residual (= %lf) did n't converge to tolenerce after %d iteration",r,ite);
+    Msg::Error("TMDMN residual (= %lf) didn't converge to tolenerce after %d iteration",r,ite);
     return;
   }
   else{
     for(int m=0;m<_col_Di;m++){
-      P_hom[m] = 0.0;
+      PQ_hom[m] = 0.0;
       for(int i=0;i<_NRoot;i++){
-        P_hom[m] += (_VA[1]*_V(m, _col_Di*i+m) + _VA[2]*_V(_col_Di+m, _col_Di*i+m)) *PQvec(_col_Di*i+m); // CHECK
+        PQ_hom[m] += (_VA[1]*_V(m, _col_Di*i+m) + _VA[2]*_V(_col_Di+m, _col_Di*i+m)) *PQvec(_col_Di*i+m); // Stress average
       }
     }
+    
+    Cp_hom, thermSrc_hom, mechSource_hom = 0.;
+    for(int i=0;i<_NRoot;i++){
+      Cp_hom += (_VA[1]*_V(0, _col_Di*i) + _VA[2]*_V(_col_Di, _col_Di*i)) *Cpvec(i); // Cp average
+      thermSrc_hom += (_VA[1]*_V(0, _col_Di*i) + _VA[2]*_V(_col_Di, _col_Di*i)) *thermSrcvec(i); // w average
+      mechSource_hom += (_VA[1]*_V(0, _col_Di*i) + _VA[2]*_V(_col_Di, _col_Di*i)) *mechSrcvec(i); // mechSrc average
+    }
+
     if (_flag_isothermal && _flag_microTempFixed){
-      // Cp = 
+      Cp = Cp_hom; w = 0.; mechSource = 0.;
       for(int i=0;i<3;i++){
         Q(i) = 0.;
         for(int j=0;j<3;j++){
-          P(i,j) = P_hom[i+_row_Di*j]; // CHECK
+          P(i,j) = PQ_hom[i+_row_Di*j]; // CHECK
         }
       }
     }
     else if(!_flag_isothermal && _flag_microTempFixed){
+      Cp = Cp_hom; w = thermSrc_hom; mechSource = mechSource_hom; 
       for(int i=0;i<3;i++){
-        // Q(i) = P_hom[(i+1)*_row_Di-1];
-        Q(i) = P_hom[9+i];
+        // Q(i) = PQ_hom[(i+1)*_row_Di-1];
+        Q(i) = PQ_hom[9+i];
         for(int j=0;j<3;j++){
-          // P(i,j) = P_hom[i+_row_Di*j]; // CHECK
-          P(i,j) = P_hom[i+3*j]; // CHECK
+          // P(i,j) = PQ_hom[i+_row_Di*j];
+          P(i,j) = PQ_hom[i+3*j]; 
         }
       }
     }
     else if(!_flag_isothermal && !_flag_microTempFixed){
-      Cp = P_hom[_col_Di-1];
+      Cp = PQ_hom[_col_Di-1]; w = thermSrc_hom; mechSource = mechSource_hom;
       for(int i=0;i<3;i++){
-        // Q(i) = P_hom[(i+1)*(_row_Di-1)-1];
-        Q(i) = P_hom[9+i];
+        // Q(i) = PQ_hom[(i+1)*(_row_Di-1)-1];
+        Q(i) = PQ_hom[9+i];
         for(int j=0;j<3;j++){
-          // P(i,j) = P_hom[i+(_row_Di-1)*j]; // CHECK
-          P(i,j) = P_hom[i+3*j]; // CHECK
+          // P(i,j) = PQ_hom[i+(_row_Di-1)*j];
+          P(i,j) = PQ_hom[i+3*j];
         }
       }  
     }
 
     if(stiff){
+      // All derivatives must be complete
       NTVC.mult(_I, dRdF);
       Jacobian.mult(dRdF, dadF);
       _Nv.mult(dadF, tmp);
-- 
GitLab


From cba9325b7e8c9a4984b57952bf749573c6c06ed4 Mon Sep 17 00:00:00 2001
From: FLE_Knight <ujwalkishore.jinaga@uliege.be>
Date: Thu, 6 Mar 2025 15:00:59 +0100
Subject: [PATCH 12/19] [NEW FIX 1] TMDMN tangents Fix 1. More to follow.

---
 dG3D/src/dG3DMaterialLaw.cpp | 69 ++++++++++++++++++++++++++++--------
 1 file changed, 54 insertions(+), 15 deletions(-)

diff --git a/dG3D/src/dG3DMaterialLaw.cpp b/dG3D/src/dG3DMaterialLaw.cpp
index 89e955542..ac1d4e89c 100644
--- a/dG3D/src/dG3DMaterialLaw.cpp
+++ b/dG3D/src/dG3DMaterialLaw.cpp
@@ -5583,9 +5583,9 @@ void StochTMDMNDG3DMaterialLaw::stress(IPVariable*ipv, const IPVariable*ipvprev,
 
   STensor3& P = ipvcur->getRefToFirstPiolaKirchhoffStress(); STensorOperation::zero(P);
   SVector3& Q = ipvcur->getRefToThermalFlux(); STensorOperation::zero(Q);
-  double& w   = ipvcur->getRefToThermalSource();
+  double& w   = ipvcur->getRefToThermalSource(); w = 0.;
   double& Cp         = ipvcur->getRefToExtraDofFieldCapacityPerUnitField()(0);
-  double& mechSource = ipvcur->getRefToMechanicalSource()(0);
+  double& mechSource = ipvcur->getRefToMechanicalSource()(0); mechSource = 0.; 
 
   STensor43& L       = ipvcur->getRefToTangentModuli(); STensorOperation::zero(L);
   STensor3& dPdT     = ipvcur->getRefTodPdT(); STensorOperation::zero(dPdT);
@@ -5594,7 +5594,7 @@ void StochTMDMNDG3DMaterialLaw::stress(IPVariable*ipv, const IPVariable*ipvprev,
   STensor33& dqdF    = ipvcur->getRefTodThermalFluxdF(); STensorOperation::zero(dqdF);
   double& dwdt       = ipvcur->getRefTodThermalSourcedField();
   STensor3& dwdf     = ipvcur->getRefTodThermalSourcedF(); STensorOperation::zero(dwdf);
-  double& dmechSourcedt = ipvcur->getRefTodMechanicalSourcedField()(0,0);
+  double& dmechSourcedt = ipvcur->getRefTodMechanicalSourcedField()(0,0); dmechSourcedt = 0.;
   STensor3& dmechSourcedf = ipvcur->getRefTodMechanicalSourcedF()[0]; STensorOperation::zero(dmechSourcedf);
   double dCpdT(0.);
   STensor3 dCpdF; STensorOperation::zero(dCpdF);
@@ -5603,7 +5603,9 @@ void StochTMDMNDG3DMaterialLaw::stress(IPVariable*ipv, const IPVariable*ipvprev,
 
   double C_hom[_col_Di][_col_Di]; // static // The tangent is combined with thermal tangents.
   double PQ_hom[_col_Di]; //static
-  double Cp_hom(0.), thermSrc_hom(0.), mechSource_hom(0.);
+  double dPQdT_hom[_col_Di]; // static
+  double Cp_hom(0.), thermSrc_hom(0.), mechSource_hom(0.), dwdt_hom(0.), dmechSourcedt_hom(0.);
+  static double dwdf_hom[9], dmechSourcedf_hom[9];
   // std::vector<double> PQ_hom;
 
   fullVector<double>& FHvec = ipvcur->getRefToCombinedGradientVect();
@@ -5612,11 +5614,14 @@ void StochTMDMNDG3DMaterialLaw::stress(IPVariable*ipv, const IPVariable*ipvprev,
   fullVector<double>& Cpvec = ipvcur->getRefToCpVect();
   fullVector<double>& thermSrcvec = ipvcur->getRefToThermalSourceVect();
   fullVector<double>& mechSrcvec = ipvcur->getRefToMechSourceVect();
- 
+  fullVector<double> dwdtvec, dmechSrcdTvec, dwdFvec, dmechSrcdFvec;
+  dwdtvec.resize(_NRoot); dmechSrcdTvec.resize(_NRoot);
+  dwdFvec.resize(9*_NRoot); dmechSrcdFvec.resize(9*_NRoot); 
+
   PQvec.setAll(0.0); Cpvec.setAll(0.0); thermSrcvec.setAll(0.0); mechSrcvec.setAll(0.0); 
   static fullVector<double> Res_node_t(_row_Di*_NInterface);
   static fullVector<double> Res_node(_row_Di*_NInterface);
-  static fullVector<double> a_step(_row_Di*_NInterface);
+  static fullVector<double> ab_step(_row_Di*_NInterface);
   static fullMatrix<double> NTVC(_row_Di*_NInterface, _col_Di*_NRoot);
   static fullMatrix<double> Jacobian_inv(_row_Di*_NInterface, _row_Di*_NInterface); 
   static fullMatrix<double> Modify_Jacobian(_row_Di*_NInterface, _row_Di*_NInterface); 
@@ -5753,17 +5758,24 @@ void StochTMDMNDG3DMaterialLaw::stress(IPVariable*ipv, const IPVariable*ipvprev,
           const STensor3& dmechSourcedf_i = ipv_i->getRefTodMechanicalSourcedF()[0]; 
           
           if (_flag_isothermal && _flag_microTempFixed){
+            dwdtvec(i) = 0.; dmechSrcdTvec(i) = 0.;
             for(int m=0; m<3; m++)
-              for(int n=0; n<3; n++)
+              for(int n=0; n<3; n++){
+                dwdFvec(i*_col_Di+m+_row_Di*n) = 0.;
+                dmechSrcdFvec(i*_col_Di+m+_row_Di*n) = 0.;
                 for(int k=0; k<3; k++)
                   for(int l=0; l<3; l++)  
                     _C(i*_col_Di+m+_row_Di*n, i*_col_Di+k+_row_Di*l) = L_i(m,n,k,l);
+              }
           }
           else if(!_flag_isothermal && _flag_microTempFixed){
+            dwdtvec(i) = dwdt_i; dmechSrcdTvec(i) = dmechSourcedt_i;
             for(int m=0; m<3; m++)
               for(int n=0; n<3; n++){
                 // _C(i*_col_Di + (m+1)*_row_Di-1, i*_col_Di + (n+1)*_row_Di-1) = dqdgradT_i(m,n);
                 _C(i*_col_Di + 9+m, i*_col_Di + 9+n) = dqdgradT_i(m,n);
+                dwdFvec(i*9+m+_row_Di*n) = dwdf_i(m,n);
+                dmechSrcdFvec(i*9+m+_row_Di*n) = dmechSourcedf_i(m,n);
                 for(int k=0; k<3; k++){
                   // _C(i*_col_Di + (m+1)*_row_Di-1, i*_col_Di+n+_row_Di*k) = dqdF_i(m,n,k);
                   // _C(i*_col_Di+m+_row_Di*n, i*_col_Di + (k+1)*_row_Di-1) = 0.; // This is for dPdgradT_i
@@ -5775,6 +5787,7 @@ void StochTMDMNDG3DMaterialLaw::stress(IPVariable*ipv, const IPVariable*ipvprev,
               }
           }
           else if(!_flag_isothermal && !_flag_microTempFixed){
+            dwdtvec(i) = dwdt_i; dmechSrcdTvec(i) = dmechSourcedt_i;
             for(int m=0; m<3; m++){
               _C(i*_col_Di + (m+1)*(_row_Di-1)-1, (i+1)*_col_Di-1) = dqdT_i(m);
               for(int n=0; n<3; n++){
@@ -5782,6 +5795,8 @@ void StochTMDMNDG3DMaterialLaw::stress(IPVariable*ipv, const IPVariable*ipvprev,
                 // _C(i*_col_Di + m + n*(_row_Di-1), (i+1)*_col_Di-1) = dPdT_i(m,n);
                 _C(i*_col_Di + 9+m, i*_col_Di + 9+m) = dqdgradT_i(m,n);
                 _C(i*_col_Di + m + 3*n, (i+1)*_col_Di-1) = dPdT_i(m,n);
+                dwdFvec(i*9+m+_row_Di*n) = dwdf_i(m,n);
+                dmechSrcdFvec(i*9+m+_row_Di*n) = dmechSourcedf_i(m,n);
                 for(int k=0; k<3; k++){
                   // _C(i*_col_Di + (m+1)*(_row_Di-1)-1, i*_col_Di+n+(_row_Di-1)*k) = dqdF_i(m,n,k);
                   // _C(i*_col_Di+m+(_row_Di-1)*n, i*_col_Di + (k+1)*(_row_Di-1)-1) = 0.; // This is for dPdgradT_i
@@ -5863,15 +5878,16 @@ void StochTMDMNDG3DMaterialLaw::stress(IPVariable*ipv, const IPVariable*ipvprev,
     for(int m=0;m<_col_Di;m++){
       PQ_hom[m] = 0.0;
       for(int i=0;i<_NRoot;i++){
-        PQ_hom[m] += (_VA[1]*_V(m, _col_Di*i+m) + _VA[2]*_V(_col_Di+m, _col_Di*i+m)) *PQvec(_col_Di*i+m); // Stress average
+        PQ_hom[m] += (_VA[1]*_V(m, _col_Di*i+m) + _VA[2]*_V(_col_Di+m, _col_Di*i+m))*PQvec(_col_Di*i+m); // Stress average
       }
     }
     
-    Cp_hom, thermSrc_hom, mechSource_hom = 0.;
+    double temp = 0.;
     for(int i=0;i<_NRoot;i++){
-      Cp_hom += (_VA[1]*_V(0, _col_Di*i) + _VA[2]*_V(_col_Di, _col_Di*i)) *Cpvec(i); // Cp average
-      thermSrc_hom += (_VA[1]*_V(0, _col_Di*i) + _VA[2]*_V(_col_Di, _col_Di*i)) *thermSrcvec(i); // w average
-      mechSource_hom += (_VA[1]*_V(0, _col_Di*i) + _VA[2]*_V(_col_Di, _col_Di*i)) *mechSrcvec(i); // mechSrc average
+      temp = (_VA[1]*_V(0, _col_Di*i) + _VA[2]*_V(_col_Di, _col_Di*i));
+      Cp_hom +=  temp*Cpvec(i); // Cp average
+      thermSrc_hom += temp*thermSrcvec(i); // w average
+      mechSource_hom += temp*mechSrcvec(i); // mechSrc average
     }
 
     if (_flag_isothermal && _flag_microTempFixed){
@@ -5911,20 +5927,38 @@ void StochTMDMNDG3DMaterialLaw::stress(IPVariable*ipv, const IPVariable*ipvprev,
       NTVC.mult(_I, dRdF);
       Jacobian.mult(dRdF, dadF);
       _Nv.mult(dadF, tmp);
-      tmp.add(_I);
+      tmp.add(_I); // Check this structure of _I. tmp = dFidF
 
       for(int m=0;m<_col_Di;m++){
         for(int n=0;n<_col_Di;n++){
           C_hom[m][n] = 0.0;
           for(int i=0;i<_NRoot;i++){
             for(int j=0;j< _col_Di*_NRoot;j++){
-              C_hom[m][n] += (_VA[1]*_V(m,m+_col_Di*i) + _VA[2]*_V(_col_Di+m,m+_col_Di*i))*_C(m+_col_Di*i,j)*tmp(j,n); // CHECK
+              C_hom[m][n] += (_VA[1]*_V(m,m+_col_Di*i) + _VA[2]*_V(_col_Di+m,m+_col_Di*i))*_C(m+_col_Di*i,j)*tmp(j,n); 
             }
           }
         }
       }
 
-      if (_flag_isothermal && _flag_microTempFixed){
+      double temp(0.), dTidT(0.);
+      for(int i=0;i<_NRoot;i++){
+        temp = (_VA[1]*_V(0, _col_Di*i) + _VA[2]*_V(_col_Di, _col_Di*i)); // Check
+        if (abs(temp) > 0. && Cpvec(i) > 0.){
+          dTidT = Cp_hom/(temp*Cpvec(i));
+        }
+        else{
+          dTidT = 0.;
+        }
+        dwdt_hom += temp*dwdtvec(i)*dTidT; // dwdT average
+        dmechSourcedt_hom += temp*dmechSrcdTvec(i)*dTidT; // dmechSourcedt average
+        for(int m=0;m<9;m++)
+          for(int n=0;n<9;n++){
+            dwdf_hom[n] += temp*dwdFvec(m+9*i)*tmp(9*i,n);
+            dmechSourcedf_hom[n] += temp*dmechSrcdTvec(m+9*i)*tmp(9*i,n);
+          }
+      }
+
+      if (_flag_isothermal && _flag_microTempFixed){ 
         for(int m=0; m<3; m++)
           for(int n=0; n<3; n++)
             for(int k=0; k<3; k++)
@@ -5932,10 +5966,13 @@ void StochTMDMNDG3DMaterialLaw::stress(IPVariable*ipv, const IPVariable*ipvprev,
                 L(m,n,k,l) = C_hom[m+_row_Di*n][k+_row_Di*l];
       }
       else if(!_flag_isothermal && _flag_microTempFixed){
+        dwdt = dwdt_hom; dmechSourcedt = dmechSourcedt_hom;
         for(int m=0; m<3; m++)
           for(int n=0; n<3; n++){
             // dqdgradT(m,n) = C_hom[(m+1)*_row_Di-1][(n+1)*_row_Di-1];
             dqdgradT(m,n) = C_hom[9+m][9+n];
+            dwdf(m,n) = dwdf_hom[m+3*n];
+            dmechSourcedf(m,n) = dmechSourcedf_hom[m+3*n];
               for(int k=0; k<3; k++){
                 // dqdF(m,n,k) = C_hom[(m+1)*_row_Di-1][n+_row_Di*k];
                 dqdF(m,n,k) = C_hom[9+m][n+3*k];
@@ -5953,6 +5990,8 @@ void StochTMDMNDG3DMaterialLaw::stress(IPVariable*ipv, const IPVariable*ipvprev,
             // dqdgradT(m,n) = C_hom[(m+1)*(_row_Di-1)-1][(n+1)*(_row_Di-1)-1];
             dPdT(m,n) = C_hom[m + n*(_row_Di-1)][_col_Di-1];
             dqdgradT(m,n) = C_hom[9+m][9+n];
+            dwdf(m,n) = dwdf_hom[m+3*n];
+            dmechSourcedf(m,n) = dmechSourcedf_hom[m+3*n];
             for(int k=0; k<3; k++){
               // dqdF(m,n,k) = C_hom[(m+1)*(_row_Di-1)-1][n+(_row_Di-1)*k];
               dqdF(m,n,k) = C_hom[9+m][n+3*k];
-- 
GitLab


From 440f8ac4815603ae66f980083111bc7b9b0111f3 Mon Sep 17 00:00:00 2001
From: FLE_Knight <ujwalkishore.jinaga@uliege.be>
Date: Thu, 6 Mar 2025 15:39:37 +0100
Subject: [PATCH 13/19] [NEW FIX 2] Fixes to TDMN tangents. Removal of older
 convention of gradient vector stack. Bug patches to follow.

---
 dG3D/src/dG3DMaterialLaw.cpp | 44 +++++-------------------------------
 1 file changed, 6 insertions(+), 38 deletions(-)

diff --git a/dG3D/src/dG3DMaterialLaw.cpp b/dG3D/src/dG3DMaterialLaw.cpp
index ac1d4e89c..cf674f88c 100644
--- a/dG3D/src/dG3DMaterialLaw.cpp
+++ b/dG3D/src/dG3DMaterialLaw.cpp
@@ -5671,21 +5671,17 @@ void StochTMDMNDG3DMaterialLaw::stress(IPVariable*ipv, const IPVariable*ipvprev,
         else if(!_flag_isothermal && _flag_microTempFixed){
           Tloc = T;
           for(int m=0; m<3; m++){
-            // Hloc(m) = H(m) + FHvec(i*_col_Di+ (m+1)*_row_Di-1);
             Hloc(m) = H(m) + FHvec(i*_col_Di+ 9+m);
             for(int n=0; n<3; n++){
-              // Floc(m,n) = F(m,n) + FHvec(i*_col_Di + m + n*_row_Di);
               Floc(m,n) = F(m,n) + FHvec(i*_col_Di + m + n*3);
             }
           }
         }
         else if(!_flag_isothermal && !_flag_microTempFixed){
           Tloc = T + FHvec((i+1)*_col_Di-1);
-          for(int m=0; m<3; m++){
-            // Hloc(m) = H(m) + FHvec(i*_col_Di+ (m+1)*(_row_Di-1)-1);  
+          for(int m=0; m<3; m++){  
             Hloc(m) = H(m) + FHvec(i*_col_Di+ 9+m);
             for(int n=0; n<3; n++){
-              // Floc(m,n) = F(m,n) + FHvec(i*_col_Di + m + n*(_row_Di-1));
               Floc(m,n) = F(m,n) + FHvec(i*_col_Di + m + n*3);
             }
           }
@@ -5721,10 +5717,8 @@ void StochTMDMNDG3DMaterialLaw::stress(IPVariable*ipv, const IPVariable*ipvprev,
         else if(!_flag_isothermal && _flag_microTempFixed){
           Cpvec(i) = Cp_i; thermSrcvec(i) = w_i; mechSrcvec(i) = mechSource_i;
           for(int m=0; m<3; m++){
-            // PQvec(i*_col_Di + (m+1)*_row_Di-1) = Q_i(m);
             PQvec(i*_col_Di+ 9+m) = Q_i(m);
             for(int n=0; n<3; n++){
-              // PQvec(i*_col_Di + m + n*_row_Di) = P_i(m,n); 
               PQvec(i*_col_Di + m + n*3) = P_i(m,n);
             }
           }
@@ -5733,10 +5727,8 @@ void StochTMDMNDG3DMaterialLaw::stress(IPVariable*ipv, const IPVariable*ipvprev,
           thermSrcvec(i) = w_i; mechSrcvec(i) = mechSource_i;
           PQvec((i+1)*_col_Di-1) = Cp_i;
           for(int m=0; m<3; m++){
-            // PQvec(i*_col_Di + (m+1)*(_row_Di-1)-1) = Q_i(m);
             PQvec(i*_col_Di+ 9+m) = Q_i(m);
-            for(int n=0; n<3; n++){
-              // PQvec(i*_col_Di + m + n*(_row_Di-1)) = P_i(m,n); 
+            for(int n=0; n<3; n++){ 
               PQvec(i*_col_Di + m + n*3) = P_i(m,n);
             }
           }
@@ -5772,16 +5764,13 @@ void StochTMDMNDG3DMaterialLaw::stress(IPVariable*ipv, const IPVariable*ipvprev,
             dwdtvec(i) = dwdt_i; dmechSrcdTvec(i) = dmechSourcedt_i;
             for(int m=0; m<3; m++)
               for(int n=0; n<3; n++){
-                // _C(i*_col_Di + (m+1)*_row_Di-1, i*_col_Di + (n+1)*_row_Di-1) = dqdgradT_i(m,n);
                 _C(i*_col_Di + 9+m, i*_col_Di + 9+n) = dqdgradT_i(m,n);
                 dwdFvec(i*9+m+_row_Di*n) = dwdf_i(m,n);
                 dmechSrcdFvec(i*9+m+_row_Di*n) = dmechSourcedf_i(m,n);
                 for(int k=0; k<3; k++){
-                  // _C(i*_col_Di + (m+1)*_row_Di-1, i*_col_Di+n+_row_Di*k) = dqdF_i(m,n,k);
                   // _C(i*_col_Di+m+_row_Di*n, i*_col_Di + (k+1)*_row_Di-1) = 0.; // This is for dPdgradT_i
                   _C(i*_col_Di + 9+m, i*_col_Di+n+3*k) = dqdF_i(m,n,k);
                   for(int l=0; l<3; l++)  
-                    // _C(i*_col_Di+m+_row_Di*n, i*_col_Di+k+_row_Di*l) = L_i(m,n,k,l);
                     _C(i*_col_Di+m+3*n, i*_col_Di+k+3*l) = L_i(m,n,k,l);
                 }    
               }
@@ -5791,18 +5780,14 @@ void StochTMDMNDG3DMaterialLaw::stress(IPVariable*ipv, const IPVariable*ipvprev,
             for(int m=0; m<3; m++){
               _C(i*_col_Di + (m+1)*(_row_Di-1)-1, (i+1)*_col_Di-1) = dqdT_i(m);
               for(int n=0; n<3; n++){
-                // _C(i*_col_Di + (m+1)*(_row_Di-1)-1, i*_col_Di + (n+1)*(_row_Di-1)-1) = dqdgradT_i(m,n);
-                // _C(i*_col_Di + m + n*(_row_Di-1), (i+1)*_col_Di-1) = dPdT_i(m,n);
                 _C(i*_col_Di + 9+m, i*_col_Di + 9+m) = dqdgradT_i(m,n);
                 _C(i*_col_Di + m + 3*n, (i+1)*_col_Di-1) = dPdT_i(m,n);
                 dwdFvec(i*9+m+_row_Di*n) = dwdf_i(m,n);
                 dmechSrcdFvec(i*9+m+_row_Di*n) = dmechSourcedf_i(m,n);
                 for(int k=0; k<3; k++){
-                  // _C(i*_col_Di + (m+1)*(_row_Di-1)-1, i*_col_Di+n+(_row_Di-1)*k) = dqdF_i(m,n,k);
                   // _C(i*_col_Di+m+(_row_Di-1)*n, i*_col_Di + (k+1)*(_row_Di-1)-1) = 0.; // This is for dPdgradT_i
                   _C(i*_col_Di + 9+m, i*_col_Di+n+3*k) = dqdF_i(m,n,k);
                   for(int l=0; l<3; l++)  
-                    // _C(i*_col_Di+m+(_row_Di-1)*n, i*_col_Di+k+(_row_Di-1)*l) = L_i(m,n,k,l);
                     _C(i*_col_Di+m+3*n, i*_col_Di+k+3*l) = L_i(m,n,k,l);
                 }    
               }
@@ -5836,7 +5821,7 @@ void StochTMDMNDG3DMaterialLaw::stress(IPVariable*ipv, const IPVariable*ipvprev,
         Jacobian.invertInPlace();
       }
       else{
-        // What is this? How does the following update the jacobian?
+        // Updating Jacobian
         _NTV.mult(PQvec, Res_node);
         Res_node_t.scale(-1.0);
         Res_node_t.axpy(Res_node, 1.0);
@@ -5859,7 +5844,6 @@ void StochTMDMNDG3DMaterialLaw::stress(IPVariable*ipv, const IPVariable*ipvprev,
           }
         }
         stiff_loc = true;
-        // What?
       }
 
       Res_node_t = Res_node;
@@ -5895,17 +5879,15 @@ void StochTMDMNDG3DMaterialLaw::stress(IPVariable*ipv, const IPVariable*ipvprev,
       for(int i=0;i<3;i++){
         Q(i) = 0.;
         for(int j=0;j<3;j++){
-          P(i,j) = PQ_hom[i+_row_Di*j]; // CHECK
+          P(i,j) = PQ_hom[i+_row_Di*j];
         }
       }
     }
     else if(!_flag_isothermal && _flag_microTempFixed){
       Cp = Cp_hom; w = thermSrc_hom; mechSource = mechSource_hom; 
       for(int i=0;i<3;i++){
-        // Q(i) = PQ_hom[(i+1)*_row_Di-1];
         Q(i) = PQ_hom[9+i];
         for(int j=0;j<3;j++){
-          // P(i,j) = PQ_hom[i+_row_Di*j];
           P(i,j) = PQ_hom[i+3*j]; 
         }
       }
@@ -5913,10 +5895,8 @@ void StochTMDMNDG3DMaterialLaw::stress(IPVariable*ipv, const IPVariable*ipvprev,
     else if(!_flag_isothermal && !_flag_microTempFixed){
       Cp = PQ_hom[_col_Di-1]; w = thermSrc_hom; mechSource = mechSource_hom;
       for(int i=0;i<3;i++){
-        // Q(i) = PQ_hom[(i+1)*(_row_Di-1)-1];
         Q(i) = PQ_hom[9+i];
         for(int j=0;j<3;j++){
-          // P(i,j) = PQ_hom[i+(_row_Di-1)*j];
           P(i,j) = PQ_hom[i+3*j];
         }
       }  
@@ -5940,15 +5920,9 @@ void StochTMDMNDG3DMaterialLaw::stress(IPVariable*ipv, const IPVariable*ipvprev,
         }
       }
 
-      double temp(0.), dTidT(0.);
+      double temp(0.), dTidT(1.); // = Cp_hom/(temp*Cpvec(i))
       for(int i=0;i<_NRoot;i++){
-        temp = (_VA[1]*_V(0, _col_Di*i) + _VA[2]*_V(_col_Di, _col_Di*i)); // Check
-        if (abs(temp) > 0. && Cpvec(i) > 0.){
-          dTidT = Cp_hom/(temp*Cpvec(i));
-        }
-        else{
-          dTidT = 0.;
-        }
+        temp = (_VA[1]*_V(0, _col_Di*i) + _VA[2]*_V(_col_Di, _col_Di*i));
         dwdt_hom += temp*dwdtvec(i)*dTidT; // dwdT average
         dmechSourcedt_hom += temp*dmechSrcdTvec(i)*dTidT; // dmechSourcedt average
         for(int m=0;m<9;m++)
@@ -5969,16 +5943,13 @@ void StochTMDMNDG3DMaterialLaw::stress(IPVariable*ipv, const IPVariable*ipvprev,
         dwdt = dwdt_hom; dmechSourcedt = dmechSourcedt_hom;
         for(int m=0; m<3; m++)
           for(int n=0; n<3; n++){
-            // dqdgradT(m,n) = C_hom[(m+1)*_row_Di-1][(n+1)*_row_Di-1];
             dqdgradT(m,n) = C_hom[9+m][9+n];
             dwdf(m,n) = dwdf_hom[m+3*n];
             dmechSourcedf(m,n) = dmechSourcedf_hom[m+3*n];
               for(int k=0; k<3; k++){
-                // dqdF(m,n,k) = C_hom[(m+1)*_row_Di-1][n+_row_Di*k];
                 dqdF(m,n,k) = C_hom[9+m][n+3*k];
                 // dPdgradT(m,n,l) = C_hom[m+_row_Di*n][(k+1)*_row_Di-1]; // 0. This is for dPdgradT
                 for(int l=0; l<3; l++)  
-                  // L(m,n,k,l) = C_hom[m+_row_Di*n][k+_row_Di*l];
                   L(m,n,k,l) = C_hom[m+3*n][k+3*l];
               }    
             }
@@ -5987,17 +5958,14 @@ void StochTMDMNDG3DMaterialLaw::stress(IPVariable*ipv, const IPVariable*ipvprev,
         for(int m=0; m<3; m++){
           dqdT(m) = C_hom[(m+1)*(_row_Di-1)-1][_col_Di-1];
           for(int n=0; n<3; n++){
-            // dqdgradT(m,n) = C_hom[(m+1)*(_row_Di-1)-1][(n+1)*(_row_Di-1)-1];
             dPdT(m,n) = C_hom[m + n*(_row_Di-1)][_col_Di-1];
             dqdgradT(m,n) = C_hom[9+m][9+n];
             dwdf(m,n) = dwdf_hom[m+3*n];
             dmechSourcedf(m,n) = dmechSourcedf_hom[m+3*n];
             for(int k=0; k<3; k++){
-              // dqdF(m,n,k) = C_hom[(m+1)*(_row_Di-1)-1][n+(_row_Di-1)*k];
               dqdF(m,n,k) = C_hom[9+m][n+3*k];
               // C_hom[m+(_row_Di-1)*n][(k+1)*(_row_Di-1)-1] = 0.; This is for dPdgradT
               for(int l=0; l<3; l++)  
-                // L(m,n,k,l) = C_hom[m+(_row_Di-1)*n][k+(_row_Di-1)*l];
                 L(m,n,k,l) = C_hom[m+3*n][k+3*l];
               }    
             }
-- 
GitLab


From 9e364366267573c8738d19dff2f7ec8605a53a94 Mon Sep 17 00:00:00 2001
From: FLE_Knight <ujwalkishore.jinaga@uliege.be>
Date: Tue, 11 Mar 2025 17:41:31 +0100
Subject: [PATCH 14/19] [NEW FIX 3] Compatibility with StochDMN

---
 dG3D/src/dG3DMaterialLaw.cpp | 226 +++++++++++------------------------
 dG3D/src/dG3DMaterialLaw.h   |  12 +-
 2 files changed, 78 insertions(+), 160 deletions(-)

diff --git a/dG3D/src/dG3DMaterialLaw.cpp b/dG3D/src/dG3DMaterialLaw.cpp
index 50fdf896f..0e6214ed8 100644
--- a/dG3D/src/dG3DMaterialLaw.cpp
+++ b/dG3D/src/dG3DMaterialLaw.cpp
@@ -4999,9 +4999,9 @@ void StochDMNDG3DMaterialLaw::setTime(const double t,const double dtime){
 }
 
 // FLE
-StochTMDMNDG3DMaterialLaw::StochTMDMNDG3DMaterialLaw(const int num, const double rho, const double E,const double nu, const char *ParaFile,
+StochTMDMNDG3DMaterialLaw::StochTMDMNDG3DMaterialLaw(const int num, const double rho, const double E,const double nu, const char *ParaFile, const bool ReadTree,
       const bool porous, const bool flag_isothermal, const bool flag_microTempFixed, const double tol):
-      StochDMNDG3DMaterialLaw(num,rho,E,nu,ParaFile,porous,tol),_flag_isothermal(flag_isothermal),_flag_microTempFixed(flag_microTempFixed){
+      StochDMNDG3DMaterialLaw(num,rho,E,nu,ParaFile,ReadTree,porous,tol),_flag_isothermal(flag_isothermal),_flag_microTempFixed(flag_microTempFixed){
   
   // Meanings of _col_Di and _row_Di are interchanged in this class.
   if (_flag_isothermal && _flag_microTempFixed){
@@ -5016,8 +5016,12 @@ StochTMDMNDG3DMaterialLaw::StochTMDMNDG3DMaterialLaw(const int num, const double
   else{
     Msg::Error("This combination of flags doesn't exist. Redefine in the constructor.");
   }
+  if(_ReadTree){
+    StochDMNDG3DMaterialLaw::read_TreeData(ParaFile);
+  }
+  else{
+    StochTMDMNDG3DMaterialLaw::read_parameter(ParaFile);
 
-  StochTMDMNDG3DMaterialLaw::read_parameter(ParaFile); 
   StochTMDMNDG3DMaterialLaw::fill_Matrices();         
 }
 
@@ -5031,29 +5035,22 @@ void StochTMDMNDG3DMaterialLaw::createIPState(IPStateBase* &ips, bool hasBodyFor
   bool inter=true;
   const MInterfaceElement *iele = dynamic_cast<const MInterfaceElement*>(ele);
   if(iele==NULL) inter=false;
-    IPVariable* ipvi = new StochTMDMNDG3DIPVariable(_NRoot, _NInterface, _col_Di, _row_Di, hasBodyForce,inter);
-    IPVariable* ipv1 = new StochTMDMNDG3DIPVariable(_NRoot, _NInterface, _col_Di, _row_Di, hasBodyForce,inter);
-    IPVariable* ipv2 = new StochTMDMNDG3DIPVariable(_NRoot, _NInterface, _col_Di, _row_Di, hasBodyForce,inter);
-
-    StochTMDMNDG3DIPVariable* ipvi_root = static_cast<StochTMDMNDG3DIPVariable*>(ipvi);
-    StochTMDMNDG3DIPVariable* ipv1_root = static_cast<StochTMDMNDG3DIPVariable*>(ipv1);
-    StochTMDMNDG3DIPVariable* ipv2_root = static_cast<StochTMDMNDG3DIPVariable*>(ipv2);
-    for (int i=0; i< _NRoot; i++){
+    IPVariable* ipvi = new StochTMDMNDG3DIPVariable(_NLeaf, _NInterface, _col_Di, _row_Di, hasBodyForce,inter);
+    IPVariable* ipv1 = new StochTMDMNDG3DIPVariable(_NLeaf, _NInterface, _col_Di, _row_Di, hasBodyForce,inter);
+    IPVariable* ipv2 = new StochTMDMNDG3DIPVariable(_NLeaf, _NInterface, _col_Di, _row_Di, hasBodyForce,inter);
+
+    StochTMDMNDG3DIPVariable* ipvi_Leaf = static_cast<StochTMDMNDG3DIPVariable*>(ipvi);
+    StochTMDMNDG3DIPVariable* ipv1_Leaf = static_cast<StochTMDMNDG3DIPVariable*>(ipv1);
+    StochTMDMNDG3DIPVariable* ipv2_Leaf = static_cast<StochTMDMNDG3DIPVariable*>(ipv2);
+    for (int i=0; i< _NLeaf; i++){
       int mat_IP = 0;
       IPStateBase* ips_i = NULL;
-      if(_Modified_DMN){
-        if(i%3 == 1) mat_IP = 1;
-      }
-      else{
-         mat_IP = i%2;
-      }
-      if(_porous) mat_IP=0;
       _mapLaw[mat_IP]->createIPState(ips_i, hasBodyForce, state_, ele, nbFF_, GP, gpt);
       std::vector<IPVariable*> ip_all;
       ips_i->getAllIPVariable(ip_all);
-      ipvi_root->addIPv(i, ip_all[0]);
-      ipv1_root->addIPv(i, ip_all[1]);
-      ipv2_root->addIPv(i, ip_all[2]);
+      ipvi_Leaf->addIPv(i, ip_all[0]);
+      ipv1_Leaf->addIPv(i, ip_all[1]);
+      ipv2_Leaf->addIPv(i, ip_all[2]);
     }
     if(ips != NULL) delete ips;
       ips = new IP3State(state_,ipvi,ipv1,ipv2);
@@ -5066,20 +5063,14 @@ void StochTMDMNDG3DMaterialLaw::createIPVariable(IPVariable* &ipv, bool hasBodyF
   if(iele == NULL){
     inter=false;
   }
-  ipv = new  StochTMDMNDG3DIPVariable(_NRoot, _NInterface, _col_Di, _row_Di, hasBodyForce,inter);
-  StochTMDMNDG3DIPVariable* ipv_root = static_cast<StochTMDMNDG3DIPVariable*>(ipv);
-  for (int i=0; i< _NRoot; i++){
+  ipv = new  StochTMDMNDG3DIPVariable(_NLeaf, _NInterface, _col_Di, _row_Di, hasBodyForce,inter);
+  StochTMDMNDG3DIPVariable* ipv_Leaf = static_cast<StochTMDMNDG3DIPVariable*>(ipv);
+  int mat_IP;
+  for (int i=0; i< _NLeaf; i++){
     IPVariable* ipv_i = NULL;
-    int mat_IP =0;
-    if(_Modified_DMN){
-      if(i%3 == 1) mat_IP = 1;
-    }
-    else{
-       mat_IP = i%2;
-    }
-    if(_porous) mat_IP=0;
+    mat_IP = _Mat_Id[_NInterface + i];
     _mapLaw[mat_IP]->createIPVariable(ipv_i, hasBodyForce, ele, nbFF_, GP, gpt);
-    ipv_root->addIPv(i, ipv_i);
+    ipv_Leaf->addIPv(i, ipv_i);
   }
 };
 
@@ -5089,16 +5080,10 @@ void StochTMDMNDG3DMaterialLaw::initialIPVariable(IPVariable* ipv, bool stiff){
   if (ipv_all == NULL){
     Msg::Error("StochTMDMNDG3DIPVariable must be used in StochTMDMNDG3DMaterialLaw::initialIPVariable");
   }
-  for (int i=0; i< _NRoot; i++){
+  int mat_IP;
+  for (int i=0; i< _NLeaf; i++){
     IPVariable* ipv_i = ipv_all->getIPv(i);
-    int mat_IP =0;
-    if(_Modified_DMN){
-      if(i%3 == 1) mat_IP = 1;
-    }
-    else{
-        mat_IP = i%2;
-    }
-    if(_porous) mat_IP=0;
+    mat_IP = _Mat_Id[_NInterface + i];
     _mapLaw[mat_IP]->initialIPVariable(ipv_i, stiff);
   }
 }
@@ -5109,17 +5094,11 @@ void StochTMDMNDG3DMaterialLaw::checkInternalState(IPVariable* ipv, const IPVari
   if (ipv_all == NULL){
     Msg::Error("StochTMDMNDG3DIPVariable must be used in StochTMDMNDG3DMaterialLaw::checkInternalState");
   }
-  for (int i=0; i< _NRoot; i++){
+  int mat_IP;
+  for (int i=0; i< _NLeaf; i++){
     IPVariable* ipv_i = ipv_all->getIPv(i);
     const IPVariable* ipvprev_i = ipvprev_all->getIPv(i);
-    int mat_IP = 0;
-    if(_Modified_DMN){
-      if(i%3 == 1) mat_IP = 1;
-    }
-    else{
-       mat_IP = i%2;
-    }
-    if(_porous) mat_IP=0;
+    mat_IP = _Mat_Id[_NInterface + i];
     _mapLaw[mat_IP]->checkInternalState(ipv_i, ipvprev_i);
   }
 }
@@ -5151,9 +5130,6 @@ void StochTMDMNDG3DMaterialLaw::fill_NLocal(const int pos, std::vector<std::vect
     N.resize(_col_Di);
     for(auto& row : N)
       row.resize(_row_Di,0.);
-    // N[0][0] = n0; N[1][1] = n0; N[2][2] = n0;  N[3][3] = n0;
-    // N[4][0] = n1; N[5][1] = n1; N[6][2] = n1;  N[7][3] = n1;
-    // N[8][0] = n2; N[9][1] = n2; N[10][2] = n2; N[11][3] = n2; 
     N[0][0] = n0; N[1][1] = n0; N[2][2] = n0;
     N[3][0] = n1; N[4][1] = n1; N[5][2] = n1;
     N[6][0] = n2; N[7][1] = n2; N[8][2] = n2;
@@ -5163,11 +5139,6 @@ void StochTMDMNDG3DMaterialLaw::fill_NLocal(const int pos, std::vector<std::vect
     N.resize(_col_Di);
     for(auto& row : N)
       row.resize(_row_Di,0.);
-    // N[0][0] = n0; N[1][1] = n0; N[2][2] = n0;  N[3][3] = n0;
-    // N[4][0] = n1; N[5][1] = n1; N[6][2] = n1;  N[7][3] = n1;
-    // N[8][0] = n2; N[9][1] = n2; N[10][2] = n2; N[11][3] = n2; 
-    // N[12][4] = 1.;
-
     N[0][0] = n0; N[1][1] = n0; N[2][2] = n0;
     N[3][0] = n1; N[4][1] = n1; N[5][2] = n1;
     N[6][0] = n2; N[7][1] = n2; N[8][2] = n2;
@@ -5179,24 +5150,8 @@ void StochTMDMNDG3DMaterialLaw::fill_NLocal(const int pos, std::vector<std::vect
   }
 }
 
-void StochTMDMNDG3DMaterialLaw::pos_kids(const int pos, const int level, int& pos0, int& pos1) const {
-
-  // code to calculate positions of child nodes using given "pos" and "level"
-
-  if(!_Modified_DMN or level<_TotalLevel-2 ){
-      pos0 = 2*pos+1;
-      pos1 = 2*pos+2;
-  }
-  else if(level ==_TotalLevel-2){
-    pos0 = pos + pow(2, level);
-    int k = pos - (pow(2, level)-1);
-    pos1 =  int(3*pow(2, level)-1) + k*3+2; // CHECK
-  }
-  else if(level==_TotalLevel-1){
-    int k = pos - (pow(2, level)-1);
-    pos0 = int(3*pow(2, level-1)-1) +k*3; // CHECK
-    pos1 = pos0+1;
-  }
+void StochTMDMNDG3DMaterialLaw::initLaws(const std::map<int,materialLaw*> &maplaw){
+  // To define this function, StochDMNDG3DMaterialLaw::TwoPhasesInteract has to be redefined in this class.
 }
 
 // fill the matrices which keep the topological information
@@ -5204,25 +5159,28 @@ void StochTMDMNDG3DMaterialLaw::fill_Matrices(){
 
   std::vector<std::vector<double>> Norm;   // double Norm[9][3];
   double W_WI[2][2];
-  int pos0=0;
-  int pos1=0;
-  int k, node;
+  int pos0, pos1;
+  int L_ch0, L_ch1;
+  int node_start0, node_end0, node_start1, node_end1;
   int Col_start, Col_start0, Col_start1, Row_start, Row_start0, Row_start1;
   double tmp;
 
   // set the size of rows and cols in Di matrix
   int col = _col_Di; // = 9, 12;
+  
+  _VA.resize(_N_Node,0.0); // Vector for position of nodes for Stress
+  _VA[0] = 1.0;
+  _VI.resize(_NInterface, 0.0); // fill matrix for equilibrium of interface
+  _VI[0] = _Vf;
+  int l;
 
-  for(int i=0; i <_N_Node; i++){
-    _VA.push_back(1.0); // Vector for position of nodes for Stress
-  }
-  // fill matrix for equilibrium of interface
-  _VI.push_back(_Vf);
-  int l = -1;
   for(int pos=0; pos <_NInterface; pos++){
-    if(pos == int(pow(2,l+1)-1)) l +=1; // if its the first position (interface) of every level, l+=1
+    l = _NodeLevel[pos];
     fill_NLocal(pos,Norm);  // size of Norm depends on the flags set inside this function
-    pos_kids(pos, l, pos0, pos1);
+    pos0 = _Child[pos][0];
+    pos1 = _Child[pos][1];
+    L_ch0 = _NodeLevel[pos0];
+    L_ch1 = _NodeLevel[pos1];
     Row_start = pos*_row_Di; // 3, 4;
     Col_start0 = (pos0-1)*col;
     Col_start1 = (pos1-1)*col;
@@ -5247,83 +5205,50 @@ void StochTMDMNDG3DMaterialLaw::fill_Matrices(){
         _VA[pos1] = _VI[pos];
       }
     }
-    else if(_Modified_DMN and l ==_TotalLevel-2){ // Composite nodes - 2nd last level
-      StochDMNDG3DMaterialLaw::fill_W_WI(pos,l,W_WI);
-      _VA[pos0] = W_WI[0][0];
-      _VA[pos1] = W_WI[0][1];
-      _VI.push_back(W_WI[1][0]); // Collect v_1A for all composite nodes
-    }
     else{ // Composite nodes - all other levels
       StochDMNDG3DMaterialLaw::fill_W_WI(pos,l,W_WI);
       _VA[pos0] = W_WI[0][0];
       _VA[pos1] = W_WI[0][1];
-      _VI.push_back(W_WI[1][0]);
-      _VI.push_back(W_WI[1][1]);
+      if(L_ch0 < _TotalLevel) _VI[pos0]=W_WI[1][0];
+      if(L_ch1 < _TotalLevel) _VI[pos1]=W_WI[1][1];
+      // Msg::Info("Node= %d,%d,%d, VI = %f,%f,%f",pos,pos0,pos1,_VI[pos],W_WI[1][0],W_WI[1][1]);
     }
     //information of homogenous strain to local strain
     Col_start = pos*_row_Di; // *3, 4 // Note that the meanings of _row_Di and _col_Di have been swapped
-    if(!_Modified_DMN or l< _TotalLevel-2){
-      k = int(pow(2,l));
-      node = _NRoot/k/2;
-      int i = pos-int(pow(2,l))+1;
-      for(int r=0; r<node; r++){
-        Row_start0 = (i*2*node+r)*col;
-        Row_start1 = (i*2*node+r+node)*col;
-        for(int nr=0; nr<col;nr++){
-          for(int nc=0; nc<_row_Di;nc++){
-            _Nv.set(Row_start0+nr, Col_start+nc,Norm[nr][nc]/_VA[pos0]);
-            _Nv.set(Row_start1+nr, Col_start+nc,-S_ba*Norm[nr][nc]/_VA[pos1]);
-          }
-        }
-      }
-    }
-    else if(l == _TotalLevel-2){
-      node = _row_Di; // 3;
-      int i = pos-int(pow(2,l))+1;
-      for(int r=0; r<2; r++){
-        Row_start0 = (i*node+r)*col;
-        for(int nr=0; nr<col;nr++){
-          for(int nc=0; nc<_row_Di; nc++){
-            _Nv.set(Row_start0+nr, Col_start+nc,Norm[nr][nc]/_VA[pos0]);
-          }
-        }
-      }
-      Row_start1 = (i*node+2)*col;
+    StochDMNDG3DMaterialLaw::getLeafOfInterface(pos0, node_start0, node_end0);
+    StochDMNDG3DMaterialLaw::getLeafOfInterface(pos1, node_start1, node_end1);
+    for(int r=node_start0; r<=node_end0; r++){
+      Row_start0 = (r-_NInterface)*col;
       for(int nr=0; nr<col;nr++){
-        for(int nc=0; nc<_row_Di; nc++){
-          _Nv.set(Row_start1+nr, Col_start+nc,-S_ba*Norm[nr][nc]/_VA[pos1]);
+        for(int nc=0; nc<_row_Di;nc++){
+          _Nv.set(Row_start0+nr, Col_start+nc, Norm[nr][nc]/_VA[pos0]);
         }
       }
     }
-    else if(l == _TotalLevel-1){
-      node = _row_Di; // 3;
-      int i = pos-int(pow(2,l))+1;
-      Row_start0 = (i*node)*col;
-      Row_start1 = (i*node+1)*col;
+    for(int r=node_start1; r<=node_end1; r++){
+      Row_start1 = (r-_NInterface)*col;
       for(int nr=0; nr<col;nr++){
-        for(int nc=0; nc<_row_Di; nc++){
-          _Nv.set(Row_start0+nr, Col_start+nc,Norm[nr][nc]/_VA[pos0]);
+        for(int nc=0; nc<_row_Di;nc++){
           _Nv.set(Row_start1+nr, Col_start+nc,-S_ba*Norm[nr][nc]/_VA[pos1]);
         }
       }
-    }
-   }
+    }         
+  }
 
  // information of volume fraction to stress on node
-  Row_start = col*(_N_Node-1-_NRoot);
-  for(int nc=0; nc<col*_NRoot; nc++){
+  Row_start = col*(_N_Node-1-_NLeaf);
+  for(int nc=0; nc<col*_NLeaf; nc++){
     _V.set(Row_start+nc,nc,1.0);
   }
 
-  l = _TotalLevel-1;
   for(int pos = _NInterface-1; pos > 0; pos--){
-    if(pos == int(pow(2,l)-2)) l -=1;
-    pos_kids(pos, l, pos0, pos1);
+    pos0 = _Child[pos][0];
+    pos1 = _Child[pos][1];
     Row_start = (pos-1)*col;
     Row_start0 = (pos0-1)*col;
     Row_start1 = (pos1-1)*col;
     for(int nr=0; nr<col;nr++){
-      for(int nc=0; nc<col*_NRoot ; nc++){
+      for(int nc=0; nc<col*_NLeaf ; nc++){
         tmp = _VA[pos0]*_V(Row_start0+nr,nc) + _VA[pos1]*_V(Row_start1+nr,nc);
         _V.set(Row_start+nr,nc, tmp);
       }
@@ -5331,7 +5256,7 @@ void StochTMDMNDG3DMaterialLaw::fill_Matrices(){
   }
   _NT.mult(_V, _NTV);
 
-  for(int i=0; i<col*_NRoot;i++){
+  for(int i=0; i<col*_NLeaf;i++){
     _I(i, i%col) = 1.0;
   }
 }
@@ -5341,24 +5266,17 @@ void StochTMDMNDG3DMaterialLaw::fill_Matrices(){
 void StochTMDMNDG3DMaterialLaw::read_parameter(const char *ParaFile){
 
   double sin0, cos0, sin1, cos1;
-  int Model;
+
   FILE *Para = fopen(ParaFile, "r");
   if ( Para != NULL ){
-    int okf = fscanf(Para, "%d\n", &Model);
-    _Modified_DMN = static_cast<bool>(Model);
-
-    okf = fscanf(Para, "%d %d\n", &_Dim, &_TotalLevel);
+    int okf = fscanf(Para, "%d %d\n", &_Dim, &_TotalLevel);
 
     bool resizeFlag;
-    if(_Modified_DMN){
-       _NRoot = int(pow(2,(_TotalLevel-2))*3); // CHECK THIS FLAG
-    }
-    else{
-      _NRoot = int(pow(2,_TotalLevel));
-    }
-    _NInterface = _NRoot-1;
-    _N_Node = _NRoot + _NInterface;
+    _NLeaf = int(pow(2,_TotalLevel));
+    _NInterface = _NLeaf-1;
+    _N_Node = _NLeaf + _NInterface;
 
+    // START HERE
     int row = _col_Di*_NRoot;
     int col = _row_Di*_NInterface;
     resizeFlag = _Nv.resize(row, col, true);
diff --git a/dG3D/src/dG3DMaterialLaw.h b/dG3D/src/dG3DMaterialLaw.h
index 6b3fa8a4f..765ee706e 100644
--- a/dG3D/src/dG3DMaterialLaw.h
+++ b/dG3D/src/dG3DMaterialLaw.h
@@ -709,8 +709,8 @@ class StochDMNDG3DMaterialLaw : public dG3DMaterialLaw{
     std::vector<std::vector<int>> _Child;      // Child[Node][0] = left child ; Child[Node][1] = right child of Node
  
     
-    std::vector<SPoint2> _Para_Wt;
-    std::vector<SPoint3> _Para_Norm; 
+    std::vector<SPoint2> _Para_Wt; // vector of weights
+    std::vector<SPoint3> _Para_Norm; // vector of normals
     fullMatrix<double> _ParaAngle;   
     std::vector<dG3DMaterialLaw*> _mapLaw;
     fullMatrix<double> _Nv;
@@ -784,12 +784,11 @@ class StochTMDMNDG3DMaterialLaw : public StochDMNDG3DMaterialLaw{
     std::vector<double> _Para_Alpha; // vector of coefficients 
     void fill_Matrices();
     void read_parameter(const char *ParaFile);
-    void fill_NLocal(const int pos,  std::vector<std::vector<double>> N)const;
-    void pos_kids(const int pos, const int level, int& pos0, int& pos1) const;
+    void fill_NLocal(const int pos,  std::vector<std::vector<double>> N) const;
     #endif //SWIG
   public:
-    StochTMDMNDG3DMaterialLaw(const int num, const double rho, const double E,const double nu, const char *ParaFile,
-                      const bool porous, const bool flag_isothermal, const bool flag_microTempFixed, const double tol=1e-6);
+    StochTMDMNDG3DMaterialLaw(const int num, const double rho, const double E,const double nu, const char *ParaFile, const bool ReadTree=false,
+                      const bool porous = false, const bool flag_isothermal = false, const bool flag_microTempFixed = true, const double tol=1e-6);
     #ifndef SWIG
     StochTMDMNDG3DMaterialLaw(const StochTMDMNDG3DMaterialLaw &source);
     virtual ~StochTMDMNDG3DMaterialLaw();
@@ -800,6 +799,7 @@ class StochTMDMNDG3DMaterialLaw : public StochDMNDG3DMaterialLaw{
     virtual void createIPState(IPStateBase* &ips, bool hasBodyForce, const bool* state_=NULL,const MElement *ele=NULL, const int nbFF_=0, const IntPt *GP=NULL, const int gpt = 0) const;
     virtual void createIPVariable(IPVariable* &ipv, bool hasBodyForce, const MElement *ele, const int nbFF_, const IntPt *GP, const int gpt) const;
     virtual void initialIPVariable(IPVariable* ipv, bool stiff);   
+    virtual void initLaws(const std::map<int,materialLaw*> &maplaw);
     virtual double scaleFactor() const {return 1.;};
     virtual double soundSpeed() const {return 0.;};
     virtual materialLaw* clone() const {return new StochTMDMNDG3DMaterialLaw(*this);};
-- 
GitLab


From e67ec579591c6340642581295560c641dbc0c011 Mon Sep 17 00:00:00 2001
From: FLE_Knight <ujwalkishore.jinaga@uliege.be>
Date: Tue, 11 Mar 2025 21:24:53 +0100
Subject: [PATCH 15/19] [NEW FIX 4] Adapted TMDMN to StochDMN class

---
 dG3D/src/dG3DMaterialLaw.cpp | 351 +++++++++++++++++++++--------------
 dG3D/src/dG3DMaterialLaw.h   |   1 +
 2 files changed, 215 insertions(+), 137 deletions(-)

diff --git a/dG3D/src/dG3DMaterialLaw.cpp b/dG3D/src/dG3DMaterialLaw.cpp
index 0e6214ed8..10142396d 100644
--- a/dG3D/src/dG3DMaterialLaw.cpp
+++ b/dG3D/src/dG3DMaterialLaw.cpp
@@ -5017,16 +5017,17 @@ StochTMDMNDG3DMaterialLaw::StochTMDMNDG3DMaterialLaw(const int num, const double
     Msg::Error("This combination of flags doesn't exist. Redefine in the constructor.");
   }
   if(_ReadTree){
-    StochDMNDG3DMaterialLaw::read_TreeData(ParaFile);
+    StochTMDMNDG3DMaterialLaw::read_TreeData(ParaFile);
   }
   else{
     StochTMDMNDG3DMaterialLaw::read_parameter(ParaFile);
+  }
 
   StochTMDMNDG3DMaterialLaw::fill_Matrices();         
 }
 
-StochTMDMNDG3DMaterialLaw::StochTMDMNDG3DMaterialLaw(const StochTMDMNDG3DMaterialLaw &src): StochDMNDG3DMaterialLaw(src), 
-    _col_Di(src._col_Di), _row_Di(src._row_Di), _flag_isothermal(src._flag_isothermal), _flag_microTempFixed(src._flag_microTempFixed), _Para_Alpha(src._Para_Alpha){}
+StochTMDMNDG3DMaterialLaw::StochTMDMNDG3DMaterialLaw(const StochTMDMNDG3DMaterialLaw &source): StochDMNDG3DMaterialLaw(source), 
+    _col_Di(source._col_Di), _row_Di(source._row_Di), _flag_isothermal(source._flag_isothermal), _flag_microTempFixed(source._flag_microTempFixed), _Para_Alpha(source._Para_Alpha){};
 
 StochTMDMNDG3DMaterialLaw::~StochTMDMNDG3DMaterialLaw(){};
 
@@ -5206,7 +5207,7 @@ void StochTMDMNDG3DMaterialLaw::fill_Matrices(){
       }
     }
     else{ // Composite nodes - all other levels
-      StochDMNDG3DMaterialLaw::fill_W_WI(pos,l,W_WI);
+      StochDMNDG3DMaterialLaw::fill_W_WI(pos,W_WI);
       _VA[pos0] = W_WI[0][0];
       _VA[pos1] = W_WI[0][1];
       if(L_ch0 < _TotalLevel) _VI[pos0]=W_WI[1][0];
@@ -5276,55 +5277,43 @@ void StochTMDMNDG3DMaterialLaw::read_parameter(const char *ParaFile){
     _NInterface = _NLeaf-1;
     _N_Node = _NLeaf + _NInterface;
 
-    // START HERE
-    int row = _col_Di*_NRoot;
+    int row = _col_Di*_NLeaf;
     int col = _row_Di*_NInterface;
     resizeFlag = _Nv.resize(row, col, true);
 
     resizeFlag = _I.resize(row, _col_Di, true);
 
     row = _col_Di*(_N_Node-1);
-    col = _col_Di*_NRoot;
+    col = _col_Di*_NLeaf;
     resizeFlag = _V.resize(row, col, true);
         
     row = _row_Di*_NInterface;        
     resizeFlag = _NTV.resize(row, col, true);  
     
-    resizeFlag = _NT.resize(_row_Di*_NInterface, _col_Di*(_N_Node-1), true);            
+    resizeFlag = _NT.resize(row, _col_Di*(_N_Node-1), true);            
         
     okf = fscanf(Para, "%lf\n", &_Vf);
 
     _NPara_Norm = _NInterface;
     
-    resizeFlag = _C.resize(_col_Di*_NRoot,_col_Di*_NRoot,true);
-    resizeFlag = Jacobian.resize(_row_Di*_NInterface, _row_Di*_NInterface,true); 
+    resizeFlag = _C.resize(col,col,true);
+    resizeFlag = Jacobian.resize(row,row,true); 
     
-    _ParaAngle.resize(_NInterface,2,true);
+    resizeFlag = _ParaAngle.resize(_NInterface,2,true);
         
     double ParaN[2]; // W_alpha and w_beta -> Eq. 37 in Ling's draft
     double Pi(3.14159265359);        
     SPoint3 Para_Norm;
     SPoint2 Para_Wt;
 
-    if(_Dim==2){
-      ParaN[1] = 0.0;
-      sin1 = sin(Pi*ParaN[1]);
-      cos1 = cos(Pi*ParaN[1]);
-      for(int i=0;i<_NInterface;i++){          
+    for(int i=0;i<_NInterface;i++){        
+      if(_Dim==2){  
         okf = fscanf(Para, "%lf\n", &ParaN[0]);
-        sin0 = sin(2.0*Pi*ParaN[0]);
-        cos0 = cos(2.0*Pi*ParaN[0]);
-        Para_Norm[0] = cos1*sin0;
-        Para_Norm[1] = cos1*cos0;
-        Para_Norm[2] = sin1;
-        _Para_Norm.push_back(Para_Norm); 
-        _ParaAngle(i,0) =  ParaN[0];
+        ParaN[1] = 0.0; 
       }
-    }
-
-    else if(_Dim==3){
-      for(int i=0;i<_NInterface;i++){
+      else if(_Dim==3){
         okf = fscanf(Para, "%lf %lf\n", &ParaN[0],  &ParaN[1]);
+      }
         sin0 = sin(2.0*Pi*ParaN[0]);
         cos0 = cos(2.0*Pi*ParaN[0]);
         sin1 = sin(Pi*ParaN[1]);
@@ -5335,7 +5324,6 @@ void StochTMDMNDG3DMaterialLaw::read_parameter(const char *ParaFile){
         _Para_Norm.push_back(Para_Norm); 
         _ParaAngle(i,0) =  ParaN[0];
         _ParaAngle(i,1) =  ParaN[1]; 
-      }  
     }       
         
     if(_porous){
@@ -5349,49 +5337,178 @@ void StochTMDMNDG3DMaterialLaw::read_parameter(const char *ParaFile){
       _Para_Wt.push_back(Para_Wt);
     }
   }
-  Msg::Info("Finish reading parameter file, Model = %d, level = %d, Dim = %d, NRoot = %d",Model, _TotalLevel, _Dim, _NRoot);
+   // creat data as for tree data
+  int n = 0;
+  int m = -10;
+  for(int l=0; l<=_TotalLevel; l++){
+    std::vector<int> ln;
+    _LevelNode.push_back(ln);
+    while(n < pow(2,l+1)-1){
+      _LevelNode[l].push_back(n);
+      _NodeLevel.push_back(l);
+      if(n==0){
+        _Parent.push_back(0);
+      }
+      else{
+        _Parent.push_back(int((n-1)/2));
+      }
+      if(l==_TotalLevel){
+        _Mat_Id.push_back((n+1)%2);
+      }
+      else{
+        std::vector<int> ch;
+        ch.push_back(2*n+1);
+        ch.push_back(2*n+2);
+        _Child.push_back(ch);
+        _Mat_Id.push_back(m);
+      }      
+      n +=1;
+    }  
+  }
+
+  Msg::Info("Finish reading parameter filefor Complete Binary Tree,  level = %d, Dim = %d, NLeaf = %d", _TotalLevel, _Dim, _NLeaf);
 }
    // end of read_parameter
 
+void StochTMDMNDG3DMaterialLaw::read_TreeData(const char *TreeFile){
+  std::ifstream file(TreeFile);
+  if(!file.is_open()) {
+        Msg::Error( "Error: Could not open the tree file." );
+        return ;
+  }
+  int level_value, node_value, parent_value;
+  double sin0, cos0, sin1,cos1;
+  double ParaN[2];
+  int pn = 0;
+  double Pi(3.14159265359);        
+  SPoint3 Para_Norm;
+  SPoint2 Para_Wt;
+  bool resizeFlag;
+  
+  std::string line;
+  int DataId = 0;
+  while(std::getline(file, line)) {
+    if(line.empty()) continue;
+    std::istringstream stream(line);
+    std::string value;
+    std::vector<std::string> row;
+    while (std::getline(stream, value, ',')) {
+      row.push_back(value);  
+    }
+    if (std::isalpha(row[0][0])){
+      DataId +=1;
+      if(DataId == 4){      
+        _NLeaf = static_cast<int>(_LevelNode[_TotalLevel].size());
+        _N_Node = static_cast<int>(_Parent.size());
+        _NInterface = _N_Node - _NLeaf;
+        resizeFlag = _ParaAngle.resize(_NInterface,2,true); 
+      } 
+    }
+    else{      
+      if(DataId == 1){                            // read the tree structure------------------
+        _TotalLevel = std::stoi(row[0]); 
+        for(int i=0; i<=_TotalLevel; i++){
+          std::vector<int> LN;
+          _LevelNode.push_back(LN);
+        }
+      }  
+      else if(DataId == 2){ 
+        level_value = std::stoi(row[0]);
+        node_value = std::stoi(row[1]);
+        parent_value = std::stoi(row[2]);
+        _Mat_Id.push_back(std::stoi(row[3]));
+                
+        _LevelNode[level_value].push_back(node_value);
+        _NodeLevel.push_back(level_value);
+        _Parent.push_back(parent_value);
+                
+        if(level_value < _TotalLevel){
+          std::vector<int> ch;
+          _Child.push_back(ch);
+        }  
+        if(parent_value != node_value) _Child[parent_value].push_back(node_value);
+      }  
+      else if(DataId == 3){               // read the DMN Parameter  -----------------------
+        _Dim = std::stoi(row[0]);
+        _Vf = std::stod(row[1]);        
+      }    
+      else if(DataId == 4){
+        if(_Dim==2){
+          ParaN[0] = std::stod(row[0]);           
+          ParaN[1] = 0.0;
+        }
+        else if(_Dim==3){
+          ParaN[0] = std::stod(row[0]);           
+          ParaN[1] = std::stod(row[1]);         
+        }          
+        sin0 = sin(2.0*Pi*ParaN[0]);
+        cos0 = cos(2.0*Pi*ParaN[0]);
+        sin1 = sin(Pi*ParaN[1]);
+        cos1 = cos(Pi*ParaN[1]);
+        Para_Norm[0] = cos1*sin0;
+        Para_Norm[1] = cos1*cos0;
+        Para_Norm[2] = sin1;
+        _Para_Norm.push_back(Para_Norm); 
+        _ParaAngle(pn,0) =  ParaN[0];
+        _ParaAngle(pn,1) =  ParaN[1]; 
+        pn +=1;
+      }  
+      else if(DataId == 5){
+        Para_Wt[0] = std::stod(row[0]);
+        Para_Wt[1] = std::stod(row[1]);
+        _Para_Wt.push_back(Para_Wt);
+      }
+    }
+  }      
+    
+  int row = _col_Di*_NLeaf;
+  int col = _row_Di*_NInterface;
+  resizeFlag = _Nv.resize(row, col, true);
+  resizeFlag = _I.resize(row, _col_Di, true);
+
+  row = _col_Di*(_N_Node-1);
+  col = _col_Di*_NLeaf;
+  resizeFlag = _V.resize(row, col, true);
+        
+  row = _row_Di*_NInterface;  
+  resizeFlag = _NT.resize(row, _col_Di*(_N_Node-1), true);         
+  resizeFlag = _NTV.resize(row, col, true);     
+           
+  resizeFlag = _C.resize(col, col,true);
+  resizeFlag = Jacobian.resize(row, row,true); 
+  _NPara_Norm = _NInterface; 
+  _NPara_Wt = static_cast<int>(_Para_Wt.size()); 
+  
+  Msg::Info("Finish reading Tree Data and parameter file, level = %d, Dim = %d, NLeaf = %d", _TotalLevel, _Dim, _NLeaf);
+}  
+
 void StochTMDMNDG3DMaterialLaw::reset_Parameter(std::vector<std::vector<double>>& Para_Norm, std::vector<std::vector<double>>& Para_Wt, std::vector<double>& Para_Alpha, const double Vf){
     
   double sin0, cos0, sin1,cos1; 
   double Pi(3.14159265359);
-  if(_Dim==2){
-    sin1 = 0.0;
-    cos1 = 1.0;
-    for(int i=0;i<_NInterface;i++){          
-      sin0 = sin(2.0*Pi*Para_Norm[i][0]);
-      cos0 = cos(2.0*Pi*Para_Norm[i][0]);
-      _Para_Norm[i][0] = cos1*sin0;
-      _Para_Norm[i][1] = cos1*cos0;
-      _Para_Norm[i][2] = sin1;
+  for(int i=0;i<_NInterface;i++){ 
+    if(_Dim==2){
+      sin1 = 0.0;
+      cos1 = 1.0;
       _ParaAngle(i,0) =  Para_Norm[i][0];
-    }  
-  }
-  else if(_Dim==3){          
-    for(int i=0;i<_NInterface;i++){          
-      sin0 = sin(2.0*Pi*Para_Norm[i][0]);
-      cos0 = cos(2.0*Pi*Para_Norm[i][0]);
+    }
+    else if(_Dim==3){
       sin1 = sin(Pi*Para_Norm[i][1]);
-      cos1 = cos(Pi*Para_Norm[i][1]);
-      _Para_Norm[i][0] = cos1*sin0;
-      _Para_Norm[i][1] = cos1*cos0;
-      _Para_Norm[i][2] = sin1;
+      cos1 = cos(Pi*Para_Norm[i][1]); 
       _ParaAngle(i,0) =  Para_Norm[i][0];
       _ParaAngle(i,1) =  Para_Norm[i][1]; 
     }  
-  }       
-        
-  if(_porous){
-    _NPara_Wt = _NInterface;
-  }  
-  else{  
-    _NPara_Wt = int(pow(2,(_TotalLevel-1)))-1;
-  }
+    sin0 = sin(2.0*Pi*Para_Norm[i][0]);
+    cos0 = cos(2.0*Pi*Para_Norm[i][0]);
+    _Para_Norm[i][0] = cos1*sin0;
+    _Para_Norm[i][1] = cos1*cos0;
+    _Para_Norm[i][2] = sin1; 
+  }      
+       
   for(int i=0;i<_NPara_Wt;i++){          
     _Para_Wt[i][0] = Para_Wt[i][0]; 
     _Para_Wt[i][1] = Para_Wt[i][1]; 
+    if(_NodeLevel[_Child[i][1]]==_TotalLevel) _Para_Wt[i][1] = 1.0; 
   }      
   for(int i=0;i<Para_Alpha.size();i++){          
     _Para_Alpha[i] = _Para_Alpha[i]; 
@@ -5419,7 +5536,17 @@ void StochTMDMNDG3DMaterialLaw::reset_Parameter(const char* Para){
   _Para_Norm.clear();
   _Para_Wt.clear();
   _Para_Alpha.clear();
-  StochTMDMNDG3DMaterialLaw::read_parameter(Para);
+  _LevelNode.clear(); 
+  _NodeLevel.clear();    
+  _Mat_Id.clear();
+  _Parent.clear();      
+  _Child.clear();
+  if(_ReadTree){
+    StochTMDMNDG3DMaterialLaw::read_TreeData(Para);
+  }
+  else{
+    StochTMDMNDG3DMaterialLaw::read_parameter(Para);
+  } 
   StochTMDMNDG3DMaterialLaw::fill_Matrices();
 }
 
@@ -5466,21 +5593,20 @@ void StochTMDMNDG3DMaterialLaw::stress(IPVariable*ipv, const IPVariable*ipvprev,
   fullVector<double>& thermSrcvec = ipvcur->getRefToThermalSourceVect();
   fullVector<double>& mechSrcvec = ipvcur->getRefToMechSourceVect();
   fullVector<double> dwdtvec, dmechSrcdTvec, dwdFvec, dmechSrcdFvec;
-  dwdtvec.resize(_NRoot); dmechSrcdTvec.resize(_NRoot);
-  dwdFvec.resize(9*_NRoot); dmechSrcdFvec.resize(9*_NRoot); 
+  dwdtvec.resize(_NLeaf); dmechSrcdTvec.resize(_NLeaf);
+  dwdFvec.resize(9*_NLeaf); dmechSrcdFvec.resize(9*_NLeaf); 
 
   PQvec.setAll(0.0); Cpvec.setAll(0.0); thermSrcvec.setAll(0.0); mechSrcvec.setAll(0.0); 
-  static fullVector<double> Res_node_t(_row_Di*_NInterface);
+
   static fullVector<double> Res_node(_row_Di*_NInterface);
   static fullVector<double> ab_step(_row_Di*_NInterface);
-  static fullMatrix<double> NTVC(_row_Di*_NInterface, _col_Di*_NRoot);
+  static fullMatrix<double> NTVC(_row_Di*_NInterface, _col_Di*_NLeaf);
   static fullMatrix<double> Jacobian_inv(_row_Di*_NInterface, _row_Di*_NInterface); 
   static fullMatrix<double> Modify_Jacobian(_row_Di*_NInterface, _row_Di*_NInterface); 
-  static fullMatrix<double> tmp(_col_Di*_NRoot, _col_Di); 
+  static fullMatrix<double> tmp(_col_Di*_NLeaf, _col_Di); 
   static fullMatrix<double> dRdF(_row_Di*_NInterface, _col_Di); 
   static fullMatrix<double> dadF(_row_Di*_NInterface, _col_Di); 
     
-  Res_node_t.setAll(0.0);
   Res_node.setAll(0.0);
   ab_step.setAll(0.0);
   _C.setAll(0.0);
@@ -5491,17 +5617,15 @@ void StochTMDMNDG3DMaterialLaw::stress(IPVariable*ipv, const IPVariable*ipvprev,
   tmp.setAll(0.0);
   int ite = 0;
   double r = 1.0;
-  bool last = false;
-  int pos_start = _N_Node-_NRoot;
+  int pos_start = _NInterface;
   int max_iter= 15;
   bool stiff_loc = true;
 
 
-  while( (r>_tol and ite < max_iter) or last){
-  //  if((1+ite)%5 == 0) stiff_loc=false;
+  while(r>_tol and ite < max_iter){
     ite +=1;
     _Nv.mult(ab_cur, FHvec);
-    for(int i=0; i<_NRoot; i++){
+    for(int i=0; i<_NLeaf; i++){
       if (_VA[pos_start+i] > 1.e-6){
         ThermoMechanicsDG3DIPVariableBase* ipv_i = dynamic_cast<ThermoMechanicsDG3DIPVariableBase*>(ipvcur->getIPv(i));
         const ThermoMechanicsDG3DIPVariableBase* ipvprev_i = dynamic_cast<const ThermoMechanicsDG3DIPVariableBase*>(ipv_prev->getIPv(i));
@@ -5541,15 +5665,7 @@ void StochTMDMNDG3DMaterialLaw::stress(IPVariable*ipv, const IPVariable*ipvprev,
           Msg::Error("This combination of flags doesn't exist. Redefine in the constructor.");
         }
 
-        int mat_IP = 0;
-        if(_Modified_DMN){
-          if(i%3 == 1) mat_IP = 1; // CHECK THIS FLAG
-        }
-        else{
-           mat_IP = i%2;
-        }
-
-        if(_porous) mat_IP=0;
+        int mat_IP = _Mat_Id[_NInterface + i];
         _mapLaw[mat_IP]->stress(ipv_i, ipvprev_i, stiff_loc, checkfrac, dTangent);
         const STensor3& P_i        = ipv_i->getConstRefToFirstPiolaKirchhoffStress();
         const SVector3& Q_i        = ipv_i->getConstRefToThermalFlux();
@@ -5652,58 +5768,19 @@ void StochTMDMNDG3DMaterialLaw::stress(IPVariable*ipv, const IPVariable*ipvprev,
 
     _NTV.mult(PQvec, Res_node);
     r = Res_node.norm()/_NInterface;
+        
+    _NTV.mult(_C, NTVC);
+    NTVC.mult(_Nv, Jacobian);
+    Jacobian.invertInPlace();
 
-    if(r<_tol){
-      if(last or stiff_loc){
-        _NTV.mult(_C, NTVC);
-        NTVC.mult(_Nv, Jacobian);
-        Jacobian.invertInPlace();
-        break;
-      }
-      else{
-        last = true;
-        stiff_loc = true;
-      }  
-    }       
-    else{         
-      if(stiff_loc){         
-        _NTV.mult(_C, NTVC);
-        NTVC.mult(_Nv, Jacobian);
-        Jacobian.invertInPlace();
-      }
-      else{
-        // Updating Jacobian
-        _NTV.mult(PQvec, Res_node);
-        Res_node_t.scale(-1.0);
-        Res_node_t.axpy(Res_node, 1.0);
-
-        double Rho = 1.0/(Res_node_t*ab_step);
-        Modify_Jacobian.setAll(0.0);
-        for(int i =0; i<3*_NInterface; i++){
-          Modify_Jacobian(i,i) = 1.0;
-          for(int j =0; j<3*_NInterface; j++){
-            Modify_Jacobian(i,j) -= ab_step(i)*Res_node_t(j)*Rho;
-          }
-        }
-        Modify_Jacobian.mult(Jacobian,Jacobian_inv);
-        Modify_Jacobian.transposeInPlace();
-        Jacobian_inv.mult(Modify_Jacobian,Jacobian);
-
-        for(int i =0; i<3*_NInterface; i++){
-          for(int j =0; j<3*_NInterface; j++){
-            Jacobian(i,j) += ab_step(i)*ab_step(j)*Rho;
-          }
-        }
-        stiff_loc = true;
-      }
-
-      Res_node_t = Res_node;
-      Jacobian.mult(Res_node, ab_step);
-      ab_step.scale(-1.0);
-      ab_cur.axpy(ab_step, 1.0);
-    }
+    Jacobian.mult(Res_node, ab_step);
+    ab_step.scale(-1.0);
+    ab_cur.axpy(ab_step, 1.0);
   }
+
   Jacobian.scale(-1.0);
+  int pos0 = _Child[0][0];
+  int pos1 = _Child[0][1];  
 
   if(r>_tol){
     Msg::Error("TMDMN residual (= %lf) didn't converge to tolenerce after %d iteration",r,ite);
@@ -5712,14 +5789,14 @@ void StochTMDMNDG3DMaterialLaw::stress(IPVariable*ipv, const IPVariable*ipvprev,
   else{
     for(int m=0;m<_col_Di;m++){
       PQ_hom[m] = 0.0;
-      for(int i=0;i<_NRoot;i++){
-        PQ_hom[m] += (_VA[1]*_V(m, _col_Di*i+m) + _VA[2]*_V(_col_Di+m, _col_Di*i+m))*PQvec(_col_Di*i+m); // Stress average
+      for(int i=0;i<_NLeaf;i++){
+        PQ_hom[m] += (_VA[pos0]*_V((pos0-1)*_col_Di+m, _col_Di*i+m) + _VA[pos1]*_V((pos1-1)*_col_Di+m, _col_Di*i+m))*PQvec(_col_Di*i+m); // Stress average
       }
     }
     
     double temp = 0.;
-    for(int i=0;i<_NRoot;i++){
-      temp = (_VA[1]*_V(0, _col_Di*i) + _VA[2]*_V(_col_Di, _col_Di*i));
+    for(int i=0;i<_NLeaf;i++){
+      temp = (_VA[pos0]*_V(0, _col_Di*i) + _VA[pos1]*_V(_col_Di, _col_Di*i));
       Cp_hom +=  temp*Cpvec(i); // Cp average
       thermSrc_hom += temp*thermSrcvec(i); // w average
       mechSource_hom += temp*mechSrcvec(i); // mechSrc average
@@ -5754,26 +5831,26 @@ void StochTMDMNDG3DMaterialLaw::stress(IPVariable*ipv, const IPVariable*ipvprev,
     }
 
     if(stiff){
-      // All derivatives must be complete
+
       NTVC.mult(_I, dRdF);
       Jacobian.mult(dRdF, dadF);
       _Nv.mult(dadF, tmp);
-      tmp.add(_I); // Check this structure of _I. tmp = dFidF
+      tmp.add(_I);
 
       for(int m=0;m<_col_Di;m++){
         for(int n=0;n<_col_Di;n++){
           C_hom[m][n] = 0.0;
-          for(int i=0;i<_NRoot;i++){
-            for(int j=0;j< _col_Di*_NRoot;j++){
-              C_hom[m][n] += (_VA[1]*_V(m,m+_col_Di*i) + _VA[2]*_V(_col_Di+m,m+_col_Di*i))*_C(m+_col_Di*i,j)*tmp(j,n); 
+          for(int i=0;i<_NLeaf;i++){
+            for(int j=0;j< _col_Di*_NLeaf;j++){
+              C_hom[m][n] += (_VA[pos0]*_V((pos0-1)*_col_Di+m,m+_col_Di*i) + _VA[pos1]*_V((pos1-1)*_col_Di+m,m+_col_Di*i))*_C(m+_col_Di*i,j)*tmp(j,n); 
             }
           }
         }
       }
 
       double temp(0.), dTidT(1.); // = Cp_hom/(temp*Cpvec(i))
-      for(int i=0;i<_NRoot;i++){
-        temp = (_VA[1]*_V(0, _col_Di*i) + _VA[2]*_V(_col_Di, _col_Di*i));
+      for(int i=0;i<_NLeaf;i++){
+        temp = (_VA[pos0]*_V(0, _col_Di*i) + _VA[pos1]*_V(_col_Di, _col_Di*i));
         dwdt_hom += temp*dwdtvec(i)*dTidT; // dwdT average
         dmechSourcedt_hom += temp*dmechSrcdTvec(i)*dTidT; // dmechSourcedt average
         for(int m=0;m<9;m++)
diff --git a/dG3D/src/dG3DMaterialLaw.h b/dG3D/src/dG3DMaterialLaw.h
index 765ee706e..4b894a5f0 100644
--- a/dG3D/src/dG3DMaterialLaw.h
+++ b/dG3D/src/dG3DMaterialLaw.h
@@ -784,6 +784,7 @@ class StochTMDMNDG3DMaterialLaw : public StochDMNDG3DMaterialLaw{
     std::vector<double> _Para_Alpha; // vector of coefficients 
     void fill_Matrices();
     void read_parameter(const char *ParaFile);
+    void read_TreeData(const char *TreeFile);
     void fill_NLocal(const int pos,  std::vector<std::vector<double>> N) const;
     #endif //SWIG
   public:
-- 
GitLab


From b4370c60920ee26e7c2e3d1d94e74cc1487d1943 Mon Sep 17 00:00:00 2001
From: FLE_Knight <ujwalkishore.jinaga@uliege.be>
Date: Wed, 12 Mar 2025 19:35:47 +0100
Subject: [PATCH 16/19] [NEW FIX 4] Minor changes to TMDMN - Fixed some vector
 incompatibility

---
 dG3D/src/dG3DIPVariable.h    |   3 -
 dG3D/src/dG3DMaterialLaw.cpp | 119 ++++++++++++++++++-----------------
 dG3D/src/dG3DMaterialLaw.h   |  19 +++---
 3 files changed, 70 insertions(+), 71 deletions(-)

diff --git a/dG3D/src/dG3DIPVariable.h b/dG3D/src/dG3DIPVariable.h
index 8b9cb8d45..2c99b0a97 100644
--- a/dG3D/src/dG3DIPVariable.h
+++ b/dG3D/src/dG3DIPVariable.h
@@ -5735,7 +5735,6 @@ public:
 
 // Take Care here, nonlocal variables cannot be directly defined with the ThermoMechanicsDG3DIPVariable Base Class (This is a pure virtual base class).
 
-// class NonLinearTVMDG3DIPVariable : public dG3DIPVariable{
 class NonLinearTVMDG3DIPVariable : public ThermoMechanicsDG3DIPVariableBase{   // Changed
 
   protected:
@@ -5743,8 +5742,6 @@ class NonLinearTVMDG3DIPVariable : public ThermoMechanicsDG3DIPVariableBase{   /
     NonLinearTVMDG3DIPVariable(const bool createBodyForceHO, const bool oninter):ThermoMechanicsDG3DIPVariableBase(createBodyForceHO, oninter) {Msg::Error("NonLinearTVMDG3DIPVariable: Cannot use the default constructor of ThermoMechanicsDG3DIPVariableBase");}
 
   public:
-// Constructor Changed
-  //  NonLinearTVMDG3DIPVariable(const mlawNonLinearTVM& viscoLaw, const bool oninter=false, int nbExtraDof=0);  // ?? - WHAT to add/change?
     NonLinearTVMDG3DIPVariable(const mlawNonLinearTVM& viscoLaw, double Tinitial, const bool createBodyForceHO, const bool oninter);  // Changed
     NonLinearTVMDG3DIPVariable(const NonLinearTVMDG3DIPVariable& src);
     virtual NonLinearTVMDG3DIPVariable& operator = (const IPVariable& src);
diff --git a/dG3D/src/dG3DMaterialLaw.cpp b/dG3D/src/dG3DMaterialLaw.cpp
index 10142396d..cee846a1a 100644
--- a/dG3D/src/dG3DMaterialLaw.cpp
+++ b/dG3D/src/dG3DMaterialLaw.cpp
@@ -3633,21 +3633,25 @@ double torchANNBasedDG3DMaterialLaw::soundSpeed() const
 
 
 
-StochDMNDG3DMaterialLaw::StochDMNDG3DMaterialLaw(const int num, const double rho, const double E,const double nu, const char *ParaFile, const bool ReadTree, const bool porous,const double tol):
-  dG3DMaterialLaw(num,rho,false), _ReadTree(ReadTree), _porous(porous),_tol(tol){
-  if(_ReadTree){
-    read_TreeData(ParaFile);
-  }
-  else{
-    read_parameter(ParaFile);
-  }  
-  fill_Matrices();         
+StochDMNDG3DMaterialLaw::StochDMNDG3DMaterialLaw(const int num, const double rho, const double E,const double nu, const char *ParaFile, const bool ReadTree, const bool porous,const double tol, const bool flag_isothermal):
+  dG3DMaterialLaw(num,rho,false), _ReadTree(ReadTree), _porous(porous),_tol(tol), _flag_isothermal(flag_isothermal){
+  
+  if(_flag_isothermal){
+    if(_ReadTree){
+      read_TreeData(ParaFile);
+    }
+    else{
+      read_parameter(ParaFile);
+    }  
+    fill_Matrices();        
+  } 
 }
 
 StochDMNDG3DMaterialLaw::StochDMNDG3DMaterialLaw(const StochDMNDG3DMaterialLaw &src): dG3DMaterialLaw(src), _ReadTree(src._ReadTree), _porous(src._porous), 
     _LevelNode(src._LevelNode), _NodeLevel(src._NodeLevel), _Mat_Id(src._Mat_Id), _Parent(src._Parent), _Child(src._Child), _TotalLevel(src._TotalLevel), _NLeaf(src._NLeaf),
        _NInterface(src._NInterface), _N_Node(src._N_Node), _NPara_Wt(src._NPara_Wt), _NPara_Norm(src._NPara_Norm), _Dim(src._Dim), _Vf(src._Vf), _tol(src._tol),
-       _Nv(src._Nv), _NTV(src._NTV), _V(src._V), _Para_Wt(src._Para_Wt), _Para_Norm(src._Para_Norm), _VA(src._VA), _VI(src._VI), _mapLaw(src._mapLaw){ }
+       _Nv(src._Nv), _NTV(src._NTV), _V(src._V), _Para_Wt(src._Para_Wt), _Para_Norm(src._Para_Norm), _VA(src._VA), _VI(src._VI), _mapLaw(src._mapLaw),
+       _flag_isothermal(src._flag_isothermal){ }
 
 StochDMNDG3DMaterialLaw::~StochDMNDG3DMaterialLaw(){};
 
@@ -4120,7 +4124,7 @@ void StochDMNDG3DMaterialLaw::read_parameter(const char *ParaFile){
     }  
   }
    
-  Msg::Info("Finish reading parameter filefor Complete Binary Tree,  level = %d, Dim = %d, NLeaf = %d", _TotalLevel, _Dim, _NLeaf);
+  Msg::Info("Finish reading parameter file for Complete Binary Tree,  level = %d, Dim = %d, NLeaf = %d", _TotalLevel, _Dim, _NLeaf);
 }
    // end of read_parameter 
  
@@ -5001,7 +5005,7 @@ void StochDMNDG3DMaterialLaw::setTime(const double t,const double dtime){
 // FLE
 StochTMDMNDG3DMaterialLaw::StochTMDMNDG3DMaterialLaw(const int num, const double rho, const double E,const double nu, const char *ParaFile, const bool ReadTree,
       const bool porous, const bool flag_isothermal, const bool flag_microTempFixed, const double tol):
-      StochDMNDG3DMaterialLaw(num,rho,E,nu,ParaFile,ReadTree,porous,tol),_flag_isothermal(flag_isothermal),_flag_microTempFixed(flag_microTempFixed){
+      StochDMNDG3DMaterialLaw(num,rho,E,nu,ParaFile,ReadTree,porous,tol,flag_isothermal),_flag_microTempFixed(flag_microTempFixed){
   
   // Meanings of _col_Di and _row_Di are interchanged in this class.
   if (_flag_isothermal && _flag_microTempFixed){
@@ -5027,7 +5031,7 @@ StochTMDMNDG3DMaterialLaw::StochTMDMNDG3DMaterialLaw(const int num, const double
 }
 
 StochTMDMNDG3DMaterialLaw::StochTMDMNDG3DMaterialLaw(const StochTMDMNDG3DMaterialLaw &source): StochDMNDG3DMaterialLaw(source), 
-    _col_Di(source._col_Di), _row_Di(source._row_Di), _flag_isothermal(source._flag_isothermal), _flag_microTempFixed(source._flag_microTempFixed), _Para_Alpha(source._Para_Alpha){};
+    _col_Di(source._col_Di), _row_Di(source._row_Di), _flag_microTempFixed(source._flag_microTempFixed), _Para_Alpha(source._Para_Alpha){};
 
 StochTMDMNDG3DMaterialLaw::~StochTMDMNDG3DMaterialLaw(){};
 
@@ -5111,7 +5115,7 @@ void StochTMDMNDG3DMaterialLaw::setMacroSolver(const nonLinearMechSolver* sv){
     }
 }
 
-void StochTMDMNDG3DMaterialLaw::fill_NLocal(const int pos, std::vector<std::vector<double>> N)const{
+void StochTMDMNDG3DMaterialLaw::fill_NLocal(const int pos, fullMatrix<double> N)const{
 
   // code to fill a matrix related to local normals
 
@@ -5120,31 +5124,22 @@ void StochTMDMNDG3DMaterialLaw::fill_NLocal(const int pos, std::vector<std::vect
   double n2 = _Para_Norm[pos][2];
 
   if (_flag_isothermal && _flag_microTempFixed){
-    N.resize(_col_Di);
-    for(auto& row : N)
-      row.resize(_row_Di,0.);
-    N[0][0] = n0; N[1][1] = n0; N[2][2] = n0;
-    N[3][0] = n1; N[4][1] = n1; N[5][2] = n1;
-    N[6][0] = n2; N[7][1] = n2; N[8][2] = n2;
+    N.set(0,0,n0); N.set(1,1,n0); N.set(2,2,n0);
+    N.set(3,0,n1); N.set(4,1,n1); N.set(5,2,n1);
+    N.set(6,0,n2); N.set(7,1,n2); N.set(8,2,n2);
   }
   else if(!_flag_isothermal && _flag_microTempFixed){
-    N.resize(_col_Di);
-    for(auto& row : N)
-      row.resize(_row_Di,0.);
-    N[0][0] = n0; N[1][1] = n0; N[2][2] = n0;
-    N[3][0] = n1; N[4][1] = n1; N[5][2] = n1;
-    N[6][0] = n2; N[7][1] = n2; N[8][2] = n2;
-    N[9][3] = n0; N[10][3] = n1; N[11][3] = n2;
+    N.set(0,0,n0); N.set(1,1,n0); N.set(2,2,n0);
+    N.set(3,0,n1); N.set(4,1,n1); N.set(5,2,n1);
+    N.set(6,0,n2); N.set(7,1,n2); N.set(8,2,n2);
+    N.set(9,3,n0); N.set(10,3,n1); N.set(11,3,n2);
   }
   else if(!_flag_isothermal && !_flag_microTempFixed){
-    N.resize(_col_Di);
-    for(auto& row : N)
-      row.resize(_row_Di,0.);
-    N[0][0] = n0; N[1][1] = n0; N[2][2] = n0;
-    N[3][0] = n1; N[4][1] = n1; N[5][2] = n1;
-    N[6][0] = n2; N[7][1] = n2; N[8][2] = n2;
-    N[9][3] = n0; N[10][3] = n1; N[11][3] = n2;
-    N[12][4] = 1.;
+    N.set(0,0,n0); N.set(1,1,n0); N.set(2,2,n0);
+    N.set(3,0,n1); N.set(4,1,n1); N.set(5,2,n1);
+    N.set(6,0,n2); N.set(7,1,n2); N.set(8,2,n2);
+    N.set(9,3,n0); N.set(10,3,n1); N.set(11,3,n2);
+    N.set(12,4,1.);
   }
   else{
     Msg::Error("This combination of flags doesn't exist. Redefine in the constructor.");
@@ -5158,16 +5153,14 @@ void StochTMDMNDG3DMaterialLaw::initLaws(const std::map<int,materialLaw*> &mapla
 // fill the matrices which keep the topological information
 void StochTMDMNDG3DMaterialLaw::fill_Matrices(){  
 
-  std::vector<std::vector<double>> Norm;   // double Norm[9][3];
+  fullMatrix<double> Norm; bool resizeFlag = Norm.resize(_col_Di, _row_Di, true);
   double W_WI[2][2];
   int pos0, pos1;
   int L_ch0, L_ch1;
   int node_start0, node_end0, node_start1, node_end1;
   int Col_start, Col_start0, Col_start1, Row_start, Row_start0, Row_start1;
   double tmp;
-
-  // set the size of rows and cols in Di matrix
-  int col = _col_Di; // = 9, 12;
+  int col = _col_Di; // = 9, 12;   // set the size of rows and cols in Di matrix
   
   _VA.resize(_N_Node,0.0); // Vector for position of nodes for Stress
   _VA[0] = 1.0;
@@ -5177,7 +5170,7 @@ void StochTMDMNDG3DMaterialLaw::fill_Matrices(){
 
   for(int pos=0; pos <_NInterface; pos++){
     l = _NodeLevel[pos];
-    fill_NLocal(pos,Norm);  // size of Norm depends on the flags set inside this function
+    StochTMDMNDG3DMaterialLaw::fill_NLocal(pos,Norm);  // size of Norm depends on the flags set inside this function
     pos0 = _Child[pos][0];
     pos1 = _Child[pos][1];
     L_ch0 = _NodeLevel[pos0];
@@ -5188,11 +5181,12 @@ void StochTMDMNDG3DMaterialLaw::fill_Matrices(){
 
     double S_ba = 1.0;
     if(l ==_TotalLevel-1 and _porous) S_ba = _Para_Wt[pos][1];
+
     // information of interface norm
     for(int nc=0; nc<col;nc++){
       for(int nr=0; nr<_row_Di; nr++){
-        _NT.set(Row_start+nr, Col_start0+nc, Norm[nc][nr]);
-        _NT.set(Row_start+nr, Col_start1+nc,-S_ba*Norm[nc][nr]);
+        _NT.set(Row_start+nr, Col_start0+nc, Norm(nc,nr));
+        _NT.set(Row_start+nr, Col_start1+nc,-S_ba*Norm(nc,nr));
       }
     }
 
@@ -5222,7 +5216,7 @@ void StochTMDMNDG3DMaterialLaw::fill_Matrices(){
       Row_start0 = (r-_NInterface)*col;
       for(int nr=0; nr<col;nr++){
         for(int nc=0; nc<_row_Di;nc++){
-          _Nv.set(Row_start0+nr, Col_start+nc, Norm[nr][nc]/_VA[pos0]);
+          _Nv.set(Row_start0+nr, Col_start+nc, Norm(nr,nc)/_VA[pos0]);
         }
       }
     }
@@ -5230,7 +5224,7 @@ void StochTMDMNDG3DMaterialLaw::fill_Matrices(){
       Row_start1 = (r-_NInterface)*col;
       for(int nr=0; nr<col;nr++){
         for(int nc=0; nc<_row_Di;nc++){
-          _Nv.set(Row_start1+nr, Col_start+nc,-S_ba*Norm[nr][nc]/_VA[pos1]);
+          _Nv.set(Row_start1+nr, Col_start+nc,-S_ba*Norm(nr,nc)/_VA[pos1]);
         }
       }
     }         
@@ -5314,16 +5308,16 @@ void StochTMDMNDG3DMaterialLaw::read_parameter(const char *ParaFile){
       else if(_Dim==3){
         okf = fscanf(Para, "%lf %lf\n", &ParaN[0],  &ParaN[1]);
       }
-        sin0 = sin(2.0*Pi*ParaN[0]);
-        cos0 = cos(2.0*Pi*ParaN[0]);
-        sin1 = sin(Pi*ParaN[1]);
-        cos1 = cos(Pi*ParaN[1]);
-        Para_Norm[0] = cos1*sin0;
-        Para_Norm[1] = cos1*cos0;
-        Para_Norm[2] = sin1;
-        _Para_Norm.push_back(Para_Norm); 
-        _ParaAngle(i,0) =  ParaN[0];
-        _ParaAngle(i,1) =  ParaN[1]; 
+      sin0 = sin(2.0*Pi*ParaN[0]);
+      cos0 = cos(2.0*Pi*ParaN[0]);
+      sin1 = sin(Pi*ParaN[1]);
+      cos1 = cos(Pi*ParaN[1]);
+      Para_Norm[0] = cos1*sin0;
+      Para_Norm[1] = cos1*cos0;
+      Para_Norm[2] = sin1;
+      _Para_Norm.push_back(Para_Norm); 
+      _ParaAngle(i,0) =  ParaN[0];
+      _ParaAngle(i,1) =  ParaN[1]; 
     }       
         
     if(_porous){
@@ -5366,7 +5360,7 @@ void StochTMDMNDG3DMaterialLaw::read_parameter(const char *ParaFile){
     }  
   }
 
-  Msg::Info("Finish reading parameter filefor Complete Binary Tree,  level = %d, Dim = %d, NLeaf = %d", _TotalLevel, _Dim, _NLeaf);
+  Msg::Info("Finished reading parameter file for Complete Binary Tree,  level = %d, Dim = %d, NLeaf = %d", _TotalLevel, _Dim, _NLeaf);
 }
    // end of read_parameter
 
@@ -5626,10 +5620,15 @@ void StochTMDMNDG3DMaterialLaw::stress(IPVariable*ipv, const IPVariable*ipvprev,
     ite +=1;
     _Nv.mult(ab_cur, FHvec);
     for(int i=0; i<_NLeaf; i++){
+
+      Msg::Error("i is %d", i);
+      
       if (_VA[pos_start+i] > 1.e-6){
         ThermoMechanicsDG3DIPVariableBase* ipv_i = dynamic_cast<ThermoMechanicsDG3DIPVariableBase*>(ipvcur->getIPv(i));
         const ThermoMechanicsDG3DIPVariableBase* ipvprev_i = dynamic_cast<const ThermoMechanicsDG3DIPVariableBase*>(ipv_prev->getIPv(i));
 
+        std::cout << "Object type: " << typeid(*ipv_i).name() << std::endl;
+
         STensor3& Floc = ipv_i->getRefToDeformationGradient();
         SVector3& Hloc = ipv_i->getRefToGradT();
         double& Tloc   = ipv_i->getRefToTemperature();
@@ -5664,9 +5663,10 @@ void StochTMDMNDG3DMaterialLaw::stress(IPVariable*ipv, const IPVariable*ipvprev,
         else{
           Msg::Error("This combination of flags doesn't exist. Redefine in the constructor.");
         }
-
+        
         int mat_IP = _Mat_Id[_NInterface + i];
         _mapLaw[mat_IP]->stress(ipv_i, ipvprev_i, stiff_loc, checkfrac, dTangent);
+
         const STensor3& P_i        = ipv_i->getConstRefToFirstPiolaKirchhoffStress();
         const SVector3& Q_i        = ipv_i->getConstRefToThermalFlux();
         const double& w_i          = ipv_i->getConstRefToThermalSource();
@@ -5715,7 +5715,7 @@ void StochTMDMNDG3DMaterialLaw::stress(IPVariable*ipv, const IPVariable*ipvprev,
           const STensor3& dwdf_i     = ipv_i->getRefTodThermalSourcedF(); STensorOperation::zero(dwdf);
           const double& dmechSourcedt_i = ipv_i->getRefTodMechanicalSourcedField()(0,0);
           const STensor3& dmechSourcedf_i = ipv_i->getRefTodMechanicalSourcedF()[0]; 
-          
+
           if (_flag_isothermal && _flag_microTempFixed){
             dwdtvec(i) = 0.; dmechSrcdTvec(i) = 0.;
             for(int m=0; m<3; m++)
@@ -5761,11 +5761,12 @@ void StochTMDMNDG3DMaterialLaw::stress(IPVariable*ipv, const IPVariable*ipvprev,
             }
           }
 
-
         }
       }
+      // Msg::Error("Sizes of PQVec are %d", PQvec.size());
     }
-
+    // Msg::Error("Sizes of PQVec are %d", PQvec.size());
+    Msg::Error("Sizes of _NTV are %d and %d", _NTV.size1(),_NTV.size2());
     _NTV.mult(PQvec, Res_node);
     r = Res_node.norm()/_NInterface;
         
diff --git a/dG3D/src/dG3DMaterialLaw.h b/dG3D/src/dG3DMaterialLaw.h
index 4b894a5f0..f6b8b4996 100644
--- a/dG3D/src/dG3DMaterialLaw.h
+++ b/dG3D/src/dG3DMaterialLaw.h
@@ -707,7 +707,7 @@ class StochDMNDG3DMaterialLaw : public dG3DMaterialLaw{
     std::vector<int> _Mat_Id;
     std::vector<int> _Parent;       //Parent[Node] = Parent of Node
     std::vector<std::vector<int>> _Child;      // Child[Node][0] = left child ; Child[Node][1] = right child of Node
- 
+  
     
     std::vector<SPoint2> _Para_Wt; // vector of weights
     std::vector<SPoint3> _Para_Norm; // vector of normals
@@ -722,12 +722,14 @@ class StochDMNDG3DMaterialLaw : public dG3DMaterialLaw{
     
     fullMatrix<double> _C;
     fullMatrix<double> Jacobian;
-        
-    void fill_NLocal(const int pos, double N[][3])const;
+    
+    bool _flag_isothermal;
+
+    virtual void fill_NLocal(const int pos, double N[][3])const;
     void fill_W_WI(const int pos,  double W[][2]);
-    void fill_Matrices();
-    void read_parameter(const char *ParaFile);
-    void read_TreeData(const char *TreeFile); 
+    virtual void fill_Matrices();
+    virtual void read_parameter(const char *ParaFile);
+    virtual void read_TreeData(const char *TreeFile); 
     virtual void getLeafOfInterface(const int pos, int &node_start, int &node_end) const;
     virtual void TwoPhasesInteract(const std::vector<STensor43>& C, fullMatrix<double> &mat, const int pos);
     virtual void getdVAdP(std::vector< std::vector <SPoint2> >& dVAdPv) const;
@@ -737,7 +739,7 @@ class StochDMNDG3DMaterialLaw : public dG3DMaterialLaw{
     virtual void get_matrixdNTdPv(std::vector<std::vector<std::vector<std::vector<double>>>>& d_NTdPv) const;
     #endif //SWIG
   public:
-    StochDMNDG3DMaterialLaw(const int num, const double rho, const double E,const double nu, const char *ParaFile, const bool ReadTree=false, const bool porous=false,const double tol=1e-6);
+    StochDMNDG3DMaterialLaw(const int num, const double rho, const double E,const double nu, const char *ParaFile, const bool ReadTree=false, const bool porous=false,const double tol=1e-6,const bool flag_isothermal=true);
     void addLaw(dG3DMaterialLaw* law);
     #ifndef SWIG
     StochDMNDG3DMaterialLaw(const StochDMNDG3DMaterialLaw &source);
@@ -779,13 +781,12 @@ class StochTMDMNDG3DMaterialLaw : public StochDMNDG3DMaterialLaw{
   protected:
     #ifndef SWIG
     int _col_Di, _row_Di;
-    bool _flag_isothermal;
     bool _flag_microTempFixed;
     std::vector<double> _Para_Alpha; // vector of coefficients 
     void fill_Matrices();
     void read_parameter(const char *ParaFile);
     void read_TreeData(const char *TreeFile);
-    void fill_NLocal(const int pos,  std::vector<std::vector<double>> N) const;
+    void fill_NLocal(const int pos, fullMatrix<double> N) const;
     #endif //SWIG
   public:
     StochTMDMNDG3DMaterialLaw(const int num, const double rho, const double E,const double nu, const char *ParaFile, const bool ReadTree=false,
-- 
GitLab


From 9fb414dcc65667999aed036e961af73048ffec0f Mon Sep 17 00:00:00 2001
From: FLE_Knight <ujwalkishore.jinaga@uliege.be>
Date: Thu, 13 Mar 2025 17:38:35 +0100
Subject: [PATCH 17/19] [NEW FEATURE and PATCH] Added rotation matrix
 functionality to StochDMN

---
 NonLinearSolver/materialLaw/mlaw.h |   2 +-
 dG3D/src/dG3DIPVariable.cpp        |  11 ++-
 dG3D/src/dG3DIPVariable.h          |   4 +
 dG3D/src/dG3DMaterialLaw.cpp       | 135 ++++++++++++++++-------------
 dG3D/src/dG3DMaterialLaw.h         |   9 +-
 5 files changed, 95 insertions(+), 66 deletions(-)

diff --git a/NonLinearSolver/materialLaw/mlaw.h b/NonLinearSolver/materialLaw/mlaw.h
index 4329b2659..c9fa30748 100644
--- a/NonLinearSolver/materialLaw/mlaw.h
+++ b/NonLinearSolver/materialLaw/mlaw.h
@@ -33,7 +33,7 @@ class materialLaw{
                  hyperelastic, powerYieldLaw, powerYieldLawWithFailure,nonLocalDamagePowerYieldHyper,
                  localDamagePowerYieldHyperWithFailure,nonLocalDamagePowerYieldHyperWithFailure,ElecSMP,
                  ThermalConducter,AnIsotropicTherMech, localDamageJ2Hyper,linearElastic,nonLocalDamageGursonThermoMechanics,
-                 localDamageJ2SmallStrain,nonLocalDamageJ2SmallStrain,cluster,tfa,ANN, DMN, torchANN, NonlocalDamageTorchANN, StochDMN, LinearElecMagTherMech, LinearElecMagInductor, hyperviscoelastic, GenericResidualStrain,
+                 localDamageJ2SmallStrain,nonLocalDamageJ2SmallStrain,cluster,tfa,ANN, DMN, torchANN, NonlocalDamageTorchANN, StochDMN, StochTMDMN, LinearElecMagTherMech, LinearElecMagInductor, hyperviscoelastic, GenericResidualStrain,
                  GenericThermoMechanics, ElecMagGenericThermoMechanics, ElecMagInductor,
                  nonlineartvm,nonlinearTVE,nonlinearTVP,vevpmfh, VEVPUMAT, IMDEACPUMAT, Hill48,nonlinearTVEnonlinearTVP,nonlinearTVEnonlinearTVP2,
 				 TVEVPwithFailure,nonLocalDamageTVEVP,localDamageTVEVPWithFailure,nonLocalDamageTVEVPWithFailure,
diff --git a/dG3D/src/dG3DIPVariable.cpp b/dG3D/src/dG3DIPVariable.cpp
index 718dc3f54..364670af7 100644
--- a/dG3D/src/dG3DIPVariable.cpp
+++ b/dG3D/src/dG3DIPVariable.cpp
@@ -4054,6 +4054,7 @@ void ThermoMechanicsDG3DIPVariableBase::restart()
 
 StochDMNDG3DIPVariable::StochDMNDG3DIPVariable(const int NRoot,const int NInterface, const bool createBodyForceHO, const bool oninter):
     dG3DIPVariable(createBodyForceHO, oninter), _NRoot(NRoot), _NInterface(NInterface), _IPVector(NRoot,NULL){
+    static STensor3 _I(1.); _R = _I; 
     bool resizeFlag;
     int entryFP = 9*_NRoot;
     int entry_a = 3*_NInterface;
@@ -4063,7 +4064,7 @@ StochDMNDG3DIPVariable::StochDMNDG3DIPVariable(const int NRoot,const int NInterf
  }
 
 StochDMNDG3DIPVariable::StochDMNDG3DIPVariable(const StochDMNDG3DIPVariable& src):
-  dG3DIPVariable(src), _NRoot(src._NRoot), _NInterface(src._NInterface), Fvec(src.Fvec), Pvec(src.Pvec), a(src.a),_IPVector(src._NRoot,NULL){
+  dG3DIPVariable(src), _NRoot(src._NRoot), _NInterface(src._NInterface), Fvec(src.Fvec), Pvec(src.Pvec), a(src.a),_IPVector(src._NRoot,NULL), _R(src._R){
     for (int j=0; j< src._NRoot; j++){
       if (src._IPVector[j] != NULL){
         _IPVector[j] = src._IPVector[j]->clone();
@@ -4083,6 +4084,7 @@ StochDMNDG3DIPVariable& StochDMNDG3DIPVariable::operator =(const IPVariable& src
     Fvec = psrc->Fvec;
     Pvec = psrc->Pvec;
     a = psrc->a;
+    _R = psrc->_R;
     for (int j=0; j< _NRoot; j++)
     {
       if ((_IPVector[j]!=NULL) and (psrc->_IPVector[j] != NULL))
@@ -4143,6 +4145,7 @@ void StochDMNDG3DIPVariable::restart()
   restartManager::restart(Fvec.getDataPtr(),9*_NRoot);
   restartManager::restart(Pvec.getDataPtr(),9*_NRoot);
   restartManager::restart(a.getDataPtr(),3*_NInterface);
+  restartManager::restart(_R);
   restartManager::restart(_IPVector);
   for (int j=0; j< _NRoot; j++){
     _IPVector[j]->restart();
@@ -4281,9 +4284,9 @@ void StochTMDMNDG3DIPVariable::restart()
   restartManager::restart(_NInterface);
   restartManager::restart(_col_Di);
   restartManager::restart(_row_Di);
-  restartManager::restart(FHvec.getDataPtr(),12*_NRoot);
-  restartManager::restart(PQvec.getDataPtr(),12*_NRoot);
-  restartManager::restart(ab.getDataPtr(),4*_NInterface);
+  restartManager::restart(FHvec.getDataPtr(),_col_Di*_NRoot);
+  restartManager::restart(PQvec.getDataPtr(),_col_Di*_NRoot);
+  restartManager::restart(ab.getDataPtr(),_row_Di*_NInterface);
   restartManager::restart(_IPVector);
   for (int j=0; j< _NRoot; j++){
     _IPVector[j]->restart();
diff --git a/dG3D/src/dG3DIPVariable.h b/dG3D/src/dG3DIPVariable.h
index 2c99b0a97..d7a9fa082 100644
--- a/dG3D/src/dG3DIPVariable.h
+++ b/dG3D/src/dG3DIPVariable.h
@@ -3442,6 +3442,7 @@ class StochDMNDG3DIPVariable : public dG3DIPVariable
     fullVector<double> Fvec;
     fullVector<double> Pvec;
     fullVector<double> a;
+    STensor3 _R;
 
  public:
     StochDMNDG3DIPVariable(const int NRoot,const int NInterface, const bool createBodyForceHO, const bool oninter);
@@ -3466,6 +3467,9 @@ class StochDMNDG3DIPVariable : public dG3DIPVariable
     virtual fullVector<double>& getRefToInterfaceFluctuationVect() {return a;};
     virtual const fullVector<double>& getConstRefToInterfaceFluctuationVect() const {return a;};
 
+    virtual STensor3& getReftoRotationMatrix() {return _R;};
+    virtual const STensor3& getConstReftoRotationMatrix() const {return _R;};
+
     virtual IPVariable* getInternalData() {return NULL;};
     virtual const IPVariable* getInternalData()  const {return NULL;};
     virtual IPVariable* clone() const {return new StochDMNDG3DIPVariable(*this);};
diff --git a/dG3D/src/dG3DMaterialLaw.cpp b/dG3D/src/dG3DMaterialLaw.cpp
index cee846a1a..9724b5967 100644
--- a/dG3D/src/dG3DMaterialLaw.cpp
+++ b/dG3D/src/dG3DMaterialLaw.cpp
@@ -3636,6 +3636,8 @@ double torchANNBasedDG3DMaterialLaw::soundSpeed() const
 StochDMNDG3DMaterialLaw::StochDMNDG3DMaterialLaw(const int num, const double rho, const double E,const double nu, const char *ParaFile, const bool ReadTree, const bool porous,const double tol, const bool flag_isothermal):
   dG3DMaterialLaw(num,rho,false), _ReadTree(ReadTree), _porous(porous),_tol(tol), _flag_isothermal(flag_isothermal){
   
+    _alpha = 0.; _beta = 0.; _gamma = 0.; 
+  
   if(_flag_isothermal){
     if(_ReadTree){
       read_TreeData(ParaFile);
@@ -3651,7 +3653,7 @@ StochDMNDG3DMaterialLaw::StochDMNDG3DMaterialLaw(const StochDMNDG3DMaterialLaw &
     _LevelNode(src._LevelNode), _NodeLevel(src._NodeLevel), _Mat_Id(src._Mat_Id), _Parent(src._Parent), _Child(src._Child), _TotalLevel(src._TotalLevel), _NLeaf(src._NLeaf),
        _NInterface(src._NInterface), _N_Node(src._N_Node), _NPara_Wt(src._NPara_Wt), _NPara_Norm(src._NPara_Norm), _Dim(src._Dim), _Vf(src._Vf), _tol(src._tol),
        _Nv(src._Nv), _NTV(src._NTV), _V(src._V), _Para_Wt(src._Para_Wt), _Para_Norm(src._Para_Norm), _VA(src._VA), _VI(src._VI), _mapLaw(src._mapLaw),
-       _flag_isothermal(src._flag_isothermal){ }
+       _flag_isothermal(src._flag_isothermal), _alpha(src._alpha), _beta(src._beta), _gamma(src._gamma){ }
 
 StochDMNDG3DMaterialLaw::~StochDMNDG3DMaterialLaw(){};
 
@@ -5002,6 +5004,32 @@ void StochDMNDG3DMaterialLaw::setTime(const double t,const double dtime){
   }
 }
 
+void StochDMNDG3DMaterialLaw::eulerZXZToRotationMatrix(const double phi, const double theta, const double psi, STensor3& rotationMatrix) {
+  double cosPhi = cos(phi);
+  double sinPhi = sin(phi);
+  double cosTheta = cos(theta);
+  double sinTheta = sin(theta);
+  double cosPsi = cos(psi);
+  double sinPsi = sin(psi);
+
+  rotationMatrix(0,0) = cosPsi * cosPhi - cosTheta * sinPhi * sinPsi;
+  rotationMatrix(0,1) = cosPsi * sinPhi + cosTheta * cosPhi * sinPsi;
+  rotationMatrix(0,2) = sinPsi * sinTheta;
+
+  rotationMatrix(1,0) = -sinPsi * cosPhi - cosTheta * sinPhi * cosPsi;
+  rotationMatrix(1,1) = -sinPsi * sinPhi + cosTheta * cosPhi * cosPsi;
+  rotationMatrix(1,2) = cosPsi * sinTheta;
+
+  rotationMatrix(2,0) = sinTheta * sinPhi;
+  rotationMatrix(2,1) = -sinTheta * cosPhi;
+  rotationMatrix(2,2) = cosTheta;
+}
+
+void StochDMNDG3DMaterialLaw::setZXZRotationMatrix_in_IP(StochDMNDG3DIPVariable* ipv){
+  STensor3& R = ipv->getReftoRotationMatrix();
+  eulerZXZToRotationMatrix(_alpha,_beta,_gamma,R);
+}; 
+
 // FLE
 StochTMDMNDG3DMaterialLaw::StochTMDMNDG3DMaterialLaw(const int num, const double rho, const double E,const double nu, const char *ParaFile, const bool ReadTree,
       const bool porous, const bool flag_isothermal, const bool flag_microTempFixed, const double tol):
@@ -5047,8 +5075,9 @@ void StochTMDMNDG3DMaterialLaw::createIPState(IPStateBase* &ips, bool hasBodyFor
     StochTMDMNDG3DIPVariable* ipvi_Leaf = static_cast<StochTMDMNDG3DIPVariable*>(ipvi);
     StochTMDMNDG3DIPVariable* ipv1_Leaf = static_cast<StochTMDMNDG3DIPVariable*>(ipv1);
     StochTMDMNDG3DIPVariable* ipv2_Leaf = static_cast<StochTMDMNDG3DIPVariable*>(ipv2);
+    int mat_IP;
     for (int i=0; i< _NLeaf; i++){
-      int mat_IP = 0;
+      mat_IP = _Mat_Id[_NInterface + i];
       IPStateBase* ips_i = NULL;
       _mapLaw[mat_IP]->createIPState(ips_i, hasBodyForce, state_, ele, nbFF_, GP, gpt);
       std::vector<IPVariable*> ip_all;
@@ -5572,43 +5601,32 @@ void StochTMDMNDG3DMaterialLaw::stress(IPVariable*ipv, const IPVariable*ipvprev,
   STensor3 dCpdF; STensorOperation::zero(dCpdF);
   STensor33 dPdgradT; STensorOperation::zero(dPdgradT);
 
-
-  double C_hom[_col_Di][_col_Di]; // static // The tangent is combined with thermal tangents.
-  double PQ_hom[_col_Di]; //static
-  double dPQdT_hom[_col_Di]; // static
+  // The tangent C_hom is combined with thermal tangents.
+  static fullMatrix<double> C_hom(_col_Di,_col_Di); if(C_hom.size1()!=_col_Di || C_hom.size2()!=_col_Di){C_hom.resize(_col_Di,_col_Di);}; C_hom.setAll(0.); 
+  static fullVector<double> PQ_hom(_col_Di); if(PQ_hom.size()!=_col_Di){PQ_hom.resize(_col_Di);}; PQ_hom.setAll(0.);
+  static fullVector<double> dPQdT_hom(_col_Di); if(dPQdT_hom.size()!=_col_Di){dPQdT_hom.resize(_col_Di);}; dPQdT_hom.setAll(0.);
   double Cp_hom(0.), thermSrc_hom(0.), mechSource_hom(0.), dwdt_hom(0.), dmechSourcedt_hom(0.);
-  static double dwdf_hom[9], dmechSourcedf_hom[9];
-  // std::vector<double> PQ_hom;
+  static fullVector<double> dwdf_hom(9), dmechSourcedf_hom(9); dwdf_hom.setAll(0.); dmechSourcedf_hom.setAll(0.);
 
   fullVector<double>& FHvec = ipvcur->getRefToCombinedGradientVect();
-  fullVector<double>& PQvec = ipvcur->getRefToCombinedStressVect();
+  fullVector<double>& PQvec = ipvcur->getRefToCombinedStressVect(); PQvec.setAll(0.0);
   fullVector<double>& ab_cur = ipvcur->getRefToCombinedInterfaceFluctuationVect();
-  fullVector<double>& Cpvec = ipvcur->getRefToCpVect();
-  fullVector<double>& thermSrcvec = ipvcur->getRefToThermalSourceVect();
-  fullVector<double>& mechSrcvec = ipvcur->getRefToMechSourceVect();
+  fullVector<double>& Cpvec = ipvcur->getRefToCpVect(); Cpvec.setAll(0.0);
+  fullVector<double>& thermSrcvec = ipvcur->getRefToThermalSourceVect(); thermSrcvec.setAll(0.0);
+  fullVector<double>& mechSrcvec = ipvcur->getRefToMechSourceVect(); mechSrcvec.setAll(0.0); 
   fullVector<double> dwdtvec, dmechSrcdTvec, dwdFvec, dmechSrcdFvec;
-  dwdtvec.resize(_NLeaf); dmechSrcdTvec.resize(_NLeaf);
-  dwdFvec.resize(9*_NLeaf); dmechSrcdFvec.resize(9*_NLeaf); 
-
-  PQvec.setAll(0.0); Cpvec.setAll(0.0); thermSrcvec.setAll(0.0); mechSrcvec.setAll(0.0); 
-
-  static fullVector<double> Res_node(_row_Di*_NInterface);
-  static fullVector<double> ab_step(_row_Di*_NInterface);
-  static fullMatrix<double> NTVC(_row_Di*_NInterface, _col_Di*_NLeaf);
-  static fullMatrix<double> Jacobian_inv(_row_Di*_NInterface, _row_Di*_NInterface); 
-  static fullMatrix<double> Modify_Jacobian(_row_Di*_NInterface, _row_Di*_NInterface); 
-  static fullMatrix<double> tmp(_col_Di*_NLeaf, _col_Di); 
-  static fullMatrix<double> dRdF(_row_Di*_NInterface, _col_Di); 
-  static fullMatrix<double> dadF(_row_Di*_NInterface, _col_Di); 
+  dwdtvec.resize(_NLeaf); dwdtvec.setAll(0.); dmechSrcdTvec.resize(_NLeaf); dmechSrcdTvec.setAll(0.);
+  dwdFvec.resize(9*_NLeaf); dwdFvec.setAll(0.); dmechSrcdFvec.resize(9*_NLeaf); dmechSrcdFvec.setAll(0.);
+
+  static fullVector<double> Res_node(_row_Di*_NInterface); if(Res_node.size()!=_row_Di*_NInterface){Res_node.resize(_row_Di*_NInterface);}; Res_node.setAll(0.);  
+  static fullVector<double> ab_step(_row_Di*_NInterface); if(ab_step.size()!=_row_Di*_NInterface){ab_step.resize(_row_Di*_NInterface);}; ab_step.setAll(0.0);
+  static fullMatrix<double> NTVC(_row_Di*_NInterface, _col_Di*_NLeaf); if(NTVC.size1()!=_row_Di*_NInterface || NTVC.size2()!=_col_Di*_NLeaf){NTVC.resize(_row_Di*_NInterface, _col_Di*_NLeaf);}; NTVC.setAll(0.0); 
+  static fullMatrix<double> Jacobian_inv(_row_Di*_NInterface, _row_Di*_NInterface); if(Jacobian_inv.size1()!=_row_Di*_NInterface || Jacobian_inv.size2()!=_row_Di*_NInterface){Jacobian_inv.resize(_row_Di*_NInterface, _row_Di*_NInterface);}; Jacobian_inv.setAll(0.0); 
+  static fullMatrix<double> tmp(_col_Di*_NLeaf, _col_Di); if(tmp.size1()!=_col_Di*_NLeaf || tmp.size2()!=_col_Di){tmp.resize(_col_Di*_NLeaf, _col_Di);}; tmp.setAll(0.0); 
+  static fullMatrix<double> dRdF(_row_Di*_NInterface, _col_Di); if(dRdF.size1()!=_row_Di*_NInterface || dRdF.size2()!=_col_Di){dRdF.resize(_row_Di*_NInterface, _col_Di);}; dRdF.setAll(0.0);
+  static fullMatrix<double> dadF(_row_Di*_NInterface, _col_Di); if(dadF.size1()!=_row_Di*_NInterface || dadF.size2()!=_col_Di){dadF.resize(_row_Di*_NInterface, _col_Di);}; dadF.setAll(0.0);
     
-  Res_node.setAll(0.0);
-  ab_step.setAll(0.0);
   _C.setAll(0.0);
-  NTVC.setAll(0.0); 
-  Jacobian.setAll(0.0);
-  dRdF.setAll(0.0);
-  dadF.setAll(0.0);
-  tmp.setAll(0.0);
   int ite = 0;
   double r = 1.0;
   int pos_start = _NInterface;
@@ -5626,8 +5644,7 @@ void StochTMDMNDG3DMaterialLaw::stress(IPVariable*ipv, const IPVariable*ipvprev,
       if (_VA[pos_start+i] > 1.e-6){
         ThermoMechanicsDG3DIPVariableBase* ipv_i = dynamic_cast<ThermoMechanicsDG3DIPVariableBase*>(ipvcur->getIPv(i));
         const ThermoMechanicsDG3DIPVariableBase* ipvprev_i = dynamic_cast<const ThermoMechanicsDG3DIPVariableBase*>(ipv_prev->getIPv(i));
-
-        std::cout << "Object type: " << typeid(*ipv_i).name() << std::endl;
+        // std::cout << "Object type: " << typeid(*ipv_i).name() << std::endl;
 
         STensor3& Floc = ipv_i->getRefToDeformationGradient();
         SVector3& Hloc = ipv_i->getRefToGradT();
@@ -5789,9 +5806,9 @@ void StochTMDMNDG3DMaterialLaw::stress(IPVariable*ipv, const IPVariable*ipvprev,
   }
   else{
     for(int m=0;m<_col_Di;m++){
-      PQ_hom[m] = 0.0;
+      PQ_hom(m) = 0.0;
       for(int i=0;i<_NLeaf;i++){
-        PQ_hom[m] += (_VA[pos0]*_V((pos0-1)*_col_Di+m, _col_Di*i+m) + _VA[pos1]*_V((pos1-1)*_col_Di+m, _col_Di*i+m))*PQvec(_col_Di*i+m); // Stress average
+        PQ_hom(m) += (_VA[pos0]*_V((pos0-1)*_col_Di+m, _col_Di*i+m) + _VA[pos1]*_V((pos1-1)*_col_Di+m, _col_Di*i+m))*PQvec(_col_Di*i+m); // Stress average
       }
     }
     
@@ -5808,25 +5825,25 @@ void StochTMDMNDG3DMaterialLaw::stress(IPVariable*ipv, const IPVariable*ipvprev,
       for(int i=0;i<3;i++){
         Q(i) = 0.;
         for(int j=0;j<3;j++){
-          P(i,j) = PQ_hom[i+_row_Di*j];
+          P(i,j) = PQ_hom(i+_row_Di*j);
         }
       }
     }
     else if(!_flag_isothermal && _flag_microTempFixed){
       Cp = Cp_hom; w = thermSrc_hom; mechSource = mechSource_hom; 
       for(int i=0;i<3;i++){
-        Q(i) = PQ_hom[9+i];
+        Q(i) = PQ_hom(9+i);
         for(int j=0;j<3;j++){
-          P(i,j) = PQ_hom[i+3*j]; 
+          P(i,j) = PQ_hom(i+3*j); 
         }
       }
     }
     else if(!_flag_isothermal && !_flag_microTempFixed){
-      Cp = PQ_hom[_col_Di-1]; w = thermSrc_hom; mechSource = mechSource_hom;
+      Cp = PQ_hom(_col_Di-1); w = thermSrc_hom; mechSource = mechSource_hom;
       for(int i=0;i<3;i++){
-        Q(i) = PQ_hom[9+i];
+        Q(i) = PQ_hom(9+i);
         for(int j=0;j<3;j++){
-          P(i,j) = PQ_hom[i+3*j];
+          P(i,j) = PQ_hom(i+3*j);
         }
       }  
     }
@@ -5840,10 +5857,10 @@ void StochTMDMNDG3DMaterialLaw::stress(IPVariable*ipv, const IPVariable*ipvprev,
 
       for(int m=0;m<_col_Di;m++){
         for(int n=0;n<_col_Di;n++){
-          C_hom[m][n] = 0.0;
+          C_hom(m,n) = 0.0;
           for(int i=0;i<_NLeaf;i++){
             for(int j=0;j< _col_Di*_NLeaf;j++){
-              C_hom[m][n] += (_VA[pos0]*_V((pos0-1)*_col_Di+m,m+_col_Di*i) + _VA[pos1]*_V((pos1-1)*_col_Di+m,m+_col_Di*i))*_C(m+_col_Di*i,j)*tmp(j,n); 
+              C_hom(m,n) += (_VA[pos0]*_V((pos0-1)*_col_Di+m,m+_col_Di*i) + _VA[pos1]*_V((pos1-1)*_col_Di+m,m+_col_Di*i))*_C(m+_col_Di*i,j)*tmp(j,n); 
             }
           }
         }
@@ -5856,8 +5873,8 @@ void StochTMDMNDG3DMaterialLaw::stress(IPVariable*ipv, const IPVariable*ipvprev,
         dmechSourcedt_hom += temp*dmechSrcdTvec(i)*dTidT; // dmechSourcedt average
         for(int m=0;m<9;m++)
           for(int n=0;n<9;n++){
-            dwdf_hom[n] += temp*dwdFvec(m+9*i)*tmp(9*i,n);
-            dmechSourcedf_hom[n] += temp*dmechSrcdTvec(m+9*i)*tmp(9*i,n);
+            dwdf_hom(n) += temp*dwdFvec(m+9*i)*tmp(9*i,n);
+            dmechSourcedf_hom(n) += temp*dmechSrcdTvec(m+9*i)*tmp(9*i,n);
           }
       }
 
@@ -5866,36 +5883,36 @@ void StochTMDMNDG3DMaterialLaw::stress(IPVariable*ipv, const IPVariable*ipvprev,
           for(int n=0; n<3; n++)
             for(int k=0; k<3; k++)
               for(int l=0; l<3; l++)  
-                L(m,n,k,l) = C_hom[m+_row_Di*n][k+_row_Di*l];
+                L(m,n,k,l) = C_hom(m+_row_Di*n,k+_row_Di*l);
       }
       else if(!_flag_isothermal && _flag_microTempFixed){
         dwdt = dwdt_hom; dmechSourcedt = dmechSourcedt_hom;
         for(int m=0; m<3; m++)
           for(int n=0; n<3; n++){
-            dqdgradT(m,n) = C_hom[9+m][9+n];
-            dwdf(m,n) = dwdf_hom[m+3*n];
-            dmechSourcedf(m,n) = dmechSourcedf_hom[m+3*n];
+            dqdgradT(m,n) = C_hom(9+m,9+n);
+            dwdf(m,n) = dwdf_hom(m+3*n);
+            dmechSourcedf(m,n) = dmechSourcedf_hom(m+3*n);
               for(int k=0; k<3; k++){
-                dqdF(m,n,k) = C_hom[9+m][n+3*k];
+                dqdF(m,n,k) = C_hom(9+m,n+3*k);
                 // dPdgradT(m,n,l) = C_hom[m+_row_Di*n][(k+1)*_row_Di-1]; // 0. This is for dPdgradT
                 for(int l=0; l<3; l++)  
-                  L(m,n,k,l) = C_hom[m+3*n][k+3*l];
+                  L(m,n,k,l) = C_hom(m+3*n,k+3*l);
               }    
             }
       }
       else if(!_flag_isothermal && !_flag_microTempFixed){
         for(int m=0; m<3; m++){
-          dqdT(m) = C_hom[(m+1)*(_row_Di-1)-1][_col_Di-1];
+          dqdT(m) = C_hom( (m+1)*(_row_Di-1)-1, _col_Di-1 );
           for(int n=0; n<3; n++){
-            dPdT(m,n) = C_hom[m + n*(_row_Di-1)][_col_Di-1];
-            dqdgradT(m,n) = C_hom[9+m][9+n];
-            dwdf(m,n) = dwdf_hom[m+3*n];
-            dmechSourcedf(m,n) = dmechSourcedf_hom[m+3*n];
+            dPdT(m,n) = C_hom( m + n*(_row_Di-1), _col_Di-1 );
+            dqdgradT(m,n) = C_hom( 9+m, 9+n);
+            dwdf(m,n) = dwdf_hom(m+3*n);
+            dmechSourcedf(m,n) = dmechSourcedf_hom(m+3*n);
             for(int k=0; k<3; k++){
-              dqdF(m,n,k) = C_hom[9+m][n+3*k];
+              dqdF(m,n,k) = C_hom(9+m, n+3*k);
               // C_hom[m+(_row_Di-1)*n][(k+1)*(_row_Di-1)-1] = 0.; This is for dPdgradT
               for(int l=0; l<3; l++)  
-                L(m,n,k,l) = C_hom[m+3*n][k+3*l];
+                L(m,n,k,l) = C_hom(m+3*n, k+3*l);
               }    
             }
         }
diff --git a/dG3D/src/dG3DMaterialLaw.h b/dG3D/src/dG3DMaterialLaw.h
index f6b8b4996..a059ea83f 100644
--- a/dG3D/src/dG3DMaterialLaw.h
+++ b/dG3D/src/dG3DMaterialLaw.h
@@ -702,6 +702,7 @@ class StochDMNDG3DMaterialLaw : public dG3DMaterialLaw{
     int _Dim;
     double _Vf;
     double _tol;   
+    double _alpha, _beta, _gamma; // Euler Angles
     std::vector<std::vector<int>> _LevelNode;  // keep the Nodes at each level
     std::vector<int> _NodeLevel;    // _NodeLevel[Node] = Level of Node
     std::vector<int> _Mat_Id;
@@ -737,6 +738,7 @@ class StochDMNDG3DMaterialLaw : public dG3DMaterialLaw{
     virtual void get_matrixdVdPv(std::vector< std::vector <SPoint2> >& dVAdPv, std::vector<std::vector<std::vector<std::vector<double>>>>& d_VdPv) const; 
     virtual void get_matrixdNdP(std::vector< std::vector <SPoint2> >& dVAdPv, std::vector<std::vector<std::vector<std::vector<double>>>>& d_NvdPv, std::vector<std::vector<std::vector<std::vector<double>>>>& d_NvdPn, std::vector<std::vector<std::vector<std::vector<double>>>>& d_NTdPn) const; 
     virtual void get_matrixdNTdPv(std::vector<std::vector<std::vector<std::vector<double>>>>& d_NTdPv) const;
+    virtual void eulerZXZToRotationMatrix(const double alpha, const double beta, const double gamma, STensor3& rotationMatrix);
     #endif //SWIG
   public:
     StochDMNDG3DMaterialLaw(const int num, const double rho, const double E,const double nu, const char *ParaFile, const bool ReadTree=false, const bool porous=false,const double tol=1e-6,const bool flag_isothermal=true);
@@ -772,8 +774,10 @@ class StochDMNDG3DMaterialLaw : public dG3DMaterialLaw{
     virtual void setMacroSolver(const nonLinearMechSolver* sv);
     virtual void getParameterDerivative(const IPVariable*ipv, std::vector< fullMatrix<double> >& dPdPn, std::vector< fullMatrix<double> >&dPdPv) const;
     virtual void reset_Parameter(std::vector<std::vector<double>>& Para_Norm, std::vector<std::vector<double>>& Para_Wt, const double Vf = 0.0);
-    virtual void reset_Parameter(const char* Para);
+    virtual void reset_Parameter(const char* Para); 
+    virtual void setZXZRotationMatrix_in_IP(StochDMNDG3DIPVariable* ipv); 
     #endif //SWIG
+    virtual void setEulerAngles_rotation_DMN_response(const double alpha, const double beta, const double gamma){_alpha = alpha; _beta = beta; _gamma = gamma;};
  };   
 
 // FLE
@@ -796,7 +800,7 @@ class StochTMDMNDG3DMaterialLaw : public StochDMNDG3DMaterialLaw{
     virtual ~StochTMDMNDG3DMaterialLaw();
 
     virtual void setTime(const double t,const double dtime);
-    virtual materialLaw::matname getType() const {return materialLaw::StochDMN;}
+    virtual materialLaw::matname getType() const {return materialLaw::StochTMDMN;}
 
     virtual void createIPState(IPStateBase* &ips, bool hasBodyForce, const bool* state_=NULL,const MElement *ele=NULL, const int nbFF_=0, const IntPt *GP=NULL, const int gpt = 0) const;
     virtual void createIPVariable(IPVariable* &ipv, bool hasBodyForce, const MElement *ele, const int nbFF_, const IntPt *GP, const int gpt) const;
@@ -823,6 +827,7 @@ class StochTMDMNDG3DMaterialLaw : public StochDMNDG3DMaterialLaw{
     virtual void reset_Parameter(const char* Para);
     virtual void reset_Parameter(std::vector<std::vector<double>>& Para_Norm, std::vector<std::vector<double>>& Para_Wt, std::vector<double>& Para_Alpha, const double Vf);
     #endif //SWIG
+    virtual void setEulerAngles_rotation_DMN_response(const double alpha, const double beta, const double gamma){_alpha = alpha; _beta = beta; _gamma = gamma;};
  }; 
 // FLE
 
-- 
GitLab


From 63cfb53295591ecfbbd41889113835bc4306afb6 Mon Sep 17 00:00:00 2001
From: FLE_Knight <ujwalkishore.jinaga@uliege.be>
Date: Fri, 14 Mar 2025 15:21:26 +0100
Subject: [PATCH 18/19] [NEW PATCH] StochDMNdG3DIPVariable is now a child class
 of ThermoMechanicsDG3DIPVariableBase to avoid the diamond inheritance problem
 while creating StochTMDMNdG3DIPVariable as a child class of
 StochDMNdG3DIPVariable.

---
 dG3D/src/dG3DIPVariable.cpp | 65 ++++++++-----------------------------
 dG3D/src/dG3DIPVariable.h   |  8 ++---
 2 files changed, 18 insertions(+), 55 deletions(-)

diff --git a/dG3D/src/dG3DIPVariable.cpp b/dG3D/src/dG3DIPVariable.cpp
index 364670af7..06d0c8844 100644
--- a/dG3D/src/dG3DIPVariable.cpp
+++ b/dG3D/src/dG3DIPVariable.cpp
@@ -4053,7 +4053,7 @@ void ThermoMechanicsDG3DIPVariableBase::restart()
 }
 
 StochDMNDG3DIPVariable::StochDMNDG3DIPVariable(const int NRoot,const int NInterface, const bool createBodyForceHO, const bool oninter):
-    dG3DIPVariable(createBodyForceHO, oninter), _NRoot(NRoot), _NInterface(NInterface), _IPVector(NRoot,NULL){
+ThermoMechanicsDG3DIPVariableBase(createBodyForceHO, oninter), _NRoot(NRoot), _NInterface(NInterface), _IPVector(NRoot,NULL){
     static STensor3 _I(1.); _R = _I; 
     bool resizeFlag;
     int entryFP = 9*_NRoot;
@@ -4064,7 +4064,7 @@ StochDMNDG3DIPVariable::StochDMNDG3DIPVariable(const int NRoot,const int NInterf
  }
 
 StochDMNDG3DIPVariable::StochDMNDG3DIPVariable(const StochDMNDG3DIPVariable& src):
-  dG3DIPVariable(src), _NRoot(src._NRoot), _NInterface(src._NInterface), Fvec(src.Fvec), Pvec(src.Pvec), a(src.a),_IPVector(src._NRoot,NULL), _R(src._R){
+ThermoMechanicsDG3DIPVariableBase(src), _NRoot(src._NRoot), _NInterface(src._NInterface), Fvec(src.Fvec), Pvec(src.Pvec), a(src.a),_IPVector(src._NRoot,NULL), _R(src._R){
     for (int j=0; j< src._NRoot; j++){
       if (src._IPVector[j] != NULL){
         _IPVector[j] = src._IPVector[j]->clone();
@@ -4075,7 +4075,7 @@ StochDMNDG3DIPVariable::StochDMNDG3DIPVariable(const StochDMNDG3DIPVariable& src
 
 StochDMNDG3DIPVariable& StochDMNDG3DIPVariable::operator =(const IPVariable& src)
 {
-  dG3DIPVariable::operator=(src);
+  ThermoMechanicsDG3DIPVariableBase::operator=(src);
   const StochDMNDG3DIPVariable* psrc = dynamic_cast<const StochDMNDG3DIPVariable*>(&src);
   if (psrc!=NULL)
   {
@@ -4132,14 +4132,14 @@ double StochDMNDG3DIPVariable::get(const int comp) const
   }
   else
   {
-    return dG3DIPVariable::get(comp);
+    return ThermoMechanicsDG3DIPVariableBase::get(comp);
   }
 };
 
 
 void StochDMNDG3DIPVariable::restart()
 {
-  dG3DIPVariable::restart();
+  ThermoMechanicsDG3DIPVariableBase::restart();
   restartManager::restart(_NRoot);
   restartManager::restart(_NInterface);
   restartManager::restart(Fvec.getDataPtr(),9*_NRoot);
@@ -4185,8 +4185,7 @@ double StochDMNDG3DIPVariable::damageEnergy() const
 // FLE
 StochTMDMNDG3DIPVariable::StochTMDMNDG3DIPVariable(const int NRoot,const int NInterface, const int col_Di, const int row_Di,
                      const bool createBodyForceHO, const bool oninter):
-    ThermoMechanicsDG3DIPVariableBase(createBodyForceHO, oninter), _NRoot(NRoot), _NInterface(NInterface),
-    _col_Di(col_Di), _row_Di(row_Di), _IPVector(NRoot,NULL){
+    StochDMNDG3DIPVariable(NRoot,NInterface,createBodyForceHO,oninter),_col_Di(col_Di), _row_Di(row_Di){
     bool resizeFlag;
     int entryFHPQ = _col_Di*_NRoot;
     int entry_ab = _row_Di*_NInterface;
@@ -4198,25 +4197,18 @@ StochTMDMNDG3DIPVariable::StochTMDMNDG3DIPVariable(const int NRoot,const int NIn
     resizeFlag = mechSrcvec.resize(_NRoot, true);
  }
 
-StochTMDMNDG3DIPVariable::StochTMDMNDG3DIPVariable(const StochTMDMNDG3DIPVariable& src): ThermoMechanicsDG3DIPVariableBase(src), 
-    _NRoot(src._NRoot), _NInterface(src._NInterface), _col_Di(src._col_Di), _row_Di(src._row_Di),
+StochTMDMNDG3DIPVariable::StochTMDMNDG3DIPVariable(const StochTMDMNDG3DIPVariable& src): StochDMNDG3DIPVariable(src),
+    _col_Di(src._col_Di), _row_Di(src._row_Di),
     FHvec(src.FHvec), PQvec(src.PQvec), ab(src.ab), Cpvec(src.Cpvec), 
-    thermSrcvec(src.thermSrcvec), mechSrcvec(src.mechSrcvec), _IPVector(src._NRoot,NULL){
-    for (int j=0; j< src._NRoot; j++){
-      if (src._IPVector[j] != NULL){
-        _IPVector[j] = src._IPVector[j]->clone();
-      }
-    }
+    thermSrcvec(src.thermSrcvec), mechSrcvec(src.mechSrcvec){
   }
 
 StochTMDMNDG3DIPVariable& StochTMDMNDG3DIPVariable::operator =(const IPVariable& src)
 {
-  ThermoMechanicsDG3DIPVariableBase::operator=(src);
+  StochDMNDG3DIPVariable::operator=(src);
   const StochTMDMNDG3DIPVariable* psrc = dynamic_cast<const StochTMDMNDG3DIPVariable*>(&src);
   if (psrc!=NULL)
   {
-    _NRoot = psrc->_NRoot;
-    _NInterface = psrc->_NInterface;
     _col_Di = psrc->_col_Di;
     _row_Di = psrc->_row_Di;
     FHvec = psrc->FHvec;
@@ -4225,30 +4217,12 @@ StochTMDMNDG3DIPVariable& StochTMDMNDG3DIPVariable::operator =(const IPVariable&
     Cpvec = psrc->Cpvec;
     thermSrcvec = psrc->thermSrcvec;
     mechSrcvec = psrc->mechSrcvec;
-    for (int j=0; j< _NRoot; j++)
-    {
-      if ((_IPVector[j]!=NULL) and (psrc->_IPVector[j] != NULL))
-      {
-        _IPVector[j]->operator =(*(psrc->_IPVector[j]));
-      }
-      else
-      {
-        Msg::Error("cannot perform equal operator in StochTMDMNDG3DIPVariable::operator =");
-      }
-    }
   }
   return *this;
 }
 
 StochTMDMNDG3DIPVariable::~StochTMDMNDG3DIPVariable()
 {
-  for (int j=0; j< _NRoot; j++)
-  {
-    if (_IPVector[j] != NULL)
-    {
-      delete _IPVector[j];
-    }
-  }
 }
 
 void StochTMDMNDG3DIPVariable::addIPv(int loc, IPVariable* ipv)
@@ -4258,11 +4232,7 @@ void StochTMDMNDG3DIPVariable::addIPv(int loc, IPVariable* ipv)
 
 double StochTMDMNDG3DIPVariable::get(const int comp) const
 {
-  if (comp == IPField::DEFO_ENERGY ||
-      comp == IPField::PLASTIC_ENERGY ||
-      comp == IPField::DAMAGE_ENERGY ||
-      comp == IPField::DAMAGE ||
-      comp == IPField::_thermalEnergy)
+  if (comp == IPField::_thermalEnergy)
   {
     double v = 0;
     for (int j=0; j< _NRoot; j++)
@@ -4271,26 +4241,19 @@ double StochTMDMNDG3DIPVariable::get(const int comp) const
     }
     return v;
   }
-  else
-  {
-    return ThermoMechanicsDG3DIPVariableBase::get(comp);
+  else{
+    return StochDMNDG3DIPVariable::get(comp);
   }
 };
 
 void StochTMDMNDG3DIPVariable::restart()
 {
-  ThermoMechanicsDG3DIPVariableBase::restart();
-  restartManager::restart(_NRoot);
-  restartManager::restart(_NInterface);
+  StochDMNDG3DIPVariable::restart();
   restartManager::restart(_col_Di);
   restartManager::restart(_row_Di);
   restartManager::restart(FHvec.getDataPtr(),_col_Di*_NRoot);
   restartManager::restart(PQvec.getDataPtr(),_col_Di*_NRoot);
   restartManager::restart(ab.getDataPtr(),_row_Di*_NInterface);
-  restartManager::restart(_IPVector);
-  for (int j=0; j< _NRoot; j++){
-    _IPVector[j]->restart();
-  }
 };
 
 double StochTMDMNDG3DIPVariable::defoEnergy() const
diff --git a/dG3D/src/dG3DIPVariable.h b/dG3D/src/dG3DIPVariable.h
index d7a9fa082..6bfee1b08 100644
--- a/dG3D/src/dG3DIPVariable.h
+++ b/dG3D/src/dG3DIPVariable.h
@@ -3434,7 +3434,7 @@ class ThermoMechanicsDG3DIPVariableBase : public dG3DIPVariable, public extraDof
   virtual void restart();
 };
 
-class StochDMNDG3DIPVariable : public dG3DIPVariable
+class StochDMNDG3DIPVariable : public ThermoMechanicsDG3DIPVariableBase
 {
   protected:
     int _NRoot, _NInterface;
@@ -3454,6 +3454,7 @@ class StochDMNDG3DIPVariable : public dG3DIPVariable
     virtual double defoEnergy() const;
     virtual double plasticEnergy() const;
     virtual double damageEnergy() const;
+    virtual double getInternalEnergyExtraDofDiffusion() const {return 0.;};
 
     void addIPv(int i, IPVariable* ipv);
     IPVariable* getIPv(int i) {return _IPVector[i];};
@@ -3477,11 +3478,10 @@ class StochDMNDG3DIPVariable : public dG3DIPVariable
 };
 
 // FLE
-class StochTMDMNDG3DIPVariable : public ThermoMechanicsDG3DIPVariableBase 
+class StochTMDMNDG3DIPVariable : public StochDMNDG3DIPVariable 
 {
   protected:
-    int _NRoot, _NInterface, _col_Di, _row_Di;
-    std::vector<IPVariable*> _IPVector;
+    int _col_Di, _row_Di;
 
     // combined vectors
     fullVector<double> FHvec; // F- defo, H -tempGrad
-- 
GitLab


From 384f35138950cf6fd12beba5cf1e57a2e23af204 Mon Sep 17 00:00:00 2001
From: FLE_Knight <ujwalkishore.jinaga@uliege.be>
Date: Fri, 14 Mar 2025 18:12:58 +0100
Subject: [PATCH 19/19] [NEW PATCH] Minor Bug in the stress function

---
 dG3D/src/dG3DMaterialLaw.cpp | 50 ++++++++++++++++++++++++++----------
 1 file changed, 36 insertions(+), 14 deletions(-)

diff --git a/dG3D/src/dG3DMaterialLaw.cpp b/dG3D/src/dG3DMaterialLaw.cpp
index 9724b5967..a8a505472 100644
--- a/dG3D/src/dG3DMaterialLaw.cpp
+++ b/dG3D/src/dG3DMaterialLaw.cpp
@@ -5602,11 +5602,17 @@ void StochTMDMNDG3DMaterialLaw::stress(IPVariable*ipv, const IPVariable*ipvprev,
   STensor33 dPdgradT; STensorOperation::zero(dPdgradT);
 
   // The tangent C_hom is combined with thermal tangents.
-  static fullMatrix<double> C_hom(_col_Di,_col_Di); if(C_hom.size1()!=_col_Di || C_hom.size2()!=_col_Di){C_hom.resize(_col_Di,_col_Di);}; C_hom.setAll(0.); 
-  static fullVector<double> PQ_hom(_col_Di); if(PQ_hom.size()!=_col_Di){PQ_hom.resize(_col_Di);}; PQ_hom.setAll(0.);
-  static fullVector<double> dPQdT_hom(_col_Di); if(dPQdT_hom.size()!=_col_Di){dPQdT_hom.resize(_col_Di);}; dPQdT_hom.setAll(0.);
+  fullMatrix<double> C_hom(_col_Di,_col_Di); 
+  // if(C_hom.size1()!=_col_Di || C_hom.size2()!=_col_Di){C_hom.resize(_col_Di,_col_Di);}; 
+  C_hom.setAll(0.); 
+  fullVector<double> PQ_hom(_col_Di); 
+  // if(PQ_hom.size()!=_col_Di){PQ_hom.resize(_col_Di);}; 
+  PQ_hom.setAll(0.);
+  fullVector<double> dPQdT_hom(_col_Di); 
+  // if(dPQdT_hom.size()!=_col_Di){dPQdT_hom.resize(_col_Di);}; 
+  dPQdT_hom.setAll(0.);
   double Cp_hom(0.), thermSrc_hom(0.), mechSource_hom(0.), dwdt_hom(0.), dmechSourcedt_hom(0.);
-  static fullVector<double> dwdf_hom(9), dmechSourcedf_hom(9); dwdf_hom.setAll(0.); dmechSourcedf_hom.setAll(0.);
+  fullVector<double> dwdf_hom(9), dmechSourcedf_hom(9); dwdf_hom.setAll(0.); dmechSourcedf_hom.setAll(0.);
 
   fullVector<double>& FHvec = ipvcur->getRefToCombinedGradientVect();
   fullVector<double>& PQvec = ipvcur->getRefToCombinedStressVect(); PQvec.setAll(0.0);
@@ -5618,13 +5624,27 @@ void StochTMDMNDG3DMaterialLaw::stress(IPVariable*ipv, const IPVariable*ipvprev,
   dwdtvec.resize(_NLeaf); dwdtvec.setAll(0.); dmechSrcdTvec.resize(_NLeaf); dmechSrcdTvec.setAll(0.);
   dwdFvec.resize(9*_NLeaf); dwdFvec.setAll(0.); dmechSrcdFvec.resize(9*_NLeaf); dmechSrcdFvec.setAll(0.);
 
-  static fullVector<double> Res_node(_row_Di*_NInterface); if(Res_node.size()!=_row_Di*_NInterface){Res_node.resize(_row_Di*_NInterface);}; Res_node.setAll(0.);  
-  static fullVector<double> ab_step(_row_Di*_NInterface); if(ab_step.size()!=_row_Di*_NInterface){ab_step.resize(_row_Di*_NInterface);}; ab_step.setAll(0.0);
-  static fullMatrix<double> NTVC(_row_Di*_NInterface, _col_Di*_NLeaf); if(NTVC.size1()!=_row_Di*_NInterface || NTVC.size2()!=_col_Di*_NLeaf){NTVC.resize(_row_Di*_NInterface, _col_Di*_NLeaf);}; NTVC.setAll(0.0); 
-  static fullMatrix<double> Jacobian_inv(_row_Di*_NInterface, _row_Di*_NInterface); if(Jacobian_inv.size1()!=_row_Di*_NInterface || Jacobian_inv.size2()!=_row_Di*_NInterface){Jacobian_inv.resize(_row_Di*_NInterface, _row_Di*_NInterface);}; Jacobian_inv.setAll(0.0); 
-  static fullMatrix<double> tmp(_col_Di*_NLeaf, _col_Di); if(tmp.size1()!=_col_Di*_NLeaf || tmp.size2()!=_col_Di){tmp.resize(_col_Di*_NLeaf, _col_Di);}; tmp.setAll(0.0); 
-  static fullMatrix<double> dRdF(_row_Di*_NInterface, _col_Di); if(dRdF.size1()!=_row_Di*_NInterface || dRdF.size2()!=_col_Di){dRdF.resize(_row_Di*_NInterface, _col_Di);}; dRdF.setAll(0.0);
-  static fullMatrix<double> dadF(_row_Di*_NInterface, _col_Di); if(dadF.size1()!=_row_Di*_NInterface || dadF.size2()!=_col_Di){dadF.resize(_row_Di*_NInterface, _col_Di);}; dadF.setAll(0.0);
+  fullVector<double> Res_node(_row_Di*_NInterface); 
+  // if(Res_node.size()!=_row_Di*_NInterface){Res_node.resize(_row_Di*_NInterface);}; 
+  Res_node.setAll(0.);  
+  fullVector<double> ab_step(_row_Di*_NInterface); 
+  // if(ab_step.size()!=_row_Di*_NInterface){ab_step.resize(_row_Di*_NInterface);}; 
+  ab_step.setAll(0.0);
+  fullMatrix<double> NTVC(_row_Di*_NInterface, _col_Di*_NLeaf); 
+  // if(NTVC.size1()!=_row_Di*_NInterface || NTVC.size2()!=_col_Di*_NLeaf){NTVC.resize(_row_Di*_NInterface, _col_Di*_NLeaf);}; 
+  NTVC.setAll(0.0); 
+  fullMatrix<double> Jacobian_inv(_row_Di*_NInterface, _row_Di*_NInterface); 
+  // if(Jacobian_inv.size1()!=_row_Di*_NInterface || Jacobian_inv.size2()!=_row_Di*_NInterface){Jacobian_inv.resize(_row_Di*_NInterface, _row_Di*_NInterface);}; 
+  Jacobian_inv.setAll(0.0); 
+  fullMatrix<double> tmp(_col_Di*_NLeaf, _col_Di); 
+  // if(tmp.size1()!=_col_Di*_NLeaf || tmp.size2()!=_col_Di){tmp.resize(_col_Di*_NLeaf, _col_Di);}; 
+  tmp.setAll(0.0); 
+  fullMatrix<double> dRdF(_row_Di*_NInterface, _col_Di); 
+  // if(dRdF.size1()!=_row_Di*_NInterface || dRdF.size2()!=_col_Di){dRdF.resize(_row_Di*_NInterface, _col_Di);}; 
+  dRdF.setAll(0.0);
+  fullMatrix<double> dadF(_row_Di*_NInterface, _col_Di); 
+  // if(dadF.size1()!=_row_Di*_NInterface || dadF.size2()!=_col_Di){dadF.resize(_row_Di*_NInterface, _col_Di);}; 
+  dadF.setAll(0.0);
     
   _C.setAll(0.0);
   int ite = 0;
@@ -5639,7 +5659,7 @@ void StochTMDMNDG3DMaterialLaw::stress(IPVariable*ipv, const IPVariable*ipvprev,
     _Nv.mult(ab_cur, FHvec);
     for(int i=0; i<_NLeaf; i++){
 
-      Msg::Error("i is %d", i);
+      // Msg::Error("i is %d", i);
       
       if (_VA[pos_start+i] > 1.e-6){
         ThermoMechanicsDG3DIPVariableBase* ipv_i = dynamic_cast<ThermoMechanicsDG3DIPVariableBase*>(ipvcur->getIPv(i));
@@ -5799,7 +5819,6 @@ void StochTMDMNDG3DMaterialLaw::stress(IPVariable*ipv, const IPVariable*ipvprev,
   Jacobian.scale(-1.0);
   int pos0 = _Child[0][0];
   int pos1 = _Child[0][1];  
-
   if(r>_tol){
     Msg::Error("TMDMN residual (= %lf) didn't converge to tolenerce after %d iteration",r,ite);
     return;
@@ -5874,7 +5893,7 @@ void StochTMDMNDG3DMaterialLaw::stress(IPVariable*ipv, const IPVariable*ipvprev,
         for(int m=0;m<9;m++)
           for(int n=0;n<9;n++){
             dwdf_hom(n) += temp*dwdFvec(m+9*i)*tmp(9*i,n);
-            dmechSourcedf_hom(n) += temp*dmechSrcdTvec(m+9*i)*tmp(9*i,n);
+            dmechSourcedf_hom(n) += temp*dmechSrcdFvec(m+9*i)*tmp(9*i,n);
           }
       }
 
@@ -5919,7 +5938,10 @@ void StochTMDMNDG3DMaterialLaw::stress(IPVariable*ipv, const IPVariable*ipvprev,
       }
     }
   }
+  Msg::Error("Sizes of PQVec are %d", PQvec.size());
   ipvcur->setRefToDGElasticTangentModuli(this->elasticStiffness);
+  Msg::Error("Sizes");
+  Msg::Error("Sizes of PQVec are %d", PQvec.size());
 } 
 
 void StochTMDMNDG3DMaterialLaw::setTime(const double t,const double dtime){
-- 
GitLab