From 2c463548fca87084024e9a4c797d81fd0e325369 Mon Sep 17 00:00:00 2001
From: Gauthier Becker <gauthierbecker@gmail.com>
Date: Fri, 11 Jun 2010 15:18:28 +0000
Subject: [PATCH] Adds in dgplate : 1) Non linear solver (Newton-Raphson) 2)
 cohesive law (fracture in bending OK) 3) lua version of code 4) a test case
 with 3rd order quadrilateral element. Some modifications are made in
 linearSystem (add a function to compute norm of RightHandSide) and in
 dofManager (add a function to have the fixed dof outside dofManager)

---
 Geo/MElement.cpp           |  8 +++----
 Post/PViewDataGModel.cpp   | 46 +++++++++++++++++++-------------------
 Solver/dofManager.h        | 15 +++++++++----
 Solver/linearSystem.h      |  1 +
 Solver/linearSystemCSR.h   | 45 +++++++++++++++++++++++--------------
 Solver/linearSystemFull.h  | 18 +++++++++++----
 Solver/linearSystemGMM.h   | 17 +++++++++++---
 Solver/linearSystemPETSc.h | 10 +++++++--
 8 files changed, 103 insertions(+), 57 deletions(-)

diff --git a/Geo/MElement.cpp b/Geo/MElement.cpp
index b62648a362..f885578e7d 100644
--- a/Geo/MElement.cpp
+++ b/Geo/MElement.cpp
@@ -156,7 +156,7 @@ int MElement::getVolumeSign()
 }
 
 bool MElement::setVolumePositive()
