Changes in / [06c7a3:7326b2]
- Files:
-
- 25 added
- 1 deleted
- 52 edited
Legend:
- Unmodified
- Added
- Removed
-
configure.ac
r06c7a3 r7326b2 27 27 28 28 # Boost libraries 29 AX_BOOST_BASE([1.33.1])30 AX_BOOST_PROGRAM_OPTIONS29 #AX_BOOST_BASE([1.33.1]) 30 #AX_BOOST_PROGRAM_OPTIONS 31 31 #AX_BOOST_FOREACH 32 32 #AX_BOOST_FILESYSTEM -
src/Makefile.am
r06c7a3 r7326b2 1 SOURCE = analysis_correlation.cpp atom.cpp bond.cpp boundary.cpp config.cpp element.cpp ellipsoid.cpp graph.cpp helpers.cpp leastsquaremin.cpp linkedcell.cpp memoryusageobserver.cpp moleculelist.cpp molecule.cpp molecule_dynamics.cpp molecule_fragmentation.cpp molecule_geometry.cpp molecule_graph.cpp molecule_pointcloud.cpp parser.cpp periodentafel.cpp tesselation.cpp tesselationhelpers.cpp vector.cpp verbose.cpp 2 HEADER = analysis_correlation.hpp atom.hpp bond.hpp boundary.hpp config.hpp defs.hpp element.hpp ellipsoid.hpp graph.hpp helpers.hpp leastsquaremin.hpp linkedcell.hpp lists.hpp memoryallocator.hpp memoryusageobserver.hpp molecule.hpp molecule_template.hpp parser.hpp periodentafel.hpp stackclass.hpp tesselation.hpp tesselationhelpers.hpp vector.hpp verbose.hpp 1 ATOMSOURCE = atom.cpp atom_atominfo.cpp atom_bondedparticle.cpp atom_bondedparticleinfo.cpp atom_graphnode.cpp atom_graphnodeinfo.cpp atom_particleinfo.cpp atom_trajectoryparticle.cpp atom_trajectoryparticleinfo.cpp 2 ATOMHEADER = atom.hpp atom_atominfo.hpp atom_bondedparticle.hpp atom_bondedparticleinfo.hpp atom_graphnode.hpp atom_graphnodeinfo.hpp atom_particleinfo.hpp atom_trajectoryparticle.hpp atom_trajectoryparticleinfo.hpp 3 4 SOURCE = analysis_correlation.cpp ${ATOMSOURCE} bond.cpp bondgraph.cpp boundary.cpp config.cpp element.cpp ellipsoid.cpp errorLogger.cpp graph.cpp helpers.cpp leastsquaremin.cpp linkedcell.cpp log.cpp logger.cpp memoryusageobserver.cpp moleculelist.cpp molecule.cpp molecule_dynamics.cpp molecule_fragmentation.cpp molecule_geometry.cpp molecule_graph.cpp molecule_pointcloud.cpp parser.cpp periodentafel.cpp tesselation.cpp tesselationhelpers.cpp vector.cpp verbose.cpp 5 HEADER = analysis_correlation.hpp ${ATOMHEADER} bond.hpp bondgraph.hpp boundary.hpp config.hpp defs.hpp element.hpp ellipsoid.hpp errorLogger.hpp graph.hpp helpers.hpp leastsquaremin.hpp linkedcell.hpp lists.hpp log.hpp logger.hpp memoryallocator.hpp memoryusageobserver.hpp molecule.hpp molecule_template.hpp parser.hpp periodentafel.hpp stackclass.hpp tesselation.hpp tesselationhelpers.hpp vector.hpp verbose.hpp 3 6 4 7 BOOST_LIB = $(BOOST_LDFLAGS) $(BOOST_MPL_LIB) -
src/analysis_correlation.cpp
r06c7a3 r7326b2 14 14 #include "tesselationhelpers.hpp" 15 15 #include "vector.hpp" 16 #include "verbose.hpp" 16 17 17 18 … … 19 20 * Note given element order is unimportant (i.e. g(Si, O) === g(O, Si)) 20 21 * \param *out output stream for debugging 21 * \param *mol molecule with atoms22 * \param *molecules list of molecules structure 22 23 * \param *type1 first element or NULL (if any element) 23 24 * \param *type2 second element or NULL (if any element) 24 25 * \return Map of doubles with values the pair of the two atoms. 25 26 */ 26 PairCorrelationMap *PairCorrelation( ofstream * out, molecule *mol, element *type1, element *type2 )27 PairCorrelationMap *PairCorrelation( ofstream * const out, MoleculeListClass * const &molecules, const element * const type1, const element * const type2 ) 27 28 { 28 29 PairCorrelationMap *outmap = NULL; 29 30 double distance = 0.; 30 31 31 if ( (mol == NULL)) {32 c out <<"No molecule given." << endl;32 if (molecules->ListOfMolecules.empty()) { 33 cerr << Verbose(1) <<"No molecule given." << endl; 33 34 return outmap; 34 35 } 35 36 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) ) ); 37 for (MoleculeList::const_iterator MolWalker = molecules->ListOfMolecules.begin(); MolWalker != molecules->ListOfMolecules.end(); MolWalker++) 38 if ((*MolWalker)->ActiveFlag) { 39 cerr << Verbose(2) << "Current molecule is " << *MolWalker << "." << endl; 40 atom *Walker = (*MolWalker)->start; 41 while (Walker->next != (*MolWalker)->end) { 42 Walker = Walker->next; 43 *out << Verbose(3) << "Current atom is " << *Walker << "." << endl; 44 if ((type1 == NULL) || (Walker->type == type1)) { 45 for (MoleculeList::const_iterator MolOtherWalker = MolWalker; MolOtherWalker != molecules->ListOfMolecules.end(); MolOtherWalker++) 46 if ((*MolOtherWalker)->ActiveFlag) { 47 *out << Verbose(2) << "Current other molecule is " << *MolOtherWalker << "." << endl; 48 atom *OtherWalker = (*MolOtherWalker)->start; 49 while (OtherWalker->next != (*MolOtherWalker)->end) { // only go up to Walker 50 OtherWalker = OtherWalker->next; 51 *out << Verbose(3) << "Current otheratom is " << *OtherWalker << "." << endl; 52 if (Walker->nr < OtherWalker->nr) 53 if ((type2 == NULL) || (OtherWalker->type == type2)) { 54 distance = Walker->node->PeriodicDistance(OtherWalker->node, (*MolWalker)->cell_size); 55 //*out << Verbose(1) <<"Inserting " << *Walker << " and " << *OtherWalker << endl; 56 outmap->insert ( pair<double, pair <atom *, atom*> > (distance, pair<atom *, atom*> (Walker, OtherWalker) ) ); 57 } 58 } 48 59 } 49 } 50 } 51 } 60 } 61 } 62 } 63 64 return outmap; 65 }; 66 67 /** Calculates the pair correlation between given elements. 68 * Note given element order is unimportant (i.e. g(Si, O) === g(O, Si)) 69 * \param *out output stream for debugging 70 * \param *molecules list of molecules structure 71 * \param *type1 first element or NULL (if any element) 72 * \param *type2 second element or NULL (if any element) 73 * \param ranges[NDIM] interval boundaries for the periodic images to scan also 74 * \return Map of doubles with values the pair of the two atoms. 75 */ 76 PairCorrelationMap *PeriodicPairCorrelation( ofstream * const out, MoleculeListClass * const &molecules, const element * const type1, const element * const type2, const int ranges[NDIM] ) 77 { 78 PairCorrelationMap *outmap = NULL; 79 double distance = 0.; 80 int n[NDIM]; 81 Vector checkX; 82 Vector periodicX; 83 int Othern[NDIM]; 84 Vector checkOtherX; 85 Vector periodicOtherX; 86 87 if (molecules->ListOfMolecules.empty()) { 88 cerr << Verbose(1) <<"No molecule given." << endl; 89 return outmap; 90 } 91 outmap = new PairCorrelationMap; 92 for (MoleculeList::const_iterator MolWalker = molecules->ListOfMolecules.begin(); MolWalker != molecules->ListOfMolecules.end(); MolWalker++) 93 if ((*MolWalker)->ActiveFlag) { 94 const double * const FullMatrix = ReturnFullMatrixforSymmetric((*MolWalker)->cell_size); 95 const double * const FullInverseMatrix = InverseMatrix(FullMatrix); 96 cerr << Verbose(2) << "Current molecule is " << *MolWalker << "." << endl; 97 atom *Walker = (*MolWalker)->start; 98 while (Walker->next != (*MolWalker)->end) { 99 Walker = Walker->next; 100 *out << Verbose(3) << "Current atom is " << *Walker << "." << endl; 101 if ((type1 == NULL) || (Walker->type == type1)) { 102 periodicX.CopyVector(Walker->node); 103 periodicX.MatrixMultiplication(FullInverseMatrix); // x now in [0,1)^3 104 // go through every range in xyz and get distance 105 for (n[0]=-ranges[0]; n[0] <= ranges[0]; n[0]++) 106 for (n[1]=-ranges[1]; n[1] <= ranges[1]; n[1]++) 107 for (n[2]=-ranges[2]; n[2] <= ranges[2]; n[2]++) { 108 checkX.Init(n[0], n[1], n[2]); 109 checkX.AddVector(&periodicX); 110 checkX.MatrixMultiplication(FullMatrix); 111 for (MoleculeList::const_iterator MolOtherWalker = MolWalker; MolOtherWalker != molecules->ListOfMolecules.end(); MolOtherWalker++) 112 if ((*MolOtherWalker)->ActiveFlag) { 113 *out << Verbose(2) << "Current other molecule is " << *MolOtherWalker << "." << endl; 114 atom *OtherWalker = (*MolOtherWalker)->start; 115 while (OtherWalker->next != (*MolOtherWalker)->end) { // only go up to Walker 116 OtherWalker = OtherWalker->next; 117 *out << Verbose(3) << "Current otheratom is " << *OtherWalker << "." << endl; 118 if (Walker->nr < OtherWalker->nr) 119 if ((type2 == NULL) || (OtherWalker->type == type2)) { 120 periodicOtherX.CopyVector(OtherWalker->node); 121 periodicOtherX.MatrixMultiplication(FullInverseMatrix); // x now in [0,1)^3 122 // go through every range in xyz and get distance 123 for (Othern[0]=-ranges[0]; Othern[0] <= ranges[0]; Othern[0]++) 124 for (Othern[1]=-ranges[1]; Othern[1] <= ranges[1]; Othern[1]++) 125 for (Othern[2]=-ranges[2]; Othern[2] <= ranges[2]; Othern[2]++) { 126 checkOtherX.Init(Othern[0], Othern[1], Othern[2]); 127 checkOtherX.AddVector(&periodicOtherX); 128 checkOtherX.MatrixMultiplication(FullMatrix); 129 distance = checkX.Distance(&checkOtherX); 130 //*out << Verbose(1) <<"Inserting " << *Walker << " and " << *OtherWalker << endl; 131 outmap->insert ( pair<double, pair <atom *, atom*> > (distance, pair<atom *, atom*> (Walker, OtherWalker) ) ); 132 } 133 } 134 } 135 } 136 } 137 } 138 } 139 } 52 140 53 141 return outmap; … … 56 144 /** Calculates the distance (pair) correlation between a given element and a point. 57 145 * \param *out output stream for debugging 58 * \param *mol molecule with atoms146 * \param *molecules list of molecules structure 59 147 * \param *type element or NULL (if any element) 60 148 * \param *point vector to the correlation point 61 149 * \return Map of dobules with values as pairs of atom and the vector 62 150 */ 63 CorrelationToPointMap *CorrelationToPoint( ofstream *out, molecule *mol, element *type,Vector *point )151 CorrelationToPointMap *CorrelationToPoint( ofstream * const out, MoleculeListClass * const &molecules, const element * const type, const Vector *point ) 64 152 { 65 153 CorrelationToPointMap *outmap = NULL; 66 154 double distance = 0.; 67 155 68 if ( (mol == NULL)) {69 cout <<"No molecule given." << endl;156 if (molecules->ListOfMolecules.empty()) { 157 *out << Verbose(1) <<"No molecule given." << endl; 70 158 return outmap; 71 159 } 72 160 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 } 161 for (MoleculeList::const_iterator MolWalker = molecules->ListOfMolecules.begin(); MolWalker != molecules->ListOfMolecules.end(); MolWalker++) 162 if ((*MolWalker)->ActiveFlag) { 163 *out << Verbose(2) << "Current molecule is " << *MolWalker << "." << endl; 164 atom *Walker = (*MolWalker)->start; 165 while (Walker->next != (*MolWalker)->end) { 166 Walker = Walker->next; 167 *out << Verbose(3) << "Current atom is " << *Walker << "." << endl; 168 if ((type == NULL) || (Walker->type == type)) { 169 distance = Walker->node->PeriodicDistance(point, (*MolWalker)->cell_size); 170 *out << Verbose(4) << "Current distance is " << distance << "." << endl; 171 outmap->insert ( pair<double, pair<atom *, const Vector*> >(distance, pair<atom *, const Vector*> (Walker, point) ) ); 172 } 173 } 174 } 175 176 return outmap; 177 }; 178 179 /** Calculates the distance (pair) correlation between a given element, all its periodic images and a point. 180 * \param *out output stream for debugging 181 * \param *molecules list of molecules structure 182 * \param *type element or NULL (if any element) 183 * \param *point vector to the correlation point 184 * \param ranges[NDIM] interval boundaries for the periodic images to scan also 185 * \return Map of dobules with values as pairs of atom and the vector 186 */ 187 CorrelationToPointMap *PeriodicCorrelationToPoint( ofstream * const out, MoleculeListClass * const &molecules, const element * const type, const Vector *point, const int ranges[NDIM] ) 188 { 189 CorrelationToPointMap *outmap = NULL; 190 double distance = 0.; 191 int n[NDIM]; 192 Vector periodicX; 193 Vector checkX; 194 195 if (molecules->ListOfMolecules.empty()) { 196 *out << Verbose(1) <<"No molecule given." << endl; 197 return outmap; 198 } 199 outmap = new CorrelationToPointMap; 200 for (MoleculeList::const_iterator MolWalker = molecules->ListOfMolecules.begin(); MolWalker != molecules->ListOfMolecules.end(); MolWalker++) 201 if ((*MolWalker)->ActiveFlag) { 202 const double * const FullMatrix = ReturnFullMatrixforSymmetric((*MolWalker)->cell_size); 203 const double * const FullInverseMatrix = InverseMatrix(FullMatrix); 204 *out << Verbose(2) << "Current molecule is " << *MolWalker << "." << endl; 205 atom *Walker = (*MolWalker)->start; 206 while (Walker->next != (*MolWalker)->end) { 207 Walker = Walker->next; 208 *out << Verbose(3) << "Current atom is " << *Walker << "." << endl; 209 if ((type == NULL) || (Walker->type == type)) { 210 periodicX.CopyVector(Walker->node); 211 periodicX.MatrixMultiplication(FullInverseMatrix); // x now in [0,1)^3 212 // go through every range in xyz and get distance 213 for (n[0]=-ranges[0]; n[0] <= ranges[0]; n[0]++) 214 for (n[1]=-ranges[1]; n[1] <= ranges[1]; n[1]++) 215 for (n[2]=-ranges[2]; n[2] <= ranges[2]; n[2]++) { 216 checkX.Init(n[0], n[1], n[2]); 217 checkX.AddVector(&periodicX); 218 checkX.MatrixMultiplication(FullMatrix); 219 distance = checkX.Distance(point); 220 *out << Verbose(4) << "Current distance is " << distance << "." << endl; 221 outmap->insert ( pair<double, pair<atom *, const Vector*> >(distance, pair<atom *, const Vector*> (Walker, point) ) ); 222 } 223 } 224 } 225 } 81 226 82 227 return outmap; … … 85 230 /** Calculates the distance (pair) correlation between a given element and a surface. 86 231 * \param *out output stream for debugging 87 * \param *mol molecule with atoms232 * \param *molecules list of molecules structure 88 233 * \param *type element or NULL (if any element) 89 234 * \param *Surface pointer to Tesselation class surface … … 91 236 * \return Map of doubles with values as pairs of atom and the BoundaryTriangleSet that's closest 92 237 */ 93 CorrelationToSurfaceMap *CorrelationToSurface( ofstream *out, molecule *mol, element *type, Tesselation *Surface, LinkedCell *LC ) 94 { 95 238 CorrelationToSurfaceMap *CorrelationToSurface( ofstream * const out, MoleculeListClass * const &molecules, const element * const type, const Tesselation * const Surface, const LinkedCell *LC ) 239 { 96 240 CorrelationToSurfaceMap *outmap = NULL; 97 double distance = 0 .;241 double distance = 0; 98 242 class BoundaryTriangleSet *triangle = NULL; 99 243 Vector centroid; 100 244 101 if ((Surface == NULL) || (LC == NULL) || (mol == NULL)) {102 cout <<"No Tesselation, no LinkedCell or no molecule given." << endl;245 if ((Surface == NULL) || (LC == NULL) || (molecules->ListOfMolecules.empty())) { 246 *out << Verbose(1) <<"No Tesselation, no LinkedCell or no molecule given." << endl; 103 247 return outmap; 104 248 } 105 249 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 } 250 for (MoleculeList::const_iterator MolWalker = molecules->ListOfMolecules.begin(); MolWalker != molecules->ListOfMolecules.end(); MolWalker++) 251 if ((*MolWalker)->ActiveFlag) { 252 *out << Verbose(2) << "Current molecule is " << *MolWalker << "." << endl; 253 atom *Walker = (*MolWalker)->start; 254 while (Walker->next != (*MolWalker)->end) { 255 Walker = Walker->next; 256 *out << Verbose(3) << "Current atom is " << *Walker << "." << endl; 257 if ((type == NULL) || (Walker->type == type)) { 258 triangle = Surface->FindClosestTriangleToPoint(out, Walker->node, LC ); 259 if (triangle != NULL) { 260 distance = DistanceToTrianglePlane(out, Walker->node, triangle); 261 outmap->insert ( pair<double, pair<atom *, BoundaryTriangleSet*> >(distance, pair<atom *, BoundaryTriangleSet*> (Walker, triangle) ) ); 262 } 263 } 264 } 265 } 266 267 return outmap; 268 }; 269 270 /** Calculates the distance (pair) correlation between a given element, all its periodic images and and a surface. 271 * Note that we also put all periodic images found in the cells given by [ -ranges[i], ranges[i] ] and i=0,...,NDIM-1. 272 * I.e. We multiply the atom::node with the inverse of the domain matrix, i.e. transform it to \f$[0,0^3\f$, then add per 273 * axis an integer from [ -ranges[i], ranges[i] ] onto it and multiply with the domain matrix to bring it back into 274 * the real space. Then, we Tesselation::FindClosestTriangleToPoint() and DistanceToTrianglePlane(). 275 * \param *out output stream for debugging 276 * \param *molecules list of molecules structure 277 * \param *type element or NULL (if any element) 278 * \param *Surface pointer to Tesselation class surface 279 * \param *LC LinkedCell structure to quickly find neighbouring atoms 280 * \param ranges[NDIM] interval boundaries for the periodic images to scan also 281 * \return Map of doubles with values as pairs of atom and the BoundaryTriangleSet that's closest 282 */ 283 CorrelationToSurfaceMap *PeriodicCorrelationToSurface( ofstream * const out, MoleculeListClass * const &molecules, const element * const type, const Tesselation * const Surface, const LinkedCell *LC, const int ranges[NDIM] ) 284 { 285 CorrelationToSurfaceMap *outmap = NULL; 286 double distance = 0; 287 class BoundaryTriangleSet *triangle = NULL; 288 Vector centroid; 289 int n[NDIM]; 290 Vector periodicX; 291 Vector checkX; 292 293 if ((Surface == NULL) || (LC == NULL) || (molecules->ListOfMolecules.empty())) { 294 *out << Verbose(1) <<"No Tesselation, no LinkedCell or no molecule given." << endl; 295 return outmap; 296 } 297 outmap = new CorrelationToSurfaceMap; 298 for (MoleculeList::const_iterator MolWalker = molecules->ListOfMolecules.begin(); MolWalker != molecules->ListOfMolecules.end(); MolWalker++) 299 if ((*MolWalker)->ActiveFlag) { 300 const double * const FullMatrix = ReturnFullMatrixforSymmetric((*MolWalker)->cell_size); 301 const double * const FullInverseMatrix = InverseMatrix(FullMatrix); 302 *out << Verbose(2) << "Current molecule is " << *MolWalker << "." << endl; 303 atom *Walker = (*MolWalker)->start; 304 while (Walker->next != (*MolWalker)->end) { 305 Walker = Walker->next; 306 *out << Verbose(3) << "Current atom is " << *Walker << "." << endl; 307 if ((type == NULL) || (Walker->type == type)) { 308 periodicX.CopyVector(Walker->node); 309 periodicX.MatrixMultiplication(FullInverseMatrix); // x now in [0,1)^3 310 // go through every range in xyz and get distance 311 for (n[0]=-ranges[0]; n[0] <= ranges[0]; n[0]++) 312 for (n[1]=-ranges[1]; n[1] <= ranges[1]; n[1]++) 313 for (n[2]=-ranges[2]; n[2] <= ranges[2]; n[2]++) { 314 checkX.Init(n[0], n[1], n[2]); 315 checkX.AddVector(&periodicX); 316 checkX.MatrixMultiplication(FullMatrix); 317 triangle = Surface->FindClosestTriangleToPoint(out, &checkX, LC ); 318 if (triangle != NULL) { 319 distance = DistanceToTrianglePlane(out, &checkX, triangle); 320 outmap->insert ( pair<double, pair<atom *, BoundaryTriangleSet*> >(distance, pair<atom *, BoundaryTriangleSet*> (Walker, triangle) ) ); 321 } 322 } 323 } 324 } 325 } 117 326 118 327 return outmap; … … 124 333 * \param BinStart first bin 125 334 */ 126 double GetBin ( double value, double BinWidth,double BinStart )335 double GetBin ( const double value, const double BinWidth, const double BinStart ) 127 336 { 128 337 double bin =(double) (floor((value - BinStart)/BinWidth)); … … 135 344 * \param *map map to write 136 345 */ 137 void OutputCorrelation( ofstream * file, BinPairMap *map )346 void OutputCorrelation( ofstream * const file, const BinPairMap * const map ) 138 347 { 139 348 *file << "# BinStart\tCount" << endl; 140 for (BinPairMap:: iterator runner = map->begin(); runner != map->end(); ++runner) {349 for (BinPairMap::const_iterator runner = map->begin(); runner != map->end(); ++runner) { 141 350 *file << runner->first << "\t" << runner->second << endl; 142 351 } 143 352 }; 353 354 /** Prints correlation (double, (atom*,atom*) ) pairs to file. 355 * \param *file file to write to 356 * \param *map map to write 357 */ 358 void OutputPairCorrelation( ofstream * const file, const PairCorrelationMap * const map ) 359 { 360 *file << "# BinStart\tAtom1\tAtom2" << endl; 361 for (PairCorrelationMap::const_iterator runner = map->begin(); runner != map->end(); ++runner) { 362 *file << runner->first << "\t" << *(runner->second.first) << "\t" << *(runner->second.second) << endl; 363 } 364 }; 365 366 /** Prints correlation (double, int) pairs to file. 367 * \param *file file to write to 368 * \param *map map to write 369 */ 370 void OutputCorrelationToPoint( ofstream * const file, const CorrelationToPointMap * const map ) 371 { 372 *file << "# BinStart\tAtom::x[i]-point.x[i]" << endl; 373 for (CorrelationToPointMap::const_iterator runner = map->begin(); runner != map->end(); ++runner) { 374 *file << runner->first; 375 for (int i=0;i<NDIM;i++) 376 *file << "\t" << (runner->second.first->node->x[i] - runner->second.second->x[i]); 377 *file << endl; 378 } 379 }; 380 381 /** Prints correlation (double, int) pairs to file. 382 * \param *file file to write to 383 * \param *map map to write 384 */ 385 void OutputCorrelationToSurface( ofstream * const file, const CorrelationToSurfaceMap * const map ) 386 { 387 *file << "# BinStart\tTriangle" << endl; 388 for (CorrelationToSurfaceMap::const_iterator runner = map->begin(); runner != map->end(); ++runner) { 389 *file << runner->first << "\t" << *(runner->second.second) << endl; 390 } 391 }; 392 -
src/analysis_correlation.hpp
r06c7a3 r7326b2 32 32 class element; 33 33 class LinkedCell; 34 class molecule;34 class MoleculeListClass; 35 35 class Tesselation; 36 36 class Vector; … … 39 39 40 40 typedef multimap<double, pair<atom *, atom *> > PairCorrelationMap; 41 typedef multimap<double, pair<atom *, Vector *> > CorrelationToPointMap;41 typedef multimap<double, pair<atom *, const Vector *> > CorrelationToPointMap; 42 42 typedef multimap<double, pair<atom *, BoundaryTriangleSet *> > CorrelationToSurfaceMap; 43 43 typedef map<double, int> BinPairMap; … … 45 45 /********************************************** declarations *******************************/ 46 46 47 PairCorrelationMap *PairCorrelation( ofstream *out, molecule *mol, element *type1, element *type2 ); 48 CorrelationToPointMap *CorrelationToPoint( ofstream *out, molecule *mol, element *type, Vector *point ); 49 CorrelationToSurfaceMap *CorrelationToSurface( ofstream *out, molecule *mol, element *type, Tesselation *Surface, LinkedCell *LC ); 50 double GetBin ( double value, double BinWidth, double BinStart ); 51 void OutputCorrelation( ofstream *file, BinPairMap *map ); 47 PairCorrelationMap *PairCorrelation( ofstream * const out, MoleculeListClass * const &molecules, const element * const type1, const element * const type2 ); 48 CorrelationToPointMap *CorrelationToPoint( ofstream * const out, MoleculeListClass * const &molecules, const element * const type, const Vector *point ); 49 CorrelationToSurfaceMap *CorrelationToSurface( ofstream * const out, MoleculeListClass * const &molecules, const element * const type, const Tesselation * const Surface, const LinkedCell *LC ); 50 PairCorrelationMap *PeriodicPairCorrelation( ofstream * const out, MoleculeListClass * const &molecules, const element * const type1, const element * const type2, const int ranges[NDIM] ); 51 CorrelationToPointMap *PeriodicCorrelationToPoint( ofstream * const out, MoleculeListClass * const &molecules, const element * const type, const Vector *point, const int ranges[NDIM] ); 52 CorrelationToSurfaceMap *PeriodicCorrelationToSurface( ofstream * const out, MoleculeListClass * const &molecules, const element * const type, const Tesselation * const Surface, const LinkedCell *LC, const int ranges[NDIM] ); 53 double GetBin ( const double value, const double BinWidth, const double BinStart ); 54 void OutputCorrelation( ofstream * const file, const BinPairMap * const map ); 55 void OutputPairCorrelation( ofstream * const file, const BinPairMap * const map ); 56 void OutputCorrelationToPoint( ofstream * const file, const BinPairMap * const map ); 57 void OutputCorrelationToSurface( ofstream * const file, const BinPairMap * const map ); 52 58 53 59 … … 63 69 bool FirstMinFound = false; 64 70 bool FirstMaxFound = false; 71 72 if (map == NULL) { 73 cerr << "Nothing to min/max, map is NULL!" << endl; 74 return; 75 } 65 76 66 77 for (typename T::iterator runner = map->begin(); runner != map->end(); ++runner) { … … 87 98 * \return Map of doubles (the bins) with counts as values 88 99 */ 89 template <typename T> BinPairMap *BinData ( ofstream *out, T *map, double BinWidth, double BinStart,double BinEnd )100 template <typename T> BinPairMap *BinData ( ofstream *out, T *map, const double BinWidth, const double BinStart, const double BinEnd ) 90 101 { 91 102 BinPairMap *outmap = new BinPairMap; … … 95 106 pair <BinPairMap::iterator, bool > BinPairMapInserter; 96 107 108 if (map == NULL) { 109 cerr << "Nothing to bin, is NULL!" << endl; 110 return outmap; 111 } 112 97 113 if (BinStart == BinEnd) { // if same, find range ourselves 98 114 GetMinMax( map, start, end); … … 101 117 end = BinEnd; 102 118 for (double runner = start; runner <= end; runner += BinWidth) 103 outmap->insert( pair<double, int> (runner, 0 .) );119 outmap->insert( pair<double, int> (runner, 0) ); 104 120 } 105 121 -
src/analyzer.cpp
r06c7a3 r7326b2 59 59 bool NoTime = false; 60 60 bool NoHCorrection = true; 61 int counter ;61 int counter = 0; 62 62 63 63 cout << "ANOVA Analyzer" << endl; -
src/atom.cpp
r06c7a3 r7326b2 9 9 #include "config.hpp" 10 10 #include "element.hpp" 11 #include "lists.hpp" 11 12 #include "memoryallocator.hpp" 12 13 #include "parser.hpp" … … 15 16 /************************************* Functions for class atom *************************************/ 16 17 18 17 19 /** Constructor of class atom. 18 20 */ 19 atom::atom() 20 { 21 father = this; // generally, father is itself 22 previous = NULL; 23 next = NULL; 24 Ancestor = NULL; 25 type = NULL; 26 sort = NULL; 27 FixedIon = 0; 28 GraphNr = -1; 29 ComponentNr = NULL; 30 IsCyclic = false; 31 SeparationVertex = false; 32 LowpointNr = -1; 33 AdaptiveOrder = 0; 34 MaxOrder = false; 35 // set LCNode::Vector to our Vector 36 node = &x; 21 atom::atom() : previous(NULL), next(NULL), father(this), sort(&nr) 22 { 23 node = &x; // TesselPoint::x can only be referenced from here 37 24 }; 38 25 39 26 /** Constructor of class atom. 40 27 */ 41 atom::atom(atom *pointer) 42 { 43 Name = NULL; 44 previous = NULL; 45 next = NULL; 46 father = pointer; // generally, father is itself 47 Ancestor = NULL; 48 GraphNr = -1; 49 ComponentNr = NULL; 50 IsCyclic = false; 51 SeparationVertex = false; 52 LowpointNr = -1; 53 AdaptiveOrder = 0; 54 MaxOrder = false; 28 atom::atom(atom *pointer) : previous(NULL), next(NULL), father(pointer), sort(&nr) 29 { 55 30 type = pointer->type; // copy element of atom 56 31 x.CopyVector(&pointer->x); // copy coordination 57 32 v.CopyVector(&pointer->v); // copy velocity 58 33 FixedIon = pointer->FixedIon; 59 nr = -1;60 sort = &nr;61 34 node = &x; 62 } 35 }; 63 36 64 37 … … 67 40 atom::~atom() 68 41 { 69 Free<int>(&ComponentNr, "atom::~atom: *ComponentNr"); 70 Free<char>(&Name, "atom::~atom: *Name"); 71 Trajectory.R.clear(); 72 Trajectory.U.clear(); 73 Trajectory.F.clear(); 42 unlink(this); 74 43 }; 75 44 … … 104 73 * \param **res return value (only set if atom::father is equal to \a *ptr) 105 74 */ 106 void atom::EqualsFather ( atom *ptr, atom **res )75 void atom::EqualsFather ( const atom *ptr, const atom **res ) const 107 76 { 108 77 if ( ptr == father ) … … 115 84 * \return true - is inside, false - is not 116 85 */ 117 bool atom::IsInParallelepiped( Vector offset, double *parallelepiped)86 bool atom::IsInParallelepiped(const Vector offset, const double *parallelepiped) const 118 87 { 119 88 return (node->IsInParallelepiped(offset, parallelepiped)); 120 89 }; 121 90 122 /** Output of a single atom. 91 /** Counts the number of bonds weighted by bond::BondDegree. 92 * \param bonds times bond::BondDegree 93 */ 94 int BondedParticle::CountBonds() const 95 { 96 int NoBonds = 0; 97 for (BondList::const_iterator Runner = ListOfBonds.begin(); Runner != ListOfBonds.end(); (++Runner)) 98 NoBonds += (*Runner)->BondDegree; 99 return NoBonds; 100 }; 101 102 /** Output of a single atom with given numbering. 123 103 * \param ElementNo cardinal number of the element 124 104 * \param AtomNo cardinal number among these atoms of the same element … … 127 107 * \return true - \a *out present, false - \a *out is NULL 128 108 */ 129 bool atom::Output (ofstream *out, int ElementNo,int AtomNo, const char *comment) const109 bool atom::OutputIndexed(ofstream *out, const int ElementNo, const int AtomNo, const char *comment) const 130 110 { 131 111 if (out != NULL) { … … 143 123 return false; 144 124 }; 145 bool atom::Output(ofstream *out, int *ElementNo, int *AtomNo, const char *comment) 125 126 /** Output of a single atom with numbering from array according to atom::type. 127 * \param *ElementNo cardinal number of the element 128 * \param *AtomNo cardinal number among these atoms of the same element 129 * \param *out stream to output to 130 * \param *comment commentary after '#' sign 131 * \return true - \a *out present, false - \a *out is NULL 132 */ 133 bool atom::OutputArrayIndexed(ofstream *out, const int *ElementNo, int *AtomNo, const char *comment) const 146 134 { 147 135 AtomNo[type->Z]++; // increment number … … 181 169 * \return true - \a *out present, false - \a *out is NULL 182 170 */ 183 bool atom::OutputTrajectory(ofstream *out, int *ElementNo, int *AtomNo,int step) const171 bool atom::OutputTrajectory(ofstream *out, const int *ElementNo, int *AtomNo, const int step) const 184 172 { 185 173 AtomNo[type->Z]++; … … 203 191 * \return true - \a *out present, false - \a *out is NULL 204 192 */ 205 bool atom::OutputTrajectoryXYZ(ofstream *out, int step) const193 bool atom::OutputTrajectoryXYZ(ofstream *out, const int step) const 206 194 { 207 195 if (out != NULL) { … … 215 203 }; 216 204 217 /** Prints all bonds of this atom from given global lists. 218 * \param *out stream to output to 219 * \param *NumberOfBondsPerAtom array with number of bonds per atomic index 220 * \param ***ListOfBondsPerAtom array per atomic index of array with pointer to bond 221 * \return true - \a *out present, false - \a *out is NULL 222 */ 223 bool atom::OutputBondOfAtom(ofstream *out, int *NumberOfBondsPerAtom, bond ***ListOfBondsPerAtom) const 224 { 225 if (out != NULL) { 226 #ifdef ADDHYDROGEN 227 if (type->Z != 1) { // regard only non-hydrogen 228 #endif 229 *out << Verbose(4) << "Atom " << Name << "/" << nr << " with " << NumberOfBondsPerAtom[nr] << " bonds: "; 230 int TotalDegree = 0; 231 for (int j=0;j<NumberOfBondsPerAtom[nr];j++) { 232 *out << *ListOfBondsPerAtom[nr][j] << "\t"; 233 TotalDegree += ListOfBondsPerAtom[nr][j]->BondDegree; 234 } 235 *out << " -- TotalDegree: " << TotalDegree << endl; 236 #ifdef ADDHYDROGEN 237 } 238 #endif 239 return true; 240 } else 241 return false; 242 }; 243 244 ostream & operator << (ostream &ost, const atom &a) 245 { 246 ost << "[" << a.Name << "|" << &a << "]"; 247 return ost; 248 }; 249 250 ostream & atom::operator << (ostream &ost) 251 { 252 ost << "[" << Name << "|" << this << "]"; 253 return ost; 205 /** Outputs the MPQC configuration line for this atom. 206 * \param *out output stream 207 * \param *center center of molecule subtracted from position 208 * \param *AtomNo pointer to atom counter that is increased by one 209 */ 210 void atom::OutputMPQCLine(ofstream *out, const Vector *center, int *AtomNo = NULL) const 211 { 212 *out << "\t\t" << type->symbol << " [ " << x.x[0]-center->x[0] << "\t" << x.x[1]-center->x[1] << "\t" << x.x[2]-center->x[2] << " ]" << endl; 213 if (AtomNo != NULL) 214 *AtomNo++; 254 215 }; 255 216 … … 258 219 * \return true - this one's is smaller, false - not 259 220 */ 260 bool atom::Compare(const atom &ptr) 221 bool atom::Compare(const atom &ptr) const 261 222 { 262 223 if (nr < ptr.nr) … … 265 226 return false; 266 227 }; 267 268 /** Extends the trajectory STL vector to the new size.269 * Does nothing if \a MaxSteps is smaller than current size.270 * \param MaxSteps271 */272 void atom::ResizeTrajectory(int MaxSteps)273 {274 if (Trajectory.R.size() <= (unsigned int)(MaxSteps)) {275 //cout << "Increasing size for trajectory array of " << keyword << " to " << (MaxSteps+1) << "." << endl;276 Trajectory.R.resize(MaxSteps+1);277 Trajectory.U.resize(MaxSteps+1);278 Trajectory.F.resize(MaxSteps+1);279 }280 };281 282 /** Copies a given trajectory step \a src onto another \a dest283 * \param dest index of destination step284 * \param src index of source step285 */286 void atom::CopyStepOnStep(int dest, int src)287 {288 if (dest == src) // self assignment check289 return;290 291 for (int n=NDIM;n--;) {292 Trajectory.R.at(dest).x[n] = Trajectory.R.at(src).x[n];293 Trajectory.U.at(dest).x[n] = Trajectory.U.at(src).x[n];294 Trajectory.F.at(dest).x[n] = Trajectory.F.at(src).x[n];295 }296 };297 298 /** Performs a velocity verlet update of the trajectory.299 * Parameters are according to those in configuration class.300 * \param NextStep index of sequential step to set301 * \param *configuration pointer to configuration with parameters302 * \param *Force matrix with forces303 */304 void atom::VelocityVerletUpdate(int NextStep, config *configuration, ForceMatrix *Force)305 {306 //a = configuration.Deltat*0.5/walker->type->mass; // (F+F_old)/2m = a and thus: v = (F+F_old)/2m * t = (F + F_old) * a307 for (int d=0; d<NDIM; d++) {308 Trajectory.F.at(NextStep).x[d] = -Force->Matrix[0][nr][d+5]*(configuration->GetIsAngstroem() ? AtomicLengthToAngstroem : 1.);309 Trajectory.R.at(NextStep).x[d] = Trajectory.R.at(NextStep-1).x[d];310 Trajectory.R.at(NextStep).x[d] += configuration->Deltat*(Trajectory.U.at(NextStep-1).x[d]); // s(t) = s(0) + v * deltat + 1/2 a * deltat^2311 Trajectory.R.at(NextStep).x[d] += 0.5*configuration->Deltat*configuration->Deltat*(Trajectory.F.at(NextStep).x[d]/type->mass); // F = m * a and s = 0.5 * F/m * t^2 = F * a * t312 }313 // Update U314 for (int d=0; d<NDIM; d++) {315 Trajectory.U.at(NextStep).x[d] = Trajectory.U.at(NextStep-1).x[d];316 Trajectory.U.at(NextStep).x[d] += configuration->Deltat * (Trajectory.F.at(NextStep).x[d]+Trajectory.F.at(NextStep-1).x[d]/type->mass); // v = F/m * t317 }318 // Update R (and F)319 // out << "Integrated position&velocity of step " << (NextStep) << ": (";320 // for (int d=0;d<NDIM;d++)321 // out << Trajectory.R.at(NextStep).x[d] << " "; // next step322 // out << ")\t(";323 // for (int d=0;d<NDIM;d++)324 // cout << Trajectory.U.at(NextStep).x[d] << " "; // next step325 // out << ")" << endl;326 };327 328 /** Sums up mass and kinetics.329 * \param Step step to sum for330 * \param *TotalMass pointer to total mass sum331 * \param *TotalVelocity pointer to tota velocity sum332 */333 void atom::SumUpKineticEnergy( int Step, double *TotalMass, Vector *TotalVelocity )334 {335 *TotalMass += type->mass; // sum up total mass336 for(int d=0;d<NDIM;d++) {337 TotalVelocity->x[d] += Trajectory.U.at(Step).x[d]*type->mass;338 }339 };340 341 /** Outputs the current atom::AdaptiveOrder and atom::MaxOrder to \a *file.342 * \param *file output stream343 */344 void atom::OutputOrder(ofstream *file)345 {346 *file << nr << "\t" << (int)AdaptiveOrder << "\t" << (int)MaxOrder << endl;347 //cout << Verbose(2) << "Storing: " << Walker->nr << "\t" << (int)Walker->AdaptiveOrder << "\t" << (int)Walker->MaxOrder << "." << endl;348 }349 228 350 229 /** Returns squared distance to a given vector. … … 352 231 * \return distance squared 353 232 */ 354 double atom::DistanceSquaredToVector( Vector &origin)233 double atom::DistanceSquaredToVector(const Vector &origin) const 355 234 { 356 235 return origin.DistanceSquared(&x); 357 };358 359 /** Adds kinetic energy of this atom to given temperature value.360 * \param *temperature add on this value361 * \param step given step of trajectory to add362 */363 void atom::AddKineticToTemperature(double *temperature, int step) const364 {365 for (int i=NDIM;i--;)366 *temperature += type->mass * Trajectory.U.at(step).x[i]* Trajectory.U.at(step).x[i];367 236 }; 368 237 … … 371 240 * \return distance 372 241 */ 373 double atom::DistanceToVector( Vector &origin)242 double atom::DistanceToVector(const Vector &origin) const 374 243 { 375 244 return origin.Distance(&x); 376 245 }; 377 246 247 /** Initialises the component number array. 248 * Size is set to atom::ListOfBonds.size()+1 (last is th encode end by -1) 249 */ 250 void atom::InitComponentNr() 251 { 252 if (ComponentNr != NULL) 253 Free(&ComponentNr); 254 ComponentNr = Malloc<int>(ListOfBonds.size()+1, "atom::InitComponentNumbers: *ComponentNr"); 255 for (int i=ListOfBonds.size()+1;i--;) 256 ComponentNr[i] = -1; 257 }; 258 259 378 260 bool operator < (atom &a, atom &b) 379 261 { … … 381 263 }; 382 264 383 /** Evaluates some constraint potential if atom moves from \a startstep at once to \endstep in trajectory.384 * \param startstep trajectory begins at385 * \param endstep trajectory ends at386 * \param **PermutationMap if atom switches places with some other atom, there is no translation but a permutaton noted here (not in the trajectories of each).387 * \param *Force Force matrix to store result in388 */389 void atom::EvaluateConstrainedForce(int startstep, int endstep, atom **PermutationMap, ForceMatrix *Force)390 {391 double constant = 10.;392 atom *Sprinter = PermutationMap[nr];393 // set forces394 for (int i=NDIM;i++;)395 Force->Matrix[0][nr][5+i] += 2.*constant*sqrt(Trajectory.R.at(startstep).Distance(&Sprinter->Trajectory.R.at(endstep)));396 };397 398 /** Correct velocity against the summed \a CoGVelocity for \a step.399 * \param *ActualTemp sum up actual temperature meanwhile400 * \param Step MD step in atom::Tracjetory401 * \param *CoGVelocity remnant velocity (i.e. vector sum of all atom velocities)402 */403 void atom::CorrectVelocity(double *ActualTemp, int Step, Vector *CoGVelocity)404 {405 for(int d=0;d<NDIM;d++) {406 Trajectory.U.at(Step).x[d] -= CoGVelocity->x[d];407 *ActualTemp += 0.5 * type->mass * Trajectory.U.at(Step).x[d] * Trajectory.U.at(Step).x[d];408 }409 };410 411 /** Scales velocity of atom according to Woodcock thermostat.412 * \param ScaleTempFactor factor to scale the velocities with (i.e. sqrt of energy scale factor)413 * \param Step MD step to scale414 * \param *ekin sum of kinetic energy415 */416 void atom::Thermostat_Woodcock(double ScaleTempFactor, int Step, double *ekin)417 {418 double *U = Trajectory.U.at(Step).x;419 if (FixedIon == 0) // even FixedIon moves, only not by other's forces420 for (int d=0; d<NDIM; d++) {421 U[d] *= ScaleTempFactor;422 *ekin += 0.5*type->mass * U[d]*U[d];423 }424 };425 426 /** Scales velocity of atom according to Gaussian thermostat.427 * \param Step MD step to scale428 * \param *G429 * \param *E430 */431 void atom::Thermostat_Gaussian_init(int Step, double *G, double *E)432 {433 double *U = Trajectory.U.at(Step).x;434 double *F = Trajectory.F.at(Step).x;435 if (FixedIon == 0) // even FixedIon moves, only not by other's forces436 for (int d=0; d<NDIM; d++) {437 *G += U[d] * F[d];438 *E += U[d]*U[d]*type->mass;439 }440 };441 442 /** Determines scale factors according to Gaussian thermostat.443 * \param Step MD step to scale444 * \param GE G over E ratio445 * \param *ekin sum of kinetic energy446 * \param *configuration configuration class with TempFrequency and TargetTemp447 */448 void atom::Thermostat_Gaussian_least_constraint(int Step, double G_over_E, double *ekin, config *configuration)449 {450 double *U = Trajectory.U.at(Step).x;451 if (FixedIon == 0) // even FixedIon moves, only not by other's forces452 for (int d=0; d<NDIM; d++) {453 U[d] += configuration->Deltat/type->mass * ( (G_over_E) * (U[d]*type->mass) );454 *ekin += type->mass * U[d]*U[d];455 }456 };457 458 /** Scales velocity of atom according to Langevin thermostat.459 * \param Step MD step to scale460 * \param *r random number generator461 * \param *ekin sum of kinetic energy462 * \param *configuration configuration class with TempFrequency and TargetTemp463 */464 void atom::Thermostat_Langevin(int Step, gsl_rng * r, double *ekin, config *configuration)465 {466 double sigma = sqrt(configuration->TargetTemp/type->mass); // sigma = (k_b T)/m (Hartree/atomicmass = atomiclength/atomictime)467 double *U = Trajectory.U.at(Step).x;468 if (FixedIon == 0) { // even FixedIon moves, only not by other's forces469 // throw a dice to determine whether it gets hit by a heat bath particle470 if (((((rand()/(double)RAND_MAX))*configuration->TempFrequency) < 1.)) {471 cout << Verbose(3) << "Particle " << *this << " was hit (sigma " << sigma << "): " << sqrt(U[0]*U[0]+U[1]*U[1]+U[2]*U[2]) << " -> ";472 // pick three random numbers from a Boltzmann distribution around the desired temperature T for each momenta axis473 for (int d=0; d<NDIM; d++) {474 U[d] = gsl_ran_gaussian (r, sigma);475 }476 cout << sqrt(U[0]*U[0]+U[1]*U[1]+U[2]*U[2]) << endl;477 }478 for (int d=0; d<NDIM; d++)479 *ekin += 0.5*type->mass * U[d]*U[d];480 }481 };482 483 /** Scales velocity of atom according to Berendsen thermostat.484 * \param Step MD step to scale485 * \param ScaleTempFactor factor to scale energy (not velocity!) with486 * \param *ekin sum of kinetic energy487 * \param *configuration configuration class with TempFrequency and Deltat488 */489 void atom::Thermostat_Berendsen(int Step, double ScaleTempFactor, double *ekin, config *configuration)490 {491 double *U = Trajectory.U.at(Step).x;492 if (FixedIon == 0) { // even FixedIon moves, only not by other's forces493 for (int d=0; d<NDIM; d++) {494 U[d] *= sqrt(1+(configuration->Deltat/configuration->TempFrequency)*(ScaleTempFactor-1));495 *ekin += 0.5*type->mass * U[d]*U[d];496 }497 }498 };499 500 /** Initializes current run of NoseHoover thermostat.501 * \param Step MD step to scale502 * \param *delta_alpha additional sum of kinetic energy on return503 */504 void atom::Thermostat_NoseHoover_init(int Step, double *delta_alpha)505 {506 double *U = Trajectory.U.at(Step).x;507 if (FixedIon == 0) { // even FixedIon moves, only not by other's forces508 for (int d=0; d<NDIM; d++) {509 *delta_alpha += U[d]*U[d]*type->mass;510 }511 }512 };513 514 /** Initializes current run of NoseHoover thermostat.515 * \param Step MD step to scale516 * \param *ekin sum of kinetic energy517 * \param *configuration configuration class with TempFrequency and Deltat518 */519 void atom::Thermostat_NoseHoover_scale(int Step, double *ekin, config *configuration)520 {521 double *U = Trajectory.U.at(Step).x;522 if (FixedIon == 0) { // even FixedIon moves, only not by other's forces523 for (int d=0; d<NDIM; d++) {524 U[d] += configuration->Deltat/type->mass * (configuration->alpha * (U[d] * type->mass));525 *ekin += (0.5*type->mass) * U[d]*U[d];526 }527 }528 }; -
src/atom.hpp
r06c7a3 r7326b2 19 19 20 20 #include <iostream> 21 #include <list> 21 22 #include <vector> 22 23 23 #include <gsl/gsl_randist.h> 24 24 #include "atom_atominfo.hpp" 25 #include "atom_bondedparticle.hpp" 26 #include "atom_graphnode.hpp" 27 #include "atom_particleinfo.hpp" 28 #include "atom_trajectoryparticle.hpp" 25 29 #include "tesselation.hpp" 26 30 27 31 /****************************************** forward declarations *****************************/ 28 32 29 class bond;30 class config;31 class element;32 class ForceMatrix;33 33 class Vector; 34 34 … … 38 38 * Class incorporates position, type 39 39 */ 40 class atom : public TesselPoint {40 class atom : public TesselPoint, public TrajectoryParticle, public GraphNode, public BondedParticle, public virtual ParticleInfo, public virtual AtomInfo { 41 41 public: 42 struct43 {44 vector<Vector> R; //!< position vector45 vector<Vector> U; //!< velocity vector46 vector<Vector> F; //!< last force vector47 } Trajectory;48 49 Vector x; //!< coordinate vector of atom, giving last position within cell50 Vector v; //!< velocity vector of atom, giving last velocity within cell51 Vector F; //!< Force vector of atom, giving last force within cell52 element *type; //!< pointing to element53 42 atom *previous; //!< previous atom in molecule list 54 43 atom *next; //!< next atom in molecule list 55 44 atom *father; //!< In many-body bond order fragmentations points to originating atom 56 atom *Ancestor; //!< "Father" in Depth-First-Search57 //char *Name; //!< unique name used during many-body bond-order fragmentation, comes from TesselPoint58 int FixedIon; //!< config variable that states whether forces act on the ion or not59 45 int *sort; //!< sort criteria 60 //int nr; //!< continuous, unique number, comes from TesselPoint61 int GraphNr; //!< unique number, given in DepthFirstSearchAnalysis()62 int *ComponentNr;//!< belongs to this nonseparable components, given in DepthFirstSearchAnalysis() (if more than one, then is SeparationVertex)63 int LowpointNr; //!< needed in DepthFirstSearchAnalysis() to detect nonseparable components, is the lowest possible number of an atom to reach via tree edges only followed by at most one back edge.64 bool SeparationVertex; //!< whether this atom separates off subsets of atoms or not, determined in DepthFirstSearchAnalysis()65 bool IsCyclic; //!< whether atom belong to as cycle or not, determined in DepthFirstSearchAnalysis()66 unsigned char AdaptiveOrder; //!< current present bond order at site (0 means "not set")67 bool MaxOrder; //!< whether this atom as a root in fragmentation still creates more fragments on higher orders or not68 46 69 47 atom(); … … 71 49 virtual ~atom(); 72 50 73 bool Output (ofstream *out, int ElementNo,int AtomNo, const char *comment = NULL) const;74 bool Output (ofstream *out, int *ElementNo, int *AtomNo, const char *comment = NULL);51 bool OutputIndexed(ofstream *out, const int ElementNo, const int AtomNo, const char *comment = NULL) const; 52 bool OutputArrayIndexed(ofstream *out, const int *ElementNo, int *AtomNo, const char *comment = NULL) const; 75 53 bool OutputXYZLine(ofstream *out) const; 76 bool OutputTrajectory(ofstream *out, int *ElementNo, int *AtomNo,int step) const;77 bool OutputTrajectoryXYZ(ofstream *out, int step) const;78 bool OutputBondOfAtom(ofstream *out, int *NumberOfBondsPerAtom, bond ***ListOfBondsPerAtom) const;54 bool OutputTrajectory(ofstream *out, const int *ElementNo, int *AtomNo, const int step) const; 55 bool OutputTrajectoryXYZ(ofstream *out, const int step) const; 56 void OutputMPQCLine(ofstream *out, const Vector *center, int *AtomNo) const; 79 57 80 void EqualsFather ( atom *ptr, atom **res ); 58 void InitComponentNr(); 59 60 void EqualsFather ( const atom *ptr, const atom **res ) const; 81 61 void CorrectFather(); 82 62 atom *GetTrueFather(); 83 bool Compare(const atom &ptr) ;63 bool Compare(const atom &ptr) const; 84 64 85 // trajectory stuff 86 void ResizeTrajectory(int MaxSteps); 87 void CopyStepOnStep(int dest, int src); 88 void VelocityVerletUpdate(int MDSteps, config *configuration, ForceMatrix *Force); 89 void SumUpKineticEnergy( int Step, double *TotalMass, Vector *TotalVelocity ); 90 91 double DistanceToVector(Vector &origin); 92 double DistanceSquaredToVector(Vector &origin); 93 94 bool IsInParallelepiped(Vector offset, double *parallelepiped); 95 96 // bond order stuff 97 void OutputOrder(ofstream *file); 98 99 // constraint potential and dynamics stuff 100 void AddKineticToTemperature(double *temperature, int step) const; 101 void EvaluateConstrainedForce(int startstep, int endstep, atom **PermutationMap, ForceMatrix *Force); 102 void CorrectVelocity(double *ActualTemp, int Step, Vector *CoGVelocity); 103 104 // thermostats 105 void Thermostat_Woodcock(double ScaleTempFactor, int Step, double *ekin); 106 void Thermostat_Gaussian_init(int Step, double *G, double *E); 107 void Thermostat_Gaussian_least_constraint(int Step, double G_over_E, double *ekin, config *configuration); 108 void Thermostat_Langevin(int Step, gsl_rng * r, double *ekin, config *configuration); 109 void Thermostat_Berendsen(int Step, double ScaleTempFactor, double *ekin, config *configuration); 110 void Thermostat_NoseHoover_init(int Step, double *delta_alpha); 111 void Thermostat_NoseHoover_scale(int Step, double *ekin, config *configuration); 112 113 114 ostream & operator << (ostream &ost); 65 double DistanceToVector(const Vector &origin) const; 66 double DistanceSquaredToVector(const Vector &origin) const; 67 bool IsInParallelepiped(const Vector offset, const double *parallelepiped) const; 115 68 116 69 private: 117 70 }; 118 71 119 ostream & operator << (ostream &ost, const atom &a);120 121 72 #endif /* ATOM_HPP_ */ -
src/bond.cpp
r06c7a3 r7326b2 15 15 /** Empty Constructor for class bond. 16 16 */ 17 bond::bond() 17 bond::bond() : leftatom(NULL), rightatom(NULL), previous(NULL), next(NULL), HydrogenBond(0), BondDegree(0), nr(-1), Cyclic(false), Type(Undetermined), Used(white) 18 18 { 19 leftatom = NULL;20 rightatom = NULL;21 previous = NULL;22 next = NULL;23 nr = -1;24 HydrogenBond = 0;25 BondDegree = 0;26 Used = white;27 Cyclic = false;28 Type = Undetermined;29 19 }; 30 20 … … 35 25 * \param number increasing index 36 26 */ 37 bond::bond(atom *left, atom *right, int degree=1, int number=0)27 bond::bond(atom *left, atom *right, const int degree, const int number) : leftatom(left), rightatom(right), previous(NULL), next(NULL), HydrogenBond(0), BondDegree(degree), nr(number), Cyclic(false), Type(Undetermined), Used(white) 38 28 { 39 leftatom = left;40 rightatom = right;41 previous = NULL;42 next = NULL;43 HydrogenBond = 0;44 29 if ((left != NULL) && (right != NULL)) { 45 30 if ((left->type != NULL) && (left->type->Z == 1)) … … 48 33 HydrogenBond++; 49 34 } 50 BondDegree = degree;51 nr = number;52 Used = white;53 Cyclic = false;54 };55 bond::bond(atom *left, atom *right)56 {57 leftatom = left;58 rightatom = right;59 previous = NULL;60 next = NULL;61 HydrogenBond = 0;62 if ((left != NULL) && (right != NULL)) {63 if ((left->type != NULL) && (left->type->Z == 1))64 HydrogenBond++;65 if ((right->type != NULL) && (right->type->Z == 1))66 HydrogenBond++;67 }68 BondDegree = 1;69 nr = 0;70 Used = white;71 Cyclic = false;72 35 }; 73 36 … … 77 40 { 78 41 // remove this node from the list structure 79 if (previous != NULL) { 80 previous->next = next; 81 } 82 if (next != NULL) { 83 next->previous = previous; 84 } 42 if (leftatom != NULL) 43 leftatom->UnregisterBond(this); 44 if (rightatom != NULL) 45 rightatom->UnregisterBond(this); 46 unlink(this); 85 47 }; 86 48 87 ostream & operator << (ostream &ost, const bond &b) 49 ostream & operator << (ostream &ost, const bond &b) 88 50 { 89 51 ost << "[" << b.leftatom->Name << " <" << b.BondDegree << "(H" << b.HydrogenBond << ")>" << b.rightatom->Name << "]"; … … 95 57 * \return pointer to the other atom in the bond, NULL if no match (indicates something's wrong with the bond) 96 58 */ 97 atom * bond::GetOtherAtom( atom *Atom) const59 atom * bond::GetOtherAtom(const ParticleInfo * const Atom) const 98 60 { 99 61 if(leftatom == Atom) … … 105 67 }; 106 68 107 /** Get the other atom in a bond if one is specified.108 * \param *Atom the pointer to the one atom109 * \return pointer to the other atom in the bond, NULL if no match (indicates something's wrong with the bond)110 */111 bond * bond::GetFirstBond()112 {113 return GetFirst(this);114 };115 116 /** Get the other atom in a bond if one is specified.117 * \param *Atom the pointer to the one atom118 * \return pointer to the other atom in the bond, NULL if no match (indicates something's wrong with the bond)119 */120 bond * bond::GetLastBond()121 {122 return GetLast(this);123 };124 69 125 70 /** Returns whether vertex was used in DFS. … … 135 80 * \return true if it is either bond::leftatom or bond::rightatom, false otherwise 136 81 */ 137 bool bond::Contains(const atom *ptr)82 bool bond::Contains(const ParticleInfo * const ptr) 138 83 { 139 84 return ((leftatom == ptr) || (rightatom == ptr)); … … 152 97 * \return bond::Used, false if bond was already marked used 153 98 */ 154 bool bond::MarkUsed( enum Shading color) {99 bool bond::MarkUsed(const enum Shading color) { 155 100 if (Used == black) { 156 101 cerr << "ERROR: Bond " << this << " was already marked black!." << endl; -
src/bond.hpp
r06c7a3 r7326b2 21 21 22 22 class atom; 23 class ParticleInfo; 23 24 24 25 /********************************************** declarations *******************************/ 25 26 26 27 /** Bonds between atoms. 27 * Class incorporates bonds between atoms in a molecule, 28 * used to derive tge fragments in many-body bond order 29 * calculations. 28 * Class incorporates bonds between atoms in a molecule. 29 * Note that we regard bond always as something in a molecule, 30 * as it is the glue making up the connected subgrapgh and 31 * hence the molecule. Thus, bonds belong globally to the molecule 32 * (and are free'd there) and only locally to the atom classs. 30 33 */ 31 34 class bond { … … 41 44 enum EdgeType Type;//!< whether this is a tree or back edge 42 45 43 atom * GetOtherAtom(atom *Atom) const; 44 bond * GetFirstBond(); 45 bond * GetLastBond(); 46 atom * GetOtherAtom(const ParticleInfo * const Atom) const; 46 47 47 bool MarkUsed( enum Shading color);48 bool MarkUsed(const enum Shading color); 48 49 enum Shading IsUsed(); 49 50 void ResetUsed(); 50 bool Contains(const atom *ptr);51 bool Contains(const ParticleInfo * const ptr); 51 52 bool Contains(const int nr); 52 53 53 54 bond(); 54 bond(atom *left, atom *right); 55 bond(atom *left, atom *right, int degree); 56 bond(atom *left, atom *right, int degree, int number); 55 bond(atom *left, atom *right, const int degree=1, const int number=0); 57 56 ~bond(); 58 57 -
src/boundary.cpp
r06c7a3 r7326b2 26 26 * \param *BoundaryPoints NDIM set of boundary points defining the convex envelope on each projected plane 27 27 * \param *mol molecule structure representing the cluster 28 * \param *&TesselStruct Tesselation structure with triangles 28 29 * \param IsAngstroem whether we have angstroem or atomic units 29 30 * \return NDIM array of the diameters 30 31 */ 31 double *GetDiametersOfCluster(ofstream *out, Boundaries *BoundaryPtr, molecule *mol,bool IsAngstroem)32 double *GetDiametersOfCluster(ofstream *out, const Boundaries *BoundaryPtr, const molecule *mol, Tesselation *&TesselStruct, const bool IsAngstroem) 32 33 { 33 34 // get points on boundary of NULL was given as parameter 34 35 bool BoundaryFreeFlag = false; 35 Boundaries *BoundaryPoints = BoundaryPtr; 36 if (BoundaryPoints == NULL) { 36 double OldComponent = 0.; 37 double tmp = 0.; 38 double w1 = 0.; 39 double w2 = 0.; 40 Vector DistanceVector; 41 Vector OtherVector; 42 int component = 0; 43 int Othercomponent = 0; 44 Boundaries::const_iterator Neighbour; 45 Boundaries::const_iterator OtherNeighbour; 46 double *GreatestDiameter = new double[NDIM]; 47 48 const Boundaries *BoundaryPoints; 49 if (BoundaryPtr == NULL) { 37 50 BoundaryFreeFlag = true; 38 BoundaryPoints = GetBoundaryPoints(out, mol );51 BoundaryPoints = GetBoundaryPoints(out, mol, TesselStruct); 39 52 } else { 53 BoundaryPoints = BoundaryPtr; 40 54 *out << Verbose(1) << "Using given boundary points set." << endl; 41 55 } 42 56 // determine biggest "diameter" of cluster for each axis 43 Boundaries::iterator Neighbour, OtherNeighbour;44 double *GreatestDiameter = new double[NDIM];45 57 for (int i = 0; i < NDIM; i++) 46 58 GreatestDiameter[i] = 0.; 47 double OldComponent, tmp, w1, w2;48 Vector DistanceVector, OtherVector;49 int component, Othercomponent;50 59 for (int axis = 0; axis < NDIM; axis++) 51 60 { // regard each projected plane … … 56 65 Othercomponent = (axis + 1 + ((j + 1) & 1)) % NDIM; 57 66 //*out << Verbose(1) << "Current component is " << component << ", Othercomponent is " << Othercomponent << "." << endl; 58 for (Boundaries::iterator runner = BoundaryPoints[axis].begin(); runner 59 != BoundaryPoints[axis].end(); runner++) 60 { 67 for (Boundaries::const_iterator runner = BoundaryPoints[axis].begin(); runner != BoundaryPoints[axis].end(); runner++) { 61 68 //*out << Verbose(2) << "Current runner is " << *(runner->second.second) << "." << endl; 62 69 // seek for the neighbours pair where the Othercomponent sign flips … … 67 74 DistanceVector.CopyVector(&runner->second.second->x); 68 75 DistanceVector.SubtractVector(&Neighbour->second.second->x); 69 do 70 { // seek for neighbour pair where it flips 76 do { // seek for neighbour pair where it flips 71 77 OldComponent = DistanceVector.x[Othercomponent]; 72 78 Neighbour++; … … 76 82 DistanceVector.SubtractVector(&Neighbour->second.second->x); 77 83 //*out << Verbose(3) << "OldComponent is " << OldComponent << ", new one is " << DistanceVector.x[Othercomponent] << "." << endl; 78 } 79 while ((runner != Neighbour) && (fabs(OldComponent / fabs( 84 } while ((runner != Neighbour) && (fabs(OldComponent / fabs( 80 85 OldComponent) - DistanceVector.x[Othercomponent] / fabs( 81 86 DistanceVector.x[Othercomponent])) < MYEPSILON)); // as long as sign does not flip 82 if (runner != Neighbour) 83 { 87 if (runner != Neighbour) { 84 88 OtherNeighbour = Neighbour; 85 89 if (OtherNeighbour == BoundaryPoints[axis].begin()) // make it wrap around … … 126 130 * \param *out output stream for debugging 127 131 * \param *mol molecule structure representing the cluster 128 */ 129 Boundaries *GetBoundaryPoints(ofstream *out, molecule *mol) 132 * \param *&TesselStruct pointer to Tesselation structure 133 */ 134 Boundaries *GetBoundaryPoints(ofstream *out, const molecule *mol, Tesselation *&TesselStruct) 130 135 { 131 136 atom *Walker = NULL; … … 135 140 Vector *MolCenter = mol->DetermineCenterOfAll(out); 136 141 Vector helper; 142 BoundariesTestPair BoundaryTestPair; 143 Vector AxisVector; 144 Vector AngleReferenceVector; 145 Vector AngleReferenceNormalVector; 146 Vector ProjectedVector; 147 Boundaries *BoundaryPoints = new Boundaries[NDIM]; // first is alpha, second is (r, nr) 148 double angle = 0.; 137 149 138 150 *out << Verbose(1) << "Finding all boundary points." << endl; 139 Boundaries *BoundaryPoints = new Boundaries[NDIM]; // first is alpha, second is (r, nr)140 BoundariesTestPair BoundaryTestPair;141 Vector AxisVector, AngleReferenceVector, AngleReferenceNormalVector;142 double radius, angle;143 151 // 3a. Go through every axis 144 152 for (int axis = 0; axis < NDIM; axis++) { … … 156 164 while (Walker->next != mol->end) { 157 165 Walker = Walker->next; 158 Vector ProjectedVector;159 166 ProjectedVector.CopyVector(&Walker->x); 160 167 ProjectedVector.SubtractVector(MolCenter); … … 162 169 163 170 // correct for negative side 164 radius = ProjectedVector.NormSquared();171 const double radius = ProjectedVector.NormSquared(); 165 172 if (fabs(radius) > MYEPSILON) 166 173 angle = ProjectedVector.Angle(&AngleReferenceVector); … … 178 185 *out << Verbose(2) << "Present vector: " << *BoundaryTestPair.first->second.second << endl; 179 186 *out << Verbose(2) << "New vector: " << *Walker << endl; 180 double tmp= ProjectedVector.NormSquared();181 if (( tmp- BoundaryTestPair.first->second.first) > MYEPSILON) {182 BoundaryTestPair.first->second.first = tmp;187 const double ProjectedVectorNorm = ProjectedVector.NormSquared(); 188 if ((ProjectedVectorNorm - BoundaryTestPair.first->second.first) > MYEPSILON) { 189 BoundaryTestPair.first->second.first = ProjectedVectorNorm; 183 190 BoundaryTestPair.first->second.second = Walker; 184 *out << Verbose(2) << "Keeping new vector due to larger projected distance " << tmp<< "." << endl;185 } else if (fabs( tmp- BoundaryTestPair.first->second.first) < MYEPSILON) {191 *out << Verbose(2) << "Keeping new vector due to larger projected distance " << ProjectedVectorNorm << "." << endl; 192 } else if (fabs(ProjectedVectorNorm - BoundaryTestPair.first->second.first) < MYEPSILON) { 186 193 helper.CopyVector(&Walker->x); 187 194 helper.SubtractVector(MolCenter); 188 tmp= helper.NormSquared();195 const double oldhelperNorm = helper.NormSquared(); 189 196 helper.CopyVector(&BoundaryTestPair.first->second.second->x); 190 197 helper.SubtractVector(MolCenter); 191 if (helper.NormSquared() < tmp) {198 if (helper.NormSquared() < oldhelperNorm) { 192 199 BoundaryTestPair.first->second.second = Walker; 193 200 *out << Verbose(2) << "Keeping new vector due to larger distance to molecule center " << helper.NormSquared() << "." << endl; 194 201 } else { 195 *out << Verbose(2) << "Keeping present vector due to larger distance to molecule center " << tmp<< "." << endl;202 *out << Verbose(2) << "Keeping present vector due to larger distance to molecule center " << oldhelperNorm << "." << endl; 196 203 } 197 204 } else { 198 *out << Verbose(2) << "Keeping present vector due to larger projected distance " << tmp<< "." << endl;205 *out << Verbose(2) << "Keeping present vector due to larger projected distance " << ProjectedVectorNorm << "." << endl; 199 206 } 200 207 } … … 267 274 268 275 // calculate each length 269 double a = SideA.Norm();270 // double b = SideB.Norm();271 // double c = SideC.Norm();272 double h = SideH.Norm();276 const double a = SideA.Norm(); 277 //const double b = SideB.Norm(); 278 //const double c = SideC.Norm(); 279 const double h = SideH.Norm(); 273 280 // calculate the angles 274 double alpha = SideA.Angle(&SideH);275 double beta = SideA.Angle(&SideC);276 double gamma = SideB.Angle(&SideH);277 double delta = SideC.Angle(&SideH);278 double MinDistance = a * sin(beta) / (sin(delta)) * (((alpha < M_PI / 2.) || (gamma < M_PI / 2.)) ? 1. : -1.);281 const double alpha = SideA.Angle(&SideH); 282 const double beta = SideA.Angle(&SideC); 283 const double gamma = SideB.Angle(&SideH); 284 const double delta = SideC.Angle(&SideH); 285 const double MinDistance = a * sin(beta) / (sin(delta)) * (((alpha < M_PI / 2.) || (gamma < M_PI / 2.)) ? 1. : -1.); 279 286 //*out << Verbose(2) << " I calculated: a = " << a << ", h = " << h << ", beta(" << left->second.second->Name << "," << left->second.second->Name << "-" << right->second.second->Name << ") = " << beta << ", delta(" << left->second.second->Name << "," << runner->second.second->Name << ") = " << delta << ", Min = " << MinDistance << "." << endl; 280 287 *out << Verbose(1) << "Checking CoG distance of runner " << *runner->second.second << " " << h << " against triangle's side length spanned by (" << *left->second.second << "," << *right->second.second << ") of " << MinDistance << "." << endl; … … 295 302 /** Tesselates the convex boundary by finding all boundary points. 296 303 * \param *out output stream for debugging 297 * \param *mol molecule structure with Atom's and Bond's 304 * \param *mol molecule structure with Atom's and Bond's. 298 305 * \param *TesselStruct Tesselation filled with points, lines and triangles on boundary on return 299 306 * \param *LCList atoms in LinkedCell list … … 301 308 * \return *TesselStruct is filled with convex boundary and tesselation is stored under \a *filename. 302 309 */ 303 void FindConvexBorder(ofstream *out, molecule* mol, classLinkedCell *LCList, const char *filename)310 void FindConvexBorder(ofstream *out, const molecule* mol, Tesselation *&TesselStruct, const LinkedCell *LCList, const char *filename) 304 311 { 305 312 bool BoundaryFreeFlag = false; … … 308 315 cout << Verbose(1) << "Begin of FindConvexBorder" << endl; 309 316 310 if ( mol->TesselStruct != NULL) // free if allocated311 delete( mol->TesselStruct);312 mol->TesselStruct = new class Tesselation;317 if (TesselStruct != NULL) // free if allocated 318 delete(TesselStruct); 319 TesselStruct = new class Tesselation; 313 320 314 321 // 1. Find all points on the boundary 315 322 if (BoundaryPoints == NULL) { 316 323 BoundaryFreeFlag = true; 317 BoundaryPoints = GetBoundaryPoints(out, mol );324 BoundaryPoints = GetBoundaryPoints(out, mol, TesselStruct); 318 325 } else { 319 326 *out << Verbose(1) << "Using given boundary points set." << endl; … … 338 345 for (int axis = 0; axis < NDIM; axis++) 339 346 for (Boundaries::iterator runner = BoundaryPoints[axis].begin(); runner != BoundaryPoints[axis].end(); runner++) 340 if (! mol->TesselStruct->AddBoundaryPoint(runner->second.second, 0))347 if (!TesselStruct->AddBoundaryPoint(runner->second.second, 0)) 341 348 *out << Verbose(3) << "WARNING: Point " << *(runner->second.second) << " is already present!" << endl; 342 349 343 *out << Verbose(2) << "I found " << mol->TesselStruct->PointsOnBoundaryCount << " points on the convex boundary." << endl;350 *out << Verbose(2) << "I found " << TesselStruct->PointsOnBoundaryCount << " points on the convex boundary." << endl; 344 351 // now we have the whole set of edge points in the BoundaryList 345 352 … … 352 359 353 360 // 3a. guess starting triangle 354 mol->TesselStruct->GuessStartingTriangle(out);361 TesselStruct->GuessStartingTriangle(out); 355 362 356 363 // 3b. go through all lines, that are not yet part of two triangles (only of one so far) 357 mol->TesselStruct->TesselateOnBoundary(out, mol);364 TesselStruct->TesselateOnBoundary(out, mol); 358 365 359 366 // 3c. check whether all atoms lay inside the boundary, if not, add to boundary points, segment triangle into three with the new point 360 if (! mol->TesselStruct->InsertStraddlingPoints(out, mol, LCList))367 if (!TesselStruct->InsertStraddlingPoints(out, mol, LCList)) 361 368 *out << Verbose(1) << "Insertion of straddling points failed!" << endl; 362 369 363 *out << Verbose(2) << "I created " << mol->TesselStruct->TrianglesOnBoundary.size() << " intermediate triangles with " << mol->TesselStruct->LinesOnBoundary.size() << " lines and " << mol->TesselStruct->PointsOnBoundary.size() << " points." << endl;370 *out << Verbose(2) << "I created " << TesselStruct->TrianglesOnBoundary.size() << " intermediate triangles with " << TesselStruct->LinesOnBoundary.size() << " lines and " << TesselStruct->PointsOnBoundary.size() << " points." << endl; 364 371 365 372 // 4. Store triangles in tecplot file … … 370 377 OutputName.append(TecplotSuffix); 371 378 ofstream *tecplot = new ofstream(OutputName.c_str()); 372 WriteTecplotFile(out, tecplot, mol->TesselStruct, mol, 0);379 WriteTecplotFile(out, tecplot, TesselStruct, mol, 0); 373 380 tecplot->close(); 374 381 delete(tecplot); … … 379 386 OutputName.append(Raster3DSuffix); 380 387 ofstream *rasterplot = new ofstream(OutputName.c_str()); 381 WriteRaster3dFile(out, rasterplot, mol->TesselStruct, mol);388 WriteRaster3dFile(out, rasterplot, TesselStruct, mol); 382 389 rasterplot->close(); 383 390 delete(rasterplot); … … 386 393 387 394 // 3d. check all baselines whether the peaks of the two adjacent triangles with respect to center of baseline are convex, if not, make the baseline between the two peaks and baseline endpoints become the new peaks 388 bool AllConvex ;395 bool AllConvex = true; 389 396 class BoundaryLineSet *line = NULL; 390 397 do { 391 398 AllConvex = true; 392 for (LineMap::iterator LineRunner = mol->TesselStruct->LinesOnBoundary.begin(); LineRunner != mol->TesselStruct->LinesOnBoundary.end(); LineRunner++) {399 for (LineMap::iterator LineRunner = TesselStruct->LinesOnBoundary.begin(); LineRunner != TesselStruct->LinesOnBoundary.end(); LineRunner++) { 393 400 line = LineRunner->second; 394 401 *out << Verbose(1) << "INFO: Current line is " << *line << "." << endl; … … 397 404 398 405 // flip the line 399 if ( mol->TesselStruct->PickFarthestofTwoBaselines(out, line) == 0.)406 if (TesselStruct->PickFarthestofTwoBaselines(out, line) == 0.) 400 407 *out << Verbose(1) << "ERROR: Correction of concave baselines failed!" << endl; 401 408 else { 402 mol->TesselStruct->FlipBaseline(out, line);409 TesselStruct->FlipBaseline(out, line); 403 410 *out << Verbose(1) << "INFO: Correction of concave baselines worked." << endl; 404 411 } … … 408 415 409 416 // 3e. we need another correction here, for TesselPoints that are below the surface (i.e. have an odd number of concave triangles surrounding it) 410 // if (! mol->TesselStruct->CorrectConcaveTesselPoints(out))417 // if (!TesselStruct->CorrectConcaveTesselPoints(out)) 411 418 // *out << Verbose(1) << "Correction of concave tesselpoints failed!" << endl; 412 419 413 *out << Verbose(2) << "I created " << mol->TesselStruct->TrianglesOnBoundary.size() << " triangles with " << mol->TesselStruct->LinesOnBoundary.size() << " lines and " << mol->TesselStruct->PointsOnBoundary.size() << " points." << endl;420 *out << Verbose(2) << "I created " << TesselStruct->TrianglesOnBoundary.size() << " triangles with " << TesselStruct->LinesOnBoundary.size() << " lines and " << TesselStruct->PointsOnBoundary.size() << " points." << endl; 414 421 415 422 // 4. Store triangles in tecplot file … … 419 426 OutputName.append(TecplotSuffix); 420 427 ofstream *tecplot = new ofstream(OutputName.c_str()); 421 WriteTecplotFile(out, tecplot, mol->TesselStruct, mol, 0);428 WriteTecplotFile(out, tecplot, TesselStruct, mol, 0); 422 429 tecplot->close(); 423 430 delete(tecplot); … … 427 434 OutputName.append(Raster3DSuffix); 428 435 ofstream *rasterplot = new ofstream(OutputName.c_str()); 429 WriteRaster3dFile(out, rasterplot, mol->TesselStruct, mol);436 WriteRaster3dFile(out, rasterplot, TesselStruct, mol); 430 437 rasterplot->close(); 431 438 delete(rasterplot); … … 448 455 * \return true - all removed, false - something went wrong 449 456 */ 450 bool RemoveAllBoundaryPoints(ofstream *out, class Tesselation * TesselStruct, molecule *mol, char *filename)457 bool RemoveAllBoundaryPoints(ofstream *out, class Tesselation *&TesselStruct, const molecule * const mol, const char * const filename) 451 458 { 452 459 int i=0; … … 471 478 // store envelope 472 479 sprintf(number, "-%04d", i++); 473 StoreTrianglesinFile(out, mol, filename, number);480 StoreTrianglesinFile(out, mol, (const Tesselation *&)TesselStruct, filename, number); 474 481 } 475 482 … … 501 508 * \return volume difference between the non- and the created convex envelope 502 509 */ 503 double ConvexizeNonconvexEnvelope(ofstream *out, class Tesselation * TesselStruct, molecule *mol, char *filename)510 double ConvexizeNonconvexEnvelope(ofstream *out, class Tesselation *&TesselStruct, const molecule * const mol, const char * const filename) 504 511 { 505 512 double volume = 0; 506 513 class BoundaryPointSet *point = NULL; 507 514 class BoundaryLineSet *line = NULL; 508 bool Concavity ;515 bool Concavity = false; 509 516 char dummy[MAXSTRINGSIZE]; 510 PointMap::iterator PointRunner, PointAdvance; 511 LineMap::iterator LineRunner, LineAdvance; 512 TriangleMap::iterator TriangleRunner, TriangleAdvance; 517 PointMap::iterator PointRunner; 518 PointMap::iterator PointAdvance; 519 LineMap::iterator LineRunner; 520 LineMap::iterator LineAdvance; 521 TriangleMap::iterator TriangleRunner; 522 TriangleMap::iterator TriangleAdvance; 523 int run = 0; 513 524 514 525 *out << Verbose(0) << "Begin of ConvexizeNonconvexEnvelope" << endl; … … 521 532 522 533 // First step: RemovePointFromTesselatedSurface 523 int run = 0;524 double tmp;525 534 do { 526 535 Concavity = false; 527 536 sprintf(dummy, "-first-%d", run); 528 537 //CalculateConcavityPerBoundaryPoint(out, TesselStruct); 529 StoreTrianglesinFile(out, mol, filename, dummy);538 StoreTrianglesinFile(out, mol, (const Tesselation *&)TesselStruct, filename, dummy); 530 539 531 540 PointRunner = TesselStruct->PointsOnBoundary.begin(); … … 543 552 volume += TesselStruct->RemovePointFromTesselatedSurface(out, point); 544 553 sprintf(dummy, "-first-%d", ++run); 545 StoreTrianglesinFile(out, mol, filename, dummy);554 StoreTrianglesinFile(out, mol, (const Tesselation *&)TesselStruct, filename, dummy); 546 555 Concavity = true; 547 556 break; … … 553 562 sprintf(dummy, "-second-%d", run); 554 563 //CalculateConcavityPerBoundaryPoint(out, TesselStruct); 555 StoreTrianglesinFile(out, mol, filename, dummy);564 StoreTrianglesinFile(out, mol, (const Tesselation *&)TesselStruct, filename, dummy); 556 565 557 566 // second step: PickFarthestofTwoBaselines … … 564 573 // take highest of both lines 565 574 if (TesselStruct->IsConvexRectangle(out, line) == NULL) { 566 tmp = TesselStruct->PickFarthestofTwoBaselines(out, line);575 const double tmp = TesselStruct->PickFarthestofTwoBaselines(out, line); 567 576 volume += tmp; 568 if (tmp != 0 ) {569 mol->TesselStruct->FlipBaseline(out, line);577 if (tmp != 0.) { 578 TesselStruct->FlipBaseline(out, line); 570 579 Concavity = true; 571 580 } … … 599 608 600 609 CalculateConcavityPerBoundaryPoint(out, TesselStruct); 601 StoreTrianglesinFile(out, mol, filename, "");610 StoreTrianglesinFile(out, mol, (const Tesselation *&)TesselStruct, filename, ""); 602 611 603 612 // end … … 619 628 bool IsAngstroem = configuration->GetIsAngstroem(); 620 629 double volume = 0.; 621 double PyramidVolume = 0.; 622 double G, h; 623 Vector x, y; 624 double a, b, c; 630 Vector x; 631 Vector y; 625 632 626 633 // 6a. Every triangle forms a pyramid with the center of gravity as its peak, sum up the volumes … … 634 641 y.CopyVector(runner->second->endpoints[0]->node->node); 635 642 y.SubtractVector(runner->second->endpoints[2]->node->node); 636 a = sqrt(runner->second->endpoints[0]->node->node->DistanceSquared(runner->second->endpoints[1]->node->node));637 b = sqrt(runner->second->endpoints[0]->node->node->DistanceSquared(runner->second->endpoints[2]->node->node));638 c = sqrt(runner->second->endpoints[2]->node->node->DistanceSquared(runner->second->endpoints[1]->node->node));639 G = sqrt(((a + b + c) * (a + b + c) - 2 * (a * a + b * b + c * c)) / 16.); // area of tesselated triangle643 const double a = sqrt(runner->second->endpoints[0]->node->node->DistanceSquared(runner->second->endpoints[1]->node->node)); 644 const double b = sqrt(runner->second->endpoints[0]->node->node->DistanceSquared(runner->second->endpoints[2]->node->node)); 645 const double c = sqrt(runner->second->endpoints[2]->node->node->DistanceSquared(runner->second->endpoints[1]->node->node)); 646 const double G = sqrt(((a + b + c) * (a + b + c) - 2 * (a * a + b * b + c * c)) / 16.); // area of tesselated triangle 640 647 x.MakeNormalVector(runner->second->endpoints[0]->node->node, runner->second->endpoints[1]->node->node, runner->second->endpoints[2]->node->node); 641 648 x.Scale(runner->second->endpoints[1]->node->node->ScalarProduct(&x)); 642 h = x.Norm(); // distance of CoG to triangle643 PyramidVolume = (1. / 3.) * G * h; // this formula holds for _all_ pyramids (independent of n-edge base or (not) centered peak)644 *out << Verbose(2) << "Area of triangle is " << G << " "649 const double h = x.Norm(); // distance of CoG to triangle 650 const double PyramidVolume = (1. / 3.) * G * h; // this formula holds for _all_ pyramids (independent of n-edge base or (not) centered peak) 651 *out << Verbose(2) << "Area of triangle is " << setprecision(10) << G << " " 645 652 << (IsAngstroem ? "angstrom" : "atomiclength") << "^2, height is " 646 653 << h << " and the volume is " << PyramidVolume << " " … … 648 655 volume += PyramidVolume; 649 656 } 650 *out << Verbose(0) << "RESULT: The summed volume is " << setprecision( 10)657 *out << Verbose(0) << "RESULT: The summed volume is " << setprecision(6) 651 658 << volume << " " << (IsAngstroem ? "angstrom" : "atomiclength") << "^3." 652 659 << endl; … … 658 665 * \param *out output stream for debugging 659 666 * \param *mol molecule with atoms and bonds 667 * \param *&TesselStruct Tesselation with boundary triangles 660 668 * \param *filename prefix of filename 661 669 * \param *extraSuffix intermediate suffix 662 670 */ 663 void StoreTrianglesinFile(ofstream *out, molecule *mol, const char *filename, const char *extraSuffix)671 void StoreTrianglesinFile(ofstream *out, const molecule * const mol, const Tesselation *&TesselStruct, const char *filename, const char *extraSuffix) 664 672 { 665 673 // 4. Store triangles in tecplot file … … 670 678 OutputName.append(TecplotSuffix); 671 679 ofstream *tecplot = new ofstream(OutputName.c_str()); 672 WriteTecplotFile(out, tecplot, mol->TesselStruct, mol, 0);680 WriteTecplotFile(out, tecplot, TesselStruct, mol, 0); 673 681 tecplot->close(); 674 682 delete(tecplot); … … 679 687 OutputName.append(Raster3DSuffix); 680 688 ofstream *rasterplot = new ofstream(OutputName.c_str()); 681 WriteRaster3dFile(out, rasterplot, mol->TesselStruct, mol);689 WriteRaster3dFile(out, rasterplot, TesselStruct, mol); 682 690 rasterplot->close(); 683 691 delete(rasterplot); … … 691 699 * \param *configuration needed for path to store convex envelope file 692 700 * \param *mol molecule structure representing the cluster 701 * \param *&TesselStruct Tesselation structure with triangles on return 693 702 * \param ClusterVolume guesstimated cluster volume, if equal 0 we used VolumeOfConvexEnvelope() instead. 694 703 * \param celldensity desired average density in final cell 695 704 */ 696 void 697 PrepareClustersinWater(ofstream *out, config *configuration, molecule *mol, 698 double ClusterVolume, double celldensity) 705 void PrepareClustersinWater(ofstream *out, config *configuration, molecule *mol, double ClusterVolume, double celldensity) 699 706 { 707 bool IsAngstroem = true; 708 double *GreatestDiameter = NULL; 709 Boundaries *BoundaryPoints = NULL; 710 class Tesselation *TesselStruct = NULL; 711 Vector BoxLengths; 712 int repetition[NDIM] = { 1, 1, 1 }; 713 int TotalNoClusters = 1; 714 atom *Walker = NULL; 715 double totalmass = 0.; 716 double clustervolume = 0.; 717 double cellvolume = 0.; 718 700 719 // transform to PAS 701 720 mol->PrincipalAxisSystem(out, true); 702 721 722 IsAngstroem = configuration->GetIsAngstroem(); 723 GreatestDiameter = GetDiametersOfCluster(out, BoundaryPoints, mol, TesselStruct, IsAngstroem); 724 BoundaryPoints = GetBoundaryPoints(out, mol, TesselStruct); 725 LinkedCell LCList(mol, 10.); 726 FindConvexBorder(out, mol, TesselStruct, &LCList, NULL); 727 703 728 // some preparations beforehand 704 bool IsAngstroem = configuration->GetIsAngstroem();705 Boundaries *BoundaryPoints = GetBoundaryPoints(out, mol);706 class Tesselation *TesselStruct = NULL;707 LinkedCell LCList(mol, 10.);708 FindConvexBorder(out, mol, &LCList, NULL);709 double clustervolume;710 729 if (ClusterVolume == 0) 711 730 clustervolume = VolumeOfConvexEnvelope(out, TesselStruct, configuration); 712 731 else 713 732 clustervolume = ClusterVolume; 714 double *GreatestDiameter = GetDiametersOfCluster(out, BoundaryPoints, mol, IsAngstroem); 715 Vector BoxLengths; 716 int repetition[NDIM] = 717 { 1, 1, 1 }; 718 int TotalNoClusters = 1; 733 719 734 for (int i = 0; i < NDIM; i++) 720 735 TotalNoClusters *= repetition[i]; 721 736 722 737 // sum up the atomic masses 723 double totalmass = 0.; 724 atom *Walker = mol->start; 725 while (Walker->next != mol->end) 726 { 738 Walker = mol->start; 739 while (Walker->next != mol->end) { 727 740 Walker = Walker->next; 728 741 totalmass += Walker->type->mass; 729 } 730 *out << Verbose(0) << "RESULT: The summed mass is " << setprecision(10) 731 << totalmass << " atomicmassunit." << endl; 732 733 *out << Verbose(0) << "RESULT: The average density is " << setprecision(10) 734 << totalmass / clustervolume << " atomicmassunit/" 735 << (IsAngstroem ? "angstrom" : "atomiclength") << "^3." << endl; 742 } 743 *out << Verbose(0) << "RESULT: The summed mass is " << setprecision(10) << totalmass << " atomicmassunit." << endl; 744 *out << Verbose(0) << "RESULT: The average density is " << setprecision(10) << totalmass / clustervolume << " atomicmassunit/" << (IsAngstroem ? "angstrom" : "atomiclength") << "^3." << endl; 736 745 737 746 // solve cubic polynomial 738 *out << Verbose(1) << "Solving equidistant suspension in water problem ..." 739 << endl; 740 double cellvolume; 747 *out << Verbose(1) << "Solving equidistant suspension in water problem ..." << endl; 741 748 if (IsAngstroem) 742 cellvolume = (TotalNoClusters * totalmass / SOLVENTDENSITY_A - (totalmass 743 / clustervolume)) / (celldensity - 1); 749 cellvolume = (TotalNoClusters * totalmass / SOLVENTDENSITY_A - (totalmass / clustervolume)) / (celldensity - 1); 744 750 else 745 cellvolume = (TotalNoClusters * totalmass / SOLVENTDENSITY_a0 - (totalmass 746 / clustervolume)) / (celldensity - 1); 747 *out << Verbose(1) << "Cellvolume needed for a density of " << celldensity 748 << " g/cm^3 is " << cellvolume << " " << (IsAngstroem ? "angstrom" 749 : "atomiclength") << "^3." << endl; 750 751 double minimumvolume = TotalNoClusters * (GreatestDiameter[0] 752 * GreatestDiameter[1] * GreatestDiameter[2]); 753 *out << Verbose(1) 754 << "Minimum volume of the convex envelope contained in a rectangular box is " 755 << minimumvolume << " atomicmassunit/" << (IsAngstroem ? "angstrom" 756 : "atomiclength") << "^3." << endl; 757 if (minimumvolume > cellvolume) 758 { 759 cerr << Verbose(0) 760 << "ERROR: the containing box already has a greater volume than the envisaged cell volume!" 761 << endl; 762 cout << Verbose(0) 763 << "Setting Box dimensions to minimum possible, the greatest diameters." 764 << endl; 765 for (int i = 0; i < NDIM; i++) 766 BoxLengths.x[i] = GreatestDiameter[i]; 767 mol->CenterEdge(out, &BoxLengths); 768 } 769 else 770 { 771 BoxLengths.x[0] = (repetition[0] * GreatestDiameter[0] + repetition[1] 772 * GreatestDiameter[1] + repetition[2] * GreatestDiameter[2]); 773 BoxLengths.x[1] = (repetition[0] * repetition[1] * GreatestDiameter[0] 774 * GreatestDiameter[1] + repetition[0] * repetition[2] 775 * GreatestDiameter[0] * GreatestDiameter[2] + repetition[1] 776 * repetition[2] * GreatestDiameter[1] * GreatestDiameter[2]); 777 BoxLengths.x[2] = minimumvolume - cellvolume; 778 double x0 = 0., x1 = 0., x2 = 0.; 779 if (gsl_poly_solve_cubic(BoxLengths.x[0], BoxLengths.x[1], 780 BoxLengths.x[2], &x0, &x1, &x2) == 1) // either 1 or 3 on return 781 *out << Verbose(0) << "RESULT: The resulting spacing is: " << x0 782 << " ." << endl; 783 else 784 { 785 *out << Verbose(0) << "RESULT: The resulting spacings are: " << x0 786 << " and " << x1 << " and " << x2 << " ." << endl; 787 x0 = x2; // sorted in ascending order 788 } 789 790 cellvolume = 1; 791 for (int i = 0; i < NDIM; i++) 792 { 793 BoxLengths.x[i] = repetition[i] * (x0 + GreatestDiameter[i]); 794 cellvolume *= BoxLengths.x[i]; 795 } 796 797 // set new box dimensions 798 *out << Verbose(0) << "Translating to box with these boundaries." << endl; 799 mol->SetBoxDimension(&BoxLengths); 800 mol->CenterInBox((ofstream *) &cout); 801 } 751 cellvolume = (TotalNoClusters * totalmass / SOLVENTDENSITY_a0 - (totalmass / clustervolume)) / (celldensity - 1); 752 *out << Verbose(1) << "Cellvolume needed for a density of " << celldensity << " g/cm^3 is " << cellvolume << " " << (IsAngstroem ? "angstrom" : "atomiclength") << "^3." << endl; 753 754 double minimumvolume = TotalNoClusters * (GreatestDiameter[0] * GreatestDiameter[1] * GreatestDiameter[2]); 755 *out << Verbose(1) << "Minimum volume of the convex envelope contained in a rectangular box is " << minimumvolume << " atomicmassunit/" << (IsAngstroem ? "angstrom" : "atomiclength") << "^3." << endl; 756 if (minimumvolume > cellvolume) { 757 cerr << Verbose(0) << "ERROR: the containing box already has a greater volume than the envisaged cell volume!" << endl; 758 cout << Verbose(0) << "Setting Box dimensions to minimum possible, the greatest diameters." << endl; 759 for (int i = 0; i < NDIM; i++) 760 BoxLengths.x[i] = GreatestDiameter[i]; 761 mol->CenterEdge(out, &BoxLengths); 762 } else { 763 BoxLengths.x[0] = (repetition[0] * GreatestDiameter[0] + repetition[1] * GreatestDiameter[1] + repetition[2] * GreatestDiameter[2]); 764 BoxLengths.x[1] = (repetition[0] * repetition[1] * GreatestDiameter[0] * GreatestDiameter[1] + repetition[0] * repetition[2] * GreatestDiameter[0] * GreatestDiameter[2] + repetition[1] * repetition[2] * GreatestDiameter[1] * GreatestDiameter[2]); 765 BoxLengths.x[2] = minimumvolume - cellvolume; 766 double x0 = 0.; 767 double x1 = 0.; 768 double x2 = 0.; 769 if (gsl_poly_solve_cubic(BoxLengths.x[0], BoxLengths.x[1], BoxLengths.x[2], &x0, &x1, &x2) == 1) // either 1 or 3 on return 770 *out << Verbose(0) << "RESULT: The resulting spacing is: " << x0 << " ." << endl; 771 else { 772 *out << Verbose(0) << "RESULT: The resulting spacings are: " << x0 << " and " << x1 << " and " << x2 << " ." << endl; 773 x0 = x2; // sorted in ascending order 774 } 775 776 cellvolume = 1.; 777 for (int i = 0; i < NDIM; i++) { 778 BoxLengths.x[i] = repetition[i] * (x0 + GreatestDiameter[i]); 779 cellvolume *= BoxLengths.x[i]; 780 } 781 782 // set new box dimensions 783 *out << Verbose(0) << "Translating to box with these boundaries." << endl; 784 mol->SetBoxDimension(&BoxLengths); 785 mol->CenterInBox((ofstream *) &cout); 786 } 802 787 // update Box of atoms by boundary 803 788 mol->SetBoxDimension(&BoxLengths); 804 *out << Verbose(0) << "RESULT: The resulting cell dimensions are: " 805 << BoxLengths.x[0] << " and " << BoxLengths.x[1] << " and " 806 << BoxLengths.x[2] << " with total volume of " << cellvolume << " " 807 << (IsAngstroem ? "angstrom" : "atomiclength") << "^3." << endl; 808 } 809 ; 789 *out << Verbose(0) << "RESULT: The resulting cell dimensions are: " << BoxLengths.x[0] << " and " << BoxLengths.x[1] << " and " << BoxLengths.x[2] << " with total volume of " << cellvolume << " " << (IsAngstroem ? "angstrom" : "atomiclength") << "^3." << endl; 790 }; 810 791 811 792 … … 836 817 atom *Walker = NULL; 837 818 bond *Binder = NULL; 838 int i ;819 int i = 0; 839 820 LinkedCell *LCList[List->ListOfMolecules.size()]; 821 double phi[NDIM]; 822 class Tesselation *TesselStruct[List->ListOfMolecules.size()]; 840 823 841 824 *out << Verbose(0) << "Begin of FillBoxWithMolecule" << endl; … … 845 828 *out << Verbose(1) << "Pre-creating linked cell lists for molecule " << *ListRunner << "." << endl; 846 829 LCList[i] = new LinkedCell((*ListRunner), 5.); // get linked cell list 847 if ( (*ListRunner)->TesselStruct== NULL) {830 if (TesselStruct[i] == NULL) { 848 831 *out << Verbose(1) << "Pre-creating tesselation for molecule " << *ListRunner << "." << endl; 849 FindNonConvexBorder((ofstream *)&cout, (*ListRunner), LCList[i], 5., NULL);832 FindNonConvexBorder((ofstream *)&cout, (*ListRunner), TesselStruct[i], (const LinkedCell *&)LCList[i], 5., NULL); 850 833 } 851 834 i++; … … 858 841 filler->CountAtoms(out); 859 842 atom * CopyAtoms[filler->AtomCount]; 860 int nr = 0;861 843 862 844 // calculate filler grid in [0,1]^3 … … 886 868 for (MoleculeList::iterator ListRunner = List->ListOfMolecules.begin(); ListRunner != List->ListOfMolecules.end(); ListRunner++) { 887 869 // get linked cell list 888 if ( (*ListRunner)->TesselStruct== NULL) {870 if (TesselStruct[i] == NULL) { 889 871 *out << Verbose(1) << "ERROR: TesselStruct of " << (*ListRunner) << " is NULL. Didn't we pre-create it?" << endl; 890 872 FillIt = false; 891 } else 892 FillIt = FillIt && (!(*ListRunner)->TesselStruct->IsInnerPoint(out, CurrentPosition, LCList[i++])); 873 } else { 874 FillIt = FillIt && (!TesselStruct[i]->IsInnerPoint(out, CurrentPosition, LCList[i])); 875 i++; 876 } 893 877 } 894 878 … … 903 887 904 888 // go through all atoms 905 nr=0;906 889 Walker = filler->start; 907 890 while (Walker->next != filler->end) { … … 916 899 // ... and rotation matrix 917 900 if (DoRandomRotation) { 918 double phi[NDIM];919 901 for (int i=0;i<NDIM;i++) { 920 902 phi[i] = rand()/(RAND_MAX/(2.*M_PI)); … … 967 949 * \param *out output stream for debugging 968 950 * \param *mol molecule structure with Atom's and Bond's 969 * \param * TessTesselation filled with points, lines and triangles on boundary on return970 * \param * LCList atoms in LinkedCell list951 * \param *&TesselStruct Tesselation filled with points, lines and triangles on boundary on return 952 * \param *&LCList atoms in LinkedCell list 971 953 * \param RADIUS radius of the virtual sphere 972 954 * \param *filename filename prefix for output of vertex data 973 955 */ 974 void FindNonConvexBorder(ofstream *out, molecule* mol, class LinkedCell *LCList, const double RADIUS, const char *filename = NULL)956 void FindNonConvexBorder(ofstream *out, const molecule* const mol, Tesselation *&TesselStruct, const LinkedCell *&LCList, const double RADIUS, const char *filename = NULL) 975 957 { 976 958 bool freeLC = false; 977 978 *out << Verbose(1) << "Entering search for non convex hull. " << endl;979 if (mol->TesselStruct == NULL) {980 *out << Verbose(1) << "Allocating Tesselation struct ..." << endl;981 mol->TesselStruct = new Tesselation;982 } else {983 delete(mol->TesselStruct);984 *out << Verbose(1) << "Re-Allocating Tesselation struct ..." << endl;985 mol->TesselStruct = new Tesselation;986 }987 959 LineMap::iterator baseline; 988 960 LineMap::iterator testline; 989 *out << Verbose(0) << "Begin of FindNonConvexBorder\n";990 961 bool OneLoopWithoutSuccessFlag = false; // marks whether we went once through all baselines without finding any without two triangles 991 962 bool TesselationFailFlag = false; 963 964 *out << Verbose(1) << "Entering search for non convex hull. " << endl; 965 if (TesselStruct == NULL) { 966 *out << Verbose(1) << "Allocating Tesselation struct ..." << endl; 967 TesselStruct= new Tesselation; 968 } else { 969 delete(TesselStruct); 970 *out << Verbose(1) << "Re-Allocating Tesselation struct ..." << endl; 971 TesselStruct = new Tesselation; 972 } 973 974 *out << Verbose(0) << "Begin of FindNonConvexBorder\n"; 992 975 993 976 // initialise Linked Cell … … 998 981 999 982 // 1. get starting triangle 1000 mol->TesselStruct->FindStartingTriangle(out, RADIUS, LCList);983 TesselStruct->FindStartingTriangle(out, RADIUS, LCList); 1001 984 1002 985 // 2. expand from there 1003 baseline = mol->TesselStruct->LinesOnBoundary.begin();986 baseline = TesselStruct->LinesOnBoundary.begin(); 1004 987 baseline++; // skip first line 1005 while ((baseline != mol->TesselStruct->LinesOnBoundary.end()) || (OneLoopWithoutSuccessFlag)) {988 while ((baseline != TesselStruct->LinesOnBoundary.end()) || (OneLoopWithoutSuccessFlag)) { 1006 989 if (baseline->second->triangles.size() == 1) { 1007 990 // 3. find next triangle 1008 TesselationFailFlag = mol->TesselStruct->FindNextSuitableTriangle(out, *(baseline->second), *(((baseline->second->triangles.begin()))->second), RADIUS, LCList); //the line is there, so there is a triangle, but only one.991 TesselationFailFlag = TesselStruct->FindNextSuitableTriangle(out, *(baseline->second), *(((baseline->second->triangles.begin()))->second), RADIUS, LCList); //the line is there, so there is a triangle, but only one. 1009 992 OneLoopWithoutSuccessFlag = OneLoopWithoutSuccessFlag || TesselationFailFlag; 1010 993 if (!TesselationFailFlag) … … 1013 996 // write temporary envelope 1014 997 if (filename != NULL) { 1015 if ((DoSingleStepOutput && (( mol->TesselStruct->TrianglesOnBoundary.size() % SingleStepWidth == 0)))) { // if we have a new triangle and want to output each new triangle configuration1016 mol->TesselStruct->Output(out, filename, mol);998 if ((DoSingleStepOutput && ((TesselStruct->TrianglesOnBoundary.size() % SingleStepWidth == 0)))) { // if we have a new triangle and want to output each new triangle configuration 999 TesselStruct->Output(out, filename, mol); 1017 1000 } 1018 1001 } 1019 baseline = mol->TesselStruct->LinesOnBoundary.end();1002 baseline = TesselStruct->LinesOnBoundary.end(); 1020 1003 *out << Verbose(2) << "Baseline set to end." << endl; 1021 1004 } else { … … 1025 1008 } 1026 1009 1027 if ((baseline == mol->TesselStruct->LinesOnBoundary.end()) && (OneLoopWithoutSuccessFlag)) {1028 baseline = mol->TesselStruct->LinesOnBoundary.begin(); // restart if we reach end due to newly inserted lines1010 if ((baseline == TesselStruct->LinesOnBoundary.end()) && (OneLoopWithoutSuccessFlag)) { 1011 baseline = TesselStruct->LinesOnBoundary.begin(); // restart if we reach end due to newly inserted lines 1029 1012 OneLoopWithoutSuccessFlag = false; 1030 1013 } … … 1032 1015 } 1033 1016 // check envelope for consistency 1034 CheckListOfBaselines(out, mol->TesselStruct);1017 CheckListOfBaselines(out, TesselStruct); 1035 1018 1036 1019 // look whether all points are inside of the convex envelope, otherwise add them via degenerated triangles 1037 // mol->TesselStruct->InsertStraddlingPoints(out, mol, LCList);1020 //->InsertStraddlingPoints(out, mol, LCList); 1038 1021 // mol->GoToFirst(); 1039 1022 // class TesselPoint *Runner = NULL; … … 1041 1024 // Runner = mol->GetPoint(); 1042 1025 // *out << Verbose(1) << "Checking on " << Runner->Name << " ... " << endl; 1043 // if (! mol->TesselStruct->IsInnerPoint(out, Runner, LCList)) {1026 // if (!->IsInnerPoint(out, Runner, LCList)) { 1044 1027 // *out << Verbose(2) << Runner->Name << " is outside of envelope, adding via degenerated triangles." << endl; 1045 // mol->TesselStruct->AddBoundaryPointByDegeneratedTriangle(out, Runner, LCList);1028 // ->AddBoundaryPointByDegeneratedTriangle(out, Runner, LCList); 1046 1029 // } else { 1047 1030 // *out << Verbose(2) << Runner->Name << " is inside of or on envelope." << endl; … … 1051 1034 1052 1035 // Purges surplus triangles. 1053 mol->TesselStruct->RemoveDegeneratedTriangles();1036 TesselStruct->RemoveDegeneratedTriangles(); 1054 1037 1055 1038 // check envelope for consistency 1056 CheckListOfBaselines(out, mol->TesselStruct);1039 CheckListOfBaselines(out, TesselStruct); 1057 1040 1058 1041 // write final envelope 1059 CalculateConcavityPerBoundaryPoint(out, mol->TesselStruct);1060 StoreTrianglesinFile(out, mol, filename, "");1042 CalculateConcavityPerBoundaryPoint(out, TesselStruct); 1043 StoreTrianglesinFile(out, mol, (const Tesselation *&)TesselStruct, filename, ""); 1061 1044 1062 1045 if (freeLC) … … 1066 1049 1067 1050 1068 /** Finds a hole of sufficient size in \a this moleculeto embed \a *srcmol into it.1051 /** Finds a hole of sufficient size in \a *mols to embed \a *srcmol into it. 1069 1052 * \param *out output stream for debugging 1070 * \param *srcmol molecule to embed into 1053 * \param *mols molecules in the domain to embed in between 1054 * \param *srcmol embedding molecule 1071 1055 * \return *Vector new center of \a *srcmol for embedding relative to \a this 1072 1056 */ 1073 Vector* molecule::FindEmbeddingHole(ofstream *out, molecule *srcmol)1057 Vector* FindEmbeddingHole(ofstream *out, MoleculeListClass *mols, molecule *srcmol) 1074 1058 { 1075 1059 Vector *Center = new Vector; -
src/boundary.hpp
r06c7a3 r7326b2 48 48 /********************************************** declarations *******************************/ 49 49 50 double ConvexizeNonconvexEnvelope(ofstream *out, class Tesselation *&TesselStruct, const molecule * const mol, const char * const filename); 51 molecule * FillBoxWithMolecule(ofstream *out, MoleculeListClass *List, molecule *filler, config &configuration, double distance[NDIM], double RandAtomDisplacement, double RandMolDisplacement, bool DoRandomRotation); 52 void FindConvexBorder(ofstream *out, const molecule* const mol, Tesselation *&TesselStruct, const LinkedCell *LCList, const char *filename); 53 Vector* FindEmbeddingHole(ofstream *out, MoleculeListClass *mols, molecule *srcmol); 54 void FindNextSuitablePoint(class BoundaryTriangleSet *BaseTriangle, class BoundaryLineSet *BaseLine, atom*& OptCandidate, Vector *OptCandidateCenter, double *ShortestAngle, const double RADIUS, LinkedCell *LC); 55 void FindNonConvexBorder(ofstream *out, const molecule* const mol, Tesselation *&TesselStruct, const LinkedCell *&LC, const double RADIUS, const char *tempbasename); 56 Boundaries *GetBoundaryPoints(ofstream *out, const molecule *mol, Tesselation *&TesselStruct); 57 double * GetDiametersOfCluster(ofstream *out, const Boundaries *BoundaryPtr, const molecule *mol, Tesselation *&TesselStruct, const bool IsAngstroem); 58 void PrepareClustersinWater(ofstream *out, config *configuration, molecule *mol, double ClusterVolume, double celldensity); 59 bool RemoveAllBoundaryPoints(ofstream *out, class Tesselation *&TesselStruct, const molecule * const mol, const char * const filename); 60 void StoreTrianglesinFile(ofstream *out, const molecule * const mol, const Tesselation *&TesselStruct, const char *filename, const char *extraSuffix); 50 61 double VolumeOfConvexEnvelope(ofstream *out, class Tesselation *TesselStruct, class config *configuration); 51 double * GetDiametersOfCluster(ofstream *out, Boundaries *BoundaryPtr, molecule *mol, bool IsAngstroem);52 void PrepareClustersinWater(ofstream *out, config *configuration, molecule *mol, double ClusterVolume, double celldensity);53 molecule * FillBoxWithMolecule(ofstream *out, MoleculeListClass *List, molecule *filler, config &configuration, double distance[NDIM], double RandAtomDisplacement, double RandMolDisplacement, bool DoRandomRotation);54 void FindConvexBorder(ofstream *out, molecule* mol, class LinkedCell *LCList, const char *filename);55 void FindNonConvexBorder(ofstream *out, molecule* mol, class LinkedCell *LC, const double RADIUS, const char *tempbasename);56 double ConvexizeNonconvexEnvelope(ofstream *out, class Tesselation *TesselStruct, molecule *mol, char *filename);57 void FindNextSuitablePoint(class BoundaryTriangleSet *BaseTriangle, class BoundaryLineSet *BaseLine, atom*& OptCandidate, Vector *OptCandidateCenter, double *ShortestAngle, const double RADIUS, LinkedCell *LC);58 Boundaries *GetBoundaryPoints(ofstream *out, molecule *mol);59 void StoreTrianglesinFile(ofstream *out, molecule *mol, const char *filename, const char *extraSuffix);60 bool RemoveAllBoundaryPoints(ofstream *out, class Tesselation *TesselStruct, molecule *mol, char *filename);61 62 62 63 -
src/builder.cpp
r06c7a3 r7326b2 50 50 using namespace std; 51 51 52 #include "analysis_correlation.hpp" 52 53 #include "atom.hpp" 53 54 #include "bond.hpp" 55 #include "bondgraph.hpp" 54 56 #include "boundary.hpp" 55 57 #include "config.hpp" … … 253 255 } while ((j != -1) && (i<128)); 254 256 if (i >= 2) { 255 first->x.LSQdistance( atoms, i);257 first->x.LSQdistance((const Vector **)atoms, i); 256 258 257 259 first->x.Output((ofstream *)&cout); … … 591 593 { 592 594 cout << Verbose(0) << "Evaluating volume of the convex envelope."; 593 LinkedCell LCList(mol, 10.);594 595 class Tesselation *TesselStruct = NULL; 595 FindConvexBorder((ofstream *)&cout, mol, &LCList, NULL); 596 const LinkedCell *LCList = NULL; 597 LCList = new LinkedCell(mol, 10.); 598 FindConvexBorder((ofstream *)&cout, mol, TesselStruct, LCList, NULL); 596 599 double clustervolume = VolumeOfConvexEnvelope((ofstream *)&cout, TesselStruct, configuration); 597 cout << Verbose(0) << "The tesselated surface area is " << clustervolume << "." << endl; 600 cout << Verbose(0) << "The tesselated surface area is " << clustervolume << "." << endl;\ 601 delete(LCList); 598 602 delete(TesselStruct); 599 603 } … … 719 723 cin >> factor[2]; 720 724 valid = true; 721 mol->Scale( &factor);725 mol->Scale((const double ** const)&factor); 722 726 delete[](factor); 723 727 } … … 837 841 } 838 842 if (mol->first->next != mol->last) // if connect matrix is present already, redo it 839 mol->CreateAdjacencyList((ofstream *)&cout, mol->BondDistance, configuration->GetIsAngstroem() );843 mol->CreateAdjacencyList((ofstream *)&cout, mol->BondDistance, configuration->GetIsAngstroem(), &BondGraph::CovalentMinMaxDistance, NULL); 840 844 // free memory 841 845 delete[](Elements); … … 893 897 cin >> bonddistance; 894 898 start = clock(); 895 mol->CreateAdjacencyList((ofstream *)&cout, bonddistance, configuration->GetIsAngstroem()); 896 mol->CreateListOfBondsPerAtom((ofstream *)&cout); 899 mol->CreateAdjacencyList((ofstream *)&cout, bonddistance, configuration->GetIsAngstroem(), &BondGraph::CovalentMinMaxDistance, NULL); 897 900 end = clock(); 898 901 cout << Verbose(0) << "Clocks for this operation: " << (end-start) << ", time: " << ((double)(end-start)/CLOCKS_PER_SEC) << "s." << endl; … … 1247 1250 // translate each to its center and merge all molecules in MoleculeListClass into this molecule 1248 1251 int N = molecules->ListOfMolecules.size(); 1249 int *src = new int (N);1252 int *src = new int[N]; 1250 1253 N=0; 1251 1254 for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++) { … … 1254 1257 } 1255 1258 molecules->SimpleMultiAdd(mol, src, N); 1256 delete (src);1259 delete[](src); 1257 1260 1258 1261 // ... and translate back … … 1354 1357 int argptr; 1355 1358 molecule *mol = NULL; 1359 string BondGraphFileName(""); 1356 1360 strncpy(configuration.databasepath, LocalPath, MAXSTRINGSIZE-1); 1357 1361 … … 1375 1379 cout << "\t-B xx xy xz yy yz zz\tBound atoms by domain with given symmetric matrix of (xx,xy,xz,yy,yz,zz)." << endl; 1376 1380 cout << "\t-c x1 x2 x3\tCenter atoms in domain with a minimum distance to boundary of (x1,x2,x3)." << endl; 1381 cout << "\t-C\tPair Correlation analysis." << endl; 1377 1382 cout << "\t-d x1 x2 x3\tDuplicate cell along each axis by given factor." << endl; 1378 1383 cout << "\t-D <bond distance>\tDepth-First-Search Analysis of the molecule, giving cycles and tree/back edges." << endl; … … 1380 1385 cout << "\t-E <id> <Z>\tChange atom <id>'s element to <Z>, <id> begins at 0." << endl; 1381 1386 cout << "\t-f/F <dist> <order>\tFragments the molecule in BOSSANOVA manner (with/out rings compressed) and stores config files in same dir as config (return code 0 - fragmented, 2 - no fragmentation necessary)." << endl; 1387 cout << "\t-g <file>\tParses a bond length table from the given file." << endl; 1382 1388 cout << "\t-h/-H/-?\tGive this help screen." << endl; 1383 1389 cout << "\t-L <step0> <step1> <prefix>\tStore a linear interpolation between two configurations <step0> and <step1> into single config files with prefix <prefix> and as Trajectories into the current config file." << endl; … … 1416 1422 } 1417 1423 break; 1424 case 'g': 1425 if ((argptr >= argc) || (argv[argptr][0] == '-')) { 1426 cerr << "Not enough or invalid arguments for specifying bond length table: -g <table file>" << endl; 1427 } else { 1428 BondGraphFileName = argv[argptr]; 1429 cout << "Using " << BondGraphFileName << " as bond length table." << endl; 1430 argptr+=1; 1431 } 1432 break; 1418 1433 case 'n': 1419 1434 cout << "I won't parse trajectories." << endl; … … 1428 1443 } while (argptr < argc); 1429 1444 1430 // 2. Parse the element database1445 // 3a. Parse the element database 1431 1446 if (periode->LoadPeriodentafel(configuration.databasepath)) { 1432 1447 cout << Verbose(0) << "Element list loaded successfully." << endl; … … 1436 1451 return 1; 1437 1452 } 1438 // 3 . Find config file name and parse if possible1453 // 3b. Find config file name and parse if possible, also BondGraphFileName 1439 1454 if (argv[1][0] != '-') { 1440 1455 // simply create a new molecule, wherein the config file is loaded and the manipulation takes place 1441 mol = new molecule(periode);1442 mol->ActiveFlag = true;1443 molecules->insert(mol);1444 1445 1456 cout << Verbose(0) << "Config file given." << endl; 1446 1457 test.open(argv[1], ios::in); … … 1461 1472 ConfigFileName = argv[1]; 1462 1473 cout << Verbose(1) << "Specified config file found, parsing ... "; 1463 switch (configuration.TestSyntax(ConfigFileName, periode , mol)) {1474 switch (configuration.TestSyntax(ConfigFileName, periode)) { 1464 1475 case 1: 1465 1476 cout << "new syntax." << endl; 1466 configuration.Load(ConfigFileName, periode, mol);1477 configuration.Load(ConfigFileName, BondGraphFileName, periode, molecules); 1467 1478 configPresent = present; 1468 1479 break; 1469 1480 case 0: 1470 1481 cout << "old syntax." << endl; 1471 configuration.LoadOld(ConfigFileName, periode, mol);1482 configuration.LoadOld(ConfigFileName, BondGraphFileName, periode, molecules); 1472 1483 configPresent = present; 1473 1484 break; … … 1479 1490 } else 1480 1491 configPresent = absent; 1492 // set mol to first active molecule 1493 if (molecules->ListOfMolecules.size() != 0) { 1494 for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++) 1495 if ((*ListRunner)->ActiveFlag) { 1496 mol = *ListRunner; 1497 break; 1498 } 1499 } 1500 if (mol == NULL) { 1501 mol = new molecule(periode); 1502 mol->ActiveFlag = true; 1503 molecules->insert(mol); 1504 } 1505 1481 1506 // 4. parse again through options, now for those depending on elements db and config presence 1482 1507 argptr = 1; … … 1505 1530 case 'a': 1506 1531 if (ExitFlag == 0) ExitFlag = 1; 1507 if ((argptr >= argc) || (argv[argptr][0] == '-') || (!IsValidNumber(argv[argptr+1])) ) {1532 if ((argptr >= argc) || (argv[argptr][0] == '-') || (!IsValidNumber(argv[argptr+1])) || (!IsValidNumber(argv[argptr+2])) || (!IsValidNumber(argv[argptr+3]))) { 1508 1533 ExitFlag = 255; 1509 1534 cerr << "Not enough or invalid arguments for adding atom: -a <element> <x> <y> <z>" << endl; … … 1549 1574 int *MinimumRingSize = new int[mol->AtomCount]; 1550 1575 atom ***ListOfLocalAtoms = NULL; 1551 int FragmentCounter = 0;1552 1576 class StackClass<bond *> *BackEdgeStack = NULL; 1553 1577 class StackClass<bond *> *LocalBackEdgeStack = NULL; 1554 mol->CreateAdjacencyList((ofstream *)&cout, atof(argv[argptr]), configuration.GetIsAngstroem()); 1555 mol->CreateListOfBondsPerAtom((ofstream *)&cout); 1578 mol->CreateAdjacencyList((ofstream *)&cout, atof(argv[argptr]), configuration.GetIsAngstroem(), &BondGraph::CovalentMinMaxDistance, NULL); 1556 1579 Subgraphs = mol->DepthFirstSearchAnalysis((ofstream *)&cout, BackEdgeStack); 1557 1580 if (Subgraphs != NULL) { 1558 Subgraphs->next->FillBondStructureFromReference((ofstream *)&cout, mol, (FragmentCounter = 0), ListOfLocalAtoms, false); // we want to keep the created ListOfLocalAtoms1581 int FragmentCounter = 0; 1559 1582 while (Subgraphs->next != NULL) { 1560 1583 Subgraphs = Subgraphs->next; 1584 Subgraphs->FillBondStructureFromReference((ofstream *)&cout, mol, FragmentCounter, ListOfLocalAtoms, false); // we want to keep the created ListOfLocalAtoms 1561 1585 LocalBackEdgeStack = new StackClass<bond *> (Subgraphs->Leaf->BondCount); 1562 Subgraphs->Leaf->PickLocalBackEdges((ofstream *)&cout, ListOfLocalAtoms[FragmentCounter ++], BackEdgeStack, LocalBackEdgeStack);1563 Subgraphs->Leaf->CyclicStructureAnalysis((ofstream *)&cout, BackEdgeStack, MinimumRingSize);1586 Subgraphs->Leaf->PickLocalBackEdges((ofstream *)&cout, ListOfLocalAtoms[FragmentCounter], BackEdgeStack, LocalBackEdgeStack); 1587 Subgraphs->Leaf->CyclicStructureAnalysis((ofstream *)&cout, LocalBackEdgeStack, MinimumRingSize); 1564 1588 delete(LocalBackEdgeStack); 1565 1589 delete(Subgraphs->previous); 1590 FragmentCounter++; 1566 1591 } 1567 1592 delete(Subgraphs); 1568 1593 for (int i=0;i<FragmentCounter;i++) 1569 Free(&ListOfLocalAtoms[ FragmentCounter]);1594 Free(&ListOfLocalAtoms[i]); 1570 1595 Free(&ListOfLocalAtoms); 1571 1596 } … … 1574 1599 } 1575 1600 //argptr+=1; 1601 break; 1602 case 'C': 1603 if (ExitFlag == 0) ExitFlag = 1; 1604 if ((argptr+2 >= argc) || (!IsValidNumber(argv[argptr])) || (argv[argptr][0] == '-') || (argv[argptr+1][0] == '-') || (argv[argptr+2][0] == '-')) { 1605 ExitFlag = 255; 1606 cerr << "Not enough or invalid arguments given for pair correlation analysis: -C <Z> <output> <bin output>" << endl; 1607 } else { 1608 SaveFlag = false; 1609 ofstream output(argv[argptr+1]); 1610 ofstream binoutput(argv[argptr+2]); 1611 const double radius = 5.; 1612 1613 // get the boundary 1614 class molecule *Boundary = NULL; 1615 class Tesselation *TesselStruct = NULL; 1616 const LinkedCell *LCList = NULL; 1617 // find biggest molecule 1618 int counter = 0; 1619 for (MoleculeList::iterator BigFinder = molecules->ListOfMolecules.begin(); BigFinder != molecules->ListOfMolecules.end(); BigFinder++) { 1620 if ((Boundary == NULL) || (Boundary->AtomCount < (*BigFinder)->AtomCount)) { 1621 Boundary = *BigFinder; 1622 } 1623 counter++; 1624 } 1625 bool *Actives = Malloc<bool>(counter, "ParseCommandLineOptions() - case C -- *Actives"); 1626 counter = 0; 1627 for (MoleculeList::iterator BigFinder = molecules->ListOfMolecules.begin(); BigFinder != molecules->ListOfMolecules.end(); BigFinder++) { 1628 Actives[counter] = (*BigFinder)->ActiveFlag; 1629 (*BigFinder)->ActiveFlag = (*BigFinder == Boundary) ? false : true; 1630 } 1631 LCList = new LinkedCell(Boundary, 2.*radius); 1632 element *elemental = periode->FindElement((const int) atoi(argv[argptr])); 1633 FindNonConvexBorder((ofstream *)&cout, Boundary, TesselStruct, LCList, radius, NULL); 1634 int ranges[NDIM] = {1,1,1}; 1635 CorrelationToSurfaceMap *surfacemap = PeriodicCorrelationToSurface( (ofstream *)&cout, molecules, elemental, TesselStruct, LCList, ranges ); 1636 BinPairMap *binmap = BinData( (ofstream *)&cout, surfacemap, 0.5, 0., 0. ); 1637 OutputCorrelation ( &binoutput, binmap ); 1638 output.close(); 1639 binoutput.close(); 1640 for (MoleculeList::iterator BigFinder = molecules->ListOfMolecules.begin(); BigFinder != molecules->ListOfMolecules.end(); BigFinder++) 1641 (*BigFinder)->ActiveFlag = Actives[counter]; 1642 Free(&Actives); 1643 delete(LCList); 1644 delete(TesselStruct); 1645 argptr+=3; 1646 } 1576 1647 break; 1577 1648 case 'E': … … 1634 1705 cout << "Parsing bonds from " << argv[argptr] << "." << endl; 1635 1706 ifstream *input = new ifstream(argv[argptr]); 1636 mol->CreateAdjacencyList 2((ofstream *)&cout, input);1707 mol->CreateAdjacencyListFromDbondFile((ofstream *)&cout, input); 1637 1708 input->close(); 1638 1709 argptr+=1; … … 1645 1716 cerr << "Not enough or invalid arguments given for non-convex envelope: -o <radius> <tecplot output file>" << endl; 1646 1717 } else { 1647 class Tesselation T; 1718 class Tesselation *T = NULL; 1719 const LinkedCell *LCList = NULL; 1648 1720 string filename(argv[argptr+1]); 1649 1721 filename.append(".csv"); … … 1651 1723 cout << Verbose(1) << "Using rolling ball of radius " << atof(argv[argptr]) << " and storing tecplot data in " << argv[argptr+1] << "." << endl; 1652 1724 start = clock(); 1653 L inkedCell LCList(mol, atof(argv[argptr])*2.);1654 FindNonConvexBorder((ofstream *)&cout, mol, &LCList, atof(argv[argptr]), argv[argptr+1]);1655 //FindDistributionOfEllipsoids((ofstream *)&cout, &T, &LCList, N, number, filename.c_str());1725 LCList = new LinkedCell(mol, atof(argv[argptr])*2.); 1726 FindNonConvexBorder((ofstream *)&cout, mol, T, LCList, atof(argv[argptr]), argv[argptr+1]); 1727 //FindDistributionOfEllipsoids((ofstream *)&cout, T, &LCList, N, number, filename.c_str()); 1656 1728 end = clock(); 1657 1729 cout << Verbose(0) << "Clocks for this operation: " << (end-start) << ", time: " << ((double)(end-start)/CLOCKS_PER_SEC) << "s." << endl; 1730 delete(LCList); 1658 1731 argptr+=2; 1659 1732 } … … 1735 1808 case 't': 1736 1809 if (ExitFlag == 0) ExitFlag = 1; 1737 if ((argptr+2 >= argc) || ( argv[argptr][0] == '-') || (!IsValidNumber(argv[argptr])) || (!IsValidNumber(argv[argptr+1])) || (!IsValidNumber(argv[argptr+2])) ) {1810 if ((argptr+2 >= argc) || (!IsValidNumber(argv[argptr])) || (!IsValidNumber(argv[argptr+1])) || (!IsValidNumber(argv[argptr+2])) ) { 1738 1811 ExitFlag = 255; 1739 1812 cerr << "Not enough or invalid arguments given for translation: -t <x> <y> <z>" << endl; … … 1750 1823 case 'T': 1751 1824 if (ExitFlag == 0) ExitFlag = 1; 1752 if ((argptr+2 >= argc) || ( argv[argptr][0] == '-') || (!IsValidNumber(argv[argptr])) || (!IsValidNumber(argv[argptr+1])) || (!IsValidNumber(argv[argptr+2])) ) {1825 if ((argptr+2 >= argc) || (!IsValidNumber(argv[argptr])) || (!IsValidNumber(argv[argptr+1])) || (!IsValidNumber(argv[argptr+2])) ) { 1753 1826 ExitFlag = 255; 1754 1827 cerr << "Not enough or invalid arguments given for periodic translation: -T <x> <y> <z>" << endl; … … 1765 1838 case 's': 1766 1839 if (ExitFlag == 0) ExitFlag = 1; 1767 if ((argptr >= argc) || ( argv[argptr][0] == '-') || (!IsValidNumber(argv[argptr])) ) {1840 if ((argptr >= argc) || (!IsValidNumber(argv[argptr])) || (!IsValidNumber(argv[argptr+1])) || (!IsValidNumber(argv[argptr+2])) ) { 1768 1841 ExitFlag = 255; 1769 cerr << "Not enough or invalid arguments given for scaling: -s <factor /[factor_x]> [factor_y] [factor_z]" << endl;1842 cerr << "Not enough or invalid arguments given for scaling: -s <factor_x> [factor_y] [factor_z]" << endl; 1770 1843 } else { 1771 1844 SaveFlag = true; … … 1774 1847 factor = new double[NDIM]; 1775 1848 factor[0] = atof(argv[argptr]); 1776 if ((argptr < argc) && (IsValidNumber(argv[argptr]))) 1777 argptr++; 1778 factor[1] = atof(argv[argptr]); 1779 if ((argptr < argc) && (IsValidNumber(argv[argptr]))) 1780 argptr++; 1781 factor[2] = atof(argv[argptr]); 1782 mol->Scale(&factor); 1849 factor[1] = atof(argv[argptr+1]); 1850 factor[2] = atof(argv[argptr+2]); 1851 mol->Scale((const double ** const)&factor); 1783 1852 for (int i=0;i<NDIM;i++) { 1784 1853 j += i+1; … … 1787 1856 } 1788 1857 delete[](factor); 1789 argptr+= 1;1858 argptr+=3; 1790 1859 } 1791 1860 break; … … 1879 1948 cout << Verbose(0) << "Creating connection matrix..." << endl; 1880 1949 start = clock(); 1881 mol->CreateAdjacencyList((ofstream *)&cout, atof(argv[argptr++]), configuration.GetIsAngstroem() );1950 mol->CreateAdjacencyList((ofstream *)&cout, atof(argv[argptr++]), configuration.GetIsAngstroem(), &BondGraph::CovalentMinMaxDistance, NULL); 1882 1951 cout << Verbose(0) << "Fragmenting molecule with current connection matrix ..." << endl; 1883 1952 if (mol->first->next != mol->last) { … … 1909 1978 cerr << "Not enough or invalid arguments given for convex envelope: -o <convex output file> <non-convex output file>" << endl; 1910 1979 } else { 1980 class Tesselation *TesselStruct = NULL; 1981 const LinkedCell *LCList = NULL; 1911 1982 cout << Verbose(0) << "Evaluating volume of the convex envelope."; 1912 1983 cout << Verbose(1) << "Storing tecplot convex data in " << argv[argptr] << "." << endl; 1913 1984 cout << Verbose(1) << "Storing tecplot non-convex data in " << argv[argptr+1] << "." << endl; 1914 L inkedCell LCList(mol, 10.);1915 //FindConvexBorder((ofstream *)&cout, mol, &LCList, argv[argptr]);1916 FindNonConvexBorder((ofstream *)&cout, mol, &LCList, 5., argv[argptr+1]);1917 // RemoveAllBoundaryPoints((ofstream *)&cout, mol->TesselStruct, mol, argv[argptr]);1918 double volumedifference = ConvexizeNonconvexEnvelope((ofstream *)&cout, mol->TesselStruct, mol, argv[argptr]);1919 double clustervolume = VolumeOfConvexEnvelope((ofstream *)&cout, mol->TesselStruct, &configuration);1985 LCList = new LinkedCell(mol, 10.); 1986 //FindConvexBorder((ofstream *)&cout, mol, LCList, argv[argptr]); 1987 FindNonConvexBorder((ofstream *)&cout, mol, TesselStruct, LCList, 5., argv[argptr+1]); 1988 // RemoveAllBoundaryPoints((ofstream *)&cout, TesselStruct, mol, argv[argptr]); 1989 double volumedifference = ConvexizeNonconvexEnvelope((ofstream *)&cout, TesselStruct, mol, argv[argptr]); 1990 double clustervolume = VolumeOfConvexEnvelope((ofstream *)&cout, TesselStruct, &configuration); 1920 1991 cout << Verbose(0) << "The tesselated volume area is " << clustervolume << " " << (configuration.GetIsAngstroem() ? "angstrom" : "atomiclength") << "^3." << endl; 1921 1992 cout << Verbose(0) << "The non-convex tesselated volume area is " << clustervolume-volumedifference << " " << (configuration.GetIsAngstroem() ? "angstrom" : "atomiclength") << "^3." << endl; 1993 delete(TesselStruct); 1994 delete(LCList); 1922 1995 argptr+=2; 1923 1996 } … … 2043 2116 MoleculeListClass *molecules = new MoleculeListClass; // list of all molecules 2044 2117 molecule *mol = NULL; 2045 config configuration;2118 config *configuration = new config; 2046 2119 char choice; // menu choice char 2047 2120 Vector x,y,z,n; // coordinates for absolute point in cell volume … … 2053 2126 2054 2127 // =========================== PARSE COMMAND LINE OPTIONS ==================================== 2055 j = ParseCommandLineOptions(argc, argv, molecules, periode, configuration, ConfigFileName);2128 j = ParseCommandLineOptions(argc, argv, molecules, periode, *configuration, ConfigFileName); 2056 2129 switch(j) { 2057 2130 case 255: // something went wrong 2131 case 2: // just for -f option 2132 case 1: // just for -v and -h options 2058 2133 delete(molecules); // also free's all molecules contained 2059 2134 delete(periode); 2135 delete(configuration); 2060 2136 cout << Verbose(0) << "Maximum of allocated memory: " 2061 2137 << MemoryUsageObserver::getInstance()->getMaximumUsedMemory() << endl; 2062 2138 cout << Verbose(0) << "Remaining non-freed memory: " 2063 2139 << MemoryUsageObserver::getInstance()->getUsedMemorySize() << endl; 2064 return j; 2065 break; 2066 case 1: // just for -v and -h options 2067 delete(molecules); // also free's all molecules contained 2068 delete(periode); 2069 cout << Verbose(0) << "Maximum of allocated memory: " 2070 << MemoryUsageObserver::getInstance()->getMaximumUsedMemory() << endl; 2071 cout << Verbose(0) << "Remaining non-freed memory: " 2072 << MemoryUsageObserver::getInstance()->getUsedMemorySize() << endl; 2073 return 0; 2074 break; 2075 case 2: // just for -f option 2076 delete(molecules); // also free's all molecules contained 2077 delete(periode); 2078 cout << Verbose(0) << "Maximum of allocated memory: " 2079 << MemoryUsageObserver::getInstance()->getMaximumUsedMemory() << endl; 2080 cout << Verbose(0) << "Remaining non-freed memory: " 2081 << MemoryUsageObserver::getInstance()->getUsedMemorySize() << endl; 2082 return 2; 2083 break; 2140 MemoryUsageObserver::getInstance()->purgeInstance(); 2141 return (j == 1 ? 0 : j); 2084 2142 default: 2085 2143 break; … … 2096 2154 } 2097 2155 } 2156 mol->ActiveFlag = true; 2098 2157 molecules->insert(mol); 2099 2158 } … … 2135 2194 2136 2195 case 'c': // edit each field of the configuration 2137 configuration .Edit();2196 configuration->Edit(); 2138 2197 break; 2139 2198 … … 2143 2202 2144 2203 case 'g': // manipulate molecules 2145 ManipulateMolecules(periode, molecules, &configuration);2204 ManipulateMolecules(periode, molecules, configuration); 2146 2205 break; 2147 2206 … … 2151 2210 2152 2211 case 'm': // manipulate atoms 2153 ManipulateAtoms(periode, molecules, &configuration);2212 ManipulateAtoms(periode, molecules, configuration); 2154 2213 break; 2155 2214 … … 2158 2217 2159 2218 case 's': // save to config file 2160 SaveConfig(ConfigFileName, &configuration, periode, molecules);2219 SaveConfig(ConfigFileName, configuration, periode, molecules); 2161 2220 break; 2162 2221 … … 2171 2230 2172 2231 // save element data base 2173 if (periode->StorePeriodentafel(configuration .databasepath)) //ElementsFileName2232 if (periode->StorePeriodentafel(configuration->databasepath)) //ElementsFileName 2174 2233 cout << Verbose(0) << "Saving of elements.db successful." << endl; 2175 2234 else … … 2178 2237 delete(molecules); // also free's all molecules contained 2179 2238 delete(periode); 2239 delete(configuration); 2180 2240 2181 2241 cout << Verbose(0) << "Maximum of allocated memory: " … … 2183 2243 cout << Verbose(0) << "Remaining non-freed memory: " 2184 2244 << MemoryUsageObserver::getInstance()->getUsedMemorySize() << endl; 2245 MemoryUsageObserver::purgeInstance(); 2185 2246 2186 2247 return (0); -
src/config.cpp
-
Property mode
changed from
100755
to100644
r06c7a3 r7326b2 8 8 #include "config.hpp" 9 9 #include "element.hpp" 10 #include "helpers.hpp" 11 #include "lists.hpp" 12 #include "molecule.hpp" 10 13 #include "memoryallocator.hpp" 11 14 #include "molecule.hpp" … … 50 53 /** Constructor for ConfigFileBuffer class. 51 54 */ 52 ConfigFileBuffer::ConfigFileBuffer() 55 ConfigFileBuffer::ConfigFileBuffer() : buffer(NULL), LineMapping(NULL), CurrentLine(0), NoLines(0) 53 56 { 54 NoLines = 0; 55 CurrentLine = 0; 56 buffer = NULL; 57 LineMapping = NULL; 58 } 57 }; 59 58 60 59 /** Constructor for ConfigFileBuffer class with filename to be parsed. 61 60 * \param *filename file name 62 61 */ 63 ConfigFileBuffer::ConfigFileBuffer(c har *filename)62 ConfigFileBuffer::ConfigFileBuffer(const char * const filename) : buffer(NULL), LineMapping(NULL), CurrentLine(0), NoLines(0) 64 63 { 65 NoLines = 0;66 CurrentLine = 0;67 buffer = NULL;68 LineMapping = NULL;69 64 ifstream *file = NULL; 70 65 char line[MAXSTRINGSIZE]; … … 139 134 * \param NoAtoms of subsequent lines to look at 140 135 */ 141 void ConfigFileBuffer::MapIonTypesInBuffer( int NoAtoms)136 void ConfigFileBuffer::MapIonTypesInBuffer(const int NoAtoms) 142 137 { 143 138 map<const char *, int, IonTypeCompare> LineList; … … 166 161 /** Constructor for config file class. 167 162 */ 168 config::config() 169 { 163 config::config() : BG(NULL), PsiType(0), MaxPsiDouble(0), PsiMaxNoUp(0), PsiMaxNoDown(0), MaxMinStopStep(1), InitMaxMinStopStep(1), ProcPEGamma(8), ProcPEPsi(1), configpath(NULL), 164 configname(NULL), FastParsing(false), Deltat(0.01), basis(""), databasepath(NULL), DoConstrainedMD(0), MaxOuterStep(0), Thermostat(4), ThermostatImplemented(NULL), 165 ThermostatNames(NULL), TempFrequency(2.5), alpha(0.), HooverMass(0.), TargetTemp(0.00095004455), ScaleTempStep(25), mainname(NULL), defaultpath(NULL), pseudopotpath(NULL), 166 DoOutVis(0), DoOutMes(1), DoOutNICS(0), DoOutOrbitals(0), DoOutCurrent(0), DoFullCurrent(0), DoPerturbation(0), DoWannier(0), CommonWannier(0), SawtoothStart(0.01), 167 VectorPlane(0), VectorCut(0.), UseAddGramSch(1), Seed(1), OutVisStep(10), OutSrcStep(5), MaxPsiStep(0), EpsWannier(1e-7), MaxMinStep(100), RelEpsTotalEnergy(1e-7), 168 RelEpsKineticEnergy(1e-5), MaxMinGapStopStep(0), MaxInitMinStep(100), InitRelEpsTotalEnergy(1e-5), InitRelEpsKineticEnergy(1e-4), InitMaxMinGapStopStep(0), ECut(128.), 169 MaxLevel(5), RiemannTensor(0), LevRFactor(0), RiemannLevel(0), Lev0Factor(2), RTActualUse(0), AddPsis(0), RCut(20.), StructOpt(0), IsAngstroem(1), RelativeCoord(0), 170 MaxTypes(0) { 170 171 mainname = Malloc<char>(MAXSTRINGSIZE,"config constructor: mainname"); 171 172 defaultpath = Malloc<char>(MAXSTRINGSIZE,"config constructor: defaultpath"); … … 174 175 configpath = Malloc<char>(MAXSTRINGSIZE,"config constructor: configpath"); 175 176 configname = Malloc<char>(MAXSTRINGSIZE,"config constructor: configname"); 176 ThermostatImplemented = Malloc<int>(MaxThermostats, "config constructor: *ThermostatImplemented");177 ThermostatNames = Malloc<char*>(MaxThermostats, "config constructor: *ThermostatNames");178 for (int j=0;j<MaxThermostats;j++)179 ThermostatNames[j] = Malloc<char>(12, "config constructor: ThermostatNames[]");180 Thermostat = 4;181 alpha = 0.;182 ScaleTempStep = 25;183 TempFrequency = 2.5;184 177 strcpy(mainname,"pcp"); 185 178 strcpy(defaultpath,"not specified"); … … 189 182 basis = "3-21G"; 190 183 191 strcpy(ThermostatNames[0],"None"); 192 ThermostatImplemented[0] = 1; 193 strcpy(ThermostatNames[1],"Woodcock"); 194 ThermostatImplemented[1] = 1; 195 strcpy(ThermostatNames[2],"Gaussian"); 196 ThermostatImplemented[2] = 1; 197 strcpy(ThermostatNames[3],"Langevin"); 198 ThermostatImplemented[3] = 1; 199 strcpy(ThermostatNames[4],"Berendsen"); 200 ThermostatImplemented[4] = 1; 201 strcpy(ThermostatNames[5],"NoseHoover"); 202 ThermostatImplemented[5] = 1; 203 204 FastParsing = false; 205 ProcPEGamma=8; 206 ProcPEPsi=1; 207 DoOutVis=0; 208 DoOutMes=1; 209 DoOutNICS=0; 210 DoOutOrbitals=0; 211 DoOutCurrent=0; 212 DoPerturbation=0; 213 DoFullCurrent=0; 214 DoWannier=0; 215 DoConstrainedMD=0; 216 CommonWannier=0; 217 SawtoothStart=0.01; 218 VectorPlane=0; 219 VectorCut=0; 220 UseAddGramSch=1; 221 Seed=1; 222 223 MaxOuterStep=0; 224 Deltat=0.01; 225 OutVisStep=10; 226 OutSrcStep=5; 227 TargetTemp=0.00095004455; 228 ScaleTempStep=25; 229 MaxPsiStep=0; 230 EpsWannier=1e-7; 231 232 MaxMinStep=100; 233 RelEpsTotalEnergy=1e-7; 234 RelEpsKineticEnergy=1e-5; 235 MaxMinStopStep=1; 236 MaxMinGapStopStep=0; 237 MaxInitMinStep=100; 238 InitRelEpsTotalEnergy=1e-5; 239 InitRelEpsKineticEnergy=1e-4; 240 InitMaxMinStopStep=1; 241 InitMaxMinGapStopStep=0; 242 243 //BoxLength[NDIM*NDIM]; 244 245 ECut=128.; 246 MaxLevel=5; 247 RiemannTensor=0; 248 LevRFactor=0; 249 RiemannLevel=0; 250 Lev0Factor=2; 251 RTActualUse=0; 252 PsiType=0; 253 MaxPsiDouble=0; 254 PsiMaxNoUp=0; 255 PsiMaxNoDown=0; 256 AddPsis=0; 257 258 RCut=20.; 259 StructOpt=0; 260 IsAngstroem=1; 261 RelativeCoord=0; 262 MaxTypes=0; 184 InitThermostats(); 263 185 }; 264 265 186 266 187 /** Destructor for config file class. … … 278 199 Free(&ThermostatNames[j]); 279 200 Free(&ThermostatNames); 201 if (BG != NULL) 202 delete(BG); 203 }; 204 205 /** Initialises variables in class config for Thermostats. 206 */ 207 void config::InitThermostats() 208 { 209 ThermostatImplemented = Malloc<int>(MaxThermostats, "config constructor: *ThermostatImplemented"); 210 ThermostatNames = Malloc<char*>(MaxThermostats, "config constructor: *ThermostatNames"); 211 for (int j=0;j<MaxThermostats;j++) 212 ThermostatNames[j] = Malloc<char>(12, "config constructor: ThermostatNames[]"); 213 214 strcpy(ThermostatNames[0],"None"); 215 ThermostatImplemented[0] = 1; 216 strcpy(ThermostatNames[1],"Woodcock"); 217 ThermostatImplemented[1] = 1; 218 strcpy(ThermostatNames[2],"Gaussian"); 219 ThermostatImplemented[2] = 1; 220 strcpy(ThermostatNames[3],"Langevin"); 221 ThermostatImplemented[3] = 1; 222 strcpy(ThermostatNames[4],"Berendsen"); 223 ThermostatImplemented[4] = 1; 224 strcpy(ThermostatNames[5],"NoseHoover"); 225 ThermostatImplemented[5] = 1; 280 226 }; 281 227 … … 283 229 * \param *fb file buffer containing the config file 284 230 */ 285 void config:: InitThermostats(class ConfigFileBuffer *fb)231 void config::ParseThermostats(class ConfigFileBuffer * const fb) 286 232 { 287 char * thermo = Malloc<char>(12, "IonsInitRead: thermo");288 int verbose = 0;233 char * const thermo = Malloc<char>(12, "IonsInitRead: thermo"); 234 const int verbose = 0; 289 235 290 236 // read desired Thermostat from file along with needed additional parameters … … 352 298 Thermostat = None; 353 299 } 354 Free( &thermo);300 Free(thermo); 355 301 }; 356 302 … … 622 568 * \param *filename filename of config file to be tested 623 569 * \param *periode pointer to a periodentafel class with all elements 624 * \param *mol pointer to molecule containing all atoms of the molecule625 570 * \return 0 - old syntax, 1 - new syntax, -1 - unknown syntax 626 571 */ 627 int config::TestSyntax(c har *filename, periodentafel *periode, molecule *mol)572 int config::TestSyntax(const char * const filename, const periodentafel * const periode) const 628 573 { 629 574 int test; … … 664 609 * \return *defaultpath 665 610 */ 666 void config::SetDefaultPath(const char * path)611 void config::SetDefaultPath(const char * const path) 667 612 { 668 613 strcpy(defaultpath, path); … … 672 617 * \param filename config file string 673 618 */ 674 void config::RetrieveConfigPathAndName( string filename)619 void config::RetrieveConfigPathAndName(const string filename) 675 620 { 676 621 char *ptr = NULL; … … 696 641 }; 697 642 698 699 /** Initializes config file structure by loading elements from a give file. 643 /** Initializes ConfigFileBuffer from a file. 700 644 * \param *file input file stream being the opened config file 701 * \param *periode pointer to a periodentafel class with all elements 702 * \param *mol pointer to molecule containing all atoms of the molecule 703 */ 704 void config::Load(char *filename, periodentafel *periode, molecule *mol) 645 * \param *FileBuffer pointer to FileBuffer on return, should point to NULL 646 */ 647 void PrepareFileBuffer(const char * const filename, struct ConfigFileBuffer *&FileBuffer) 705 648 { 706 ifstream *file = new ifstream(filename); 707 if (file == NULL) { 708 cerr << "ERROR: config file " << filename << " missing!" << endl; 709 return; 710 } 711 file->close(); 712 delete(file); 713 RetrieveConfigPathAndName(filename); 714 715 // ParseParameterFile 716 struct ConfigFileBuffer *FileBuffer = new ConfigFileBuffer(filename); 649 if (FileBuffer != NULL) { 650 cerr << Verbose(1) << "WARNING: deleting present FileBuffer in PrepareFileBuffer()." << endl; 651 delete(FileBuffer); 652 } 653 FileBuffer = new ConfigFileBuffer(filename); 654 717 655 FileBuffer->InitMapping(); 718 719 /* Oeffne Hauptparameterdatei */ 720 int di; 721 double BoxLength[9]; 722 string zeile; 723 string dummy; 656 }; 657 658 /** Loads a molecule from a ConfigFileBuffer. 659 * \param *mol molecule to load 660 * \param *FileBuffer ConfigFileBuffer to use 661 * \param *periode periodentafel for finding elements 662 * \param FastParsing whether to parse trajectories or not 663 */ 664 void LoadMolecule(molecule * const &mol, struct ConfigFileBuffer * const &FileBuffer, const periodentafel * const periode, const bool FastParsing) 665 { 666 int MaxTypes = 0; 724 667 element *elementhash[MAX_ELEMENTS]; 725 668 char name[MAX_ELEMENTS]; 726 669 char keyword[MAX_ELEMENTS]; 727 int Z, No[MAX_ELEMENTS]; 670 int Z = -1; 671 int No[MAX_ELEMENTS]; 728 672 int verbose = 0; 729 673 double value[3]; 730 731 InitThermostats(FileBuffer); 732 733 /* Namen einlesen */ 734 735 ParseForParameter(verbose,FileBuffer, "mainname", 0, 1, 1, string_type, (config::mainname), 1, critical); 736 ParseForParameter(verbose,FileBuffer, "defaultpath", 0, 1, 1, string_type, (config::defaultpath), 1, critical); 737 ParseForParameter(verbose,FileBuffer, "pseudopotpath", 0, 1, 1, string_type, (config::pseudopotpath), 1, critical); 738 ParseForParameter(verbose,FileBuffer,"ProcPEGamma", 0, 1, 1, int_type, &(config::ProcPEGamma), 1, critical); 739 ParseForParameter(verbose,FileBuffer,"ProcPEPsi", 0, 1, 1, int_type, &(config::ProcPEPsi), 1, critical); 740 741 if (!ParseForParameter(verbose,FileBuffer,"Seed", 0, 1, 1, int_type, &(config::Seed), 1, optional)) 742 config::Seed = 1; 743 744 if(!ParseForParameter(verbose,FileBuffer,"DoOutOrbitals", 0, 1, 1, int_type, &(config::DoOutOrbitals), 1, optional)) { 745 config::DoOutOrbitals = 0; 746 } else { 747 if (config::DoOutOrbitals < 0) config::DoOutOrbitals = 0; 748 if (config::DoOutOrbitals > 1) config::DoOutOrbitals = 1; 749 } 750 ParseForParameter(verbose,FileBuffer,"DoOutVis", 0, 1, 1, int_type, &(config::DoOutVis), 1, critical); 751 if (config::DoOutVis < 0) config::DoOutVis = 0; 752 if (config::DoOutVis > 1) config::DoOutVis = 1; 753 if (!ParseForParameter(verbose,FileBuffer,"VectorPlane", 0, 1, 1, int_type, &(config::VectorPlane), 1, optional)) 754 config::VectorPlane = -1; 755 if (!ParseForParameter(verbose,FileBuffer,"VectorCut", 0, 1, 1, double_type, &(config::VectorCut), 1, optional)) 756 config::VectorCut = 0.; 757 ParseForParameter(verbose,FileBuffer,"DoOutMes", 0, 1, 1, int_type, &(config::DoOutMes), 1, critical); 758 if (config::DoOutMes < 0) config::DoOutMes = 0; 759 if (config::DoOutMes > 1) config::DoOutMes = 1; 760 if (!ParseForParameter(verbose,FileBuffer,"DoOutCurr", 0, 1, 1, int_type, &(config::DoOutCurrent), 1, optional)) 761 config::DoOutCurrent = 0; 762 if (config::DoOutCurrent < 0) config::DoOutCurrent = 0; 763 if (config::DoOutCurrent > 1) config::DoOutCurrent = 1; 764 ParseForParameter(verbose,FileBuffer,"AddGramSch", 0, 1, 1, int_type, &(config::UseAddGramSch), 1, critical); 765 if (config::UseAddGramSch < 0) config::UseAddGramSch = 0; 766 if (config::UseAddGramSch > 2) config::UseAddGramSch = 2; 767 if(!ParseForParameter(verbose,FileBuffer,"DoWannier", 0, 1, 1, int_type, &(config::DoWannier), 1, optional)) { 768 config::DoWannier = 0; 769 } else { 770 if (config::DoWannier < 0) config::DoWannier = 0; 771 if (config::DoWannier > 1) config::DoWannier = 1; 772 } 773 if(!ParseForParameter(verbose,FileBuffer,"CommonWannier", 0, 1, 1, int_type, &(config::CommonWannier), 1, optional)) { 774 config::CommonWannier = 0; 775 } else { 776 if (config::CommonWannier < 0) config::CommonWannier = 0; 777 if (config::CommonWannier > 4) config::CommonWannier = 4; 778 } 779 if(!ParseForParameter(verbose,FileBuffer,"SawtoothStart", 0, 1, 1, double_type, &(config::SawtoothStart), 1, optional)) { 780 config::SawtoothStart = 0.01; 781 } else { 782 if (config::SawtoothStart < 0.) config::SawtoothStart = 0.; 783 if (config::SawtoothStart > 1.) config::SawtoothStart = 1.; 784 } 785 786 if (ParseForParameter(verbose,FileBuffer,"DoConstrainedMD", 0, 1, 1, int_type, &(config::DoConstrainedMD), 1, optional)) 787 if (config::DoConstrainedMD < 0) 788 config::DoConstrainedMD = 0; 789 ParseForParameter(verbose,FileBuffer,"MaxOuterStep", 0, 1, 1, int_type, &(config::MaxOuterStep), 1, critical); 790 if (!ParseForParameter(verbose,FileBuffer,"Deltat", 0, 1, 1, double_type, &(config::Deltat), 1, optional)) 791 config::Deltat = 1; 792 ParseForParameter(verbose,FileBuffer,"OutVisStep", 0, 1, 1, int_type, &(config::OutVisStep), 1, optional); 793 ParseForParameter(verbose,FileBuffer,"OutSrcStep", 0, 1, 1, int_type, &(config::OutSrcStep), 1, optional); 794 ParseForParameter(verbose,FileBuffer,"TargetTemp", 0, 1, 1, double_type, &(config::TargetTemp), 1, optional); 795 //ParseForParameter(verbose,FileBuffer,"Thermostat", 0, 1, 1, int_type, &(config::ScaleTempStep), 1, optional); 796 if (!ParseForParameter(verbose,FileBuffer,"EpsWannier", 0, 1, 1, double_type, &(config::EpsWannier), 1, optional)) 797 config::EpsWannier = 1e-8; 798 799 // stop conditions 800 //if (config::MaxOuterStep <= 0) config::MaxOuterStep = 1; 801 ParseForParameter(verbose,FileBuffer,"MaxPsiStep", 0, 1, 1, int_type, &(config::MaxPsiStep), 1, critical); 802 if (config::MaxPsiStep <= 0) config::MaxPsiStep = 3; 803 804 ParseForParameter(verbose,FileBuffer,"MaxMinStep", 0, 1, 1, int_type, &(config::MaxMinStep), 1, critical); 805 ParseForParameter(verbose,FileBuffer,"RelEpsTotalE", 0, 1, 1, double_type, &(config::RelEpsTotalEnergy), 1, critical); 806 ParseForParameter(verbose,FileBuffer,"RelEpsKineticE", 0, 1, 1, double_type, &(config::RelEpsKineticEnergy), 1, critical); 807 ParseForParameter(verbose,FileBuffer,"MaxMinStopStep", 0, 1, 1, int_type, &(config::MaxMinStopStep), 1, critical); 808 ParseForParameter(verbose,FileBuffer,"MaxMinGapStopStep", 0, 1, 1, int_type, &(config::MaxMinGapStopStep), 1, critical); 809 if (config::MaxMinStep <= 0) config::MaxMinStep = config::MaxPsiStep; 810 if (config::MaxMinStopStep < 1) config::MaxMinStopStep = 1; 811 if (config::MaxMinGapStopStep < 1) config::MaxMinGapStopStep = 1; 812 813 ParseForParameter(verbose,FileBuffer,"MaxInitMinStep", 0, 1, 1, int_type, &(config::MaxInitMinStep), 1, critical); 814 ParseForParameter(verbose,FileBuffer,"InitRelEpsTotalE", 0, 1, 1, double_type, &(config::InitRelEpsTotalEnergy), 1, critical); 815 ParseForParameter(verbose,FileBuffer,"InitRelEpsKineticE", 0, 1, 1, double_type, &(config::InitRelEpsKineticEnergy), 1, critical); 816 ParseForParameter(verbose,FileBuffer,"InitMaxMinStopStep", 0, 1, 1, int_type, &(config::InitMaxMinStopStep), 1, critical); 817 ParseForParameter(verbose,FileBuffer,"InitMaxMinGapStopStep", 0, 1, 1, int_type, &(config::InitMaxMinGapStopStep), 1, critical); 818 if (config::MaxInitMinStep <= 0) config::MaxInitMinStep = config::MaxPsiStep; 819 if (config::InitMaxMinStopStep < 1) config::InitMaxMinStopStep = 1; 820 if (config::InitMaxMinGapStopStep < 1) config::InitMaxMinGapStopStep = 1; 821 822 // Unit cell and magnetic field 823 ParseForParameter(verbose,FileBuffer, "BoxLength", 0, 3, 3, lower_trigrid, BoxLength, 1, critical); /* Lattice->RealBasis */ 824 mol->cell_size[0] = BoxLength[0]; 825 mol->cell_size[1] = BoxLength[3]; 826 mol->cell_size[2] = BoxLength[4]; 827 mol->cell_size[3] = BoxLength[6]; 828 mol->cell_size[4] = BoxLength[7]; 829 mol->cell_size[5] = BoxLength[8]; 830 //if (1) fprintf(stderr,"\n"); 831 832 ParseForParameter(verbose,FileBuffer,"DoPerturbation", 0, 1, 1, int_type, &(config::DoPerturbation), 1, optional); 833 ParseForParameter(verbose,FileBuffer,"DoOutNICS", 0, 1, 1, int_type, &(config::DoOutNICS), 1, optional); 834 if (!ParseForParameter(verbose,FileBuffer,"DoFullCurrent", 0, 1, 1, int_type, &(config::DoFullCurrent), 1, optional)) 835 config::DoFullCurrent = 0; 836 if (config::DoFullCurrent < 0) config::DoFullCurrent = 0; 837 if (config::DoFullCurrent > 2) config::DoFullCurrent = 2; 838 if (config::DoOutNICS < 0) config::DoOutNICS = 0; 839 if (config::DoOutNICS > 2) config::DoOutNICS = 2; 840 if (config::DoPerturbation == 0) { 841 config::DoFullCurrent = 0; 842 config::DoOutNICS = 0; 843 } 844 845 ParseForParameter(verbose,FileBuffer,"ECut", 0, 1, 1, double_type, &(config::ECut), 1, critical); 846 ParseForParameter(verbose,FileBuffer,"MaxLevel", 0, 1, 1, int_type, &(config::MaxLevel), 1, critical); 847 ParseForParameter(verbose,FileBuffer,"Level0Factor", 0, 1, 1, int_type, &(config::Lev0Factor), 1, critical); 848 if (config::Lev0Factor < 2) { 849 config::Lev0Factor = 2; 850 } 851 ParseForParameter(verbose,FileBuffer,"RiemannTensor", 0, 1, 1, int_type, &di, 1, critical); 852 if (di >= 0 && di < 2) { 853 config::RiemannTensor = di; 854 } else { 855 fprintf(stderr, "0 <= RiemanTensor < 2: 0 UseNotRT, 1 UseRT"); 856 exit(1); 857 } 858 switch (config::RiemannTensor) { 859 case 0: //UseNoRT 860 if (config::MaxLevel < 2) { 861 config::MaxLevel = 2; 862 } 863 config::LevRFactor = 2; 864 config::RTActualUse = 0; 865 break; 866 case 1: // UseRT 867 if (config::MaxLevel < 3) { 868 config::MaxLevel = 3; 869 } 870 ParseForParameter(verbose,FileBuffer,"RiemannLevel", 0, 1, 1, int_type, &(config::RiemannLevel), 1, critical); 871 if (config::RiemannLevel < 2) { 872 config::RiemannLevel = 2; 873 } 874 if (config::RiemannLevel > config::MaxLevel-1) { 875 config::RiemannLevel = config::MaxLevel-1; 876 } 877 ParseForParameter(verbose,FileBuffer,"LevRFactor", 0, 1, 1, int_type, &(config::LevRFactor), 1, critical); 878 if (config::LevRFactor < 2) { 879 config::LevRFactor = 2; 880 } 881 config::Lev0Factor = 2; 882 config::RTActualUse = 2; 883 break; 884 } 885 ParseForParameter(verbose,FileBuffer,"PsiType", 0, 1, 1, int_type, &di, 1, critical); 886 if (di >= 0 && di < 2) { 887 config::PsiType = di; 888 } else { 889 fprintf(stderr, "0 <= PsiType < 2: 0 UseSpinDouble, 1 UseSpinUpDown"); 890 exit(1); 891 } 892 switch (config::PsiType) { 893 case 0: // SpinDouble 894 ParseForParameter(verbose,FileBuffer,"MaxPsiDouble", 0, 1, 1, int_type, &(config::MaxPsiDouble), 1, critical); 895 ParseForParameter(verbose,FileBuffer,"AddPsis", 0, 1, 1, int_type, &(config::AddPsis), 1, optional); 896 break; 897 case 1: // SpinUpDown 898 if (config::ProcPEGamma % 2) config::ProcPEGamma*=2; 899 ParseForParameter(verbose,FileBuffer,"PsiMaxNoUp", 0, 1, 1, int_type, &(config::PsiMaxNoUp), 1, critical); 900 ParseForParameter(verbose,FileBuffer,"PsiMaxNoDown", 0, 1, 1, int_type, &(config::PsiMaxNoDown), 1, critical); 901 ParseForParameter(verbose,FileBuffer,"AddPsis", 0, 1, 1, int_type, &(config::AddPsis), 1, optional); 902 break; 903 } 904 905 // IonsInitRead 906 907 ParseForParameter(verbose,FileBuffer,"RCut", 0, 1, 1, double_type, &(config::RCut), 1, critical); 908 ParseForParameter(verbose,FileBuffer,"IsAngstroem", 0, 1, 1, int_type, &(config::IsAngstroem), 1, critical); 909 ParseForParameter(verbose,FileBuffer,"MaxTypes", 0, 1, 1, int_type, &(config::MaxTypes), 1, critical); 910 if (!ParseForParameter(verbose,FileBuffer,"RelativeCoord", 0, 1, 1, int_type, &(config::RelativeCoord) , 1, optional)) 911 config::RelativeCoord = 0; 912 if (!ParseForParameter(verbose,FileBuffer,"StructOpt", 0, 1, 1, int_type, &(config::StructOpt), 1, optional)) 913 config::StructOpt = 0; 674 675 if (mol == NULL) { 676 cerr << "Molecule is not allocated in LoadMolecule(), exit."; 677 performCriticalExit(); 678 } 679 680 ParseForParameter(verbose,FileBuffer,"MaxTypes", 0, 1, 1, int_type, &(MaxTypes), 1, critical); 914 681 if (MaxTypes == 0) { 915 682 cerr << "There are no atoms according to MaxTypes in this config file." << endl; … … 918 685 cout << Verbose(0) << "Prescanning ions per type: " << endl; 919 686 int NoAtoms = 0; 920 for (int i=0; i < config::MaxTypes; i++) {687 for (int i=0; i < MaxTypes; i++) { 921 688 sprintf(name,"Ion_Type%i",i+1); 922 689 ParseForParameter(verbose,FileBuffer, (const char*)name, 0, 1, 1, int_type, &No[i], 1, critical); … … 929 696 930 697 // sort the lines via the LineMapping 931 sprintf(name,"Ion_Type%i", config::MaxTypes);698 sprintf(name,"Ion_Type%i",MaxTypes); 932 699 if (!ParseForParameter(verbose,FileBuffer, (const char*)name, 1, 1, 1, int_type, &value[0], 1, critical)) { 933 700 cerr << "There are no atoms in the config file!" << endl; … … 941 708 //} 942 709 943 map<int, atom *> AtomList[ config::MaxTypes];710 map<int, atom *> AtomList[MaxTypes]; 944 711 map<int, atom *> LinearList; 945 712 atom *neues = NULL; … … 949 716 while (status) { 950 717 cout << "Currently parsing MD step " << repetition << "." << endl; 951 for (int i=0; i < config::MaxTypes; i++) {718 for (int i=0; i < MaxTypes; i++) { 952 719 sprintf(name,"Ion_Type%i",i+1); 953 720 for(int j=0;j<No[i];j++) { … … 1028 795 cout << "I found " << repetition << " times the keyword Ion_Type1_1." << endl; 1029 796 // parse in molecule coordinates 1030 for (int i=0; i < config::MaxTypes; i++) {797 for (int i=0; i < MaxTypes; i++) { 1031 798 sprintf(name,"Ion_Type%i",i+1); 1032 799 for(int j=0;j<No[i];j++) { … … 1061 828 } 1062 829 } 1063 delete(FileBuffer);1064 830 }; 1065 831 1066 /** Initializes config file structure by loading elements from a give file with old pcp syntax. 1067 * \param *file input file stream being the opened config file with old pcp syntax 832 833 /** Initializes config file structure by loading elements from a give file. 834 * \param *file input file stream being the opened config file 835 * \param BondGraphFileName file name of the bond length table file, if string is left blank, no table is parsed. 1068 836 * \param *periode pointer to a periodentafel class with all elements 1069 * \param * mol pointer to molecule containing all atoms of the molecule1070 */ 1071 void config::Load Old(char *filename, periodentafel *periode, molecule *mol)837 * \param *&MolList pointer to MoleculeListClass, on return containing all parsed molecules in system 838 */ 839 void config::Load(const char * const filename, const string &BondGraphFileName, const periodentafel * const periode, MoleculeListClass * const &MolList) 1072 840 { 841 molecule *mol = new molecule(periode); 1073 842 ifstream *file = new ifstream(filename); 1074 843 if (file == NULL) { … … 1076 845 return; 1077 846 } 847 file->close(); 848 delete(file); 849 RetrieveConfigPathAndName(filename); 850 851 // ParseParameterFile 852 struct ConfigFileBuffer *FileBuffer = NULL; 853 PrepareFileBuffer(filename,FileBuffer); 854 855 /* Oeffne Hauptparameterdatei */ 856 int di = 0; 857 double BoxLength[9]; 858 string zeile; 859 string dummy; 860 int verbose = 0; 861 862 ParseThermostats(FileBuffer); 863 864 /* Namen einlesen */ 865 866 // 1. parse in options 867 ParseForParameter(verbose,FileBuffer, "mainname", 0, 1, 1, string_type, (config::mainname), 1, critical); 868 ParseForParameter(verbose,FileBuffer, "defaultpath", 0, 1, 1, string_type, (config::defaultpath), 1, critical); 869 ParseForParameter(verbose,FileBuffer, "pseudopotpath", 0, 1, 1, string_type, (config::pseudopotpath), 1, critical); 870 ParseForParameter(verbose,FileBuffer,"ProcPEGamma", 0, 1, 1, int_type, &(config::ProcPEGamma), 1, critical); 871 ParseForParameter(verbose,FileBuffer,"ProcPEPsi", 0, 1, 1, int_type, &(config::ProcPEPsi), 1, critical); 872 873 if (!ParseForParameter(verbose,FileBuffer,"Seed", 0, 1, 1, int_type, &(config::Seed), 1, optional)) 874 config::Seed = 1; 875 876 if(!ParseForParameter(verbose,FileBuffer,"DoOutOrbitals", 0, 1, 1, int_type, &(config::DoOutOrbitals), 1, optional)) { 877 config::DoOutOrbitals = 0; 878 } else { 879 if (config::DoOutOrbitals < 0) config::DoOutOrbitals = 0; 880 if (config::DoOutOrbitals > 1) config::DoOutOrbitals = 1; 881 } 882 ParseForParameter(verbose,FileBuffer,"DoOutVis", 0, 1, 1, int_type, &(config::DoOutVis), 1, critical); 883 if (config::DoOutVis < 0) config::DoOutVis = 0; 884 if (config::DoOutVis > 1) config::DoOutVis = 1; 885 if (!ParseForParameter(verbose,FileBuffer,"VectorPlane", 0, 1, 1, int_type, &(config::VectorPlane), 1, optional)) 886 config::VectorPlane = -1; 887 if (!ParseForParameter(verbose,FileBuffer,"VectorCut", 0, 1, 1, double_type, &(config::VectorCut), 1, optional)) 888 config::VectorCut = 0.; 889 ParseForParameter(verbose,FileBuffer,"DoOutMes", 0, 1, 1, int_type, &(config::DoOutMes), 1, critical); 890 if (config::DoOutMes < 0) config::DoOutMes = 0; 891 if (config::DoOutMes > 1) config::DoOutMes = 1; 892 if (!ParseForParameter(verbose,FileBuffer,"DoOutCurr", 0, 1, 1, int_type, &(config::DoOutCurrent), 1, optional)) 893 config::DoOutCurrent = 0; 894 if (config::DoOutCurrent < 0) config::DoOutCurrent = 0; 895 if (config::DoOutCurrent > 1) config::DoOutCurrent = 1; 896 ParseForParameter(verbose,FileBuffer,"AddGramSch", 0, 1, 1, int_type, &(config::UseAddGramSch), 1, critical); 897 if (config::UseAddGramSch < 0) config::UseAddGramSch = 0; 898 if (config::UseAddGramSch > 2) config::UseAddGramSch = 2; 899 if(!ParseForParameter(verbose,FileBuffer,"DoWannier", 0, 1, 1, int_type, &(config::DoWannier), 1, optional)) { 900 config::DoWannier = 0; 901 } else { 902 if (config::DoWannier < 0) config::DoWannier = 0; 903 if (config::DoWannier > 1) config::DoWannier = 1; 904 } 905 if(!ParseForParameter(verbose,FileBuffer,"CommonWannier", 0, 1, 1, int_type, &(config::CommonWannier), 1, optional)) { 906 config::CommonWannier = 0; 907 } else { 908 if (config::CommonWannier < 0) config::CommonWannier = 0; 909 if (config::CommonWannier > 4) config::CommonWannier = 4; 910 } 911 if(!ParseForParameter(verbose,FileBuffer,"SawtoothStart", 0, 1, 1, double_type, &(config::SawtoothStart), 1, optional)) { 912 config::SawtoothStart = 0.01; 913 } else { 914 if (config::SawtoothStart < 0.) config::SawtoothStart = 0.; 915 if (config::SawtoothStart > 1.) config::SawtoothStart = 1.; 916 } 917 918 if (ParseForParameter(verbose,FileBuffer,"DoConstrainedMD", 0, 1, 1, int_type, &(config::DoConstrainedMD), 1, optional)) 919 if (config::DoConstrainedMD < 0) 920 config::DoConstrainedMD = 0; 921 ParseForParameter(verbose,FileBuffer,"MaxOuterStep", 0, 1, 1, int_type, &(config::MaxOuterStep), 1, critical); 922 if (!ParseForParameter(verbose,FileBuffer,"Deltat", 0, 1, 1, double_type, &(config::Deltat), 1, optional)) 923 config::Deltat = 1; 924 ParseForParameter(verbose,FileBuffer,"OutVisStep", 0, 1, 1, int_type, &(config::OutVisStep), 1, optional); 925 ParseForParameter(verbose,FileBuffer,"OutSrcStep", 0, 1, 1, int_type, &(config::OutSrcStep), 1, optional); 926 ParseForParameter(verbose,FileBuffer,"TargetTemp", 0, 1, 1, double_type, &(config::TargetTemp), 1, optional); 927 //ParseForParameter(verbose,FileBuffer,"Thermostat", 0, 1, 1, int_type, &(config::ScaleTempStep), 1, optional); 928 if (!ParseForParameter(verbose,FileBuffer,"EpsWannier", 0, 1, 1, double_type, &(config::EpsWannier), 1, optional)) 929 config::EpsWannier = 1e-8; 930 931 // stop conditions 932 //if (config::MaxOuterStep <= 0) config::MaxOuterStep = 1; 933 ParseForParameter(verbose,FileBuffer,"MaxPsiStep", 0, 1, 1, int_type, &(config::MaxPsiStep), 1, critical); 934 if (config::MaxPsiStep <= 0) config::MaxPsiStep = 3; 935 936 ParseForParameter(verbose,FileBuffer,"MaxMinStep", 0, 1, 1, int_type, &(config::MaxMinStep), 1, critical); 937 ParseForParameter(verbose,FileBuffer,"RelEpsTotalE", 0, 1, 1, double_type, &(config::RelEpsTotalEnergy), 1, critical); 938 ParseForParameter(verbose,FileBuffer,"RelEpsKineticE", 0, 1, 1, double_type, &(config::RelEpsKineticEnergy), 1, critical); 939 ParseForParameter(verbose,FileBuffer,"MaxMinStopStep", 0, 1, 1, int_type, &(config::MaxMinStopStep), 1, critical); 940 ParseForParameter(verbose,FileBuffer,"MaxMinGapStopStep", 0, 1, 1, int_type, &(config::MaxMinGapStopStep), 1, critical); 941 if (config::MaxMinStep <= 0) config::MaxMinStep = config::MaxPsiStep; 942 if (config::MaxMinStopStep < 1) config::MaxMinStopStep = 1; 943 if (config::MaxMinGapStopStep < 1) config::MaxMinGapStopStep = 1; 944 945 ParseForParameter(verbose,FileBuffer,"MaxInitMinStep", 0, 1, 1, int_type, &(config::MaxInitMinStep), 1, critical); 946 ParseForParameter(verbose,FileBuffer,"InitRelEpsTotalE", 0, 1, 1, double_type, &(config::InitRelEpsTotalEnergy), 1, critical); 947 ParseForParameter(verbose,FileBuffer,"InitRelEpsKineticE", 0, 1, 1, double_type, &(config::InitRelEpsKineticEnergy), 1, critical); 948 ParseForParameter(verbose,FileBuffer,"InitMaxMinStopStep", 0, 1, 1, int_type, &(config::InitMaxMinStopStep), 1, critical); 949 ParseForParameter(verbose,FileBuffer,"InitMaxMinGapStopStep", 0, 1, 1, int_type, &(config::InitMaxMinGapStopStep), 1, critical); 950 if (config::MaxInitMinStep <= 0) config::MaxInitMinStep = config::MaxPsiStep; 951 if (config::InitMaxMinStopStep < 1) config::InitMaxMinStopStep = 1; 952 if (config::InitMaxMinGapStopStep < 1) config::InitMaxMinGapStopStep = 1; 953 954 // Unit cell and magnetic field 955 ParseForParameter(verbose,FileBuffer, "BoxLength", 0, 3, 3, lower_trigrid, BoxLength, 1, critical); /* Lattice->RealBasis */ 956 mol->cell_size[0] = BoxLength[0]; 957 mol->cell_size[1] = BoxLength[3]; 958 mol->cell_size[2] = BoxLength[4]; 959 mol->cell_size[3] = BoxLength[6]; 960 mol->cell_size[4] = BoxLength[7]; 961 mol->cell_size[5] = BoxLength[8]; 962 //if (1) fprintf(stderr,"\n"); 963 964 ParseForParameter(verbose,FileBuffer,"DoPerturbation", 0, 1, 1, int_type, &(config::DoPerturbation), 1, optional); 965 ParseForParameter(verbose,FileBuffer,"DoOutNICS", 0, 1, 1, int_type, &(config::DoOutNICS), 1, optional); 966 if (!ParseForParameter(verbose,FileBuffer,"DoFullCurrent", 0, 1, 1, int_type, &(config::DoFullCurrent), 1, optional)) 967 config::DoFullCurrent = 0; 968 if (config::DoFullCurrent < 0) config::DoFullCurrent = 0; 969 if (config::DoFullCurrent > 2) config::DoFullCurrent = 2; 970 if (config::DoOutNICS < 0) config::DoOutNICS = 0; 971 if (config::DoOutNICS > 2) config::DoOutNICS = 2; 972 if (config::DoPerturbation == 0) { 973 config::DoFullCurrent = 0; 974 config::DoOutNICS = 0; 975 } 976 977 ParseForParameter(verbose,FileBuffer,"ECut", 0, 1, 1, double_type, &(config::ECut), 1, critical); 978 ParseForParameter(verbose,FileBuffer,"MaxLevel", 0, 1, 1, int_type, &(config::MaxLevel), 1, critical); 979 ParseForParameter(verbose,FileBuffer,"Level0Factor", 0, 1, 1, int_type, &(config::Lev0Factor), 1, critical); 980 if (config::Lev0Factor < 2) { 981 config::Lev0Factor = 2; 982 } 983 ParseForParameter(verbose,FileBuffer,"RiemannTensor", 0, 1, 1, int_type, &di, 1, critical); 984 if (di >= 0 && di < 2) { 985 config::RiemannTensor = di; 986 } else { 987 fprintf(stderr, "0 <= RiemanTensor < 2: 0 UseNotRT, 1 UseRT"); 988 exit(1); 989 } 990 switch (config::RiemannTensor) { 991 case 0: //UseNoRT 992 if (config::MaxLevel < 2) { 993 config::MaxLevel = 2; 994 } 995 config::LevRFactor = 2; 996 config::RTActualUse = 0; 997 break; 998 case 1: // UseRT 999 if (config::MaxLevel < 3) { 1000 config::MaxLevel = 3; 1001 } 1002 ParseForParameter(verbose,FileBuffer,"RiemannLevel", 0, 1, 1, int_type, &(config::RiemannLevel), 1, critical); 1003 if (config::RiemannLevel < 2) { 1004 config::RiemannLevel = 2; 1005 } 1006 if (config::RiemannLevel > config::MaxLevel-1) { 1007 config::RiemannLevel = config::MaxLevel-1; 1008 } 1009 ParseForParameter(verbose,FileBuffer,"LevRFactor", 0, 1, 1, int_type, &(config::LevRFactor), 1, critical); 1010 if (config::LevRFactor < 2) { 1011 config::LevRFactor = 2; 1012 } 1013 config::Lev0Factor = 2; 1014 config::RTActualUse = 2; 1015 break; 1016 } 1017 ParseForParameter(verbose,FileBuffer,"PsiType", 0, 1, 1, int_type, &di, 1, critical); 1018 if (di >= 0 && di < 2) { 1019 config::PsiType = di; 1020 } else { 1021 fprintf(stderr, "0 <= PsiType < 2: 0 UseSpinDouble, 1 UseSpinUpDown"); 1022 exit(1); 1023 } 1024 switch (config::PsiType) { 1025 case 0: // SpinDouble 1026 ParseForParameter(verbose,FileBuffer,"MaxPsiDouble", 0, 1, 1, int_type, &(config::MaxPsiDouble), 1, critical); 1027 ParseForParameter(verbose,FileBuffer,"AddPsis", 0, 1, 1, int_type, &(config::AddPsis), 1, optional); 1028 break; 1029 case 1: // SpinUpDown 1030 if (config::ProcPEGamma % 2) config::ProcPEGamma*=2; 1031 ParseForParameter(verbose,FileBuffer,"PsiMaxNoUp", 0, 1, 1, int_type, &(config::PsiMaxNoUp), 1, critical); 1032 ParseForParameter(verbose,FileBuffer,"PsiMaxNoDown", 0, 1, 1, int_type, &(config::PsiMaxNoDown), 1, critical); 1033 ParseForParameter(verbose,FileBuffer,"AddPsis", 0, 1, 1, int_type, &(config::AddPsis), 1, optional); 1034 break; 1035 } 1036 1037 // IonsInitRead 1038 1039 ParseForParameter(verbose,FileBuffer,"RCut", 0, 1, 1, double_type, &(config::RCut), 1, critical); 1040 ParseForParameter(verbose,FileBuffer,"IsAngstroem", 0, 1, 1, int_type, &(config::IsAngstroem), 1, critical); 1041 ParseForParameter(verbose,FileBuffer,"MaxTypes", 0, 1, 1, int_type, &(MaxTypes), 1, critical); 1042 if (!ParseForParameter(verbose,FileBuffer,"RelativeCoord", 0, 1, 1, int_type, &(config::RelativeCoord) , 1, optional)) 1043 config::RelativeCoord = 0; 1044 if (!ParseForParameter(verbose,FileBuffer,"StructOpt", 0, 1, 1, int_type, &(config::StructOpt), 1, optional)) 1045 config::StructOpt = 0; 1046 1047 // 2. parse the bond graph file if given 1048 BG = new BondGraph(IsAngstroem); 1049 if (BG->LoadBondLengthTable((ofstream *)&cout, BondGraphFileName)) { 1050 cout << Verbose(0) << "Bond length table loaded successfully." << endl; 1051 } else { 1052 cout << Verbose(0) << "Bond length table loading failed." << endl; 1053 } 1054 1055 // 3. parse the molecule in 1056 LoadMolecule(mol, FileBuffer, periode, FastParsing); 1057 1058 // 4. split into connected subgraphs 1059 MolList->DissectMoleculeIntoConnectedSubgraphs((ofstream *)&cout, mol, this); 1060 1061 delete(mol); 1062 delete(FileBuffer); 1063 }; 1064 1065 1066 /** Initializes config file structure by loading elements from a give file with old pcp syntax. 1067 * \param *file input file stream being the opened config file with old pcp syntax 1068 * \param BondGraphFileName file name of the bond length table file, if string is left blank, no table is parsed. 1069 * \param *periode pointer to a periodentafel class with all elements 1070 * \param *&MolList pointer to MoleculeListClass, on return containing all parsed molecules in system 1071 */ 1072 void config::LoadOld(const char * const filename, const string &BondGraphFileName, const periodentafel * const periode, MoleculeListClass * const &MolList) 1073 { 1074 molecule *mol = new molecule(periode); 1075 ifstream *file = new ifstream(filename); 1076 if (file == NULL) { 1077 cerr << "ERROR: config file " << filename << " missing!" << endl; 1078 return; 1079 } 1078 1080 RetrieveConfigPathAndName(filename); 1079 1081 // ParseParameters 1080 1082 1081 1083 /* Oeffne Hauptparameterdatei */ 1082 int l, i, di; 1083 double a,b; 1084 int l = 0; 1085 int i = 0; 1086 int di = 0; 1087 double a = 0.; 1088 double b = 0.; 1084 1089 double BoxLength[9]; 1085 1090 string zeile; 1086 1091 string dummy; 1087 1092 element *elementhash[128]; 1088 int Z, No, AtomNo, found; 1093 int Z = -1; 1094 int No = -1; 1095 int AtomNo = -1; 1096 int found = 0; 1089 1097 int verbose = 0; 1090 1098 1099 mol->ActiveFlag = true; 1100 MolList->insert(mol); 1091 1101 /* Namen einlesen */ 1092 1102 … … 1220 1230 config::StructOpt = 0; 1221 1231 1232 1233 // 2. parse the bond graph file if given 1234 BG = new BondGraph(IsAngstroem); 1235 if (BG->LoadBondLengthTable((ofstream *)&cout, BondGraphFileName)) { 1236 cout << Verbose(0) << "Bond length table loaded successfully." << endl; 1237 } else { 1238 cout << Verbose(0) << "Bond length table loading failed." << endl; 1239 } 1240 1222 1241 // Routine from builder.cpp 1223 1224 1242 1225 1243 for (i=MAX_ELEMENTS;i--;) … … 1273 1291 * \param *mol pointer to molecule containing all atoms of the molecule 1274 1292 */ 1275 bool config::Save(const char * filename, periodentafel *periode, molecule *mol) const1293 bool config::Save(const char * const filename, const periodentafel * const periode, molecule * const mol) const 1276 1294 { 1277 1295 bool result = true; 1278 1296 // bring MaxTypes up to date 1279 1297 mol->CountElements(); 1280 ofstream *output = NULL; 1281 output = new ofstream(filename, ios::out); 1298 ofstream * const output = new ofstream(filename, ios::out); 1282 1299 if (output != NULL) { 1283 1300 *output << "# ParallelCarParinello - main configuration file - created with molecuilder" << endl; … … 1403 1420 * \param *mol pointer to molecule containing all atoms of the molecule 1404 1421 */ 1405 bool config::SaveMPQC(const char * filename, molecule *mol) const1422 bool config::SaveMPQC(const char * const filename, const molecule * const mol) const 1406 1423 { 1407 int ElementNo = 0; 1408 int AtomNo; 1409 atom *Walker = NULL; 1410 element *runner = NULL; 1424 int AtomNo = -1; 1411 1425 Vector *center = NULL; 1412 1426 ofstream *output = NULL; 1413 stringstream *fname = NULL;1414 1427 1415 1428 // first without hessian 1416 fname = new stringstream; 1417 *fname << filename << ".in"; 1418 output = new ofstream(fname->str().c_str(), ios::out); 1419 *output << "% Created by MoleCuilder" << endl; 1420 *output << "mpqc: (" << endl; 1421 *output << "\tsavestate = no" << endl; 1422 *output << "\tdo_gradient = yes" << endl; 1423 *output << "\tmole<MBPT2>: (" << endl; 1424 *output << "\t\tmaxiter = 200" << endl; 1425 *output << "\t\tbasis = $:basis" << endl; 1426 *output << "\t\tmolecule = $:molecule" << endl; 1427 *output << "\t\treference<CLHF>: (" << endl; 1428 *output << "\t\t\tbasis = $:basis" << endl; 1429 *output << "\t\t\tmolecule = $:molecule" << endl; 1430 *output << "\t\t)" << endl; 1431 *output << "\t)" << endl; 1432 *output << ")" << endl; 1433 *output << "molecule<Molecule>: (" << endl; 1434 *output << "\tunit = " << (IsAngstroem ? "angstrom" : "bohr" ) << endl; 1435 *output << "\t{ atoms geometry } = {" << endl; 1436 center = mol->DetermineCenterOfAll(output); 1437 // output of atoms 1438 runner = mol->elemente->start; 1439 while (runner->next != mol->elemente->end) { // go through every element 1440 runner = runner->next; 1441 if (mol->ElementsInMolecule[runner->Z]) { // if this element got atoms 1442 ElementNo++; 1443 AtomNo = 0; 1444 Walker = mol->start; 1445 while (Walker->next != mol->end) { // go through every atom of this element 1446 Walker = Walker->next; 1447 if (Walker->type == runner) { // if this atom fits to element 1448 AtomNo++; 1449 *output << "\t\t" << Walker->type->symbol << " [ " << Walker->x.x[0]-center->x[0] << "\t" << Walker->x.x[1]-center->x[1] << "\t" << Walker->x.x[2]-center->x[2] << " ]" << endl; 1450 } 1451 } 1452 } 1453 } 1454 delete(center); 1455 *output << "\t}" << endl; 1456 *output << ")" << endl; 1457 *output << "basis<GaussianBasisSet>: (" << endl; 1458 *output << "\tname = \"" << basis << "\"" << endl; 1459 *output << "\tmolecule = $:molecule" << endl; 1460 *output << ")" << endl; 1461 output->close(); 1462 delete(output); 1463 delete(fname); 1429 { 1430 stringstream * const fname = new stringstream;; 1431 *fname << filename << ".in"; 1432 output = new ofstream(fname->str().c_str(), ios::out); 1433 *output << "% Created by MoleCuilder" << endl; 1434 *output << "mpqc: (" << endl; 1435 *output << "\tsavestate = no" << endl; 1436 *output << "\tdo_gradient = yes" << endl; 1437 *output << "\tmole<MBPT2>: (" << endl; 1438 *output << "\t\tmaxiter = 200" << endl; 1439 *output << "\t\tbasis = $:basis" << endl; 1440 *output << "\t\tmolecule = $:molecule" << endl; 1441 *output << "\t\treference<CLHF>: (" << endl; 1442 *output << "\t\t\tbasis = $:basis" << endl; 1443 *output << "\t\t\tmolecule = $:molecule" << endl; 1444 *output << "\t\t)" << endl; 1445 *output << "\t)" << endl; 1446 *output << ")" << endl; 1447 *output << "molecule<Molecule>: (" << endl; 1448 *output << "\tunit = " << (IsAngstroem ? "angstrom" : "bohr" ) << endl; 1449 *output << "\t{ atoms geometry } = {" << endl; 1450 center = mol->DetermineCenterOfAll(output); 1451 // output of atoms 1452 AtomNo = 0; 1453 mol->ActOnAllAtoms( &atom::OutputMPQCLine, output, (const Vector *)center, &AtomNo ); 1454 delete(center); 1455 *output << "\t}" << endl; 1456 *output << ")" << endl; 1457 *output << "basis<GaussianBasisSet>: (" << endl; 1458 *output << "\tname = \"" << basis << "\"" << endl; 1459 *output << "\tmolecule = $:molecule" << endl; 1460 *output << ")" << endl; 1461 output->close(); 1462 delete(output); 1463 delete(fname); 1464 } 1464 1465 1465 1466 // second with hessian 1466 fname = new stringstream; 1467 *fname << filename << ".hess.in"; 1468 output = new ofstream(fname->str().c_str(), ios::out); 1469 *output << "% Created by MoleCuilder" << endl; 1470 *output << "mpqc: (" << endl; 1471 *output << "\tsavestate = no" << endl; 1472 *output << "\tdo_gradient = yes" << endl; 1473 *output << "\tmole<CLHF>: (" << endl; 1474 *output << "\t\tmaxiter = 200" << endl; 1475 *output << "\t\tbasis = $:basis" << endl; 1476 *output << "\t\tmolecule = $:molecule" << endl; 1477 *output << "\t)" << endl; 1478 *output << "\tfreq<MolecularFrequencies>: (" << endl; 1479 *output << "\t\tmolecule=$:molecule" << endl; 1480 *output << "\t)" << endl; 1481 *output << ")" << endl; 1482 *output << "molecule<Molecule>: (" << endl; 1483 *output << "\tunit = " << (IsAngstroem ? "angstrom" : "bohr" ) << endl; 1484 *output << "\t{ atoms geometry } = {" << endl; 1485 center = mol->DetermineCenterOfAll(output); 1486 // output of atoms 1487 runner = mol->elemente->start; 1488 while (runner->next != mol->elemente->end) { // go through every element 1489 runner = runner->next; 1490 if (mol->ElementsInMolecule[runner->Z]) { // if this element got atoms 1491 ElementNo++; 1492 AtomNo = 0; 1493 Walker = mol->start; 1494 while (Walker->next != mol->end) { // go through every atom of this element 1495 Walker = Walker->next; 1496 if (Walker->type == runner) { // if this atom fits to element 1497 AtomNo++; 1498 *output << "\t\t" << Walker->type->symbol << " [ " << Walker->x.x[0]-center->x[0] << "\t" << Walker->x.x[1]-center->x[1] << "\t" << Walker->x.x[2]-center->x[2] << " ]" << endl; 1499 } 1500 } 1501 } 1502 } 1503 delete(center); 1504 *output << "\t}" << endl; 1505 *output << ")" << endl; 1506 *output << "basis<GaussianBasisSet>: (" << endl; 1507 *output << "\tname = \"3-21G\"" << endl; 1508 *output << "\tmolecule = $:molecule" << endl; 1509 *output << ")" << endl; 1510 output->close(); 1511 delete(output); 1512 delete(fname); 1467 { 1468 stringstream * const fname = new stringstream; 1469 *fname << filename << ".hess.in"; 1470 output = new ofstream(fname->str().c_str(), ios::out); 1471 *output << "% Created by MoleCuilder" << endl; 1472 *output << "mpqc: (" << endl; 1473 *output << "\tsavestate = no" << endl; 1474 *output << "\tdo_gradient = yes" << endl; 1475 *output << "\tmole<CLHF>: (" << endl; 1476 *output << "\t\tmaxiter = 200" << endl; 1477 *output << "\t\tbasis = $:basis" << endl; 1478 *output << "\t\tmolecule = $:molecule" << endl; 1479 *output << "\t)" << endl; 1480 *output << "\tfreq<MolecularFrequencies>: (" << endl; 1481 *output << "\t\tmolecule=$:molecule" << endl; 1482 *output << "\t)" << endl; 1483 *output << ")" << endl; 1484 *output << "molecule<Molecule>: (" << endl; 1485 *output << "\tunit = " << (IsAngstroem ? "angstrom" : "bohr" ) << endl; 1486 *output << "\t{ atoms geometry } = {" << endl; 1487 center = mol->DetermineCenterOfAll(output); 1488 // output of atoms 1489 AtomNo = 0; 1490 mol->ActOnAllAtoms( &atom::OutputMPQCLine, output, (const Vector *)center, &AtomNo ); 1491 delete(center); 1492 *output << "\t}" << endl; 1493 *output << ")" << endl; 1494 *output << "basis<GaussianBasisSet>: (" << endl; 1495 *output << "\tname = \"3-21G\"" << endl; 1496 *output << "\tmolecule = $:molecule" << endl; 1497 *output << ")" << endl; 1498 output->close(); 1499 delete(output); 1500 delete(fname); 1501 } 1513 1502 1514 1503 return true; … … 1536 1525 * \note Routine is taken from the pcp project and hack-a-slack adapted to C++ 1537 1526 */ 1538 int config::ParseForParameter(int verbose, ifstream *file, const char *name, int sequential, int const xth, int const yth, int type, void *value, int repetition, int critical) { 1539 int i,j; // loop variables 1540 int length = 0, maxlength = -1; 1527 int ParseForParameter(const int verbose, ifstream * const file, const char * const name, const int sequential, const int xth, const int yth, const int type, void * value, const int repetition, const int critical) { 1528 int i = 0; 1529 int j = 0; // loop variables 1530 int length = 0; 1531 int maxlength = -1; 1541 1532 long file_position = file->tellg(); // mark current position 1542 char *dummy1, *dummy, *free_dummy; // pointers in the line that is read in per step 1543 dummy1 = free_dummy = Malloc<char>(256, "config::ParseForParameter: *free_dummy"); 1533 char *dummy1 = NULL; 1534 char *dummy = NULL; 1535 char * const free_dummy = Malloc<char>(256, "config::ParseForParameter: *free_dummy"); // pointers in the line that is read in per step 1536 dummy1 = free_dummy; 1544 1537 1545 1538 //fprintf(stderr,"Parsing for %s\n",name); … … 1556 1549 if (file->eof()) { 1557 1550 if ((critical) && (found == 0)) { 1558 Free( &free_dummy);1551 Free(free_dummy); 1559 1552 //Error(InitReading, name); 1560 1553 fprintf(stderr,"Error:InitReading, critical %s not found\n", name); … … 1564 1557 file->clear(); 1565 1558 file->seekg(file_position, ios::beg); // rewind to start position 1566 Free( &free_dummy);1559 Free(free_dummy); 1567 1560 return 0; 1568 1561 } … … 1616 1609 if (file->eof()) { 1617 1610 if ((critical) && (found == 0)) { 1618 Free( &free_dummy);1611 Free(free_dummy); 1619 1612 //Error(InitReading, name); 1620 1613 fprintf(stderr,"Error:InitReading, critical %s not found\n", name); … … 1624 1617 file->clear(); 1625 1618 file->seekg(file_position, ios::beg); // rewind to start position 1626 Free( &free_dummy);1619 Free(free_dummy); 1627 1620 return 0; 1628 1621 } … … 1665 1658 if (critical) { 1666 1659 if (verbose) fprintf(stderr,"Error: EoL at %i and still missing %i value(s) for parameter %s\n", line, yth-j, name); 1667 Free( &free_dummy);1660 Free(free_dummy); 1668 1661 //return 0; 1669 1662 exit(255); … … 1673 1666 file->clear(); 1674 1667 file->seekg(file_position, ios::beg); // rewind to start position 1675 Free( &free_dummy);1668 Free(free_dummy); 1676 1669 return 0; 1677 1670 } … … 1686 1679 file->seekg(file_position, ios::beg); // rewind to start position 1687 1680 } 1688 Free( &free_dummy);1681 Free(free_dummy); 1689 1682 return 0; 1690 1683 } … … 1742 1735 if ((type >= row_int) && (verbose)) 1743 1736 fprintf(stderr,"\n"); 1744 Free( &free_dummy);1737 Free(free_dummy); 1745 1738 if (!sequential) { 1746 1739 file->clear(); … … 1774 1767 * \note Routine is taken from the pcp project and hack-a-slack adapted to C++ 1775 1768 */ 1776 int config::ParseForParameter(int verbose, struct ConfigFileBuffer *FileBuffer, const char *name, int sequential, int const xth, int const yth, int type, void *value, int repetition, int critical) { 1777 int i,j; // loop variables 1778 int length = 0, maxlength = -1; 1769 int ParseForParameter(const int verbose, struct ConfigFileBuffer * const FileBuffer, const char * const name, const int sequential, const int xth, const int yth, const int type, void * value, const int repetition, const int critical) { 1770 int i = 0; 1771 int j = 0; // loop variables 1772 int length = 0; 1773 int maxlength = -1; 1779 1774 int OldCurrentLine = FileBuffer->CurrentLine; 1780 char *dummy1, *dummy; // pointers in the line that is read in per step 1775 char *dummy1 = NULL; 1776 char *dummy = NULL; // pointers in the line that is read in per step 1781 1777 1782 1778 //fprintf(stderr,"Parsing for %s\n",name); -
Property mode
changed from
-
src/config.hpp
r06c7a3 r7326b2 11 11 using namespace std; 12 12 13 class MoleculeListClass; 14 13 15 /*********************************************** includes ***********************************/ 14 16 … … 19 21 20 22 #include <string> 23 24 #include "bondgraph.hpp" 21 25 22 26 /****************************************** forward declarations *****************************/ … … 35 39 36 40 ConfigFileBuffer(); 37 ConfigFileBuffer(c har *filename);41 ConfigFileBuffer(const char * const filename); 38 42 ~ConfigFileBuffer(); 39 43 40 44 void InitMapping(); 41 void MapIonTypesInBuffer( int NoAtoms);45 void MapIonTypesInBuffer(const int NoAtoms); 42 46 }; 43 47 … … 47 51 class config { 48 52 public: 53 class BondGraph *BG; 54 49 55 int PsiType; 50 56 int MaxPsiDouble; … … 126 132 127 133 128 int ParseForParameter(int verbose, ifstream *file, const char *name, int sequential, int const xth, int const yth, int type, void *value, int repetition, int critical);129 int ParseForParameter(int verbose, struct ConfigFileBuffer *FileBuffer, const char *name, int sequential, int const xth, int const yth, int type, void *value, int repetition, int critical);130 131 134 public: 132 135 config(); 133 136 ~config(); 134 137 135 int TestSyntax(c har *filename, periodentafel *periode, molecule *mol);136 void Load(c har *filename, periodentafel *periode, molecule *mol);137 void LoadOld(c har *filename, periodentafel *periode, molecule *mol);138 void RetrieveConfigPathAndName( string filename);139 bool Save(const char * filename, periodentafel *periode, molecule *mol) const;140 bool SaveMPQC(const char * filename, molecule *mol) const;138 int TestSyntax(const char * const filename, const periodentafel * const periode) const; 139 void Load(const char * const filename, const string &BondGraphFileName, const periodentafel * const periode, MoleculeListClass * const &MolList); 140 void LoadOld(const char * const filename, const string &BondGraphFileName, const periodentafel * const periode, MoleculeListClass * const &MolList); 141 void RetrieveConfigPathAndName(const string filename); 142 bool Save(const char * const filename, const periodentafel * const periode, molecule * const mol) const; 143 bool SaveMPQC(const char * const filename, const molecule * const mol) const; 141 144 void Edit(); 142 145 bool GetIsAngstroem() const; 143 146 char *GetDefaultPath() const; 144 void SetDefaultPath(const char *path); 145 void InitThermostats(class ConfigFileBuffer *fb); 147 void SetDefaultPath(const char * const path); 148 void InitThermostats(); 149 void ParseThermostats(class ConfigFileBuffer * const fb); 146 150 }; 147 151 152 int ParseForParameter(const int verbose, ifstream * const file, const char * const name, const int sequential, const int xth, const int yth, const int type, void * value, const int repetition, const int critical); 153 int ParseForParameter(const int verbose, struct ConfigFileBuffer * const FileBuffer, const char * const name, const int sequential, const int xth, const int yth, const int type, void * value, const int repetition, const int critical); 154 void LoadMolecule(molecule * const &mol, struct ConfigFileBuffer * const &FileBuffer, const periodentafel * const periode, const bool FastParsing); 155 void PrepareFileBuffer(const char * const filename, struct ConfigFileBuffer *&FileBuffer); 156 148 157 #endif /* CONFIG_HPP_ */ -
src/ellipsoid.cpp
r06c7a3 r7326b2 234 234 int index; 235 235 TesselPoint *Candidate = NULL; 236 LinkedNodes *List = NULL;237 236 *out << Verbose(2) << "Begin of PickRandomPointSet" << endl; 238 237 … … 249 248 *out << Verbose(2) << "INFO: Center cell is " << LC->n[0] << ", " << LC->n[1] << ", " << LC->n[2] << " ... "; 250 249 // get random cell 251 List = LC->GetCurrentCell();250 const LinkedNodes *List = LC->GetCurrentCell(); 252 251 if (List == NULL) { // set index to it 253 252 continue; … … 268 267 for (LC->n[1] = Nlower[1]; LC->n[1] <= Nupper[1]; LC->n[1]++) 269 268 for (LC->n[2] = Nlower[2]; LC->n[2] <= Nupper[2]; LC->n[2]++) { 270 List = LC->GetCurrentCell();269 const LinkedNodes *List = LC->GetCurrentCell(); 271 270 PointsLeft += List->size(); 272 271 } … … 293 292 for (LC->n[1] = Nlower[1]; LC->n[1] <= Nupper[1]; LC->n[1]++) 294 293 for (LC->n[2] = Nlower[2]; LC->n[2] <= Nupper[2]; LC->n[2]++) { 295 List = LC->GetCurrentCell();294 const LinkedNodes *List = LC->GetCurrentCell(); 296 295 // *out << Verbose(2) << "Current cell is " << LC->n[0] << ", " << LC->n[1] << ", " << LC->n[2] << " with No. " << LC->index << " containing " << List->size() << " points." << endl; 297 296 if (List != NULL) { … … 300 299 // else 301 300 // *out << Verbose(2) << "Cell is empty ... " << endl; 302 for (LinkedNodes:: iterator Runner = List->begin(); Runner != List->end(); Runner++) {301 for (LinkedNodes::const_iterator Runner = List->begin(); Runner != List->end(); Runner++) { 303 302 if ((current != PickedAtomNrs.end()) && (*current == index)) { 304 303 Candidate = (*Runner); -
src/helpers.cpp
r06c7a3 r7326b2 6 6 7 7 #include "helpers.hpp" 8 9 #include "memoryusageobserver.hpp" 8 10 9 11 /********************************************** helpful functions *********************************/ … … 47 49 while (*b < lower_bound) 48 50 *b += step; 49 };50 51 /** Flips two doubles.52 * \param *x pointer to first double53 * \param *y pointer to second double54 */55 void flip(double *x, double *y)56 {57 double tmp;58 tmp = *x;59 *x = *y;60 *y = tmp;61 51 }; 62 52 … … 143 133 * \return allocated NDIM*NDIM array with the symmetric matrix 144 134 */ 145 double * ReturnFullMatrixforSymmetric( double *symm)135 double * ReturnFullMatrixforSymmetric(const double * const symm) 146 136 { 147 137 double *matrix = Malloc<double>(NDIM * NDIM, "molecule::ReturnFullMatrixforSymmetric: *matrix"); … … 158 148 }; 159 149 150 /** Calculate the inverse of a 3x3 matrix. 151 * \param *matrix NDIM_NDIM array 152 */ 153 double * InverseMatrix( const double * const A) 154 { 155 double *B = Malloc<double>(NDIM * NDIM, "Vector::InverseMatrix: *B"); 156 double detA = RDET3(A); 157 double detAReci; 158 159 for (int i=0;i<NDIM*NDIM;++i) 160 B[i] = 0.; 161 // calculate the inverse B 162 if (fabs(detA) > MYEPSILON) {; // RDET3(A) yields precisely zero if A irregular 163 detAReci = 1./detA; 164 B[0] = detAReci*RDET2(A[4],A[5],A[7],A[8]); // A_11 165 B[1] = -detAReci*RDET2(A[1],A[2],A[7],A[8]); // A_12 166 B[2] = detAReci*RDET2(A[1],A[2],A[4],A[5]); // A_13 167 B[3] = -detAReci*RDET2(A[3],A[5],A[6],A[8]); // A_21 168 B[4] = detAReci*RDET2(A[0],A[2],A[6],A[8]); // A_22 169 B[5] = -detAReci*RDET2(A[0],A[2],A[3],A[5]); // A_23 170 B[6] = detAReci*RDET2(A[3],A[4],A[6],A[7]); // A_31 171 B[7] = -detAReci*RDET2(A[0],A[1],A[6],A[7]); // A_32 172 B[8] = detAReci*RDET2(A[0],A[1],A[3],A[4]); // A_33 173 } 174 return B; 175 }; 176 177 /** hard-coded determinant of a 3x3 matrix. 178 * \param a[9] matrix 179 * \return \f$det(a)\f$ 180 */ 181 double RDET3(const double a[NDIM*NDIM]) 182 { 183 return ((a)[0]*(a)[4]*(a)[8] + (a)[3]*(a)[7]*(a)[2] + (a)[6]*(a)[1]*(a)[5] - (a)[2]*(a)[4]*(a)[6] - (a)[5]*(a)[7]*(a)[0] - (a)[8]*(a)[1]*(a)[3]); 184 }; 185 186 /** hard-coded determinant of a 2x2 matrix. 187 * \param a[4] matrix 188 * \return \f$det(a)\f$ 189 */ 190 double RDET2(const double a[4]) 191 { 192 return ((a[0])*(a[3])-(a[1])*(a[2])); 193 }; 194 195 /** hard-coded determinant of a 2x2 matrix. 196 * \param a0 (0,0) entry of matrix 197 * \param a1 (0,1) entry of matrix 198 * \param a2 (1,0) entry of matrix 199 * \param a3 (1,1) entry of matrix 200 * \return \f$det(a)\f$ 201 */ 202 double RDET2(const double a0, const double a1, const double a2, const double a3) 203 { 204 return ((a0)*(a3)-(a1)*(a2)); 205 }; 206 160 207 /** Comparison function for GSL heapsort on distances in two molecules. 161 208 * \param *a … … 202 249 * Frees all memory registered by the memory observer and calls exit(225) afterwards. 203 250 */ 204 staticvoid performCriticalExit() {251 void performCriticalExit() { 205 252 map<void*, size_t> pointers = MemoryUsageObserver::getInstance()->getPointersToAllocatedMemory(); 206 253 for (map<void*, size_t>::iterator runner = pointers.begin(); runner != pointers.end(); runner++) { -
src/helpers.hpp
-
Property mode
changed from
100755
to100644
r06c7a3 r7326b2 18 18 #include <fstream> 19 19 20 #include "defs.hpp" 20 21 #include "memoryallocator.hpp" 22 23 /********************************************** definitions *********************************/ 24 25 // some algebraic matrix stuff 26 double RDET3(const double a[NDIM*NDIM]); 27 double RDET2(const double a[4]); 28 double RDET2(const double a0, const double a1, const double a2, const double a3); 21 29 22 30 /********************************************** helpful functions *********************************/ … … 44 52 bool check_bounds(double *x, double *cell_size); 45 53 void bound(double *b, double lower_bound, double upper_bound); 46 void flip(double *x, double *y);47 54 int pot(int base, int n); 48 55 int CountLinesinFile(ifstream &InputFile); … … 50 57 bool IsValidNumber( const char *string); 51 58 int CompareDoubles (const void * a, const void * b); 52 double * ReturnFullMatrixforSymmetric(double *cell_size); 53 static void performCriticalExit(); 59 double * ReturnFullMatrixforSymmetric(const double * const cell_size); 60 double * InverseMatrix(const double * const A); 61 void performCriticalExit(); 54 62 55 63 /********************************************** helpful template functions *********************************/ 64 65 /** Flips two values. 66 * \param x first value 67 * \param y second value 68 */ 69 template <typename T> void flip(T &x, T &y) 70 { 71 T tmp; 72 tmp = x; 73 x = y; 74 y = tmp; 75 }; 56 76 57 77 /** Creates a lookup table for true father's Atom::Nr -> atom ptr. … … 60 80 * \paran *end end of chain list 61 81 * \param **Lookuptable pointer to return allocated lookup table (should be NULL on start) 62 * \param count optional predetermined countfor table (otherwise we set the count to highest true father id)82 * \param count optional predetermined size for table (otherwise we set the count to highest true father id) 63 83 * \return true - success, false - failure 64 84 */ … … 87 107 } 88 108 89 // allocat and fill90 LookupTable = Malloc<T*>(count, "CreateFatherLookupTable - **LookupTable");109 // allocate and fill 110 LookupTable = Calloc<T*>(count, "CreateFatherLookupTable - **LookupTable"); 91 111 if (LookupTable == NULL) { 92 112 cerr << "LookupTable memory allocation failed!" << endl; 93 113 status = false; 94 114 } else { 95 for (int i=0;i<count;i++)96 LookupTable[i] = NULL;97 115 Walker = start; 98 116 while (Walker->next != end) { // create a lookup table (Atom::nr -> atom) used as a marker table lateron -
Property mode
changed from
-
src/leastsquaremin.cpp
r06c7a3 r7326b2 16 16 * \return sum of square distances 17 17 */ 18 double LSQ (const gsl_vector * x, void * params)18 double LSQ (const gsl_vector * const x, void * params) 19 19 { 20 20 double sum = 0.; 21 21 struct LSQ_params *par = (struct LSQ_params *)params; 22 Vector **vectors = par->vectors;22 const Vector ** vectors = par->vectors; 23 23 int num = par->num; 24 24 -
src/leastsquaremin.hpp
r06c7a3 r7326b2 31 31 */ 32 32 struct LSQ_params { 33 Vector **vectors;33 const Vector **vectors; 34 34 int num; 35 35 }; 36 36 37 double LSQ(const gsl_vector * x, void * params);37 double LSQ(const gsl_vector * const x, void * params); 38 38 39 39 /** Parameter structure for least square minimsation. -
src/linkedcell.cpp
r06c7a3 r7326b2 33 33 * \param RADIUS edge length of cells 34 34 */ 35 LinkedCell::LinkedCell( PointCloud *set,double radius)35 LinkedCell::LinkedCell(const PointCloud * const set, const double radius) 36 36 { 37 37 TesselPoint *Walker = NULL; … … 109 109 * \param RADIUS edge length of cells 110 110 */ 111 LinkedCell::LinkedCell(LinkedNodes *set, double radius)111 LinkedCell::LinkedCell(LinkedNodes *set, const double radius) 112 112 { 113 113 class TesselPoint *Walker = NULL; … … 192 192 * \return if all in intervals - true, else -false 193 193 */ 194 bool LinkedCell::CheckBounds() 194 bool LinkedCell::CheckBounds() const 195 195 { 196 196 bool status = true; … … 202 202 }; 203 203 204 /** Checks whether LinkedCell::n[] plus relative offset is each within [0,N[]]. 205 * Note that for this check we don't admonish if out of bounds. 206 * \param relative[NDIM] relative offset to current cell 207 * \return if all in intervals - true, else -false 208 */ 209 bool LinkedCell::CheckBounds(const int relative[NDIM]) const 210 { 211 bool status = true; 212 for(int i=0;i<NDIM;i++) 213 status = status && ((n[i]+relative[i] >=0) && (n[i]+relative[i] < N[i])); 214 return status; 215 }; 216 204 217 205 218 /** Returns a pointer to the current cell. 206 219 * \return LinkedAtoms pointer to current cell, NULL if LinkedCell::n[] are out of bounds. 207 220 */ 208 LinkedNodes* LinkedCell::GetCurrentCell() 221 const LinkedNodes* LinkedCell::GetCurrentCell() const 209 222 { 210 223 if (CheckBounds()) { … … 216 229 }; 217 230 231 /** Returns a pointer to the current cell. 232 * \param relative[NDIM] offset for each axis with respect to the current cell LinkedCell::n[NDIM] 233 * \return LinkedAtoms pointer to current cell, NULL if LinkedCell::n[]+relative[] are out of bounds. 234 */ 235 const LinkedNodes* LinkedCell::GetRelativeToCurrentCell(const int relative[NDIM]) const 236 { 237 if (CheckBounds(relative)) { 238 index = (n[0]+relative[0]) * N[1] * N[2] + (n[1]+relative[1]) * N[2] + (n[2]+relative[2]); 239 return (&(LC[index])); 240 } else { 241 return NULL; 242 } 243 }; 244 218 245 /** Calculates the index for a given LCNode *Walker. 219 246 * \param *Walker LCNode to set index tos 220 247 * \return if the atom is also found in this cell - true, else - false 221 248 */ 222 bool LinkedCell::SetIndexToNode(const TesselPoint * Walker)249 bool LinkedCell::SetIndexToNode(const TesselPoint * const Walker) const 223 250 { 224 251 bool status = false; … … 241 268 * \param *upper upper bounds 242 269 */ 243 void LinkedCell::GetNeighbourBounds(int lower[NDIM], int upper[NDIM]) 270 void LinkedCell::GetNeighbourBounds(int lower[NDIM], int upper[NDIM]) const 244 271 { 245 272 for (int i=0;i<NDIM;i++) { … … 261 288 * \return Vector is inside bounding box - true, else - false 262 289 */ 263 bool LinkedCell::SetIndexToVector(const Vector * x)290 bool LinkedCell::SetIndexToVector(const Vector * const x) const 264 291 { 265 292 bool status = true; -
src/linkedcell.hpp
r06c7a3 r7326b2 46 46 double RADIUS; // cell edge length 47 47 int N[NDIM]; // number of cells per axis 48 int n[NDIM]; // temporary variable for current cell per axis49 int index; // temporary index variable , access by index = n[0] * N[1] * N[2] + n[1] * N[2] + n[2];48 mutable int n[NDIM]; // temporary variable for current cell per axis 49 mutable int index; // temporary index variable , access by index = n[0] * N[1] * N[2] + n[1] * N[2] + n[2]; 50 50 51 51 LinkedCell(); 52 LinkedCell( PointCloud *set,double RADIUS);53 LinkedCell(LinkedNodes *set, double radius);52 LinkedCell(const PointCloud * const set, const double RADIUS); 53 LinkedCell(LinkedNodes *set, const double radius); 54 54 ~LinkedCell(); 55 LinkedNodes* GetCurrentCell(); 56 bool SetIndexToNode(const TesselPoint *Walker); 57 bool SetIndexToVector(const Vector *x); 58 bool CheckBounds(); 59 void GetNeighbourBounds(int lower[NDIM], int upper[NDIM]); 55 const LinkedNodes* GetCurrentCell()const ; 56 const LinkedNodes* GetRelativeToCurrentCell(const int relative[NDIM])const ; 57 bool SetIndexToNode(const TesselPoint * const Walker)const ; 58 bool SetIndexToVector(const Vector * const x)const ; 59 bool CheckBounds()const ; 60 bool CheckBounds(const int relative[NDIM])const ; 61 void GetNeighbourBounds(int lower[NDIM], int upper[NDIM])const ; 60 62 61 63 // not implemented yet -
src/lists.hpp
r06c7a3 r7326b2 35 35 if (walker->previous != NULL) 36 36 walker->previous->next = walker->next; 37 walker->next = NULL; 38 walker->previous= NULL; 37 39 }; 38 40 … … 112 114 { 113 115 X *pointer = start->next; 114 X *walker ;116 X *walker = NULL; 115 117 while (pointer != end) { // go through list 116 118 walker = pointer; // mark current 117 119 pointer = pointer->next; // step onward beforehand 118 120 // remove walker 119 unlink(walker); 120 delete(walker); 121 walker = NULL; 121 removewithoutcheck(walker); 122 122 } 123 123 return true; -
src/memoryallocator.hpp
r06c7a3 r7326b2 55 55 template <> char* Malloc<char>(size_t size, const char* output); 56 56 57 /* *Allocates a memory range using calloc().57 /* Allocates a memory range using calloc(). 58 58 * Prints the provided error message in case of a failure. 59 59 * … … 61 61 * \param failure message which is printed if the allocation fails 62 62 * \return pointer to the allocated memory range, will be NULL if a failure occurred 63 63 */ 64 64 template <typename X> X* Calloc(size_t size, const char* output) 65 65 { 66 66 X* buffer = NULL; 67 buffer = (X*) calloc(size of(X) * size, (size_t) 0);67 buffer = (X*) calloc(size, sizeof(X)); 68 68 69 69 if (buffer != NULL) { … … 76 76 return buffer; 77 77 }; 78 78 79 79 80 /** Reallocates a memory range using realloc(). If the provided pointer to the old … … 105 106 }; 106 107 107 /** Frees allocated memory range using free() .108 /** Frees allocated memory range using free(), NULL'ing \a **buffer. 108 109 * 109 * \param pointer to the allocated memory range to free; may be NULL, this function is a no-op then110 * \param **buffer to the allocated memory range to free; may be NULL, this function is a no-op then 110 111 * \param *msg optional error message 111 112 */ … … 120 121 }; 121 122 123 /** Frees allocated memory range using free() for ... * const \a buffer types. 124 * 125 * \param *buffer to the allocated memory range to free; may be NULL, this function is a no-op then 126 * \param *msg optional error message 127 */ 128 template <typename X> void Free(X* const buffer, const char *msg = NULL) 129 { 130 if ((buffer == NULL)) 131 return; 132 133 MemoryUsageObserver::getInstance()->removeMemory(buffer, msg); 134 free(buffer); 135 }; 136 122 137 #endif /*MEMORYALLOCATOR_HPP_*/ -
src/memoryusageobserver.cpp
r06c7a3 r7326b2 23 23 */ 24 24 MemoryUsageObserver::~MemoryUsageObserver() { 25 for (map<void*, size_t>::iterator current = memoryUsers.begin(); current != memoryUsers.end(); current++) { 25 while (!memoryUsers.empty()) { 26 map<void*, size_t>::iterator current = memoryUsers.begin(); 27 free(current->first); 26 28 memoryUsers.erase(current); 27 29 } -
src/molecule.cpp
r06c7a3 r7326b2 26 26 * Initialises molecule list with correctly referenced start and end, and sets molecule::last_atom to zero. 27 27 */ 28 molecule::molecule(periodentafel *teil) 28 molecule::molecule(const periodentafel * const teil) : elemente(teil), start(new atom), end(new atom), 29 first(new bond(start, end, 1, -1)), last(new bond(start, end, 1, -1)), MDSteps(0), AtomCount(0), 30 BondCount(0), ElementCount(0), NoNonHydrogen(0), NoNonBonds(0), NoCyclicBonds(0), BondDistance(0.), 31 ActiveFlag(false), IndexNr(-1), last_atom(0), InternalPointer(start) 29 32 { 30 33 // init atom chain list 31 start = new atom;32 end = new atom;33 34 start->father = NULL; 34 35 end->father = NULL; 35 36 link(start,end); 36 InternalPointer = start; 37 37 38 // init bond chain list 38 first = new bond(start, end, 1, -1);39 last = new bond(start, end, 1, -1);40 39 link(first,last); 40 41 41 // other stuff 42 MDSteps = 0;43 last_atom = 0;44 elemente = teil;45 AtomCount = 0;46 BondCount = 0;47 NoNonBonds = 0;48 NoNonHydrogen = 0;49 NoCyclicBonds = 0;50 ListOfBondsPerAtom = NULL;51 NumberOfBondsPerAtom = NULL;52 ElementCount = 0;53 42 for(int i=MAX_ELEMENTS;i--;) 54 43 ElementsInMolecule[i] = 0; … … 56 45 cell_size[1] = cell_size[3] = cell_size[4]= 0.; 57 46 strcpy(name,"none"); 58 IndexNr = -1;59 ActiveFlag = false;60 TesselStruct = NULL;61 47 }; 62 48 … … 66 52 molecule::~molecule() 67 53 { 68 if (ListOfBondsPerAtom != NULL)69 for(int i=AtomCount;i--;)70 Free(&ListOfBondsPerAtom[i]);71 Free(&ListOfBondsPerAtom);72 Free(&NumberOfBondsPerAtom);73 if (TesselStruct != NULL)74 delete(TesselStruct);75 54 CleanupMolecule(); 76 55 delete(first); … … 160 139 * \param *origin pointer to atom which acts as the origin for scaling the added hydrogen to correct bond length 161 140 * \param *replacement pointer to the atom which shall be copied as a hydrogen atom in this molecule 162 * \param **BondList list of bonds \a *replacement has (necessary to determine plane for double and triple bonds)163 * \param NumBond number of bonds in \a **BondList164 141 * \param isAngstroem whether the coordination of the given atoms is in AtomicLength (false) or Angstrom(true) 165 142 * \return number of atoms added, if < bond::BondDegree then something went wrong 166 143 * \todo double and triple bonds splitting (always use the tetraeder angle!) 167 144 */ 168 bool molecule::AddHydrogenReplacementAtom(ofstream *out, bond *TopBond, atom *BottomOrigin, atom *TopOrigin, atom *TopReplacement, bo nd **BondList, int NumBond, bool IsAngstroem)145 bool molecule::AddHydrogenReplacementAtom(ofstream *out, bond *TopBond, atom *BottomOrigin, atom *TopOrigin, atom *TopReplacement, bool IsAngstroem) 169 146 { 170 147 double bondlength; // bond length of the bond to be replaced/cut … … 177 154 Vector Orthovector1, Orthovector2; // temporary vectors in coordination construction 178 155 Vector InBondvector; // vector in direction of *Bond 156 double *matrix; 179 157 bond *Binder = NULL; 180 double *matrix;181 158 182 159 // *out << Verbose(3) << "Begin of AddHydrogenReplacementAtom." << endl; … … 248 225 case 2: 249 226 // determine two other bonds (warning if there are more than two other) plus valence sanity check 250 for ( int i=0;i<NumBond;i++) {251 if ( BondList[i]!= TopBond) {227 for (BondList::const_iterator Runner = TopOrigin->ListOfBonds.begin(); Runner != TopOrigin->ListOfBonds.end(); (++Runner)) { 228 if ((*Runner) != TopBond) { 252 229 if (FirstBond == NULL) { 253 FirstBond = BondList[i];254 FirstOtherAtom = BondList[i]->GetOtherAtom(TopOrigin);230 FirstBond = (*Runner); 231 FirstOtherAtom = (*Runner)->GetOtherAtom(TopOrigin); 255 232 } else if (SecondBond == NULL) { 256 SecondBond = BondList[i];257 SecondOtherAtom = BondList[i]->GetOtherAtom(TopOrigin);233 SecondBond = (*Runner); 234 SecondOtherAtom = (*Runner)->GetOtherAtom(TopOrigin); 258 235 } else { 259 236 *out << Verbose(3) << "WARNING: Detected more than four bonds for atom " << TopOrigin->Name; … … 506 483 507 484 // get the pendant atoms of current bond in the copy molecule 508 copy->ActOnAllAtoms( &atom::EqualsFather, Binder->leftatom,&LeftAtom );509 copy->ActOnAllAtoms( &atom::EqualsFather, Binder->rightatom,&RightAtom );485 copy->ActOnAllAtoms( &atom::EqualsFather, (const atom *)Binder->leftatom, (const atom **)&LeftAtom ); 486 copy->ActOnAllAtoms( &atom::EqualsFather, (const atom *)Binder->rightatom, (const atom **)&RightAtom ); 510 487 511 488 NewBond = copy->AddBond(LeftAtom, RightAtom, Binder->BondDegree); … … 523 500 if (first->next != last) { // if adjaceny list is present 524 501 copy->BondDistance = BondDistance; 525 copy->CreateListOfBondsPerAtom((ofstream *)&cout);526 502 } 527 503 … … 536 512 * @param three vectors forming the matrix that defines the shape of the parallelpiped 537 513 */ 538 molecule* molecule::CopyMoleculeFromSubRegion( Vector offset, double *parallelepiped){514 molecule* molecule::CopyMoleculeFromSubRegion(const Vector offset, const double *parallelepiped) const { 539 515 molecule *copy = new molecule(elemente); 540 516 … … 557 533 if ((atom1 != NULL) && (FindAtom(atom1->nr) != NULL) && (atom2 != NULL) && (FindAtom(atom2->nr) != NULL)) { 558 534 Binder = new bond(atom1, atom2, degree, BondCount++); 535 atom1->RegisterBond(Binder); 536 atom2->RegisterBond(Binder); 559 537 if ((atom1->type != NULL) && (atom1->type->Z != 1) && (atom2->type != NULL) && (atom2->type->Z != 1)) 560 538 NoNonBonds++; … … 566 544 }; 567 545 568 /** Remove bond from bond chain list .546 /** Remove bond from bond chain list and from the both atom::ListOfBonds. 569 547 * \todo Function not implemented yet 570 548 * \param *pointer bond pointer … … 574 552 { 575 553 //cerr << Verbose(1) << "molecule::RemoveBond: Function not implemented yet." << endl; 554 pointer->leftatom->RegisterBond(pointer); 555 pointer->rightatom->RegisterBond(pointer); 576 556 removewithoutcheck(pointer); 577 557 return true; … … 585 565 bool molecule::RemoveBonds(atom *BondPartner) 586 566 { 587 cerr << Verbose(1) << "molecule::RemoveBond: Function not implemented yet." << endl; 567 //cerr << Verbose(1) << "molecule::RemoveBond: Function not implemented yet." << endl; 568 BondList::const_iterator ForeRunner; 569 while (!BondPartner->ListOfBonds.empty()) { 570 ForeRunner = BondPartner->ListOfBonds.begin(); 571 RemoveBond(*ForeRunner); 572 } 588 573 return false; 589 574 }; … … 635 620 if (ElementsInMolecule[pointer->type->Z] == 0) // was last atom of this element? 636 621 ElementCount--; 622 RemoveBonds(pointer); 637 623 return remove(pointer, start, end); 638 624 }; … … 661 647 bool molecule::CleanupMolecule() 662 648 { 663 return (cleanup( start,end) && cleanup(first,last));649 return (cleanup(first,last) && cleanup(start,end)); 664 650 }; 665 651 … … 735 721 ElementNo[i] = current++; 736 722 } 737 ActOnAllAtoms( &atom::Output , out, ElementNo, AtomNo, (const char *) NULL ); // (bool (atom::*)(int *, int *, ofstream *, const char *))723 ActOnAllAtoms( &atom::OutputArrayIndexed, (ofstream *)out, (const int *)ElementNo, (int *)AtomNo, (const char *) NULL ); 738 724 return true; 739 725 } … … 767 753 ElementNo[i] = current++; 768 754 } 769 ActOnAllAtoms( &atom::OutputTrajectory, out, ElementNo, AtomNo,step );755 ActOnAllAtoms( &atom::OutputTrajectory, out, (const int *)ElementNo, AtomNo, (const int)step ); 770 756 } 771 757 return true; … … 773 759 }; 774 760 775 /** Outputs contents of molecule::ListOfBondsPerAtom.761 /** Outputs contents of each atom::ListOfBonds. 776 762 * \param *out output stream 777 763 */ 778 764 void molecule::OutputListOfBonds(ofstream *out) const 779 765 { 780 *out << Verbose(2) << endl << "From Contents of ListOfBonds PerAtom, all non-hydrogen atoms:" << endl;781 ActOnAllAtoms (&atom::OutputBondOfAtom, out , NumberOfBondsPerAtom, ListOfBondsPerAtom);766 *out << Verbose(2) << endl << "From Contents of ListOfBonds, all non-hydrogen atoms:" << endl; 767 ActOnAllAtoms (&atom::OutputBondOfAtom, out); 782 768 *out << endl; 783 769 }; … … 902 888 }; 903 889 904 905 /** Creates an 2d array of pointer with an entry for each atom and each bond it has.906 * Updates molecule::ListOfBondsPerAtom, molecule::NumberOfBondsPerAtom by parsing through907 * bond chain list, using molecule::AtomCount and molecule::BondCount.908 * Allocates memory, fills the array and exits909 * \param *out output stream for debugging910 */911 void molecule::CreateListOfBondsPerAtom(ofstream *out)912 {913 bond *Binder = NULL;914 *out << Verbose(1) << "Begin of Creating ListOfBondsPerAtom: AtomCount = " << AtomCount << "\tBondCount = " << BondCount << "\tNoNonBonds = " << NoNonBonds << "." << endl;915 916 // re-allocate memory917 *out << Verbose(2) << "(Re-)Allocating memory." << endl;918 if (ListOfBondsPerAtom != NULL) {919 for(int i=AtomCount;i--;)920 Free(&ListOfBondsPerAtom[i]);921 Free(&ListOfBondsPerAtom);922 }923 if (NumberOfBondsPerAtom != NULL)924 Free(&NumberOfBondsPerAtom);925 ListOfBondsPerAtom = Malloc<bond**>(AtomCount, "molecule::CreateListOfBondsPerAtom: ***ListOfBondsPerAtom");926 NumberOfBondsPerAtom = Malloc<int>(AtomCount, "molecule::CreateListOfBondsPerAtom: *NumberOfBondsPerAtom");927 928 // reset bond counts per atom929 for(int i=AtomCount;i--;)930 NumberOfBondsPerAtom[i] = 0;931 // count bonds per atom932 Binder = first;933 while (Binder->next != last) {934 Binder = Binder->next;935 NumberOfBondsPerAtom[Binder->leftatom->nr]++;936 NumberOfBondsPerAtom[Binder->rightatom->nr]++;937 }938 for(int i=AtomCount;i--;) {939 // allocate list of bonds per atom940 ListOfBondsPerAtom[i] = Malloc<bond*>(NumberOfBondsPerAtom[i], "molecule::CreateListOfBondsPerAtom: **ListOfBondsPerAtom[]");941 // clear the list again, now each NumberOfBondsPerAtom marks current free field942 NumberOfBondsPerAtom[i] = 0;943 }944 // fill the list945 Binder = first;946 while (Binder->next != last) {947 Binder = Binder->next;948 ListOfBondsPerAtom[Binder->leftatom->nr][NumberOfBondsPerAtom[Binder->leftatom->nr]++] = Binder;949 ListOfBondsPerAtom[Binder->rightatom->nr][NumberOfBondsPerAtom[Binder->rightatom->nr]++] = Binder;950 }951 952 // output list for debugging953 *out << Verbose(3) << "ListOfBondsPerAtom for each atom:" << endl;954 ActOnAllAtoms( &atom::OutputBondOfAtom, out, NumberOfBondsPerAtom, ListOfBondsPerAtom );955 956 *out << Verbose(1) << "End of Creating ListOfBondsPerAtom." << endl << endl;957 };958 959 890 /** Determines whether two molecules actually contain the same atoms and coordination. 960 891 * \param *out output stream for debugging … … 1026 957 if (result) { 1027 958 *out << Verbose(5) << "Calculating distances" << endl; 1028 Distances = Malloc<double>(AtomCount, "molecule::IsEqualToWithinThreshold: Distances");1029 OtherDistances = Malloc<double>(AtomCount, "molecule::IsEqualToWithinThreshold: OtherDistances");1030 SetIndexedArrayForEachAtomTo ( Distances, &atom::nr, &atom::DistanceSquaredToVector, CenterOfGravity);1031 SetIndexedArrayForEachAtomTo ( OtherDistances, &atom::nr, &atom::DistanceSquaredToVector, CenterOfGravity);959 Distances = Calloc<double>(AtomCount, "molecule::IsEqualToWithinThreshold: Distances"); 960 OtherDistances = Calloc<double>(AtomCount, "molecule::IsEqualToWithinThreshold: OtherDistances"); 961 SetIndexedArrayForEachAtomTo ( Distances, &atom::nr, &atom::DistanceSquaredToVector, (const Vector &)CenterOfGravity); 962 SetIndexedArrayForEachAtomTo ( OtherDistances, &atom::nr, &atom::DistanceSquaredToVector, (const Vector &)CenterOfGravity); 1032 963 1033 964 /// ... sort each list (using heapsort (o(N log N)) from GSL) 1034 965 *out << Verbose(5) << "Sorting distances" << endl; 1035 PermMap = Malloc<size_t>(AtomCount, "molecule::IsEqualToWithinThreshold: *PermMap");1036 OtherPermMap = Malloc<size_t>(AtomCount, "molecule::IsEqualToWithinThreshold: *OtherPermMap");966 PermMap = Calloc<size_t>(AtomCount, "molecule::IsEqualToWithinThreshold: *PermMap"); 967 OtherPermMap = Calloc<size_t>(AtomCount, "molecule::IsEqualToWithinThreshold: *OtherPermMap"); 1037 968 gsl_heapsort_index (PermMap, Distances, AtomCount, sizeof(double), CompareDoubles); 1038 969 gsl_heapsort_index (OtherPermMap, OtherDistances, AtomCount, sizeof(double), CompareDoubles); 1039 PermutationMap = Malloc<int>(AtomCount, "molecule::IsEqualToWithinThreshold: *PermutationMap");970 PermutationMap = Calloc<int>(AtomCount, "molecule::IsEqualToWithinThreshold: *PermutationMap"); 1040 971 *out << Verbose(5) << "Combining Permutation Maps" << endl; 1041 972 for(int i=AtomCount;i--;) … … 1135 1066 for (int step=startstep;step < endstep; step++) { // loop over all time steps 1136 1067 temperature = 0.; 1137 ActOnAllAtoms( & atom::AddKineticToTemperature, &temperature, step);1068 ActOnAllAtoms( &TrajectoryParticle::AddKineticToTemperature, &temperature, step); 1138 1069 *output << step << "\t" << temperature*AtomicEnergyToKelvin << "\t" << temperature << endl; 1139 1070 } … … 1141 1072 }; 1142 1073 1143 void molecule::SetIndexedArrayForEachAtomTo ( atom **array, int TesselPoint::*index)1074 void molecule::SetIndexedArrayForEachAtomTo ( atom **array, int ParticleInfo::*index) const 1144 1075 { 1145 1076 atom *Walker = start; -
src/molecule.hpp
r06c7a3 r7326b2 35 35 class atom; 36 36 class bond; 37 class BondedParticle; 38 class BondGraph; 37 39 class element; 38 40 class ForceMatrix; … … 81 83 public: 82 84 double cell_size[6];//!< cell size 83 periodentafel *elemente; //!< periodic table with each element85 const periodentafel * const elemente; //!< periodic table with each element 84 86 atom *start; //!< start of atom list 85 87 atom *end; //!< end of atom list 86 88 bond *first; //!< start of bond list 87 89 bond *last; //!< end of bond list 88 bond ***ListOfBondsPerAtom; //!< pointer list for each atom and each bond it has89 90 int MDSteps; //!< The number of MD steps in Trajectories 90 int *NumberOfBondsPerAtom; //!< Number of Bonds each atom has91 91 int AtomCount; //!< number of atoms, brought up-to-date by CountAtoms() 92 92 int BondCount; //!< number of atoms, brought up-to-date by CountBonds() 93 93 int ElementCount; //!< how many unique elements are therein 94 94 int ElementsInMolecule[MAX_ELEMENTS]; //!< list whether element (sorted by atomic number) is alread present or not 95 int NoNonHydrogen; //!< number of non-hydrogen atoms in molecule96 int NoNonBonds; //!< number of non-hydrogen bonds in molecule97 int NoCyclicBonds; //!< number of cyclic bonds in molecule, by DepthFirstSearchAnalysis()95 mutable int NoNonHydrogen; //!< number of non-hydrogen atoms in molecule 96 mutable int NoNonBonds; //!< number of non-hydrogen bonds in molecule 97 mutable int NoCyclicBonds; //!< number of cyclic bonds in molecule, by DepthFirstSearchAnalysis() 98 98 double BondDistance; //!< typical bond distance used in CreateAdjacencyList() and furtheron 99 99 bool ActiveFlag; //!< in a MoleculeListClass used to discern active from inactive molecules … … 101 101 char name[MAXSTRINGSIZE]; //!< arbitrary name 102 102 int IndexNr; //!< index of molecule in a MoleculeListClass 103 class Tesselation *TesselStruct; 104 105 molecule(periodentafel *teil); 103 104 molecule(const periodentafel * const teil); 106 105 virtual ~molecule(); 107 106 108 107 // re-definition of virtual functions from PointCloud 109 Vector *GetCenter(ofstream *out) ;110 TesselPoint *GetPoint() ;111 TesselPoint *GetTerminalPoint() ;112 void GoToNext() ;113 void GoToPrevious() ;114 void GoToFirst() ;115 void GoToLast() ;116 bool IsEmpty() ;117 bool IsEnd() ;108 Vector *GetCenter(ofstream *out) const ; 109 TesselPoint *GetPoint() const ; 110 TesselPoint *GetTerminalPoint() const ; 111 void GoToNext() const ; 112 void GoToPrevious() const ; 113 void GoToFirst() const ; 114 void GoToLast() const ; 115 bool IsEmpty() const ; 116 bool IsEnd() const ; 118 117 119 118 // templates for allowing global manipulation of all vectors 120 template <typename res> void ActOnAllVectors( res (Vector::*f)() );121 template <typename res> void ActOnAllVectors( res (Vector::*f)() const);122 119 template <typename res> void ActOnAllVectors( res (Vector::*f)() ) const; 123 120 template <typename res> void ActOnAllVectors( res (Vector::*f)() const) const; 124 template <typename res, typename T> void ActOnAllVectors( res (Vector::*f)(T), T t );125 template <typename res, typename T> void ActOnAllVectors( res (Vector::*f)(T) const, T t );126 121 template <typename res, typename T> void ActOnAllVectors( res (Vector::*f)(T), T t ) const; 127 122 template <typename res, typename T> void ActOnAllVectors( res (Vector::*f)(T) const, T t ) const; 128 template <typename res, typename T, typename U> void ActOnAllVectors( res (Vector::*f)(T, U), T t, U u );129 template <typename res, typename T, typename U> void ActOnAllVectors( res (Vector::*f)(T, U) const, T t, U u );130 123 template <typename res, typename T, typename U> void ActOnAllVectors( res (Vector::*f)(T, U), T t, U u ) const; 131 124 template <typename res, typename T, typename U> void ActOnAllVectors( res (Vector::*f)(T, U) const, T t, U u ) const; 132 template <typename res, typename T, typename U, typename V> void ActOnAllVectors( res (Vector::*f)(T, U, V), T t, U u, V v);133 template <typename res, typename T, typename U, typename V> void ActOnAllVectors( res (Vector::*f)(T, U, V) const, T t, U u, V v);134 125 template <typename res, typename T, typename U, typename V> void ActOnAllVectors( res (Vector::*f)(T, U, V), T t, U u, V v) const; 135 126 template <typename res, typename T, typename U, typename V> void ActOnAllVectors( res (Vector::*f)(T, U, V) const, T t, U u, V v) const; 136 127 137 128 // templates for allowing global manipulation of molecule with each atom as single argument 138 template <typename res> void ActWithEachAtom( res (molecule::*f)(atom *) );139 template <typename res> void ActWithEachAtom( res (molecule::*f)(atom *) const);140 129 template <typename res> void ActWithEachAtom( res (molecule::*f)(atom *) ) const; 141 130 template <typename res> void ActWithEachAtom( res (molecule::*f)(atom *) const) const; 142 131 143 132 // templates for allowing global copying of molecule with each atom as single argument 144 template <typename res> void ActOnCopyWithEachAtom( res (molecule::*f)(atom *) , molecule *copy);145 template <typename res> void ActOnCopyWithEachAtom( res (molecule::*f)(atom *) const , molecule *copy);146 133 template <typename res> void ActOnCopyWithEachAtom( res (molecule::*f)(atom *) , molecule *copy) const; 147 134 template <typename res> void ActOnCopyWithEachAtom( res (molecule::*f)(atom *) const, molecule *copy) const; 148 135 149 136 // templates for allowing global manipulation of all atoms 150 template <typename res> void ActOnAllAtoms( res (atom::*f)() ); 151 template <typename res> void ActOnAllAtoms( res (atom::*f)() const ); 152 template <typename res> void ActOnAllAtoms( res (atom::*f)() ) const; 153 template <typename res> void ActOnAllAtoms( res (atom::*f)() const) const; 154 template <typename res, typename T> void ActOnAllAtoms( res (atom::*f)(T), T t ); 155 template <typename res, typename T> void ActOnAllAtoms( res (atom::*f)(T) const, T t ); 156 template <typename res, typename T> void ActOnAllAtoms( res (atom::*f)(T), T t ) const; 157 template <typename res, typename T> void ActOnAllAtoms( res (atom::*f)(T) const, T t ) const; 158 template <typename res, typename T, typename U> void ActOnAllAtoms( res (atom::*f)(T, U), T t, U u ); 159 template <typename res, typename T, typename U> void ActOnAllAtoms( res (atom::*f)(T, U) const, T t, U u ); 160 template <typename res, typename T, typename U> void ActOnAllAtoms( res (atom::*f)(T, U), T t, U u ) const; 161 template <typename res, typename T, typename U> void ActOnAllAtoms( res (atom::*f)(T, U) const, T t, U u ) const; 162 template <typename res, typename T, typename U, typename V> void ActOnAllAtoms( res (atom::*f)(T, U, V), T t, U u, V v); 163 template <typename res, typename T, typename U, typename V> void ActOnAllAtoms( res (atom::*f)(T, U, V) const, T t, U u, V v); 164 template <typename res, typename T, typename U, typename V> void ActOnAllAtoms( res (atom::*f)(T, U, V), T t, U u, V v) const; 165 template <typename res, typename T, typename U, typename V> void ActOnAllAtoms( res (atom::*f)(T, U, V) const, T t, U u, V v) const; 166 template <typename res, typename T, typename U, typename V, typename W> void ActOnAllAtoms( res (atom::*f)(T, U, V, W), T t, U u, V v, W w); 167 template <typename res, typename T, typename U, typename V, typename W> void ActOnAllAtoms( res (atom::*f)(T, U, V, W) const, T t, U u, V v, W w); 168 template <typename res, typename T, typename U, typename V, typename W> void ActOnAllAtoms( res (atom::*f)(T, U, V, W), T t, U u, V v, W w) const; 169 template <typename res, typename T, typename U, typename V, typename W> void ActOnAllAtoms( res (atom::*f)(T, U, V, W) const, T t, U u, V v, W w) const; 137 template <typename res, typename typ> void ActOnAllAtoms( res (typ::*f)() ) const; 138 template <typename res, typename typ> void ActOnAllAtoms( res (typ::*f)() const) const; 139 template <typename res, typename typ, typename T> void ActOnAllAtoms( res (typ::*f)(T), T t ) const; 140 template <typename res, typename typ, typename T> void ActOnAllAtoms( res (typ::*f)(T) const, T t ) const; 141 template <typename res, typename typ, typename T, typename U> void ActOnAllAtoms( res (typ::*f)(T, U), T t, U u ) const; 142 template <typename res, typename typ, typename T, typename U> void ActOnAllAtoms( res (typ::*f)(T, U) const, T t, U u ) const; 143 template <typename res, typename typ, typename T, typename U, typename V> void ActOnAllAtoms( res (typ::*f)(T, U, V), T t, U u, V v) const; 144 template <typename res, typename typ, typename T, typename U, typename V> void ActOnAllAtoms( res (typ::*f)(T, U, V) const, T t, U u, V v) const; 145 template <typename res, typename typ, typename T, typename U, typename V, typename W> void ActOnAllAtoms( res (typ::*f)(T, U, V, W), T t, U u, V v, W w) const; 146 template <typename res, typename typ, typename T, typename U, typename V, typename W> void ActOnAllAtoms( res (typ::*f)(T, U, V, W) const, T t, U u, V v, W w) const; 170 147 171 148 // templates for allowing conditional global copying of molecule with each atom as single argument 172 template <typename res> void ActOnCopyWithEachAtomIfTrue( res (molecule::*f)(atom *) , molecule *copy, bool (atom::*condition) () ); 173 template <typename res, typename T> void ActOnCopyWithEachAtomIfTrue( res (molecule::*f)(atom *) , molecule *copy, bool (atom::*condition) (T), T t ); 174 template <typename res, typename T, typename U> void ActOnCopyWithEachAtomIfTrue( res (molecule::*f)(atom *) , molecule *copy, bool (atom::*condition) (T, U), T t, U u ); 175 template <typename res, typename T, typename U, typename V> void ActOnCopyWithEachAtomIfTrue( res (molecule::*f)(atom *) , molecule *copy, bool (atom::*condition) (T, U, V), T t, U u, V v ); 149 template <typename res> void ActOnCopyWithEachAtomIfTrue( res (molecule::*f)(atom *) , molecule *copy, bool (atom::*condition) () ) const; 150 template <typename res> void ActOnCopyWithEachAtomIfTrue( res (molecule::*f)(atom *) , molecule *copy, bool (atom::*condition) () const ) const; 151 template <typename res> void ActOnCopyWithEachAtomIfTrue( res (molecule::*f)(atom *) const , molecule *copy, bool (atom::*condition) () ) const; 152 template <typename res> void ActOnCopyWithEachAtomIfTrue( res (molecule::*f)(atom *) const , molecule *copy, bool (atom::*condition) () const ) const; 153 template <typename res, typename T> void ActOnCopyWithEachAtomIfTrue( res (molecule::*f)(atom *) , molecule *copy, bool (atom::*condition) (T), T t ) const; 154 template <typename res, typename T> void ActOnCopyWithEachAtomIfTrue( res (molecule::*f)(atom *) , molecule *copy, bool (atom::*condition) (T) const, T t ) const; 155 template <typename res, typename T> void ActOnCopyWithEachAtomIfTrue( res (molecule::*f)(atom *) const , molecule *copy, bool (atom::*condition) (T), T t ) const; 156 template <typename res, typename T> void ActOnCopyWithEachAtomIfTrue( res (molecule::*f)(atom *) const , molecule *copy, bool (atom::*condition) (T) const, T t ) const; 157 template <typename res, typename T, typename U> void ActOnCopyWithEachAtomIfTrue( res (molecule::*f)(atom *) , molecule *copy, bool (atom::*condition) (T, U), T t, U u ) const; 158 template <typename res, typename T, typename U> void ActOnCopyWithEachAtomIfTrue( res (molecule::*f)(atom *) , molecule *copy, bool (atom::*condition) (T, U) const, T t, U u ) const; 159 template <typename res, typename T, typename U> void ActOnCopyWithEachAtomIfTrue( res (molecule::*f)(atom *) const , molecule *copy, bool (atom::*condition) (T, U), T t, U u ) const; 160 template <typename res, typename T, typename U> void ActOnCopyWithEachAtomIfTrue( res (molecule::*f)(atom *) const , molecule *copy, bool (atom::*condition) (T, U) const, T t, U u ) const; 161 template <typename res, typename T, typename U, typename V> void ActOnCopyWithEachAtomIfTrue( res (molecule::*f)(atom *) , molecule *copy, bool (atom::*condition) (T, U, V), T t, U u, V v ) const; 162 template <typename res, typename T, typename U, typename V> void ActOnCopyWithEachAtomIfTrue( res (molecule::*f)(atom *) , molecule *copy, bool (atom::*condition) (T, U, V) const, T t, U u, V v ) const; 163 template <typename res, typename T, typename U, typename V> void ActOnCopyWithEachAtomIfTrue( res (molecule::*f)(atom *) const , molecule *copy, bool (atom::*condition) (T, U, V), T t, U u, V v ) const; 164 template <typename res, typename T, typename U, typename V> void ActOnCopyWithEachAtomIfTrue( res (molecule::*f)(atom *) const , molecule *copy, bool (atom::*condition) (T, U, V) const, T t, U u, V v ) const; 176 165 177 166 // templates for allowing global manipulation of an array with one entry per atom 178 void SetIndexedArrayForEachAtomTo ( atom **array, int TesselPoint::* index); 179 template <typename T> void SetIndexedArrayForEachAtomTo ( T *array, int TesselPoint::* index, void (*Setor)(T *, T *)); 180 template <typename T> void SetIndexedArrayForEachAtomTo ( T *array, int TesselPoint::* index, void (*Setor)(T *, T *), T t); 181 template <typename T> void SetIndexedArrayForEachAtomTo ( T *array, int TesselPoint::* index, void (*Setor)(T *, T *), T *t); 182 template <typename T> void SetIndexedArrayForEachAtomTo ( T *array, int element::*index, void (*Setor)(T *, T *)); 183 template <typename T> void SetIndexedArrayForEachAtomTo ( T *array, int element::*index, void (*Setor)(T *, T *), T t); 184 template <typename T> void SetIndexedArrayForEachAtomTo ( T *array, int element::*index, void (*Setor)(T *, T *), T *t); 185 template <typename T> void SetIndexedArrayForEachAtomTo ( T *array, int TesselPoint::* index, T (atom::*Setor)(Vector &), Vector atom::*value); 186 template <typename T> void SetIndexedArrayForEachAtomTo ( T *array, int TesselPoint::*index, T (atom::*Setor)(Vector &), Vector &vect ); 167 void SetIndexedArrayForEachAtomTo ( atom **array, int ParticleInfo::* index) const; 168 template <typename T> void SetIndexedArrayForEachAtomTo ( T *array, int ParticleInfo::* index, void (*Setor)(T *, T *)) const; 169 template <typename T> void SetIndexedArrayForEachAtomTo ( T *array, int ParticleInfo::* index, void (*Setor)(T *, T *), T t) const; 170 template <typename T> void SetIndexedArrayForEachAtomTo ( T *array, int ParticleInfo::* index, void (*Setor)(T *, T *), T *t) const; 171 template <typename T> void SetIndexedArrayForEachAtomTo ( T *array, int element::* index, void (*Setor)(T *, T *)) const; 172 template <typename T> void SetIndexedArrayForEachAtomTo ( T *array, int element::* index, void (*Setor)(T *, T *), T t) const; 173 template <typename T> void SetIndexedArrayForEachAtomTo ( T *array, int element::* index, void (*Setor)(T *, T *), T *t) const; 174 template <typename T, typename typ> void SetIndexedArrayForEachAtomTo ( T *array, int ParticleInfo::*index, T (atom::*Setor)(typ &), typ atom::*value) const; 175 template <typename T, typename typ> void SetIndexedArrayForEachAtomTo ( T *array, int ParticleInfo::*index, T (atom::*Setor)(typ &) const, typ atom::*value) const; 176 template <typename T, typename typ> void SetIndexedArrayForEachAtomTo ( T *array, int ParticleInfo::*index, T (atom::*Setor)(typ &), typ &vect ) const; 177 template <typename T, typename typ> void SetIndexedArrayForEachAtomTo ( T *array, int ParticleInfo::*index, T (atom::*Setor)(typ &) const, typ &vect ) const; 187 178 188 179 // templates for allowing global manipulation of each atom by entries in an array 189 template <typename T> void SetAtomValueToIndexedArray ( T *array, int TesselPoint::*index, T atom::*value ); 190 template <typename T> void SetAtomValueToIndexedArray ( T *array, int element::*index, T atom::*value ); 180 template <typename T, typename typ, typename typ2> void SetAtomValueToIndexedArray ( T *array, int typ::*index, T typ2::*value ) const; 181 template <typename T, typename typ> void SetAtomValueToValue ( T value, T typ::*ptr ) const; 182 183 template <typename res, typename typ> res SumPerAtom(res (typ::*f)() ) const; 184 template <typename res, typename typ> res SumPerAtom(res (typ::*f)() const ) const; 185 template <typename res, typename typ, typename T> res SumPerAtom(res (typ::*f)(T) , T t ) const; 186 template <typename res, typename typ, typename T> res SumPerAtom(res (typ::*f)(T) const, T t ) const; 191 187 192 188 /// remove atoms from molecule. … … 199 195 atom * AddCopyAtom(atom *pointer); 200 196 bool AddXYZFile(string filename); 201 bool AddHydrogenReplacementAtom(ofstream *out, bond *Bond, atom *BottomOrigin, atom *TopOrigin, atom *TopReplacement, bo nd **BondList, int NumBond, bool IsAngstroem);197 bool AddHydrogenReplacementAtom(ofstream *out, bond *Bond, atom *BottomOrigin, atom *TopOrigin, atom *TopReplacement, bool IsAngstroem); 202 198 bond * AddBond(atom *first, atom *second, int degree = 1); 203 199 bool RemoveBond(bond *pointer); … … 222 218 void Mirror(const Vector *x); 223 219 void Align(Vector *n); 224 void Scale( double **factor);220 void Scale(const double ** const factor); 225 221 void DeterminePeriodicCenter(Vector ¢er); 226 222 Vector * DetermineCenterOfGravity(ofstream *out); 227 Vector * DetermineCenterOfAll(ofstream *out) ;223 Vector * DetermineCenterOfAll(ofstream *out) const; 228 224 void SetNameFromFilename(const char *filename); 229 225 void SetBoxDimension(Vector *dim); … … 233 229 void PrincipalAxisSystem(ofstream *out, bool DoRotate); 234 230 double VolumeOfConvexEnvelope(ofstream *out, bool IsAngstroem); 235 Vector* FindEmbeddingHole(ofstream *out, molecule *srcmol);236 237 231 238 232 double ConstrainedPotential(ofstream *out, struct EvaluatePotential &Params); … … 245 239 246 240 /// Initialising routines in fragmentation 247 void CreateAdjacencyList2(ofstream *out, ifstream *output); 248 void CreateAdjacencyList(ofstream *out, double bonddistance, bool IsAngstroem); 249 void CreateListOfBondsPerAtom(ofstream *out); 241 void CreateAdjacencyListFromDbondFile(ofstream *out, ifstream *output); 242 void CreateAdjacencyList(ofstream *out, double bonddistance, bool IsAngstroem, void (BondGraph::*f)(BondedParticle * const , BondedParticle * const , double &, double &, bool), BondGraph *BG = NULL); 243 int CorrectBondDegree(ofstream *out) const; 244 void OutputBondsList(ofstream *out) const; 245 void CyclicBondAnalysis() const; 246 void OutputGraphInfoPerAtom(ofstream *out) const; 247 void OutputGraphInfoPerBond(ofstream *out) const; 248 250 249 251 250 // Graph analysis 252 MoleculeLeafClass * DepthFirstSearchAnalysis(ofstream *out, class StackClass<bond *> *&BackEdgeStack); 253 void CyclicStructureAnalysis(ofstream *out, class StackClass<bond *> *BackEdgeStack, int *&MinimumRingSize); 254 bool PickLocalBackEdges(ofstream *out, atom **ListOfLocalAtoms, class StackClass<bond *> *&ReferenceStack, class StackClass<bond *> *&LocalStack); 255 bond * FindNextUnused(atom *vertex); 256 void SetNextComponentNumber(atom *vertex, int nr); 257 void InitComponentNumbers(); 258 void OutputComponentNumber(ofstream *out, atom *vertex); 259 void ResetAllBondsToUnused(); 260 void ResetAllAtomNumbers(); 251 MoleculeLeafClass * DepthFirstSearchAnalysis(ofstream *out, class StackClass<bond *> *&BackEdgeStack) const; 252 void CyclicStructureAnalysis(ofstream *out, class StackClass<bond *> *BackEdgeStack, int *&MinimumRingSize) const; 253 bool PickLocalBackEdges(ofstream *out, atom **ListOfLocalAtoms, class StackClass<bond *> *&ReferenceStack, class StackClass<bond *> *&LocalStack) const; 254 bond * FindNextUnused(atom *vertex) const; 255 void SetNextComponentNumber(atom *vertex, int nr) const; 256 void ResetAllBondsToUnused() const; 261 257 int CountCyclicBonds(ofstream *out); 262 258 bool CheckForConnectedSubgraph(ofstream *out, KeySet *Fragment); 263 string GetColor(enum Shading color); 259 string GetColor(enum Shading color) const; 260 bond * CopyBond(atom *left, atom *right, bond *CopyBond); 261 264 262 265 263 molecule *CopyMolecule(); 266 molecule* CopyMoleculeFromSubRegion( Vector offset, double *parallelepiped);264 molecule* CopyMoleculeFromSubRegion(const Vector offset, const double *parallelepiped) const; 267 265 268 266 /// Fragment molecule by two different approaches: … … 300 298 private: 301 299 int last_atom; //!< number given to last atom 302 atom *InternalPointer; //!< internal pointer for PointCloud300 mutable atom *InternalPointer; //!< internal pointer for PointCloud 303 301 }; 304 302 … … 323 321 void Enumerate(ofstream *out); 324 322 void Output(ofstream *out); 323 void DissectMoleculeIntoConnectedSubgraphs(ofstream * const out, molecule * const mol, config * const configuration); 325 324 326 325 // merging of molecules … … 352 351 353 352 bool AddLeaf(molecule *ptr, MoleculeLeafClass *Previous); 354 bool FillBondStructureFromReference(ofstream *out, molecule *reference, int &FragmentCounter, atom ***&ListOfLocalAtoms, bool FreeList = false);353 bool FillBondStructureFromReference(ofstream *out, const molecule * const reference, int &FragmentCounter, atom ***&ListOfLocalAtoms, bool FreeList = false); 355 354 bool FillRootStackForSubgraphs(ofstream *out, KeyStack *&RootStack, bool *AtomMask, int &FragmentCounter); 356 355 bool AssignKeySetsToFragment(ofstream *out, molecule *reference, Graph *KeySetList, atom ***&ListOfLocalAtoms, Graph **&FragmentList, int &FragmentCounter, bool FreeList = false); -
src/molecule_dynamics.cpp
r06c7a3 r7326b2 193 193 { 194 194 stringstream zeile1, zeile2; 195 int *DoubleList = Malloc<int>(AtomCount, "PrintPermutationMap: *DoubleList");195 int *DoubleList = Calloc<int>(AtomCount, "PrintPermutationMap: *DoubleList"); 196 196 int doubles = 0; 197 for (int i=0;i<AtomCount;i++)198 DoubleList[i] = 0;199 197 zeile1 << "PermutationMap: "; 200 198 zeile2 << " "; … … 243 241 void CreateInitialLists(ofstream *out, molecule *mol, struct EvaluatePotential &Params) 244 242 { 245 for (int i=mol->AtomCount; i--;)246 Params.DoubleList[i] = 0; // stores for how many atoms in startstep this atom is a target in endstep247 248 243 atom *Walker = mol->start; 249 244 while (Walker->next != mol->end) { … … 347 342 double Potential, OldPotential, OlderPotential; 348 343 struct EvaluatePotential Params; 349 Params.PermutationMap = Malloc<atom*>(AtomCount, "molecule::MinimiseConstrainedPotential: Params.**PermutationMap");344 Params.PermutationMap = Calloc<atom*>(AtomCount, "molecule::MinimiseConstrainedPotential: Params.**PermutationMap"); 350 345 Params.DistanceList = Malloc<DistanceMap*>(AtomCount, "molecule::MinimiseConstrainedPotential: Params.**DistanceList"); 351 346 Params.DistanceIterators = Malloc<DistanceMap::iterator>(AtomCount, "molecule::MinimiseConstrainedPotential: Params.*DistanceIterators"); 352 Params.DoubleList = Malloc<int>(AtomCount, "molecule::MinimiseConstrainedPotential: Params.*DoubleList");347 Params.DoubleList = Calloc<int>(AtomCount, "molecule::MinimiseConstrainedPotential: Params.*DoubleList"); 353 348 Params.StepList = Malloc<DistanceMap::iterator>(AtomCount, "molecule::MinimiseConstrainedPotential: Params.*StepList"); 354 349 int round; -
src/molecule_fragmentation.cpp
r06c7a3 r7326b2 31 31 int molecule::GuesstimateFragmentCount(ofstream *out, int order) 32 32 { 33 int c = 0;33 size_t c = 0; 34 34 int FragmentCount; 35 35 // get maximum bond degree … … 37 37 while (Walker->next != end) { 38 38 Walker = Walker->next; 39 c = ( NumberOfBondsPerAtom[Walker->nr] > c) ? NumberOfBondsPerAtom[Walker->nr]: c;39 c = (Walker->ListOfBonds.size() > c) ? Walker->ListOfBonds.size() : c; 40 40 } 41 41 FragmentCount = NoNonHydrogen*(1 << (c*order)); … … 123 123 } 124 124 125 Free(&filename); 125 126 return status; 126 127 }; … … 565 566 // ===== 1. Check whether bond structure is same as stored in files ==== 566 567 567 // fill the adjacency list568 CreateListOfBondsPerAtom(out);569 570 568 // create lookup table for Atom::nr 571 569 FragmentationToDo = FragmentationToDo && CreateFatherLookupTable(out, start, end, ListOfAtoms, AtomCount); … … 577 575 // ===== 2. perform a DFS analysis to gather info on cyclic structure and a list of disconnected subgraphs ===== 578 576 Subgraphs = DepthFirstSearchAnalysis(out, BackEdgeStack); 579 // fill the bond structure of the individually stored subgraphs 580 Subgraphs->next->FillBondStructureFromReference(out, this, (FragmentCounter = 0), ListOfLocalAtoms, false); // we want to keep the created ListOfLocalAtoms 577 581 578 // analysis of the cycles (print rings, get minimum cycle length) for each subgraph 582 579 for(int i=AtomCount;i--;) … … 586 583 while (MolecularWalker->next != NULL) { 587 584 MolecularWalker = MolecularWalker->next; 585 // fill the bond structure of the individually stored subgraphs 586 MolecularWalker->FillBondStructureFromReference(out, this, FragmentCounter, ListOfLocalAtoms, false); // we want to keep the created ListOfLocalAtoms 588 587 *out << Verbose(0) << "Analysing the cycles of subgraph " << MolecularWalker->Leaf << " with nr. " << FragmentCounter << "." << endl; 589 588 LocalBackEdgeStack = new StackClass<bond *> (MolecularWalker->Leaf->BondCount); … … 602 601 delete(LocalBackEdgeStack); 603 602 } 603 delete(BackEdgeStack); 604 604 605 605 // ===== 3. if structure still valid, parse key set file and others ===== … … 630 630 MolecularWalker = MolecularWalker->next; 631 631 *out << Verbose(1) << "Fragmenting subgraph " << MolecularWalker << "." << endl; 632 //MolecularWalker->Leaf->OutputListOfBonds(out); // output ListOfBondsPerAtomfor debugging632 //MolecularWalker->Leaf->OutputListOfBonds(out); // output atom::ListOfBonds for debugging 633 633 if (MolecularWalker->Leaf->first->next != MolecularWalker->Leaf->last) { 634 634 // call BOSSANOVA method … … 641 641 } 642 642 } 643 *out << Verbose(2) << "CheckOrder is " << CheckOrder << "." << endl; 643 644 delete[](RootStack); 644 645 delete[](AtomMask); … … 666 667 // ===== 8b. gather keyset lists (graphs) from all subgraphs and transform into MoleculeListClass ===== 667 668 //if (FragmentationToDo) { // we should always store the fragments again as coordination might have changed slightly without changing bond structure 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 } else713 714 //} else715 // *out << Verbose(1) << "No fragments to store." << endl;669 // allocate memory for the pointer array and transmorph graphs into full molecular fragments 670 BondFragments = new MoleculeListClass(); 671 int k=0; 672 for(Graph::iterator runner = TotalGraph.begin(); runner != TotalGraph.end(); runner++) { 673 KeySet test = (*runner).first; 674 *out << "Fragment No." << (*runner).second.first << " with TEFactor " << (*runner).second.second << "." << endl; 675 BondFragments->insert(StoreFragmentFromKeySet(out, test, configuration)); 676 k++; 677 } 678 *out << k << "/" << BondFragments->ListOfMolecules.size() << " fragments generated from the keysets." << endl; 679 680 // ===== 9. Save fragments' configuration and keyset files et al to disk === 681 if (BondFragments->ListOfMolecules.size() != 0) { 682 // create the SortIndex from BFS labels to order in the config file 683 CreateMappingLabelsToConfigSequence(out, SortIndex); 684 685 *out << Verbose(1) << "Writing " << BondFragments->ListOfMolecules.size() << " possible bond fragmentation configs" << endl; 686 if (BondFragments->OutputConfigForListOfFragments(out, configuration, SortIndex)) 687 *out << Verbose(1) << "All configs written." << endl; 688 else 689 *out << Verbose(1) << "Some config writing failed." << endl; 690 691 // store force index reference file 692 BondFragments->StoreForcesFile(out, configuration->configpath, SortIndex); 693 694 // store keysets file 695 StoreKeySetFile(out, TotalGraph, configuration->configpath); 696 697 // store Adjacency file 698 StoreAdjacencyToFile(out, configuration->configpath); 699 700 // store Hydrogen saturation correction file 701 BondFragments->AddHydrogenCorrection(out, configuration->configpath); 702 703 // store adaptive orders into file 704 StoreOrderAtSiteFile(out, configuration->configpath); 705 706 // restore orbital and Stop values 707 CalculateOrbitals(*configuration); 708 709 // free memory for bond part 710 *out << Verbose(1) << "Freeing bond memory" << endl; 711 delete(FragmentList); // remove bond molecule from memory 712 Free(&SortIndex); 713 } else { 714 *out << Verbose(1) << "FragmentList is zero on return, splitting failed." << endl; 715 } 716 delete(BondFragments); 716 717 *out << Verbose(0) << "End of bond fragmentation." << endl; 717 718 … … 754 755 bool molecule::ParseOrderAtSiteFromFile(ofstream *out, char *path) 755 756 { 756 unsigned char *OrderArray = Malloc<unsigned char>(AtomCount, "molecule::ParseOrderAtSiteFromFile - *OrderArray");757 bool *MaxArray = Malloc<bool>(AtomCount, "molecule::ParseOrderAtSiteFromFile - *MaxArray");757 unsigned char *OrderArray = Calloc<unsigned char>(AtomCount, "molecule::ParseOrderAtSiteFromFile - *OrderArray"); 758 bool *MaxArray = Calloc<bool>(AtomCount, "molecule::ParseOrderAtSiteFromFile - *MaxArray"); 758 759 bool status; 759 760 int AtomNr, value; … … 762 763 763 764 *out << Verbose(1) << "Begin of ParseOrderAtSiteFromFile" << endl; 764 for(int i=AtomCount;i--;)765 OrderArray[i] = 0;766 765 line << path << "/" << FRAGMENTPREFIX << ORDERATSITEFILE; 767 766 file.open(line.str().c_str()); 768 767 if (file != NULL) { 769 for (int i=AtomCount;i--;) { // initialise with 0770 OrderArray[i] = 0;771 MaxArray[i] = 0;772 }773 768 while (!file.eof()) { // parse from file 774 769 AtomNr = -1; … … 833 828 * \param *Leaf fragment molecule 834 829 * \param &Leaflet pointer to KeySet structure 835 * \param **SonList list which atom of \a *Leaf is a son of which atom in \a *mol830 * \param **SonList calloc'd list which atom of \a *Leaf is a son of which atom in \a *mol 836 831 * \return number of atoms in fragment 837 832 */ … … 843 838 for(int i=NDIM*2;i--;) 844 839 Leaf->cell_size[i] = mol->cell_size[i]; 845 846 // initialise SonList (indicates when we need to replace a bond with hydrogen instead)847 for(int i=mol->AtomCount;i--;)848 SonList[i] = NULL;849 840 850 841 // first create the minimal set of atoms from the KeySet … … 879 870 if (SonList[FatherOfRunner->nr] != NULL) { // check if this, our father, is present in list 880 871 // create all bonds 881 for ( int i=0;i<mol->NumberOfBondsPerAtom[FatherOfRunner->nr];i++) { // go through every bond of father882 OtherFather = mol->ListOfBondsPerAtom[FatherOfRunner->nr][i]->GetOtherAtom(FatherOfRunner);872 for (BondList::const_iterator BondRunner = FatherOfRunner->ListOfBonds.begin(); BondRunner != FatherOfRunner->ListOfBonds.end(); (++BondRunner)) { 873 OtherFather = (*BondRunner)->GetOtherAtom(FatherOfRunner); 883 874 // *out << Verbose(2) << "Father " << *FatherOfRunner << " of son " << *SonList[FatherOfRunner->nr] << " is bound to " << *OtherFather; 884 875 if (SonList[OtherFather->nr] != NULL) { … … 887 878 // *out << Verbose(3) << "Adding Bond: "; 888 879 // *out << 889 Leaf->AddBond(Runner, SonList[OtherFather->nr], mol->ListOfBondsPerAtom[FatherOfRunner->nr][i]->BondDegree);880 Leaf->AddBond(Runner, SonList[OtherFather->nr], (*BondRunner)->BondDegree); 890 881 // *out << "." << endl; 891 882 //NumBonds[Runner->nr]++; … … 898 889 #ifdef ADDHYDROGEN 899 890 //*out << Verbose(3) << "Adding Hydrogen to " << Runner->Name << " and a bond in between." << endl; 900 if(!Leaf->AddHydrogenReplacementAtom(out, mol->ListOfBondsPerAtom[FatherOfRunner->nr][i], Runner, FatherOfRunner, OtherFather, mol->ListOfBondsPerAtom[FatherOfRunner->nr],mol->NumberOfBondsPerAtom[FatherOfRunner->nr], IsAngstroem))891 if(!Leaf->AddHydrogenReplacementAtom(out, (*BondRunner), Runner, FatherOfRunner, OtherFather, IsAngstroem)) 901 892 exit(1); 902 893 #endif 903 //NumBonds[Runner->nr] += ListOfBondsPerAtom[FatherOfRunner->nr][i]->BondDegree;894 //NumBonds[Runner->nr] += Binder->BondDegree; 904 895 } 905 896 } … … 927 918 molecule * molecule::StoreFragmentFromKeySet(ofstream *out, KeySet &Leaflet, bool IsAngstroem) 928 919 { 929 atom **SonList = Malloc<atom*>(AtomCount, "molecule::StoreFragmentFromStack: **SonList");920 atom **SonList = Calloc<atom*>(AtomCount, "molecule::StoreFragmentFromStack: **SonList"); 930 921 molecule *Leaf = new molecule(elemente); 931 922 … … 936 927 CreateInducedSubgraphOfFragment(out, this, Leaf, SonList, IsAngstroem); 937 928 938 Leaf->CreateListOfBondsPerAtom(out);939 929 //Leaflet->Leaf->ScanForPeriodicCorrection(out); 940 930 Free(&SonList); … … 981 971 if (bit) { // if bit is set, we add this bond partner 982 972 OtherWalker = BondsSet[j]->rightatom; // rightatom is always the one more distant, i.e. the one to add 983 //*out << Verbose(1+verbosity) << "Current Bond is " << ListOfBondsPerAtom[Walker->nr][CurrentCombination] << ", checking on " << *OtherWalker << "." << endl;973 //*out << Verbose(1+verbosity) << "Current Bond is " << BondsSet[j] << ", checking on " << *OtherWalker << "." << endl; 984 974 *out << Verbose(2+verbosity) << "Adding " << *OtherWalker << " with nr " << OtherWalker->nr << "." << endl; 985 975 TestKeySetInsert = FragmentSet->insert(OtherWalker->nr); … … 1089 1079 NumCombinations = 1 << SetDimension; 1090 1080 1091 // Hier muessen von 1 bis NumberOfBondsPerAtom[Walker->nr] alle Kombinationen1092 // von Endstuecken (aus den Bonds) hinzugefuegt werden und fuer verbleibende ANOVAOrder1093 // re kursiv GraphCrawler in der naechsten Ebene aufgerufen werden1081 // here for all bonds of Walker all combinations of end pieces (from the bonds) 1082 // have to be added and for the remaining ANOVA order GraphCrawler be called 1083 // recursively for the next level 1094 1084 1095 1085 *out << Verbose(1+verbosity) << "Begin of SPFragmentGenerator." << endl; … … 1258 1248 atom *OtherWalker = NULL; 1259 1249 atom *Predecessor = NULL; 1250 bond *CurrentEdge = NULL; 1260 1251 bond *Binder = NULL; 1261 bond *CurrentEdge = NULL;1262 1252 int RootKeyNr = FragmentSearch.Root->GetTrueFather()->nr; 1263 1253 int RemainingWalkers = -1; … … 1285 1275 // go through all its bonds 1286 1276 *out << Verbose(1) << "Going through all bonds of Walker." << endl; 1287 for (int i=0;i<mol->NumberOfBondsPerAtom[AtomKeyNr];i++) { 1288 Binder = mol->ListOfBondsPerAtom[AtomKeyNr][i]; 1289 OtherWalker = Binder->GetOtherAtom(Walker); 1277 for (BondList::const_iterator Runner = Walker->ListOfBonds.begin(); Runner != Walker->ListOfBonds.end(); (++Runner)) { 1278 OtherWalker = (*Runner)->GetOtherAtom(Walker); 1290 1279 if ((RestrictedKeySet.find(OtherWalker->nr) != RestrictedKeySet.end()) 1291 1280 #ifdef ADDHYDROGEN … … 1293 1282 #endif 1294 1283 ) { // skip hydrogens and restrict to fragment 1295 *out << Verbose(2) << "Current partner is " << *OtherWalker << " with nr " << OtherWalker->nr << " in bond " << * Binder<< "." << endl;1284 *out << Verbose(2) << "Current partner is " << *OtherWalker << " with nr " << OtherWalker->nr << " in bond " << *(*Runner) << "." << endl; 1296 1285 // set the label if not set (and push on root stack as well) 1297 1286 if ((OtherWalker != Predecessor) && (OtherWalker->GetTrueFather()->nr > RootKeyNr)) { // only pass through those with label bigger than Root's … … 1394 1383 1395 1384 // prepare the subset and call the generator 1396 BondsList = Malloc<bond*>(FragmentSearch.BondsPerSPCount[0], "molecule::PowerSetGenerator: **BondsList");1385 BondsList = Calloc<bond*>(FragmentSearch.BondsPerSPCount[0], "molecule::PowerSetGenerator: **BondsList"); 1397 1386 BondsList[0] = FragmentSearch.BondsPerSPList[0]->next; // on SP level 0 there's only the root bond 1398 1387 … … 1549 1538 // FragmentLowerOrdersList is a 2D-array of pointer to MoleculeListClass objects, one dimension represents the ANOVA expansion of a single order (i.e. 5) 1550 1539 // with all needed lower orders that are subtracted, the other dimension is the BondOrder (i.e. from 1 to 5) 1551 NumMoleculesOfOrder = Malloc<int>(UpgradeCount, "molecule::FragmentBOSSANOVA: *NumMoleculesOfOrder");1552 FragmentLowerOrdersList = Malloc<Graph**>(UpgradeCount, "molecule::FragmentBOSSANOVA: ***FragmentLowerOrdersList");1540 NumMoleculesOfOrder = Calloc<int>(UpgradeCount, "molecule::FragmentBOSSANOVA: *NumMoleculesOfOrder"); 1541 FragmentLowerOrdersList = Calloc<Graph**>(UpgradeCount, "molecule::FragmentBOSSANOVA: ***FragmentLowerOrdersList"); 1553 1542 1554 1543 // initialise the fragments structure 1555 FragmentSearch.ShortestPathList = Malloc<int>(AtomCount, "molecule::PowerSetGenerator: *ShortestPathList");1556 1544 FragmentSearch.FragmentCounter = 0; 1557 1545 FragmentSearch.FragmentSet = new KeySet; 1558 1546 FragmentSearch.Root = FindAtom(RootKeyNr); 1547 FragmentSearch.ShortestPathList = Malloc<int>(AtomCount, "molecule::PowerSetGenerator: *ShortestPathList"); 1559 1548 for (int i=AtomCount;i--;) { 1560 1549 FragmentSearch.ShortestPathList[i] = -1; … … 1592 1581 // allocate memory for all lower level orders in this 1D-array of ptrs 1593 1582 NumLevels = 1 << (Order-1); // (int)pow(2,Order); 1594 FragmentLowerOrdersList[RootNr] = Malloc<Graph*>(NumLevels, "molecule::FragmentBOSSANOVA: **FragmentLowerOrdersList[]"); 1595 for (int i=0;i<NumLevels;i++) 1596 FragmentLowerOrdersList[RootNr][i] = NULL; 1583 FragmentLowerOrdersList[RootNr] = Calloc<Graph*>(NumLevels, "molecule::FragmentBOSSANOVA: **FragmentLowerOrdersList[]"); 1597 1584 1598 1585 // create top order where nothing is reduced … … 1670 1657 *out << Verbose(2) << "Begin of ScanForPeriodicCorrection." << endl; 1671 1658 1672 ColorList = Malloc<enum Shading>(AtomCount, "molecule::ScanForPeriodicCorrection: *ColorList");1659 ColorList = Calloc<enum Shading>(AtomCount, "molecule::ScanForPeriodicCorrection: *ColorList"); 1673 1660 while (flag) { 1674 1661 // remove bonds that are beyond bonddistance … … 1712 1699 ColorList[Walker->nr] = black; // mark as explored 1713 1700 Walker->x.AddVector(&Translationvector); // translate 1714 for ( int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++) { // go through all binding partners1715 if ( ListOfBondsPerAtom[Walker->nr][i]!= Binder) {1716 OtherWalker = ListOfBondsPerAtom[Walker->nr][i]->GetOtherAtom(Walker);1701 for (BondList::const_iterator Runner = Walker->ListOfBonds.begin(); Runner != Walker->ListOfBonds.end(); (++Runner)) { 1702 if ((*Runner) != Binder) { 1703 OtherWalker = (*Runner)->GetOtherAtom(Walker); 1717 1704 if (ColorList[OtherWalker->nr] == white) { 1718 1705 AtomStack->Push(OtherWalker); // push if yet unexplored -
src/molecule_geometry.cpp
r06c7a3 r7326b2 24 24 { 25 25 bool status = true; 26 Vector x;27 26 const Vector *Center = DetermineCenterOfAll(out); 28 27 double *M = ReturnFullMatrixforSymmetric(cell_size); 29 double *Minv = x.InverseMatrix(M);28 double *Minv = InverseMatrix(M); 30 29 31 30 // go through all atoms … … 46 45 { 47 46 bool status = true; 48 Vector x;49 47 double *M = ReturnFullMatrixforSymmetric(cell_size); 50 double *Minv = x.InverseMatrix(M);48 double *Minv = InverseMatrix(M); 51 49 52 50 // go through all atoms … … 122 120 * \return pointer to center of all vector 123 121 */ 124 Vector * molecule::DetermineCenterOfAll(ofstream *out) 122 Vector * molecule::DetermineCenterOfAll(ofstream *out) const 125 123 { 126 124 atom *ptr = start->next; // start at first in list … … 198 196 * \param *factor pointer to scaling factor 199 197 */ 200 void molecule::Scale( double **factor)198 void molecule::Scale(const double ** const factor) 201 199 { 202 200 atom *ptr = start; … … 231 229 void molecule::TranslatePeriodically(const Vector *trans) 232 230 { 233 Vector x;234 231 double *M = ReturnFullMatrixforSymmetric(cell_size); 235 double *Minv = x.InverseMatrix(M);232 double *Minv = InverseMatrix(M); 236 233 237 234 // go through all atoms … … 258 255 { 259 256 atom *Walker = start; 260 bond *Binder = NULL;261 257 double *matrix = ReturnFullMatrixforSymmetric(cell_size); 262 258 double tmp; … … 275 271 Testvector.InverseMatrixMultiplication(matrix); 276 272 Translationvector.Zero(); 277 for (int i=0;i<NumberOfBondsPerAtom[Walker->nr]; i++) { 278 Binder = ListOfBondsPerAtom[Walker->nr][i]; 279 if (Walker->nr < Binder->GetOtherAtom(Walker)->nr) // otherwise we shift one to, the other fro and gain nothing 273 for (BondList::const_iterator Runner = Walker->ListOfBonds.begin(); Runner != Walker->ListOfBonds.end(); (++Runner)) { 274 if (Walker->nr < (*Runner)->GetOtherAtom(Walker)->nr) // otherwise we shift one to, the other fro and gain nothing 280 275 for (int j=0;j<NDIM;j++) { 281 tmp = Walker->x.x[j] - Binder->GetOtherAtom(Walker)->x.x[j];276 tmp = Walker->x.x[j] - (*Runner)->GetOtherAtom(Walker)->x.x[j]; 282 277 if ((fabs(tmp)) > BondDistance) { 283 278 flag = false; 284 cout << Verbose(0) << "Hit: atom " << Walker->Name << " in bond " << * Binder<< " has to be shifted due to " << tmp << "." << endl;279 cout << Verbose(0) << "Hit: atom " << Walker->Name << " in bond " << *(*Runner) << " has to be shifted due to " << tmp << "." << endl; 285 280 if (tmp > 0) 286 281 Translationvector.x[j] -= 1.; … … 298 293 #ifdef ADDHYDROGEN 299 294 // now also change all hydrogens 300 for (int i=0;i<NumberOfBondsPerAtom[Walker->nr]; i++) { 301 Binder = ListOfBondsPerAtom[Walker->nr][i]; 302 if (Binder->GetOtherAtom(Walker)->type->Z == 1) { 303 Testvector.CopyVector(&Binder->GetOtherAtom(Walker)->x); 295 for (BondList::const_iterator Runner = Walker->ListOfBonds.begin(); Runner != Walker->ListOfBonds.end(); (++Runner)) { 296 if ((*Runner)->GetOtherAtom(Walker)->type->Z == 1) { 297 Testvector.CopyVector(&(*Runner)->GetOtherAtom(Walker)->x); 304 298 Testvector.InverseMatrixMultiplication(matrix); 305 299 Testvector.AddVector(&Translationvector); -
src/molecule_graph.cpp
r06c7a3 r7326b2 8 8 #include "atom.hpp" 9 9 #include "bond.hpp" 10 #include "bondgraph.hpp" 10 11 #include "config.hpp" 11 12 #include "element.hpp" 12 13 #include "helpers.hpp" 14 #include "linkedcell.hpp" 13 15 #include "lists.hpp" 14 16 #include "memoryallocator.hpp" 15 17 #include "molecule.hpp" 16 18 19 struct BFSAccounting 20 { 21 atom **PredecessorList; 22 int *ShortestPathList; 23 enum Shading *ColorList; 24 class StackClass<atom *> *BFSStack; 25 class StackClass<atom *> *TouchedStack; 26 int AtomCount; 27 int BondOrder; 28 atom *Root; 29 bool BackStepping; 30 int CurrentGraphNr; 31 int ComponentNr; 32 }; 33 34 /** Accounting data for Depth First Search. 35 */ 36 struct DFSAccounting 37 { 38 class StackClass<atom *> *AtomStack; 39 class StackClass<bond *> *BackEdgeStack; 40 int CurrentGraphNr; 41 int ComponentNumber; 42 atom *Root; 43 bool BackStepping; 44 }; 45 17 46 /************************************* Functions for class molecule *********************************/ 18 19 47 20 48 /** Creates an adjacency list of the molecule. 21 49 * We obtain an outside file with the indices of atoms which are bondmembers. 22 50 */ 23 void molecule::CreateAdjacencyList 2(ofstream *out, ifstream *input)51 void molecule::CreateAdjacencyListFromDbondFile(ofstream *out, ifstream *input) 24 52 { 25 53 26 54 // 1 We will parse bonds out of the dbond file created by tremolo. 27 int atom1, atom2, temp; 28 atom *Walker, *OtherWalker; 29 30 if (!input) 31 { 32 cout << Verbose(1) << "Opening silica failed \n"; 33 }; 34 35 *input >> ws >> atom1; 36 *input >> ws >> atom2; 37 cout << Verbose(1) << "Scanning file\n"; 38 while (!input->eof()) // Check whether we read everything already 39 { 40 *input >> ws >> atom1; 41 *input >> ws >> atom2; 42 if(atom2<atom1) //Sort indices of atoms in order 43 { 44 temp=atom1; 45 atom1=atom2; 46 atom2=temp; 47 }; 48 49 Walker=start; 50 while(Walker-> nr != atom1) // Find atom corresponding to first index 51 { 52 Walker = Walker->next; 53 }; 54 OtherWalker = Walker->next; 55 while(OtherWalker->nr != atom2) // Find atom corresponding to second index 56 { 57 OtherWalker= OtherWalker->next; 58 }; 59 AddBond(Walker, OtherWalker); //Add the bond between the two atoms with respective indices. 60 61 } 62 63 CreateListOfBondsPerAtom(out); 64 65 }; 66 55 int atom1, atom2; 56 atom *Walker, *OtherWalker; 57 58 if (!input) { 59 cout << Verbose(1) << "Opening silica failed \n"; 60 }; 61 62 *input >> ws >> atom1; 63 *input >> ws >> atom2; 64 cout << Verbose(1) << "Scanning file\n"; 65 while (!input->eof()) // Check whether we read everything already 66 { 67 *input >> ws >> atom1; 68 *input >> ws >> atom2; 69 70 if (atom2 < atom1) //Sort indices of atoms in order 71 flip(atom1, atom2); 72 Walker = FindAtom(atom1); 73 OtherWalker = FindAtom(atom2); 74 AddBond(Walker, OtherWalker); //Add the bond between the two atoms with respective indices. 75 } 76 } 77 ; 67 78 68 79 /** Creates an adjacency list of the molecule. … … 77 88 * -# put each atom into its corresponding cell 78 89 * -# go through every cell, check the atoms therein against all possible bond partners in the 27 adjacent cells, add bond if true 79 * -# create the list of bonds via CreateListOfBondsPerAtom()80 90 * -# correct the bond degree iteratively (single->double->triple bond) 81 91 * -# finally print the bond list to \a *out if desired … … 83 93 * \param bonddistance length of linked cells (i.e. maximum minimal length checked) 84 94 * \param IsAngstroem whether coordinate system is gauged to Angstroem or Bohr radii 85 */ 86 void molecule::CreateAdjacencyList(ofstream *out, double bonddistance, bool IsAngstroem) 87 { 88 89 atom *Walker = NULL, *OtherWalker = NULL, *Candidate = NULL; 90 int No, NoBonds, CandidateBondNo; 91 int NumberCells, divisor[NDIM], n[NDIM], N[NDIM], index, Index, j; 92 molecule **CellList; 93 double distance, MinDistance, MaxDistance; 94 double *matrix = ReturnFullMatrixforSymmetric(cell_size); 95 Vector x; 96 int FalseBondDegree = 0; 95 * \param *minmaxdistance function to give upper and lower bound on whether particle is bonded to some other 96 * \param *BG BondGraph with the member function above or NULL, if just standard covalent should be used. 97 */ 98 void molecule::CreateAdjacencyList(ofstream *out, double bonddistance, bool IsAngstroem, void (BondGraph::*minmaxdistance)(BondedParticle * const , BondedParticle * const , double &, double &, bool), BondGraph *BG) 99 { 100 atom *Walker = NULL; 101 atom *OtherWalker = NULL; 102 atom **AtomMap = NULL; 103 int n[NDIM]; 104 double MinDistance, MaxDistance; 105 LinkedCell *LC = NULL; 106 bool free_BG = false; 107 108 if (BG == NULL) { 109 BG = new BondGraph(IsAngstroem); 110 free_BG = true; 111 } 97 112 98 113 BondDistance = bonddistance; // * ((IsAngstroem) ? 1. : 1./AtomicLengthToAngstroem); 99 114 *out << Verbose(0) << "Begin of CreateAdjacencyList." << endl; 100 115 // remove every bond from the list 101 if ((first->next != last) && (last->previous != first)) { // there are bonds present 102 cleanup(first,last); 103 } 116 bond *Binder = NULL; 117 while (last->previous != first) { 118 Binder = last->previous; 119 Binder->leftatom->UnregisterBond(Binder); 120 Binder->rightatom->UnregisterBond(Binder); 121 removewithoutcheck(Binder); 122 } 123 BondCount = 0; 104 124 105 125 // count atoms in molecule = dimension of matrix (also give each unique name and continuous numbering) 106 126 CountAtoms(out); 107 *out << Verbose(1) << "AtomCount " << AtomCount << "." << endl; 108 109 if (AtomCount != 0) { 110 // 1. find divisor for each axis, such that a sphere with radius of at least bonddistance can be placed into each cell 111 j=-1; 112 for (int i=0;i<NDIM;i++) { 113 j += i+1; 114 divisor[i] = (int)floor(cell_size[j]/bonddistance); // take smaller value such that size of linked cell is at least bonddistance 115 //*out << Verbose(1) << "divisor[" << i << "] = " << divisor[i] << "." << endl; 116 } 117 // 2a. allocate memory for the cell list 118 NumberCells = divisor[0]*divisor[1]*divisor[2]; 119 *out << Verbose(1) << "Allocating " << NumberCells << " cells." << endl; 120 CellList = Malloc<molecule*>(NumberCells, "molecule::CreateAdjacencyList - ** CellList"); 121 for (int i=NumberCells;i--;) 122 CellList[i] = NULL; 123 124 // 2b. put all atoms into its corresponding list 127 *out << Verbose(1) << "AtomCount " << AtomCount << " and bonddistance is " << bonddistance << "." << endl; 128 129 if ((AtomCount > 1) && (bonddistance > 1.)) { 130 *out << Verbose(2) << "Creating Linked Cell structure ... " << endl; 131 LC = new LinkedCell(this, bonddistance); 132 133 // create a list to map Tesselpoint::nr to atom * 134 *out << Verbose(2) << "Creating TesselPoint to atom map ... " << endl; 135 AtomMap = Calloc<atom *> (AtomCount, "molecule::CreateAdjacencyList - **AtomCount"); 125 136 Walker = start; 126 while (Walker->next != end) {137 while (Walker->next != end) { 127 138 Walker = Walker->next; 128 //*out << Verbose(1) << "Current atom is " << *Walker << " with coordinates "; 129 //Walker->x.Output(out); 130 //*out << "." << endl; 131 // compute the cell by the atom's coordinates 132 j=-1; 133 for (int i=0;i<NDIM;i++) { 134 j += i+1; 135 x.CopyVector(&(Walker->x)); 136 x.KeepPeriodic(out, matrix); 137 n[i] = (int)floor(x.x[i]/cell_size[j]*(double)divisor[i]); 138 } 139 index = n[2] + (n[1] + n[0] * divisor[1]) * divisor[2]; 140 //*out << Verbose(1) << "Atom " << *Walker << " goes into cell number [" << n[0] << "," << n[1] << "," << n[2] << "] = " << index << "." << endl; 141 // add copy atom to this cell 142 if (CellList[index] == NULL) // allocate molecule if not done 143 CellList[index] = new molecule(elemente); 144 OtherWalker = CellList[index]->AddCopyAtom(Walker); // add a copy of walker to this atom, father will be walker for later reference 145 //*out << Verbose(1) << "Copy Atom is " << *OtherWalker << "." << endl; 146 } 147 //for (int i=0;i<NumberCells;i++) 148 //*out << Verbose(1) << "Cell number " << i << ": " << CellList[i] << "." << endl; 149 139 AtomMap[Walker->nr] = Walker; 140 } 150 141 151 142 // 3a. go through every cell 152 for (N[0]=divisor[0];N[0]--;) 153 for (N[1]=divisor[1];N[1]--;) 154 for (N[2]=divisor[2];N[2]--;) { 155 Index = N[2] + (N[1] + N[0] * divisor[1]) * divisor[2]; 156 if (CellList[Index] != NULL) { // if there atoms in this cell 157 //*out << Verbose(1) << "Current cell is " << Index << "." << endl; 158 // 3b. for every atom therein 159 Walker = CellList[Index]->start; 160 while (Walker->next != CellList[Index]->end) { // go through every atom 161 Walker = Walker->next; 143 *out << Verbose(2) << "Celling ... " << endl; 144 for (LC->n[0] = 0; LC->n[0] < LC->N[0]; LC->n[0]++) 145 for (LC->n[1] = 0; LC->n[1] < LC->N[1]; LC->n[1]++) 146 for (LC->n[2] = 0; LC->n[2] < LC->N[2]; LC->n[2]++) { 147 const LinkedNodes *List = LC->GetCurrentCell(); 148 //*out << Verbose(2) << "Current cell is " << LC->n[0] << ", " << LC->n[1] << ", " << LC->n[2] << " with No. " << LC->index << " containing " << List->size() << " points." << endl; 149 if (List != NULL) { 150 for (LinkedNodes::const_iterator Runner = List->begin(); Runner != List->end(); Runner++) { 151 Walker = AtomMap[(*Runner)->nr]; 162 152 //*out << Verbose(0) << "Current Atom is " << *Walker << "." << endl; 163 153 // 3c. check for possible bond between each atom in this and every one in the 27 cells 164 for (n[0]=-1;n[0]<=1;n[0]++) 165 for (n[1]=-1;n[1]<=1;n[1]++) 166 for (n[2]=-1;n[2]<=1;n[2]++) { 167 // compute the index of this comparison cell and make it periodic 168 index = ((N[2]+n[2]+divisor[2])%divisor[2]) + (((N[1]+n[1]+divisor[1])%divisor[1]) + ((N[0]+n[0]+divisor[0])%divisor[0]) * divisor[1]) * divisor[2]; 169 //*out << Verbose(1) << "Number of comparison cell is " << index << "." << endl; 170 if (CellList[index] != NULL) { // if there are any atoms in this cell 171 OtherWalker = CellList[index]->start; 172 while(OtherWalker->next != CellList[index]->end) { // go through every atom in this cell 173 OtherWalker = OtherWalker->next; 174 //*out << Verbose(0) << "Current comparison atom is " << *OtherWalker << "." << endl; 175 /// \todo periodic check is missing here! 176 //*out << Verbose(1) << "Checking distance " << OtherWalker->x.PeriodicDistanceSquared(&(Walker->x), cell_size) << " against typical bond length of " << bonddistance*bonddistance << "." << endl; 177 MinDistance = OtherWalker->type->CovalentRadius + Walker->type->CovalentRadius; 178 MinDistance *= (IsAngstroem) ? 1. : 1./AtomicLengthToAngstroem; 179 MaxDistance = MinDistance + BONDTHRESHOLD; 180 MinDistance -= BONDTHRESHOLD; 181 distance = OtherWalker->x.PeriodicDistanceSquared(&(Walker->x), cell_size); 182 if ((OtherWalker->father->nr > Walker->father->nr) && (distance <= MaxDistance*MaxDistance) && (distance >= MinDistance*MinDistance)) { // create bond if distance is smaller 183 //*out << Verbose(1) << "Adding Bond between " << *Walker << " and " << *OtherWalker << " in distance " << sqrt(distance) << "." << endl; 184 AddBond(Walker->father, OtherWalker->father, 1); // also increases molecule::BondCount 185 } else { 186 //*out << Verbose(1) << "Not Adding: Wrong label order or distance too great." << endl; 154 for (n[0] = -1; n[0] <= 1; n[0]++) 155 for (n[1] = -1; n[1] <= 1; n[1]++) 156 for (n[2] = -1; n[2] <= 1; n[2]++) { 157 const LinkedNodes *OtherList = LC->GetRelativeToCurrentCell(n); 158 //*out << Verbose(2) << "Current relative cell is " << LC->n[0] << ", " << LC->n[1] << ", " << LC->n[2] << " with No. " << LC->index << " containing " << List->size() << " points." << endl; 159 if (OtherList != NULL) { 160 for (LinkedNodes::const_iterator OtherRunner = OtherList->begin(); OtherRunner != OtherList->end(); OtherRunner++) { 161 if ((*OtherRunner)->nr > Walker->nr) { 162 OtherWalker = AtomMap[(*OtherRunner)->nr]; 163 //*out << Verbose(1) << "Checking distance " << OtherWalker->x.PeriodicDistanceSquared(&(Walker->x), cell_size) << " against typical bond length of " << bonddistance*bonddistance << "." << endl; 164 (BG->*minmaxdistance)(Walker, OtherWalker, MinDistance, MaxDistance, IsAngstroem); 165 const double distance = OtherWalker->x.PeriodicDistanceSquared(&(Walker->x), cell_size); 166 const bool status = (distance <= MaxDistance * MaxDistance) && (distance >= MinDistance * MinDistance); 167 if ((OtherWalker->father->nr > Walker->father->nr) && (status)) { // create bond if distance is smaller 168 //*out << Verbose(1) << "Adding Bond between " << *Walker << " and " << *OtherWalker << " in distance " << sqrt(distance) << "." << endl; 169 AddBond(Walker->father, OtherWalker->father, 1); // also increases molecule::BondCount 170 } else { 171 //*out << Verbose(1) << "Not Adding: Wrong label order or distance too great." << endl; 172 } 187 173 } 188 174 } … … 192 178 } 193 179 } 194 195 196 197 // 4. free the cell again 198 for (int i=NumberCells;i--;) 199 if (CellList[i] != NULL) { 200 delete(CellList[i]); 201 } 202 Free(&CellList); 203 204 // create the adjacency list per atom 205 CreateListOfBondsPerAtom(out); 206 207 // correct Bond degree of each bond by checking both bond partners for a mismatch between valence and current sum of bond degrees, 208 // iteratively increase the one first where the other bond partner has the fewest number of bonds (i.e. in general bonds oxygene 209 // preferred over carbon bonds). Beforehand, we had picked the first mismatching partner, which lead to oxygenes with single instead of 210 // double bonds as was expected. 211 if (BondCount != 0) { 212 NoCyclicBonds = 0; 213 *out << Verbose(1) << "Correcting Bond degree of each bond ... "; 214 do { 215 No = 0; // No acts as breakup flag (if 1 we still continue) 216 Walker = start; 217 while (Walker->next != end) { // go through every atom 218 Walker = Walker->next; 219 // count valence of first partner 220 NoBonds = 0; 221 for(j=0;j<NumberOfBondsPerAtom[Walker->nr];j++) 222 NoBonds += ListOfBondsPerAtom[Walker->nr][j]->BondDegree; 223 *out << Verbose(3) << "Walker " << *Walker << ": " << (int)Walker->type->NoValenceOrbitals << " > " << NoBonds << "?" << endl; 224 if ((int)(Walker->type->NoValenceOrbitals) > NoBonds) { // we have a mismatch, check all bonding partners for mismatch 225 Candidate = NULL; 226 CandidateBondNo = -1; 227 for(int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++) { // go through each of its bond partners 228 OtherWalker = ListOfBondsPerAtom[Walker->nr][i]->GetOtherAtom(Walker); 229 // count valence of second partner 230 NoBonds = 0; 231 for(j=0;j<NumberOfBondsPerAtom[OtherWalker->nr];j++) 232 NoBonds += ListOfBondsPerAtom[OtherWalker->nr][j]->BondDegree; 233 *out << Verbose(3) << "OtherWalker " << *OtherWalker << ": " << (int)OtherWalker->type->NoValenceOrbitals << " > " << NoBonds << "?" << endl; 234 if ((int)(OtherWalker->type->NoValenceOrbitals) > NoBonds) { // check if possible candidate 235 if ((Candidate == NULL) || (NumberOfBondsPerAtom[Candidate->nr] > NumberOfBondsPerAtom[OtherWalker->nr])) { // pick the one with fewer number of bonds first 236 Candidate = OtherWalker; 237 CandidateBondNo = i; 238 *out << Verbose(3) << "New candidate is " << *Candidate << "." << endl; 239 } 240 } 241 } 242 if ((Candidate != NULL) && (CandidateBondNo != -1)) { 243 ListOfBondsPerAtom[Walker->nr][CandidateBondNo]->BondDegree++; 244 *out << Verbose(2) << "Increased bond degree for bond " << *ListOfBondsPerAtom[Walker->nr][CandidateBondNo] << "." << endl; 245 } else 246 *out << Verbose(2) << "Could not find correct degree for atom " << *Walker << "." << endl; 247 FalseBondDegree++; 248 } 249 } 250 } while (No); 251 *out << " done." << endl; 252 } else 253 *out << Verbose(1) << "BondCount is " << BondCount << ", no bonds between any of the " << AtomCount << " atoms." << endl; 254 *out << Verbose(1) << "I detected " << BondCount << " bonds in the molecule with distance " << bonddistance << ", " << FalseBondDegree << " bonds could not be corrected." << endl; 180 Free(&AtomMap); 181 delete (LC); 182 *out << Verbose(1) << "I detected " << BondCount << " bonds in the molecule with distance " << BondDistance << "." << endl; 183 184 // correct bond degree by comparing valence and bond degree 185 *out << Verbose(2) << "Correcting bond degree ... " << endl; 186 CorrectBondDegree(out); 255 187 256 188 // output bonds for debugging (if bond chain list was correctly installed) 257 *out << Verbose(1) << endl << "From contents of bond chain list:"; 258 bond *Binder = first; 259 while(Binder->next != last) { 260 Binder = Binder->next; 261 *out << *Binder << "\t" << endl; 262 } 263 *out << endl; 189 ActOnAllAtoms(&atom::OutputBondOfAtom, out); 264 190 } else 265 191 *out << Verbose(1) << "AtomCount is " << AtomCount << ", thus no bonds, no connections!." << endl; 266 192 *out << Verbose(0) << "End of CreateAdjacencyList." << endl; 267 Free(&matrix); 268 269 }; 193 if (free_BG) 194 delete(BG); 195 } 196 ; 197 198 /** Prints a list of all bonds to \a *out. 199 * \param output stream 200 */ 201 void molecule::OutputBondsList(ofstream *out) const 202 { 203 *out << Verbose(1) << endl << "From contents of bond chain list:"; 204 bond *Binder = first; 205 while (Binder->next != last) { 206 Binder = Binder->next; 207 *out << *Binder << "\t" << endl; 208 } 209 *out << endl; 210 } 211 ; 212 213 /** correct bond degree by comparing valence and bond degree. 214 * correct Bond degree of each bond by checking both bond partners for a mismatch between valence and current sum of bond degrees, 215 * iteratively increase the one first where the other bond partner has the fewest number of bonds (i.e. in general bonds oxygene 216 * preferred over carbon bonds). Beforehand, we had picked the first mismatching partner, which lead to oxygenes with single instead of 217 * double bonds as was expected. 218 * \param *out output stream for debugging 219 * \return number of bonds that could not be corrected 220 */ 221 int molecule::CorrectBondDegree(ofstream *out) const 222 { 223 int No = 0, OldNo = -1; 224 225 if (BondCount != 0) { 226 *out << Verbose(1) << "Correcting Bond degree of each bond ... " << endl; 227 do { 228 OldNo = No; 229 No = SumPerAtom(&atom::CorrectBondDegree, out); 230 } while (OldNo != No); 231 *out << " done." << endl; 232 } else { 233 *out << Verbose(1) << "BondCount is " << BondCount << ", no bonds between any of the " << AtomCount << " atoms." << endl; 234 } 235 *out << No << " bonds could not be corrected." << endl; 236 237 return (No); 238 } 239 ; 270 240 271 241 /** Counts all cyclic bonds and returns their number. … … 276 246 int molecule::CountCyclicBonds(ofstream *out) 277 247 { 278 int No= 0;248 NoCyclicBonds = 0; 279 249 int *MinimumRingSize = NULL; 280 250 MoleculeLeafClass *Subgraphs = NULL; … … 286 256 while (Subgraphs->next != NULL) { 287 257 Subgraphs = Subgraphs->next; 288 delete (Subgraphs->previous);289 } 290 delete (Subgraphs);291 delete[] (MinimumRingSize);292 } 293 while (Binder->next != last) {258 delete (Subgraphs->previous); 259 } 260 delete (Subgraphs); 261 delete[] (MinimumRingSize); 262 } 263 while (Binder->next != last) { 294 264 Binder = Binder->next; 295 265 if (Binder->Cyclic) 296 No++; 297 } 298 delete(BackEdgeStack); 299 return No; 300 }; 266 NoCyclicBonds++; 267 } 268 delete (BackEdgeStack); 269 return NoCyclicBonds; 270 } 271 ; 272 301 273 /** Returns Shading as a char string. 302 274 * \param color the Shading 303 275 * \return string of the flag 304 276 */ 305 string molecule::GetColor(enum Shading color) 306 { 307 switch (color) {277 string molecule::GetColor(enum Shading color) const 278 { 279 switch (color) { 308 280 case white: 309 281 return "white"; … … 322 294 break; 323 295 }; 324 }; 296 } 297 ; 298 299 /** Sets atom::GraphNr and atom::LowpointNr to BFSAccounting::CurrentGraphNr. 300 * \param *out output stream for debugging 301 * \param *Walker current node 302 * \param &BFS structure with accounting data for BFS 303 */ 304 void DepthFirstSearchAnalysis_SetWalkersGraphNr(ofstream *out, atom *&Walker, struct DFSAccounting &DFS) 305 { 306 if (!DFS.BackStepping) { // if we don't just return from (8) 307 Walker->GraphNr = DFS.CurrentGraphNr; 308 Walker->LowpointNr = DFS.CurrentGraphNr; 309 *out << Verbose(1) << "Setting Walker[" << Walker->Name << "]'s number to " << Walker->GraphNr << " with Lowpoint " << Walker->LowpointNr << "." << endl; 310 DFS.AtomStack->Push(Walker); 311 DFS.CurrentGraphNr++; 312 } 313 } 314 ; 315 316 /** During DFS goes along unvisited bond and touches other atom. 317 * Sets bond::type, if 318 * -# BackEdge: set atom::LowpointNr and push on \a BackEdgeStack 319 * -# TreeEgde: set atom::Ancestor and continue with Walker along this edge 320 * Continue until molecule::FindNextUnused() finds no more unused bonds. 321 * \param *out output stream for debugging 322 * \param *mol molecule with atoms and finding unused bonds 323 * \param *&Binder current edge 324 * \param &DFS DFS accounting data 325 */ 326 void DepthFirstSearchAnalysis_ProbeAlongUnusedBond(ofstream *out, const molecule * const mol, atom *&Walker, bond *&Binder, struct DFSAccounting &DFS) 327 { 328 atom *OtherAtom = NULL; 329 330 do { // (3) if Walker has no unused egdes, go to (5) 331 DFS.BackStepping = false; // reset backstepping flag for (8) 332 if (Binder == NULL) // if we don't just return from (11), Binder is already set to next unused 333 Binder = mol->FindNextUnused(Walker); 334 if (Binder == NULL) 335 break; 336 *out << Verbose(2) << "Current Unused Bond is " << *Binder << "." << endl; 337 // (4) Mark Binder used, ... 338 Binder->MarkUsed(black); 339 OtherAtom = Binder->GetOtherAtom(Walker); 340 *out << Verbose(2) << "(4) OtherAtom is " << OtherAtom->Name << "." << endl; 341 if (OtherAtom->GraphNr != -1) { 342 // (4a) ... if "other" atom has been visited (GraphNr != 0), set lowpoint to minimum of both, go to (3) 343 Binder->Type = BackEdge; 344 DFS.BackEdgeStack->Push(Binder); 345 Walker->LowpointNr = (Walker->LowpointNr < OtherAtom->GraphNr) ? Walker->LowpointNr : OtherAtom->GraphNr; 346 *out << Verbose(3) << "(4a) Visited: Setting Lowpoint of Walker[" << Walker->Name << "] to " << Walker->LowpointNr << "." << endl; 347 } else { 348 // (4b) ... otherwise set OtherAtom as Ancestor of Walker and Walker as OtherAtom, go to (2) 349 Binder->Type = TreeEdge; 350 OtherAtom->Ancestor = Walker; 351 Walker = OtherAtom; 352 *out << Verbose(3) << "(4b) Not Visited: OtherAtom[" << OtherAtom->Name << "]'s Ancestor is now " << OtherAtom->Ancestor->Name << ", Walker is OtherAtom " << OtherAtom->Name << "." << endl; 353 break; 354 } 355 Binder = NULL; 356 } while (1); // (3) 357 } 358 ; 359 360 /** Checks whether we have a new component. 361 * if atom::LowpointNr of \a *&Walker is greater than atom::GraphNr of its atom::Ancestor, we have a new component. 362 * Meaning that if we touch upon a node who suddenly has a smaller atom::LowpointNr than its ancestor, then we 363 * have a found a new branch in the graph tree. 364 * \param *out output stream for debugging 365 * \param *mol molecule with atoms and finding unused bonds 366 * \param *&Walker current node 367 * \param &DFS DFS accounting data 368 */ 369 void DepthFirstSearchAnalysis_CheckForaNewComponent(ofstream *out, const molecule * const mol, atom *&Walker, struct DFSAccounting &DFS, MoleculeLeafClass *&LeafWalker) 370 { 371 atom *OtherAtom = NULL; 372 373 // (5) if Ancestor of Walker is ... 374 *out << Verbose(1) << "(5) Number of Walker[" << Walker->Name << "]'s Ancestor[" << Walker->Ancestor->Name << "] is " << Walker->Ancestor->GraphNr << "." << endl; 375 376 if (Walker->Ancestor->GraphNr != DFS.Root->GraphNr) { 377 // (6) (Ancestor of Walker is not Root) 378 if (Walker->LowpointNr < Walker->Ancestor->GraphNr) { 379 // (6a) set Ancestor's Lowpoint number to minimum of of its Ancestor and itself, go to Step(8) 380 Walker->Ancestor->LowpointNr = (Walker->Ancestor->LowpointNr < Walker->LowpointNr) ? Walker->Ancestor->LowpointNr : Walker->LowpointNr; 381 *out << Verbose(2) << "(6) Setting Walker[" << Walker->Name << "]'s Ancestor[" << Walker->Ancestor->Name << "]'s Lowpoint to " << Walker->Ancestor->LowpointNr << "." << endl; 382 } else { 383 // (7) (Ancestor of Walker is a separating vertex, remove all from stack till Walker (including), these and Ancestor form a component 384 Walker->Ancestor->SeparationVertex = true; 385 *out << Verbose(2) << "(7) Walker[" << Walker->Name << "]'s Ancestor[" << Walker->Ancestor->Name << "]'s is a separating vertex, creating component." << endl; 386 mol->SetNextComponentNumber(Walker->Ancestor, DFS.ComponentNumber); 387 *out << Verbose(3) << "(7) Walker[" << Walker->Name << "]'s Ancestor's Compont is " << DFS.ComponentNumber << "." << endl; 388 mol->SetNextComponentNumber(Walker, DFS.ComponentNumber); 389 *out << Verbose(3) << "(7) Walker[" << Walker->Name << "]'s Compont is " << DFS.ComponentNumber << "." << endl; 390 do { 391 OtherAtom = DFS.AtomStack->PopLast(); 392 LeafWalker->Leaf->AddCopyAtom(OtherAtom); 393 mol->SetNextComponentNumber(OtherAtom, DFS.ComponentNumber); 394 *out << Verbose(3) << "(7) Other[" << OtherAtom->Name << "]'s Compont is " << DFS.ComponentNumber << "." << endl; 395 } while (OtherAtom != Walker); 396 DFS.ComponentNumber++; 397 } 398 // (8) Walker becomes its Ancestor, go to (3) 399 *out << Verbose(2) << "(8) Walker[" << Walker->Name << "] is now its Ancestor " << Walker->Ancestor->Name << ", backstepping. " << endl; 400 Walker = Walker->Ancestor; 401 DFS.BackStepping = true; 402 } 403 } 404 ; 405 406 /** Cleans the root stack when we have found a component. 407 * If we are not DFSAccounting::BackStepping, then we clear the root stack by putting everything into a 408 * component down till we meet DFSAccounting::Root. 409 * \param *out output stream for debugging 410 * \param *mol molecule with atoms and finding unused bonds 411 * \param *&Walker current node 412 * \param *&Binder current edge 413 * \param &DFS DFS accounting data 414 */ 415 void DepthFirstSearchAnalysis_CleanRootStackDownTillWalker(ofstream *out, const molecule * const mol, atom *&Walker, bond *&Binder, struct DFSAccounting &DFS, MoleculeLeafClass *&LeafWalker) 416 { 417 atom *OtherAtom = NULL; 418 419 if (!DFS.BackStepping) { // coming from (8) want to go to (3) 420 // (9) remove all from stack till Walker (including), these and Root form a component 421 //DFS.AtomStack->Output(out); 422 mol->SetNextComponentNumber(DFS.Root, DFS.ComponentNumber); 423 *out << Verbose(3) << "(9) Root[" << DFS.Root->Name << "]'s Component is " << DFS.ComponentNumber << "." << endl; 424 mol->SetNextComponentNumber(Walker, DFS.ComponentNumber); 425 *out << Verbose(3) << "(9) Walker[" << Walker->Name << "]'s Component is " << DFS.ComponentNumber << "." << endl; 426 do { 427 OtherAtom = DFS.AtomStack->PopLast(); 428 LeafWalker->Leaf->AddCopyAtom(OtherAtom); 429 mol->SetNextComponentNumber(OtherAtom, DFS.ComponentNumber); 430 *out << Verbose(3) << "(7) Other[" << OtherAtom->Name << "]'s Compont is " << DFS.ComponentNumber << "." << endl; 431 } while (OtherAtom != Walker); 432 DFS.ComponentNumber++; 433 434 // (11) Root is separation vertex, set Walker to Root and go to (4) 435 Walker = DFS.Root; 436 Binder = mol->FindNextUnused(Walker); 437 *out << Verbose(1) << "(10) Walker is Root[" << DFS.Root->Name << "], next Unused Bond is " << Binder << "." << endl; 438 if (Binder != NULL) { // Root is separation vertex 439 *out << Verbose(1) << "(11) Root is a separation vertex." << endl; 440 Walker->SeparationVertex = true; 441 } 442 } 443 } 444 ; 445 446 /** Initializes DFSAccounting structure. 447 * \param *out output stream for debugging 448 * \param &DFS accounting structure to allocate 449 * \param *mol molecule with AtomCount, BondCount and all atoms 450 */ 451 void DepthFirstSearchAnalysis_Init(ofstream *out, struct DFSAccounting &DFS, const molecule * const mol) 452 { 453 DFS.AtomStack = new StackClass<atom *> (mol->AtomCount); 454 DFS.CurrentGraphNr = 0; 455 DFS.ComponentNumber = 0; 456 DFS.BackStepping = false; 457 mol->ResetAllBondsToUnused(); 458 mol->SetAtomValueToValue(-1, &atom::GraphNr); 459 mol->ActOnAllAtoms(&atom::InitComponentNr); 460 DFS.BackEdgeStack->ClearStack(); 461 } 462 ; 463 464 /** Free's DFSAccounting structure. 465 * \param *out output stream for debugging 466 * \param &DFS accounting structure to free 467 */ 468 void DepthFirstSearchAnalysis_Finalize(ofstream *out, struct DFSAccounting &DFS) 469 { 470 delete (DFS.AtomStack); 471 // delete (DFS.BackEdgeStack); // DON'T free, see DepthFirstSearchAnalysis(), is returned as allocated 472 } 473 ; 325 474 326 475 /** Performs a Depth-First search on this molecule. … … 332 481 * \return list of each disconnected subgraph as an individual molecule class structure 333 482 */ 334 MoleculeLeafClass * molecule::DepthFirstSearchAnalysis(ofstream *out, class StackClass<bond *> *&BackEdgeStack) 335 { 336 class StackClass<atom *> *AtomStack = new StackClass<atom *>(AtomCount);483 MoleculeLeafClass * molecule::DepthFirstSearchAnalysis(ofstream *out, class StackClass<bond *> *&BackEdgeStack) const 484 { 485 struct DFSAccounting DFS; 337 486 BackEdgeStack = new StackClass<bond *> (BondCount); 487 DFS.BackEdgeStack = BackEdgeStack; 338 488 MoleculeLeafClass *SubGraphs = new MoleculeLeafClass(NULL); 339 489 MoleculeLeafClass *LeafWalker = SubGraphs; 340 int CurrentGraphNr = 0, OldGraphNr; 341 int ComponentNumber = 0; 342 atom *Walker = NULL, *OtherAtom = NULL, *Root = start->next; 490 int OldGraphNr = 0; 491 atom *Walker = NULL; 343 492 bond *Binder = NULL; 344 bool BackStepping = false;345 493 346 494 *out << Verbose(0) << "Begin of DepthFirstSearchAnalysis" << endl; 347 348 ResetAllBondsToUnused(); 349 ResetAllAtomNumbers(); 350 InitComponentNumbers(); 351 BackEdgeStack->ClearStack(); 352 while (Root != end) { // if there any atoms at all 353 // (1) mark all edges unused, empty stack, set atom->GraphNr = 0 for all 354 AtomStack->ClearStack(); 495 DepthFirstSearchAnalysis_Init(out, DFS, this); 496 497 DFS.Root = start->next; 498 while (DFS.Root != end) { // if there any atoms at all 499 // (1) mark all edges unused, empty stack, set atom->GraphNr = -1 for all 500 DFS.AtomStack->ClearStack(); 355 501 356 502 // put into new subgraph molecule and add this to list of subgraphs 357 503 LeafWalker = new MoleculeLeafClass(LeafWalker); 358 504 LeafWalker->Leaf = new molecule(elemente); 359 LeafWalker->Leaf->AddCopyAtom( Root);360 361 OldGraphNr = CurrentGraphNr;362 Walker = Root;505 LeafWalker->Leaf->AddCopyAtom(DFS.Root); 506 507 OldGraphNr = DFS.CurrentGraphNr; 508 Walker = DFS.Root; 363 509 do { // (10) 364 510 do { // (2) set number and Lowpoint of Atom to i, increase i, push current atom 365 if (!BackStepping) { // if we don't just return from (8) 366 Walker->GraphNr = CurrentGraphNr; 367 Walker->LowpointNr = CurrentGraphNr; 368 *out << Verbose(1) << "Setting Walker[" << Walker->Name << "]'s number to " << Walker->GraphNr << " with Lowpoint " << Walker->LowpointNr << "." << endl; 369 AtomStack->Push(Walker); 370 CurrentGraphNr++; 371 } 372 do { // (3) if Walker has no unused egdes, go to (5) 373 BackStepping = false; // reset backstepping flag for (8) 374 if (Binder == NULL) // if we don't just return from (11), Binder is already set to next unused 375 Binder = FindNextUnused(Walker); 376 if (Binder == NULL) 377 break; 378 *out << Verbose(2) << "Current Unused Bond is " << *Binder << "." << endl; 379 // (4) Mark Binder used, ... 380 Binder->MarkUsed(black); 381 OtherAtom = Binder->GetOtherAtom(Walker); 382 *out << Verbose(2) << "(4) OtherAtom is " << OtherAtom->Name << "." << endl; 383 if (OtherAtom->GraphNr != -1) { 384 // (4a) ... if "other" atom has been visited (GraphNr != 0), set lowpoint to minimum of both, go to (3) 385 Binder->Type = BackEdge; 386 BackEdgeStack->Push(Binder); 387 Walker->LowpointNr = ( Walker->LowpointNr < OtherAtom->GraphNr ) ? Walker->LowpointNr : OtherAtom->GraphNr; 388 *out << Verbose(3) << "(4a) Visited: Setting Lowpoint of Walker[" << Walker->Name << "] to " << Walker->LowpointNr << "." << endl; 389 } else { 390 // (4b) ... otherwise set OtherAtom as Ancestor of Walker and Walker as OtherAtom, go to (2) 391 Binder->Type = TreeEdge; 392 OtherAtom->Ancestor = Walker; 393 Walker = OtherAtom; 394 *out << Verbose(3) << "(4b) Not Visited: OtherAtom[" << OtherAtom->Name << "]'s Ancestor is now " << OtherAtom->Ancestor->Name << ", Walker is OtherAtom " << OtherAtom->Name << "." << endl; 395 break; 396 } 397 Binder = NULL; 398 } while (1); // (3) 511 DepthFirstSearchAnalysis_SetWalkersGraphNr(out, Walker, DFS); 512 513 DepthFirstSearchAnalysis_ProbeAlongUnusedBond(out, this, Walker, Binder, DFS); 514 399 515 if (Binder == NULL) { 400 516 *out << Verbose(2) << "No more Unused Bonds." << endl; … … 402 518 } else 403 519 Binder = NULL; 404 } while (1); 520 } while (1); // (2) 405 521 406 522 // if we came from backstepping, yet there were no more unused bonds, we end up here with no Ancestor, because Walker is Root! Then we are finished! 407 if ((Walker == Root) && (Binder == NULL))523 if ((Walker == DFS.Root) && (Binder == NULL)) 408 524 break; 409 525 410 // (5) if Ancestor of Walker is ... 411 *out << Verbose(1) << "(5) Number of Walker[" << Walker->Name << "]'s Ancestor[" << Walker->Ancestor->Name << "] is " << Walker->Ancestor->GraphNr << "." << endl; 412 if (Walker->Ancestor->GraphNr != Root->GraphNr) { 413 // (6) (Ancestor of Walker is not Root) 414 if (Walker->LowpointNr < Walker->Ancestor->GraphNr) { 415 // (6a) set Ancestor's Lowpoint number to minimum of of its Ancestor and itself, go to Step(8) 416 Walker->Ancestor->LowpointNr = (Walker->Ancestor->LowpointNr < Walker->LowpointNr) ? Walker->Ancestor->LowpointNr : Walker->LowpointNr; 417 *out << Verbose(2) << "(6) Setting Walker[" << Walker->Name << "]'s Ancestor[" << Walker->Ancestor->Name << "]'s Lowpoint to " << Walker->Ancestor->LowpointNr << "." << endl; 418 } else { 419 // (7) (Ancestor of Walker is a separating vertex, remove all from stack till Walker (including), these and Ancestor form a component 420 Walker->Ancestor->SeparationVertex = true; 421 *out << Verbose(2) << "(7) Walker[" << Walker->Name << "]'s Ancestor[" << Walker->Ancestor->Name << "]'s is a separating vertex, creating component." << endl; 422 SetNextComponentNumber(Walker->Ancestor, ComponentNumber); 423 *out << Verbose(3) << "(7) Walker[" << Walker->Name << "]'s Ancestor's Compont is " << ComponentNumber << "." << endl; 424 SetNextComponentNumber(Walker, ComponentNumber); 425 *out << Verbose(3) << "(7) Walker[" << Walker->Name << "]'s Compont is " << ComponentNumber << "." << endl; 426 do { 427 OtherAtom = AtomStack->PopLast(); 428 LeafWalker->Leaf->AddCopyAtom(OtherAtom); 429 SetNextComponentNumber(OtherAtom, ComponentNumber); 430 *out << Verbose(3) << "(7) Other[" << OtherAtom->Name << "]'s Compont is " << ComponentNumber << "." << endl; 431 } while (OtherAtom != Walker); 432 ComponentNumber++; 433 } 434 // (8) Walker becomes its Ancestor, go to (3) 435 *out << Verbose(2) << "(8) Walker[" << Walker->Name << "] is now its Ancestor " << Walker->Ancestor->Name << ", backstepping. " << endl; 436 Walker = Walker->Ancestor; 437 BackStepping = true; 438 } 439 if (!BackStepping) { // coming from (8) want to go to (3) 440 // (9) remove all from stack till Walker (including), these and Root form a component 441 AtomStack->Output(out); 442 SetNextComponentNumber(Root, ComponentNumber); 443 *out << Verbose(3) << "(9) Root[" << Root->Name << "]'s Component is " << ComponentNumber << "." << endl; 444 SetNextComponentNumber(Walker, ComponentNumber); 445 *out << Verbose(3) << "(9) Walker[" << Walker->Name << "]'s Component is " << ComponentNumber << "." << endl; 446 do { 447 OtherAtom = AtomStack->PopLast(); 448 LeafWalker->Leaf->AddCopyAtom(OtherAtom); 449 SetNextComponentNumber(OtherAtom, ComponentNumber); 450 *out << Verbose(3) << "(7) Other[" << OtherAtom->Name << "]'s Compont is " << ComponentNumber << "." << endl; 451 } while (OtherAtom != Walker); 452 ComponentNumber++; 453 454 // (11) Root is separation vertex, set Walker to Root and go to (4) 455 Walker = Root; 456 Binder = FindNextUnused(Walker); 457 *out << Verbose(1) << "(10) Walker is Root[" << Root->Name << "], next Unused Bond is " << Binder << "." << endl; 458 if (Binder != NULL) { // Root is separation vertex 459 *out << Verbose(1) << "(11) Root is a separation vertex." << endl; 460 Walker->SeparationVertex = true; 461 } 462 } 463 } while ((BackStepping) || (Binder != NULL)); // (10) halt only if Root has no unused edges 526 DepthFirstSearchAnalysis_CheckForaNewComponent(out, this, Walker, DFS, LeafWalker); 527 528 DepthFirstSearchAnalysis_CleanRootStackDownTillWalker(out, this, Walker, Binder, DFS, LeafWalker); 529 530 } while ((DFS.BackStepping) || (Binder != NULL)); // (10) halt only if Root has no unused edges 464 531 465 532 // From OldGraphNr to CurrentGraphNr ranges an disconnected subgraph 466 *out << Verbose(0) << "Disconnected subgraph ranges from " << OldGraphNr << " to " << CurrentGraphNr << "." << endl;533 *out << Verbose(0) << "Disconnected subgraph ranges from " << OldGraphNr << " to " << DFS.CurrentGraphNr << "." << endl; 467 534 LeafWalker->Leaf->Output(out); 468 535 *out << endl; 469 536 470 537 // step on to next root 471 while (( Root != end) && (Root->GraphNr != -1)) {538 while ((DFS.Root != end) && (DFS.Root->GraphNr != -1)) { 472 539 //*out << Verbose(1) << "Current next subgraph root candidate is " << Root->Name << "." << endl; 473 if ( Root->GraphNr != -1) // if already discovered, step on474 Root =Root->next;540 if (DFS.Root->GraphNr != -1) // if already discovered, step on 541 DFS.Root = DFS.Root->next; 475 542 } 476 543 } 477 544 // set cyclic bond criterium on "same LP" basis 478 Binder = first; 479 while(Binder->next != last) { 545 CyclicBondAnalysis(); 546 547 OutputGraphInfoPerAtom(out); 548 549 OutputGraphInfoPerBond(out); 550 551 // free all and exit 552 DepthFirstSearchAnalysis_Finalize(out, DFS); 553 *out << Verbose(0) << "End of DepthFirstSearchAnalysis" << endl; 554 return SubGraphs; 555 } 556 ; 557 558 /** Scans through all bonds and set bond::Cyclic to true where atom::LowpointNr of both ends is equal: LP criterion. 559 */ 560 void molecule::CyclicBondAnalysis() const 561 { 562 NoCyclicBonds = 0; 563 bond *Binder = first; 564 while (Binder->next != last) { 480 565 Binder = Binder->next; 481 566 if (Binder->rightatom->LowpointNr == Binder->leftatom->LowpointNr) { // cyclic ?? … … 484 569 } 485 570 } 486 487 571 } 572 ; 573 574 /** Output graph information per atom. 575 * \param *out output stream 576 */ 577 void molecule::OutputGraphInfoPerAtom(ofstream *out) const 578 { 488 579 *out << Verbose(1) << "Final graph info for each atom is:" << endl; 489 Walker = start; 490 while (Walker->next != end) { 491 Walker = Walker->next; 492 *out << Verbose(2) << "Atom " << Walker->Name << " is " << ((Walker->SeparationVertex) ? "a" : "not a") << " separation vertex, components are "; 493 OutputComponentNumber(out, Walker); 494 *out << " with Lowpoint " << Walker->LowpointNr << " and Graph Nr. " << Walker->GraphNr << "." << endl; 495 } 496 580 ActOnAllAtoms(&atom::OutputGraphInfo, out); 581 } 582 ; 583 584 /** Output graph information per bond. 585 * \param *out output stream 586 */ 587 void molecule::OutputGraphInfoPerBond(ofstream *out) const 588 { 497 589 *out << Verbose(1) << "Final graph info for each bond is:" << endl; 498 Binder = first;499 while (Binder->next != last) {590 bond *Binder = first; 591 while (Binder->next != last) { 500 592 Binder = Binder->next; 501 593 *out << Verbose(2) << ((Binder->Type == TreeEdge) ? "TreeEdge " : "BackEdge ") << *Binder << ": <"; 502 594 *out << ((Binder->leftatom->SeparationVertex) ? "SP," : "") << "L" << Binder->leftatom->LowpointNr << " G" << Binder->leftatom->GraphNr << " Comp."; 503 OutputComponentNumber(out, Binder->leftatom);595 Binder->leftatom->OutputComponentNumber(out); 504 596 *out << " === "; 505 597 *out << ((Binder->rightatom->SeparationVertex) ? "SP," : "") << "L" << Binder->rightatom->LowpointNr << " G" << Binder->rightatom->GraphNr << " Comp."; 506 OutputComponentNumber(out, Binder->rightatom);598 Binder->rightatom->OutputComponentNumber(out); 507 599 *out << ">." << endl; 508 600 if (Binder->Cyclic) // cyclic ?? 509 601 *out << Verbose(3) << "Lowpoint at each side are equal: CYCLIC!" << endl; 510 602 } 511 512 // free all and exit 513 delete(AtomStack); 514 *out << Verbose(0) << "End of DepthFirstSearchAnalysis" << endl; 515 return SubGraphs; 603 } 604 ; 605 606 /** Initialise each vertex as white with no predecessor, empty queue, color Root lightgray. 607 * \param *out output stream for debugging 608 * \param &BFS accounting structure 609 * \param AtomCount number of entries in the array to allocate 610 */ 611 void InitializeBFSAccounting(ofstream *out, struct BFSAccounting &BFS, int AtomCount) 612 { 613 BFS.AtomCount = AtomCount; 614 BFS.PredecessorList = Calloc<atom*> (AtomCount, "molecule::BreadthFirstSearchAdd_Init: **PredecessorList"); 615 BFS.ShortestPathList = Malloc<int> (AtomCount, "molecule::BreadthFirstSearchAdd_Init: *ShortestPathList"); 616 BFS.ColorList = Calloc<enum Shading> (AtomCount, "molecule::BreadthFirstSearchAdd_Init: *ColorList"); 617 BFS.BFSStack = new StackClass<atom *> (AtomCount); 618 619 for (int i = AtomCount; i--;) 620 BFS.ShortestPathList[i] = -1; 516 621 }; 622 623 /** Free's accounting structure. 624 * \param *out output stream for debugging 625 * \param &BFS accounting structure 626 */ 627 void FinalizeBFSAccounting(ofstream *out, struct BFSAccounting &BFS) 628 { 629 Free(&BFS.PredecessorList); 630 Free(&BFS.ShortestPathList); 631 Free(&BFS.ColorList); 632 delete (BFS.BFSStack); 633 BFS.AtomCount = 0; 634 }; 635 636 /** Clean the accounting structure. 637 * \param *out output stream for debugging 638 * \param &BFS accounting structure 639 */ 640 void CleanBFSAccounting(ofstream *out, struct BFSAccounting &BFS) 641 { 642 atom *Walker = NULL; 643 while (!BFS.TouchedStack->IsEmpty()) { 644 Walker = BFS.TouchedStack->PopFirst(); 645 BFS.PredecessorList[Walker->nr] = NULL; 646 BFS.ShortestPathList[Walker->nr] = -1; 647 BFS.ColorList[Walker->nr] = white; 648 } 649 }; 650 651 /** Resets shortest path list and BFSStack. 652 * \param *out output stream for debugging 653 * \param *&Walker current node, pushed onto BFSAccounting::BFSStack and BFSAccounting::TouchedStack 654 * \param &BFS accounting structure 655 */ 656 void ResetBFSAccounting(ofstream *out, atom *&Walker, struct BFSAccounting &BFS) 657 { 658 BFS.ShortestPathList[Walker->nr] = 0; 659 BFS.BFSStack->ClearStack(); // start with empty BFS stack 660 BFS.BFSStack->Push(Walker); 661 BFS.TouchedStack->Push(Walker); 662 }; 663 664 /** Performs a BFS from \a *Root, trying to find the same node and hence a cycle. 665 * \param *out output stream for debugging 666 * \param *&BackEdge the edge from root that we don't want to move along 667 * \param &BFS accounting structure 668 */ 669 void CyclicStructureAnalysis_CyclicBFSFromRootToRoot(ofstream *out, bond *&BackEdge, struct BFSAccounting &BFS) 670 { 671 atom *Walker = NULL; 672 atom *OtherAtom = NULL; 673 do { // look for Root 674 Walker = BFS.BFSStack->PopFirst(); 675 *out << Verbose(2) << "Current Walker is " << *Walker << ", we look for SP to Root " << *BFS.Root << "." << endl; 676 for (BondList::const_iterator Runner = Walker->ListOfBonds.begin(); Runner != Walker->ListOfBonds.end(); (++Runner)) { 677 if ((*Runner) != BackEdge) { // only walk along DFS spanning tree (otherwise we always find SP of one being backedge Binder) 678 OtherAtom = (*Runner)->GetOtherAtom(Walker); 679 #ifdef ADDHYDROGEN 680 if (OtherAtom->type->Z != 1) { 681 #endif 682 *out << Verbose(2) << "Current OtherAtom is: " << OtherAtom->Name << " for bond " << *(*Runner) << "." << endl; 683 if (BFS.ColorList[OtherAtom->nr] == white) { 684 BFS.TouchedStack->Push(OtherAtom); 685 BFS.ColorList[OtherAtom->nr] = lightgray; 686 BFS.PredecessorList[OtherAtom->nr] = Walker; // Walker is the predecessor 687 BFS.ShortestPathList[OtherAtom->nr] = BFS.ShortestPathList[Walker->nr] + 1; 688 *out << Verbose(2) << "Coloring OtherAtom " << OtherAtom->Name << " lightgray, its predecessor is " << Walker->Name << " and its Shortest Path is " << BFS.ShortestPathList[OtherAtom->nr] << " egde(s) long." << endl; 689 //if (BFS.ShortestPathList[OtherAtom->nr] < MinimumRingSize[Walker->GetTrueFather()->nr]) { // Check for maximum distance 690 *out << Verbose(3) << "Putting OtherAtom into queue." << endl; 691 BFS.BFSStack->Push(OtherAtom); 692 //} 693 } else { 694 *out << Verbose(3) << "Not Adding, has already been visited." << endl; 695 } 696 if (OtherAtom == BFS.Root) 697 break; 698 #ifdef ADDHYDROGEN 699 } else { 700 *out << Verbose(2) << "Skipping hydrogen atom " << *OtherAtom << "." << endl; 701 BFS.ColorList[OtherAtom->nr] = black; 702 } 703 #endif 704 } else { 705 *out << Verbose(2) << "Bond " << *(*Runner) << " not Visiting, is the back edge." << endl; 706 } 707 } 708 BFS.ColorList[Walker->nr] = black; 709 *out << Verbose(1) << "Coloring Walker " << Walker->Name << " black." << endl; 710 if (OtherAtom == BFS.Root) { // if we have found the root, check whether this cycle wasn't already found beforehand 711 // step through predecessor list 712 while (OtherAtom != BackEdge->rightatom) { 713 if (!OtherAtom->GetTrueFather()->IsCyclic) // if one bond in the loop is not marked as cyclic, we haven't found this cycle yet 714 break; 715 else 716 OtherAtom = BFS.PredecessorList[OtherAtom->nr]; 717 } 718 if (OtherAtom == BackEdge->rightatom) { // if each atom in found cycle is cyclic, loop's been found before already 719 *out << Verbose(3) << "This cycle was already found before, skipping and removing seeker from search." << endl; 720 do { 721 OtherAtom = BFS.TouchedStack->PopLast(); 722 if (BFS.PredecessorList[OtherAtom->nr] == Walker) { 723 *out << Verbose(4) << "Removing " << *OtherAtom << " from lists and stacks." << endl; 724 BFS.PredecessorList[OtherAtom->nr] = NULL; 725 BFS.ShortestPathList[OtherAtom->nr] = -1; 726 BFS.ColorList[OtherAtom->nr] = white; 727 BFS.BFSStack->RemoveItem(OtherAtom); 728 } 729 } while ((!BFS.TouchedStack->IsEmpty()) && (BFS.PredecessorList[OtherAtom->nr] == NULL)); 730 BFS.TouchedStack->Push(OtherAtom); // last was wrongly popped 731 OtherAtom = BackEdge->rightatom; // set to not Root 732 } else 733 OtherAtom = BFS.Root; 734 } 735 } while ((!BFS.BFSStack->IsEmpty()) && (OtherAtom != BFS.Root) && (OtherAtom != NULL)); // || (ShortestPathList[OtherAtom->nr] < MinimumRingSize[Walker->GetTrueFather()->nr]))); 736 }; 737 738 /** Climb back the BFSAccounting::PredecessorList and find cycle members. 739 * \param *out output stream for debugging 740 * \param *&OtherAtom 741 * \param *&BackEdge denotes the edge we did not want to travel along when doing CyclicBFSFromRootToRoot() 742 * \param &BFS accounting structure 743 * \param *&MinimumRingSize minimum distance from this node possible without encountering oneself, set on return for each atom 744 * \param &MinRingSize global minimum distance from one node without encountering oneself, set on return 745 */ 746 void CyclicStructureAnalysis_RetrieveCycleMembers(ofstream *out, atom *&OtherAtom, bond *&BackEdge, struct BFSAccounting &BFS, int *&MinimumRingSize, int &MinRingSize) 747 { 748 atom *Walker = NULL; 749 int NumCycles = 0; 750 int RingSize = -1; 751 752 if (OtherAtom == BFS.Root) { 753 // now climb back the predecessor list and thus find the cycle members 754 NumCycles++; 755 RingSize = 1; 756 BFS.Root->GetTrueFather()->IsCyclic = true; 757 *out << Verbose(1) << "Found ring contains: "; 758 Walker = BFS.Root; 759 while (Walker != BackEdge->rightatom) { 760 *out << Walker->Name << " <-> "; 761 Walker = BFS.PredecessorList[Walker->nr]; 762 Walker->GetTrueFather()->IsCyclic = true; 763 RingSize++; 764 } 765 *out << Walker->Name << " with a length of " << RingSize << "." << endl << endl; 766 // walk through all and set MinimumRingSize 767 Walker = BFS.Root; 768 MinimumRingSize[Walker->GetTrueFather()->nr] = RingSize; 769 while (Walker != BackEdge->rightatom) { 770 Walker = BFS.PredecessorList[Walker->nr]; 771 if (RingSize < MinimumRingSize[Walker->GetTrueFather()->nr]) 772 MinimumRingSize[Walker->GetTrueFather()->nr] = RingSize; 773 } 774 if ((RingSize < MinRingSize) || (MinRingSize == -1)) 775 MinRingSize = RingSize; 776 } else { 777 *out << Verbose(1) << "No ring containing " << *BFS.Root << " with length equal to or smaller than " << MinimumRingSize[Walker->GetTrueFather()->nr] << " found." << endl; 778 } 779 }; 780 781 /** From a given node performs a BFS to touch the next cycle, for whose nodes \a *&MinimumRingSize is set and set it accordingly. 782 * \param *out output stream for debugging 783 * \param *&Root node to look for closest cycle from, i.e. \a *&MinimumRingSize is set for this node 784 * \param *&MinimumRingSize minimum distance from this node possible without encountering oneself, set on return for each atom 785 * \param AtomCount number of nodes in graph 786 */ 787 void CyclicStructureAnalysis_BFSToNextCycle(ofstream *out, atom *&Root, atom *&Walker, int *&MinimumRingSize, int AtomCount) 788 { 789 struct BFSAccounting BFS; 790 atom *OtherAtom = Walker; 791 792 InitializeBFSAccounting(out, BFS, AtomCount); 793 794 ResetBFSAccounting(out, Walker, BFS); 795 while (OtherAtom != NULL) { // look for Root 796 Walker = BFS.BFSStack->PopFirst(); 797 //*out << Verbose(2) << "Current Walker is " << *Walker << ", we look for SP to Root " << *Root << "." << endl; 798 for (BondList::const_iterator Runner = Walker->ListOfBonds.begin(); Runner != Walker->ListOfBonds.end(); (++Runner)) { 799 // "removed (*Runner) != BackEdge) || " from next if, is u 800 if ((Walker->ListOfBonds.size() == 1)) { // only walk along DFS spanning tree (otherwise we always find SP of 1 being backedge Binder), but terminal hydrogens may be connected via backedge, hence extra check 801 OtherAtom = (*Runner)->GetOtherAtom(Walker); 802 //*out << Verbose(2) << "Current OtherAtom is: " << OtherAtom->Name << " for bond " << *Binder << "." << endl; 803 if (BFS.ColorList[OtherAtom->nr] == white) { 804 BFS.TouchedStack->Push(OtherAtom); 805 BFS.ColorList[OtherAtom->nr] = lightgray; 806 BFS.PredecessorList[OtherAtom->nr] = Walker; // Walker is the predecessor 807 BFS.ShortestPathList[OtherAtom->nr] = BFS.ShortestPathList[Walker->nr] + 1; 808 //*out << Verbose(2) << "Coloring OtherAtom " << OtherAtom->Name << " lightgray, its predecessor is " << Walker->Name << " and its Shortest Path is " << ShortestPathList[OtherAtom->nr] << " egde(s) long." << endl; 809 if (OtherAtom->GetTrueFather()->IsCyclic) { // if the other atom is connected to a ring 810 MinimumRingSize[Root->GetTrueFather()->nr] = BFS.ShortestPathList[OtherAtom->nr] + MinimumRingSize[OtherAtom->GetTrueFather()->nr]; 811 OtherAtom = NULL; //break; 812 break; 813 } else 814 BFS.BFSStack->Push(OtherAtom); 815 } else { 816 //*out << Verbose(3) << "Not Adding, has already been visited." << endl; 817 } 818 } else { 819 //*out << Verbose(3) << "Not Visiting, is a back edge." << endl; 820 } 821 } 822 BFS.ColorList[Walker->nr] = black; 823 //*out << Verbose(1) << "Coloring Walker " << Walker->Name << " black." << endl; 824 } 825 //CleanAccountingLists(TouchedStack, PredecessorList, ShortestPathList, ColorList); 826 827 FinalizeBFSAccounting(out, BFS); 828 } 829 ; 830 831 /** All nodes that are not in cycles get assigned a \a *&MinimumRingSizeby BFS to next cycle. 832 * \param *out output stream for debugging 833 * \param *&MinimumRingSize array with minimum distance without encountering onself for each atom 834 * \param &MinRingSize global minium distance 835 * \param &NumCyles number of cycles in graph 836 * \param *mol molecule with atoms 837 */ 838 void CyclicStructureAnalysis_AssignRingSizetoNonCycleMembers(ofstream *out, int *&MinimumRingSize, int &MinRingSize, int &NumCycles, const molecule * const mol) 839 { 840 atom *Root = NULL; 841 atom *Walker = NULL; 842 if (MinRingSize != -1) { // if rings are present 843 // go over all atoms 844 Root = mol->start; 845 while (Root->next != mol->end) { 846 Root = Root->next; 847 848 if (MinimumRingSize[Root->GetTrueFather()->nr] == mol->AtomCount) { // check whether MinimumRingSize is set, if not BFS to next where it is 849 Walker = Root; 850 851 //*out << Verbose(1) << "---------------------------------------------------------------------------------------------------------" << endl; 852 CyclicStructureAnalysis_BFSToNextCycle(out, Root, Walker, MinimumRingSize, mol->AtomCount); 853 854 } 855 *out << Verbose(1) << "Minimum ring size of " << *Root << " is " << MinimumRingSize[Root->GetTrueFather()->nr] << "." << endl; 856 } 857 *out << Verbose(1) << "Minimum ring size is " << MinRingSize << ", over " << NumCycles << " cycles total." << endl; 858 } else 859 *out << Verbose(1) << "No rings were detected in the molecular structure." << endl; 860 } 861 ; 517 862 518 863 /** Analyses the cycles found and returns minimum of all cycle lengths. … … 526 871 * \todo BFS from the not-same-LP to find back to starting point of tributary cycle over more than one bond 527 872 */ 528 void molecule::CyclicStructureAnalysis(ofstream *out, class StackClass<bond *> * BackEdgeStack, int *&MinimumRingSize) 529 { 530 atom **PredecessorList = Malloc<atom*>(AtomCount, "molecule::CyclicStructureAnalysis: **PredecessorList"); 531 int *ShortestPathList = Malloc<int>(AtomCount, "molecule::CyclicStructureAnalysis: *ShortestPathList"); 532 enum Shading *ColorList = Malloc<enum Shading>(AtomCount, "molecule::CyclicStructureAnalysis: *ColorList"); 533 class StackClass<atom *> *BFSStack = new StackClass<atom *> (AtomCount); // will hold the current ring 534 class StackClass<atom *> *TouchedStack = new StackClass<atom *> (AtomCount); // contains all "touched" atoms (that need to be reset after BFS loop) 535 atom *Walker = NULL, *OtherAtom = NULL, *Root = NULL; 536 bond *Binder = NULL, *BackEdge = NULL; 537 int RingSize, NumCycles, MinRingSize = -1; 538 539 // initialise each vertex as white with no predecessor, empty queue, color Root lightgray 540 for (int i=AtomCount;i--;) { 541 PredecessorList[i] = NULL; 542 ShortestPathList[i] = -1; 543 ColorList[i] = white; 544 } 545 546 *out << Verbose(1) << "Back edge list - "; 547 BackEdgeStack->Output(out); 873 void molecule::CyclicStructureAnalysis(ofstream *out, class StackClass<bond *> * BackEdgeStack, int *&MinimumRingSize) const 874 { 875 struct BFSAccounting BFS; 876 atom *Walker = NULL; 877 atom *OtherAtom = NULL; 878 bond *BackEdge = NULL; 879 int NumCycles = 0; 880 int MinRingSize = -1; 881 882 InitializeBFSAccounting(out, BFS, AtomCount); 883 884 //*out << Verbose(1) << "Back edge list - "; 885 //BackEdgeStack->Output(out); 548 886 549 887 *out << Verbose(1) << "Analysing cycles ... " << endl; … … 552 890 BackEdge = BackEdgeStack->PopFirst(); 553 891 // this is the target 554 Root = BackEdge->leftatom;892 BFS.Root = BackEdge->leftatom; 555 893 // this is the source point 556 894 Walker = BackEdge->rightatom; 557 ShortestPathList[Walker->nr] = 0; 558 BFSStack->ClearStack(); // start with empty BFS stack 559 BFSStack->Push(Walker); 560 TouchedStack->Push(Walker); 895 896 ResetBFSAccounting(out, Walker, BFS); 897 561 898 *out << Verbose(1) << "---------------------------------------------------------------------------------------------------------" << endl; 562 899 OtherAtom = NULL; 563 do { // look for Root 564 Walker = BFSStack->PopFirst(); 565 *out << Verbose(2) << "Current Walker is " << *Walker << ", we look for SP to Root " << *Root << "." << endl; 566 for(int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++) { 567 Binder = ListOfBondsPerAtom[Walker->nr][i]; 568 if (Binder != BackEdge) { // only walk along DFS spanning tree (otherwise we always find SP of one being backedge Binder) 569 OtherAtom = Binder->GetOtherAtom(Walker); 570 #ifdef ADDHYDROGEN 571 if (OtherAtom->type->Z != 1) { 572 #endif 573 *out << Verbose(2) << "Current OtherAtom is: " << OtherAtom->Name << " for bond " << *Binder << "." << endl; 574 if (ColorList[OtherAtom->nr] == white) { 575 TouchedStack->Push(OtherAtom); 576 ColorList[OtherAtom->nr] = lightgray; 577 PredecessorList[OtherAtom->nr] = Walker; // Walker is the predecessor 578 ShortestPathList[OtherAtom->nr] = ShortestPathList[Walker->nr]+1; 579 *out << Verbose(2) << "Coloring OtherAtom " << OtherAtom->Name << " lightgray, its predecessor is " << Walker->Name << " and its Shortest Path is " << ShortestPathList[OtherAtom->nr] << " egde(s) long." << endl; 580 //if (ShortestPathList[OtherAtom->nr] < MinimumRingSize[Walker->GetTrueFather()->nr]) { // Check for maximum distance 581 *out << Verbose(3) << "Putting OtherAtom into queue." << endl; 582 BFSStack->Push(OtherAtom); 583 //} 584 } else { 585 *out << Verbose(3) << "Not Adding, has already been visited." << endl; 586 } 587 if (OtherAtom == Root) 588 break; 589 #ifdef ADDHYDROGEN 590 } else { 591 *out << Verbose(2) << "Skipping hydrogen atom " << *OtherAtom << "." << endl; 592 ColorList[OtherAtom->nr] = black; 593 } 594 #endif 595 } else { 596 *out << Verbose(2) << "Bond " << *Binder << " not Visiting, is the back edge." << endl; 597 } 598 } 599 ColorList[Walker->nr] = black; 600 *out << Verbose(1) << "Coloring Walker " << Walker->Name << " black." << endl; 601 if (OtherAtom == Root) { // if we have found the root, check whether this cycle wasn't already found beforehand 602 // step through predecessor list 603 while (OtherAtom != BackEdge->rightatom) { 604 if (!OtherAtom->GetTrueFather()->IsCyclic) // if one bond in the loop is not marked as cyclic, we haven't found this cycle yet 605 break; 606 else 607 OtherAtom = PredecessorList[OtherAtom->nr]; 608 } 609 if (OtherAtom == BackEdge->rightatom) { // if each atom in found cycle is cyclic, loop's been found before already 610 *out << Verbose(3) << "This cycle was already found before, skipping and removing seeker from search." << endl;\ 611 do { 612 OtherAtom = TouchedStack->PopLast(); 613 if (PredecessorList[OtherAtom->nr] == Walker) { 614 *out << Verbose(4) << "Removing " << *OtherAtom << " from lists and stacks." << endl; 615 PredecessorList[OtherAtom->nr] = NULL; 616 ShortestPathList[OtherAtom->nr] = -1; 617 ColorList[OtherAtom->nr] = white; 618 BFSStack->RemoveItem(OtherAtom); 619 } 620 } while ((!TouchedStack->IsEmpty()) && (PredecessorList[OtherAtom->nr] == NULL)); 621 TouchedStack->Push(OtherAtom); // last was wrongly popped 622 OtherAtom = BackEdge->rightatom; // set to not Root 623 } else 624 OtherAtom = Root; 625 } 626 } while ((!BFSStack->IsEmpty()) && (OtherAtom != Root) && (OtherAtom != NULL)); // || (ShortestPathList[OtherAtom->nr] < MinimumRingSize[Walker->GetTrueFather()->nr]))); 627 628 if (OtherAtom == Root) { 629 // now climb back the predecessor list and thus find the cycle members 630 NumCycles++; 631 RingSize = 1; 632 Root->GetTrueFather()->IsCyclic = true; 633 *out << Verbose(1) << "Found ring contains: "; 634 Walker = Root; 635 while (Walker != BackEdge->rightatom) { 636 *out << Walker->Name << " <-> "; 637 Walker = PredecessorList[Walker->nr]; 638 Walker->GetTrueFather()->IsCyclic = true; 639 RingSize++; 640 } 641 *out << Walker->Name << " with a length of " << RingSize << "." << endl << endl; 642 // walk through all and set MinimumRingSize 643 Walker = Root; 644 MinimumRingSize[Walker->GetTrueFather()->nr] = RingSize; 645 while (Walker != BackEdge->rightatom) { 646 Walker = PredecessorList[Walker->nr]; 647 if (RingSize < MinimumRingSize[Walker->GetTrueFather()->nr]) 648 MinimumRingSize[Walker->GetTrueFather()->nr] = RingSize; 649 } 650 if ((RingSize < MinRingSize) || (MinRingSize == -1)) 651 MinRingSize = RingSize; 652 } else { 653 *out << Verbose(1) << "No ring containing " << *Root << " with length equal to or smaller than " << MinimumRingSize[Walker->GetTrueFather()->nr] << " found." << endl; 654 } 655 656 // now clean the lists 657 while (!TouchedStack->IsEmpty()){ 658 Walker = TouchedStack->PopFirst(); 659 PredecessorList[Walker->nr] = NULL; 660 ShortestPathList[Walker->nr] = -1; 661 ColorList[Walker->nr] = white; 662 } 663 } 664 if (MinRingSize != -1) { 665 // go over all atoms 666 Root = start; 667 while(Root->next != end) { 668 Root = Root->next; 669 670 if (MinimumRingSize[Root->GetTrueFather()->nr] == AtomCount) { // check whether MinimumRingSize is set, if not BFS to next where it is 671 Walker = Root; 672 ShortestPathList[Walker->nr] = 0; 673 BFSStack->ClearStack(); // start with empty BFS stack 674 BFSStack->Push(Walker); 675 TouchedStack->Push(Walker); 676 //*out << Verbose(1) << "---------------------------------------------------------------------------------------------------------" << endl; 677 OtherAtom = Walker; 678 while (OtherAtom != NULL) { // look for Root 679 Walker = BFSStack->PopFirst(); 680 //*out << Verbose(2) << "Current Walker is " << *Walker << ", we look for SP to Root " << *Root << "." << endl; 681 for(int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++) { 682 Binder = ListOfBondsPerAtom[Walker->nr][i]; 683 if ((Binder != BackEdge) || (NumberOfBondsPerAtom[Walker->nr] == 1)) { // only walk along DFS spanning tree (otherwise we always find SP of 1 being backedge Binder), but terminal hydrogens may be connected via backedge, hence extra check 684 OtherAtom = Binder->GetOtherAtom(Walker); 685 //*out << Verbose(2) << "Current OtherAtom is: " << OtherAtom->Name << " for bond " << *Binder << "." << endl; 686 if (ColorList[OtherAtom->nr] == white) { 687 TouchedStack->Push(OtherAtom); 688 ColorList[OtherAtom->nr] = lightgray; 689 PredecessorList[OtherAtom->nr] = Walker; // Walker is the predecessor 690 ShortestPathList[OtherAtom->nr] = ShortestPathList[Walker->nr]+1; 691 //*out << Verbose(2) << "Coloring OtherAtom " << OtherAtom->Name << " lightgray, its predecessor is " << Walker->Name << " and its Shortest Path is " << ShortestPathList[OtherAtom->nr] << " egde(s) long." << endl; 692 if (OtherAtom->GetTrueFather()->IsCyclic) { // if the other atom is connected to a ring 693 MinimumRingSize[Root->GetTrueFather()->nr] = ShortestPathList[OtherAtom->nr]+MinimumRingSize[OtherAtom->GetTrueFather()->nr]; 694 OtherAtom = NULL; //break; 695 break; 696 } else 697 BFSStack->Push(OtherAtom); 698 } else { 699 //*out << Verbose(3) << "Not Adding, has already been visited." << endl; 700 } 701 } else { 702 //*out << Verbose(3) << "Not Visiting, is a back edge." << endl; 703 } 704 } 705 ColorList[Walker->nr] = black; 706 //*out << Verbose(1) << "Coloring Walker " << Walker->Name << " black." << endl; 707 } 708 709 // now clean the lists 710 while (!TouchedStack->IsEmpty()){ 711 Walker = TouchedStack->PopFirst(); 712 PredecessorList[Walker->nr] = NULL; 713 ShortestPathList[Walker->nr] = -1; 714 ColorList[Walker->nr] = white; 715 } 716 } 717 *out << Verbose(1) << "Minimum ring size of " << *Root << " is " << MinimumRingSize[Root->GetTrueFather()->nr] << "." << endl; 718 } 719 *out << Verbose(1) << "Minimum ring size is " << MinRingSize << ", over " << NumCycles << " cycles total." << endl; 720 } else 721 *out << Verbose(1) << "No rings were detected in the molecular structure." << endl; 722 723 Free(&PredecessorList); 724 Free(&ShortestPathList); 725 Free(&ColorList); 726 delete(BFSStack); 900 CyclicStructureAnalysis_CyclicBFSFromRootToRoot(out, BackEdge, BFS); 901 902 CyclicStructureAnalysis_RetrieveCycleMembers(out, OtherAtom, BackEdge, BFS, MinimumRingSize, MinRingSize); 903 904 CleanBFSAccounting(out, BFS); 905 } 906 FinalizeBFSAccounting(out, BFS); 907 908 CyclicStructureAnalysis_AssignRingSizetoNonCycleMembers(out, MinimumRingSize, MinRingSize, NumCycles, this); 727 909 }; 728 910 … … 732 914 * \param nr number to use 733 915 */ 734 void molecule::SetNextComponentNumber(atom *vertex, int nr) 735 { 736 int i=0;916 void molecule::SetNextComponentNumber(atom *vertex, int nr) const 917 { 918 size_t i = 0; 737 919 if (vertex != NULL) { 738 for (;i<NumberOfBondsPerAtom[vertex->nr];i++) {739 if (vertex->ComponentNr[i] == -1) { 920 for (; i < vertex->ListOfBonds.size(); i++) { 921 if (vertex->ComponentNr[i] == -1) { // check if not yet used 740 922 vertex->ComponentNr[i] = nr; 741 923 break; 742 } 743 else if (vertex->ComponentNr[i] == nr) // if number is already present, don't add another time 744 break; // breaking here will not cause error! 745 } 746 if (i == NumberOfBondsPerAtom[vertex->nr]) 924 } else if (vertex->ComponentNr[i] == nr) // if number is already present, don't add another time 925 break; // breaking here will not cause error! 926 } 927 if (i == vertex->ListOfBonds.size()) 747 928 cerr << "Error: All Component entries are already occupied!" << endl; 748 929 } else 749 cerr << "Error: Given vertex is NULL!" << endl; 750 }; 751 752 /** Output a list of flags, stating whether the bond was visited or not. 753 * \param *out output stream for debugging 754 */ 755 void molecule::OutputComponentNumber(ofstream *out, atom *vertex) 756 { 757 for(int i=0;i<NumberOfBondsPerAtom[vertex->nr];i++) 758 *out << vertex->ComponentNr[i] << " "; 759 }; 760 761 /** Allocates memory for all atom::*ComponentNr in this molecule and sets each entry to -1. 762 */ 763 void molecule::InitComponentNumbers() 764 { 765 atom *Walker = start; 766 while(Walker->next != end) { 767 Walker = Walker->next; 768 if (Walker->ComponentNr != NULL) 769 Free(&Walker->ComponentNr); 770 Walker->ComponentNr = Malloc<int>(NumberOfBondsPerAtom[Walker->nr], "molecule::InitComponentNumbers: *Walker->ComponentNr"); 771 for (int i=NumberOfBondsPerAtom[Walker->nr];i--;) 772 Walker->ComponentNr[i] = -1; 773 } 774 }; 930 cerr << "Error: Given vertex is NULL!" << endl; 931 } 932 ; 775 933 776 934 /** Returns next unused bond for this atom \a *vertex or NULL of none exists. … … 778 936 * \return bond class or NULL 779 937 */ 780 bond * molecule::FindNextUnused(atom *vertex) 781 { 782 for (int i=0;i<NumberOfBondsPerAtom[vertex->nr];i++)783 if ( ListOfBondsPerAtom[vertex->nr][i]->IsUsed() == white)784 return (ListOfBondsPerAtom[vertex->nr][i]);938 bond * molecule::FindNextUnused(atom *vertex) const 939 { 940 for (BondList::const_iterator Runner = vertex->ListOfBonds.begin(); Runner != vertex->ListOfBonds.end(); (++Runner)) 941 if ((*Runner)->IsUsed() == white) 942 return ((*Runner)); 785 943 return NULL; 786 }; 944 } 945 ; 787 946 788 947 /** Resets bond::Used flag of all bonds in this molecule. 789 948 * \return true - success, false - -failure 790 949 */ 791 void molecule::ResetAllBondsToUnused() 950 void molecule::ResetAllBondsToUnused() const 792 951 { 793 952 bond *Binder = first; … … 796 955 Binder->ResetUsed(); 797 956 } 798 }; 799 800 /** Resets atom::nr to -1 of all atoms in this molecule. 801 */ 802 void molecule::ResetAllAtomNumbers() 803 { 804 atom *Walker = start; 805 while (Walker->next != end) { 806 Walker = Walker->next; 807 Walker->GraphNr = -1; 808 } 809 }; 957 } 958 ; 810 959 811 960 /** Output a list of flags, stating whether the bond was visited or not. … … 816 965 { 817 966 *out << Verbose(4) << "Already Visited Bonds:\t"; 818 for(int i=1;i<=list[0];i++) *out << Verbose(0) << list[i] << " "; 967 for (int i = 1; i <= list[0]; i++) 968 *out << Verbose(0) << list[i] << " "; 819 969 *out << endl; 820 } ;821 970 } 971 ; 822 972 823 973 /** Storing the bond structure of a molecule to file. … … 830 980 { 831 981 ofstream AdjacencyFile; 832 atom *Walker = NULL;833 982 stringstream line; 834 983 bool status = true; … … 838 987 *out << Verbose(1) << "Saving adjacency list ... "; 839 988 if (AdjacencyFile != NULL) { 840 Walker = start; 841 while(Walker->next != end) { 842 Walker = Walker->next; 843 AdjacencyFile << Walker->nr << "\t"; 844 for (int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++) 845 AdjacencyFile << ListOfBondsPerAtom[Walker->nr][i]->GetOtherAtom(Walker)->nr << "\t"; 846 AdjacencyFile << endl; 847 } 989 ActOnAllAtoms(&atom::OutputAdjacency, &AdjacencyFile); 848 990 AdjacencyFile.close(); 849 991 *out << Verbose(1) << "done." << endl; … … 854 996 855 997 return status; 856 }; 998 } 999 ; 1000 1001 bool CheckAdjacencyFileAgainstMolecule_Init(ofstream *out, char *path, ifstream &File, int *&CurrentBonds) 1002 { 1003 stringstream filename; 1004 filename << path << "/" << FRAGMENTPREFIX << ADJACENCYFILE; 1005 File.open(filename.str().c_str(), ios::out); 1006 *out << Verbose(1) << "Looking at bond structure stored in adjacency file and comparing to present one ... "; 1007 if (File == NULL) 1008 return false; 1009 1010 // allocate storage structure 1011 CurrentBonds = Calloc<int> (8, "molecule::CheckAdjacencyFileAgainstMolecule - CurrentBonds"); // contains parsed bonds of current atom 1012 return true; 1013 } 1014 ; 1015 1016 void CheckAdjacencyFileAgainstMolecule_Finalize(ofstream *out, ifstream &File, int *&CurrentBonds) 1017 { 1018 File.close(); 1019 File.clear(); 1020 Free(&CurrentBonds); 1021 } 1022 ; 1023 1024 void CheckAdjacencyFileAgainstMolecule_CompareBonds(ofstream *out, bool &status, int &NonMatchNumber, atom *&Walker, size_t &CurrentBondsOfAtom, int AtomNr, int *&CurrentBonds, atom **ListOfAtoms) 1025 { 1026 size_t j = 0; 1027 int id = -1; 1028 1029 //*out << Verbose(2) << "Walker is " << *Walker << ", bond partners: "; 1030 if (CurrentBondsOfAtom == Walker->ListOfBonds.size()) { 1031 for (BondList::const_iterator Runner = Walker->ListOfBonds.begin(); Runner != Walker->ListOfBonds.end(); (++Runner)) { 1032 id = (*Runner)->GetOtherAtom(Walker)->nr; 1033 j = 0; 1034 for (; (j < CurrentBondsOfAtom) && (CurrentBonds[j++] != id);) 1035 ; // check against all parsed bonds 1036 if (CurrentBonds[j - 1] != id) { // no match ? Then mark in ListOfAtoms 1037 ListOfAtoms[AtomNr] = NULL; 1038 NonMatchNumber++; 1039 status = false; 1040 //*out << "[" << id << "]\t"; 1041 } else { 1042 //*out << id << "\t"; 1043 } 1044 } 1045 //*out << endl; 1046 } else { 1047 *out << "Number of bonds for Atom " << *Walker << " does not match, parsed " << CurrentBondsOfAtom << " against " << Walker->ListOfBonds.size() << "." << endl; 1048 status = false; 1049 } 1050 } 1051 ; 857 1052 858 1053 /** Checks contents of adjacency file against bond structure in structure molecule. … … 865 1060 { 866 1061 ifstream File; 867 stringstream filename;868 1062 bool status = true; 869 char *buffer = Malloc<char>(MAXSTRINGSIZE, "molecule::CheckAdjacencyFileAgainstMolecule: *buffer"); 870 871 filename << path << "/" << FRAGMENTPREFIX << ADJACENCYFILE; 872 File.open(filename.str().c_str(), ios::out); 873 *out << Verbose(1) << "Looking at bond structure stored in adjacency file and comparing to present one ... "; 874 if (File != NULL) { 875 // allocate storage structure 876 int NonMatchNumber = 0; // will number of atoms with differing bond structure 877 int *CurrentBonds = Malloc<int>(8, "molecule::CheckAdjacencyFileAgainstMolecule - CurrentBonds"); // contains parsed bonds of current atom 878 int CurrentBondsOfAtom; 879 880 // Parse the file line by line and count the bonds 881 while (!File.eof()) { 882 File.getline(buffer, MAXSTRINGSIZE); 883 stringstream line; 884 line.str(buffer); 885 int AtomNr = -1; 886 line >> AtomNr; 887 CurrentBondsOfAtom = -1; // we count one too far due to line end 888 // parse into structure 889 if ((AtomNr >= 0) && (AtomNr < AtomCount)) { 890 while (!line.eof()) 891 line >> CurrentBonds[ ++CurrentBondsOfAtom ]; 892 // compare against present bonds 893 //cout << Verbose(2) << "Walker is " << *Walker << ", bond partners: "; 894 if (CurrentBondsOfAtom == NumberOfBondsPerAtom[AtomNr]) { 895 for(int i=0;i<NumberOfBondsPerAtom[AtomNr];i++) { 896 int id = ListOfBondsPerAtom[AtomNr][i]->GetOtherAtom(ListOfAtoms[AtomNr])->nr; 897 int j = 0; 898 for (;(j<CurrentBondsOfAtom) && (CurrentBonds[j++] != id);); // check against all parsed bonds 899 if (CurrentBonds[j-1] != id) { // no match ? Then mark in ListOfAtoms 900 ListOfAtoms[AtomNr] = NULL; 901 NonMatchNumber++; 902 status = false; 903 //out << "[" << id << "]\t"; 904 } else { 905 //out << id << "\t"; 906 } 907 } 908 //out << endl; 909 } else { 910 *out << "Number of bonds for Atom " << *ListOfAtoms[AtomNr] << " does not match, parsed " << CurrentBondsOfAtom << " against " << NumberOfBondsPerAtom[AtomNr] << "." << endl; 911 status = false; 912 } 913 } 914 } 915 File.close(); 916 File.clear(); 917 if (status) { // if equal we parse the KeySetFile 918 *out << Verbose(1) << "done: Equal." << endl; 919 status = true; 920 } else 921 *out << Verbose(1) << "done: Not equal by " << NonMatchNumber << " atoms." << endl; 922 Free(&CurrentBonds); 923 } else { 1063 atom *Walker = NULL; 1064 char *buffer = NULL; 1065 int *CurrentBonds = NULL; 1066 int NonMatchNumber = 0; // will number of atoms with differing bond structure 1067 size_t CurrentBondsOfAtom = -1; 1068 1069 if (!CheckAdjacencyFileAgainstMolecule_Init(out, path, File, CurrentBonds)) { 924 1070 *out << Verbose(1) << "Adjacency file not found." << endl; 925 status = false; 926 } 927 *out << endl; 1071 return true; 1072 } 1073 1074 buffer = Malloc<char> (MAXSTRINGSIZE, "molecule::CheckAdjacencyFileAgainstMolecule: *buffer"); 1075 // Parse the file line by line and count the bonds 1076 while (!File.eof()) { 1077 File.getline(buffer, MAXSTRINGSIZE); 1078 stringstream line; 1079 line.str(buffer); 1080 int AtomNr = -1; 1081 line >> AtomNr; 1082 CurrentBondsOfAtom = -1; // we count one too far due to line end 1083 // parse into structure 1084 if ((AtomNr >= 0) && (AtomNr < AtomCount)) { 1085 Walker = ListOfAtoms[AtomNr]; 1086 while (!line.eof()) 1087 line >> CurrentBonds[++CurrentBondsOfAtom]; 1088 // compare against present bonds 1089 CheckAdjacencyFileAgainstMolecule_CompareBonds(out, status, NonMatchNumber, Walker, CurrentBondsOfAtom, AtomNr, CurrentBonds, ListOfAtoms); 1090 } 1091 } 928 1092 Free(&buffer); 929 1093 CheckAdjacencyFileAgainstMolecule_Finalize(out, File, CurrentBonds); 1094 1095 if (status) { // if equal we parse the KeySetFile 1096 *out << Verbose(1) << "done: Equal." << endl; 1097 } else 1098 *out << Verbose(1) << "done: Not equal by " << NonMatchNumber << " atoms." << endl; 930 1099 return status; 931 } ;932 1100 } 1101 ; 933 1102 934 1103 /** Picks from a global stack with all back edges the ones in the fragment. … … 939 1108 * \return true - everything ok, false - ReferenceStack was empty 940 1109 */ 941 bool molecule::PickLocalBackEdges(ofstream *out, atom **ListOfLocalAtoms, class StackClass<bond *> *&ReferenceStack, class StackClass<bond *> *&LocalStack) 1110 bool molecule::PickLocalBackEdges(ofstream *out, atom **ListOfLocalAtoms, class StackClass<bond *> *&ReferenceStack, class StackClass<bond *> *&LocalStack) const 942 1111 { 943 1112 bool status = true; … … 947 1116 } 948 1117 bond *Binder = ReferenceStack->PopFirst(); 949 bond *FirstBond = Binder; 1118 bond *FirstBond = Binder; // mark the first bond, so that we don't loop through the stack indefinitely 950 1119 atom *Walker = NULL, *OtherAtom = NULL; 951 1120 ReferenceStack->Push(Binder); 952 1121 953 do { 954 Walker = ListOfLocalAtoms[Binder->leftatom->nr]; 1122 do { // go through all bonds and push local ones 1123 Walker = ListOfLocalAtoms[Binder->leftatom->nr]; // get one atom in the reference molecule 955 1124 if (Walker != NULL) // if this Walker exists in the subgraph ... 956 for (int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++) { // go through the local list of bonds957 OtherAtom = ListOfBondsPerAtom[Walker->nr][i]->GetOtherAtom(Walker);958 if (OtherAtom == ListOfLocalAtoms[ Binder->rightatom->nr]) { // found the bond959 LocalStack->Push( ListOfBondsPerAtom[Walker->nr][i]);960 *out << Verbose(3) << "Found local edge " << *( ListOfBondsPerAtom[Walker->nr][i]) << "." << endl;1125 for (BondList::const_iterator Runner = Walker->ListOfBonds.begin(); Runner != Walker->ListOfBonds.end(); (++Runner)) { 1126 OtherAtom = (*Runner)->GetOtherAtom(Walker); 1127 if (OtherAtom == ListOfLocalAtoms[(*Runner)->rightatom->nr]) { // found the bond 1128 LocalStack->Push((*Runner)); 1129 *out << Verbose(3) << "Found local edge " << *(*Runner) << "." << endl; 961 1130 break; 962 1131 } 963 1132 } 964 Binder = ReferenceStack->PopFirst(); 1133 Binder = ReferenceStack->PopFirst(); // loop the stack for next item 965 1134 *out << Verbose(3) << "Current candidate edge " << Binder << "." << endl; 966 1135 ReferenceStack->Push(Binder); … … 968 1137 969 1138 return status; 970 }; 971 1139 } 1140 ; 1141 1142 void BreadthFirstSearchAdd_Init(struct BFSAccounting &BFS, atom *&Root, int AtomCount, int BondOrder, atom **AddedAtomList = NULL) 1143 { 1144 BFS.AtomCount = AtomCount; 1145 BFS.BondOrder = BondOrder; 1146 BFS.PredecessorList = Calloc<atom*> (AtomCount, "molecule::BreadthFirstSearchAdd_Init: **PredecessorList"); 1147 BFS.ShortestPathList = Calloc<int> (AtomCount, "molecule::BreadthFirstSearchAdd_Init: *ShortestPathList"); 1148 BFS.ColorList = Malloc<enum Shading> (AtomCount, "molecule::BreadthFirstSearchAdd_Init: *ColorList"); 1149 BFS.BFSStack = new StackClass<atom *> (AtomCount); 1150 1151 BFS.Root = Root; 1152 BFS.BFSStack->ClearStack(); 1153 BFS.BFSStack->Push(Root); 1154 1155 // initialise each vertex as white with no predecessor, empty queue, color Root lightgray 1156 for (int i = AtomCount; i--;) { 1157 BFS.ShortestPathList[i] = -1; 1158 if ((AddedAtomList != NULL) && (AddedAtomList[i] != NULL)) // mark already present atoms (i.e. Root and maybe others) as visited 1159 BFS.ColorList[i] = lightgray; 1160 else 1161 BFS.ColorList[i] = white; 1162 } 1163 //BFS.ShortestPathList[Root->nr] = 0; //is set due to Calloc() 1164 } 1165 ; 1166 1167 void BreadthFirstSearchAdd_Free(struct BFSAccounting &BFS) 1168 { 1169 Free(&BFS.PredecessorList); 1170 Free(&BFS.ShortestPathList); 1171 Free(&BFS.ColorList); 1172 delete (BFS.BFSStack); 1173 BFS.AtomCount = 0; 1174 } 1175 ; 1176 1177 void BreadthFirstSearchAdd_UnvisitedNode(ofstream *out, molecule *Mol, struct BFSAccounting &BFS, atom *&Walker, atom *&OtherAtom, bond *&Binder, bond *&Bond, atom **&AddedAtomList, bond **&AddedBondList, bool IsAngstroem) 1178 { 1179 if (Binder != Bond) // let other atom white if it's via Root bond. In case it's cyclic it has to be reached again (yet Root is from OtherAtom already black, thus no problem) 1180 BFS.ColorList[OtherAtom->nr] = lightgray; 1181 BFS.PredecessorList[OtherAtom->nr] = Walker; // Walker is the predecessor 1182 BFS.ShortestPathList[OtherAtom->nr] = BFS.ShortestPathList[Walker->nr] + 1; 1183 *out << Verbose(2) << "Coloring OtherAtom " << OtherAtom->Name << " " << ((BFS.ColorList[OtherAtom->nr] == white) ? "white" : "lightgray") << ", its predecessor is " << Walker->Name << " and its Shortest Path is " << BFS.ShortestPathList[OtherAtom->nr] << " egde(s) long." << endl; 1184 if ((((BFS.ShortestPathList[OtherAtom->nr] < BFS.BondOrder) && (Binder != Bond)))) { // Check for maximum distance 1185 *out << Verbose(3); 1186 if (AddedAtomList[OtherAtom->nr] == NULL) { // add if it's not been so far 1187 AddedAtomList[OtherAtom->nr] = Mol->AddCopyAtom(OtherAtom); 1188 *out << "Added OtherAtom " << OtherAtom->Name; 1189 AddedBondList[Binder->nr] = Mol->CopyBond(AddedAtomList[Walker->nr], AddedAtomList[OtherAtom->nr], Binder); 1190 *out << " and bond " << *(AddedBondList[Binder->nr]) << ", "; 1191 } else { // this code should actually never come into play (all white atoms are not yet present in BondMolecule, that's why they are white in the first place) 1192 *out << "Not adding OtherAtom " << OtherAtom->Name; 1193 if (AddedBondList[Binder->nr] == NULL) { 1194 AddedBondList[Binder->nr] = Mol->CopyBond(AddedAtomList[Walker->nr], AddedAtomList[OtherAtom->nr], Binder); 1195 *out << ", added Bond " << *(AddedBondList[Binder->nr]); 1196 } else 1197 *out << ", not added Bond "; 1198 } 1199 *out << ", putting OtherAtom into queue." << endl; 1200 BFS.BFSStack->Push(OtherAtom); 1201 } else { // out of bond order, then replace 1202 if ((AddedAtomList[OtherAtom->nr] == NULL) && (Binder->Cyclic)) 1203 BFS.ColorList[OtherAtom->nr] = white; // unmark if it has not been queued/added, to make it available via its other bonds (cyclic) 1204 if (Binder == Bond) 1205 *out << Verbose(3) << "Not Queueing, is the Root bond"; 1206 else if (BFS.ShortestPathList[OtherAtom->nr] >= BFS.BondOrder) 1207 *out << Verbose(3) << "Not Queueing, is out of Bond Count of " << BFS.BondOrder; 1208 if (!Binder->Cyclic) 1209 *out << ", is not part of a cyclic bond, saturating bond with Hydrogen." << endl; 1210 if (AddedBondList[Binder->nr] == NULL) { 1211 if ((AddedAtomList[OtherAtom->nr] != NULL)) { // .. whether we add or saturate 1212 AddedBondList[Binder->nr] = Mol->CopyBond(AddedAtomList[Walker->nr], AddedAtomList[OtherAtom->nr], Binder); 1213 } else { 1214 #ifdef ADDHYDROGEN 1215 if (!Mol->AddHydrogenReplacementAtom(out, Binder, AddedAtomList[Walker->nr], Walker, OtherAtom, IsAngstroem)) 1216 exit(1); 1217 #endif 1218 } 1219 } 1220 } 1221 } 1222 ; 1223 1224 void BreadthFirstSearchAdd_VisitedNode(ofstream *out, molecule *Mol, struct BFSAccounting &BFS, atom *&Walker, atom *&OtherAtom, bond *&Binder, bond *&Bond, atom **&AddedAtomList, bond **&AddedBondList, bool IsAngstroem) 1225 { 1226 *out << Verbose(3) << "Not Adding, has already been visited." << endl; 1227 // This has to be a cyclic bond, check whether it's present ... 1228 if (AddedBondList[Binder->nr] == NULL) { 1229 if ((Binder != Bond) && (Binder->Cyclic) && (((BFS.ShortestPathList[Walker->nr] + 1) < BFS.BondOrder))) { 1230 AddedBondList[Binder->nr] = Mol->CopyBond(AddedAtomList[Walker->nr], AddedAtomList[OtherAtom->nr], Binder); 1231 } else { // if it's root bond it has to broken (otherwise we would not create the fragments) 1232 #ifdef ADDHYDROGEN 1233 if(!Mol->AddHydrogenReplacementAtom(out, Binder, AddedAtomList[Walker->nr], Walker, OtherAtom, IsAngstroem)) 1234 exit(1); 1235 #endif 1236 } 1237 } 1238 } 1239 ; 972 1240 973 1241 /** Adds atoms up to \a BondCount distance from \a *Root and notes them down in \a **AddedAtomList. … … 985 1253 void molecule::BreadthFirstSearchAdd(ofstream *out, molecule *Mol, atom **&AddedAtomList, bond **&AddedBondList, atom *Root, bond *Bond, int BondOrder, bool IsAngstroem) 986 1254 { 987 atom **PredecessorList = Malloc<atom*>(AtomCount, "molecule::BreadthFirstSearchAdd: **PredecessorList"); 988 int *ShortestPathList = Malloc<int>(AtomCount, "molecule::BreadthFirstSearchAdd: *ShortestPathList"); 989 enum Shading *ColorList = Malloc<enum Shading>(AtomCount, "molecule::BreadthFirstSearchAdd: *ColorList"); 990 class StackClass<atom *> *AtomStack = new StackClass<atom *>(AtomCount); 1255 struct BFSAccounting BFS; 991 1256 atom *Walker = NULL, *OtherAtom = NULL; 992 1257 bond *Binder = NULL; 993 1258 994 1259 // add Root if not done yet 995 AtomStack->ClearStack(); 996 if (AddedAtomList[Root->nr] == NULL) // add Root if not yet present 1260 if (AddedAtomList[Root->nr] == NULL) // add Root if not yet present 997 1261 AddedAtomList[Root->nr] = Mol->AddCopyAtom(Root); 998 AtomStack->Push(Root); 999 1000 // initialise each vertex as white with no predecessor, empty queue, color Root lightgray 1001 for (int i=AtomCount;i--;) { 1002 PredecessorList[i] = NULL; 1003 ShortestPathList[i] = -1; 1004 if (AddedAtomList[i] != NULL) // mark already present atoms (i.e. Root and maybe others) as visited 1005 ColorList[i] = lightgray; 1006 else 1007 ColorList[i] = white; 1008 } 1009 ShortestPathList[Root->nr] = 0; 1262 1263 BreadthFirstSearchAdd_Init(BFS, Root, BondOrder, AtomCount, AddedAtomList); 1010 1264 1011 1265 // and go on ... Queue always contains all lightgray vertices 1012 while (! AtomStack->IsEmpty()) {1266 while (!BFS.BFSStack->IsEmpty()) { 1013 1267 // we have to pop the oldest atom from stack. This keeps the atoms on the stack always of the same ShortestPath distance. 1014 1268 // e.g. if current atom is 2, push to end of stack are of length 3, but first all of length 2 would be popped. They again 1015 1269 // append length of 3 (their neighbours). Thus on stack we have always atoms of a certain length n at bottom of stack and 1016 1270 // followed by n+1 till top of stack. 1017 Walker = AtomStack->PopFirst(); // pop oldest added 1018 *out << Verbose(1) << "Current Walker is: " << Walker->Name << ", and has " << NumberOfBondsPerAtom[Walker->nr] << " bonds." << endl; 1019 for(int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++) { 1020 Binder = ListOfBondsPerAtom[Walker->nr][i]; 1021 if (Binder != NULL) { // don't look at bond equal NULL 1022 OtherAtom = Binder->GetOtherAtom(Walker); 1023 *out << Verbose(2) << "Current OtherAtom is: " << OtherAtom->Name << " for bond " << *Binder << "." << endl; 1024 if (ColorList[OtherAtom->nr] == white) { 1025 if (Binder != Bond) // let other atom white if it's via Root bond. In case it's cyclic it has to be reached again (yet Root is from OtherAtom already black, thus no problem) 1026 ColorList[OtherAtom->nr] = lightgray; 1027 PredecessorList[OtherAtom->nr] = Walker; // Walker is the predecessor 1028 ShortestPathList[OtherAtom->nr] = ShortestPathList[Walker->nr]+1; 1029 *out << Verbose(2) << "Coloring OtherAtom " << OtherAtom->Name << " " << ((ColorList[OtherAtom->nr] == white) ? "white" : "lightgray") << ", its predecessor is " << Walker->Name << " and its Shortest Path is " << ShortestPathList[OtherAtom->nr] << " egde(s) long." << endl; 1030 if ((((ShortestPathList[OtherAtom->nr] < BondOrder) && (Binder != Bond))) ) { // Check for maximum distance 1031 *out << Verbose(3); 1032 if (AddedAtomList[OtherAtom->nr] == NULL) { // add if it's not been so far 1033 AddedAtomList[OtherAtom->nr] = Mol->AddCopyAtom(OtherAtom); 1034 *out << "Added OtherAtom " << OtherAtom->Name; 1035 AddedBondList[Binder->nr] = Mol->AddBond(AddedAtomList[Walker->nr], AddedAtomList[OtherAtom->nr], Binder->BondDegree); 1036 AddedBondList[Binder->nr]->Cyclic = Binder->Cyclic; 1037 AddedBondList[Binder->nr]->Type = Binder->Type; 1038 *out << " and bond " << *(AddedBondList[Binder->nr]) << ", "; 1039 } else { // this code should actually never come into play (all white atoms are not yet present in BondMolecule, that's why they are white in the first place) 1040 *out << "Not adding OtherAtom " << OtherAtom->Name; 1041 if (AddedBondList[Binder->nr] == NULL) { 1042 AddedBondList[Binder->nr] = Mol->AddBond(AddedAtomList[Walker->nr], AddedAtomList[OtherAtom->nr], Binder->BondDegree); 1043 AddedBondList[Binder->nr]->Cyclic = Binder->Cyclic; 1044 AddedBondList[Binder->nr]->Type = Binder->Type; 1045 *out << ", added Bond " << *(AddedBondList[Binder->nr]); 1046 } else 1047 *out << ", not added Bond "; 1048 } 1049 *out << ", putting OtherAtom into queue." << endl; 1050 AtomStack->Push(OtherAtom); 1051 } else { // out of bond order, then replace 1052 if ((AddedAtomList[OtherAtom->nr] == NULL) && (Binder->Cyclic)) 1053 ColorList[OtherAtom->nr] = white; // unmark if it has not been queued/added, to make it available via its other bonds (cyclic) 1054 if (Binder == Bond) 1055 *out << Verbose(3) << "Not Queueing, is the Root bond"; 1056 else if (ShortestPathList[OtherAtom->nr] >= BondOrder) 1057 *out << Verbose(3) << "Not Queueing, is out of Bond Count of " << BondOrder; 1058 if (!Binder->Cyclic) 1059 *out << ", is not part of a cyclic bond, saturating bond with Hydrogen." << endl; 1060 if (AddedBondList[Binder->nr] == NULL) { 1061 if ((AddedAtomList[OtherAtom->nr] != NULL)) { // .. whether we add or saturate 1062 AddedBondList[Binder->nr] = Mol->AddBond(AddedAtomList[Walker->nr], AddedAtomList[OtherAtom->nr], Binder->BondDegree); 1063 AddedBondList[Binder->nr]->Cyclic = Binder->Cyclic; 1064 AddedBondList[Binder->nr]->Type = Binder->Type; 1065 } else { 1066 #ifdef ADDHYDROGEN 1067 if (!Mol->AddHydrogenReplacementAtom(out, Binder, AddedAtomList[Walker->nr], Walker, OtherAtom, ListOfBondsPerAtom[Walker->nr], NumberOfBondsPerAtom[Walker->nr], IsAngstroem)) 1068 exit(1); 1069 #endif 1070 } 1071 } 1072 } 1271 Walker = BFS.BFSStack->PopFirst(); // pop oldest added 1272 *out << Verbose(1) << "Current Walker is: " << Walker->Name << ", and has " << Walker->ListOfBonds.size() << " bonds." << endl; 1273 for (BondList::const_iterator Runner = Walker->ListOfBonds.begin(); Runner != Walker->ListOfBonds.end(); (++Runner)) { 1274 if ((*Runner) != NULL) { // don't look at bond equal NULL 1275 Binder = (*Runner); 1276 OtherAtom = (*Runner)->GetOtherAtom(Walker); 1277 *out << Verbose(2) << "Current OtherAtom is: " << OtherAtom->Name << " for bond " << *(*Runner) << "." << endl; 1278 if (BFS.ColorList[OtherAtom->nr] == white) { 1279 BreadthFirstSearchAdd_UnvisitedNode(out, Mol, BFS, Walker, OtherAtom, Binder, Bond, AddedAtomList, AddedBondList, IsAngstroem); 1073 1280 } else { 1074 *out << Verbose(3) << "Not Adding, has already been visited." << endl; 1075 // This has to be a cyclic bond, check whether it's present ... 1076 if (AddedBondList[Binder->nr] == NULL) { 1077 if ((Binder != Bond) && (Binder->Cyclic) && (((ShortestPathList[Walker->nr]+1) < BondOrder))) { 1078 AddedBondList[Binder->nr] = Mol->AddBond(AddedAtomList[Walker->nr], AddedAtomList[OtherAtom->nr], Binder->BondDegree); 1079 AddedBondList[Binder->nr]->Cyclic = Binder->Cyclic; 1080 AddedBondList[Binder->nr]->Type = Binder->Type; 1081 } else { // if it's root bond it has to broken (otherwise we would not create the fragments) 1082 #ifdef ADDHYDROGEN 1083 if(!Mol->AddHydrogenReplacementAtom(out, Binder, AddedAtomList[Walker->nr], Walker, OtherAtom, ListOfBondsPerAtom[Walker->nr], NumberOfBondsPerAtom[Walker->nr], IsAngstroem)) 1084 exit(1); 1085 #endif 1086 } 1087 } 1281 BreadthFirstSearchAdd_VisitedNode(out, Mol, BFS, Walker, OtherAtom, Binder, Bond, AddedAtomList, AddedBondList, IsAngstroem); 1088 1282 } 1089 1283 } 1090 1284 } 1091 ColorList[Walker->nr] = black;1285 BFS.ColorList[Walker->nr] = black; 1092 1286 *out << Verbose(1) << "Coloring Walker " << Walker->Name << " black." << endl; 1093 1287 } 1094 Free(&PredecessorList); 1095 Free(&ShortestPathList); 1096 Free(&ColorList); 1097 delete(AtomStack); 1098 }; 1099 1100 /** Adds bond structure to this molecule from \a Father molecule. 1101 * This basically causes this molecule to become an induced subgraph of the \a Father, i.e. for every bond in Father 1102 * with end points present in this molecule, bond is created in this molecule. 1103 * Special care was taken to ensure that this is of complexity O(N), where N is the \a Father's molecule::AtomCount. 1104 * \param *out output stream for debugging 1105 * \param *Father father molecule 1106 * \return true - is induced subgraph, false - there are atoms with fathers not in \a Father 1107 * \todo not checked, not fully working probably 1108 */ 1109 bool molecule::BuildInducedSubgraph(ofstream *out, const molecule *Father) 1110 { 1111 atom *Walker = NULL, *OtherAtom = NULL; 1112 bool status = true; 1113 atom **ParentList = Malloc<atom*>(Father->AtomCount, "molecule::BuildInducedSubgraph: **ParentList"); 1114 1115 *out << Verbose(2) << "Begin of BuildInducedSubgraph." << endl; 1116 1288 BreadthFirstSearchAdd_Free(BFS); 1289 } 1290 ; 1291 1292 /** Adds a bond as a copy to a given one 1293 * \param *left leftatom of new bond 1294 * \param *right rightatom of new bond 1295 * \param *CopyBond rest of fields in bond are copied from this 1296 * \return pointer to new bond 1297 */ 1298 bond * molecule::CopyBond(atom *left, atom *right, bond *CopyBond) 1299 { 1300 bond *Binder = AddBond(left, right, CopyBond->BondDegree); 1301 Binder->Cyclic = CopyBond->Cyclic; 1302 Binder->Type = CopyBond->Type; 1303 return Binder; 1304 } 1305 ; 1306 1307 void BuildInducedSubgraph_Init(ofstream *out, atom **&ParentList, int AtomCount) 1308 { 1117 1309 // reset parent list 1310 ParentList = Calloc<atom*> (AtomCount, "molecule::BuildInducedSubgraph_Init: **ParentList"); 1118 1311 *out << Verbose(3) << "Resetting ParentList." << endl; 1119 for (int i=Father->AtomCount;i--;) 1120 ParentList[i] = NULL; 1121 1312 } 1313 ; 1314 1315 void BuildInducedSubgraph_FillParentList(ofstream *out, const molecule *mol, const molecule *Father, atom **&ParentList) 1316 { 1122 1317 // fill parent list with sons 1123 1318 *out << Verbose(3) << "Filling Parent List." << endl; 1124 Walker =start;1125 while (Walker->next != end) {1319 atom *Walker = mol->start; 1320 while (Walker->next != mol->end) { 1126 1321 Walker = Walker->next; 1127 1322 ParentList[Walker->father->nr] = Walker; 1128 1323 // Outputting List for debugging 1129 *out << Verbose(4) << "Son["<< Walker->father->nr <<"] of " << Walker->father << " is " << ParentList[Walker->father->nr] << "." << endl; 1130 } 1131 1324 *out << Verbose(4) << "Son[" << Walker->father->nr << "] of " << Walker->father << " is " << ParentList[Walker->father->nr] << "." << endl; 1325 } 1326 1327 } 1328 ; 1329 1330 void BuildInducedSubgraph_Finalize(ofstream *out, atom **&ParentList) 1331 { 1332 Free(&ParentList); 1333 } 1334 ; 1335 1336 bool BuildInducedSubgraph_CreateBondsFromParent(ofstream *out, molecule *mol, const molecule *Father, atom **&ParentList) 1337 { 1338 bool status = true; 1339 atom *Walker = NULL; 1340 atom *OtherAtom = NULL; 1132 1341 // check each entry of parent list and if ok (one-to-and-onto matching) create bonds 1133 1342 *out << Verbose(3) << "Creating bonds." << endl; … … 1139 1348 status = false; 1140 1349 } else { 1141 for ( int i=0;i<Father->NumberOfBondsPerAtom[Walker->nr];i++) {1142 OtherAtom = Father->ListOfBondsPerAtom[Walker->nr][i]->GetOtherAtom(Walker);1350 for (BondList::const_iterator Runner = Walker->ListOfBonds.begin(); Runner != Walker->ListOfBonds.end(); (++Runner)) { 1351 OtherAtom = (*Runner)->GetOtherAtom(Walker); 1143 1352 if (ParentList[OtherAtom->nr] != NULL) { // if otheratom is also a father of an atom on this molecule, create the bond 1144 *out << Verbose(4) << "Endpoints of Bond " << Father->ListOfBondsPerAtom[Walker->nr][i]<< " are both present: " << ParentList[Walker->nr]->Name << " and " << ParentList[OtherAtom->nr]->Name << "." << endl;1145 AddBond(ParentList[Walker->nr], ParentList[OtherAtom->nr], Father->ListOfBondsPerAtom[Walker->nr][i]->BondDegree);1353 *out << Verbose(4) << "Endpoints of Bond " << (*Runner) << " are both present: " << ParentList[Walker->nr]->Name << " and " << ParentList[OtherAtom->nr]->Name << "." << endl; 1354 mol->AddBond(ParentList[Walker->nr], ParentList[OtherAtom->nr], (*Runner)->BondDegree); 1146 1355 } 1147 1356 } … … 1149 1358 } 1150 1359 } 1151 1152 Free(&ParentList); 1360 return status; 1361 } 1362 ; 1363 1364 /** Adds bond structure to this molecule from \a Father molecule. 1365 * This basically causes this molecule to become an induced subgraph of the \a Father, i.e. for every bond in Father 1366 * with end points present in this molecule, bond is created in this molecule. 1367 * Special care was taken to ensure that this is of complexity O(N), where N is the \a Father's molecule::AtomCount. 1368 * \param *out output stream for debugging 1369 * \param *Father father molecule 1370 * \return true - is induced subgraph, false - there are atoms with fathers not in \a Father 1371 * \todo not checked, not fully working probably 1372 */ 1373 bool molecule::BuildInducedSubgraph(ofstream *out, const molecule *Father) 1374 { 1375 bool status = true; 1376 atom **ParentList = NULL; 1377 1378 *out << Verbose(2) << "Begin of BuildInducedSubgraph." << endl; 1379 BuildInducedSubgraph_Init(out, ParentList, Father->AtomCount); 1380 BuildInducedSubgraph_FillParentList(out, this, Father, ParentList); 1381 status = BuildInducedSubgraph_CreateBondsFromParent(out, this, Father, ParentList); 1382 BuildInducedSubgraph_Finalize(out, ParentList); 1153 1383 *out << Verbose(2) << "End of BuildInducedSubgraph." << endl; 1154 1384 return status; 1155 } ;1156 1385 } 1386 ; 1157 1387 1158 1388 /** For a given keyset \a *Fragment, checks whether it is connected in the current molecule. … … 1173 1403 // count number of atoms in graph 1174 1404 size = 0; 1175 for (KeySet::iterator runner = Fragment->begin(); runner != Fragment->end(); runner++)1405 for (KeySet::iterator runner = Fragment->begin(); runner != Fragment->end(); runner++) 1176 1406 size++; 1177 1407 if (size > 1) 1178 for (KeySet::iterator runner = Fragment->begin(); runner != Fragment->end(); runner++) {1408 for (KeySet::iterator runner = Fragment->begin(); runner != Fragment->end(); runner++) { 1179 1409 Walker = FindAtom(*runner); 1180 1410 BondStatus = false; 1181 for (KeySet::iterator runners = Fragment->begin(); runners != Fragment->end(); runners++) {1411 for (KeySet::iterator runners = Fragment->begin(); runners != Fragment->end(); runners++) { 1182 1412 Walker2 = FindAtom(*runners); 1183 for ( int i=0;i<NumberOfBondsPerAtom[Walker->nr]; i++) {1184 if ( ListOfBondsPerAtom[Walker->nr][i]->GetOtherAtom(Walker) == Walker2) {1413 for (BondList::const_iterator Runner = Walker->ListOfBonds.begin(); Runner != Walker->ListOfBonds.end(); (++Runner)) { 1414 if ((*Runner)->GetOtherAtom(Walker) == Walker2) { 1185 1415 BondStatus = true; 1186 1416 break; -
src/molecule_pointcloud.cpp
r06c7a3 r7326b2 18 18 * \return pointer to allocated with central coordinates 19 19 */ 20 Vector *molecule::GetCenter(ofstream *out) 20 Vector *molecule::GetCenter(ofstream *out) const 21 21 { 22 22 Vector *center = DetermineCenterOfAll(out); … … 27 27 * \return pointer to atom or NULL if none present 28 28 */ 29 TesselPoint *molecule::GetPoint() 29 TesselPoint *molecule::GetPoint() const 30 30 { 31 31 if ((InternalPointer != start) && (InternalPointer != end)) … … 38 38 * \return pointer to end marker 39 39 */ 40 TesselPoint *molecule::GetTerminalPoint() 40 TesselPoint *molecule::GetTerminalPoint() const 41 41 { 42 42 return end; … … 46 46 * Stops at last one. 47 47 */ 48 void molecule::GoToNext() 48 void molecule::GoToNext() const 49 49 { 50 50 if (InternalPointer != end) … … 55 55 * Stops at first one. 56 56 */ 57 void molecule::GoToPrevious() 57 void molecule::GoToPrevious() const 58 58 { 59 59 if (InternalPointer->previous != start) … … 63 63 /** Goes to first atom. 64 64 */ 65 void molecule::GoToFirst() 65 void molecule::GoToFirst() const 66 66 { 67 67 InternalPointer = start->next; … … 70 70 /** Goes to last atom. 71 71 */ 72 void molecule::GoToLast() 72 void molecule::GoToLast() const 73 73 { 74 74 InternalPointer = end->previous; … … 78 78 * \return true - no atoms, false - not empty 79 79 */ 80 bool molecule::IsEmpty() 80 bool molecule::IsEmpty() const 81 81 { 82 82 return (start->next == end); … … 86 86 * \return true - current atom is last one, false - is not last one 87 87 */ 88 bool molecule::IsEnd() 88 bool molecule::IsEnd() const 89 89 { 90 90 return (InternalPointer == end); -
src/molecule_template.hpp
r06c7a3 r7326b2 21 21 22 22 // zero arguments 23 template <typename res> void molecule::ActOnAllVectors( res (Vector::*f)() )24 {25 atom *Walker = start;26 while (Walker->next != end) {27 Walker = Walker->next;28 ((Walker->node)->*f)();29 }30 };31 template <typename res> void molecule::ActOnAllVectors( res (Vector::*f)() const )32 {33 atom *Walker = start;34 while (Walker->next != end) {35 Walker = Walker->next;36 ((Walker->node)->*f)();37 }38 };39 23 template <typename res> void molecule::ActOnAllVectors( res (Vector::*f)() ) const 40 24 { … … 54 38 }; 55 39 // one argument 56 template <typename res, typename T> void molecule::ActOnAllVectors( res (Vector::*f)(T), T t ) 40 template <typename res, typename T> void molecule::ActOnAllVectors( res (Vector::*f)(T), T t ) const 57 41 { 58 42 atom *Walker = start; … … 62 46 } 63 47 }; 64 template <typename res, typename T> void molecule::ActOnAllVectors( res (Vector::*f)(T) const, T t ) 48 template <typename res, typename T> void molecule::ActOnAllVectors( res (Vector::*f)(T) const, T t ) const 65 49 { 66 50 atom *Walker = start; … … 70 54 } 71 55 }; 72 template <typename res, typename T> void molecule::ActOnAllVectors( res (Vector::*f)(T), T t ) const73 {74 atom *Walker = start;75 while (Walker->next != end) {76 Walker = Walker->next;77 ((Walker->node)->*f)(t);78 }79 };80 template <typename res, typename T> void molecule::ActOnAllVectors( res (Vector::*f)(T) const, T t ) const81 {82 atom *Walker = start;83 while (Walker->next != end) {84 Walker = Walker->next;85 ((Walker->node)->*f)(t);86 }87 };88 56 // two arguments 89 template <typename res, typename T, typename U> void molecule::ActOnAllVectors( res (Vector::*f)(T, U), T t, U u ) 57 template <typename res, typename T, typename U> void molecule::ActOnAllVectors( res (Vector::*f)(T, U), T t, U u ) const 90 58 { 91 59 atom *Walker = start; … … 95 63 } 96 64 }; 97 template <typename res, typename T, typename U> void molecule::ActOnAllVectors( res (Vector::*f)(T, U) const, T t, U u ) 65 template <typename res, typename T, typename U> void molecule::ActOnAllVectors( res (Vector::*f)(T, U) const, T t, U u ) const 98 66 { 99 67 atom *Walker = start; … … 103 71 } 104 72 }; 105 template <typename res, typename T, typename U> void molecule::ActOnAllVectors( res (Vector::*f)(T, U), T t, U u ) const106 {107 atom *Walker = start;108 while (Walker->next != end) {109 Walker = Walker->next;110 ((Walker->node)->*f)(t, u);111 }112 };113 template <typename res, typename T, typename U> void molecule::ActOnAllVectors( res (Vector::*f)(T, U) const, T t, U u ) const114 {115 atom *Walker = start;116 while (Walker->next != end) {117 Walker = Walker->next;118 ((Walker->node)->*f)(t, u);119 }120 };121 73 // three arguments 122 template <typename res, typename T, typename U, typename V> void molecule::ActOnAllVectors( res (Vector::*f)(T, U, V), T t, U u, V v) 74 template <typename res, typename T, typename U, typename V> void molecule::ActOnAllVectors( res (Vector::*f)(T, U, V), T t, U u, V v) const 123 75 { 124 76 atom *Walker = start; … … 128 80 } 129 81 }; 130 template <typename res, typename T, typename U, typename V> void molecule::ActOnAllVectors( res (Vector::*f)(T, U, V) const, T t, U u, V v) 82 template <typename res, typename T, typename U, typename V> void molecule::ActOnAllVectors( res (Vector::*f)(T, U, V) const, T t, U u, V v) const 131 83 { 132 84 atom *Walker = start; … … 136 88 } 137 89 }; 138 template <typename res, typename T, typename U, typename V> void molecule::ActOnAllVectors( res (Vector::*f)(T, U, V), T t, U u, V v) const 139 { 140 atom *Walker = start; 141 while (Walker->next != end) { 142 Walker = Walker->next; 143 ((Walker->node)->*f)(t, u, v); 144 } 145 }; 146 template <typename res, typename T, typename U, typename V> void molecule::ActOnAllVectors( res (Vector::*f)(T, U, V) const, T t, U u, V v) const 147 { 148 atom *Walker = start; 149 while (Walker->next != end) { 150 Walker = Walker->next; 151 ((Walker->node)->*f)(t, u, v); 152 } 153 }; 90 91 // ========================= Summing over each Atoms =================================== // 92 93 // zero arguments 94 template <typename res, typename typ> res molecule::SumPerAtom(res (typ::*f)() ) const 95 { 96 res result = 0; 97 atom *Walker = start; 98 while (Walker->next != end) { 99 Walker = Walker->next; 100 result += (Walker->*f)(); 101 } 102 return result; 103 }; 104 template <typename res, typename typ> res molecule::SumPerAtom(res (typ::*f)() const ) const 105 { 106 res result = 0; 107 atom *Walker = start; 108 while (Walker->next != end) { 109 Walker = Walker->next; 110 result += (Walker->*f)(); 111 } 112 return result; 113 }; 114 // one argument 115 template <typename res, typename typ, typename T> res molecule::SumPerAtom(res (typ::*f)(T), T t ) const 116 { 117 res result = 0; 118 atom *Walker = start; 119 while (Walker->next != end) { 120 Walker = Walker->next; 121 result += (Walker->*f)(t); 122 } 123 return result; 124 }; 125 template <typename res, typename typ, typename T> res molecule::SumPerAtom(res (typ::*f)(T) const, T t ) const 126 { 127 res result = 0; 128 atom *Walker = start; 129 while (Walker->next != end) { 130 Walker = Walker->next; 131 result += (Walker->*f)(t); 132 } 133 return result; 134 }; 135 154 136 155 137 // ================== Acting with each Atoms on same molecule ========================== // 156 138 157 139 // zero arguments 158 template <typename res> void molecule::ActWithEachAtom( res (molecule::*f)(atom *)) 140 template <typename res> void molecule::ActWithEachAtom( res (molecule::*f)(atom *)) const 159 141 { 160 142 atom *Walker = start; … … 164 146 } 165 147 }; 166 template <typename res> void molecule::ActWithEachAtom( res (molecule::*f)(atom *) const) 148 template <typename res> void molecule::ActWithEachAtom( res (molecule::*f)(atom *) const) const 167 149 { 168 150 atom *Walker = start; … … 172 154 } 173 155 }; 174 template <typename res> void molecule::ActWithEachAtom( res (molecule::*f)(atom *)) const175 {176 atom *Walker = start;177 while (Walker->next != end) {178 Walker = Walker->next;179 (*f)(Walker);180 }181 };182 template <typename res> void molecule::ActWithEachAtom( res (molecule::*f)(atom *) const) const183 {184 atom *Walker = start;185 while (Walker->next != end) {186 Walker = Walker->next;187 (*f)(Walker);188 }189 };190 156 191 157 // ================== Acting with each Atoms on copy molecule ========================== // 192 158 193 159 // zero arguments 194 template <typename res> void molecule::ActOnCopyWithEachAtom( res (molecule::*f)(atom *) , molecule *copy) 160 template <typename res> void molecule::ActOnCopyWithEachAtom( res (molecule::*f)(atom *) , molecule *copy) const 195 161 { 196 162 atom *Walker = start; … … 200 166 } 201 167 }; 202 template <typename res> void molecule::ActOnCopyWithEachAtom( res (molecule::*f)(atom *) const , molecule *copy)168 template <typename res> void molecule::ActOnCopyWithEachAtom( res (molecule::*f)(atom *) const, molecule *copy) const 203 169 { 204 170 atom *Walker = start; … … 208 174 } 209 175 }; 210 template <typename res> void molecule::ActOnCopyWithEachAtom( res (molecule::*f)(atom *) , molecule *copy) const211 {212 atom *Walker = start;213 while (Walker->next != end) {214 Walker = Walker->next;215 (copy->*f)(Walker);216 }217 };218 template <typename res> void molecule::ActOnCopyWithEachAtom( res (molecule::*f)(atom *) const, molecule *copy) const219 {220 atom *Walker = start;221 while (Walker->next != end) {222 Walker = Walker->next;223 (copy->*f)(Walker);224 }225 };226 176 227 177 // ================== Acting with each Atoms on copy molecule if true ========================== // 228 178 229 179 // zero arguments 230 template <typename res> void molecule::ActOnCopyWithEachAtomIfTrue( res (molecule::*f)(atom *) , molecule *copy, bool (atom::*condition) () ) 180 template <typename res> void molecule::ActOnCopyWithEachAtomIfTrue( res (molecule::*f)(atom *) , molecule *copy, bool (atom::*condition) () ) const 231 181 { 232 182 atom *Walker = start; … … 237 187 } 238 188 }; 189 template <typename res> void molecule::ActOnCopyWithEachAtomIfTrue( res (molecule::*f)(atom *) , molecule *copy, bool (atom::*condition) () const ) const 190 { 191 atom *Walker = start; 192 while (Walker->next != end) { 193 Walker = Walker->next; 194 if ((Walker->*condition)()) 195 (copy->*f)(Walker); 196 } 197 }; 198 template <typename res> void molecule::ActOnCopyWithEachAtomIfTrue( res (molecule::*f)(atom *) const , molecule *copy, bool (atom::*condition) () ) const 199 { 200 atom *Walker = start; 201 while (Walker->next != end) { 202 Walker = Walker->next; 203 if ((Walker->*condition)()) 204 (copy->*f)(Walker); 205 } 206 }; 207 template <typename res> void molecule::ActOnCopyWithEachAtomIfTrue( res (molecule::*f)(atom *) const, molecule *copy, bool (atom::*condition) () const ) const 208 { 209 atom *Walker = start; 210 while (Walker->next != end) { 211 Walker = Walker->next; 212 if ((Walker->*condition)()) 213 (copy->*f)(Walker); 214 } 215 }; 239 216 // one argument 240 template <typename res, typename T> void molecule::ActOnCopyWithEachAtomIfTrue( res (molecule::*f)(atom *) , molecule *copy, bool (atom::*condition) (T), T t ) 217 template <typename res, typename T> void molecule::ActOnCopyWithEachAtomIfTrue( res (molecule::*f)(atom *) , molecule *copy, bool (atom::*condition) (T), T t ) const 241 218 { 242 219 atom *Walker = start; … … 247 224 } 248 225 }; 226 template <typename res, typename T> void molecule::ActOnCopyWithEachAtomIfTrue( res (molecule::*f)(atom *) , molecule *copy, bool (atom::*condition) (T) const, T t ) const 227 { 228 atom *Walker = start; 229 while (Walker->next != end) { 230 Walker = Walker->next; 231 if ((Walker->*condition)(t)) 232 (copy->*f)(Walker); 233 } 234 }; 235 template <typename res, typename T> void molecule::ActOnCopyWithEachAtomIfTrue( res (molecule::*f)(atom *) const, molecule *copy, bool (atom::*condition) (T), T t ) const 236 { 237 atom *Walker = start; 238 while (Walker->next != end) { 239 Walker = Walker->next; 240 if ((Walker->*condition)(t)) 241 (copy->*f)(Walker); 242 } 243 }; 244 template <typename res, typename T> void molecule::ActOnCopyWithEachAtomIfTrue( res (molecule::*f)(atom *) const, molecule *copy, bool (atom::*condition) (T) const, T t ) const 245 { 246 atom *Walker = start; 247 while (Walker->next != end) { 248 Walker = Walker->next; 249 if ((Walker->*condition)(t)) 250 (copy->*f)(Walker); 251 } 252 }; 249 253 // two arguments 250 template <typename res, typename T, typename U> void molecule::ActOnCopyWithEachAtomIfTrue( res (molecule::*f)(atom *) , molecule *copy, bool (atom::*condition) (T, U), T t, U u ) 254 template <typename res, typename T, typename U> void molecule::ActOnCopyWithEachAtomIfTrue( res (molecule::*f)(atom *) , molecule *copy, bool (atom::*condition) (T, U), T t, U u ) const 251 255 { 252 256 atom *Walker = start; … … 257 261 } 258 262 }; 263 template <typename res, typename T, typename U> void molecule::ActOnCopyWithEachAtomIfTrue( res (molecule::*f)(atom *) , molecule *copy, bool (atom::*condition) (T, U) const, T t, U u ) const 264 { 265 atom *Walker = start; 266 while (Walker->next != end) { 267 Walker = Walker->next; 268 if ((Walker->*condition)(t,u)) 269 (copy->*f)(Walker); 270 } 271 }; 272 template <typename res, typename T, typename U> void molecule::ActOnCopyWithEachAtomIfTrue( res (molecule::*f)(atom *) const, molecule *copy, bool (atom::*condition) (T, U), T t, U u ) const 273 { 274 atom *Walker = start; 275 while (Walker->next != end) { 276 Walker = Walker->next; 277 if ((Walker->*condition)(t,u)) 278 (copy->*f)(Walker); 279 } 280 }; 281 template <typename res, typename T, typename U> void molecule::ActOnCopyWithEachAtomIfTrue( res (molecule::*f)(atom *) const, molecule *copy, bool (atom::*condition) (T, U) const, T t, U u ) const 282 { 283 atom *Walker = start; 284 while (Walker->next != end) { 285 Walker = Walker->next; 286 if ((Walker->*condition)(t,u)) 287 (copy->*f)(Walker); 288 } 289 }; 259 290 // three arguments 260 template <typename res, typename T, typename U, typename V> void molecule::ActOnCopyWithEachAtomIfTrue( res (molecule::*f)(atom *) , molecule *copy, bool (atom::*condition) (T, U, V), T t, U u, V v ) 291 template <typename res, typename T, typename U, typename V> void molecule::ActOnCopyWithEachAtomIfTrue( res (molecule::*f)(atom *) , molecule *copy, bool (atom::*condition) (T, U, V), T t, U u, V v ) const 261 292 { 262 293 atom *Walker = start; … … 267 298 } 268 299 }; 300 template <typename res, typename T, typename U, typename V> void molecule::ActOnCopyWithEachAtomIfTrue( res (molecule::*f)(atom *) , molecule *copy, bool (atom::*condition) (T, U, V) const, T t, U u, V v ) const 301 { 302 atom *Walker = start; 303 while (Walker->next != end) { 304 Walker = Walker->next; 305 if ((Walker->*condition)(t,u,v)) 306 (copy->*f)(Walker); 307 } 308 }; 309 template <typename res, typename T, typename U, typename V> void molecule::ActOnCopyWithEachAtomIfTrue( res (molecule::*f)(atom *) const, molecule *copy, bool (atom::*condition) (T, U, V), T t, U u, V v ) const 310 { 311 atom *Walker = start; 312 while (Walker->next != end) { 313 Walker = Walker->next; 314 if ((Walker->*condition)(t,u,v)) 315 (copy->*f)(Walker); 316 } 317 }; 318 template <typename res, typename T, typename U, typename V> void molecule::ActOnCopyWithEachAtomIfTrue( res (molecule::*f)(atom *) const, molecule *copy, bool (atom::*condition) (T, U, V) const, T t, U u, V v ) const 319 { 320 atom *Walker = start; 321 while (Walker->next != end) { 322 Walker = Walker->next; 323 if ((Walker->*condition)(t,u,v)) 324 (copy->*f)(Walker); 325 } 326 }; 269 327 270 328 // ================== Acting on all Atoms ========================== // 271 329 272 330 // zero arguments 273 template <typename res > void molecule::ActOnAllAtoms( res (atom::*f)())331 template <typename res, typename typ> void molecule::ActOnAllAtoms( res (typ::*f)()) const 274 332 { 275 333 atom *Walker = start; … … 279 337 } 280 338 }; 281 template <typename res > void molecule::ActOnAllAtoms( res (atom::*f)() const)339 template <typename res, typename typ> void molecule::ActOnAllAtoms( res (typ::*f)() const) const 282 340 { 283 341 atom *Walker = start; … … 287 345 } 288 346 }; 289 template <typename res> void molecule::ActOnAllAtoms( res (atom::*f)()) const290 {291 atom *Walker = start;292 while (Walker->next != end) {293 Walker = Walker->next;294 (Walker->*f)();295 }296 };297 template <typename res> void molecule::ActOnAllAtoms( res (atom::*f)() const) const298 {299 atom *Walker = start;300 while (Walker->next != end) {301 Walker = Walker->next;302 (Walker->*f)();303 }304 };305 347 // one argument 306 template <typename res, typename T> void molecule::ActOnAllAtoms( res (atom::*f)(T), T t )348 template <typename res, typename typ, typename T> void molecule::ActOnAllAtoms( res (typ::*f)(T), T t ) const 307 349 { 308 350 atom *Walker = start; … … 312 354 } 313 355 }; 314 template <typename res, typename T> void molecule::ActOnAllAtoms( res (atom::*f)(T) const, T t )356 template <typename res, typename typ, typename T> void molecule::ActOnAllAtoms( res (typ::*f)(T) const, T t ) const 315 357 { 316 358 atom *Walker = start; … … 320 362 } 321 363 }; 322 template <typename res, typename T> void molecule::ActOnAllAtoms( res (atom::*f)(T), T t ) const323 {324 atom *Walker = start;325 while (Walker->next != end) {326 Walker = Walker->next;327 (Walker->*f)(t);328 }329 };330 template <typename res, typename T> void molecule::ActOnAllAtoms( res (atom::*f)(T) const, T t ) const331 {332 atom *Walker = start;333 while (Walker->next != end) {334 Walker = Walker->next;335 (Walker->*f)(t);336 }337 };338 364 // two argument 339 template <typename res, typename T, typename U> void molecule::ActOnAllAtoms( res (atom::*f)(T, U), T t, U u )365 template <typename res, typename typ, typename T, typename U> void molecule::ActOnAllAtoms( res (typ::*f)(T, U), T t, U u ) const 340 366 { 341 367 atom *Walker = start; … … 345 371 } 346 372 }; 347 template <typename res, typename T, typename U> void molecule::ActOnAllAtoms( res (atom::*f)(T, U) const, T t, U u )373 template <typename res, typename typ, typename T, typename U> void molecule::ActOnAllAtoms( res (typ::*f)(T, U) const, T t, U u ) const 348 374 { 349 375 atom *Walker = start; … … 353 379 } 354 380 }; 355 template <typename res, typename T, typename U> void molecule::ActOnAllAtoms( res (atom::*f)(T, U), T t, U u ) const356 {357 atom *Walker = start;358 while (Walker->next != end) {359 Walker = Walker->next;360 (Walker->*f)(t, u);361 }362 };363 template <typename res, typename T, typename U> void molecule::ActOnAllAtoms( res (atom::*f)(T, U) const, T t, U u ) const364 {365 atom *Walker = start;366 while (Walker->next != end) {367 Walker = Walker->next;368 (Walker->*f)(t, u);369 }370 };371 381 // three argument 372 template <typename res, typename T, typename U, typename V> void molecule::ActOnAllAtoms( res (atom::*f)(T, U, V), T t, U u, V v)382 template <typename res, typename typ, typename T, typename U, typename V> void molecule::ActOnAllAtoms( res (typ::*f)(T, U, V), T t, U u, V v) const 373 383 { 374 384 atom *Walker = start; … … 378 388 } 379 389 }; 380 template <typename res, typename T, typename U, typename V> void molecule::ActOnAllAtoms( res (atom::*f)(T, U, V) const, T t, U u, V v)390 template <typename res, typename typ, typename T, typename U, typename V> void molecule::ActOnAllAtoms( res (typ::*f)(T, U, V) const, T t, U u, V v) const 381 391 { 382 392 atom *Walker = start; … … 386 396 } 387 397 }; 388 template <typename res, typename T, typename U, typename V> void molecule::ActOnAllAtoms( res (atom::*f)(T, U, V), T t, U u, V v) const389 {390 atom *Walker = start;391 while (Walker->next != end) {392 Walker = Walker->next;393 (Walker->*f)(t, u, v);394 }395 };396 template <typename res, typename T, typename U, typename V> void molecule::ActOnAllAtoms( res (atom::*f)(T, U, V) const, T t, U u, V v) const397 {398 atom *Walker = start;399 while (Walker->next != end) {400 Walker = Walker->next;401 (Walker->*f)(t, u, v);402 }403 };404 398 // four arguments 405 template <typename res, typename T, typename U, typename V, typename W> void molecule::ActOnAllAtoms( res (atom::*f)(T, U, V, W), T t, U u, V v, W w)399 template <typename res, typename typ, typename T, typename U, typename V, typename W> void molecule::ActOnAllAtoms( res (typ::*f)(T, U, V, W), T t, U u, V v, W w) const 406 400 { 407 401 atom *Walker = start; … … 411 405 } 412 406 }; 413 template <typename res, typename T, typename U, typename V, typename W> void molecule::ActOnAllAtoms( res (atom::*f)(T, U, V, W) const, T t, U u, V v, W w)407 template <typename res, typename typ, typename T, typename U, typename V, typename W> void molecule::ActOnAllAtoms( res (typ::*f)(T, U, V, W) const, T t, U u, V v, W w) const 414 408 { 415 409 atom *Walker = start; … … 419 413 } 420 414 }; 421 template <typename res, typename T, typename U, typename V, typename W> void molecule::ActOnAllAtoms( res (atom::*f)(T, U, V, W), T t, U u, V v, W w) const422 {423 atom *Walker = start;424 while (Walker->next != end) {425 Walker = Walker->next;426 (Walker->*f)(t, u, v, w);427 }428 };429 template <typename res, typename T, typename U, typename V, typename W> void molecule::ActOnAllAtoms( res (atom::*f)(T, U, V, W) const, T t, U u, V v, W w) const430 {431 atom *Walker = start;432 while (Walker->next != end) {433 Walker = Walker->next;434 (Walker->*f)(t, u, v, w);435 }436 };437 415 438 416 // ===================== Accessing arrays indexed by some integer for each atom ====================== 439 417 440 418 // for atom ints 441 template <typename T> void molecule::SetIndexedArrayForEachAtomTo ( T *array, int TesselPoint::*index, void (*Setor)(T *, T *) )419 template <typename T> void molecule::SetIndexedArrayForEachAtomTo ( T *array, int ParticleInfo::*index, void (*Setor)(T *, T *) ) const 442 420 { 443 421 atom *Walker = start; … … 448 426 } 449 427 }; 450 template <typename T> void molecule::SetIndexedArrayForEachAtomTo ( T *array, int TesselPoint::*index, void (*Setor)(T *, T *), T value )428 template <typename T> void molecule::SetIndexedArrayForEachAtomTo ( T *array, int ParticleInfo::*index, void (*Setor)(T *, T *), T value ) const 451 429 { 452 430 atom *Walker = start; … … 456 434 } 457 435 }; 458 template <typename T> void molecule::SetIndexedArrayForEachAtomTo ( T *array, int TesselPoint::*index, void (*Setor)(T *, T *), T *value )436 template <typename T> void molecule::SetIndexedArrayForEachAtomTo ( T *array, int ParticleInfo::*index, void (*Setor)(T *, T *), T *value ) const 459 437 { 460 438 atom *Walker = start; … … 464 442 } 465 443 }; 466 // for element ints inside atom class467 template <typename T> void molecule::SetIndexedArrayForEachAtomTo ( T *array, int element::*index, void (*Setor)(T *, T *) ) 444 // for element ints 445 template <typename T> void molecule::SetIndexedArrayForEachAtomTo ( T *array, int element::*index, void (*Setor)(T *, T *) ) const 468 446 { 469 447 atom *Walker = start; … … 474 452 } 475 453 }; 476 template <typename T> void molecule::SetIndexedArrayForEachAtomTo ( T *array, int element::*index, void (*Setor)(T *, T *), T value ) 454 template <typename T> void molecule::SetIndexedArrayForEachAtomTo ( T *array, int element::*index, void (*Setor)(T *, T *), T value ) const 477 455 { 478 456 atom *Walker = start; … … 482 460 } 483 461 }; 484 template <typename T> void molecule::SetIndexedArrayForEachAtomTo ( T *array, int element::*index, void (*Setor)(T *, T *), T *value ) 462 template <typename T> void molecule::SetIndexedArrayForEachAtomTo ( T *array, int element::*index, void (*Setor)(T *, T *), T *value ) const 485 463 { 486 464 atom *Walker = start; … … 490 468 } 491 469 }; 492 template <typename T> void molecule::SetIndexedArrayForEachAtomTo ( T *array, int TesselPoint::*index, T (atom::*Setor)(Vector &), Vector atom::*value ) 470 471 template <typename T, typename typ> void molecule::SetIndexedArrayForEachAtomTo ( T *array, int ParticleInfo::*index, T (atom::*Setor)(typ &), typ atom::*value ) const 493 472 { 494 473 atom *Walker = start; … … 498 477 } 499 478 }; 500 template <typename T> void molecule::SetIndexedArrayForEachAtomTo ( T *array, int TesselPoint::*index, T (atom::*Setor)(Vector &), Vector &vect ) 479 template <typename T, typename typ> void molecule::SetIndexedArrayForEachAtomTo ( T *array, int ParticleInfo::*index, T (atom::*Setor)(typ &) const, typ atom::*value ) const 480 { 481 atom *Walker = start; 482 while (Walker->next != end) { 483 Walker = Walker->next; 484 array[(Walker->*index)] = (Walker->*Setor) (Walker->*value); 485 } 486 }; 487 template <typename T, typename typ> void molecule::SetIndexedArrayForEachAtomTo ( T *array, int ParticleInfo::*index, T (atom::*Setor)(typ &), typ &vect ) const 501 488 { 502 489 atom *Walker = start; … … 506 493 } 507 494 }; 508 509 template <typename T> void molecule::SetAtomValueToIndexedArray ( T *array, int TesselPoint::*index, T atom::*value ) 495 template <typename T, typename typ> void molecule::SetIndexedArrayForEachAtomTo ( T *array, int ParticleInfo::*index, T (atom::*Setor)(typ &) const, typ &vect ) const 496 { 497 atom *Walker = start; 498 while (Walker->next != end) { 499 Walker = Walker->next; 500 array[(Walker->*index)] = (Walker->*Setor) (vect); 501 } 502 }; 503 template <typename T, typename typ, typename typ2> void molecule::SetAtomValueToIndexedArray ( T *array, int typ::*index, T typ2::*value ) const 510 504 { 511 505 atom *Walker = start; … … 517 511 }; 518 512 519 template <typename T> void molecule::SetAtomValueToIndexedArray ( T *array, int element::*index, T atom::*value ) 520 { 521 atom *Walker = start; 522 while (Walker->next != end) { 523 Walker = Walker->next; 524 Walker->*value = array[(Walker->type->*index)]; 525 //cout << Verbose(2) << *Walker << " gets " << (Walker->*value) << endl; 526 } 527 }; 513 template <typename T, typename typ> void molecule::SetAtomValueToValue ( T value, T typ::*ptr ) const 514 { 515 atom *Walker = start; 516 while (Walker->next != end) { 517 Walker = Walker->next; 518 Walker->*ptr = value; 519 //cout << Verbose(2) << *Walker << " gets " << (Walker->*ptr) << endl; 520 } 521 }; 522 528 523 529 524 #endif /* MOLECULE_TEMPLATE_HPP_ */ -
src/moleculelist.cpp
r06c7a3 r7326b2 12 12 #include "helpers.hpp" 13 13 #include "linkedcell.hpp" 14 #include "lists.hpp" 14 15 #include "molecule.hpp" 15 16 #include "memoryallocator.hpp" … … 306 307 bool MoleculeListClass::EmbedMerge(molecule *mol, molecule *srcmol) 307 308 { 309 LinkedCell *LCList = NULL; 310 Tesselation *TesselStruct = NULL; 308 311 if ((srcmol == NULL) || (mol == NULL)) { 309 312 cout << Verbose(1) << "ERROR: Either fixed or variable molecule is given as NULL." << endl; … … 312 315 313 316 // calculate envelope for *mol 314 L inkedCell *LCList = new LinkedCell(mol, 8.);315 FindNonConvexBorder((ofstream *)&cout, mol, LCList, 4., NULL);316 if ( mol->TesselStruct == NULL) {317 LCList = new LinkedCell(mol, 8.); 318 FindNonConvexBorder((ofstream *)&cout, mol, TesselStruct, (const LinkedCell *&)LCList, 4., NULL); 319 if (TesselStruct == NULL) { 317 320 cout << Verbose(1) << "ERROR: Could not tesselate the fixed molecule." << endl; 318 321 return false; 319 322 } 320 323 delete(LCList); 321 LCList = new LinkedCell( mol->TesselStruct, 8.); // re-create with boundary points only!324 LCList = new LinkedCell(TesselStruct, 8.); // re-create with boundary points only! 322 325 323 326 // prepare index list for bonds … … 333 336 Walker = Walker->next; 334 337 cout << Verbose(2) << "INFO: Current Walker is " << *Walker << "." << endl; 335 if (! mol->TesselStruct->IsInnerPoint((ofstream *)&cout, Walker->x, LCList)) {338 if (!TesselStruct->IsInnerPoint((ofstream *)&cout, Walker->x, LCList)) { 336 339 CopyAtoms[Walker->nr] = new atom(Walker); 337 340 mol->AddAtom(CopyAtoms[Walker->nr]); … … 376 379 atom *Walker = NULL; 377 380 atom *Runner = NULL; 381 bond *Binder = NULL; 378 382 double ***FitConstant = NULL, **correction = NULL; 379 383 int a, b; … … 419 423 420 424 // 0b. allocate memory for constants 421 FitConstant = Malloc<double**>(3, "MoleculeListClass::AddHydrogenCorrection: ***FitConstant");425 FitConstant = Calloc<double**>(3, "MoleculeListClass::AddHydrogenCorrection: ***FitConstant"); 422 426 for (int k = 0; k < 3; k++) { 423 FitConstant[k] = Malloc<double*>(a, "MoleculeListClass::AddHydrogenCorrection: **FitConstant[]");427 FitConstant[k] = Calloc<double*>(a, "MoleculeListClass::AddHydrogenCorrection: **FitConstant[]"); 424 428 for (int i = a; i--;) { 425 FitConstant[k][i] = Malloc<double>(b, "MoleculeListClass::AddHydrogenCorrection: *FitConstant[][]");429 FitConstant[k][i] = Calloc<double>(b, "MoleculeListClass::AddHydrogenCorrection: *FitConstant[][]"); 426 430 } 427 431 } … … 468 472 469 473 // 0d. allocate final correction matrix 470 correction = Malloc<double*>(a, "MoleculeListClass::AddHydrogenCorrection: **correction");474 correction = Calloc<double*>(a, "MoleculeListClass::AddHydrogenCorrection: **correction"); 471 475 for (int i = a; i--;) 472 correction[i] = Malloc<double>(b, "MoleculeListClass::AddHydrogenCorrection: *correction[]");476 correction[i] = Calloc<double>(b, "MoleculeListClass::AddHydrogenCorrection: *correction[]"); 473 477 474 478 // 1a. go through every molecule in the list … … 482 486 while (Walker->next != (*ListRunner)->end) { 483 487 Walker = Walker->next; 484 //cout << Verbose(1) << "Walker: " << *Walker << " with first bond " << *( *Runner)->ListOfBondsPerAtom[Walker->nr][0]<< "." << endl;488 //cout << Verbose(1) << "Walker: " << *Walker << " with first bond " << *(Walker->ListOfBonds.begin()) << "." << endl; 485 489 if ((Walker->type->Z == 1) && ((Walker->father == NULL) 486 490 || (Walker->father->type->Z != 1))) { // if it's a hydrogen … … 488 492 while (Runner->next != (*ListRunner)->end) { 489 493 Runner = Runner->next; 490 //cout << Verbose(2) << "Runner: " << *Runner << " with first bond " << *( *Runner)->ListOfBondsPerAtom[Runner->nr][0]<< "." << endl;494 //cout << Verbose(2) << "Runner: " << *Runner << " with first bond " << *(Walker->ListOfBonds.begin()) << "." << endl; 491 495 // 3. take every other hydrogen that is the not the first and not bound to same bonding partner 492 if ((Runner->type->Z == 1) && (Runner->nr > Walker->nr) && ((*ListRunner)->ListOfBondsPerAtom[Runner->nr][0]->GetOtherAtom(Runner) != (*ListRunner)->ListOfBondsPerAtom[Walker->nr][0]->GetOtherAtom(Walker))) { // (hydrogens have only one bonding partner!) 496 Binder = *(Runner->ListOfBonds.begin()); 497 if ((Runner->type->Z == 1) && (Runner->nr > Walker->nr) && (Binder->GetOtherAtom(Runner) != Binder->GetOtherAtom(Walker))) { // (hydrogens have only one bonding partner!) 493 498 // 4. evaluate the morse potential for each matrix component and add up 494 499 distance = Runner->x.Distance(&Walker->x); … … 544 549 output.close(); 545 550 // 6. free memory of parsed matrices 546 FitConstant = Malloc<double**>(a, "MoleculeListClass::AddHydrogenCorrection: ***FitConstant");547 551 for (int k = 0; k < 3; k++) { 548 FitConstant[k] = Malloc<double*>(a, "MoleculeListClass::AddHydrogenCorrection: **FitConstant[]");549 552 for (int i = a; i--;) { 550 FitConstant[k][i] = Malloc<double>(b, "MoleculeListClass::AddHydrogenCorrection: *FitConstant[][]"); 551 } 552 } 553 Free(&FitConstant[k][i]); 554 } 555 Free(&FitConstant[k]); 556 } 557 Free(&FitConstant); 553 558 cout << "done." << endl; 554 559 return true; … … 708 713 //outputFragment.close(); 709 714 //outputFragment.clear(); 710 delete (FragmentNumber); 711 //Free(&FragmentNumber); 715 Free(&FragmentNumber); 712 716 } 713 717 cout << " done." << endl; … … 730 734 }; 731 735 736 /** Dissects given \a *mol into connected subgraphs and inserts them as new molecules but with old atoms into \a this. 737 * \param *out output stream for debugging 738 * \param *mol molecule with atoms to dissect 739 * \param *configuration config with BondGraph 740 */ 741 void MoleculeListClass::DissectMoleculeIntoConnectedSubgraphs(ofstream * const out, molecule * const mol, config * const configuration) 742 { 743 // 1. dissect the molecule into connected subgraphs 744 configuration ->BG->ConstructBondGraph(out, mol); 745 746 // 2. scan for connected subgraphs 747 MoleculeLeafClass *Subgraphs = NULL; // list of subgraphs from DFS analysis 748 class StackClass<bond *> *BackEdgeStack = NULL; 749 Subgraphs = mol->DepthFirstSearchAnalysis(out, BackEdgeStack); 750 delete(BackEdgeStack); 751 752 // 3. dissect (the following construct is needed to have the atoms not in the order of the DFS, but in 753 // the original one as parsed in) 754 // TODO: Optimize this, when molecules just contain pointer list of global atoms! 755 756 // 4a. create array of molecules to fill 757 const int MolCount = Subgraphs->next->Count(); 758 molecule **molecules = Malloc<molecule *>(MolCount, "config::Load() - **molecules"); 759 for (int i=0;i<MolCount;i++) { 760 molecules[i] = (molecule*) new molecule(mol->elemente); 761 molecules[i]->ActiveFlag = true; 762 insert(molecules[i]); 763 } 764 765 // 4b. create and fill map of which atom is associated to which connected molecule (note, counting starts at 1) 766 int FragmentCounter = 0; 767 int *MolMap = Calloc<int>(mol->AtomCount, "config::Load() - *MolMap"); 768 MoleculeLeafClass *MolecularWalker = Subgraphs; 769 atom *Walker = NULL; 770 while (MolecularWalker->next != NULL) { 771 MolecularWalker = MolecularWalker->next; 772 Walker = MolecularWalker->Leaf->start; 773 while (Walker->next != MolecularWalker->Leaf->end) { 774 Walker = Walker->next; 775 MolMap[Walker->GetTrueFather()->nr] = FragmentCounter+1; 776 } 777 FragmentCounter++; 778 } 779 780 // 4c. relocate atoms to new molecules and remove from Leafs 781 Walker = mol->start; 782 while (mol->start->next != mol->end) { 783 Walker = mol->start->next; 784 if ((Walker->nr <0) || (Walker->nr >= mol->AtomCount)) { 785 cerr << "Index of atom " << *Walker << " is invalid!" << endl; 786 performCriticalExit(); 787 } 788 FragmentCounter = MolMap[Walker->nr]; 789 if (FragmentCounter != 0) { 790 cout << Verbose(3) << "Re-linking " << *Walker << "..." << endl; 791 unlink(Walker); 792 molecules[FragmentCounter-1]->AddAtom(Walker); // counting starts at 1 793 } else { 794 cerr << "Atom " << *Walker << " not associated to molecule!" << endl; 795 performCriticalExit(); 796 } 797 } 798 // 4d. we don't need to redo bonds, as they are connected subgraphs and still maintained their ListOfBonds 799 // 4e. free Leafs 800 MolecularWalker = Subgraphs; 801 while (MolecularWalker->next != NULL) { 802 MolecularWalker = MolecularWalker->next; 803 delete(MolecularWalker->previous); 804 } 805 delete(MolecularWalker); 806 Free(&MolMap); 807 Free(&molecules); 808 cout << Verbose(1) << "I scanned " << FragmentCounter << " molecules." << endl; 809 }; 732 810 733 811 /******************************************* Class MoleculeLeafClass ************************************************/ … … 810 888 * \return true - success, false - faoilure 811 889 */ 812 bool MoleculeLeafClass::FillBondStructureFromReference(ofstream *out, molecule *reference, int &FragmentCounter, atom ***&ListOfLocalAtoms, bool FreeList) 813 { 814 atom *Walker = NULL, *OtherWalker = NULL; 815 bond *Binder = NULL; 890 bool MoleculeLeafClass::FillBondStructureFromReference(ofstream *out, const molecule * const reference, int &FragmentCounter, atom ***&ListOfLocalAtoms, bool FreeList) 891 { 892 atom *Walker = NULL; 893 atom *OtherWalker = NULL; 894 atom *Father = NULL; 816 895 bool status = true; 817 896 int AtomNo; … … 825 904 826 905 if (status) { 827 *out << Verbose(1) << "Creating adjacency list for subgraph " << this 828 << "." << endl; 906 *out << Verbose(1) << "Creating adjacency list for subgraph " << Leaf << "." << endl; 907 // remove every bond from the list 908 bond *Binder = NULL; 909 while (Leaf->last->previous != Leaf->first) { 910 Binder = Leaf->last->previous; 911 Binder->leftatom->UnregisterBond(Binder); 912 Binder->rightatom->UnregisterBond(Binder); 913 removewithoutcheck(Binder); 914 } 915 829 916 Walker = Leaf->start; 830 917 while (Walker->next != Leaf->end) { 831 918 Walker = Walker->next; 832 AtomNo = Walker->GetTrueFather()->nr; // global id of the current walker833 for (int i = 0; i < reference->NumberOfBondsPerAtom[AtomNo]; i++) { // go through father's bonds and copy them all834 Binder = reference->ListOfBondsPerAtom[AtomNo][i];835 OtherWalker = ListOfLocalAtoms[FragmentCounter][ Binder->GetOtherAtom(Walker->GetTrueFather())->nr]; // local copy of current bond partner of walker919 Father = Walker->GetTrueFather(); 920 AtomNo = Father->nr; // global id of the current walker 921 for (BondList::const_iterator Runner = Father->ListOfBonds.begin(); Runner != Father->ListOfBonds.end(); (++Runner)) { 922 OtherWalker = ListOfLocalAtoms[FragmentCounter][(*Runner)->GetOtherAtom(Walker->GetTrueFather())->nr]; // local copy of current bond partner of walker 836 923 if (OtherWalker != NULL) { 837 924 if (OtherWalker->nr > Walker->nr) 838 Leaf->AddBond(Walker, OtherWalker, Binder->BondDegree);925 Leaf->AddBond(Walker, OtherWalker, (*Runner)->BondDegree); 839 926 } else { 840 *out << Verbose(1) << "OtherWalker = ListOfLocalAtoms[" << FragmentCounter << "][" << Binder->GetOtherAtom(Walker->GetTrueFather())->nr << "] is NULL!" << endl;927 *out << Verbose(1) << "OtherWalker = ListOfLocalAtoms[" << FragmentCounter << "][" << (*Runner)->GetOtherAtom(Walker->GetTrueFather())->nr << "] is NULL!" << endl; 841 928 status = false; 842 929 } 843 930 } 844 931 } 845 Leaf->CreateListOfBondsPerAtom(out);846 FragmentCounter++;847 if (next != NULL)848 status = next->FillBondStructureFromReference(out, reference, FragmentCounter, ListOfLocalAtoms);849 FragmentCounter--;850 932 } 851 933 … … 856 938 Free(&ListOfLocalAtoms); 857 939 } 858 FragmentCounter--;859 940 *out << Verbose(1) << "End of FillBondStructureFromReference." << endl; 860 941 return status; … … 903 984 904 985 /** Fills a lookup list of father's Atom::nr -> atom for each subgraph. 905 * \param *out output stream fro debugging986 * \param *out output stream from debugging 906 987 * \param ***ListOfLocalAtoms Lookup table for each subgraph and index of each atom in global molecule, may be NULL on start, then it is filled 907 988 * \param FragmentCounter counts the fragments as we move along the list 908 989 * \param GlobalAtomCount number of atoms in the complete molecule 909 990 * \param &FreeList true - ***ListOfLocalAtoms is free'd before return, false - it is not 910 * \return true - succes , false - failure991 * \return true - success, false - failure 911 992 */ 912 993 bool MoleculeLeafClass::FillListOfLocalAtoms(ofstream *out, atom ***&ListOfLocalAtoms, const int FragmentCounter, const int GlobalAtomCount, bool &FreeList) … … 914 995 bool status = true; 915 996 916 int Counter = Count();917 997 if (ListOfLocalAtoms == NULL) { // allocated initial pointer 918 998 // allocate and set each field to NULL 919 ListOfLocalAtoms = Malloc<atom**>(Counter, "MoleculeLeafClass::FillBondStructureFromReference - ***ListOfLocalAtoms"); 920 if (ListOfLocalAtoms != NULL) { 921 for (int i = Counter; i--;) 922 ListOfLocalAtoms[i] = NULL; 923 FreeList = FreeList && true; 924 } else 999 const int Counter = Count(); 1000 ListOfLocalAtoms = Calloc<atom**>(Counter, "MoleculeLeafClass::FillListOfLocalAtoms - ***ListOfLocalAtoms"); 1001 if (ListOfLocalAtoms == NULL) { 1002 FreeList = FreeList && false; 925 1003 status = false; 1004 } 926 1005 } 927 1006 … … 961 1040 if (FragmentList == NULL) { 962 1041 KeySetCounter = Count(); 963 FragmentList = Malloc<Graph*>(KeySetCounter, "MoleculeLeafClass::AssignKeySetsToFragment - **FragmentList"); 964 for (int i = KeySetCounter; i--;) 965 FragmentList[i] = NULL; 1042 FragmentList = Calloc<Graph*>(KeySetCounter, "MoleculeLeafClass::AssignKeySetsToFragment - **FragmentList"); 966 1043 KeySetCounter = 0; 967 1044 } -
src/periodentafel.cpp
r06c7a3 r7326b2 21 21 * Initialises start and end of list and resets periodentafel::checkliste to false. 22 22 */ 23 periodentafel::periodentafel() 24 { 25 start = new element; 26 end = new element; 23 periodentafel::periodentafel() : start(new element), end(new element) 24 { 27 25 start->previous = NULL; 28 26 start->next = end; … … 45 43 * \return true - succeeded, false - does not occur 46 44 */ 47 bool periodentafel::AddElement(element * pointer)45 bool periodentafel::AddElement(element * const pointer) 48 46 { 49 47 pointer->sort = &pointer->Z; … … 57 55 * \return true - succeeded, false - element not found 58 56 */ 59 bool periodentafel::RemoveElement(element * pointer)57 bool periodentafel::RemoveElement(element * const pointer) 60 58 { 61 59 return remove(pointer, start, end); … … 71 69 72 70 /** Finds an element by its atomic number. 73 * If element is not yet in list, datas are asked and stored in database.71 * If element is not yet in list, returns NULL. 74 72 * \param Z atomic number 75 * \return pointer to element 76 */ 77 element * periodentafel::FindElement(int Z)73 * \return pointer to element or NULL if not found 74 */ 75 element * const periodentafel::FindElement(const int Z) const 78 76 { 79 77 element *walker = find(&Z, start,end); 80 if (walker == NULL) { // not found: enter and put into db81 cout << Verbose(0) << "Element not found in database, please enter." << endl;82 walker = new element;83 cout << Verbose(0) << "Mass: " << endl;84 cin >> walker->mass;85 walker->Z = Z;86 cout << Verbose(0) << "Atomic number: " << walker->Z << endl;87 cout << Verbose(0) << "Name [max 64 chars]: " << endl;88 cin >> walker->name;89 cout << Verbose(0) << "Short form [max 3 chars]: " << endl;90 cin >> walker->symbol;91 periodentafel::AddElement(walker);92 }93 78 return(walker); 94 79 }; … … 99 84 * \return pointer to element 100 85 */ 101 element * periodentafel::FindElement(const char *shorthand) const86 element * const periodentafel::FindElement(const char * const shorthand) const 102 87 { 103 88 element *walker = periodentafel::start; … … 112 97 /** Asks for element number and returns pointer to element 113 98 */ 114 element * periodentafel::AskElement()99 element * const periodentafel::AskElement() const 115 100 { 116 101 element *walker = NULL; … … 124 109 }; 125 110 111 /** Asks for element and if not found, presents mask to enter info. 112 * \return pointer to either present or newly created element 113 */ 114 element * const periodentafel::EnterElement() 115 { 116 element *walker = NULL; 117 int Z = -1; 118 cout << Verbose(0) << "Atomic number: " << Z << endl; 119 cin >> Z; 120 walker = FindElement(Z); 121 if (walker == NULL) { 122 cout << Verbose(0) << "Element not found in database, please enter." << endl; 123 walker = new element; 124 walker->Z = Z; 125 cout << Verbose(0) << "Mass: " << endl; 126 cin >> walker->mass; 127 cout << Verbose(0) << "Name [max 64 chars]: " << endl; 128 cin >> walker->name; 129 cout << Verbose(0) << "Short form [max 3 chars]: " << endl; 130 cin >> walker->symbol; 131 periodentafel::AddElement(walker); 132 } 133 return(walker); 134 }; 135 126 136 /** Prints period table to given stream. 127 137 * \param output stream 128 138 */ 129 bool periodentafel::Output(ofstream * output) const139 bool periodentafel::Output(ofstream * const output) const 130 140 { 131 141 bool result = true; … … 145 155 * \param *checkliste elements table for this molecule 146 156 */ 147 bool periodentafel::Checkout(ofstream * output, const int *checkliste) const157 bool periodentafel::Checkout(ofstream * const output, const int * const checkliste) const 148 158 { 149 159 element *walker = start; … … 215 225 cout << "Could not parse element: "; 216 226 neues->Output((ofstream *)&cout); 227 delete(neues); 217 228 } 218 229 } -
src/periodentafel.hpp
r06c7a3 r7326b2 34 34 ~periodentafel(); 35 35 36 bool AddElement(element * pointer);37 bool RemoveElement(element * pointer);36 bool AddElement(element * const pointer); 37 bool RemoveElement(element * const pointer); 38 38 bool CleanupPeriodtable(); 39 element * FindElement(int Z); 40 element * FindElement(const char *shorthand) const; 41 element * AskElement(); 42 bool Output(ofstream *output) const; 43 bool Checkout(ofstream *output, const int *checkliste) const; 44 bool LoadPeriodentafel(const char *path); 45 bool StorePeriodentafel(const char *path) const; 39 element * const FindElement(const int Z) const; 40 element * const FindElement(const char * const shorthand) const; 41 element * const AskElement() const; 42 element * const EnterElement(); 43 bool Output(ofstream * const output) const; 44 bool Checkout(ofstream * const output, const int * const checkliste) const; 45 bool LoadPeriodentafel(const char * const path); 46 bool StorePeriodentafel(const char * const path) const; 46 47 47 48 private: -
src/stackclass.hpp
r06c7a3 r7326b2 33 33 bool RemoveItem(T ptr); 34 34 void ClearStack(); 35 bool IsEmpty(); 36 bool IsFull(); 37 int ItemCount(); 38 void Output(ofstream *out) const; 39 void TestImplementation(ofstream *out, T test); 35 bool IsEmpty() const; 36 bool IsFull() const; 37 int ItemCount() const; 38 void Output(ofstream * const out) const; 40 39 41 40 private: … … 49 48 /** Constructor of class StackClass. 50 49 */ 51 template <typename T> StackClass<T>::StackClass(int dimension) 52 { 53 CurrentLastEntry = 0; 54 CurrentFirstEntry = 0; 55 NextFreeField = 0; 56 EntryCount = dimension; 57 StackList = Malloc<T>(EntryCount, "StackClass::StackClass: **StackList"); 50 template <typename T> StackClass<T>::StackClass(int dimension) : StackList(NULL), EntryCount(dimension), CurrentLastEntry(0), CurrentFirstEntry(0), NextFreeField(0) 51 { 52 StackList = Calloc<T>(EntryCount, "StackClass::StackClass: **StackList"); 58 53 }; 59 54 … … 165 160 }; 166 161 167 /** Test the functionality of the stack.168 * \param *out ofstream for debugging169 * \param *test one item to put on stack170 * \return true - all tests worked correctly171 */172 template <typename T> void StackClass<T>::TestImplementation(ofstream *out, T test)173 {174 T Walker = test;175 *out << Verbose(1) << "Testing the snake stack..." << endl;176 for (int i=0;i<EntryCount;i++) {177 *out << Verbose(2) << "Filling " << i << "th element of stack." << endl;178 Push(Walker);179 Walker=Walker->next;180 }181 *out << endl;182 Output(out);183 if (IsFull())184 *out << "Stack is full as supposed to be!" << endl;185 else186 *out << "ERROR: Stack is not as full as supposed to be!" << endl;187 //if (StackList[(EntryCount+1)/2] != NULL) {188 *out << "Removing element in the middle ..." << endl;189 RemoveItem(StackList[(EntryCount+1)/2]);190 Output(out);191 //}192 //if (StackList[CurrentFirstEntry] != NULL) {193 *out << "Removing first element ..." << endl;194 RemoveItem(StackList[CurrentFirstEntry]);195 Output(out);196 //}197 //if (StackList[CurrentLastEntry] != NULL) {198 *out << "Removing last element ..." << endl;199 RemoveItem(StackList[CurrentLastEntry]);200 Output(out);201 //}202 *out << "Clearing stack ... " << endl;203 ClearStack();204 Output(out);205 if (IsEmpty())206 *out << "Stack is empty as supposed to be!" << endl;207 else208 *out << "ERROR: Stack is not as empty as supposed to be!" << endl;209 *out << "done." << endl;210 };211 162 212 163 /** Puts contents of stack into ofstream \a *out. 213 164 * \param *out ofstream for output 214 165 */ 215 template <typename T> void StackClass<T>::Output(ofstream * out) const166 template <typename T> void StackClass<T>::Output(ofstream * const out) const 216 167 { 217 168 *out << "Contents of Stack: "; … … 234 185 * \return true - empty, false - not 235 186 */ 236 template <typename T> bool StackClass<T>::IsEmpty() 187 template <typename T> bool StackClass<T>::IsEmpty() const 237 188 { 238 189 return((NextFreeField == CurrentFirstEntry) && (CurrentLastEntry == CurrentFirstEntry)); … … 244 195 * \return true - full, false - not 245 196 */ 246 template <typename T> bool StackClass<T>::IsFull() 197 template <typename T> bool StackClass<T>::IsFull() const 247 198 { 248 199 return((NextFreeField == CurrentFirstEntry) && (CurrentLastEntry != CurrentFirstEntry)); … … 254 205 * \warning will never return correct item count if stack is full, i.e. count would be StackClass::EntryCount. 255 206 */ 256 template <typename T> int StackClass<T>::ItemCount() 207 template <typename T> int StackClass<T>::ItemCount() const 257 208 { 258 209 //cout << "Stack: CurrentLastEntry " << CurrentLastEntry<< "\tCurrentFirstEntry " << CurrentFirstEntry << "\tEntryCount " << EntryCount << "." << endl; -
src/tesselation.cpp
r06c7a3 r7326b2 8 8 #include <fstream> 9 9 10 #include "helpers.hpp" 10 11 #include "linkedcell.hpp" 11 12 #include "tesselation.hpp" … … 30 31 * \param *Walker TesselPoint this boundary point represents 31 32 */ 32 BoundaryPointSet::BoundaryPointSet(TesselPoint * Walker)33 BoundaryPointSet::BoundaryPointSet(TesselPoint * Walker) 33 34 { 34 35 node = Walker; … … 72 73 * \param &a boundary point 73 74 */ 74 ostream & operator <<(ostream &ost, BoundaryPointSet &a)75 ostream & operator <<(ostream &ost, const BoundaryPointSet &a) 75 76 { 76 77 ost << "[" << a.Nr << "|" << a.node->Name << " at " << *a.node->node << "]"; … … 95 96 * \param number number of the list 96 97 */ 97 BoundaryLineSet::BoundaryLineSet(class BoundaryPointSet *Point[2], int number)98 BoundaryLineSet::BoundaryLineSet(class BoundaryPointSet *Point[2], const int number) 98 99 { 99 100 // set number … … 274 275 * \param &a boundary line 275 276 */ 276 ostream & operator <<(ostream &ost, BoundaryLineSet &a)277 ostream & operator <<(ostream &ost, const BoundaryLineSet &a) 277 278 { 278 279 ost << "[" << a.Nr << "|" << a.endpoints[0]->node->Name << " at " << *a.endpoints[0]->node->node << "," << a.endpoints[1]->node->Name << " at " << *a.endpoints[1]->node->node << "]"; … … 531 532 * \param &a boundary triangle 532 533 */ 533 ostream &operator <<(ostream &ost, BoundaryTriangleSet &a)534 ostream &operator <<(ostream &ost, const BoundaryTriangleSet &a) 534 535 { 535 536 ost << "[" << a.Nr << "|" << a.endpoints[0]->node->Name << " at " << *a.endpoints[0]->node->node << "," … … 641 642 * Uses PointsOnBoundary and STL stuff. 642 643 */ 643 Vector * Tesselation::GetCenter(ofstream *out) 644 Vector * Tesselation::GetCenter(ofstream *out) const 644 645 { 645 646 Vector *Center = new Vector(0.,0.,0.); … … 656 657 * Uses PointsOnBoundary and STL stuff. 657 658 */ 658 TesselPoint * Tesselation::GetPoint() 659 TesselPoint * Tesselation::GetPoint() const 659 660 { 660 661 return (InternalPointer->second->node); … … 664 665 * Uses PointsOnBoundary and STL stuff. 665 666 */ 666 TesselPoint * Tesselation::GetTerminalPoint() 667 { 668 PointMap:: iterator Runner = PointsOnBoundary.end();667 TesselPoint * Tesselation::GetTerminalPoint() const 668 { 669 PointMap::const_iterator Runner = PointsOnBoundary.end(); 669 670 Runner--; 670 671 return (Runner->second->node); … … 674 675 * Uses PointsOnBoundary and STL stuff. 675 676 */ 676 void Tesselation::GoToNext() 677 void Tesselation::GoToNext() const 677 678 { 678 679 if (InternalPointer != PointsOnBoundary.end()) … … 683 684 * Uses PointsOnBoundary and STL stuff. 684 685 */ 685 void Tesselation::GoToPrevious() 686 void Tesselation::GoToPrevious() const 686 687 { 687 688 if (InternalPointer != PointsOnBoundary.begin()) … … 692 693 * Uses PointsOnBoundary and STL stuff. 693 694 */ 694 void Tesselation::GoToFirst() 695 void Tesselation::GoToFirst() const 695 696 { 696 697 InternalPointer = PointsOnBoundary.begin(); … … 699 700 /** PointCloud implementation of GoToLast. 700 701 * Uses PointsOnBoundary and STL stuff. 701 */ 702 void Tesselation::GoToLast() 702 */ 703 void Tesselation::GoToLast() const 703 704 { 704 705 InternalPointer = PointsOnBoundary.end(); … … 709 710 * Uses PointsOnBoundary and STL stuff. 710 711 */ 711 bool Tesselation::IsEmpty() 712 bool Tesselation::IsEmpty() const 712 713 { 713 714 return (PointsOnBoundary.empty()); … … 717 718 * Uses PointsOnBoundary and STL stuff. 718 719 */ 719 bool Tesselation::IsEnd() 720 bool Tesselation::IsEnd() const 720 721 { 721 722 return (InternalPointer == PointsOnBoundary.end()); … … 898 899 * \param *cloud cluster of points 899 900 */ 900 void Tesselation::TesselateOnBoundary(ofstream *out, PointCloud *cloud)901 void Tesselation::TesselateOnBoundary(ofstream *out, const PointCloud * const cloud) 901 902 { 902 903 bool flag; … … 1096 1097 * \return true - all straddling points insert, false - something went wrong 1097 1098 */ 1098 bool Tesselation::InsertStraddlingPoints(ofstream *out, PointCloud *cloud,LinkedCell *LC)1099 bool Tesselation::InsertStraddlingPoints(ofstream *out, const PointCloud *cloud, const LinkedCell *LC) 1099 1100 { 1100 1101 Vector Intersection, Normal; … … 1206 1207 * \return true - new point was added, false - point already present 1207 1208 */ 1208 bool 1209 Tesselation::AddBoundaryPoint(TesselPoint *Walker, int n) 1209 bool Tesselation::AddBoundaryPoint(TesselPoint * Walker, const int n) 1210 1210 { 1211 1211 PointTestPair InsertUnique; … … 1228 1228 * @param n index for this point in Tesselation::TPS array 1229 1229 */ 1230 void 1231 Tesselation::AddTesselationPoint(TesselPoint* Candidate, int n) 1230 void Tesselation::AddTesselationPoint(TesselPoint* Candidate, const int n) 1232 1231 { 1233 1232 PointTestPair InsertUnique; … … 1251 1250 * @param n index of Tesselation::BLS giving the line with both endpoints 1252 1251 */ 1253 void Tesselation::AddTesselationLine(class BoundaryPointSet *a, class BoundaryPointSet *b, int n) {1252 void Tesselation::AddTesselationLine(class BoundaryPointSet *a, class BoundaryPointSet *b, const int n) { 1254 1253 bool insertNewLine = true; 1255 1254 … … 1289 1288 * @param n index of Tesselation::BLS giving the line with both endpoints 1290 1289 */ 1291 void Tesselation::AlwaysAddTesselationTriangleLine(class BoundaryPointSet *a, class BoundaryPointSet *b, int n)1290 void Tesselation::AlwaysAddTesselationTriangleLine(class BoundaryPointSet *a, class BoundaryPointSet *b, const int n) 1292 1291 { 1293 1292 cout << Verbose(4) << "Adding line [" << LinesOnBoundaryCount << "|" << *(a->node) << " and " << *(b->node) << "." << endl; … … 1322 1321 * \param nr triangle number 1323 1322 */ 1324 void Tesselation::AddTesselationTriangle( int nr)1323 void Tesselation::AddTesselationTriangle(const int nr) 1325 1324 { 1326 1325 cout << Verbose(1) << "Adding triangle to global TrianglesOnBoundary map." << endl; … … 1553 1552 * \param *LC LinkedCell structure with neighbouring TesselPoint's 1554 1553 */ 1555 void Tesselation::FindStartingTriangle(ofstream *out, const double RADIUS, LinkedCell *LC)1554 void Tesselation::FindStartingTriangle(ofstream *out, const double RADIUS, const LinkedCell *LC) 1556 1555 { 1557 1556 cout << Verbose(1) << "Begin of FindStartingTriangle\n"; 1558 1557 int i = 0; 1559 LinkedNodes *List = NULL;1560 1558 TesselPoint* FirstPoint = NULL; 1561 1559 TesselPoint* SecondPoint = NULL; … … 1579 1577 for (LC->n[(i+1)%NDIM]=0;LC->n[(i+1)%NDIM]<LC->N[(i+1)%NDIM];LC->n[(i+1)%NDIM]++) 1580 1578 for (LC->n[(i+2)%NDIM]=0;LC->n[(i+2)%NDIM]<LC->N[(i+2)%NDIM];LC->n[(i+2)%NDIM]++) { 1581 List = LC->GetCurrentCell();1579 const LinkedNodes *List = LC->GetCurrentCell(); 1582 1580 //cout << Verbose(2) << "Current cell is " << LC->n[0] << ", " << LC->n[1] << ", " << LC->n[2] << " with No. " << LC->index << "." << endl; 1583 1581 if (List != NULL) { 1584 for (LinkedNodes:: iterator Runner = List->begin();Runner != List->end();Runner++) {1582 for (LinkedNodes::const_iterator Runner = List->begin();Runner != List->end();Runner++) { 1585 1583 if ((*Runner)->node->x[i] > maxCoordinate[i]) { 1586 1584 cout << Verbose(2) << "New maximal for axis " << i << " node is " << *(*Runner) << " at " << *(*Runner)->node << "." << endl; … … 1644 1642 1645 1643 //cout << Verbose(2) << "INFO: OldSphereCenter is at " << helper << ".\n"; 1646 FindThirdPointForTesselation( 1647 Oben, SearchDirection, helper, BLS[0], NULL, *&OptCandidates, &ShortestAngle, RADIUS, LC 1648 ); 1644 FindThirdPointForTesselation(Oben, SearchDirection, helper, BLS[0], NULL, *&OptCandidates, &ShortestAngle, RADIUS, LC); 1649 1645 cout << Verbose(1) << "List of third Points is "; 1650 1646 for (CandidateList::iterator it = OptCandidates->begin(); it != OptCandidates->end(); ++it) { … … 1712 1708 * @param *LC LinkedCell structure with neighbouring points 1713 1709 */ 1714 bool Tesselation::FindNextSuitableTriangle(ofstream *out, BoundaryLineSet &Line, BoundaryTriangleSet &T, const double& RADIUS, LinkedCell *LC)1710 bool Tesselation::FindNextSuitableTriangle(ofstream *out, BoundaryLineSet &Line, BoundaryTriangleSet &T, const double& RADIUS, const LinkedCell *LC) 1715 1711 { 1716 1712 cout << Verbose(0) << "Begin of FindNextSuitableTriangle\n"; … … 1750 1746 1751 1747 // construct old center 1752 GetCenterofCircumcircle(&OldSphereCenter, T.endpoints[0]->node->node, T.endpoints[1]->node->node,T.endpoints[2]->node->node);1748 GetCenterofCircumcircle(&OldSphereCenter, *T.endpoints[0]->node->node, *T.endpoints[1]->node->node, *T.endpoints[2]->node->node); 1753 1749 helper.CopyVector(&T.NormalVector); // normal vector ensures that this is correct center of the two possible ones 1754 1750 radius = Line.endpoints[0]->node->node->DistanceSquared(&OldSphereCenter); … … 1773 1769 1774 1770 // add third point 1775 FindThirdPointForTesselation( 1776 T.NormalVector, SearchDirection, OldSphereCenter, &Line, ThirdNode, OptCandidates, 1777 &ShortestAngle, RADIUS, LC 1778 ); 1771 FindThirdPointForTesselation(T.NormalVector, SearchDirection, OldSphereCenter, &Line, ThirdNode, OptCandidates, &ShortestAngle, RADIUS, LC); 1779 1772 1780 1773 } else { … … 1812 1805 AddTesselationPoint(BaseRay->endpoints[1]->node, 2); 1813 1806 1814 if (CheckLineCriteriaForDegeneratedTriangle( TPS)) {1807 if (CheckLineCriteriaForDegeneratedTriangle((const BoundaryPointSet ** const )TPS)) { 1815 1808 AddTesselationLine(TPS[0], TPS[1], 0); 1816 1809 AddTesselationLine(TPS[0], TPS[2], 1); … … 1841 1834 // We demand that at most one new degenerate line is created and that this line also already exists (which has to be the case due to existentTrianglesCount == 1) 1842 1835 // i.e. at least one of the three lines must be present with TriangleCount <= 1 1843 if (CheckLineCriteriaForDegeneratedTriangle( TPS)) {1836 if (CheckLineCriteriaForDegeneratedTriangle((const BoundaryPointSet ** const)TPS)) { 1844 1837 AddTesselationLine(TPS[0], TPS[1], 0); 1845 1838 AddTesselationLine(TPS[0], TPS[2], 1); … … 1948 1941 }; 1949 1942 1950 void Tesselation::PrintAllBoundaryPoints(ofstream *out) 1943 void Tesselation::PrintAllBoundaryPoints(ofstream *out) const 1951 1944 { 1952 1945 // print all lines 1953 1946 *out << Verbose(1) << "Printing all boundary points for debugging:" << endl; 1954 for (PointMap:: iterator PointRunner = PointsOnBoundary.begin();PointRunner != PointsOnBoundary.end(); PointRunner++)1947 for (PointMap::const_iterator PointRunner = PointsOnBoundary.begin();PointRunner != PointsOnBoundary.end(); PointRunner++) 1955 1948 *out << Verbose(2) << *(PointRunner->second) << endl; 1956 1949 }; 1957 1950 1958 void Tesselation::PrintAllBoundaryLines(ofstream *out) 1951 void Tesselation::PrintAllBoundaryLines(ofstream *out) const 1959 1952 { 1960 1953 // print all lines 1961 1954 *out << Verbose(1) << "Printing all boundary lines for debugging:" << endl; 1962 for (LineMap:: iterator LineRunner = LinesOnBoundary.begin(); LineRunner != LinesOnBoundary.end(); LineRunner++)1955 for (LineMap::const_iterator LineRunner = LinesOnBoundary.begin(); LineRunner != LinesOnBoundary.end(); LineRunner++) 1963 1956 *out << Verbose(2) << *(LineRunner->second) << endl; 1964 1957 }; 1965 1958 1966 void Tesselation::PrintAllBoundaryTriangles(ofstream *out) 1959 void Tesselation::PrintAllBoundaryTriangles(ofstream *out) const 1967 1960 { 1968 1961 // print all triangles 1969 1962 *out << Verbose(1) << "Printing all boundary triangles for debugging:" << endl; 1970 for (TriangleMap:: iterator TriangleRunner = TrianglesOnBoundary.begin(); TriangleRunner != TrianglesOnBoundary.end(); TriangleRunner++)1963 for (TriangleMap::const_iterator TriangleRunner = TrianglesOnBoundary.begin(); TriangleRunner != TrianglesOnBoundary.end(); TriangleRunner++) 1971 1964 *out << Verbose(2) << *(TriangleRunner->second) << endl; 1972 1965 }; … … 2003 1996 2004 1997 // calculate volume 2005 volume = CalculateVolumeofGeneralTetraeder( Base->endpoints[1]->node->node, OtherBase->endpoints[0]->node->node, OtherBase->endpoints[1]->node->node,Base->endpoints[0]->node->node);1998 volume = CalculateVolumeofGeneralTetraeder(*Base->endpoints[1]->node->node, *OtherBase->endpoints[0]->node->node, *OtherBase->endpoints[1]->node->node, *Base->endpoints[0]->node->node); 2006 1999 2007 2000 // delete the temporary other base line and the closest points … … 2164 2157 * \param *LC LinkedCell structure with neighbouring points 2165 2158 */ 2166 void Tesselation::FindSecondPointForTesselation(TesselPoint* a, Vector Oben, TesselPoint*& OptCandidate, double Storage[3], double RADIUS, LinkedCell *LC)2159 void Tesselation::FindSecondPointForTesselation(TesselPoint* a, Vector Oben, TesselPoint*& OptCandidate, double Storage[3], double RADIUS, const LinkedCell *LC) 2167 2160 { 2168 2161 cout << Verbose(2) << "Begin of FindSecondPointForTesselation" << endl; 2169 2162 Vector AngleCheck; 2170 2163 class TesselPoint* Candidate = NULL; 2171 double norm = -1., angle; 2172 LinkedNodes *List = NULL; 2173 int N[NDIM], Nlower[NDIM], Nupper[NDIM]; 2164 double norm = -1.; 2165 double angle = 0.; 2166 int N[NDIM]; 2167 int Nlower[NDIM]; 2168 int Nupper[NDIM]; 2174 2169 2175 2170 if (LC->SetIndexToNode(a)) { // get cell for the starting point … … 2197 2192 for (LC->n[1] = Nlower[1]; LC->n[1] <= Nupper[1]; LC->n[1]++) 2198 2193 for (LC->n[2] = Nlower[2]; LC->n[2] <= Nupper[2]; LC->n[2]++) { 2199 List = LC->GetCurrentCell();2194 const LinkedNodes *List = LC->GetCurrentCell(); 2200 2195 //cout << Verbose(2) << "Current cell is " << LC->n[0] << ", " << LC->n[1] << ", " << LC->n[2] << " with No. " << LC->index << "." << endl; 2201 2196 if (List != NULL) { 2202 for (LinkedNodes:: iterator Runner = List->begin(); Runner != List->end(); Runner++) {2197 for (LinkedNodes::const_iterator Runner = List->begin(); Runner != List->end(); Runner++) { 2203 2198 Candidate = (*Runner); 2204 2199 // check if we only have one unique point yet ... … … 2284 2279 * @param *LC LinkedCell structure with neighbouring points 2285 2280 */ 2286 void Tesselation::FindThirdPointForTesselation(Vector NormalVector, Vector SearchDirection, Vector OldSphereCenter, class BoundaryLineSet *BaseLine, class TesselPoint *ThirdNode, CandidateList* &candidates, double *ShortestAngle, const double RADIUS, LinkedCell *LC)2281 void Tesselation::FindThirdPointForTesselation(Vector NormalVector, Vector SearchDirection, Vector OldSphereCenter, class BoundaryLineSet *BaseLine, class TesselPoint *ThirdNode, CandidateList* &candidates, double *ShortestAngle, const double RADIUS, const LinkedCell *LC) 2287 2282 { 2288 2283 Vector CircleCenter; // center of the circle, i.e. of the band of sphere's centers … … 2293 2288 Vector NewNormalVector; // normal vector of the Candidate's triangle 2294 2289 Vector helper, OptCandidateCenter, OtherOptCandidateCenter; 2295 LinkedNodes *List = NULL;2296 2290 double CircleRadius; // radius of this circle 2297 2291 double radius; … … 2356 2350 for (LC->n[1] = Nlower[1]; LC->n[1] <= Nupper[1]; LC->n[1]++) 2357 2351 for (LC->n[2] = Nlower[2]; LC->n[2] <= Nupper[2]; LC->n[2]++) { 2358 List = LC->GetCurrentCell();2352 const LinkedNodes *List = LC->GetCurrentCell(); 2359 2353 //cout << Verbose(2) << "Current cell is " << LC->n[0] << ", " << LC->n[1] << ", " << LC->n[2] << " with No. " << LC->index << "." << endl; 2360 2354 if (List != NULL) { 2361 for (LinkedNodes:: iterator Runner = List->begin(); Runner != List->end(); Runner++) {2355 for (LinkedNodes::const_iterator Runner = List->begin(); Runner != List->end(); Runner++) { 2362 2356 Candidate = (*Runner); 2363 2357 … … 2367 2361 2368 2362 // construct both new centers 2369 GetCenterofCircumcircle(&NewSphereCenter, BaseLine->endpoints[0]->node->node, BaseLine->endpoints[1]->node->node,Candidate->node);2363 GetCenterofCircumcircle(&NewSphereCenter, *BaseLine->endpoints[0]->node->node, *BaseLine->endpoints[1]->node->node, *Candidate->node); 2370 2364 OtherNewSphereCenter.CopyVector(&NewSphereCenter); 2371 2365 … … 2470 2464 * \return point which is shared or NULL if none 2471 2465 */ 2472 class BoundaryPointSet *Tesselation::GetCommonEndpoint(class BoundaryLineSet * line1, class BoundaryLineSet * line2) 2473 { 2474 class BoundaryLineSet * lines[2] = 2475 { line1, line2 }; 2466 class BoundaryPointSet *Tesselation::GetCommonEndpoint(const BoundaryLineSet * line1, const BoundaryLineSet * line2) const 2467 { 2468 const BoundaryLineSet * lines[2] = { line1, line2 }; 2476 2469 class BoundaryPointSet *node = NULL; 2477 2470 map<int, class BoundaryPointSet *> OrderMap; … … 2501 2494 * \return list of BoundaryTriangleSet of nearest triangles or NULL in degenerate case. 2502 2495 */ 2503 list<BoundaryTriangleSet*> * Tesselation::FindClosestTrianglesToPoint(ofstream *out, Vector *x, LinkedCell* LC)2496 list<BoundaryTriangleSet*> * Tesselation::FindClosestTrianglesToPoint(ofstream *out, const Vector *x, const LinkedCell* LC) const 2504 2497 { 2505 2498 TesselPoint *trianglePoints[3]; … … 2511 2504 return NULL; 2512 2505 } 2513 2506 *out << Verbose(1) << "Finding closest Tesselpoint to " << *x << " ... " << endl; 2514 2507 trianglePoints[0] = FindClosestPoint(x, SecondPoint, LC); 2515 2508 … … 2521 2514 if (trianglePoints[0]->node->DistanceSquared(x) < MYEPSILON) { 2522 2515 *out << Verbose(3) << "Point is right on a tesselation point, no nearest triangle." << endl; 2523 PointMap:: iterator PointRunner = PointsOnBoundary.find(trianglePoints[0]->nr);2516 PointMap::const_iterator PointRunner = PointsOnBoundary.find(trianglePoints[0]->nr); 2524 2517 triangles = new list<BoundaryTriangleSet*>; 2525 2518 if (PointRunner != PointsOnBoundary.end()) { … … 2545 2538 } else { 2546 2539 list<TesselPoint*> *connectedClosestPoints = GetCircleOfConnectedPoints(out, trianglePoints[0], x); 2547 trianglePoints[1] = connectedClosestPoints->front(); 2548 trianglePoints[2] = connectedClosestPoints->back(); 2549 for (int i=0;i<3;i++) { 2550 if (trianglePoints[i] == NULL) { 2551 *out << Verbose(1) << "ERROR: IsInnerPoint encounters serious error, point " << i << " not found." << endl; 2540 if (connectedClosestPoints != NULL) { 2541 trianglePoints[1] = connectedClosestPoints->front(); 2542 trianglePoints[2] = connectedClosestPoints->back(); 2543 for (int i=0;i<3;i++) { 2544 if (trianglePoints[i] == NULL) { 2545 *out << Verbose(1) << "ERROR: IsInnerPoint encounters serious error, point " << i << " not found." << endl; 2546 } 2547 //*out << Verbose(2) << "List of triangle points:" << endl; 2548 //*out << Verbose(3) << *trianglePoints[i] << endl; 2552 2549 } 2553 //*out << Verbose(2) << "List of triangle points:" << endl; 2554 //*out << Verbose(3) << *trianglePoints[i] << endl; 2555 } 2556 2557 triangles = FindTriangles(trianglePoints); 2558 *out << Verbose(2) << "List of possible triangles:" << endl; 2559 for(list<BoundaryTriangleSet*>::iterator Runner = triangles->begin(); Runner != triangles->end(); Runner++) 2560 *out << Verbose(3) << **Runner << endl; 2561 2562 delete(connectedClosestPoints); 2550 2551 triangles = FindTriangles(trianglePoints); 2552 *out << Verbose(2) << "List of possible triangles:" << endl; 2553 for(list<BoundaryTriangleSet*>::iterator Runner = triangles->begin(); Runner != triangles->end(); Runner++) 2554 *out << Verbose(3) << **Runner << endl; 2555 2556 delete(connectedClosestPoints); 2557 } else { 2558 triangles = NULL; 2559 *out << Verbose(1) << "There is no circle of connected points!" << endl; 2560 } 2563 2561 } 2564 2562 2565 if ( triangles->empty()) {2563 if ((triangles == NULL) || (triangles->empty())) { 2566 2564 *out << Verbose(0) << "ERROR: There is no nearest triangle. Please check the tesselation structure."; 2567 2565 delete(triangles); … … 2577 2575 * \return list of BoundaryTriangleSet of nearest triangles or NULL. 2578 2576 */ 2579 class BoundaryTriangleSet * Tesselation::FindClosestTriangleToPoint(ofstream *out, Vector *x, LinkedCell* LC)2577 class BoundaryTriangleSet * Tesselation::FindClosestTriangleToPoint(ofstream *out, const Vector *x, const LinkedCell* LC) const 2580 2578 { 2581 2579 class BoundaryTriangleSet *result = NULL; … … 2613 2611 * @return true if the point is inside the tesselation structure, false otherwise 2614 2612 */ 2615 bool Tesselation::IsInnerPoint(ofstream *out, Vector Point, LinkedCell* LC)2613 bool Tesselation::IsInnerPoint(ofstream *out, const Vector &Point, const LinkedCell* const LC) const 2616 2614 { 2617 2615 class BoundaryTriangleSet *result = FindClosestTriangleToPoint(out, &Point, LC); … … 2643 2641 * @return true if the point is inside the tesselation structure, false otherwise 2644 2642 */ 2645 bool Tesselation::IsInnerPoint(ofstream *out, TesselPoint *Point, LinkedCell* LC)2643 bool Tesselation::IsInnerPoint(ofstream *out, const TesselPoint * const Point, const LinkedCell* const LC) const 2646 2644 { 2647 2645 return IsInnerPoint(out, *(Point->node), LC); … … 2654 2652 * @return set of the all points linked to the provided one 2655 2653 */ 2656 set<TesselPoint*> * Tesselation::GetAllConnectedPoints(ofstream *out, TesselPoint* Point)2654 set<TesselPoint*> * Tesselation::GetAllConnectedPoints(ofstream *out, const TesselPoint* const Point) const 2657 2655 { 2658 2656 set<TesselPoint*> *connectedPoints = new set<TesselPoint*>; … … 2661 2659 bool takePoint = false; 2662 2660 2661 *out << Verbose(3) << "Begin of GetAllConnectedPoints" << endl; 2662 2663 2663 // find the respective boundary point 2664 PointMap:: iterator PointRunner = PointsOnBoundary.find(Point->nr);2664 PointMap::const_iterator PointRunner = PointsOnBoundary.find(Point->nr); 2665 2665 if (PointRunner != PointsOnBoundary.end()) { 2666 2666 ReferencePoint = PointRunner->second; … … 2672 2672 // little trick so that we look just through lines connect to the BoundaryPoint 2673 2673 // OR fall-back to look through all lines if there is no such BoundaryPoint 2674 LineMap *Lines = &LinesOnBoundary;2674 const LineMap *Lines;; 2675 2675 if (ReferencePoint != NULL) 2676 2676 Lines = &(ReferencePoint->lines); 2677 LineMap::iterator findLines = Lines->begin(); 2677 else 2678 Lines = &LinesOnBoundary; 2679 LineMap::const_iterator findLines = Lines->begin(); 2678 2680 while (findLines != Lines->end()) { 2679 2681 takePoint = false; … … 2700 2702 } 2701 2703 2704 *out << Verbose(3) << "End of GetAllConnectedPoints" << endl; 2702 2705 return connectedPoints; 2703 2706 }; … … 2715 2718 * @return list of the all points linked to the provided one 2716 2719 */ 2717 list<TesselPoint*> * Tesselation::GetCircleOfConnectedPoints(ofstream *out, TesselPoint* Point, Vector *Reference)2720 list<TesselPoint*> * Tesselation::GetCircleOfConnectedPoints(ofstream *out, const TesselPoint* const Point, const Vector * const Reference) const 2718 2721 { 2719 2722 map<double, TesselPoint*> anglesOfPoints; … … 2726 2729 Vector helper; 2727 2730 2731 if (connectedPoints == NULL) { 2732 *out << Verbose(2) << "Could not find any connected points!" << endl; 2733 delete(connectedCircle); 2734 return NULL; 2735 } 2736 *out << Verbose(2) << "Begin of GetCircleOfConnectedPoints" << endl; 2737 2728 2738 // calculate central point 2729 for (set<TesselPoint*>:: iterator TesselRunner = connectedPoints->begin(); TesselRunner != connectedPoints->end(); TesselRunner++)2739 for (set<TesselPoint*>::const_iterator TesselRunner = connectedPoints->begin(); TesselRunner != connectedPoints->end(); TesselRunner++) 2730 2740 center.AddVector((*TesselRunner)->node); 2731 2741 //*out << "Summed vectors " << center << "; number of points " << connectedPoints.size() … … 2741 2751 2742 2752 // construct one orthogonal vector 2743 if (Reference != NULL) 2753 if (Reference != NULL) { 2744 2754 AngleZero.CopyVector(Reference); 2755 AngleZero.SubtractVector(Point->node); 2756 AngleZero.ProjectOntoPlane(&PlaneNormal); 2757 } 2758 if ((Reference == NULL) || (AngleZero.NormSquared() < MYEPSILON )) { 2759 *out << Verbose(4) << "Using alternatively " << *(*connectedPoints->begin())->node << " as angle 0 referencer." << endl; 2760 AngleZero.CopyVector((*connectedPoints->begin())->node); 2761 AngleZero.SubtractVector(Point->node); 2762 AngleZero.ProjectOntoPlane(&PlaneNormal); 2763 if (AngleZero.NormSquared() < MYEPSILON) { 2764 cerr << Verbose(0) << "CRITIAL: AngleZero is 0 even with alternative reference. The algorithm has to be changed here!" << endl; 2765 performCriticalExit(); 2766 } 2767 } 2768 *out << Verbose(4) << "INFO: Reference vector on this plane representing angle 0 is " << AngleZero << "." << endl; 2769 if (AngleZero.NormSquared() > MYEPSILON) 2770 OrthogonalVector.MakeNormalVector(&PlaneNormal, &AngleZero); 2745 2771 else 2746 AngleZero.CopyVector((*connectedPoints->begin())->node); 2747 AngleZero.SubtractVector(Point->node); 2748 AngleZero.ProjectOntoPlane(&PlaneNormal); 2749 *out << Verbose(4) << "INFO: Reference vector on this plane representing angle 0 is " << AngleZero << "." << endl; 2750 OrthogonalVector.MakeNormalVector(&PlaneNormal, &AngleZero); 2772 OrthogonalVector.MakeNormalVector(&PlaneNormal); 2751 2773 *out << Verbose(4) << "INFO: OrthogonalVector on plane is " << OrthogonalVector << "." << endl; 2752 2774 … … 2766 2788 2767 2789 delete(connectedPoints); 2790 2791 *out << Verbose(2) << "End of GetCircleOfConnectedPoints" << endl; 2792 2768 2793 return connectedCircle; 2769 2794 } … … 2775 2800 * @return list of the all points linked to the provided one 2776 2801 */ 2777 list<list<TesselPoint*> *> * Tesselation::GetPathsOfConnectedPoints(ofstream *out, TesselPoint* Point)2802 list<list<TesselPoint*> *> * Tesselation::GetPathsOfConnectedPoints(ofstream *out, const TesselPoint* const Point) const 2778 2803 { 2779 2804 map<double, TesselPoint*> anglesOfPoints; … … 2792 2817 2793 2818 // find the respective boundary point 2794 PointMap:: iterator PointRunner = PointsOnBoundary.find(Point->nr);2819 PointMap::const_iterator PointRunner = PointsOnBoundary.find(Point->nr); 2795 2820 if (PointRunner != PointsOnBoundary.end()) { 2796 2821 ReferencePoint = PointRunner->second; … … 2890 2915 * @return list of the closed paths 2891 2916 */ 2892 list<list<TesselPoint*> *> * Tesselation::GetClosedPathsOfConnectedPoints(ofstream *out, TesselPoint* Point)2917 list<list<TesselPoint*> *> * Tesselation::GetClosedPathsOfConnectedPoints(ofstream *out, const TesselPoint* const Point) const 2893 2918 { 2894 2919 list<list<TesselPoint*> *> *ListofPaths = GetPathsOfConnectedPoints(out, Point); … … 2951 2976 * \return pointer to allocated list of triangles 2952 2977 */ 2953 set<BoundaryTriangleSet*> *Tesselation::GetAllTriangles(ofstream *out, c lass BoundaryPointSet *Point)2978 set<BoundaryTriangleSet*> *Tesselation::GetAllTriangles(ofstream *out, const BoundaryPointSet * const Point) const 2954 2979 { 2955 2980 set<BoundaryTriangleSet*> *connectedTriangles = new set<BoundaryTriangleSet*>; … … 2959 2984 } else { 2960 2985 // go through its lines and insert all triangles 2961 for (LineMap:: iterator LineRunner = Point->lines.begin(); LineRunner != Point->lines.end(); LineRunner++)2986 for (LineMap::const_iterator LineRunner = Point->lines.begin(); LineRunner != Point->lines.end(); LineRunner++) 2962 2987 for (TriangleMap::iterator TriangleRunner = (LineRunner->second)->triangles.begin(); TriangleRunner != (LineRunner->second)->triangles.end(); TriangleRunner++) { 2963 2988 connectedTriangles->insert(TriangleRunner->second); … … 3123 3148 AddTesselationTriangle(); 3124 3149 // calculate volume summand as a general tetraeder 3125 volume += CalculateVolumeofGeneralTetraeder( TPS[0]->node->node, TPS[1]->node->node, TPS[2]->node->node, &OldPoint);3150 volume += CalculateVolumeofGeneralTetraeder(*TPS[0]->node->node, *TPS[1]->node->node, *TPS[2]->node->node, OldPoint); 3126 3151 // advance number 3127 3152 count++; … … 3203 3228 * will usually be one, in case of degeneration, there will be two 3204 3229 */ 3205 list<BoundaryTriangleSet*> *Tesselation::FindTriangles( TesselPoint* Points[3])3230 list<BoundaryTriangleSet*> *Tesselation::FindTriangles(const TesselPoint* const Points[3]) const 3206 3231 { 3207 3232 list<BoundaryTriangleSet*> *result = new list<BoundaryTriangleSet*>; 3208 LineMap::iterator FindLine; 3209 PointMap::iterator FindPoint; 3210 TriangleMap::iterator FindTriangle; 3233 LineMap::const_iterator FindLine; 3234 TriangleMap::const_iterator FindTriangle; 3211 3235 class BoundaryPointSet *TrianglePoints[3]; 3212 3236 3213 3237 for (int i = 0; i < 3; i++) { 3214 FindPoint = PointsOnBoundary.find(Points[i]->nr);3238 PointMap::const_iterator FindPoint = PointsOnBoundary.find(Points[i]->nr); 3215 3239 if (FindPoint != PointsOnBoundary.end()) { 3216 3240 TrianglePoints[i] = FindPoint->second; … … 3223 3247 for (int i = 0; i < 3; i++) { 3224 3248 if (TrianglePoints[i] != NULL) { 3225 for (int j = i ; j < 3; j++) {3249 for (int j = i+1; j < 3; j++) { 3226 3250 if (TrianglePoints[j] != NULL) { 3227 FindLine = TrianglePoints[i]->lines.find(TrianglePoints[j]->node->nr);3228 if (FindLine != TrianglePoints[i]->lines.end()) {3229 for (; FindLine->first == TrianglePoints[j]->node->nr;FindLine++) {3230 3231 for (; FindTriangle != FindLine->second->triangles.end(); FindTriangle++) {3232 if (FindTriangle->second->IsPresentTupel(TrianglePoints)) {3233 result->push_back(FindTriangle->second);3234 }3251 for (FindLine = TrianglePoints[i]->lines.find(TrianglePoints[j]->node->nr); // is a multimap! 3252 (FindLine != TrianglePoints[i]->lines.end()) && (FindLine->first == TrianglePoints[j]->node->nr); 3253 FindLine++) { 3254 for (FindTriangle = FindLine->second->triangles.begin(); 3255 FindTriangle != FindLine->second->triangles.end(); 3256 FindTriangle++) { 3257 if (FindTriangle->second->IsPresentTupel(TrianglePoints)) { 3258 result->push_back(FindTriangle->second); 3235 3259 } 3236 3260 } 3237 // Is it sufficient to consider one of the triangle lines for this.3238 return result;3239 3240 3261 } 3262 // Is it sufficient to consider one of the triangle lines for this. 3263 return result; 3241 3264 } 3242 3265 } … … 3524 3547 * \param *cloud PointCloud structure with all nodes 3525 3548 */ 3526 void Tesselation::Output(ofstream *out, const char *filename, PointCloud *cloud)3549 void Tesselation::Output(ofstream *out, const char *filename, const PointCloud * const cloud) 3527 3550 { 3528 3551 ofstream *tempstream = NULL; -
src/tesselation.hpp
r06c7a3 r7326b2 24 24 #include <set> 25 25 26 #include "atom_particleinfo.hpp" 27 #include "helpers.hpp" 26 28 #include "vector.hpp" 27 29 … … 81 83 public: 82 84 BoundaryPointSet(); 83 BoundaryPointSet(TesselPoint * Walker);85 BoundaryPointSet(TesselPoint * Walker); 84 86 ~BoundaryPointSet(); 85 87 … … 93 95 }; 94 96 95 ostream & operator << (ostream &ost, BoundaryPointSet &a);97 ostream & operator << (ostream &ost, const BoundaryPointSet &a); 96 98 97 99 // ======================================================== class BoundaryLineSet ========================================== … … 100 102 public: 101 103 BoundaryLineSet(); 102 BoundaryLineSet(class BoundaryPointSet *Point[2], int number);104 BoundaryLineSet(class BoundaryPointSet *Point[2], const int number); 103 105 ~BoundaryLineSet(); 104 106 … … 114 116 }; 115 117 116 ostream & operator << (ostream &ost, BoundaryLineSet &a);118 ostream & operator << (ostream &ost, const BoundaryLineSet &a); 117 119 118 120 // ======================================================== class BoundaryTriangleSet ======================================= … … 140 142 }; 141 143 142 ostream & operator << (ostream &ost, BoundaryTriangleSet &a);144 ostream & operator << (ostream &ost, const BoundaryTriangleSet &a); 143 145 144 146 // =========================================================== class TESSELPOINT =========================================== … … 146 148 /** Is a single point of the set of Vectors, also a super-class to be inherited and and its functions to be implemented. 147 149 */ 148 class TesselPoint {150 class TesselPoint : virtual public ParticleInfo { 149 151 public: 150 152 TesselPoint(); … … 152 154 153 155 Vector *node; // pointer to position of the dot in space 154 int nr; // index to easierly identify155 char *Name; // some name to reference to on output156 156 157 157 virtual ostream & operator << (ostream &ost); … … 170 170 virtual ~PointCloud(); 171 171 172 virtual Vector *GetCenter(ofstream *out) { return NULL; };173 virtual TesselPoint *GetPoint() { return NULL; };174 virtual TesselPoint *GetTerminalPoint() { return NULL; };175 virtual void GoToNext() {};176 virtual void GoToPrevious() {};177 virtual void GoToFirst() {};178 virtual void GoToLast() {};179 virtual bool IsEmpty() { return false; };180 virtual bool IsEnd() { return false; };172 virtual Vector *GetCenter(ofstream *out) const { return NULL; }; 173 virtual TesselPoint *GetPoint() const { return NULL; }; 174 virtual TesselPoint *GetTerminalPoint() const { return NULL; }; 175 virtual void GoToNext() const {}; 176 virtual void GoToPrevious() const {}; 177 virtual void GoToFirst() const {}; 178 virtual void GoToLast() const {}; 179 virtual bool IsEmpty() const { return false; }; 180 virtual bool IsEnd() const { return false; }; 181 181 }; 182 182 … … 204 204 virtual ~Tesselation(); 205 205 206 void AddTesselationPoint(TesselPoint* Candidate, int n);207 void AddTesselationLine(class BoundaryPointSet *a, class BoundaryPointSet *b, int n);208 void AlwaysAddTesselationTriangleLine(class BoundaryPointSet *a, class BoundaryPointSet *b, int n);206 void AddTesselationPoint(TesselPoint* Candidate, const int n); 207 void AddTesselationLine(class BoundaryPointSet *a, class BoundaryPointSet *b, const int n); 208 void AlwaysAddTesselationTriangleLine(class BoundaryPointSet *a, class BoundaryPointSet *b, const int n); 209 209 void AddTesselationTriangle(); 210 void AddTesselationTriangle( int nr);210 void AddTesselationTriangle(const int nr); 211 211 void RemoveTesselationTriangle(class BoundaryTriangleSet *triangle); 212 212 void RemoveTesselationLine(class BoundaryLineSet *line); 213 213 void RemoveTesselationPoint(class BoundaryPointSet *point); 214 214 215 class BoundaryPointSet *GetCommonEndpoint(class BoundaryLineSet * line1, class BoundaryLineSet * line2);216 215 217 216 // concave envelope 218 void FindStartingTriangle(ofstream *out, const double RADIUS, c lassLinkedCell *LC);219 void FindSecondPointForTesselation(class TesselPoint* a, Vector Oben, class TesselPoint*& OptCandidate, double Storage[3], double RADIUS, c lassLinkedCell *LC);220 void FindThirdPointForTesselation(Vector NormalVector, Vector SearchDirection, Vector OldSphereCenter, class BoundaryLineSet *BaseLine, class TesselPoint *ThirdNode, CandidateList* &candidates, double *ShortestAngle, const double RADIUS, c lassLinkedCell *LC);221 bool FindNextSuitableTriangle(ofstream *out, BoundaryLineSet &Line, BoundaryTriangleSet &T, const double& RADIUS, LinkedCell *LC);217 void FindStartingTriangle(ofstream *out, const double RADIUS, const LinkedCell *LC); 218 void FindSecondPointForTesselation(class TesselPoint* a, Vector Oben, class TesselPoint*& OptCandidate, double Storage[3], double RADIUS, const LinkedCell *LC); 219 void FindThirdPointForTesselation(Vector NormalVector, Vector SearchDirection, Vector OldSphereCenter, class BoundaryLineSet *BaseLine, class TesselPoint *ThirdNode, CandidateList* &candidates, double *ShortestAngle, const double RADIUS, const LinkedCell *LC); 220 bool FindNextSuitableTriangle(ofstream *out, BoundaryLineSet &Line, BoundaryTriangleSet &T, const double& RADIUS, const LinkedCell *LC); 222 221 int CheckPresenceOfTriangle(ofstream *out, class TesselPoint *Candidates[3]); 223 222 class BoundaryTriangleSet * GetPresentTriangle(ofstream *out, TesselPoint *Candidates[3]); 224 223 225 224 // convex envelope 226 void TesselateOnBoundary(ofstream *out, PointCloud *cloud);225 void TesselateOnBoundary(ofstream *out, const PointCloud * const cloud); 227 226 void GuessStartingTriangle(ofstream *out); 228 bool InsertStraddlingPoints(ofstream *out, PointCloud *cloud,LinkedCell *LC);227 bool InsertStraddlingPoints(ofstream *out, const PointCloud *cloud, const LinkedCell *LC); 229 228 double RemovePointFromTesselatedSurface(ofstream *out, class BoundaryPointSet *point); 230 229 class BoundaryLineSet * FlipBaseline(ofstream *out, class BoundaryLineSet *Base); … … 236 235 void AddBoundaryPointByDegeneratedTriangle(ofstream *out, class TesselPoint *point, LinkedCell *LC); 237 236 238 set<TesselPoint*> * GetAllConnectedPoints(ofstream *out, TesselPoint* Point); 239 set<BoundaryTriangleSet*> *GetAllTriangles(ofstream *out, class BoundaryPointSet *Point); 240 list<list<TesselPoint*> *> * GetPathsOfConnectedPoints(ofstream *out, TesselPoint* Point); 241 list<list<TesselPoint*> *> * GetClosedPathsOfConnectedPoints(ofstream *out, TesselPoint* Point); 242 list<TesselPoint*> * GetCircleOfConnectedPoints(ofstream *out, TesselPoint* Point, Vector *Reference = NULL); 243 list<BoundaryTriangleSet*> *FindTriangles(TesselPoint* Points[3]); 244 list<BoundaryTriangleSet*> * FindClosestTrianglesToPoint(ofstream *out, Vector *x, LinkedCell* LC); 245 class BoundaryTriangleSet * FindClosestTriangleToPoint(ofstream *out, Vector *x, LinkedCell* LC); 246 bool IsInnerPoint(ofstream *out, Vector Point, LinkedCell* LC); 247 bool IsInnerPoint(ofstream *out, TesselPoint *Point, LinkedCell* LC); 248 bool AddBoundaryPoint(TesselPoint *Walker, int n); 237 set<TesselPoint*> * GetAllConnectedPoints(ofstream *out, const TesselPoint* const Point) const; 238 set<BoundaryTriangleSet*> *GetAllTriangles(ofstream *out, const BoundaryPointSet * const Point) const; 239 list<list<TesselPoint*> *> * GetPathsOfConnectedPoints(ofstream *out, const TesselPoint* const Point) const; 240 list<list<TesselPoint*> *> * GetClosedPathsOfConnectedPoints(ofstream *out, const TesselPoint* const Point) const; 241 list<TesselPoint*> * GetCircleOfConnectedPoints(ofstream *out, const TesselPoint* const Point, const Vector * const Reference = NULL) const; 242 class BoundaryPointSet *GetCommonEndpoint(const BoundaryLineSet * line1, const BoundaryLineSet * line2) const; 243 list<BoundaryTriangleSet*> *FindTriangles(const TesselPoint* const Points[3]) const; 244 list<BoundaryTriangleSet*> * FindClosestTrianglesToPoint(ofstream *out, const Vector *x, const LinkedCell* LC) const; 245 class BoundaryTriangleSet * FindClosestTriangleToPoint(ofstream *out, const Vector *x, const LinkedCell* LC) const; 246 bool IsInnerPoint(ofstream *out, const Vector &Point, const LinkedCell* const LC) const; 247 bool IsInnerPoint(ofstream *out, const TesselPoint * const Point, const LinkedCell* const LC) const; 248 bool AddBoundaryPoint(TesselPoint * Walker, const int n); 249 249 250 250 // print for debugging 251 void PrintAllBoundaryPoints(ofstream *out) ;252 void PrintAllBoundaryLines(ofstream *out) ;253 void PrintAllBoundaryTriangles(ofstream *out) ;251 void PrintAllBoundaryPoints(ofstream *out) const; 252 void PrintAllBoundaryLines(ofstream *out) const; 253 void PrintAllBoundaryTriangles(ofstream *out) const; 254 254 255 255 // store envelope in file 256 void Output(ofstream *out, const char *filename, PointCloud *cloud);256 void Output(ofstream *out, const char *filename, const PointCloud * const cloud); 257 257 258 258 PointMap PointsOnBoundary; … … 264 264 265 265 // PointCloud implementation for PointsOnBoundary 266 virtual Vector *GetCenter(ofstream *out) ;267 virtual TesselPoint *GetPoint() ;268 virtual TesselPoint *GetTerminalPoint() ;269 virtual void GoToNext() ;270 virtual void GoToPrevious() ;271 virtual void GoToFirst() ;272 virtual void GoToLast() ;273 virtual bool IsEmpty() ;274 virtual bool IsEnd() ;266 virtual Vector *GetCenter(ofstream *out) const; 267 virtual TesselPoint *GetPoint() const; 268 virtual TesselPoint *GetTerminalPoint() const; 269 virtual void GoToNext() const; 270 virtual void GoToPrevious() const; 271 virtual void GoToFirst() const; 272 virtual void GoToLast() const; 273 virtual bool IsEmpty() const; 274 virtual bool IsEnd() const; 275 275 276 276 class BoundaryPointSet *BPS[2]; … … 283 283 class BoundaryPointSet *TPS[3]; //this is a Storage for pointers to triangle points, this and BPS[2] needed due to AddLine restrictions 284 284 285 PointMap::iterator InternalPointer;285 mutable PointMap::const_iterator InternalPointer; 286 286 }; 287 287 -
src/tesselationhelpers.cpp
r06c7a3 r7326b2 14 14 #include "verbose.hpp" 15 15 16 double DetGet(gsl_matrix * A,int inPlace) {16 double DetGet(gsl_matrix * const A, const int inPlace) { 17 17 /* 18 18 inPlace = 1 => A is replaced with the LU decomposed copy. … … 42 42 }; 43 43 44 void GetSphere(Vector * center, Vector &a, Vector &b, Vector &c,double RADIUS)44 void GetSphere(Vector * const center, const Vector &a, const Vector &b, const Vector &c, const double RADIUS) 45 45 { 46 46 gsl_matrix *A = gsl_matrix_calloc(3,3); … … 96 96 * @param b vector second point of triangle 97 97 * @param c vector third point of triangle 98 * @param *Umkreismittelpunkt new c neter point of circumference98 * @param *Umkreismittelpunkt new center point of circumference 99 99 * @param Direction vector indicates up/down 100 * @param AlternativeDirection vecotr, needed in case the triangles have 90 deg angle100 * @param AlternativeDirection Vector, needed in case the triangles have 90 deg angle 101 101 * @param Halfplaneindicator double indicates whether Direction is up or down 102 * @param AlternativeIndicator doub e indicates in case of orthogonal triangles which direction of AlternativeDirection is suitable102 * @param AlternativeIndicator double indicates in case of orthogonal triangles which direction of AlternativeDirection is suitable 103 103 * @param alpha double angle at a 104 104 * @param beta double, angle at b … … 107 107 * @param Umkreisradius double radius of circumscribing circle 108 108 */ 109 void GetCenterOfSphere(Vector* Center, Vector a, Vector b, Vector c, Vector *NewUmkreismittelpunkt, Vector* Direction, Vector*AlternativeDirection,110 double HalfplaneIndicator, double AlternativeIndicator, double alpha, double beta, double gamma, double RADIUS,double Umkreisradius)109 void GetCenterOfSphere(Vector* const & Center, const Vector &a, const Vector &b, const Vector &c, Vector * const NewUmkreismittelpunkt, const Vector* const Direction, const Vector* const AlternativeDirection, 110 const double HalfplaneIndicator, const double AlternativeIndicator, const double alpha, const double beta, const double gamma, const double RADIUS, const double Umkreisradius) 111 111 { 112 112 Vector TempNormal, helper; … … 171 171 * \param *c third point 172 172 */ 173 void GetCenterofCircumcircle(Vector * Center, Vector *a, Vector *b, Vector *c)173 void GetCenterofCircumcircle(Vector * const Center, const Vector &a, const Vector &b, const Vector &c) 174 174 { 175 175 Vector helper; … … 177 177 Vector SideA, SideB, SideC; 178 178 SideA.CopyVector(b); 179 SideA.SubtractVector( c);179 SideA.SubtractVector(&c); 180 180 SideB.CopyVector(c); 181 SideB.SubtractVector( a);181 SideB.SubtractVector(&a); 182 182 SideC.CopyVector(a); 183 SideC.SubtractVector( b);183 SideC.SubtractVector(&b); 184 184 alpha = M_PI - SideB.Angle(&SideC); 185 185 beta = M_PI - SideC.Angle(&SideA); … … 215 215 * \return Angle between \a NewSphereCenter and \a OldSphereCenter relative to \a CircleCenter, 2.*M_PI if one test fails 216 216 */ 217 double GetPathLengthonCircumCircle( Vector &CircleCenter, Vector &CirclePlaneNormal, double CircleRadius, Vector &NewSphereCenter, Vector &OldSphereCenter, Vector &NormalVector,Vector &SearchDirection)217 double GetPathLengthonCircumCircle(const Vector &CircleCenter, const Vector &CirclePlaneNormal, const double CircleRadius, const Vector &NewSphereCenter, const Vector &OldSphereCenter, const Vector &NormalVector, const Vector &SearchDirection) 218 218 { 219 219 Vector helper; … … 300 300 * @return true if there is an intersection between the given lines, false otherwise 301 301 */ 302 bool existsIntersection( Vector point1, Vector point2, Vector point3, Vectorpoint4)302 bool existsIntersection(const Vector &point1, const Vector &point2, const Vector &point3, const Vector &point4) 303 303 { 304 304 bool result; … … 403 403 * @return angle between point and reference 404 404 */ 405 double GetAngle(const Vector &point, const Vector &reference, const Vector OrthogonalVector)405 double GetAngle(const Vector &point, const Vector &reference, const Vector &OrthogonalVector) 406 406 { 407 407 if (reference.IsZero()) … … 429 429 * \return \f$ \frac{1}{6} \cdot ((a-d) \times (a-c) \cdot (a-b)) \f$ 430 430 */ 431 double CalculateVolumeofGeneralTetraeder( Vector *a, Vector *b, Vector *c, Vector *d)431 double CalculateVolumeofGeneralTetraeder(const Vector &a, const Vector &b, const Vector &c, const Vector &d) 432 432 { 433 433 Vector Point, TetraederVector[3]; … … 438 438 TetraederVector[2].CopyVector(c); 439 439 for (int j=0;j<3;j++) 440 TetraederVector[j].SubtractVector( d);440 TetraederVector[j].SubtractVector(&d); 441 441 Point.CopyVector(&TetraederVector[0]); 442 442 Point.VectorProduct(&TetraederVector[1]); … … 452 452 * \return true - there is such a line (i.e. creation of degenerated triangle is valid), false - no such line (don't create) 453 453 */ 454 bool CheckLineCriteriaForDegeneratedTriangle(c lass BoundaryPointSet *nodes[3])454 bool CheckLineCriteriaForDegeneratedTriangle(const BoundaryPointSet * const nodes[3]) 455 455 { 456 456 bool result = false; … … 461 461 for (int j=i+1; j<3; j++) { 462 462 if (nodes[i]->lines.find(nodes[j]->node->nr) != nodes[i]->lines.end()) { // there already is a line 463 LineMap:: iterator FindLine;464 pair<LineMap:: iterator,LineMap::iterator> FindPair;463 LineMap::const_iterator FindLine; 464 pair<LineMap::const_iterator,LineMap::const_iterator> FindPair; 465 465 FindPair = nodes[i]->lines.equal_range(nodes[j]->node->nr); 466 466 for (FindLine = FindPair.first; FindLine != FindPair.second; ++FindLine) { … … 486 486 /** Sort function for the candidate list. 487 487 */ 488 bool SortCandidates( CandidateForTesselation* candidate1,CandidateForTesselation* candidate2)488 bool SortCandidates(const CandidateForTesselation* candidate1, const CandidateForTesselation* candidate2) 489 489 { 490 490 Vector BaseLineVector, OrthogonalVector, helper; … … 536 536 * @return point which is second closest to the provided one 537 537 */ 538 TesselPoint* FindSecondClosestPoint(const Vector* Point, LinkedCell* LC) 539 { 540 LinkedNodes *List = NULL; 538 TesselPoint* FindSecondClosestPoint(const Vector* Point, const LinkedCell* const LC) 539 { 541 540 TesselPoint* closestPoint = NULL; 542 541 TesselPoint* secondClosestPoint = NULL; … … 556 555 for (LC->n[1] = Nlower[1]; LC->n[1] <= Nupper[1]; LC->n[1]++) 557 556 for (LC->n[2] = Nlower[2]; LC->n[2] <= Nupper[2]; LC->n[2]++) { 558 List = LC->GetCurrentCell();557 const LinkedNodes *List = LC->GetCurrentCell(); 559 558 //cout << Verbose(3) << "The current cell " << LC->n[0] << "," << LC->n[1] << "," << LC->n[2] << endl; 560 559 if (List != NULL) { 561 for (LinkedNodes:: iterator Runner = List->begin(); Runner != List->end(); Runner++) {560 for (LinkedNodes::const_iterator Runner = List->begin(); Runner != List->end(); Runner++) { 562 561 helper.CopyVector(Point); 563 562 helper.SubtractVector((*Runner)->node); … … 591 590 * @return point which is closest to the provided one, NULL if none found 592 591 */ 593 TesselPoint* FindClosestPoint(const Vector* Point, TesselPoint *&SecondPoint, LinkedCell* LC) 594 { 595 LinkedNodes *List = NULL; 592 TesselPoint* FindClosestPoint(const Vector* Point, TesselPoint *&SecondPoint, const LinkedCell* const LC) 593 { 596 594 TesselPoint* closestPoint = NULL; 597 595 SecondPoint = NULL; … … 611 609 for (LC->n[1] = Nlower[1]; LC->n[1] <= Nupper[1]; LC->n[1]++) 612 610 for (LC->n[2] = Nlower[2]; LC->n[2] <= Nupper[2]; LC->n[2]++) { 613 List = LC->GetCurrentCell();611 const LinkedNodes *List = LC->GetCurrentCell(); 614 612 //cout << Verbose(3) << "The current cell " << LC->n[0] << "," << LC->n[1] << "," << LC->n[2] << endl; 615 613 if (List != NULL) { 616 for (LinkedNodes:: iterator Runner = List->begin(); Runner != List->end(); Runner++) {614 for (LinkedNodes::const_iterator Runner = List->begin(); Runner != List->end(); Runner++) { 617 615 helper.CopyVector(Point); 618 616 helper.SubtractVector((*Runner)->node); … … 635 633 } 636 634 } 637 635 // output 636 if (closestPoint != NULL) { 637 cout << Verbose(2) << "Closest point is " << *closestPoint; 638 if (SecondPoint != NULL) 639 cout << " and second closest is " << *SecondPoint; 640 cout << "." << endl; 641 } 638 642 return closestPoint; 639 643 }; … … 645 649 * \return Vector on reference line that has closest distance 646 650 */ 647 Vector * GetClosestPointBetweenLine(ofstream *out, c lass BoundaryLineSet *Base, class BoundaryLineSet *OtherBase)651 Vector * GetClosestPointBetweenLine(ofstream *out, const BoundaryLineSet * const Base, const BoundaryLineSet * const OtherBase) 648 652 { 649 653 // construct the plane of the two baselines (i.e. take both their directional vectors) … … 685 689 * \return distance between \a *x and plane defined by \a *triangle, -1 - if something went wrong 686 690 */ 687 double DistanceToTrianglePlane(ofstream * out, Vector *x, BoundaryTriangleSet *triangle)691 double DistanceToTrianglePlane(ofstream * const out, const Vector *x, const BoundaryTriangleSet * const triangle) 688 692 { 689 693 double distance = 0.; … … 701 705 * \param *mol molecule structure with atom positions 702 706 */ 703 void WriteVrmlFile(ofstream * out, ofstream *vrmlfile, class Tesselation *Tess, PointCloud *cloud)707 void WriteVrmlFile(ofstream * const out, ofstream * const vrmlfile, const Tesselation * const Tess, const PointCloud * const cloud) 704 708 { 705 709 TesselPoint *Walker = NULL; … … 722 726 723 727 *vrmlfile << "# All tesselation triangles" << endl; 724 for (TriangleMap:: iterator TriangleRunner = Tess->TrianglesOnBoundary.begin(); TriangleRunner != Tess->TrianglesOnBoundary.end(); TriangleRunner++) {728 for (TriangleMap::const_iterator TriangleRunner = Tess->TrianglesOnBoundary.begin(); TriangleRunner != Tess->TrianglesOnBoundary.end(); TriangleRunner++) { 725 729 *vrmlfile << "1" << endl << " "; // 1 is triangle type 726 730 for (i=0;i<3;i++) { // print each node … … 744 748 * \param *mol molecule structure with atom positions 745 749 */ 746 void IncludeSphereinRaster3D(ofstream * out, ofstream *rasterfile, class Tesselation *Tess, PointCloud *cloud)750 void IncludeSphereinRaster3D(ofstream * const out, ofstream * const rasterfile, const Tesselation * const Tess, const PointCloud * const cloud) 747 751 { 748 752 Vector helper; … … 769 773 * \param *mol molecule structure with atom positions 770 774 */ 771 void WriteRaster3dFile(ofstream * out, ofstream *rasterfile, class Tesselation *Tess, PointCloud *cloud)775 void WriteRaster3dFile(ofstream * const out, ofstream * const rasterfile, const Tesselation * const Tess, const PointCloud * const cloud) 772 776 { 773 777 TesselPoint *Walker = NULL; … … 791 795 *rasterfile << "# All tesselation triangles" << endl; 792 796 *rasterfile << "8\n 25. -1. 1. 1. 1. 0.0 0 0 0 2\n SOLID 1.0 0.0 0.0\n BACKFACE 0.3 0.3 1.0 0 0\n"; 793 for (TriangleMap:: iterator TriangleRunner = Tess->TrianglesOnBoundary.begin(); TriangleRunner != Tess->TrianglesOnBoundary.end(); TriangleRunner++) {797 for (TriangleMap::const_iterator TriangleRunner = Tess->TrianglesOnBoundary.begin(); TriangleRunner != Tess->TrianglesOnBoundary.end(); TriangleRunner++) { 794 798 *rasterfile << "1" << endl << " "; // 1 is triangle type 795 799 for (i=0;i<3;i++) { // print each node … … 814 818 * \param N arbitrary number to differentiate various zones in the tecplot format 815 819 */ 816 void WriteTecplotFile(ofstream * out, ofstream *tecplot, class Tesselation *TesselStruct, PointCloud *cloud,int N)820 void WriteTecplotFile(ofstream * const out, ofstream * const tecplot, const Tesselation * const TesselStruct, const PointCloud * const cloud, const int N) 817 821 { 818 822 if ((tecplot != NULL) && (TesselStruct != NULL)) { … … 834 838 int Counter = 1; 835 839 TesselPoint *Walker = NULL; 836 for (PointMap:: iterator target = TesselStruct->PointsOnBoundary.begin(); target != TesselStruct->PointsOnBoundary.end(); target++) {840 for (PointMap::const_iterator target = TesselStruct->PointsOnBoundary.begin(); target != TesselStruct->PointsOnBoundary.end(); target++) { 837 841 Walker = target->second->node; 838 842 LookupList[Walker->nr] = Counter++; … … 841 845 *tecplot << endl; 842 846 // print connectivity 843 for (TriangleMap:: iterator runner = TesselStruct->TrianglesOnBoundary.begin(); runner != TesselStruct->TrianglesOnBoundary.end(); runner++) {847 for (TriangleMap::const_iterator runner = TesselStruct->TrianglesOnBoundary.begin(); runner != TesselStruct->TrianglesOnBoundary.end(); runner++) { 844 848 *out << " " << runner->second->endpoints[0]->node->Name << "<->" << runner->second->endpoints[1]->node->Name << "<->" << runner->second->endpoints[2]->node->Name; 845 849 *tecplot << LookupList[runner->second->endpoints[0]->node->nr] << " " << LookupList[runner->second->endpoints[1]->node->nr] << " " << LookupList[runner->second->endpoints[2]->node->nr] << endl; … … 855 859 * \param *TesselStruct pointer to Tesselation structure 856 860 */ 857 void CalculateConcavityPerBoundaryPoint(ofstream * out, class Tesselation *TesselStruct)861 void CalculateConcavityPerBoundaryPoint(ofstream * const out, const Tesselation * const TesselStruct) 858 862 { 859 863 class BoundaryPointSet *point = NULL; … … 862 866 //*out << Verbose(2) << "Begin of CalculateConcavityPerBoundaryPoint" << endl; 863 867 // calculate remaining concavity 864 for (PointMap:: iterator PointRunner = TesselStruct->PointsOnBoundary.begin(); PointRunner != TesselStruct->PointsOnBoundary.end(); PointRunner++) {868 for (PointMap::const_iterator PointRunner = TesselStruct->PointsOnBoundary.begin(); PointRunner != TesselStruct->PointsOnBoundary.end(); PointRunner++) { 865 869 point = PointRunner->second; 866 870 *out << Verbose(1) << "INFO: Current point is " << *point << "." << endl; … … 882 886 * \return true - all have exactly two triangles, false - some not, list is printed to screen 883 887 */ 884 bool CheckListOfBaselines(ofstream * out, Tesselation *TesselStruct)885 { 886 LineMap:: iterator testline;888 bool CheckListOfBaselines(ofstream * const out, const Tesselation * const TesselStruct) 889 { 890 LineMap::const_iterator testline; 887 891 bool result = false; 888 892 int counter = 0; -
src/tesselationhelpers.hpp
r06c7a3 r7326b2 47 47 /********************************************** declarations *******************************/ 48 48 49 double DetGet(gsl_matrix * A,int inPlace);50 void GetSphere(Vector * center, Vector &a, Vector &b, Vector &c,double RADIUS);51 void GetCenterOfSphere(Vector* Center, Vector a, Vector b, Vector c, Vector *NewUmkreismittelpunkt, Vector* Direction, Vector* AlternativeDirection, double HalfplaneIndicator, double AlternativeIndicator, double alpha, double beta, double gamma, double RADIUS,double Umkreisradius);52 void GetCenterofCircumcircle(Vector * Center, Vector *a, Vector *b, Vector *c);53 double GetPathLengthonCircumCircle( Vector &CircleCenter, Vector &CirclePlaneNormal, double CircleRadius, Vector &NewSphereCenter, Vector &OldSphereCenter, Vector &NormalVector,Vector &SearchDirection);49 double DetGet(gsl_matrix * const A, const int inPlace); 50 void GetSphere(Vector * const Center, const Vector &a, const Vector &b, const Vector &c, const double RADIUS); 51 void GetCenterOfSphere(Vector* const Center, const Vector &a, const Vector &b, const Vector &c, Vector * const NewUmkreismittelpunkt, const Vector* const Direction, const Vector* const AlternativeDirection, const double HalfplaneIndicator, const double AlternativeIndicator, const double alpha, const double beta, const double gamma, const double RADIUS, const double Umkreisradius); 52 void GetCenterofCircumcircle(Vector * const Center, const Vector &a, const Vector &b, const Vector &c); 53 double GetPathLengthonCircumCircle(const Vector &CircleCenter, const Vector &CirclePlaneNormal, const double CircleRadius, const Vector &NewSphereCenter, const Vector &OldSphereCenter, const Vector &NormalVector, const Vector &SearchDirection); 54 54 double MinIntersectDistance(const gsl_vector * x, void *params); 55 bool existsIntersection( Vector point1, Vector point2, Vector point3, Vectorpoint4);56 double CalculateVolumeofGeneralTetraeder( Vector *a, Vector *b, Vector *c, Vector *d);57 double GetAngle(const Vector &point, const Vector &reference, const Vector OrthogonalVector);55 bool existsIntersection(const Vector &point1, const Vector &point2, const Vector &point3, const Vector &point4); 56 double CalculateVolumeofGeneralTetraeder(const Vector &a, const Vector &b, const Vector &c, const Vector &d); 57 double GetAngle(const Vector &point, const Vector &reference, const Vector &OrthogonalVector); 58 58 59 bool CheckLineCriteriaForDegeneratedTriangle(c lass BoundaryPointSet *nodes[3]);60 bool SortCandidates(c lass CandidateForTesselation* candidate1, class CandidateForTesselation*candidate2);61 TesselPoint* FindClosestPoint(const Vector* Point, TesselPoint *&SecondPoint, LinkedCell*LC);62 TesselPoint* FindSecondClosestPoint(const Vector*, LinkedCell*);63 Vector * GetClosestPointBetweenLine(ofstream *out, c lass BoundaryLineSet *Base, class BoundaryLineSet *OtherBase);59 bool CheckLineCriteriaForDegeneratedTriangle(const BoundaryPointSet * const nodes[3]); 60 bool SortCandidates(const CandidateForTesselation* candidate1, const CandidateForTesselation *candidate2); 61 TesselPoint* FindClosestPoint(const Vector* Point, TesselPoint *&SecondPoint, const LinkedCell* const LC); 62 TesselPoint* FindSecondClosestPoint(const Vector*, const LinkedCell* const LC); 63 Vector * GetClosestPointBetweenLine(ofstream *out, const BoundaryLineSet * const Base, const BoundaryLineSet * const OtherBase); 64 64 65 void WriteTecplotFile(ofstream * out, ofstream *tecplot, class Tesselation *TesselStruct, PointCloud *cloud,int N);66 void WriteRaster3dFile(ofstream * out, ofstream *rasterfile, class Tesselation *Tess, PointCloud *cloud);67 void IncludeSphereinRaster3D(ofstream * out, ofstream *rasterfile, class Tesselation *Tess,PointCloud *cloud);68 void WriteVrmlFile(ofstream * out, ofstream *vrmlfile, class Tesselation *Tess, PointCloud *cloud);69 void CalculateConcavityPerBoundaryPoint(ofstream * out, class Tesselation *TesselStruct);70 double DistanceToTrianglePlane(ofstream * out, Vector *x, BoundaryTriangleSet *triangle);65 void WriteTecplotFile(ofstream * const out, ofstream * const tecplot, const Tesselation * const TesselStruct, const PointCloud * const cloud, const int N); 66 void WriteRaster3dFile(ofstream * const out, ofstream * const rasterfile, const Tesselation * const Tess, const PointCloud * const cloud); 67 void IncludeSphereinRaster3D(ofstream * const out, ofstream * const rasterfile, const Tesselation *Tess, const PointCloud *cloud); 68 void WriteVrmlFile(ofstream * const out, ofstream * const vrmlfile, const Tesselation * const Tess, const PointCloud * const cloud); 69 void CalculateConcavityPerBoundaryPoint(ofstream * const out, const Tesselation * const TesselStruct); 70 double DistanceToTrianglePlane(ofstream * const out, const Vector *x, const BoundaryTriangleSet * const triangle); 71 71 72 bool CheckListOfBaselines(ofstream * out, Tesselation *TesselStruct);72 bool CheckListOfBaselines(ofstream * const out, const Tesselation * const TesselStruct); 73 73 74 74 -
src/unittests/ActOnAllUnitTest.cpp
r06c7a3 r7326b2 12 12 #include <cppunit/ui/text/TestRunner.h> 13 13 14 #include " ActOnAlltest.hpp"14 #include "../test/ActOnAlltest.hpp" 15 15 #include "ActOnAllUnitTest.hpp" 16 16 #include "memoryallocator.hpp" … … 62 62 63 63 // scaling by value 64 VL.ActOnAll( (void (Vector::*)( double)) &Vector::Scale, 2. );64 VL.ActOnAll( (void (Vector::*)(const double)) &Vector::Scale, 2. ); 65 65 CPPUNIT_ASSERT_EQUAL( VL == Ref , false ); 66 66 67 VL.ActOnAll( (void (Vector::*)( double)) &Vector::Scale, 0.5 );67 VL.ActOnAll( (void (Vector::*)(const double)) &Vector::Scale, 0.5 ); 68 68 CPPUNIT_ASSERT_EQUAL( VL == Ref , true ); 69 69 70 70 // scaling by ref 71 VL.ActOnAll( (void (Vector::*)( double *)) &Vector::Scale,&factor );71 VL.ActOnAll( (void (Vector::*)(const double * const)) &Vector::Scale, (const double * const)&factor ); 72 72 CPPUNIT_ASSERT_EQUAL( VL == Ref , false ); 73 73 74 VL.ActOnAll( (void (Vector::*)( double *)) &Vector::Scale,&inverse );74 VL.ActOnAll( (void (Vector::*)(const double * const)) &Vector::Scale, (const double * const)&inverse ); 75 75 CPPUNIT_ASSERT_EQUAL( VL == Ref , true ); 76 76 … … 82 82 inverses[i] = 1./factors[i]; 83 83 } 84 VL.ActOnAll( (void (Vector::*)( double **)) &Vector::Scale,&factors );84 VL.ActOnAll( (void (Vector::*)(const double ** const)) &Vector::Scale, (const double ** const)&factors ); 85 85 CPPUNIT_ASSERT_EQUAL( VL == Ref , false ); 86 86 87 VL.ActOnAll( (void (Vector::*)( double **)) &Vector::Scale,&inverses );87 VL.ActOnAll( (void (Vector::*)(const double ** const)) &Vector::Scale, (const double ** const)&inverses ); 88 88 CPPUNIT_ASSERT_EQUAL( VL == Ref , true ); 89 89 }; -
src/unittests/ActOnAllUnitTest.hpp
r06c7a3 r7326b2 11 11 #include <cppunit/extensions/HelperMacros.h> 12 12 13 #include " ActOnAlltest.hpp"13 #include "../test/ActOnAlltest.hpp" 14 14 15 15 /********************************************** Test classes **************************************/ -
src/unittests/AnalysisCorrelationToPointUnitTest.cpp
r06c7a3 r7326b2 33 33 34 34 // init private all pointers to zero 35 TestList = NULL; 35 36 TestMolecule = NULL; 36 37 hydrogen = NULL; … … 44 45 hydrogen->Z = 1; 45 46 strcpy(hydrogen->name, "hydrogen"); 46 hydrogen->symbol[0] = 'H'; 47 strcpy(hydrogen->symbol, "H"); 48 47 49 48 50 // construct periodentafel … … 72 74 CPPUNIT_ASSERT_EQUAL( TestMolecule->AtomCount, 4 ); 73 75 76 TestList = new MoleculeListClass; 77 TestMolecule->ActiveFlag = true; 78 TestList->insert(TestMolecule); 79 74 80 // init point 75 81 point = new Vector(1.,1.,1.); 76 82 77 83 // init maps 78 pointmap = CorrelationToPoint( (ofstream *)&cout, TestMolecule, hydrogen,point );84 pointmap = CorrelationToPoint( (ofstream *)&cout, (MoleculeListClass * const)TestList, (const element * const)hydrogen, (const Vector *)point ); 79 85 binmap = NULL; 80 86 … … 90 96 91 97 // remove 92 delete(Test Molecule);98 delete(TestList); 93 99 // note that all the atoms are cleaned by TestMolecule 94 100 delete(point); -
src/unittests/AnalysisCorrelationToPointUnitTest.hpp
r06c7a3 r7326b2 12 12 13 13 class element; 14 class LinkedCell; 14 15 class molecule; 15 class LinkedCell;16 class MoleculeListClass; 16 17 class periodentafel; 17 18 class Tesselation; … … 37 38 private: 38 39 40 MoleculeListClass *TestList; 39 41 molecule *TestMolecule; 40 42 element *hydrogen; -
src/unittests/AnalysisCorrelationToSurfaceUnitTest.cpp
r06c7a3 r7326b2 33 33 34 34 // init private all pointers to zero 35 TestList = NULL; 35 36 TestMolecule = NULL; 36 37 hydrogen = NULL; … … 41 42 LC = NULL; 42 43 43 44 44 // construct element 45 45 hydrogen = new element; 46 46 hydrogen->Z = 1; 47 47 strcpy(hydrogen->name, "hydrogen"); 48 hydrogen->symbol[0] = 'H'; 48 strcpy(hydrogen->symbol, "H"); 49 carbon = new element; 50 carbon->Z = 6; 51 strcpy(carbon->name, "carbon"); 52 strcpy(carbon->symbol, "C"); 49 53 50 54 // construct periodentafel 51 55 tafel = new periodentafel; 52 56 tafel->AddElement(hydrogen); 53 54 // construct molecule (tetraeder of hydrogens) 57 tafel->AddElement(carbon); 58 59 // construct molecule (tetraeder of hydrogens) base 55 60 TestMolecule = new molecule(tafel); 56 61 Walker = new atom(); … … 74 79 CPPUNIT_ASSERT_EQUAL( TestMolecule->AtomCount, 4 ); 75 80 81 TestList = new MoleculeListClass; 82 TestMolecule->ActiveFlag = true; 83 TestList->insert(TestMolecule); 84 76 85 // init tesselation and linked cell 77 86 Surface = new Tesselation; 78 TestMolecule->TesselStruct = Surface; 79 FindNonConvexBorder((ofstream *)&cout, TestMolecule, LC, 2.5, NULL); 87 FindNonConvexBorder((ofstream *)&cerr, TestMolecule, Surface, (const LinkedCell *&)LC, 2.5, NULL); 80 88 LC = new LinkedCell(TestMolecule, 5.); 81 89 CPPUNIT_ASSERT_EQUAL( (size_t)4, Surface->PointsOnBoundary.size() ); … … 83 91 CPPUNIT_ASSERT_EQUAL( (size_t)4, Surface->TrianglesOnBoundary.size() ); 84 92 93 // add outer atoms 94 Walker = new atom(); 95 Walker->type = carbon; 96 Walker->node->Init(4., 0., 4. ); 97 TestMolecule->AddAtom(Walker); 98 Walker = new atom(); 99 Walker->type = carbon; 100 Walker->node->Init(0., 4., 4. ); 101 TestMolecule->AddAtom(Walker); 102 Walker = new atom(); 103 Walker->type = carbon; 104 Walker->node->Init(4., 4., 0. ); 105 TestMolecule->AddAtom(Walker); 106 // add inner atoms 107 Walker = new atom(); 108 Walker->type = carbon; 109 Walker->node->Init(0.5, 0.5, 0.5 ); 110 TestMolecule->AddAtom(Walker); 111 85 112 // init maps 86 surfacemap = CorrelationToSurface( (ofstream *)&cout, TestMolecule, hydrogen, Surface, LC );113 surfacemap = NULL; 87 114 binmap = NULL; 88 115 … … 98 125 99 126 // remove 100 delete(TestMolecule); 101 // note that Surface and all the atoms are cleaned by TestMolecule 127 delete(TestList); 128 delete(Surface); 129 // note that all the atoms are cleaned by TestMolecule 102 130 delete(LC); 103 131 delete(tafel); … … 109 137 { 110 138 // do the pair correlation 139 surfacemap = CorrelationToSurface( (ofstream *)&cout, TestList, hydrogen, Surface, LC ); 111 140 CPPUNIT_ASSERT( surfacemap != NULL ); 112 141 CPPUNIT_ASSERT_EQUAL( (size_t)4, surfacemap->size() ); 113 142 }; 114 143 115 void AnalysisCorrelationToSurfaceUnitTest::CorrelationToSurfaceBinNoRangeTest() 116 { 117 BinPairMap::iterator tester; 144 void AnalysisCorrelationToSurfaceUnitTest::CorrelationToSurfaceHydrogenBinNoRangeTest() 145 { 146 BinPairMap::iterator tester; 147 surfacemap = CorrelationToSurface( (ofstream *)&cout, TestList, hydrogen, Surface, LC ); 118 148 // put pair correlation into bins and check with no range 119 149 binmap = BinData( (ofstream *)&cout, surfacemap, 0.5, 0., 0. ); … … 126 156 }; 127 157 128 void AnalysisCorrelationToSurfaceUnitTest::CorrelationToSurfaceBinRangeTest() 129 { 130 BinPairMap::iterator tester; 158 void AnalysisCorrelationToSurfaceUnitTest::CorrelationToSurfaceHydrogenBinRangeTest() 159 { 160 BinPairMap::iterator tester; 161 surfacemap = CorrelationToSurface( (ofstream *)&cout, TestList, hydrogen, Surface, LC ); 131 162 // ... and check with [0., 2.] range 132 163 binmap = BinData( (ofstream *)&cout, surfacemap, 0.5, 0., 2. ); … … 142 173 }; 143 174 175 void AnalysisCorrelationToSurfaceUnitTest::CorrelationToSurfaceCarbonBinNoRangeTest() 176 { 177 BinPairMap::iterator tester; 178 surfacemap = CorrelationToSurface( (ofstream *)&cout, TestList, carbon, Surface, LC ); 179 // put pair correlation into bins and check with no range 180 binmap = BinData( (ofstream *)&cout, surfacemap, 0.5, 0., 0. ); 181 CPPUNIT_ASSERT_EQUAL( (size_t)2, binmap->size() ); 182 OutputCorrelation ( (ofstream *)&cout, binmap ); 183 // inside point is first and must have negative value 184 tester = binmap->lower_bound(2.95); // start depends on the min value and 185 CPPUNIT_ASSERT( tester != binmap->end() ); 186 CPPUNIT_ASSERT_EQUAL( 3, tester->second ); 187 // inner point 188 tester = binmap->lower_bound(-0.5); 189 CPPUNIT_ASSERT( tester != binmap->end() ); 190 CPPUNIT_ASSERT_EQUAL( 1, tester->second ); 191 }; 192 193 void AnalysisCorrelationToSurfaceUnitTest::CorrelationToSurfaceCarbonBinRangeTest() 194 { 195 BinPairMap::iterator tester; 196 surfacemap = CorrelationToSurface( (ofstream *)&cout, TestList, carbon, Surface, LC ); 197 // ... and check with [0., 2.] range 198 binmap = BinData( (ofstream *)&cout, surfacemap, 0.5, -2., 4. ); 199 CPPUNIT_ASSERT_EQUAL( (size_t)13, binmap->size() ); 200 OutputCorrelation ( (ofstream *)&cout, binmap ); 201 // three outside points 202 tester = binmap->lower_bound(3.); 203 CPPUNIT_ASSERT( tester != binmap->end() ); 204 CPPUNIT_ASSERT_EQUAL( 3, tester->second ); 205 // inner point 206 tester = binmap->lower_bound(-0.5); 207 CPPUNIT_ASSERT( tester != binmap->end() ); 208 CPPUNIT_ASSERT_EQUAL( 1, tester->second ); 209 210 }; 211 144 212 /********************************************** Main routine **************************************/ 145 213 -
src/unittests/AnalysisCorrelationToSurfaceUnitTest.hpp
r06c7a3 r7326b2 12 12 13 13 class element; 14 class LinkedCell; 14 15 class molecule; 15 class LinkedCell;16 class MoleculeListClass; 16 17 class periodentafel; 17 18 class Tesselation; … … 23 24 CPPUNIT_TEST_SUITE( AnalysisCorrelationToSurfaceUnitTest ) ; 24 25 CPPUNIT_TEST ( CorrelationToSurfaceTest ); 25 CPPUNIT_TEST ( CorrelationToSurfaceBinNoRangeTest ); 26 CPPUNIT_TEST ( CorrelationToSurfaceBinRangeTest ); 26 CPPUNIT_TEST ( CorrelationToSurfaceHydrogenBinNoRangeTest ); 27 CPPUNIT_TEST ( CorrelationToSurfaceHydrogenBinRangeTest ); 28 CPPUNIT_TEST ( CorrelationToSurfaceCarbonBinNoRangeTest ); 29 CPPUNIT_TEST ( CorrelationToSurfaceCarbonBinRangeTest ); 27 30 CPPUNIT_TEST_SUITE_END(); 28 31 … … 31 34 void tearDown(); 32 35 void CorrelationToSurfaceTest(); 33 void CorrelationToSurfaceBinNoRangeTest(); 34 void CorrelationToSurfaceBinRangeTest(); 36 void CorrelationToSurfaceHydrogenBinNoRangeTest(); 37 void CorrelationToSurfaceHydrogenBinRangeTest(); 38 void CorrelationToSurfaceCarbonBinNoRangeTest(); 39 void CorrelationToSurfaceCarbonBinRangeTest(); 35 40 36 41 private: 37 42 43 MoleculeListClass *TestList; 38 44 molecule *TestMolecule; 39 45 element *hydrogen; 46 element *carbon; 40 47 periodentafel *tafel; 41 48 -
src/unittests/AnalysisPairCorrelationUnitTest.cpp
r06c7a3 r7326b2 34 34 35 35 // init private all pointers to zero 36 TestList = NULL; 36 37 TestMolecule = NULL; 37 38 hydrogen = NULL; … … 44 45 hydrogen->Z = 1; 45 46 strcpy(hydrogen->name, "hydrogen"); 46 hydrogen->symbol[0] = 'H';47 strcpy(hydrogen->symbol, "H"); 47 48 48 49 // construct periodentafel … … 72 73 CPPUNIT_ASSERT_EQUAL( TestMolecule->AtomCount, 4 ); 73 74 75 TestList = new MoleculeListClass; 76 TestMolecule->ActiveFlag = true; 77 TestList->insert(TestMolecule); 78 74 79 // init maps 75 correlationmap = PairCorrelation( (ofstream *)&cout, Test Molecule, hydrogen, hydrogen );80 correlationmap = PairCorrelation( (ofstream *)&cout, TestList, hydrogen, hydrogen ); 76 81 binmap = NULL; 77 82 … … 87 92 88 93 // remove 89 delete(Test Molecule);94 delete(TestList); 90 95 // note that all the atoms are cleaned by TestMolecule 91 96 delete(tafel); -
src/unittests/AnalysisPairCorrelationUnitTest.hpp
r06c7a3 r7326b2 12 12 13 13 class element; 14 class LinkedCell; 14 15 class molecule; 15 class LinkedCell;16 class MoleculeListClass; 16 17 class periodentafel; 17 18 class Tesselation; … … 37 38 private: 38 39 40 MoleculeListClass *TestList; 39 41 molecule *TestMolecule; 40 42 element *hydrogen; -
src/unittests/Makefile.am
r06c7a3 r7326b2 1 1 INCLUDES = -I$(top_srcdir)/src 2 2 3 noinst_PROGRAMS = ActOnAllUnitTest AnalysisCorrelationToPointUnitTest AnalysisCorrelationToSurfaceUnitTest AnalysisPairCorrelationUnitTest LogUnitTest MemoryAllocatorUnitTest MemoryUsageObserverUnitTest VectorUnitTest 3 AM_LDFLAGS = $(CPPUNIT_LIBS) -ldl 4 AM_CXXFLAGS = $(CPPUNIT_CFLAGS) 4 5 5 TESTS = ActOnAllUnitTest AnalysisCorrelationToPointUnitTest AnalysisCorrelationToSurfaceUnitTest AnalysisPairCorrelationUnitTest MemoryUsageObserverUnitTest MemoryAllocatorUnitTest VectorUnitTest6 TESTS = ActOnAllUnitTest AnalysisCorrelationToPointUnitTest AnalysisCorrelationToSurfaceUnitTest AnalysisPairCorrelationUnitTest BondGraphUnitTest ListOfBondsUnitTest LogUnitTest MemoryUsageObserverUnitTest MemoryAllocatorUnitTest StackClassUnitTest VectorUnitTest 6 7 check_PROGRAMS = $(TESTS) 8 noinst_PROGRAMS = $(TESTS) 7 9 8 ActOnAllUnitTest_SOURCES = ActOnAllTest.hpp ActOnAllUnitTest.cpp ActOnAllUnitTest.hpp memoryallocator.hpp 9 ActOnAllUnitTest_CXXFLAGS = $(CPPUNIT_CFLAGS) 10 ActOnAllUnitTest_LDFLAGS = $(CPPUNIT_LIBS) -ldl 11 ActOnAllUnitTest_LDADD = ../libmolecuilder.a 10 ActOnAllUnitTest_SOURCES = ../test/ActOnAllTest.hpp ActOnAllUnitTest.cpp ActOnAllUnitTest.hpp memoryallocator.hpp 12 11 13 12 AnalysisCorrelationToPointUnitTest_SOURCES = analysis_correlation.hpp AnalysisCorrelationToPointUnitTest.cpp AnalysisCorrelationToPointUnitTest.hpp 14 AnalysisCorrelationToPointUnitTest_CXXFLAGS = $(CPPUNIT_CFLAGS)15 AnalysisCorrelationToPointUnitTest_LDFLAGS = $(CPPUNIT_LIBS) -ldl16 13 AnalysisCorrelationToPointUnitTest_LDADD = ../libmolecuilder.a 17 14 18 15 AnalysisCorrelationToSurfaceUnitTest_SOURCES = analysis_correlation.hpp AnalysisCorrelationToSurfaceUnitTest.cpp AnalysisCorrelationToSurfaceUnitTest.hpp 19 AnalysisCorrelationToSurfaceUnitTest_CXXFLAGS = $(CPPUNIT_CFLAGS)20 AnalysisCorrelationToSurfaceUnitTest_LDFLAGS = $(CPPUNIT_LIBS) -ldl21 16 AnalysisCorrelationToSurfaceUnitTest_LDADD = ../libmolecuilder.a 22 17 23 18 AnalysisPairCorrelationUnitTest_SOURCES = analysis_correlation.hpp AnalysisPairCorrelationUnitTest.cpp AnalysisPairCorrelationUnitTest.hpp 24 AnalysisPairCorrelationUnitTest_CXXFLAGS = $(CPPUNIT_CFLAGS)25 AnalysisPairCorrelationUnitTest_LDFLAGS = $(CPPUNIT_LIBS) -ldl26 19 AnalysisPairCorrelationUnitTest_LDADD = ../libmolecuilder.a 27 20 28 VectorUnitTest_SOURCES = defs.hpp helpers.hpp leastsquaremin.hpp memoryallocator.hpp memoryusageobserver.hpp vectorunittest.cpp vectorunittest.hpp vector.hpp verbose.hpp 29 VectorUnitTest_CXXFLAGS = $(CPPUNIT_CFLAGS) 30 VectorUnitTest_LDFLAGS = $(CPPUNIT_LIBS) -ldl 31 VectorUnitTest_LDADD = ../libmolecuilder.a 21 BondGraphUnitTest_SOURCES = bondgraphunittest.cpp bondgraphunittest.hpp 22 BondGraphUnitTest_LDADD = ../libmolecuilder.a 32 23 33 MemoryAllocatorUnitTest_SOURCES = defs.hpp helpers.hpp memoryallocatorunittest.cpp memoryallocatorunittest.hpp memoryallocator.hpp memoryusageobserver.hpp verbose.hpp 34 MemoryAllocatorUnitTest_CXXFLAGS = $(CPPUNIT_CFLAGS) -I.. 35 MemoryAllocatorUnitTest_LDFLAGS = $(CPPUNIT_LIBS) -ldl 36 MemoryAllocatorUnitTest_LDADD = ../libmolecuilder.a 24 ListOfBondsUnitTest_SOURCES = listofbondsunittest.cpp listofbondsunittest.hpp 25 ListOfBondsUnitTest_LDADD = ../libmolecuilder.a 26 27 LogUnitTest_SOURCES = logunittest.cpp logunittest.hpp 28 LogUnitTest_LDADD = ../libmolecuilder.a 29 30 MemoryAllocatorUnitTest_SOURCES = defs.hpp ../helpers.cpp ../helpers.hpp memoryallocatorunittest.cpp memoryallocatorunittest.hpp memoryallocator.hpp ../memoryusageobserver.cpp memoryusageobserver.hpp ../verbose.cpp verbose.hpp 37 31 38 32 MemoryUsageObserverUnitTest_SOURCES = defs.hpp helpers.hpp memoryusageobserverunittest.cpp memoryusageobserverunittest.hpp memoryusageobserver.hpp verbose.hpp 39 MemoryUsageObserverUnitTest_CXXFLAGS = $(CPPUNIT_CFLAGS)40 MemoryUsageObserverUnitTest_LDFLAGS = $(CPPUNIT_LIBS) -ldl41 MemoryUsageObserverUnitTest_LDADD = ../libmolecuilder.a42 33 43 LogUnitTest_SOURCES = ../errorLogger.cpp ../errorLogger.hpp ../log.cpp ../log.hpp ../logger.cpp ../logger.hpp logunittest.cpp logunittest.hpp 44 LogUnitTest_CXXFLAGS = $(CPPUNIT_CFLAGS) 45 LogUnitTest_LDFLAGS = $(CPPUNIT_LIBS) -ldl 46 LogUnitTest_LDADD = ../libmolecuilder.a 34 StackClassUnitTest_SOURCES = memoryallocator.hpp stackclass.hpp stackclassunittest.cpp stackclassunittest.hpp 35 36 VectorUnitTest_SOURCES = defs.hpp ../helpers.cpp helpers.hpp ../leastsquaremin.cpp leastsquaremin.hpp memoryallocator.hpp memoryusageobserver.hpp ../memoryusageobserver.cpp vectorunittest.cpp vectorunittest.hpp vector.hpp ../vector.cpp verbose.hpp ../verbose.cpp 37 38 39 #AUTOMAKE_OPTIONS = parallel-tests 40 -
src/unittests/memoryallocatorunittest.cpp
r06c7a3 r7326b2 28 28 void MemoryAllocatorTest::tearDown() 29 29 { 30 MemoryUsageObserver::getInstance()->purgeInstance(); 30 31 }; 31 32 … … 49 50 50 51 char** buffer4 = NULL; 51 buffer4 = Malloc<char*>(1, ""); 52 buffer4 = Malloc<char*>(10, ""); 53 for (int i=0;i<10;i++) 54 buffer4[i] = NULL; 52 55 Free(&buffer4); 53 56 }; … … 59 62 { 60 63 int* buffer1 = NULL; 61 buffer1 = Calloc<int>(1 , "");64 buffer1 = Calloc<int>(10, ""); 62 65 Free(&buffer1); 63 66 64 67 long* buffer2 = NULL; 65 buffer2 = Calloc<long>(1 , "");68 buffer2 = Calloc<long>(10, ""); 66 69 Free(&buffer2); 67 70 68 char* buffer3 = NULL; 69 buffer3 = Calloc<char>(1, ""); 71 char** buffer3 = NULL; 72 buffer3 = Calloc<char *>(10, ""); 73 for (int i=0;i<10;i++) 74 buffer3[i] = NULL; 70 75 Free(&buffer3); 71 76 }; -
src/vector.cpp
-
Property mode
changed from
100755
to100644
r06c7a3 r7326b2 21 21 /** Constructor of class vector. 22 22 */ 23 Vector::Vector( double x1, double x2,double x3) { x[0] = x1; x[1] = x2; x[2] = x3; };23 Vector::Vector(const double x1, const double x2, const double x3) { x[0] = x1; x[1] = x2; x[2] = x3; }; 24 24 25 25 /** Desctructor of class vector. … … 31 31 * \return \f$| x - y |^2\f$ 32 32 */ 33 double Vector::DistanceSquared(const Vector * y) const33 double Vector::DistanceSquared(const Vector * const y) const 34 34 { 35 35 double res = 0.; … … 43 43 * \return \f$| x - y |\f$ 44 44 */ 45 double Vector::Distance(const Vector * y) const45 double Vector::Distance(const Vector * const y) const 46 46 { 47 47 double res = 0.; … … 56 56 * \return \f$| x - y |\f$ 57 57 */ 58 double Vector::PeriodicDistance(const Vector * y, const double *cell_size) const58 double Vector::PeriodicDistance(const Vector * const y, const double * const cell_size) const 59 59 { 60 60 double res = Distance(y), tmp, matrix[NDIM*NDIM]; … … 94 94 * \return \f$| x - y |^2\f$ 95 95 */ 96 double Vector::PeriodicDistanceSquared(const Vector * y, const double *cell_size) const96 double Vector::PeriodicDistanceSquared(const Vector * const y, const double * const cell_size) const 97 97 { 98 98 double res = DistanceSquared(y), tmp, matrix[NDIM*NDIM]; … … 131 131 * Tries to translate a vector into each adjacent neighbouring cell. 132 132 */ 133 void Vector::KeepPeriodic(ofstream *out, double *matrix)133 void Vector::KeepPeriodic(ofstream *out, const double * const matrix) 134 134 { 135 135 // int N[NDIM]; … … 162 162 * \return \f$\langle x, y \rangle\f$ 163 163 */ 164 double Vector::ScalarProduct(const Vector * y) const164 double Vector::ScalarProduct(const Vector * const y) const 165 165 { 166 166 double res = 0.; … … 177 177 * \return \f$ x \times y \f& 178 178 */ 179 void Vector::VectorProduct(const Vector * y)179 void Vector::VectorProduct(const Vector * const y) 180 180 { 181 181 Vector tmp; … … 184 184 tmp.x[2] = x[0]* (y->x[1]) - x[1]* (y->x[0]); 185 185 this->CopyVector(&tmp); 186 187 186 }; 188 187 … … 192 191 * \return \f$\langle x, y \rangle\f$ 193 192 */ 194 void Vector::ProjectOntoPlane(const Vector * y)193 void Vector::ProjectOntoPlane(const Vector * const y) 195 194 { 196 195 Vector tmp; … … 217 216 * \return true - \a this contains intersection point on return, false - line is parallel to plane 218 217 */ 219 bool Vector::GetIntersectionWithPlane(ofstream *out, Vector *PlaneNormal, Vector *PlaneOffset, Vector *Origin, Vector *LineVector)218 bool Vector::GetIntersectionWithPlane(ofstream *out, const Vector * const PlaneNormal, const Vector * const PlaneOffset, const Vector * const Origin, const Vector * const LineVector) 220 219 { 221 220 double factor; … … 264 263 * \return distance to plane 265 264 */ 266 double Vector::DistanceToPlane(ofstream *out, Vector *PlaneNormal, Vector *PlaneOffset)265 double Vector::DistanceToPlane(ofstream *out, const Vector * const PlaneNormal, const Vector * const PlaneOffset) const 267 266 { 268 267 Vector temp; … … 276 275 temp.AddVector(this); 277 276 temp.SubtractVector(PlaneOffset); 278 279 return temp.Norm(); 277 double sign = temp.ScalarProduct(PlaneNormal); 278 if (fabs(sign) > MYEPSILON) 279 sign /= fabs(sign); 280 else 281 sign = 0.; 282 283 return (temp.Norm()*sign); 280 284 }; 281 285 … … 292 296 * \return true - \a this will contain the intersection on return, false - lines are parallel 293 297 */ 294 bool Vector::GetIntersectionOfTwoLinesOnPlane(ofstream *out, Vector *Line1a, Vector *Line1b, Vector *Line2a, Vector *Line2b, const Vector *PlaneNormal)298 bool Vector::GetIntersectionOfTwoLinesOnPlane(ofstream *out, const Vector * const Line1a, const Vector * const Line1b, const Vector * const Line2a, const Vector * const Line2b, const Vector *PlaneNormal) 295 299 { 296 300 bool result = true; … … 375 379 * \param *y array to second vector 376 380 */ 377 void Vector::ProjectIt(const Vector * y)381 void Vector::ProjectIt(const Vector * const y) 378 382 { 379 383 Vector helper(*y); … … 386 390 * \return Vector 387 391 */ 388 Vector Vector::Projection(const Vector * y) const392 Vector Vector::Projection(const Vector * const y) const 389 393 { 390 394 Vector helper(*y); … … 435 439 /** Zeros all components of this vector. 436 440 */ 437 void Vector::One( double one)441 void Vector::One(const double one) 438 442 { 439 443 for (int i=NDIM;i--;) … … 443 447 /** Initialises all components of this vector. 444 448 */ 445 void Vector::Init( double x1, double x2,double x3)449 void Vector::Init(const double x1, const double x2, const double x3) 446 450 { 447 451 x[0] = x1; … … 469 473 * @return true - vector is normalized, false - vector is not 470 474 */ 471 bool Vector::IsNormalTo(const Vector * normal) const475 bool Vector::IsNormalTo(const Vector * const normal) const 472 476 { 473 477 if (ScalarProduct(normal) < MYEPSILON) … … 481 485 * \return \f$\acos\bigl(frac{\langle x, y \rangle}{|x||y|}\bigr)\f$ 482 486 */ 483 double Vector::Angle(const Vector * y) const487 double Vector::Angle(const Vector * const y) const 484 488 { 485 489 double norm1 = Norm(), norm2 = y->Norm(); … … 500 504 * \param alpha rotation angle in radian 501 505 */ 502 void Vector::RotateVector(const Vector * axis, const double alpha)506 void Vector::RotateVector(const Vector * const axis, const double alpha) 503 507 { 504 508 Vector a,y; … … 656 660 * \param *factor pointer to scaling factor 657 661 */ 658 void Vector::Scale( double **factor)662 void Vector::Scale(const double ** const factor) 659 663 { 660 664 for (int i=NDIM;i--;) … … 662 666 }; 663 667 664 void Vector::Scale( double *factor)668 void Vector::Scale(const double * const factor) 665 669 { 666 670 for (int i=NDIM;i--;) … … 668 672 }; 669 673 670 void Vector::Scale( double factor)674 void Vector::Scale(const double factor) 671 675 { 672 676 for (int i=NDIM;i--;) … … 677 681 * \param trans[] translation vector. 678 682 */ 679 void Vector::Translate(const Vector * trans)683 void Vector::Translate(const Vector * const trans) 680 684 { 681 685 for (int i=NDIM;i--;) … … 687 691 * \param *Minv inverse matrix 688 692 */ 689 void Vector::WrapPeriodically(const double * M, const double *Minv)693 void Vector::WrapPeriodically(const double * const M, const double * const Minv) 690 694 { 691 695 MatrixMultiplication(Minv); … … 704 708 * \param *matrix NDIM_NDIM array 705 709 */ 706 void Vector::MatrixMultiplication(const double * M)710 void Vector::MatrixMultiplication(const double * const M) 707 711 { 708 712 Vector C; … … 716 720 }; 717 721 718 /** Calculate the inverse of a 3x3 matrix.722 /** Do a matrix multiplication with the \a *A' inverse. 719 723 * \param *matrix NDIM_NDIM array 720 724 */ 721 double * Vector::InverseMatrix(double *A) 722 { 723 double *B = Malloc<double>(NDIM * NDIM, "Vector::InverseMatrix: *B"); 725 void Vector::InverseMatrixMultiplication(const double * const A) 726 { 727 Vector C; 728 double B[NDIM*NDIM]; 724 729 double detA = RDET3(A); 725 730 double detAReci; 726 731 727 for (int i=0;i<NDIM*NDIM;++i)728 B[i] = 0.;729 732 // calculate the inverse B 730 733 if (fabs(detA) > MYEPSILON) {; // RDET3(A) yields precisely zero if A irregular … … 739 742 B[7] = -detAReci*RDET2(A[0],A[1],A[6],A[7]); // A_32 740 743 B[8] = detAReci*RDET2(A[0],A[1],A[3],A[4]); // A_33 741 }742 return B;743 };744 745 /** Do a matrix multiplication with the \a *A' inverse.746 * \param *matrix NDIM_NDIM array747 */748 void Vector::InverseMatrixMultiplication(const double *A)749 {750 Vector C;751 double B[NDIM*NDIM];752 double detA = RDET3(A);753 double detAReci;754 755 // calculate the inverse B756 if (fabs(detA) > MYEPSILON) {; // RDET3(A) yields precisely zero if A irregular757 detAReci = 1./detA;758 B[0] = detAReci*RDET2(A[4],A[5],A[7],A[8]); // A_11759 B[1] = -detAReci*RDET2(A[1],A[2],A[7],A[8]); // A_12760 B[2] = detAReci*RDET2(A[1],A[2],A[4],A[5]); // A_13761 B[3] = -detAReci*RDET2(A[3],A[5],A[6],A[8]); // A_21762 B[4] = detAReci*RDET2(A[0],A[2],A[6],A[8]); // A_22763 B[5] = -detAReci*RDET2(A[0],A[2],A[3],A[5]); // A_23764 B[6] = detAReci*RDET2(A[3],A[4],A[6],A[7]); // A_31765 B[7] = -detAReci*RDET2(A[0],A[1],A[6],A[7]); // A_32766 B[8] = detAReci*RDET2(A[0],A[1],A[3],A[4]); // A_33767 744 768 745 // do the matrix multiplication … … 786 763 * \param *factors three-component vector with the factor for each given vector 787 764 */ 788 void Vector::LinearCombinationOfVectors(const Vector * x1, const Vector *x2, const Vector *x3, double *factors)765 void Vector::LinearCombinationOfVectors(const Vector * const x1, const Vector * const x2, const Vector * const x3, const double * const factors) 789 766 { 790 767 for(int i=NDIM;i--;) … … 795 772 * \param n[] normal vector of mirror plane. 796 773 */ 797 void Vector::Mirror(const Vector * n)774 void Vector::Mirror(const Vector * const n) 798 775 { 799 776 double projection; … … 817 794 * \return true - success, vectors are linear independent, false - failure due to linear dependency 818 795 */ 819 bool Vector::MakeNormalVector(const Vector * y1, const Vector *y2, const Vector *y3)796 bool Vector::MakeNormalVector(const Vector * const y1, const Vector * const y2, const Vector * const y3) 820 797 { 821 798 Vector x1, x2; … … 853 830 * \return true - success, vectors are linear independent, false - failure due to linear dependency 854 831 */ 855 bool Vector::MakeNormalVector(const Vector * y1, const Vector *y2)832 bool Vector::MakeNormalVector(const Vector * const y1, const Vector * const y2) 856 833 { 857 834 Vector x1,x2; … … 884 861 * \return true - success, false - vector is zero 885 862 */ 886 bool Vector::MakeNormalVector(const Vector * y1)863 bool Vector::MakeNormalVector(const Vector * const y1) 887 864 { 888 865 bool result = false; … … 904 881 * \return true - success, false - failure (null vector given) 905 882 */ 906 bool Vector::GetOneNormalVector(const Vector * GivenVector)883 bool Vector::GetOneNormalVector(const Vector * const GivenVector) 907 884 { 908 885 int Components[NDIM]; // contains indices of non-zero components … … 950 927 * \return scaling parameter for this vector 951 928 */ 952 double Vector::CutsPlaneAt( Vector *A, Vector *B, Vector *C)929 double Vector::CutsPlaneAt(const Vector * const A, const Vector * const B, const Vector * const C) const 953 930 { 954 931 // cout << Verbose(3) << "For comparison: "; … … 965 942 * \return true if success, false if failed due to linear dependency 966 943 */ 967 bool Vector::LSQdistance( Vector **vectors, int num)944 bool Vector::LSQdistance(const Vector **vectors, int num) 968 945 { 969 946 int j; … … 1047 1024 * \param *y vector 1048 1025 */ 1049 void Vector::AddVector(const Vector * y)1026 void Vector::AddVector(const Vector * const y) 1050 1027 { 1051 1028 for (int i=NDIM;i--;) … … 1056 1033 * \param *y vector 1057 1034 */ 1058 void Vector::SubtractVector(const Vector * y)1035 void Vector::SubtractVector(const Vector * const y) 1059 1036 { 1060 1037 for (int i=NDIM;i--;) … … 1065 1042 * \param *y vector 1066 1043 */ 1067 void Vector::CopyVector(const Vector * y)1044 void Vector::CopyVector(const Vector * const y) 1068 1045 { 1069 1046 for (int i=NDIM;i--;) … … 1074 1051 * \param y vector 1075 1052 */ 1076 void Vector::CopyVector(const Vector y)1053 void Vector::CopyVector(const Vector &y) 1077 1054 { 1078 1055 for (int i=NDIM;i--;) … … 1085 1062 * \param check whether bounds shall be checked (true) or not (false) 1086 1063 */ 1087 void Vector::AskPosition( double *cell_size,bool check)1064 void Vector::AskPosition(const double * const cell_size, const bool check) 1088 1065 { 1089 1066 char coords[3] = {'x','y','z'}; … … 1113 1090 * \bug this is not yet working properly 1114 1091 */ 1115 bool Vector::SolveSystem(Vector * x1, Vector *x2, Vector *y, double alpha, double beta,double c)1092 bool Vector::SolveSystem(Vector * x1, Vector * x2, Vector * y, const double alpha, const double beta, const double c) 1116 1093 { 1117 1094 double D1,D2,D3,E1,E2,F1,F2,F3,p,q=0., A, B1, B2, C; … … 1139 1116 break; 1140 1117 case 2: 1141 flip( &x1->x[0],&x1->x[1]);1142 flip( &x2->x[0],&x2->x[1]);1143 flip( &y->x[0],&y->x[1]);1144 //flip( &x[0],&x[1]);1145 flip( &x1->x[1],&x1->x[2]);1146 flip( &x2->x[1],&x2->x[2]);1147 flip( &y->x[1],&y->x[2]);1148 //flip( &x[1],&x[2]);1118 flip(x1->x[0],x1->x[1]); 1119 flip(x2->x[0],x2->x[1]); 1120 flip(y->x[0],y->x[1]); 1121 //flip(x[0],x[1]); 1122 flip(x1->x[1],x1->x[2]); 1123 flip(x2->x[1],x2->x[2]); 1124 flip(y->x[1],y->x[2]); 1125 //flip(x[1],x[2]); 1149 1126 case 1: 1150 flip( &x1->x[0],&x1->x[1]);1151 flip( &x2->x[0],&x2->x[1]);1152 flip( &y->x[0],&y->x[1]);1153 //flip( &x[0],&x[1]);1154 flip( &x1->x[1],&x1->x[2]);1155 flip( &x2->x[1],&x2->x[2]);1156 flip( &y->x[1],&y->x[2]);1157 //flip( &x[1],&x[2]);1127 flip(x1->x[0],x1->x[1]); 1128 flip(x2->x[0],x2->x[1]); 1129 flip(y->x[0],y->x[1]); 1130 //flip(x[0],x[1]); 1131 flip(x1->x[1],x1->x[2]); 1132 flip(x2->x[1],x2->x[2]); 1133 flip(y->x[1],y->x[2]); 1134 //flip(x[1],x[2]); 1158 1135 break; 1159 1136 } … … 1224 1201 break; 1225 1202 case 2: 1226 flip( &x1->x[0],&x1->x[1]);1227 flip( &x2->x[0],&x2->x[1]);1228 flip( &y->x[0],&y->x[1]);1229 flip( &x[0],&x[1]);1230 flip( &x1->x[1],&x1->x[2]);1231 flip( &x2->x[1],&x2->x[2]);1232 flip( &y->x[1],&y->x[2]);1233 flip( &x[1],&x[2]);1203 flip(x1->x[0],x1->x[1]); 1204 flip(x2->x[0],x2->x[1]); 1205 flip(y->x[0],y->x[1]); 1206 flip(x[0],x[1]); 1207 flip(x1->x[1],x1->x[2]); 1208 flip(x2->x[1],x2->x[2]); 1209 flip(y->x[1],y->x[2]); 1210 flip(x[1],x[2]); 1234 1211 case 1: 1235 flip( &x1->x[0],&x1->x[1]);1236 flip( &x2->x[0],&x2->x[1]);1237 flip( &y->x[0],&y->x[1]);1238 //flip( &x[0],&x[1]);1239 flip( &x1->x[1],&x1->x[2]);1240 flip( &x2->x[1],&x2->x[2]);1241 flip( &y->x[1],&y->x[2]);1242 flip( &x[1],&x[2]);1212 flip(x1->x[0],x1->x[1]); 1213 flip(x2->x[0],x2->x[1]); 1214 flip(y->x[0],y->x[1]); 1215 //flip(x[0],x[1]); 1216 flip(x1->x[1],x1->x[2]); 1217 flip(x2->x[1],x2->x[2]); 1218 flip(y->x[1],y->x[2]); 1219 flip(x[1],x[2]); 1243 1220 break; 1244 1221 } … … 1276 1253 * @param three vectors forming the matrix that defines the shape of the parallelpiped 1277 1254 */ 1278 bool Vector::IsInParallelepiped( Vector offset, double *parallelepiped)1255 bool Vector::IsInParallelepiped(const Vector &offset, const double * const parallelepiped) const 1279 1256 { 1280 1257 Vector a; -
Property mode
changed from
-
src/vector.hpp
r06c7a3 r7326b2 11 11 #endif 12 12 13 #include <iostream> 13 14 #include <gsl/gsl_vector.h> 14 15 #include <gsl/gsl_multimin.h> … … 26 27 27 28 Vector(); 28 Vector( double x1, double x2,double x3);29 Vector(const double x1, const double x2, const double x3); 29 30 ~Vector(); 30 31 31 double Distance(const Vector * y) const;32 double DistanceSquared(const Vector * y) const;33 double DistanceToPlane(ofstream *out, Vector *PlaneNormal, Vector *PlaneOffset);34 double PeriodicDistance(const Vector * y, const double *cell_size) const;35 double PeriodicDistanceSquared(const Vector * y, const double *cell_size) const;36 double ScalarProduct(const Vector * y) const;32 double Distance(const Vector * const y) const; 33 double DistanceSquared(const Vector * const y) const; 34 double DistanceToPlane(ofstream *out, const Vector * const PlaneNormal, const Vector * const PlaneOffset) const; 35 double PeriodicDistance(const Vector * const y, const double * const cell_size) const; 36 double PeriodicDistanceSquared(const Vector * const y, const double * const cell_size) const; 37 double ScalarProduct(const Vector * const y) const; 37 38 double Norm() const; 38 39 double NormSquared() const; 39 double Angle(const Vector * y) const;40 double Angle(const Vector * const y) const; 40 41 bool IsZero() const; 41 42 bool IsOne() const; 42 bool IsNormalTo(const Vector * normal) const;43 bool IsNormalTo(const Vector * const normal) const; 43 44 44 void AddVector(const Vector * y);45 void SubtractVector(const Vector * y);46 void CopyVector(const Vector * y);47 void CopyVector(const Vector y);48 void RotateVector(const Vector * y, const double alpha);49 void VectorProduct(const Vector * y);50 void ProjectOntoPlane(const Vector * y);51 void ProjectIt(const Vector * y);52 Vector Projection(const Vector * y) const;45 void AddVector(const Vector * const y); 46 void SubtractVector(const Vector * const y); 47 void CopyVector(const Vector * const y); 48 void CopyVector(const Vector &y); 49 void RotateVector(const Vector * const y, const double alpha); 50 void VectorProduct(const Vector * const y); 51 void ProjectOntoPlane(const Vector * const y); 52 void ProjectIt(const Vector * const y); 53 Vector Projection(const Vector * const y) const; 53 54 void Zero(); 54 void One( double one);55 void Init( double x1, double x2,double x3);55 void One(const double one); 56 void Init(const double x1, const double x2, const double x3); 56 57 void Normalize(); 57 void Translate(const Vector *x); 58 void Mirror(const Vector *x); 59 void Scale(double **factor); 60 void Scale(double *factor); 61 void Scale(double factor); 62 void MatrixMultiplication(const double *M); 63 double * InverseMatrix(double *A); 64 void InverseMatrixMultiplication(const double *M); 65 void KeepPeriodic(ofstream *out, double *matrix); 66 void LinearCombinationOfVectors(const Vector *x1, const Vector *x2, const Vector *x3, double *factors); 67 double CutsPlaneAt(Vector *A, Vector *B, Vector *C); 68 bool GetIntersectionWithPlane(ofstream *out, Vector *PlaneNormal, Vector *PlaneOffset, Vector *Origin, Vector *LineVector); 69 bool GetIntersectionOfTwoLinesOnPlane(ofstream *out, Vector *Line1a, Vector *Line1b, Vector *Line2a, Vector *Line2b, const Vector *Normal = NULL); 70 bool GetOneNormalVector(const Vector *x1); 71 bool MakeNormalVector(const Vector *y1); 72 bool MakeNormalVector(const Vector *y1, const Vector *y2); 73 bool MakeNormalVector(const Vector *x1, const Vector *x2, const Vector *x3); 74 bool SolveSystem(Vector *x1, Vector *x2, Vector *y, double alpha, double beta, double c); 75 bool LSQdistance(Vector **vectors, int dim); 76 void AskPosition(double *cell_size, bool check); 58 void Translate(const Vector * const x); 59 void Mirror(const Vector * const x); 60 void Scale(const double ** const factor); 61 void Scale(const double * const factor); 62 void Scale(const double factor); 63 void MatrixMultiplication(const double * const M); 64 void InverseMatrixMultiplication(const double * const M); 65 void KeepPeriodic(ofstream *out, const double * const matrix); 66 void LinearCombinationOfVectors(const Vector * const x1, const Vector * const x2, const Vector * const x3, const double * const factors); 67 double CutsPlaneAt(const Vector * const A, const Vector * const B, const Vector * const C) const; 68 bool GetIntersectionWithPlane(ofstream *out, const Vector * const PlaneNormal, const Vector * const PlaneOffset, const Vector * const Origin, const Vector * const LineVector); 69 bool GetIntersectionOfTwoLinesOnPlane(ofstream *out, const Vector * const Line1a, const Vector * const Line1b, const Vector * const Line2a, const Vector * const Line2b, const Vector *Normal = NULL); 70 bool GetOneNormalVector(const Vector * const x1); 71 bool MakeNormalVector(const Vector * const y1); 72 bool MakeNormalVector(const Vector * const y1, const Vector * const y2); 73 bool MakeNormalVector(const Vector * const x1, const Vector * const x2, const Vector * const x3); 74 bool SolveSystem(Vector * x1, Vector * x2, Vector * y, const double alpha, const double beta, const double c); 75 bool LSQdistance(const Vector ** vectors, int dim); 76 void AskPosition(const double * const cell_size, const bool check); 77 77 bool Output(ofstream *out) const; 78 bool IsInParallelepiped( Vector offset, double *parallelepiped);79 void WrapPeriodically(const double * M, const double *Minv);78 bool IsInParallelepiped(const Vector &offset, const double * const parallelepiped) const; 79 void WrapPeriodically(const double * const M, const double * const Minv); 80 80 }; 81 81 … … 90 90 Vector& operator-(const Vector& a, const Vector& b); 91 91 92 // some algebraic matrix stuff93 #define RDET3(a) ((a)[0]*(a)[4]*(a)[8] + (a)[3]*(a)[7]*(a)[2] + (a)[6]*(a)[1]*(a)[5] - (a)[2]*(a)[4]*(a)[6] - (a)[5]*(a)[7]*(a)[0] - (a)[8]*(a)[1]*(a)[3]) //!< hard-coded determinant of a 3x3 matrix94 #define RDET2(a0,a1,a2,a3) ((a0)*(a3)-(a1)*(a2)) //!< hard-coded determinant of a 2x2 matrix95 96 97 92 98 93 #endif /*VECTOR_HPP_*/
Note:
See TracChangeset
for help on using the changeset viewer.