From eee6f90888072c2df294f55bfb492da663468e39 Mon Sep 17 00:00:00 2001
From: Thomas Toulorge <thomas.toulorge@mines-paristech.fr>
Date: Tue, 21 May 2013 21:28:00 +0000
Subject: [PATCH] Fixed computeMetricIsoLinInterp and cleaned details in
 meshMetric

---
 Mesh/meshMetric.cpp | 151 +++++++++-----------------------------------
 Mesh/meshMetric.h   |   8 +--
 2 files changed, 35 insertions(+), 124 deletions(-)

diff --git a/Mesh/meshMetric.cpp b/Mesh/meshMetric.cpp
index ad9c500eba..4579566f7f 100644
--- a/Mesh/meshMetric.cpp
+++ b/Mesh/meshMetric.cpp
@@ -166,10 +166,7 @@ void meshMetric::exportInfo(const char * fileendname)
     for ( int i = 0; i < e->getNumVertices(); i++) {
       MVertex *ver = e->getVertex(i);
       out_ls << vals[ver];
-      SVector3 gradudx = dgrads[0][ver];
-      SVector3 gradudy = dgrads[1][ver];
-      SVector3 gradudz = dgrads[2][ver];
-      out_hess << (gradudx(0) + gradudy(1) + gradudz(2));
+      out_hess << (hessians[ver](0,0) + hessians[ver](1,1) + hessians[ver](2,2));
       if (i == (e->getNumVertices() - 1)){
         out_ls << "};" << std::endl;
         out_hess << "};" << std::endl;
@@ -184,7 +181,7 @@ void meshMetric::exportInfo(const char * fileendname)
         else out_grad << ",";
         for (int l=0;l<3;l++){
           out_metric << _nodalMetrics[ver](k,l);
-          out_hessmat << dgrads[k][ver](l);
+          out_hessmat << hessians[ver](k,l);
           if ((k == 2) && (l == 2) && (i == (e->getNumVertices() - 1))) {
             out_metric << "};" << std::endl;
             out_hessmat << "};" << std::endl;
@@ -315,9 +312,9 @@ void meshMetric::computeHessian()
     if (duNorm == 0. || _technique == meshMetric::HESSIAN ||
         _technique == meshMetric::EIGENDIRECTIONS || _technique == meshMetric::EIGENDIRECTIONS_LINEARINTERP_H) duNorm = 1.;
     grads[ver] = SVector3(dudx/duNorm,dudy/duNorm,dudz/duNorm);
-    dgrads[0][ver] = SVector3(d2udx2,d2udxy,d2udxz);
-    dgrads[1][ver] = SVector3(d2udxy,d2udy2,d2udyz);
-    dgrads[2][ver] = SVector3(d2udxz,d2udyz,d2udz2);
+    hessians[ver](0,0) = d2udx2; hessians[ver](0,1) = d2udxy; hessians[ver](0,2) = d2udxz;
+    hessians[ver](1,0) = d2udxy; hessians[ver](1,1) = d2udy2; hessians[ver](1,2) = d2udyz;
+    hessians[ver](2,0) = d2udxz; hessians[ver](2,1) = d2udyz; hessians[ver](2,2) = d2udz2;
   }
 }
 
@@ -325,16 +322,11 @@ void meshMetric::computeMetricLevelSet(MVertex *ver, SMetric3 &hessian,  SMetric
 {
 
   double signed_dist;
-  SVector3 gradudx, gradudy,gradudz, gr;
+  SVector3 gr;
   if(ver != NULL){
     signed_dist = vals[ver];
     gr = grads[ver];
-    gradudx = dgrads[0][ver];
-    gradudy = dgrads[1][ver];
-    gradudz = dgrads[2][ver];
-    hessian(0,0) = gradudx(0); hessian(0,1) = gradudx(1); hessian(0,2) = gradudx(2);
-    hessian(1,0) = gradudy(0); hessian(1,1) = gradudy(1); hessian(1,2) = gradudy(2);
-    hessian(2,0) = gradudz(0); hessian(2,1) = gradudz(1); hessian(2,2) = gradudz(2);
+    hessian = hessians[ver];
   }
   else if (ver == NULL){
     signed_dist = (*_fct)(x,y,z); 
@@ -380,15 +372,10 @@ void meshMetric::computeMetricLevelSet(MVertex *ver, SMetric3 &hessian,  SMetric
 void meshMetric::computeMetricHessian(MVertex *ver, SMetric3 &hessian,  SMetric3 &metric, double &size, double x, double y, double z)
 {
 
-  SVector3 gradudx, gradudy,gradudz,gr;
+  SVector3 gr;
   if(ver != NULL){
     gr = grads[ver];
-    gradudx = dgrads[0][ver];
-    gradudy = dgrads[1][ver];
-    gradudz = dgrads[2][ver];
-    hessian(0,0) = gradudx(0); hessian(0,1) = gradudx(1); hessian(0,2) = gradudx(2);
-    hessian(1,0) = gradudy(0); hessian(1,1) = gradudy(1); hessian(1,2) = gradudy(2);
-    hessian(2,0) = gradudz(0); hessian(2,1) = gradudz(1); hessian(2,2) = gradudz(2);
+    hessian = hessians[ver];
   }
   else if (ver == NULL){
     _fct->gradient(x,y,z,gr(0),gr(1),gr(2));
@@ -422,16 +409,11 @@ void meshMetric::computeMetricFrey(MVertex *ver, SMetric3 &hessian,  SMetric3 &m
 {
   
   double signed_dist;
-  SVector3 gradudx, gradudy,gradudz,gr;
+  SVector3 gr;
   if(ver != NULL){
     signed_dist = vals[ver];
     gr = grads[ver];
-    gradudx = dgrads[0][ver];
-    gradudy = dgrads[1][ver];
-    gradudz = dgrads[2][ver];
-    hessian(0,0) = gradudx(0); hessian(0,1) = gradudx(1); hessian(0,2) = gradudx(2);
-    hessian(1,0) = gradudy(0); hessian(1,1) = gradudy(1); hessian(1,2) = gradudy(2);
-    hessian(2,0) = gradudz(0); hessian(2,1) = gradudz(1); hessian(2,2) = gradudz(2);
+    hessian = hessians[ver];
   }
   else if (ver == NULL){
     signed_dist = (*_fct)(x,y,z); 
@@ -486,16 +468,11 @@ void meshMetric::computeMetricEigenDir(MVertex *ver, SMetric3 &hessian,  SMetric
 {
   
   double signed_dist;
-  SVector3 gradudx, gradudy,gradudz,gVec;
+  SVector3 gVec;
   if(ver != NULL){
     signed_dist = vals[ver];
     gVec = grads[ver];
-    gradudx = dgrads[0][ver];
-    gradudy = dgrads[1][ver];
-    gradudz = dgrads[2][ver];
-    hessian(0,0) = gradudx(0); hessian(0,1) = gradudx(1); hessian(0,2) = gradudx(2);
-    hessian(1,0) = gradudy(0); hessian(1,1) = gradudy(1); hessian(1,2) = gradudy(2);
-    hessian(2,0) = gradudz(0); hessian(2,1) = gradudz(1); hessian(2,2) = gradudz(2);
+    hessian = hessians[ver];
   }
   else if (ver == NULL){
     signed_dist = (*_fct)(x,y,z); 
@@ -589,16 +566,11 @@ void meshMetric::computeMetricIsoLinInterp(MVertex *ver, SMetric3 &hessian,  SMe
 {
 
   double signed_dist;
-  SVector3 gradudx, gradudy,gradudz,gr;
+  SVector3 gr;
   if(ver != NULL){
     signed_dist = vals[ver];
     gr = grads[ver];
-    gradudx = dgrads[0][ver];
-    gradudy = dgrads[1][ver];
-    gradudz = dgrads[2][ver];
-    hessian(0,0) = gradudx(0); hessian(0,1) = gradudx(1); hessian(0,2) = gradudx(2);
-    hessian(1,0) = gradudy(0); hessian(1,1) = gradudy(1); hessian(1,2) = gradudy(2);
-    hessian(2,0) = gradudz(0); hessian(2,1) = gradudz(1); hessian(2,2) = gradudz(2);
+    hessian = hessians[ver];
   }
   else if (ver == NULL){
     signed_dist = (*_fct)(x,y,z); 
@@ -610,75 +582,17 @@ void meshMetric::computeMetricIsoLinInterp(MVertex *ver, SMetric3 &hessian,  SMe
 
   double dist = fabs(signed_dist);
   double norm = gr.normalize();
-  double h_dist = (signed_dist < _E && signed_dist > _E_moins && norm != 0.0) ? hmin + ((hmax-hmin)/_E)*dist : hmax;  // the charcteristic element size in all directions - linear interp between hmin and hmax
-
-  double lambda = 1./h_dist/h_dist;
-  SMetric3 H;
-  H(0,0) = H(1,1) = lambda;
-  H(2,2) = (_dim == 3)? lambda : 1.;
-  
-  hessian = H;
-  size =  lambda;
-  
-}
-
-void meshMetric::computeMetricScaledHessian(MVertex *ver, SMetric3 &hessian,  SMetric3 &metric, double &size, double x, double y, double z)
-{
-
-  printf("Exit : computeMetricScaledHessian should be repaired  \n");
-  exit(1);
-
-  //   std::list<double> lambda1, lambda2, lambda3;
-  //   std::list<SVector3> t1, t2, t3;
-
-  //   // Compute and store eignvalues and eigenvectors of Hessian
-  //   SMetric3 H;
-  //   SVector3 gradudx = dgrads[0][ver];
-  //   SVector3 gradudy = dgrads[1][ver];
-  //   SVector3 gradudz = dgrads[2][ver];
-  //   hessian(0,0) = gradudx(0); hessian(0,1) = gradudx(1); hessian(0,2) = gradudx(2);
-  //   hessian(1,0) = gradudy(0); hessian(1,1) = gradudy(1); hessian(1,2) = gradudy(2);
-  //   hessian(2,0) = gradudz(0); hessian(2,1) = gradudz(1); hessian(2,2) = gradudz(2);
+  size = hmax;                      // the characteristic element size in all directions - linear interp between hmin and hmax
+  if (norm != 0.) {
+    if ((signed_dist >= 0) && (signed_dist < _E)) size = hmin + ((hmax-hmin)/_E)*dist;
+    else if ((signed_dist < 0) && (signed_dist > _E_moins)) size = hmin - ((hmax-hmin)/_E_moins)*dist;
+  }
   
-  //   fullMatrix<double> V(3,3);
-  //   fullVector<double> S(3);
-  //   hessian.eig(V,S);
-
-  //   lambda1.push_back(fabs(S(0)));
-  //   lambda2.push_back(fabs(S(1)));
-  //   if (_dim == 3) lambda3.push_back(fabs(S(2)));
+  double lambda = 1./size/size;
+  metric(0,0) = lambda; metric(0,1) = 0.; metric(0,2) = 0.;
+  metric(1,0) = 0.; metric(1,1) = lambda; metric(1,2) = 0.;
+  metric(2,0) = 0.; metric(2,1) = 0.; metric(2,2) = (_dim == 3)? lambda : 1.;
   
-  //   t1.push_back(SVector3(V(0,0),V(1,0),V(2,0)));
-  //   t2.push_back(SVector3(V(0,1),V(1,1),V(2,1)));
-  //   t3.push_back(SVector3(V(0,2),V(1,2),V(2,2)));
-
-  //   // Calculate scale factor based on max. eigenvalue and min. element length
-  //   const double maxLambda1 = *std::max_element(lambda1.begin(), lambda1.end());
-  //   const double maxLambda2 = *std::max_element(lambda2.begin(), lambda2.end());
-  //   double maxLambda;
-  //   if (_dim == 3) {
-  //     const double maxLambda3 = *std::max_element(lambda3.begin(),lambda3.end());
-  //     maxLambda = std::max(std::max(maxLambda1, maxLambda2), maxLambda3);
-  //   }
-  //   else maxLambda = std::max(maxLambda1, maxLambda2);
-  //   const double factor = 1./(hmin*hmin*maxLambda);
-
-  //   // Rescale metric
-  //   const double lMinBound = 1./(hmax*hmax);
-  //   std::list<double>::iterator itL1 = lambda1.begin(), itL2 = lambda2.begin(), itL3 = lambda3.begin();
-  //   std::list<SVector3>::iterator itT1 = t1.begin(), itT2 = t2.begin(), itT3 = t3.begin();
-  //   for (v2t_cont::iterator it=_adj.begin(); it!=_adj.end(); it++) {
-  //     MVertex *ver = it->first;
-  //     const double l1 = std::max(*itL1*factor, lMinBound);
-  //     const double l2 = std::max(*itL2*factor, lMinBound);
-  //     const double l3 = (_dim == 3) ? std::max(*itL3*factor, lMinBound) : 1.;
-  //     const double lMax = (_dim == 3) ? std::max(std::max(l1, l2), l3) : std::max(l1, l2);
-  //     metric = SMetric3(l1,l2,l3,*itT1,*itT2,*itT3);
-  //     size =  1./sqrt(lMax);
-  //     //    setOfDetMetric[metricNumber].insert(std::make_pair(ver,sqrt(metric.determinant())));
-  //     itL1++; itL2++; if (_dim == 3) itL3++;
-  //     itT1++; itT2++; itT3++;
-  //   }
 }
 
 
@@ -764,16 +678,14 @@ void meshMetric::computeMetric(int metricNumber)
     SMetric3 hessian, metric;
     double size;
     switch(_technique) {
-    case (LEVELSET) : computeMetricLevelSet(ver,hessian,metric,size); break;
-    case (HESSIAN) : computeMetricHessian(ver, hessian,metric, size); break;
-    case (FREY) : computeMetricFrey(ver, hessian,metric, size); break;
-    case (EIGENDIRECTIONS) : computeMetricEigenDir(ver, hessian,metric, size); break;
-    case (EIGENDIRECTIONS_LINEARINTERP_H) : computeMetricEigenDir(ver, hessian,metric,size); break;
-    case (ISOTROPIC_LINEARINTERP_H) : computeMetricIsoLinInterp(ver, hessian,metric,size); break;
-    case (SCALED_HESSIAN) : computeMetricScaledHessian(ver, hessian,metric, size); break;
+    case (LEVELSET) : computeMetricLevelSet(ver, hessian, metric, size); break;
+    case (HESSIAN) : computeMetricHessian(ver, hessian, metric, size); break;
+    case (FREY) : computeMetricFrey(ver, hessian, metric, size); break;
+    case (EIGENDIRECTIONS) : computeMetricEigenDir(ver, hessian, metric, size); break;
+    case (EIGENDIRECTIONS_LINEARINTERP_H) : computeMetricEigenDir(ver, hessian, metric,size); break;
+    case (ISOTROPIC_LINEARINTERP_H) : computeMetricIsoLinInterp(ver, hessian, metric, size); break;
     }
 
-    _hessian[ver] = hessian;
     setOfSizes[metricNumber].insert(std::make_pair(ver,size));
     setOfMetrics[metricNumber].insert(std::make_pair(ver,metric));
     
@@ -847,7 +759,6 @@ void meshMetric::operator() (double x, double y, double z, SMetric3 &metr, GEnti
 	case (EIGENDIRECTIONS) : computeMetricEigenDir(NULL, hessian,metric,size,x,y,z); break;
 	case (EIGENDIRECTIONS_LINEARINTERP_H) : computeMetricEigenDir(NULL, hessian,metric,size,x,y,z); break;
 	case (ISOTROPIC_LINEARINTERP_H) : computeMetricIsoLinInterp(NULL, hessian,metric,size,x,y,z); break;
-	case (SCALED_HESSIAN) : computeMetricScaledHessian(NULL, hessian,metric, size,x,y,z); break;
 	}
 	newSetOfMetrics[iMetric] = metric;
       }
@@ -921,7 +832,7 @@ void meshMetric::operator() (double x, double y, double z, SMetric3 &metr, GEnti
 
 double meshMetric::getLaplacian (MVertex *v) {
   MVertex *vNew = _vertexMap[v->getNum()];
-  std::map<MVertex*, SMetric3 >::const_iterator it = _hessian.find(vNew);
+  std::map<MVertex*, SMetric3 >::const_iterator it = hessians.find(vNew);
   SMetric3 h = it->second;
   return h(0,0)+h(1,1)+h(2,2);
 }
diff --git a/Mesh/meshMetric.h b/Mesh/meshMetric.h
index 5958d763c8..03a2f5313a 100644
--- a/Mesh/meshMetric.h
+++ b/Mesh/meshMetric.h
@@ -23,7 +23,7 @@ class STensor3;
 class meshMetric: public Field {
  public:
   typedef enum {LEVELSET=1,HESSIAN=2, FREY=3, EIGENDIRECTIONS=4, EIGENDIRECTIONS_LINEARINTERP_H=5,
-                ISOTROPIC_LINEARINTERP_H=6, SCALED_HESSIAN=7} MetricComputationTechnique;
+                ISOTROPIC_LINEARINTERP_H=6} MetricComputationTechnique;
  private:
   // intersect all metrics added in "setOfMetrics", preserve eigendirections of the "most anisotropic" metric
   void updateMetrics();
@@ -41,13 +41,14 @@ class meshMetric: public Field {
   std::map<int, MVertex*> _vertexMap;
 
   std::map<MVertex*,double> vals;
-  std::map<MVertex*,SVector3> grads,dgrads[3];
+  std::map<MVertex*,SVector3> grads;
+  std::map<MVertex*,SMetric3> hessians;
 
  public:
   typedef std::map<MVertex*,SMetric3> nodalMetricTensor;
   typedef std::map<MVertex*,double> nodalField;
  private:
-  nodalMetricTensor _nodalMetrics,_hessian;
+  nodalMetricTensor _nodalMetrics;
   nodalField _nodalSizes, _detMetric;
 
   std::map<int,nodalMetricTensor> setOfMetrics;
@@ -99,7 +100,6 @@ class meshMetric: public Field {
   void computeMetricFrey(MVertex *ver, SMetric3 &hessian,  SMetric3 &metric, double &size, double x=0.0, double y = 0.0, double z = 0.0);
   void computeMetricEigenDir(MVertex *ver, SMetric3 &hessian,  SMetric3 &metric, double &size, double x=0.0, double y = 0.0, double z = 0.0);
   void computeMetricIsoLinInterp(MVertex *ver, SMetric3 &hessian,  SMetric3 &metric, double &size, double x=0.0, double y = 0.0, double z = 0.0);
-  void computeMetricScaledHessian(MVertex *ver, SMetric3 &hessian,  SMetric3 &metric, double &size, double x=0.0, double y = 0.0, double z = 0.0);
 
   void computeValues();
   void computeHessian();
-- 
GitLab