| 1 | /*
 | 
|---|
| 2 |  * analysis.cpp
 | 
|---|
| 3 |  *
 | 
|---|
| 4 |  *  Created on: Oct 13, 2009
 | 
|---|
| 5 |  *      Author: heber
 | 
|---|
| 6 |  */
 | 
|---|
| 7 | 
 | 
|---|
| 8 | #include <iostream>
 | 
|---|
| 9 | 
 | 
|---|
| 10 | #include "analysis_correlation.hpp"
 | 
|---|
| 11 | #include "element.hpp"
 | 
|---|
| 12 | #include "molecule.hpp"
 | 
|---|
| 13 | #include "tesselation.hpp"
 | 
|---|
| 14 | #include "tesselationhelpers.hpp"
 | 
|---|
| 15 | #include "vector.hpp"
 | 
|---|
| 16 | 
 | 
|---|
| 17 | 
 | 
|---|
| 18 | /** Calculates the pair correlation between given elements.
 | 
|---|
| 19 |  * Note given element order is unimportant (i.e. g(Si, O) === g(O, Si))
 | 
|---|
| 20 |  * \param *out output stream for debugging
 | 
|---|
| 21 |  * \param *mol molecule with atoms
 | 
|---|
| 22 |  * \param *type1 first element or NULL (if any element)
 | 
|---|
| 23 |  * \param *type2 second element or NULL (if any element)
 | 
|---|
| 24 |  * \return Map of doubles with values the pair of the two atoms.
 | 
|---|
| 25 |  */
 | 
|---|
| 26 | PairCorrelationMap *PairCorrelation( ofstream *out, molecule *mol, element *type1, element *type2 )
 | 
|---|
| 27 | {
 | 
|---|
| 28 |   PairCorrelationMap *outmap = NULL;
 | 
|---|
| 29 |   double distance = 0.;
 | 
|---|
| 30 | 
 | 
|---|
| 31 |   if ((mol == NULL)) {
 | 
|---|
| 32 |     cout << "No molecule given." << endl;
 | 
|---|
| 33 |     return outmap;
 | 
|---|
| 34 |   }
 | 
|---|
| 35 |   outmap = new PairCorrelationMap;
 | 
|---|
| 36 |   atom *Walker = mol->start;
 | 
|---|
| 37 |   while (Walker->next != mol->end) {
 | 
|---|
| 38 |     Walker = Walker->next;
 | 
|---|
| 39 |     if ((type1 == NULL) || (Walker->type == type1)) {
 | 
|---|
| 40 |       atom *OtherWalker = mol->start;
 | 
|---|
| 41 |       while (OtherWalker->next != mol->end) { // only go up to Walker
 | 
|---|
| 42 |         OtherWalker = OtherWalker->next;
 | 
|---|
| 43 |         if (Walker->nr < OtherWalker->nr)
 | 
|---|
| 44 |           if ((type2 == NULL) || (OtherWalker->type == type2)) {
 | 
|---|
| 45 |             distance = Walker->node->Distance(OtherWalker->node);
 | 
|---|
| 46 |             //cout << "Inserting " << *Walker << " and " << *OtherWalker << endl;
 | 
|---|
| 47 |             outmap->insert ( pair<double, pair <atom *, atom*> > (distance, pair<atom *, atom*> (Walker, OtherWalker) ) );
 | 
|---|
| 48 |           }
 | 
|---|
| 49 |       }
 | 
|---|
| 50 |     }
 | 
|---|
| 51 |   }
 | 
|---|
| 52 | 
 | 
|---|
| 53 |   return outmap;
 | 
|---|
| 54 | };
 | 
|---|
| 55 | 
 | 
|---|
| 56 | /** Calculates the distance (pair) correlation between a given element and a point.
 | 
|---|
| 57 |  * \param *out output stream for debugging
 | 
|---|
| 58 |  * \param *mol molecule with atoms
 | 
|---|
| 59 |  * \param *type element or NULL (if any element)
 | 
|---|
| 60 |  * \param *point vector to the correlation point
 | 
|---|
| 61 |  * \return Map of dobules with values as pairs of atom and the vector
 | 
|---|
| 62 |  */
 | 
|---|
| 63 | CorrelationToPointMap *CorrelationToPoint( ofstream *out, molecule *mol, element *type, Vector *point )
 | 
