From 539fdb6d9f0541a273fa9026b354614ecf169dea Mon Sep 17 00:00:00 2001
From: Jean-Francois Remacle <jean-francois.remacle@uclouvain.be>
Date: Fri, 9 Oct 2009 20:43:31 +0000
Subject: [PATCH] *** empty log message ***

---
 Numeric/cartesian.cpp |  51 +++++++++++
 Numeric/cartesian.h   | 192 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 243 insertions(+)
 create mode 100644 Numeric/cartesian.cpp
 create mode 100644 Numeric/cartesian.h

diff --git a/Numeric/cartesian.cpp b/Numeric/cartesian.cpp
new file mode 100644
index 0000000000..439e23c018
--- /dev/null
+++ b/Numeric/cartesian.cpp
@@ -0,0 +1,51 @@
+#include "GmshConfig.h"
+#include "cartesian.h"
+
+#if defined(HAVE_ANN)
+#include "ANN/ANN.h"
+class hiddenANN{
+public: 
+  ANNkd_tree *kdtree;
+  ANNpointArray zeronodes;
+  ANNidxArray index;
+  ANNdistArray dist;
+};
+
+template <>
+double cartesianBox<double>::distance (double x, double y, double z) const{
+  if (!_ann){
+    _ann = new hiddenANN;
+    _ann->index = new ANNidx[2];
+    _ann->dist = new ANNdist[2];
+    if(_points.size())
+      _ann->zeronodes = annAllocPts(_points.size(), 4);
+    for (int i=0;i<_points.size();i++){
+      _ann->zeronodes[i][0] = _points[i].x(); 
+      _ann->zeronodes[i][1] = _points[i].y(); 
+      _ann->zeronodes[i][2] = _points[i].z(); 
+    }
+    _ann->kdtree = new ANNkd_tree(_ann->zeronodes, _points.size(), 3);
+  }
+  double xyz[3] = { x, y, z };
+  _ann->kdtree->annkSearch(xyz, 1, _ann->index, _ann->dist);
+  SVector3 n1  = _normals[_ann->index[0]];
+  //  SVector3 n2  = _normals[_ann->index[1]];
+  SVector3 dx1 = SPoint3(x,y,z) - _points[_ann->index[0]];
+  //  SVector3 dx2 = SPoint3(x,y,z) - _points[_ann->index[1]];
+  double d1 = sqrt(_ann->dist[0]);
+  //  double d2 = sqrt(_ann->dist[1]);
+  double sign1 = dot(n1,dx1) > 0 ? 1. : -1.0;
+  //  double sign2 = dot(n2,dx2) > 0 ? 1. : -1.0;
+  //  if (fabs(d1-d2) > 1.e-4 * _dxi/((double)_Nxi)){
+  return sign1 * d1;
+    //  }
+    //  return (sign1 != sign2) ? d1 : sign1 *d1;
+}
+#else
+template <>
+double cartesianBox<double>::distance (double x, double y, double z) const{
+  printf("youpiiie\n");
+  return 0.0;
+}
+#endif
+
diff --git a/Numeric/cartesian.h b/Numeric/cartesian.h
new file mode 100644
index 0000000000..f2877aff6e
--- /dev/null
+++ b/Numeric/cartesian.h
@@ -0,0 +1,192 @@
+#ifndef _CARTESIAN_H_
+#define _CARTESIAN_H_
+
+#include <set>
+#include <map>
+#include <vector>
+#include <stdio.h>
+#include "SVector3.h"
+#include "SPoint3.h"
+// this is a cartesian mesh that encompasses
+// an oriented box with _NX x _NY x _NZ hexaderal 
+// cells
+
+/*             j
+   +---+---+---+---+---+---+
+   |   |   |   |ij |   |   |
+ i +---+---+---+---+---+---+
+   |   |   |   |   |   |   |
+   +---+---+---+---+---+---+
+
+   cell ij -> nodes i;j , i+i;j , i+1;j+1, i;j+1
+   
+   active = CELLS : store i+N*j
+
+*/
+
+class hiddenANN;
+
+template <class scalar>
+class cartesianBox {
+  mutable hiddenANN *_ann;
+public:
+  typedef int INDEXTYPE;
+private:  
+  int _Nxi, _Neta, _Nzeta;  
+  std::set<INDEXTYPE> _active;
+  double _X,_Y,_Z,_dxi,_deta,_dzeta;
+  SVector3 _xiAxis,_etaAxis,_zetaAxis;
+  std::map<INDEXTYPE,scalar> _nodal_values;
+  std::vector<SVector3> _normals;
+  std::vector<SPoint3> _points;
+ public:
+  std::vector<SPoint3> & points() {return _points;}
+  std::vector<SVector3> & normals() {return _normals;}
+  
+  cartesianBox (double X, double Y, double Z, 
+		const SVector3 &DXI, 
+		const SVector3 &DETA, 
+		const SVector3 &DZETA, 
+		int NXI, int NETA, int NZETA)
+    : _ann(0),_X(X), _Y(Y), _Z(Z), 
+      _dxi(norm(DXI)), 
+      _deta(norm(DETA)),
+      _dzeta(norm(DZETA)),
+      _xiAxis(DXI),
+      _etaAxis(DETA),
+      _zetaAxis(DZETA),
+      _Nxi(NXI), _Neta(NETA), _Nzeta(NZETA) 
+  {
+    _xiAxis.normalize();
+    _etaAxis.normalize();
+    _zetaAxis.normalize();
+  }  
+
+  typename std::map<INDEXTYPE,scalar>::const_iterator begin() const {return _nodal_values.begin();}
+  typename std::map<INDEXTYPE,scalar>::const_iterator ens() const {return _nodal_values.endn();}
+
+  // add that in the ann search tool
+  void insert_point (double x, double y, double z){
+    _points.push_back(SPoint3(x,y,z));
+  }    
+  // compute distance
+  double distance (double x, double y, double z) const;
+  
+  inline INDEXTYPE index_of_element (double x, double y, double z) const{
+    
+    // P = P_0 + xi * _vdx + eta * _vdy + zeta *vdz
+    // DP = P-P_0 * _vdx = xi
+    SVector3 DP (x-_X,y-_Y,z-_Z);
+
+    const double xi   = dot(DP,_xiAxis);
+    const double eta  = dot(DP,_etaAxis);
+    const double zeta = dot(DP,_zetaAxis);
+    
+    const int i = xi/_dxi * _Nxi;
+    const int j = eta/_deta * _Neta;
+    const int k = zeta/_dzeta * _Nzeta;
+
+    return element_index(i,j,k);
+  }
+
+  inline SPoint3 coordinates_of_node (const INDEXTYPE &t) const{
+    int i,j,k;
+    node_ijk(t,i,j,k);
+
+    //    SVector3 DP (x-_X,y-_Y,z-_Z);
+
+    const double xi   = i*_dxi/_Nxi;
+    const double eta  = j*_deta/_Neta;
+    const double zeta = k*_dzeta/_Nzeta;
+
+    // printf("index %d -> %d %d %d xi %g %g %g X %g %g %g N %d %d %d D %g %g %g\n",
+    //	   t,i,j,k,xi,eta,zeta,_X,_Y,_Z,_Nxi,_Neta,_Nzeta,_dxi,_deta,_dzeta);
+    
+    SVector3 D = xi * _xiAxis  + eta * _etaAxis + zeta * _zetaAxis;
+    
+    return SPoint3(_X+D.x(),_Y+D.y(),_Z+D.z());
+  }
+
+  void insert (const INDEXTYPE &t){
+    _active.insert(t);
+  }
+  
+  inline INDEXTYPE element_index (int i, int j, int k) const {
+    return i + _Nxi * j + _Nxi *_Neta * k;
+  }
+  inline INDEXTYPE node_index (int i, int j, int k) const {
+    return i + (_Nxi+1) * j + (_Nxi+1) * (_Neta+1) * k;
+  }
+
+  inline void element_ijk (INDEXTYPE index, int &i, int &j, int &k) const {
+    k = index / (_Nxi *_Neta);
+    j = (index-k*(_Nxi *_Neta))/_Nxi;
+    i = (index-k*(_Nxi *_Neta)-j*_Nxi);
+  }
+  
+  inline void node_ijk (INDEXTYPE index, int &i, int &j, int &k) const {
+    k = index / ((_Nxi+1) *(_Neta+1));
+    j = (index-k*((_Nxi+1) *(_Neta+1)))/(_Nxi+1);
+    i = (index-k*((_Nxi+1) *(_Neta+1))-j*(_Nxi+1));
+  }
+  inline void create_nodes(){
+    std::set<INDEXTYPE>::const_iterator it = _active.begin();
+    for( ; it != _active.end() ; ++it){
+      const INDEXTYPE &t = *it;
+      int i,j,k;
+      element_ijk(t,i,j,k);
+      for (int I=0;I<2;I++)
+	for (int J=0;J<2;J++)
+	  for (int K=0;K<2;K++)
+	    _nodal_values[node_index(i+I,j+J,k+K)] = 0.0;
+    }
+  }
+  
+  void writeMSH (const std::string &filename) const {
+    FILE *f = fopen (filename.c_str(), "w");
+    fprintf(f,"$MeshFormat\n2.1 0 8\n$EndMeshFormat\n");
+
+    {
+      fprintf(f,"$Nodes\n%d\n",_nodal_values.size());
+      typename std::map<INDEXTYPE,scalar>::const_iterator it = _nodal_values.begin();
+      for ( ; it!=_nodal_values.end();++it){
+	SPoint3 p = coordinates_of_node(it->first);
+	fprintf(f,"%d %g %g %g\n",it->first,p.x(),p.y(),p.z());
+      }    
+      fprintf(f,"$EndNodes\n");
+    }
+    {
+      fprintf(f,"$Elements\n%d\n",_active.size());
+      std::set<INDEXTYPE>::const_iterator it = _active.begin();
+      for ( ; it!=_active.end();++it){
+	fprintf(f,"%d 5 3 1 1 1",*it);
+     	int i,j,k;
+	element_ijk(*it,i,j,k);
+	fprintf(f," %d",node_index(i,j,k));
+	fprintf(f," %d",node_index(i+1,j,k));
+	fprintf(f," %d",node_index(i+1,j+1,k));
+	fprintf(f," %d",node_index(i,j+1,k));
+	fprintf(f," %d",node_index(i,j,k+1));
+	fprintf(f," %d",node_index(i+1,j,k+1));
+	fprintf(f," %d",node_index(i+1,j+1,k+1));
+	fprintf(f," %d",node_index(i,j+1,k+1));
+	fprintf(f,"\n");
+      }    
+      fprintf(f,"$EndElements\n");    
+    }
+    {
+      fprintf(f,"$NodeData\n1\n\"distance\"\n 1\n 0.0\n3\n0\n 1\n %d\n",_nodal_values.size());
+      typename std::map<INDEXTYPE,scalar>::const_iterator it = _nodal_values.begin();
+      for ( ; it!=_nodal_values.end();++it){
+	SPoint3 p = coordinates_of_node(it->first);
+	fprintf(f,"%d %g\n",it->first,distance(p.x(),p.y(),p.z()));
+      }    
+      fprintf(f,"$EndNodeData\n");
+    }
+    fclose (f);
+  }
+
+};
+
+
+#endif
-- 
GitLab