-{ 
+{
   int s = getVolumeSign();
   if(s < 0) revert();
   if(!s) return false;
@@ -438,7 +438,7 @@ void MElement::interpolateCurl(double val[], double u, double v, double w, doubl
   f[2] = fy[0] - fx[1];
 }
 
-double MElement::interpolateDiv(double val[], double u, double v, double w, 
+double MElement::interpolateDiv(double val[], double u, double v, double w,
                                 int stride, int order)
 {
   double fx[3], fy[3], fz[3], jac[3][3], inv[3][3];
@@ -477,7 +477,7 @@ void MElement::writeMSH(FILE *fp, double version, bool binary, int num,
       fprintf(fp, " %d %d %d 1 %d", 4 + par, abs(physical), elementary, _partition);
     else{
       int numGhosts = ghosts->size();
-      fprintf(fp, " %d %d %d %d %d", 4 + numGhosts + par, abs(physical), elementary, 
+      fprintf(fp, " %d %d %d %d %d", 4 + numGhosts + par, abs(physical), elementary,
               1 + numGhosts, _partition);
       for(unsigned int i = 0; i < ghosts->size(); i++)
         fprintf(fp, " %d", -(*ghosts)[i]);
@@ -501,7 +501,7 @@ void MElement::writeMSH(FILE *fp, double version, bool binary, int num,
     // tags change from element to element (third-party codes can
     // still write MSH file optimized for reading speed, by grouping
     // elements with the same number of tags in blobs)
-    int blob[60] = {type, 1, numTags, num ? num : _num, abs(physical), elementary, 
+    int blob[60] = {type, 1, numTags, num ? num : _num, abs(physical), elementary,
                     1 + numGhosts, _partition};
     if(ghosts)
       for(int i = 0; i < numGhosts; i++) blob[8 + i] = -(*ghosts)[i];
diff --git a/Post/PViewDataGModel.cpp b/Post/PViewDataGModel.cpp
index 94fae4dda8..8b14f91532 100644
--- a/Post/PViewDataGModel.cpp
+++ b/Post/PViewDataGModel.cpp
@@ -15,7 +15,7 @@
 #include "Numeric.h"
 #include "GmshMessage.h"
 
-PViewDataGModel::PViewDataGModel(DataType type) 
+PViewDataGModel::PViewDataGModel(DataType type)
   : PViewData(), _min(VAL_INF), _max(-VAL_INF), _type(type)
 {
 }
@@ -69,25 +69,25 @@ bool PViewDataGModel::finalize(bool computeMinMax)
   for(int step = 0; step < getNumTimeSteps(); step++){
     GModel *m = _steps[step]->getModel();
     for(GModel::eiter it = m->firstEdge(); it != m->lastEdge(); it++){
-      if((*it)->lines.size()) 
+      if((*it)->lines.size())
         _addInterpolationMatricesForElement((*it)->lines[0]);
     }
     for(GModel::fiter it = m->firstFace(); it != m->lastFace(); it++){
-      if((*it)->triangles.size()) 
+      if((*it)->triangles.size())
         _addInterpolationMatricesForElement((*it)->triangles[0]);
-      if((*it)->quadrangles.size()) 
+      if((*it)->quadrangles.size())
         _addInterpolationMatricesForElement((*it)->quadrangles[0]);
       if((*it)->polygons.size())
         _addInterpolationMatricesForElement((*it)->polygons[0]);
     }
     for(GModel::riter it = m->firstRegion(); it != m->lastRegion(); it++){
-      if((*it)->tetrahedra.size()) 
+      if((*it)->tetrahedra.size())
         _addInterpolationMatricesForElement((*it)->tetrahedra[0]);
-      if((*it)->hexahedra.size()) 
+      if((*it)->hexahedra.size())
         _addInterpolationMatricesForElement((*it)->hexahedra[0]);
-      if((*it)->prisms.size()) 
+      if((*it)->prisms.size())
         _addInterpolationMatricesForElement((*it)->prisms[0]);
-      if((*it)->pyramids.size()) 
+      if((*it)->pyramids.size())
         _addInterpolationMatricesForElement((*it)->pyramids[0]);
       if((*it)->polyhedra.size())
         _addInterpolationMatricesForElement((*it)->polyhedra[0]);
@@ -107,7 +107,7 @@ void PViewDataGModel::_addInterpolationMatricesForElement(MElement *e)
                                fs->coefficients, fs->monomials);
     else
       setInterpolationMatrices(type, fs->coefficients, fs->monomials);
-  }                               
+  }
 }
 
 MElement *PViewDataGModel::_getElement(int step, int ent, int ele)
@@ -149,7 +149,7 @@ double PViewDataGModel::getMax(int step)
 }
 
 SBoundingBox3d PViewDataGModel::getBoundingBox(int step)
-{ 
+{
   if(step < 0 || _steps.empty()){
     SBoundingBox3d tmp;
     for(unsigned int i = 0; i < _steps.size(); i++)
@@ -297,7 +297,7 @@ int PViewDataGModel::getNumElements(int step, int ent)
   // to generalize
   if(step < 0 && ent < 0) return _steps[0]->getModel()->getNumMeshElements();
   if(step < 0) return _steps[0]->getEntity(ent)->getNumMeshElements();
-  if(ent < 0) return _steps[step]->getModel()->getNumMeshElements(); 
+  if(ent < 0) return _steps[step]->getModel()->getNumMeshElements();
   return _steps[step]->getEntity(ent)->getNumMeshElements();
 }
 
@@ -320,11 +320,11 @@ int PViewDataGModel::getNumNodes(int step, int ent, int ele)
   }
 }
 
-int PViewDataGModel::getNode(int step, int ent, int ele, int nod, 
+int PViewDataGModel::getNode(int step, int ent, int ele, int nod,
                              double &x, double &y, double &z)
 {
   MElement *e = _getElement(step, ent, ele);
-  if(_type == GaussPointData){ 
+  if(_type == GaussPointData){
     std::vector<double> &p(_steps[step]->getGaussPoints(e->getTypeForMSH()));
     if(p[0] == 1.e22){
       // hack: the points are the element vertices
@@ -354,7 +354,7 @@ int PViewDataGModel::getNode(int step, int ent, int ele, int nod,
   }
 }
 
-void PViewDataGModel::setNode(int step, int ent, int ele, int nod, 
+void PViewDataGModel::setNode(int step, int ent, int ele, int nod,
                               double x, double y, double z)
 {
   MVertex *v = _getElement(step, ent, ele)->getVertex(nod);
@@ -409,7 +409,7 @@ void PViewDataGModel::getValue(int step, int ent, int ele, int nod, int comp, do
 {
   MElement *e = _getElement(step, ent, ele);
   switch(_type){
-  case NodeData: 
+  case NodeData:
     val = _steps[step]->getData(e->getVertex(nod)->getNum())[comp];
     break;
   case ElementNodeData:
@@ -417,7 +417,7 @@ void PViewDataGModel::getValue(int step, int ent, int ele, int nod, int comp, do
     val = _steps[step]->getData(e->getNum())[_steps[step]->getNumComponents() * nod + comp];
     break;
   case ElementData:
-  default: 
+  default:
     val = _steps[step]->getData(e->getNum())[comp];
     break;
   }
@@ -427,22 +427,22 @@ void PViewDataGModel::setValue(int step, int ent, int ele, int nod, int comp, do
 {
   MElement *e = _getElement(step, ent, ele);
   switch(_type){
-  case NodeData: 
+  case NodeData:
     _steps[step]->getData(e->getVertex(nod)->getNum())[comp] = val;
     break;
   case ElementNodeData:
-  case GaussPointData: 
+  case GaussPointData:
     _steps[step]->getData(e->getNum())[_steps[step]->getNumComponents() * nod + comp] = val;
     break;
-  case ElementData: 
-  default: 
+  case ElementData:
+  default:
     _steps[step]->getData(e->getNum())[comp] = val;
     break;
   }
 }
 
 int PViewDataGModel::getNumEdges(int step, int ent, int ele)
-{ 
+{
   return _getElement(step, ent, ele)->getNumEdges();
 }
 
@@ -511,7 +511,7 @@ bool PViewDataGModel::combineTime(nameData &nd)
   }
 
   // copy interpolation matrices
-  for(std::map<int, std::vector<fullMatrix<double>*> >::iterator it = 
+  for(std::map<int, std::vector<fullMatrix<double>*> >::iterator it =
         data[0]->_interpolation.begin(); it != data[0]->_interpolation.end(); it++)
     if(_interpolation[it->first].empty())
       for(unsigned int i = 0; i < it->second.size(); i++)
@@ -522,7 +522,7 @@ bool PViewDataGModel::combineTime(nameData &nd)
     for(unsigned int j = 0; j < data[i]->_steps.size(); j++)
       if(data[i]->hasTimeStep(j))
         _steps.push_back(new stepData<double>(*data[i]->_steps[j]));
-  
+
   std::string tmp;
   if(nd.name == "__all__")
     tmp = "all";
diff --git a/Solver/dofManager.h b/Solver/dofManager.h
index e2a4f4886f..d4682c6915 100644
--- a/Solver/dofManager.h
+++ b/Solver/dofManager.h
@@ -82,7 +82,7 @@ class dofManager{
  public:
   typedef typename dofTraits<T>::VecType dataVec;
   typedef typename dofTraits<T>::MatType dataMat;
- private:
+ protected:
   // general affine constraint on sub-blocks, treated by adding
   // equations:
 
@@ -301,7 +301,7 @@ class dofManager{
     }
   }
 
-  inline void assemble(std::vector<Dof> &R, const fullVector<dataMat> &m) // for linear forms
+  virtual inline void assemble(std::vector<Dof> &R, const fullVector<dataMat> &m) // for linear forms
   {
     if (!_current->isAllocated()) _current->allocate(unknown.size());
     std::vector<int> NR(R.size());
@@ -335,7 +335,7 @@ class dofManager{
   }
 
 
-  inline void assemble(std::vector<Dof> &R, const fullMatrix<dataMat> &m)
+  virtual inline void assemble(std::vector<Dof> &R, const fullMatrix<dataMat> &m)
   {
     if (!_current->isAllocated()) _current->allocate(unknown.size());
     std::vector<int> NR(R.size());
@@ -487,6 +487,13 @@ class dofManager{
       }
     }
   }
-
+  void getFixedDof(std::vector<Dof> &R){
+    R.reserve(fixed.size());
+    std::map<Dof, double>::iterator it; // template problem ?? //TODO
+    for(it=fixed.begin(); it!=fixed.end();++it){
+      R.push_back((*it).first);
+    }
+  }
 };
+
 #endif
diff --git a/Solver/linearSystem.h b/Solver/linearSystem.h
index 5ff9c10a14..bec6ac2bd4 100644
--- a/Solver/linearSystem.h
+++ b/Solver/linearSystem.h
@@ -27,6 +27,7 @@ class linearSystem {
   virtual void zeroRightHandSide() = 0;
   virtual int systemSolve() = 0;
   static void registerBindings (binding*);
+  virtual double normInfRightHandSide() const = 0;
 };
 
 #endif
diff --git a/Solver/linearSystemCSR.h b/Solver/linearSystemCSR.h
index 5e9f325a35..a83561e326 100644
--- a/Solver/linearSystemCSR.h
+++ b/Solver/linearSystemCSR.h
@@ -13,7 +13,7 @@
 
 class binding;
 
-typedef int INDEX_TYPE ;  
+typedef int INDEX_TYPE ;
 typedef struct {
   int nmax;
   int size;
@@ -22,7 +22,7 @@ typedef struct {
   int isorder;
   char *array;
 } CSRList_T;
-  
+
 void CSRList_Add(CSRList_T *liste, const void *data);
 int  CSRList_Nbr(CSRList_T *liste);
 
@@ -31,7 +31,7 @@ class linearSystemCSR : public linearSystem<scalar> {
  protected:
   bool sorted;
   char *something;
-  CSRList_T *_a, *_ai, *_ptr, *_jptr; 
+  CSRList_T *_a, *_ai, *_ptr, *_jptr;
   std::vector<scalar> *_b, *_x;
  public:
   linearSystemCSR()
@@ -52,9 +52,9 @@ class linearSystemCSR : public linearSystem<scalar> {
     INDEX_TYPE  *ptr   = (INDEX_TYPE*) _ptr->array;
     INDEX_TYPE  *ai    = (INDEX_TYPE*) _ai->array;
     scalar      *a     = ( scalar * ) _a->array;
-    
+
     INDEX_TYPE  position = jptr[il];
-    
+
     if(something[il]) {
       while(1){
         if(ai[position] == ic){
@@ -64,24 +64,24 @@ class linearSystemCSR : public linearSystem<scalar> {
         if (ptr[position] == 0) break;
         position = ptr[position];
       }
-    }  
-    
+    }
+
     INDEX_TYPE zero = 0;
     CSRList_Add(_a, &val);
     CSRList_Add(_ai, &ic);
     CSRList_Add(_ptr, &zero);
     // The pointers may have been modified
-    // if there has been a reallocation in CSRList_Add  
-    
+    // if there has been a reallocation in CSRList_Add
+
     ptr = (INDEX_TYPE*) _ptr->array;
     ai  = (INDEX_TYPE*) _ai->array;
     a   = (scalar*) _a->array;
-    
+
     INDEX_TYPE n = CSRList_Nbr(_a) - 1;
-    
+
     if(!something[il]) {
       jptr[il] = n;
-      something[il] = 1;      
+      something[il] = 1;
     }
     else ptr[position] = n;
   }
@@ -91,11 +91,11 @@ class linearSystemCSR : public linearSystem<scalar> {
   {
     Msg::Error("getFromMatrix not implemented for CSR");
   }
-  virtual void addToRightHandSide(int row, const scalar &val) 
+  virtual void addToRightHandSide(int row, const scalar &val)
   {
     if(val != 0.0) (*_b)[row] += val;
   }
-  virtual void getFromRightHandSide(int row, scalar &val) const 
+  virtual void getFromRightHandSide(int row, scalar &val) const
   {
     val = (*_b)[row];
   }
@@ -109,10 +109,21 @@ class linearSystemCSR : public linearSystem<scalar> {
     scalar *a = (scalar*) _a->array;
     for (int i = 0; i < N; i++) a[i] = 0;
   }
-  virtual void zeroRightHandSide() 
+  virtual void zeroRightHandSide()
   {
     for(unsigned int i = 0; i < _b->size(); i++) (*_b)[i] = 0.;
   }
+  virtual double normInfRightHandSide() const{
+    double nor = 0.;
+    double temp;
+    for(int i=0;i<_b->size();i++){
+      temp = (*_b)[i];
+      if(temp<0) temp = -temp;
+      if(nor<temp) nor=temp;
+
+    }
+    return nor;
+  }
 };
 
 template <class scalar>
@@ -126,7 +137,7 @@ class linearSystemCSRGmm : public linearSystemCSR<scalar> {
   void setPrec(double p){ _prec = p; }
   void setNoisy(int n){ _noisy = n; }
   void setGmres(int n){ _gmres = n; }
-  virtual int systemSolve() 
+  virtual int systemSolve()
 #if !defined(HAVE_GMM)
   {
     Msg::Error("Gmm++ is not available in this version of Gmsh");
@@ -147,7 +158,7 @@ class linearSystemCSRTaucs : public linearSystemCSR<scalar> {
     if (il <= ic)
       linearSystemCSR<scalar>::addToMatrix(il, ic, val);
   }
-  virtual int systemSolve()     
+  virtual int systemSolve()
 #if !defined(HAVE_TAUCS)
   {
     Msg::Error("TAUCS is not available in this version of Gmsh");
diff --git a/Solver/linearSystemFull.h b/Solver/linearSystemFull.h
index 1c3cf865e4..eb8c17839b 100644
--- a/Solver/linearSystemFull.h
+++ b/Solver/linearSystemFull.h
@@ -54,15 +54,15 @@ class linearSystemFull : public linearSystem<scalar> {
   {
     if(val != 0.0) (*_b)(row) += val;
   }
-  virtual void getFromRightHandSide(int row, scalar &val) const 
+  virtual void getFromRightHandSide(int row, scalar &val) const
   {
     val = (*_b)(row);
   }
-  virtual void getFromSolution(int row, scalar &val) const 
+  virtual void getFromSolution(int row, scalar &val) const
   {
     val = (*_x)(row);
   }
-  virtual void zeroMatrix() 
+  virtual void zeroMatrix()
   {
     _a->setAll(0.);
   }
@@ -70,7 +70,17 @@ class linearSystemFull : public linearSystem<scalar> {
   {
     for(int i = 0; i < _b->size(); i++) (*_b)(i) = 0.;
   }
-  virtual int systemSolve() 
+  virtual double normInfRightHandSide() const{
+    double nor = 0.;
+    double temp;
+    for(int i=0;i<_b->size();i++){
+      temp = (*_b)(i);
+      if(temp<0) temp = -temp;
+      if(nor<temp) nor=temp;
+    }
+    return nor;
+  }
+  virtual int systemSolve()
   {
     if (_b->size())
       _a->luSolve(*_b, *_x);
diff --git a/Solver/linearSystemGMM.h b/Solver/linearSystemGMM.h
index 6198561a6a..8d8fabf5e6 100644
--- a/Solver/linearSystemGMM.h
+++ b/Solver/linearSystemGMM.h
@@ -47,7 +47,7 @@ class linearSystemGmm : public linearSystem<scalar> {
     _a = 0;
   }
 
-  virtual void  addToMatrix(int row, int col, const scalar &val) 
+  virtual void  addToMatrix(int row, int col, const scalar &val)
   {
     if(val != 0.0) (*_a)(row, col) += val;
   }
@@ -56,12 +56,12 @@ class linearSystemGmm : public linearSystem<scalar> {
     val = (*_a)(row, col);
   }
 
-  virtual void addToRightHandSide(int row, const scalar &val) 
+  virtual void addToRightHandSide(int row, const scalar &val)
   {
     if(val != 0.0) (*_b)[row] += val;
   }
 
-  virtual void getFromRightHandSide(int row, scalar &val) const 
+  virtual void getFromRightHandSide(int row, scalar &val) const
   {
     val = (*_b)[row];
   }
@@ -77,6 +77,17 @@ class linearSystemGmm : public linearSystem<scalar> {
   {
     for(unsigned int i = 0; i < _b->size(); i++) (*_b)[i] = 0.;
   }
+  virtual double normInfRightHandSide() const {
+    double nor = 0.;
+    double temp;
+    for(int i=0;i<_b->size();i++){
+      temp = (*_b)[i];
+      if(temp<0) temp = -temp;
+      if(nor<temp) nor=temp;
+    }
+    return nor;
+  }
+
   void setPrec(double p){ _prec = p; }
   void setNoisy(int n){ _noisy = n; }
   void setGmres(int n){ _gmres = n; }
diff --git a/Solver/linearSystemPETSc.h b/Solver/linearSystemPETSc.h
index 4097a529bd..32cc3b0d1c 100644
--- a/Solver/linearSystemPETSc.h
+++ b/Solver/linearSystemPETSc.h
@@ -56,7 +56,7 @@ class linearSystemPETSc : public linearSystem<scalar> {
   virtual void allocate(int nbRows)
   {
     clear();
-    _try(MatCreate(PETSC_COMM_WORLD, &_a)); 
+    _try(MatCreate(PETSC_COMM_WORLD, &_a));
     _try(MatSetSizes(_a, PETSC_DECIDE, PETSC_DECIDE, nbRows, nbRows));
     // override the default options with the ones from the option
     // database (if any)
@@ -105,6 +105,12 @@ class linearSystemPETSc : public linearSystem<scalar> {
 #else
     val = s;
 #endif
+  }
+  virtual double normInfRightHandSide() const {
+  PetscScalar nor;
+  _try(VecNorm(_b,NORM_INFINITY,&nor));
+  return nor;
+
   }
   virtual void addToMatrix(int row, int col, const scalar &val)
   {
@@ -185,7 +191,7 @@ class linearSystemPETSc : public linearSystem<scalar> {
   virtual void zeroMatrix() {}
   virtual void zeroRightHandSide() {}
   virtual int systemSolve() { return 0; }
-}; 
+};
 
 #endif
 
-- 
GitLab