|---|
| 64 | {
 | 
|---|
| 65 |   CorrelationToPointMap *outmap = NULL;
 | 
|---|
| 66 |   double distance = 0.;
 | 
|---|
| 67 | 
 | 
|---|
| 68 |   if ((mol == NULL)) {
 | 
|---|
| 69 |     cout << "No molecule given." << endl;
 | 
|---|
| 70 |     return outmap;
 | 
|---|
| 71 |   }
 | 
|---|
| 72 |   outmap = new CorrelationToPointMap;
 | 
|---|
| 73 |   atom *Walker = mol->start;
 | 
|---|
| 74 |   while (Walker->next != mol->end) {
 | 
|---|
| 75 |     Walker = Walker->next;
 | 
|---|
| 76 |     if ((type == NULL) || (Walker->type == type)) {
 | 
|---|
| 77 |       distance = Walker->node->Distance(point);
 | 
|---|
| 78 |       outmap->insert ( pair<double, pair<atom *, Vector*> >(distance, pair<atom *, Vector*> (Walker, point) ) );
 | 
|---|
| 79 |     }
 | 
|---|
| 80 |   }
 | 
|---|
| 81 | 
 | 
|---|
| 82 |   return outmap;
 | 
|---|
| 83 | };
 | 
|---|
| 84 | 
 | 
|---|
| 85 | /** Calculates the distance (pair) correlation between a given element and a surface.
 | 
|---|
| 86 |  * \param *out output stream for debugging
 | 
|---|
| 87 |  * \param *mol molecule with atoms
 | 
|---|
| 88 |  * \param *type element or NULL (if any element)
 | 
|---|
| 89 |  * \param *Surface pointer to Tesselation class surface
 | 
|---|
| 90 |  * \param *LC LinkedCell structure to quickly find neighbouring atoms
 | 
|---|
| 91 |  * \return Map of doubles with values as pairs of atom and the BoundaryTriangleSet that's closest
 | 
|---|
| 92 |  */
 | 
|---|
| 93 | CorrelationToSurfaceMap *CorrelationToSurface( ofstream *out, molecule *mol, element *type, Tesselation *Surface, LinkedCell *LC )
 | 
|---|
| 94 | {
 | 
|---|
| 95 | 
 | 
|---|
| 96 |   CorrelationToSurfaceMap *outmap = NULL;
 | 
|---|
| 97 |   double distance = 0.;
 | 
|---|
| 98 |   class BoundaryTriangleSet *triangle = NULL;
 | 
|---|
| 99 |   Vector centroid;
 | 
|---|
| 100 | 
 | 
|---|
| 101 |   if ((Surface == NULL) || (LC == NULL) || (mol == NULL)) {
 | 
|---|
| 102 |     cout << "No Tesselation, no LinkedCell or no molecule given." << endl;
 | 
|---|
| 103 |     return outmap;
 | 
|---|
| 104 |   }
 | 
|---|
| 105 |   outmap = new CorrelationToSurfaceMap;
 | 
|---|
| 106 |   atom *Walker = mol->start;
 | 
|---|
| 107 |   while (Walker->next != mol->end) {
 | 
|---|
| 108 |     Walker = Walker->next;
 | 
|---|
| 109 |     if ((type == NULL) || (Walker->type == type)) {
 | 
|---|
| 110 |       triangle = Surface->FindClosestTriangleToPoint(out, Walker->node, LC );
 | 
|---|
| 111 |       if (triangle != NULL) {
 | 
|---|
| 112 |         distance = DistanceToTrianglePlane(out, Walker->node, triangle);
 | 
|---|
| 113 |         outmap->insert ( pair<double, pair<atom *, BoundaryTriangleSet*> >(distance, pair<atom *, BoundaryTriangleSet*> (Walker, triangle) ) );
 | 
|---|
| 114 |       }
 | 
|---|
| 115 |     }
 | 
|---|
| 116 |   }
 | 
|---|
| 117 | 
 | 
|---|
| 118 |   return outmap;
 | 
|---|
| 119 | };
 | 
|---|
| 120 | 
 | 
|---|
| 121 | /** Returns the start of the bin for a given value.
 | 
|---|
| 122 |  * \param value value whose bin to look for
 | 
|---|
| 123 |  * \param BinWidth width of bin
 | 
|---|
| 124 |  * \param BinStart first bin
 | 
|---|
| 125 |  */
 | 
|---|
| 126 | double GetBin ( double value, double BinWidth, double BinStart )
 | 
|---|
| 127 | {
 | 
|---|
| 128 |   double bin =(double) (floor((value - BinStart)/BinWidth));
 | 
|---|
| 129 |   return (bin*BinWidth+BinStart);
 | 
|---|
| 130 | };
 | 
|---|
| 131 | 
 | 
|---|
| 132 | 
 | 
|---|
| 133 | /** Prints correlation (double, int) pairs to file.
 | 
|---|
| 134 |  * \param *file file to write to
 | 
|---|
| 135 |  * \param *map map to write
 | 
|---|
| 136 |  */
 | 
|---|
| 137 | void OutputCorrelation( ofstream *file, BinPairMap *map )
 | 
|---|
| 138 | {
 | 
|---|
| 139 |   *file << "# BinStart\tCount" << endl;
 | 
|---|
| 140 |   for (BinPairMap::iterator runner = map->begin(); runner != map->end(); ++runner) {
 | 
|---|
| 141 |     *file << runner->first << "\t" << runner->second << endl;
 | 
|---|
| 142 |   }
 | 
|---|
| 143 | };
 | 
|---|