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

Comparing branches/development/src/math/AlphaHull.cpp (file contents):
Revision 1850 by gezelter, Wed Feb 20 15:39:39 2013 UTC vs.
Revision 1858 by gezelter, Wed Apr 3 21:32:13 2013 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, 234107 (2008).          
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 < * [4] , Stocker & Gezelter, J. Chem. Theory Comput. 7, 834 (2011). *
39 > * [5] Vardeman, Stocker & Gezelter, J. Chem. Theory Comput. 7, 834 (2011).
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$
48 < *
43 > *  Purpose: To calculate an alpha-shape hull.
44   */
45  
46   /* Standard includes independent of library */
# Line 55 | Line 50
50   #include <list>
51   #include <algorithm>
52   #include <iterator>
58 #include <utility>
53   #include "math/AlphaHull.hpp"
54   #include "utils/simError.h"
55 +
56   #ifdef IS_MPI
57   #include <mpi.h>
58   #endif
59 +
60   #include "math/qhull.hpp"
61  
62 + #ifdef HAVE_QHULL
63 + using namespace std;
64   using namespace OpenMD;
65  
66 < #ifdef HAVE_QHULL
69 < 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 Pp") {
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();
77  // bool alphashape=true;
75    
76    Triangles_.clear();
77    
78    vertexT *vertex;
82  // vertexT **vertexp;
79    facetT *facet, *neighbor;
84  // setT *vertices, *verticestop, *verticesbottom;
85  int curlong, totlong;
80    pointT *interiorPoint;
81 +  int curlong, totlong;
82    
83 <  std::vector<double> ptArray(numpoints*dim_);
84 <
83 >  Vector3d boxMax;
84 >  Vector3d boxMin;
85 >  
86 >  vector<double> ptArray(numpoints*dim_);
87 >  
88    // Copy the positon vector into a points vector for qhull.
89 <  std::vector<StuntDouble*>::iterator SD;
89 >  vector<StuntDouble*>::iterator SD;
90    int i = 0;
91    for (SD =bodydoubles.begin(); SD != bodydoubles.end(); ++SD){
92      Vector3d pos = (*SD)->getPos();      
# Line 97 | Line 95 | void AlphaHull::computeHull(std::vector<StuntDouble*>
95      ptArray[dim_ * i + 2] = pos.z();
96      i++;
97    }
98 <
99 <    /* Clean up memory from previous convex hull calculations*/
98 >  
99 >  /* Clean up memory from previous convex hull calculations*/
100    boolT ismalloc = False;
101 <
102 <  int ridgesCount=0;
101 >  
102 >  /* compute the hull for our local points (or all the points for single
103 >     processor versions) */
104    if (qh_new_qhull(dim_, numpoints, &ptArray[0], ismalloc,
105                     const_cast<char *>(options_.c_str()), NULL, stderr)) {
106 <
106 >    
107      sprintf(painCave.errMsg, "AlphaHull: Qhull failed to compute convex hull");
108      painCave.isFatal = 1;
109      simError();
110      
111    } //qh_new_qhull
112 <
113 <
112 >  
113 >  
114   #ifdef IS_MPI
115    //If we are doing the mpi version, set up some vectors for data communication
116    
# Line 119 | Line 118 | void AlphaHull::computeHull(std::vector<StuntDouble*>
118    int myrank = MPI::COMM_WORLD.Get_rank();
119    int localHullSites = 0;
120  
121 <  std::vector<int> hullSitesOnProc(nproc, 0);
122 <  std::vector<int> coordsOnProc(nproc, 0);
123 <  std::vector<int> displacements(nproc, 0);
124 <  std::vector<int> vectorDisplacements(nproc, 0);
121 >  vector<int> hullSitesOnProc(nproc, 0);
122 >  vector<int> coordsOnProc(nproc, 0);
123 >  vector<int> displacements(nproc, 0);
124 >  vector<int> vectorDisplacements(nproc, 0);
125  
126 <  std::vector<double> coords;
127 <  std::vector<double> vels;
128 <  std::vector<int> indexMap;
129 <  std::vector<double> masses;
126 >  vector<double> coords;
127 >  vector<double> vels;
128 >  vector<int> indexMap;
129 >  vector<double> masses;
130  
131    FORALLvertices{
132      localHullSites++;
# Line 167 | Line 166 | void AlphaHull::computeHull(std::vector<StuntDouble*>
166      vectorDisplacements[iproc] = vectorDisplacements[iproc-1] + coordsOnProc[iproc-1];
167    }
168  
169 <  std::vector<double> globalCoords(dim_ * globalHullSites);
170 <  std::vector<double> globalVels(dim_ * globalHullSites);
171 <  std::vector<double> globalMasses(globalHullSites);
169 >  vector<double> globalCoords(dim_ * globalHullSites);
170 >  vector<double> globalVels(dim_ * globalHullSites);
171 >  vector<double> globalMasses(globalHullSites);
172  
173    int count = coordsOnProc[myrank];
174    
# Line 188 | Line 187 | void AlphaHull::computeHull(std::vector<StuntDouble*>
187    // Free previous hull
188    qh_freeqhull(!qh_ALL);
189    qh_memfreeshort(&curlong, &totlong);
190 <  if (curlong || totlong)
191 <    std::cerr << "qhull internal warning (main): did not free %d bytes of long memory (%d pieces) "
192 <              << totlong << curlong << std::endl;
190 >  if (curlong || totlong) {
191 >    sprintf(painCave.errMsg, "AlphaHull: qhull internal warning:\n"
192 >            "\tdid not free %d bytes of long memory (%d pieces)",
193 >            totlong, curlong);
194 >    painCave.isFatal = 1;
195 >    simError();
196 >  }
197    
198    if (qh_new_qhull(dim_, globalHullSites, &globalCoords[0], ismalloc,
199                     const_cast<char *>(options_.c_str()), NULL, stderr)){
200      
201 <    sprintf(painCave.errMsg, "AlphaHull: Qhull failed to compute global convex hull");
201 >    sprintf(painCave.errMsg,
202 >            "AlphaHull: Qhull failed to compute global convex hull");
203      painCave.isFatal = 1;
204      simError();
205 <    
205 >        
206    } //qh_new_qhull
207  
204
208   #endif
209  
210    //Set facet->center as the Voronoi center
# Line 233 | Line 236 | void AlphaHull::computeHull(std::vector<StuntDouble*>
236    
237    qh visit_id++;
238    int numFacets=0;
239 <  std::vector<std::vector <int> > facetlist;
239 >  vector<vector <int> > facetlist;
240    interiorPoint = qh interior_point;
241    FORALLfacet_(qh facet_list) {
242      numFacets++;
# Line 300 | Line 303 | void AlphaHull::computeHull(std::vector<StuntDouble*>
303    
304    //Filter the triangles (only the ones on the boundary of the alpha complex) and build the mesh
305  
306 <
306 >  int ridgesCount=0;
307    
308    ridgeT *ridge, **ridgep;
309    FOREACHridge_(set) {
# Line 315 | Line 318 | void AlphaHull::computeHull(std::vector<StuntDouble*>
318        
319        
320        //coordT *center = qh_getcenter(ridge->vertices);
321 <      //std::cout << "Centers are " << center[0] << "  " <<center[1] << "  " << center[2] << std::endl;
321 >      //cout << "Centers are " << center[0] << "  " <<center[1] << "  " << center[2] << endl;
322        //Vector3d V3dCentroid(center[0], center[1], center[2]);
323        //face.setCentroid(V3dCentroid);
324  
# Line 325 | Line 328 | void AlphaHull::computeHull(std::vector<StuntDouble*>
328        RealType faceMass = 0.0;
329        
330        int ver = 0;
331 <      std::vector<int> virtexlist;
331 >      vector<int> virtexlist;
332        FOREACHvertex_i_(ridge->vertices){
333          int id = qh_pointid(vertex->point);
334          p[ver][0] = vertex->point[0];
# Line 335 | Line 338 | void AlphaHull::computeHull(std::vector<StuntDouble*>
338          RealType mass;
339          ver++;
340          virtexlist.push_back(id);
341 <        // std::cout << "Ridge: " << ridgesCount << " Vertex " << id << std::endl;
341 >        // cout << "Ridge: " << ridgesCount << " Vertex " << id << endl;
342  
343          vel = bodydoubles[id]->getVel();
344          mass = bodydoubles[id]->getMass();
# Line 355 | Line 358 | void AlphaHull::computeHull(std::vector<StuntDouble*>
358        Vector3d normal = face.getUnitNormal();
359        RealType offset =  ((0.0-p[0][0])*normal[0] + (0.0-p[0][1])*normal[1] + (0.0-p[0][2])*normal[2]);
360        RealType dist =  normal[0] * interiorPoint[0] + normal[1]*interiorPoint[1] + normal[2]*interiorPoint[2];
361 <      std::cout << "Dist and normal and area are: " << normal << std::endl;
361 >     cout << "Dist and normal and area are: " << normal << endl;
362        volume_ += dist *area/qh hull_dim;
363        
364        Triangles_.push_back(face);
365      }
366    }
367  
368 <  std::cout << "Volume is: " << volume_ << std::endl;
368 >  cout << "Volume is: " << volume_ << endl;
369  
370   //assert(pm.cm.fn == ridgesCount);
371   /*
# Line 456 | Line 459 | void AlphaHull::computeHull(std::vector<StuntDouble*>
459    //volume_ = qh totvol;
460    // area_ = qh totarea;
461  
462 +
463 +  int index = 0;
464 +  FORALLvertices {
465 +    Vector3d point(vertex->point[0], vertex->point[1], vertex->point[2]);
466 +    if (index == 0) {
467 +      boxMax = point;
468 +      boxMin = point;
469 +    } else {
470 +      for (int i = 0; i < 3; i++) {
471 +        boxMax[i] = max(boxMax[i], point[i]);
472 +        boxMin[i] = min(boxMin[i], point[i]);
473 +      }
474 +    }
475 +    index++;
476 +  }
477 +  boundingBox_ = Mat3x3d(0.0);
478 +  boundingBox_(0,0) = boxMax[0] - boxMin[0];
479 +  boundingBox_(1,1) = boxMax[1] - boxMin[1];
480 +  boundingBox_(2,2) = boxMax[2] - boxMin[2];
481 +
482    qh_freeqhull(!qh_ALL);
483    qh_memfreeshort(&curlong, &totlong);
484 <  if (curlong || totlong)
485 <    std::cerr << "qhull internal warning (main): did not free %d bytes of long memory (%d pieces) "
486 <              << totlong << curlong << std::endl;    
484 >  if (curlong || totlong) {
485 >    sprintf(painCave.errMsg, "AlphaHull: qhull internal warning:\n"
486 >            "\tdid not free %d bytes of long memory (%d pieces)",
487 >            totlong, curlong);
488 >    painCave.isFatal = 1;
489 >    simError();
490 >  }
491   }
492  
493 < void AlphaHull::printHull(const std::string& geomFileName) {
494 <
493 > void AlphaHull::printHull(const string& geomFileName) {
494 >  
495   #ifdef IS_MPI
496    if (worldRank == 0)  {
497   #endif
498 <  FILE *newGeomFile;
499 <  
500 <  //create new .md file based on old .md file
501 <  newGeomFile = fopen(geomFileName.c_str(), "w");
502 <  qh_findgood_all(qh facet_list);
503 <  for (int i = 0; i < qh_PRINTEND; i++)
504 <    qh_printfacets(newGeomFile, qh PRINTout[i], qh facet_list, NULL, !qh_ALL);
505 <  
506 <  fclose(newGeomFile);
498 >    FILE *newGeomFile;
499 >    
500 >    //create new .md file based on old .md file
501 >    newGeomFile = fopen(geomFileName.c_str(), "w");
502 >    qh_findgood_all(qh facet_list);
503 >    for (int i = 0; i < qh_PRINTEND; i++)
504 >      qh_printfacets(newGeomFile, qh PRINTout[i], qh facet_list, NULL, !qh_ALL);
505 >    
506 >    fclose(newGeomFile);
507   #ifdef IS_MPI
508    }
509   #endif  

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines