ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/OpenMD/trunk/src/math/AlphaHull.cpp
(Generate patch)

Comparing trunk/src/math/AlphaHull.cpp (file contents):
Revision 1402 by chuckv, Fri Jan 8 17:15:27 2010 UTC vs.
Revision 2069 by gezelter, Thu Mar 5 16:30:23 2015 UTC

# Line 1 | Line 1
1 < /* Copyright (c) 2008, 2009, 2010 The University of Notre Dame. All Rights Reserved.
1 > /* Copyright (c) 2010 The University of Notre Dame. All Rights Reserved.
2   *
3   * The University of Notre Dame grants you ("Licensee") a
4   * non-exclusive, royalty free, license to use, modify and
# Line 32 | Line 32
32   * research, please cite the appropriate papers when you publish your
33   * work.  Good starting points are:
34   *                                                                      
35 < * [1]  Meineke, et al., J. Comp. Chem. 26, 252-271 (2005).            
36 < * [2]  Fennell & Gezelter, J. Chem. Phys. 124, 234104 (2006).          
37 < * [3]  Sun, Lin & Gezelter, J. Chem. Phys. 128, 24107 (2008).          
38 < * [4]  Vardeman & Gezelter, in progress (2009).                        
35 > * [1] Meineke, et al., J. Comp. Chem. 26, 252-271 (2005).            
36 > * [2] Fennell & Gezelter, J. Chem. Phys. 124, 234104 (2006).          
37 > * [3] Sun, Lin & Gezelter, J. Chem. Phys. 128, 234107 (2008).          
38 > * [4] Kuang & Gezelter,  J. Chem. Phys. 133, 164101 (2010).
39 > * [5] Vardeman, Stocker & Gezelter, J. Chem. Theory Comput. 7, 834 (2011).
40   *
40 *
41   *  AlphaHull.cpp
42   *
43 < *  Purpose: To calculate Alpha hull, hull volume libqhull.
44 < *
45 < *  Created by Charles F. Vardeman II on 11 Dec 2006.
46 < *  @author  Charles F. Vardeman II
47 < *  @version $Id: ConvexHull.cpp,v 1.21 2009-11-25 20:02:01 gezelter Exp $
48 < *
43 > *  Purpose: To calculate an alpha-shape hull.
44   */
45  
46 + #ifdef IS_MPI
47 + #include <mpi.h>
48 + #endif
49 +
50   /* Standard includes independent of library */
51  
52   #include <iostream>
# Line 55 | Line 54
54   #include <list>
55   #include <algorithm>
56   #include <iterator>
58 #include <utility>
57   #include "math/AlphaHull.hpp"
58   #include "utils/simError.h"
59  
60 < #ifdef IS_MPI
63 < #include <mpi.h>
64 < #endif
60 > #include "math/qhull.hpp"
61  
62 + #ifdef HAVE_QHULL
63 + using namespace std;
64   using namespace OpenMD;
65  
66 < #ifdef HAVE_QHULL
69 < extern "C"
70 < {
71 < #include <qhull/qhull.h>
72 < #include <qhull/mem.h>
73 < #include <qhull/qset.h>
74 < #include <qhull/geom.h>
75 < #include <qhull/merge.h>
76 < #include <qhull/poly.h>
77 < #include <qhull/io.h>
78 < #include <qhull/stat.h>
79 < }
80 < double calculate_circumradius(pointT* p0,pointT* p1,pointT* p2, int dim);
66 > double calculate_circumradius(pointT* p0, pointT* p1, pointT* p2, int dim);
67  
68 < AlphaHull::AlphaHull(double alpha) : Hull(), dim_(3), alpha_(alpha), options_("qhull d QJ Tcv ") {
68 > AlphaHull::AlphaHull(double alpha) : Hull(), dim_(3), alpha_(alpha),
69 >                                     options_("qhull d QJ Tcv Pp") {
70   }
71  
72 < void AlphaHull::computeHull(std::vector<StuntDouble*> bodydoubles) {
72 > void AlphaHull::computeHull(vector<StuntDouble*> bodydoubles) {
73  
74    int numpoints = bodydoubles.size();
88  bool alphashape=true;
75    
76    Triangles_.clear();
77    
78 <  vertexT *vertex, **vertexp;
78 >  vertexT *vertex;
79    facetT *facet, *neighbor;
80 <  setT *vertices;
80 >  pointT *interiorPoint;
81    int curlong, totlong;
82    
83 <  std::vector<double> ptArray(numpoints*dim_);
84 <
83 >  
84 >  vector<double> ptArray(numpoints*dim_);
85 >  
86    // Copy the positon vector into a points vector for qhull.
87 <  std::vector<StuntDouble*>::iterator SD;
87 >  vector<StuntDouble*>::iterator SD;
88    int i = 0;
89    for (SD =bodydoubles.begin(); SD != bodydoubles.end(); ++SD){
90      Vector3d pos = (*SD)->getPos();      
# Line 106 | Line 93 | void AlphaHull::computeHull(std::vector<StuntDouble*>
93      ptArray[dim_ * i + 2] = pos.z();
94      i++;
95    }
96 <
97 <    /* Clean up memory from previous convex hull calculations*/
96 >  
97 >  /* Clean up memory from previous convex hull calculations*/
98    boolT ismalloc = False;
99 <
100 <  int ridgesCount=0;
99 >  
100 >  /* compute the hull for our local points (or all the points for single
101 >     processor versions) */
102    if (qh_new_qhull(dim_, numpoints, &ptArray[0], ismalloc,
103                     const_cast<char *>(options_.c_str()), NULL, stderr)) {
104 <
104 >    
105      sprintf(painCave.errMsg, "AlphaHull: Qhull failed to compute convex hull");
106      painCave.isFatal = 1;
107      simError();
108      
109    } //qh_new_qhull
110 <
111 <
110 >  
111 >  
112   #ifdef IS_MPI
113    //If we are doing the mpi version, set up some vectors for data communication
114    
115 <  int nproc = MPI::COMM_WORLD.Get_size();
116 <  int myrank = MPI::COMM_WORLD.Get_rank();
115 >  int nproc;
116 >  int myrank;
117 >  MPI_Comm_size( MPI_COMM_WORLD, &nproc);
118 >  MPI_Comm_rank( MPI_COMM_WORLD, &myrank);
119 >
120    int localHullSites = 0;
121  
122 <  std::vector<int> hullSitesOnProc(nproc, 0);
123 <  std::vector<int> coordsOnProc(nproc, 0);
124 <  std::vector<int> displacements(nproc, 0);
125 <  std::vector<int> vectorDisplacements(nproc, 0);
122 >  vector<int> hullSitesOnProc(nproc, 0);
123 >  vector<int> coordsOnProc(nproc, 0);
124 >  vector<int> displacements(nproc, 0);
125 >  vector<int> vectorDisplacements(nproc, 0);
126  
127 <  std::vector<double> coords;
128 <  std::vector<double> vels;
129 <  std::vector<int> indexMap;
130 <  std::vector<double> masses;
127 >  vector<double> coords;
128 >  vector<double> vels;
129 >  vector<int> indexMap;
130 >  vector<double> masses;
131  
132    FORALLvertices{
133      localHullSites++;
134      
135      int idx = qh_pointid(vertex->point);
136 <
136 >    
137      indexMap.push_back(idx);
138  
139      coords.push_back(ptArray[dim_  * idx]);
# Line 159 | Line 150 | void AlphaHull::computeHull(std::vector<StuntDouble*>
150      masses.push_back(sd->getMass());
151    }
152  
153 <  MPI::COMM_WORLD.Allgather(&localHullSites, 1, MPI::INT, &hullSitesOnProc[0],
154 <                            1, MPI::INT);
153 >  MPI_Allgather(&localHullSites, 1, MPI_INT, &hullSitesOnProc[0],
154 >                1, MPI_INT, MPI_COMM_WORLD);
155  
156    int globalHullSites = 0;
157    for (int iproc = 0; iproc < nproc; iproc++){
# Line 176 | Line 167 | void AlphaHull::computeHull(std::vector<StuntDouble*>
167      vectorDisplacements[iproc] = vectorDisplacements[iproc-1] + coordsOnProc[iproc-1];
168    }
169  
170 <  std::vector<double> globalCoords(dim_ * globalHullSites);
171 <  std::vector<double> globalVels(dim_ * globalHullSites);
172 <  std::vector<double> globalMasses(globalHullSites);
170 >  vector<double> globalCoords(dim_ * globalHullSites);
171 >  vector<double> globalVels(dim_ * globalHullSites);
172 >  vector<double> globalMasses(globalHullSites);
173  
174    int count = coordsOnProc[myrank];
175    
176 <  MPI::COMM_WORLD.Allgatherv(&coords[0], count, MPI::DOUBLE, &globalCoords[0],
177 <                             &coordsOnProc[0], &vectorDisplacements[0],
178 <                             MPI::DOUBLE);
179 <
180 <  MPI::COMM_WORLD.Allgatherv(&vels[0], count, MPI::DOUBLE, &globalVels[0],
181 <                             &coordsOnProc[0], &vectorDisplacements[0],
182 <                             MPI::DOUBLE);
183 <
184 <  MPI::COMM_WORLD.Allgatherv(&masses[0], localHullSites, MPI::DOUBLE,
185 <                             &globalMasses[0], &hullSitesOnProc[0],
186 <                             &displacements[0], MPI::DOUBLE);
187 <
176 >  MPI_Allgatherv(&coords[0], count, MPI_DOUBLE, &globalCoords[0],
177 >                 &coordsOnProc[0], &vectorDisplacements[0],
178 >                 MPI_DOUBLE, MPI_COMM_WORLD);
179 >  
180 >  MPI_Allgatherv(&vels[0], count, MPI_DOUBLE, &globalVels[0],
181 >                 &coordsOnProc[0], &vectorDisplacements[0],
182 >                 MPI_DOUBLE, MPI_COMM_WORLD);
183 >  
184 >  MPI_Allgatherv(&masses[0], localHullSites, MPI_DOUBLE,
185 >                 &globalMasses[0], &hullSitesOnProc[0],
186 >                 &displacements[0], MPI_DOUBLE, MPI_COMM_WORLD);
187 >  
188    // Free previous hull
189    qh_freeqhull(!qh_ALL);
190    qh_memfreeshort(&curlong, &totlong);
191 <  if (curlong || totlong)
192 <    std::cerr << "qhull internal warning (main): did not free %d bytes of long memory (%d pieces) "
193 <              << totlong << curlong << std::endl;
191 >  if (curlong || totlong) {
192 >    sprintf(painCave.errMsg, "AlphaHull: qhull internal warning:\n"
193 >            "\tdid not free %d bytes of long memory (%d pieces)",
194 >            totlong, curlong);
195 >    painCave.isFatal = 1;
196 >    simError();
197 >  }
198    
199    if (qh_new_qhull(dim_, globalHullSites, &globalCoords[0], ismalloc,
200                     const_cast<char *>(options_.c_str()), NULL, stderr)){
201      
202 <    sprintf(painCave.errMsg, "AlphaHull: Qhull failed to compute global convex hull");
202 >    sprintf(painCave.errMsg,
203 >            "AlphaHull: Qhull failed to compute global convex hull");
204      painCave.isFatal = 1;
205      simError();
206 <    
206 >        
207    } //qh_new_qhull
208  
213
209   #endif
210  
211    //Set facet->center as the Voronoi center
212    qh_setvoronoi_all();
213    
214    
215 <  int convexNumVert = qh_setsize(qh_facetvertices (qh facet_list, NULL, false));
216 <  //Insert all the sample points, because, even with alpha=0, the alpha shape/alpha complex will
217 <  //contain them.
215 >  // int convexNumVert = qh_setsize(qh_facetvertices (qh facet_list, NULL, false));
216 >  //Insert all the sample points, because, even with alpha=0, the
217 >  //alpha shape/alpha complex will contain them.
218  
219    //  tri::Allocator<CMeshO>::AddVertices(pm.cm,convexNumVert);
220    
# Line 242 | Line 237 | void AlphaHull::computeHull(std::vector<StuntDouble*>
237    
238    qh visit_id++;
239    int numFacets=0;
240 <  std::vector<std::vector <int> > facetlist;
240 >  vector<vector <int> > facetlist;
241 >  interiorPoint = qh interior_point;
242    FORALLfacet_(qh facet_list) {
243      numFacets++;
244      if (!facet->upperdelaunay) {
245 <      //For all facets (that are tetrahedrons)calculate the radius of the empty circumsphere considering
246 <      //the distance between the circumcenter and a vertex of the facet
245 >      //For all facets (that are tetrahedrons)calculate the radius of
246 >      //the empty circumsphere considering the distance between the
247 >      //circumcenter and a vertex of the facet
248        vertexT* vertex = (vertexT *)(facet->vertices->e[0].p);
249        double* center = facet->center;
250        double radius =  qh_pointdist(vertex->point,center,dim_);
251        
252        if (radius>alpha_) // if the facet is not good consider the ridges
253          {
254 <          //if calculating the alphashape, unmark the facet ('good' is used as 'marked').
254 >          //if calculating the alphashape, unmark the facet ('good' is
255 >          //used as 'marked').
256            facet->good=false;
257            
258 <          //Compute each ridge (triangle) once and test the cironference radius with alpha
258 >          //Compute each ridge (triangle) once and test the
259 >          //cironference radius with alpha
260            facet->visitid= qh visit_id;
261            qh_makeridges(facet);
262            ridgeT *ridge, **ridgep;
# Line 280 | Line 279 | void AlphaHull::computeHull(std::vector<StuntDouble*>
279              }
280            }
281  
282 <          //If calculating the alphashape, mark the facet('good' is used as 'marked').
283 <          //This facet will have some triangles hidden by the facet's neighbor.
282 >          //If calculating the alphashape, mark the facet('good' is
283 >          //used as 'marked').  This facet will have some triangles
284 >          //hidden by the facet's neighbor.
285            if(goodTriangles==4)
286              facet->good=true;
287            
288          }
289 <      else //the facet is good. Put all the triangles of the tetrahedron in the mesh
289 >      else //the facet is good. Put all the triangles of the
290 >           //tetrahedron in the mesh
291          {
292            //Compute each ridge (triangle) once
293            facet->visitid= qh visit_id;
294 <          //If calculating the alphashape, mark the facet('good' is used as 'marked').
295 <          //This facet will have some triangles hidden by the facet's neighbor.
294 >          //If calculating the alphashape, mark the facet('good' is
295 >          //used as 'marked').  This facet will have some triangles
296 >          //hidden by the facet's neighbor.
297            facet->good=true;
298            qh_makeridges(facet);
299            ridgeT *ridge, **ridgep;
# Line 306 | Line 308 | void AlphaHull::computeHull(std::vector<StuntDouble*>
308    }
309    //assert(numFacets== qh num_facets);
310    
311 <  //Filter the triangles (only the ones on the boundary of the alpha complex) and build the mesh
311 >  //Filter the triangles (only the ones on the boundary of the alpha
312 >  //complex) and build the mesh
313 >
314 >  int ridgesCount=0;
315    
316    ridgeT *ridge, **ridgep;
317    FOREACHridge_(set) {
# Line 319 | Line 324 | void AlphaHull::computeHull(std::vector<StuntDouble*>
324        // Vector3d V3dNormal(facet->normal[0], facet->normal[1], facet->normal[2]);
325        //face.setNormal(V3dNormal);
326        
322      // RealType faceArea = qh_facetarea(facet);
323      //face.setArea(faceArea);
327        
328 <      //vertices = qh_facet3vertex(facet);
329 <      
327 <      //coordT *center = qh_getcenter(vertices);
328 >      //coordT *center = qh_getcenter(ridge->vertices);
329 >      //cout << "Centers are " << center[0] << "  " <<center[1] << "  " << center[2] << endl;
330        //Vector3d V3dCentroid(center[0], center[1], center[2]);
331        //face.setCentroid(V3dCentroid);
332 +
333        
334 <      //Vector3d faceVel = V3Zero;
334 >      Vector3d faceVel = V3Zero;
335        Vector3d p[3];
336 <      //RealType faceMass = 0.0;
336 >      RealType faceMass = 0.0;
337        
338        int ver = 0;
339 <      std::vector<int> virtexlist;
339 >      vector<int> virtexlist;
340        FOREACHvertex_i_(ridge->vertices){
341          int id = qh_pointid(vertex->point);
342          p[ver][0] = vertex->point[0];
# Line 343 | Line 346 | void AlphaHull::computeHull(std::vector<StuntDouble*>
346          RealType mass;
347          ver++;
348          virtexlist.push_back(id);
349 <      }
347 <      facetlist.push_back(virtexlist);
349 >        // cout << "Ridge: " << ridgesCount << " Vertex " << id << endl;
350  
351 +        vel = bodydoubles[id]->getVel();
352 +        mass = bodydoubles[id]->getMass();
353 +        face.addVertexSD(bodydoubles[id]);
354 +
355 +
356 +        faceVel = faceVel + vel;
357 +        faceMass = faceMass + mass;
358 +      } //FOREACH Vertex
359 +      facetlist.push_back(virtexlist);
360 +      face.addVertices(p[0],p[1],p[2]);
361 +      face.setFacetMass(faceMass);
362 +      face.setFacetVelocity(faceVel / RealType(3.0));
363 +      
364 +      RealType area = face.getArea();
365 +      area_ += area;
366 +      Vector3d normal = face.getUnitNormal();
367 +      // RealType offset =  ((0.0-p[0][0])*normal[0] + (0.0-p[0][1])*normal[1] + (0.0-p[0][2])*normal[2]);
368 +      RealType dist =  normal[0] * interiorPoint[0] + normal[1]*interiorPoint[1] + normal[2]*interiorPoint[2];
369 +      volume_ += dist *area/qh hull_dim;
370 +      
371 +      Triangles_.push_back(face);
372      }
373    }
351                
374  
353 //assert(pm.cm.fn == ridgesCount);
375  
376 + //assert(pm.cm.fn == ridgesCount);
377 + /*
378    std::cout <<"OFF"<<std::endl;
379    std::cout << bodydoubles.size() << "  " << facetlist.size() << "  " << 3*facetlist.size() << std::endl;
380    for (SD =bodydoubles.begin(); SD != bodydoubles.end(); ++SD){
# Line 370 | Line 393 | void AlphaHull::computeHull(std::vector<StuntDouble*>
393      }
394      std::cout << std::endl;
395    }
396 + */
397  
398  
399  
376
400   /*  
401    FORALLfacets {  
402      Triangle face;
# Line 438 | Line 461 | void AlphaHull::computeHull(std::vector<StuntDouble*>
461  
462    } //FORALLfacets
463   */
464 <  qh_getarea(qh facet_list);
465 <  volume_ = qh totvol;
466 <  area_ = qh totarea;
464 >  // qh_getarea(qh facet_list);
465 >  //volume_ = qh totvol;
466 >  // area_ = qh totarea;
467  
468    qh_freeqhull(!qh_ALL);
469    qh_memfreeshort(&curlong, &totlong);
470 <  if (curlong || totlong)
471 <    std::cerr << "qhull internal warning (main): did not free %d bytes of long memory (%d pieces) "
472 <              << totlong << curlong << std::endl;    
470 >  if (curlong || totlong) {
471 >    sprintf(painCave.errMsg, "AlphaHull: qhull internal warning:\n"
472 >            "\tdid not free %d bytes of long memory (%d pieces)",
473 >            totlong, curlong);
474 >    painCave.isFatal = 1;
475 >    simError();
476 >  }
477   }
478  
479 < void AlphaHull::printHull(const std::string& geomFileName) {
480 <
479 > void AlphaHull::printHull(const string& geomFileName) {
480 >  
481   #ifdef IS_MPI
482    if (worldRank == 0)  {
483   #endif
484 <  FILE *newGeomFile;
485 <  
486 <  //create new .md file based on old .md file
487 <  newGeomFile = fopen(geomFileName.c_str(), "w");
488 <  qh_findgood_all(qh facet_list);
489 <  for (int i = 0; i < qh_PRINTEND; i++)
490 <    qh_printfacets(newGeomFile, qh PRINTout[i], qh facet_list, NULL, !qh_ALL);
491 <  
492 <  fclose(newGeomFile);
484 >    FILE *newGeomFile;
485 >    
486 >    //create new .md file based on old .md file
487 >    newGeomFile = fopen(geomFileName.c_str(), "w");
488 >    qh_findgood_all(qh facet_list);
489 >    for (int i = 0; i < qh_PRINTEND; i++)
490 >      qh_printfacets(newGeomFile, qh PRINTout[i], qh facet_list, NULL, !qh_ALL);
491 >    
492 >    fclose(newGeomFile);
493   #ifdef IS_MPI
494    }
495   #endif  

Comparing trunk/src/math/AlphaHull.cpp (property svn:keywords):
Revision 1402 by chuckv, Fri Jan 8 17:15:27 2010 UTC vs.
Revision 2069 by gezelter, Thu Mar 5 16:30:23 2015 UTC

# Line 0 | Line 1
1 + Author Id Revision Date

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines