diff --git a/NonLinearSolver/modelReduction/Optimizer.h b/NonLinearSolver/modelReduction/Optimizer.h
index e36297d5771607ed79bc18736e227c4e2043b71a..d3db3e9fd77f9c6f6ad10f1af34642f072afaef5 100644
--- a/NonLinearSolver/modelReduction/Optimizer.h
+++ b/NonLinearSolver/modelReduction/Optimizer.h
@@ -53,6 +53,11 @@ class LossFunction
      */
     virtual void initializeFittingParameters(fullVector<double>& W) = 0; 
     
+    /*! @param[out] WLower lower bound of the fitting parameters 
+     *  @param[out] WUpper upper bound of the fitting parameters 
+     */
+    virtual void getUnknownBounds(fullVector<double>& WLower, fullVector<double>& WUpper) const = 0;
+    
     /*! \brief update the model with the new fitting parameter
       @param[in] W the fitting parameters
      */
diff --git a/NonLinearSolver/modelReduction/TrainingArbitraryDeepMaterialNetworks.cpp b/NonLinearSolver/modelReduction/TrainingArbitraryDeepMaterialNetworks.cpp
index 89bff9c5eb4e08623986c7589a47aaf5cb253c1f..0cf2d4d7aa8d56ef48510aeedb81a0fa81f8fe48 100644
--- a/NonLinearSolver/modelReduction/TrainingArbitraryDeepMaterialNetworks.cpp
+++ b/NonLinearSolver/modelReduction/TrainingArbitraryDeepMaterialNetworks.cpp
@@ -870,7 +870,15 @@ void TrainingDeepMaterialNetworkLinearElastic::saveModel(const std::string fname
 void TrainingDeepMaterialNetworkLinearElastic::initializeFittingParameters(fullVector<double>& W)
 {
   numberDofs(W);
-}
+};
+
+// get bounds of fitting parmaters
+void TrainingDeepMaterialNetworkLinearElastic::getUnknownBounds(fullVector<double>& WLower, fullVector<double>& WUpper) const
+{
+  Msg::Error("TrainingDeepMaterialNetworkLinearElastic::getUnknownBounds has not been implemeneted");
+  Msg::Exit(1);
+};
+
 // update the model with the new fitting parameter
 void TrainingDeepMaterialNetworkLinearElastic::updateModelFromFittingParameters(const fullVector<double>& W)
 {
diff --git a/NonLinearSolver/modelReduction/TrainingArbitraryDeepMaterialNetworks.h b/NonLinearSolver/modelReduction/TrainingArbitraryDeepMaterialNetworks.h
index d5373ff2102a1543e778b4bb5efa28aaecde82c6..6b031e0bde50747d6f461b7cfdde1026ca42c773 100644
--- a/NonLinearSolver/modelReduction/TrainingArbitraryDeepMaterialNetworks.h
+++ b/NonLinearSolver/modelReduction/TrainingArbitraryDeepMaterialNetworks.h
@@ -106,6 +106,8 @@ class TrainingDeepMaterialNetworkLinearElastic : public TrainingArbitraryDeepMat
     virtual void saveModel(const std::string fname) const;
     // start numbering fitting parameters
     virtual void initializeFittingParameters(fullVector<double>& W); 
+    // get bounds of fitting parmaters
+    virtual void getUnknownBounds(fullVector<double>& WLower, fullVector<double>& WUpper) const;
     // update the model with the new fitting parameter
     virtual void updateModelFromFittingParameters(const fullVector<double>& W);
     //  in case of fails
diff --git a/NonLinearSolver/modelReduction/TrainingDeepMaterialNetworks.cpp b/NonLinearSolver/modelReduction/TrainingDeepMaterialNetworks.cpp
index 3c963eec91918fdb9e2dc4b1b9dbcfb3fd0795fb..9f010a1159c1629661d476eaa3439125a9a3524c 100644
--- a/NonLinearSolver/modelReduction/TrainingDeepMaterialNetworks.cpp
+++ b/NonLinearSolver/modelReduction/TrainingDeepMaterialNetworks.cpp
@@ -4028,7 +4028,84 @@ void TrainingDeepMaterialNetwork::saveModel(const std::string fname) const
 void TrainingDeepMaterialNetwork::initializeFittingParameters(fullVector<double>& W)
 {
   numberDofs(W);
-}
+};
+
+void TrainingDeepMaterialNetwork::getUnknownBounds(fullVector<double>& WLower, fullVector<double>& WUpper) const
+{
+  // Dof of all nodes
+  Tree::nodeContainer allNodes;
+  _T->getAllNodes(allNodes);
+
+  // initialize data from tree
+  //
+  int sizeOfR = _unknown.size();
+  WLower.resize(sizeOfR,true);
+  WUpper.resize(sizeOfR,true);
+    //
+  for (int i=0; i< allNodes.size(); i++)
+  {
+    const TreeNode& node = *(allNodes[i]);
+    std::vector<Dof> R;
+    getKeys(&node,R);
+    int Rsize = R.size();
+    if (node.childs.size() ==0)
+    {
+      int numCoh = 0; 
+      int numCohDirVars = 0;
+      if (node.withCohesive())
+      {
+        numCoh = node.cohesiveCoeffVars.size();
+        numCohDirVars = node.cohesiveDirectionVars.size2();
+      }
+      for (int j=0; j< Rsize; j++)
+      {
+        std::map<Dof,int>::const_iterator itR =  _unknown.find(R[j]);
+        if (itR != _unknown.end())
+        {
+          if (j == 0)
+          {
+            // leaf
+            WLower(itR->second) =  node.af->getReciprocalVal(0.001);
+            WUpper(itR->second) = node.af->getReciprocalVal(1);
+          }
+          else if ((j > 0) && (j< numCoh+1))
+          {
+            WLower(itR->second) = 0.1;
+            WUpper(itR->second) = 0.9;
+          }
+          else if ((j >= numCoh+1) && (j < numCoh*numCohDirVars+numCoh+1))
+          {
+            int index = j -(numCoh+1);
+            int k = index/numCohDirVars;
+            int l = index%numCohDirVars;
+            //Msg::Info("index = %d k=%d, l=%d",index,k,l);
+            WLower(itR->second) = 0;
+            WUpper(itR->second) = 1.;
+          }
+          else
+          {
+            Msg::Error("wrong position");
+            Msg::Exit(0);
+          }
+        };
+      }
+    }
+    else
+    {
+      for (int j=0; j< Rsize; j++)
+      {
+        std::map<Dof,int>::const_iterator itR =  _unknown.find(R[j]);
+        if (itR != _unknown.end())
+        {
+          WLower(itR->second) = 0;
+          WUpper(itR->second) = 1.;
+        };
+      }
+    }
+  };  
+};
+
+
 // update the model with the new fitting parameter
 void TrainingDeepMaterialNetwork::updateModelFromFittingParameters(const fullVector<double>& W)
 {
diff --git a/NonLinearSolver/modelReduction/TrainingDeepMaterialNetworks.h b/NonLinearSolver/modelReduction/TrainingDeepMaterialNetworks.h
index 34a1849a00b23cfdce9cc81ab8db7a2b7a7c4f03..8e5de7ed10455a847398d5596d5a84d3fc728dc7 100644
--- a/NonLinearSolver/modelReduction/TrainingDeepMaterialNetworks.h
+++ b/NonLinearSolver/modelReduction/TrainingDeepMaterialNetworks.h
@@ -403,6 +403,8 @@ class TrainingDeepMaterialNetwork : public LossFunction
     virtual void saveModel(const std::string fname) const;
     // start numbering fitting parameters
     virtual void initializeFittingParameters(fullVector<double>& W); 
+    // get bounds of fitting paraeters
+    virtual void getUnknownBounds(fullVector<double>& WLower, fullVector<double>& WUpper) const;
     // update the model with the new fitting parameter
     virtual void updateModelFromFittingParameters(const fullVector<double>& W);
     //  in case of fails
diff --git a/NonLinearSolver/modelReduction/TrainingDeepMaterialNetworksNonLinear.cpp b/NonLinearSolver/modelReduction/TrainingDeepMaterialNetworksNonLinear.cpp
index 7d2752e00f3b1873cc18b5ff20705064c1446c76..6f2d9b1067c9c0b2e322a8666662c3ef412a2ba5 100644
--- a/NonLinearSolver/modelReduction/TrainingDeepMaterialNetworksNonLinear.cpp
+++ b/NonLinearSolver/modelReduction/TrainingDeepMaterialNetworksNonLinear.cpp
@@ -1811,6 +1811,13 @@ void TrainingDeepMaterialNetworkNonLinear::initializeFittingParameters(fullVecto
 {
   numberDofs(W);
 }
+
+// get bounds of fitting parmaters
+void TrainingDeepMaterialNetworkNonLinear::getUnknownBounds(fullVector<double>& WLower, fullVector<double>& WUpper) const
+{
+  Msg::Error("TrainingDeepMaterialNetworkNonLinear::getUnknownBounds has not been implemeneted");
+  Msg::Exit(1);
+};
 // update the model with the new fitting parameter
 void TrainingDeepMaterialNetworkNonLinear::updateModelFromFittingParameters(const fullVector<double>& W)
 {
diff --git a/NonLinearSolver/modelReduction/TrainingDeepMaterialNetworksNonLinear.h b/NonLinearSolver/modelReduction/TrainingDeepMaterialNetworksNonLinear.h
index 5dbafa39912552ee22693e8dec971f905d60c552..3bf011cd2019d89cda8e69f37434057c4aa7db13 100644
--- a/NonLinearSolver/modelReduction/TrainingDeepMaterialNetworksNonLinear.h
+++ b/NonLinearSolver/modelReduction/TrainingDeepMaterialNetworksNonLinear.h
@@ -208,6 +208,8 @@ class TrainingDeepMaterialNetworkNonLinear : public TrainingArbitraryDeepMateria
     virtual void saveModel(const std::string fname) const;
     // start numbering fitting parameters
     virtual void initializeFittingParameters(fullVector<double>& W); 
+    // get bounds of fitting paraeters
+    virtual void getUnknownBounds(fullVector<double>& WLower, fullVector<double>& WUpper) const;
     // update the model with the new fitting parameter
     virtual void updateModelFromFittingParameters(const fullVector<double>& W);
     //  in case of fails