Changes in / [87e2e39:c111db]
- Files:
-
- 83 added
- 2 deleted
- 47 edited
Legend:
- Unmodified
- Added
- Removed
-
configure.ac
r87e2e39 rc111db 25 25 # Checks for libraries. 26 26 AC_CHECK_LIB(m, sqrt, ,AC_MSG_ERROR([compatible libc math library not found])) 27 28 # Boost libraries 29 AX_BOOST_BASE([1.33.1]) 30 AX_BOOST_PROGRAM_OPTIONS 31 #AX_BOOST_FOREACH 32 #AX_BOOST_FILESYSTEM 33 #AX_BOOST_THREAD 34 #AX_BOOST_PROGRAM_OPTIONS 35 #AX_BOOST_SERIALIZATION 27 36 28 37 # Checks for header files. -
src/Makefile.am
r87e2e39 rc111db 1 SOURCE = atom.cpp bond.cpp boundary.cpp config.cpp element.cpp ellipsoid.cpp helpers.cpp leastsquaremin.cpp linkedcell.cpp memoryusageobserver.cpp molecules.cpp moleculelist.cpp parser.cpp periodentafel.cpptesselation.cpp tesselationhelpers.cpp vector.cpp verbose.cpp2 HEADER = atom.hpp bond.hpp boundary.hpp config.hpp defs.hpp element.hpp ellipsoid.hpp helpers.hpp leastsquaremin.hpp linkedcell.hpp memoryusageobserver.hpp molecules.hppparser.hpp periodentafel.hpp stackclass.hpp tesselation.hpp tesselationhelpers.hpp vector.hpp verbose.hpp1 SOURCE = 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 = 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 3 3 4 BOOST_LIB = $(BOOST_LDFLAGS) $(BOOST_MPL_LIB) 4 5 INCLUDES = -I$(top_srcdir)/src/unittests 5 6 … … 9 10 libmolecuilder_a_SOURCES = ${SOURCE} ${HEADER} 10 11 molecuilder_DATA = elements.db valence.db orbitals.db Hbonddistance.db Hbondangle.db 12 molecuilder_LDFLAGS = $(BOOST_LIB) 11 13 molecuilder_SOURCES = builder.cpp 12 14 molecuilder_LDADD = libmolecuilder.a -
src/atom.cpp
r87e2e39 rc111db 6 6 7 7 #include "atom.hpp" 8 #include "bond.hpp" 9 #include "element.hpp" 8 10 #include "memoryallocator.hpp" 11 #include "vector.hpp" 9 12 10 13 /************************************* Functions for class atom *************************************/ … … 62 65 atom::~atom() 63 66 { 64 Free(&ComponentNr); 67 Free<int>(&ComponentNr, "atom::~atom: *ComponentNr"); 68 Free<char>(&Name, "atom::~atom: *Name"); 69 Trajectory.R.clear(); 70 Trajectory.U.clear(); 71 Trajectory.F.clear(); 65 72 }; 66 73 … … 80 87 }; 81 88 89 /** Sets father to itself or its father in case of copying a molecule. 90 */ 91 void atom::CorrectFather() 92 { 93 if (father->father == father) // same atom in copy's father points to itself 94 father = this; // set father to itself (copy of a whole molecule) 95 else 96 father = father->father; // set father to original's father 97 98 }; 99 100 /** Check whether father is equal to given atom. 101 * \param *ptr atom to compare father to 102 * \param **res return value (only set if atom::father is equal to \a *ptr) 103 */ 104 void atom::EqualsFather ( atom *ptr, atom **res ) 105 { 106 if ( ptr == father ) 107 *res = this; 108 }; 109 110 /** Checks whether atom is within the given box. 111 * \param offset offset to box origin 112 * \param *parallelepiped box matrix 113 * \return true - is inside, false - is not 114 */ 115 bool atom::IsInParallelepiped(Vector offset, double *parallelepiped) 116 { 117 return (node->IsInParallelepiped(offset, parallelepiped)); 118 }; 119 82 120 /** Output of a single atom. 83 121 * \param ElementNo cardinal number of the element … … 85 123 * \param *out stream to output to 86 124 * \param *comment commentary after '#' sign 87 */ 88 bool atom::Output(int ElementNo, int AtomNo, ofstream *out, const char *comment) const 125 * \return true - \a *out present, false - \a *out is NULL 126 */ 127 bool atom::Output(ofstream *out, int ElementNo, int AtomNo, const char *comment) const 89 128 { 90 129 if (out != NULL) { … … 102 141 return false; 103 142 }; 143 bool atom::Output(ofstream *out, int *ElementNo, int *AtomNo, const char *comment) 144 { 145 AtomNo[type->Z]++; // increment number 146 if (out != NULL) { 147 *out << "Ion_Type" << ElementNo[type->Z] << "_" << AtomNo[type->Z] << "\t" << fixed << setprecision(9) << showpoint; 148 *out << x.x[0] << "\t" << x.x[1] << "\t" << x.x[2]; 149 *out << "\t" << FixedIon; 150 if (v.Norm() > MYEPSILON) 151 *out << "\t" << scientific << setprecision(6) << v.x[0] << "\t" << v.x[1] << "\t" << v.x[2] << "\t"; 152 if (comment != NULL) 153 *out << " # " << comment << endl; 154 else 155 *out << " # molecule nr " << nr << endl; 156 return true; 157 } else 158 return false; 159 }; 104 160 105 161 /** Output of a single atom as one lin in xyz file. 106 162 * \param *out stream to output to 163 * \return true - \a *out present, false - \a *out is NULL 107 164 */ 108 165 bool atom::OutputXYZLine(ofstream *out) const … … 110 167 if (out != NULL) { 111 168 *out << type->symbol << "\t" << x.x[0] << "\t" << x.x[1] << "\t" << x.x[2] << "\t" << endl; 169 return true; 170 } else 171 return false; 172 }; 173 174 /** Output of a single atom as one lin in xyz file. 175 * \param *out stream to output to 176 * \param *ElementNo array with ion type number in the config file this atom's element shall have 177 * \param *AtomNo array with atom number in the config file this atom shall have, is increase by one automatically 178 * \param step Trajectory time step to output 179 * \return true - \a *out present, false - \a *out is NULL 180 */ 181 bool atom::OutputTrajectory(ofstream *out, int *ElementNo, int *AtomNo, int step) const 182 { 183 AtomNo[type->Z]++; 184 if (out != NULL) { 185 *out << "Ion_Type" << ElementNo[type->Z] << "_" << AtomNo[type->Z] << "\t" << fixed << setprecision(9) << showpoint; 186 *out << Trajectory.R.at(step).x[0] << "\t" << Trajectory.R.at(step).x[1] << "\t" << Trajectory.R.at(step).x[2]; 187 *out << "\t" << FixedIon; 188 if (Trajectory.U.at(step).Norm() > MYEPSILON) 189 *out << "\t" << scientific << setprecision(6) << Trajectory.U.at(step).x[0] << "\t" << Trajectory.U.at(step).x[1] << "\t" << Trajectory.U.at(step).x[2] << "\t"; 190 if (Trajectory.F.at(step).Norm() > MYEPSILON) 191 *out << "\t" << scientific << setprecision(6) << Trajectory.F.at(step).x[0] << "\t" << Trajectory.F.at(step).x[1] << "\t" << Trajectory.F.at(step).x[2] << "\t"; 192 *out << "\t# Number in molecule " << nr << endl; 193 return true; 194 } else 195 return false; 196 }; 197 198 /** Output of a single atom as one lin in xyz file. 199 * \param *out stream to output to 200 * \param step Trajectory time step to output 201 * \return true - \a *out present, false - \a *out is NULL 202 */ 203 bool atom::OutputTrajectoryXYZ(ofstream *out, int step) const 204 { 205 if (out != NULL) { 206 *out << type->symbol << "\t"; 207 *out << Trajectory.R.at(step).x[0] << "\t"; 208 *out << Trajectory.R.at(step).x[1] << "\t"; 209 *out << Trajectory.R.at(step).x[2] << endl; 210 return true; 211 } else 212 return false; 213 }; 214 215 /** Prints all bonds of this atom from given global lists. 216 * \param *out stream to output to 217 * \param *NumberOfBondsPerAtom array with number of bonds per atomic index 218 * \param ***ListOfBondsPerAtom array per atomic index of array with pointer to bond 219 * \return true - \a *out present, false - \a *out is NULL 220 */ 221 bool atom::OutputBondOfAtom(ofstream *out, int *NumberOfBondsPerAtom, bond ***ListOfBondsPerAtom) const 222 { 223 if (out != NULL) { 224 #ifdef ADDHYDROGEN 225 if (type->Z != 1) { // regard only non-hydrogen 226 #endif 227 *out << Verbose(4) << "Atom " << Name << "/" << nr << " with " << NumberOfBondsPerAtom[nr] << " bonds: "; 228 int TotalDegree = 0; 229 for (int j=0;j<NumberOfBondsPerAtom[nr];j++) { 230 *out << *ListOfBondsPerAtom[nr][j] << "\t"; 231 TotalDegree += ListOfBondsPerAtom[nr][j]->BondDegree; 232 } 233 *out << " -- TotalDegree: " << TotalDegree << endl; 234 #ifdef ADDHYDROGEN 235 } 236 #endif 112 237 return true; 113 238 } else … … 139 264 }; 140 265 266 /** Returns squared distance to a given vector. 267 * \param origin vector to calculate distance to 268 * \return distance squared 269 */ 270 double atom::DistanceSquaredToVector(Vector &origin) 271 { 272 return origin.DistanceSquared(&x); 273 }; 274 275 /** Adds kinetic energy of this atom to given temperature value. 276 * \param *temperature add on this value 277 * \param step given step of trajectory to add 278 */ 279 void atom::AddKineticToTemperature(double *temperature, int step) const 280 { 281 for (int i=NDIM;i--;) 282 *temperature += type->mass * Trajectory.U.at(step).x[i]* Trajectory.U.at(step).x[i]; 283 }; 284 285 /** Returns distance to a given vector. 286 * \param origin vector to calculate distance to 287 * \return distance 288 */ 289 double atom::DistanceToVector(Vector &origin) 290 { 291 return origin.Distance(&x); 292 }; 293 141 294 bool operator < (atom &a, atom &b) 142 295 { -
src/atom.hpp
r87e2e39 rc111db 11 11 using namespace std; 12 12 13 /*********************************************** includes ***********************************/ 14 13 15 // include config.h 14 16 #ifdef HAVE_CONFIG_H … … 16 18 #endif 17 19 20 #include <iostream> 21 #include <vector> 18 22 19 #include <iostream>23 #include "tesselation.hpp" 20 24 21 #include "element.hpp" 22 #include "tesselation.hpp" 23 #include "vector.hpp" 25 /****************************************** forward declarations *****************************/ 26 27 class bond; 28 class element; 29 class Vector; 30 31 /********************************************** declarations *******************************/ 24 32 25 33 /** Single atom. … … 28 36 class atom : public TesselPoint { 29 37 public: 30 Vector x; //!< coordinate array of atom, giving position within cell 31 Vector v; //!< velocity array of atom 38 struct 39 { 40 vector<Vector> R; //!< position vector 41 vector<Vector> U; //!< velocity vector 42 vector<Vector> F; //!< last force vector 43 } Trajectory; 44 45 Vector x; //!< coordinate vector of atom, giving last position within cell 46 Vector v; //!< velocity vector of atom, giving last velocity within cell 47 Vector F; //!< Force vector of atom, giving last force within cell 32 48 element *type; //!< pointing to element 33 49 atom *previous; //!< previous atom in molecule list … … 51 67 virtual ~atom(); 52 68 53 bool Output(int ElementNo, int AtomNo, ofstream *out, const char *comment = NULL) const; 69 bool Output(ofstream *out, int ElementNo, int AtomNo, const char *comment = NULL) const; 70 bool Output(ofstream *out, int *ElementNo, int *AtomNo, const char *comment = NULL); 54 71 bool OutputXYZLine(ofstream *out) const; 72 bool OutputTrajectory(ofstream *out, int *ElementNo, int *AtomNo, int step) const; 73 bool OutputTrajectoryXYZ(ofstream *out, int step) const; 74 bool OutputBondOfAtom(ofstream *out, int *NumberOfBondsPerAtom, bond ***ListOfBondsPerAtom) const; 75 76 void EqualsFather ( atom *ptr, atom **res ); 77 void CorrectFather(); 55 78 atom *GetTrueFather(); 56 79 bool Compare(const atom &ptr); 80 81 double DistanceToVector(Vector &origin); 82 double DistanceSquaredToVector(Vector &origin); 83 84 void AddKineticToTemperature(double *temperature, int step) const; 85 86 bool IsInParallelepiped(Vector offset, double *parallelepiped); 57 87 58 88 ostream & operator << (ostream &ost); -
src/bond.cpp
r87e2e39 rc111db 5 5 */ 6 6 7 #include "atom.hpp" 7 8 #include "bond.hpp" 9 #include "element.hpp" 10 #include "lists.hpp" 11 8 12 9 13 /***************************************** Functions for class bond ********************************/ -
src/bond.hpp
r87e2e39 rc111db 11 11 using namespace std; 12 12 13 /*********************************************** includes ***********************************/ 14 13 15 // include config.h 14 16 #ifdef HAVE_CONFIG_H … … 16 18 #endif 17 19 18 #include "atom.hpp" 20 /****************************************** forward declarations *****************************/ 21 22 class atom; 23 24 /********************************************** declarations *******************************/ 19 25 20 26 /** Bonds between atoms. -
src/boundary.cpp
r87e2e39 rc111db 1 /** \file boundary. hpp1 /** \file boundary.cpp 2 2 * 3 3 * Implementations and super-function for envelopes 4 4 */ 5 5 6 6 #include "atom.hpp" 7 #include "bond.hpp" 7 8 #include "boundary.hpp" 9 #include "config.hpp" 10 #include "element.hpp" 11 #include "helpers.hpp" 12 #include "linkedcell.hpp" 8 13 #include "memoryallocator.hpp" 14 #include "molecule.hpp" 15 #include "tesselation.hpp" 16 #include "tesselationhelpers.hpp" 9 17 10 18 #include<gsl/gsl_poly.h> … … 21 29 * \return NDIM array of the diameters 22 30 */ 23 double * 24 GetDiametersOfCluster(ofstream *out, Boundaries *BoundaryPtr, molecule *mol, 25 bool IsAngstroem) 31 double *GetDiametersOfCluster(ofstream *out, Boundaries *BoundaryPtr, molecule *mol, bool IsAngstroem) 26 32 { 27 33 // get points on boundary of NULL was given as parameter … … 113 119 ; 114 120 115 /** Creates the objects in a VRML file.116 * \param *out output stream for debugging117 * \param *vrmlfile output stream for tecplot data118 * \param *Tess Tesselation structure with constructed triangles119 * \param *mol molecule structure with atom positions120 */121 void WriteVrmlFile(ofstream *out, ofstream *vrmlfile, class Tesselation *Tess, class molecule *mol)122 {123 atom *Walker = mol->start;124 bond *Binder = mol->first;125 int i;126 Vector *center = mol->DetermineCenterOfAll(out);127 if (vrmlfile != NULL) {128 //cout << Verbose(1) << "Writing Raster3D file ... ";129 *vrmlfile << "#VRML V2.0 utf8" << endl;130 *vrmlfile << "#Created by molecuilder" << endl;131 *vrmlfile << "#All atoms as spheres" << endl;132 while (Walker->next != mol->end) {133 Walker = Walker->next;134 *vrmlfile << "Sphere {" << endl << " "; // 2 is sphere type135 for (i=0;i<NDIM;i++)136 *vrmlfile << Walker->x.x[i]-center->x[i] << " ";137 *vrmlfile << "\t0.1\t1. 1. 1." << endl; // radius 0.05 and white as colour138 }139 140 *vrmlfile << "# All bonds as vertices" << endl;141 while (Binder->next != mol->last) {142 Binder = Binder->next;143 *vrmlfile << "3" << endl << " "; // 2 is round-ended cylinder type144 for (i=0;i<NDIM;i++)145 *vrmlfile << Binder->leftatom->x.x[i]-center->x[i] << " ";146 *vrmlfile << "\t0.03\t";147 for (i=0;i<NDIM;i++)148 *vrmlfile << Binder->rightatom->x.x[i]-center->x[i] << " ";149 *vrmlfile << "\t0.03\t0. 0. 1." << endl; // radius 0.05 and blue as colour150 }151 152 *vrmlfile << "# All tesselation triangles" << endl;153 for (TriangleMap::iterator TriangleRunner = Tess->TrianglesOnBoundary.begin(); TriangleRunner != Tess->TrianglesOnBoundary.end(); TriangleRunner++) {154 *vrmlfile << "1" << endl << " "; // 1 is triangle type155 for (i=0;i<3;i++) { // print each node156 for (int j=0;j<NDIM;j++) // and for each node all NDIM coordinates157 *vrmlfile << TriangleRunner->second->endpoints[i]->node->node->x[j]-center->x[j] << " ";158 *vrmlfile << "\t";159 }160 *vrmlfile << "1. 0. 0." << endl; // red as colour161 *vrmlfile << "18" << endl << " 0.5 0.5 0.5" << endl; // 18 is transparency type for previous object162 }163 } else {164 cerr << "ERROR: Given vrmlfile is " << vrmlfile << "." << endl;165 }166 delete(center);167 };168 169 /** Creates the objects in a raster3d file (renderable with a header.r3d).170 * \param *out output stream for debugging171 * \param *rasterfile output stream for tecplot data172 * \param *Tess Tesselation structure with constructed triangles173 * \param *mol molecule structure with atom positions174 */175 void WriteRaster3dFile(ofstream *out, ofstream *rasterfile, class Tesselation *Tess, class molecule *mol)176 {177 atom *Walker = mol->start;178 bond *Binder = mol->first;179 int i;180 Vector *center = mol->DetermineCenterOfAll(out);181 if (rasterfile != NULL) {182 //cout << Verbose(1) << "Writing Raster3D file ... ";183 *rasterfile << "# Raster3D object description, created by MoleCuilder" << endl;184 *rasterfile << "@header.r3d" << endl;185 *rasterfile << "# All atoms as spheres" << endl;186 while (Walker->next != mol->end) {187 Walker = Walker->next;188 *rasterfile << "2" << endl << " "; // 2 is sphere type189 for (i=0;i<NDIM;i++)190 *rasterfile << Walker->x.x[i]-center->x[i] << " ";191 *rasterfile << "\t0.1\t1. 1. 1." << endl; // radius 0.05 and white as colour192 }193 194 *rasterfile << "# All bonds as vertices" << endl;195 while (Binder->next != mol->last) {196 Binder = Binder->next;197 *rasterfile << "3" << endl << " "; // 2 is round-ended cylinder type198 for (i=0;i<NDIM;i++)199 *rasterfile << Binder->leftatom->x.x[i]-center->x[i] << " ";200 *rasterfile << "\t0.03\t";201 for (i=0;i<NDIM;i++)202 *rasterfile << Binder->rightatom->x.x[i]-center->x[i] << " ";203 *rasterfile << "\t0.03\t0. 0. 1." << endl; // radius 0.05 and blue as colour204 }205 206 *rasterfile << "# All tesselation triangles" << endl;207 *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";208 for (TriangleMap::iterator TriangleRunner = Tess->TrianglesOnBoundary.begin(); TriangleRunner != Tess->TrianglesOnBoundary.end(); TriangleRunner++) {209 *rasterfile << "1" << endl << " "; // 1 is triangle type210 for (i=0;i<3;i++) { // print each node211 for (int j=0;j<NDIM;j++) // and for each node all NDIM coordinates212 *rasterfile << TriangleRunner->second->endpoints[i]->node->node->x[j]-center->x[j] << " ";213 *rasterfile << "\t";214 }215 *rasterfile << "1. 0. 0." << endl; // red as colour216 //*rasterfile << "18" << endl << " 0.5 0.5 0.5" << endl; // 18 is transparency type for previous object217 }218 *rasterfile << "9\n# terminating special property\n";219 } else {220 cerr << "ERROR: Given rasterfile is " << rasterfile << "." << endl;221 }222 delete(center);223 };224 225 /** This function creates the tecplot file, displaying the tesselation of the hull.226 * \param *out output stream for debugging227 * \param *tecplot output stream for tecplot data228 * \param N arbitrary number to differentiate various zones in the tecplot format229 */230 void WriteTecplotFile(ofstream *out, ofstream *tecplot, class Tesselation *TesselStruct, class molecule *mol, int N)231 {232 if ((tecplot != NULL) && (TesselStruct != NULL)) {233 // write header234 *tecplot << "TITLE = \"3D CONVEX SHELL\"" << endl;235 *tecplot << "VARIABLES = \"X\" \"Y\" \"Z\" \"U\"" << endl;236 *tecplot << "ZONE T=\"TRIANGLES" << N << "\", N=" << TesselStruct->PointsOnBoundary.size() << ", E=" << TesselStruct->TrianglesOnBoundary.size() << ", DATAPACKING=POINT, ZONETYPE=FETRIANGLE" << endl;237 int *LookupList = new int[mol->AtomCount];238 for (int i = 0; i < mol->AtomCount; i++)239 LookupList[i] = -1;240 241 // print atom coordinates242 *out << Verbose(2) << "The following triangles were created:";243 int Counter = 1;244 TesselPoint *Walker = NULL;245 for (PointMap::iterator target = TesselStruct->PointsOnBoundary.begin(); target != TesselStruct->PointsOnBoundary.end(); target++) {246 Walker = target->second->node;247 LookupList[Walker->nr] = Counter++;248 *tecplot << Walker->node->x[0] << " " << Walker->node->x[1] << " " << Walker->node->x[2] << " " << target->second->value << endl;249 }250 *tecplot << endl;251 // print connectivity252 for (TriangleMap::iterator runner = TesselStruct->TrianglesOnBoundary.begin(); runner != TesselStruct->TrianglesOnBoundary.end(); runner++) {253 *out << " " << runner->second->endpoints[0]->node->Name << "<->" << runner->second->endpoints[1]->node->Name << "<->" << runner->second->endpoints[2]->node->Name;254 *tecplot << LookupList[runner->second->endpoints[0]->node->nr] << " " << LookupList[runner->second->endpoints[1]->node->nr] << " " << LookupList[runner->second->endpoints[2]->node->nr] << endl;255 }256 delete[] (LookupList);257 *out << endl;258 }259 }260 261 121 262 122 /** Determines the boundary points of a cluster. … … 537 397 538 398 // flip the line 539 if ( !mol->TesselStruct->PickFarthestofTwoBaselines(out, line))399 if (mol->TesselStruct->PickFarthestofTwoBaselines(out, line) == 0.) 540 400 *out << Verbose(1) << "ERROR: Correction of concave baselines failed!" << endl; 541 else 401 else { 402 mol->TesselStruct->FlipBaseline(out, line); 542 403 *out << Verbose(1) << "INFO: Correction of concave baselines worked." << endl; 404 } 543 405 } 544 406 } … … 577 439 578 440 cout << Verbose(1) << "End of FindConvexBorder" << endl; 441 }; 442 443 /** For testing removes one boundary point after another to check for leaks. 444 * \param *out output stream for debugging 445 * \param *TesselStruct Tesselation containing envelope with boundary points 446 * \param *mol molecule 447 * \param *filename name of file 448 * \return true - all removed, false - something went wrong 449 */ 450 bool RemoveAllBoundaryPoints(ofstream *out, class Tesselation *TesselStruct, molecule *mol, char *filename) 451 { 452 int i=0; 453 char number[MAXSTRINGSIZE]; 454 455 if ((TesselStruct == NULL) || (TesselStruct->PointsOnBoundary.empty())) { 456 *out << Verbose(2) << "ERROR: TesselStruct is empty." << endl; 457 return false; 458 } 459 460 PointMap::iterator PointRunner; 461 while (!TesselStruct->PointsOnBoundary.empty()) { 462 *out << Verbose(2) << "Remaining points are: "; 463 for (PointMap::iterator PointSprinter = TesselStruct->PointsOnBoundary.begin(); PointSprinter != TesselStruct->PointsOnBoundary.end(); PointSprinter++) 464 *out << *(PointSprinter->second) << "\t"; 465 *out << endl; 466 467 PointRunner = TesselStruct->PointsOnBoundary.begin(); 468 // remove point 469 TesselStruct->RemovePointFromTesselatedSurface(out, PointRunner->second); 470 471 // store envelope 472 sprintf(number, "-%04d", i++); 473 StoreTrianglesinFile(out, mol, filename, number); 474 } 475 476 return true; 579 477 }; 580 478 … … 609 507 class BoundaryLineSet *line = NULL; 610 508 bool Concavity; 509 char dummy[MAXSTRINGSIZE]; 611 510 PointMap::iterator PointRunner, PointAdvance; 612 511 LineMap::iterator LineRunner, LineAdvance; … … 621 520 } 622 521 623 //CalculateConcavityPerBoundaryPoint(out, TesselStruct);624 StoreTrianglesinFile(out, mol, filename, "-first");625 626 522 // First step: RemovePointFromTesselatedSurface 523 int run = 0; 524 double tmp; 627 525 do { 628 526 Concavity = false; 527 sprintf(dummy, "-first-%d", run); 528 //CalculateConcavityPerBoundaryPoint(out, TesselStruct); 529 StoreTrianglesinFile(out, mol, filename, dummy); 530 629 531 PointRunner = TesselStruct->PointsOnBoundary.begin(); 630 532 PointAdvance = PointRunner; // we need an advanced point, as the PointRunner might get removed … … 636 538 line = LineRunner->second; 637 539 *out << Verbose(2) << "INFO: Current line of point " << *point << " is " << *line << "." << endl; 638 } 639 if (!line->CheckConvexityCriterion(out)) { 640 *out << Verbose(1) << "... point " << *point << " cannot be on convex envelope." << endl; 641 // remove the point 642 Concavity = true; 643 TesselStruct->RemovePointFromTesselatedSurface(out, point); 540 if (!line->CheckConvexityCriterion(out)) { 541 // remove the point if needed 542 *out << Verbose(1) << "... point " << *point << " cannot be on convex envelope." << endl; 543 volume += TesselStruct->RemovePointFromTesselatedSurface(out, point); 544 sprintf(dummy, "-first-%d", ++run); 545 StoreTrianglesinFile(out, mol, filename, dummy); 546 Concavity = true; 547 break; 548 } 644 549 } 645 550 PointRunner = PointAdvance; 646 551 } 647 552 553 sprintf(dummy, "-second-%d", run); 648 554 //CalculateConcavityPerBoundaryPoint(out, TesselStruct); 649 //StoreTrianglesinFile(out, mol, filename, "-second");555 StoreTrianglesinFile(out, mol, filename, dummy); 650 556 651 557 // second step: PickFarthestofTwoBaselines … … 658 564 // take highest of both lines 659 565 if (TesselStruct->IsConvexRectangle(out, line) == NULL) { 660 TesselStruct->PickFarthestofTwoBaselines(out, line); 661 Concavity = true; 566 tmp = TesselStruct->PickFarthestofTwoBaselines(out, line); 567 volume += tmp; 568 if (tmp != 0) { 569 mol->TesselStruct->FlipBaseline(out, line); 570 Concavity = true; 571 } 662 572 } 663 573 LineRunner = LineAdvance; 664 574 } 575 run++; 665 576 } while (Concavity); 577 //CalculateConcavityPerBoundaryPoint(out, TesselStruct); 578 //StoreTrianglesinFile(out, mol, filename, "-third"); 579 580 // third step: IsConvexRectangle 581 // LineRunner = TesselStruct->LinesOnBoundary.begin(); 582 // LineAdvance = LineRunner; // we need an advanced line, as the LineRunner might get removed 583 // while (LineRunner != TesselStruct->LinesOnBoundary.end()) { 584 // LineAdvance++; 585 // line = LineRunner->second; 586 // *out << Verbose(1) << "INFO: Current line is " << *line << "." << endl; 587 // //if (LineAdvance != TesselStruct->LinesOnBoundary.end()) 588 // //*out << Verbose(1) << "INFO: Next line will be " << *(LineAdvance->second) << "." << endl; 589 // if (!line->CheckConvexityCriterion(out)) { 590 // *out << Verbose(1) << "... line " << *line << " is concave, flipping it." << endl; 591 // 592 // // take highest of both lines 593 // point = TesselStruct->IsConvexRectangle(out, line); 594 // if (point != NULL) 595 // volume += TesselStruct->RemovePointFromTesselatedSurface(out, point); 596 // } 597 // LineRunner = LineAdvance; 598 // } 599 666 600 CalculateConcavityPerBoundaryPoint(out, TesselStruct); 667 StoreTrianglesinFile(out, mol, filename, "-third"); 668 669 // third step: IsConvexRectangle 670 LineRunner = TesselStruct->LinesOnBoundary.begin(); 671 LineAdvance = LineRunner; // we need an advanced line, as the LineRunner might get removed 672 while (LineRunner != TesselStruct->LinesOnBoundary.end()) { 673 LineAdvance++; 674 line = LineRunner->second; 675 *out << Verbose(1) << "INFO: Current line is " << *line << "." << endl; 676 //if (LineAdvance != TesselStruct->LinesOnBoundary.end()) 677 //*out << Verbose(1) << "INFO: Next line will be " << *(LineAdvance->second) << "." << endl; 678 if (!line->CheckConvexityCriterion(out)) { 679 *out << Verbose(1) << "... line " << *line << " is concave, flipping it." << endl; 680 681 // take highest of both lines 682 point = TesselStruct->IsConvexRectangle(out, line); 683 if (point != NULL) 684 TesselStruct->RemovePointFromTesselatedSurface(out, point); 685 } 686 LineRunner = LineAdvance; 687 } 688 689 CalculateConcavityPerBoundaryPoint(out, TesselStruct); 690 StoreTrianglesinFile(out, mol, filename, "-fourth"); 601 StoreTrianglesinFile(out, mol, filename, ""); 691 602 692 603 // end 604 *out << Verbose(1) << "Volume is " << volume << "." << endl; 693 605 *out << Verbose(0) << "End of ConvexizeNonconvexEnvelope" << endl; 694 606 return volume; 695 607 }; 696 608 697 /** Calculates the concavity for each of the BoundaryPointSet's in a Tesselation.698 * Sets BoundaryPointSet::value equal to the number of connected lines that are not convex.699 * \param *out output stream for debugging700 * \param *TesselStruct pointer to Tesselation structure701 */702 void CalculateConcavityPerBoundaryPoint(ofstream *out, class Tesselation *TesselStruct)703 {704 class BoundaryPointSet *point = NULL;705 class BoundaryLineSet *line = NULL;706 // calculate remaining concavity707 for (PointMap::iterator PointRunner = TesselStruct->PointsOnBoundary.begin(); PointRunner != TesselStruct->PointsOnBoundary.end(); PointRunner++) {708 point = PointRunner->second;709 *out << Verbose(1) << "INFO: Current point is " << *point << "." << endl;710 point->value = 0;711 for (LineMap::iterator LineRunner = point->lines.begin(); LineRunner != point->lines.end(); LineRunner++) {712 line = LineRunner->second;713 *out << Verbose(2) << "INFO: Current line of point " << *point << " is " << *line << "." << endl;714 if (!line->CheckConvexityCriterion(out))715 point->value += 1;716 }717 }718 };719 720 /** Stores triangles to file.721 * \param *out output stream for debugging722 * \param *mol molecule with atoms and bonds723 * \param *filename prefix of filename724 * \param *extraSuffix intermediate suffix725 */726 void StoreTrianglesinFile(ofstream *out, molecule *mol, const char *filename, const char *extraSuffix)727 {728 // 4. Store triangles in tecplot file729 if (filename != NULL) {730 if (DoTecplotOutput) {731 string OutputName(filename);732 OutputName.append(extraSuffix);733 OutputName.append(TecplotSuffix);734 ofstream *tecplot = new ofstream(OutputName.c_str());735 WriteTecplotFile(out, tecplot, mol->TesselStruct, mol, 0);736 tecplot->close();737 delete(tecplot);738 }739 if (DoRaster3DOutput) {740 string OutputName(filename);741 OutputName.append(extraSuffix);742 OutputName.append(Raster3DSuffix);743 ofstream *rasterplot = new ofstream(OutputName.c_str());744 WriteRaster3dFile(out, rasterplot, mol->TesselStruct, mol);745 rasterplot->close();746 delete(rasterplot);747 }748 }749 };750 609 751 610 /** Determines the volume of a cluster. … … 794 653 795 654 return volume; 796 } 797 ; 655 }; 656 657 /** Stores triangles to file. 658 * \param *out output stream for debugging 659 * \param *mol molecule with atoms and bonds 660 * \param *filename prefix of filename 661 * \param *extraSuffix intermediate suffix 662 */ 663 void StoreTrianglesinFile(ofstream *out, molecule *mol, const char *filename, const char *extraSuffix) 664 { 665 // 4. Store triangles in tecplot file 666 if (filename != NULL) { 667 if (DoTecplotOutput) { 668 string OutputName(filename); 669 OutputName.append(extraSuffix); 670 OutputName.append(TecplotSuffix); 671 ofstream *tecplot = new ofstream(OutputName.c_str()); 672 WriteTecplotFile(out, tecplot, mol->TesselStruct, mol, 0); 673 tecplot->close(); 674 delete(tecplot); 675 } 676 if (DoRaster3DOutput) { 677 string OutputName(filename); 678 OutputName.append(extraSuffix); 679 OutputName.append(Raster3DSuffix); 680 ofstream *rasterplot = new ofstream(OutputName.c_str()); 681 WriteRaster3dFile(out, rasterplot, mol->TesselStruct, mol); 682 rasterplot->close(); 683 delete(rasterplot); 684 } 685 } 686 }; 798 687 799 688 /** Creates multiples of the by \a *mol given cluster and suspends them in water with a given final density. … … 939 828 int N[NDIM]; 940 829 int n[NDIM]; 941 double *M = filler->ReturnFullMatrixforSymmetric(filler->cell_size);830 double *M = ReturnFullMatrixforSymmetric(filler->cell_size); 942 831 double Rotations[NDIM*NDIM]; 943 832 Vector AtomTranslations; … … 958 847 if ((*ListRunner)->TesselStruct == NULL) { 959 848 *out << Verbose(1) << "Pre-creating tesselation for molecule " << *ListRunner << "." << endl; 960 FindNonConvexBorder((ofstream *)&cout, (*ListRunner), LCList[i], NULL, 5.);849 FindNonConvexBorder((ofstream *)&cout, (*ListRunner), LCList[i], 5., NULL); 961 850 } 962 851 i++; … … 1080 969 * \param *Tess Tesselation filled with points, lines and triangles on boundary on return 1081 970 * \param *LCList atoms in LinkedCell list 971 * \param RADIUS radius of the virtual sphere 1082 972 * \param *filename filename prefix for output of vertex data 1083 * \para RADIUS radius of the virtual sphere 1084 */ 1085 void FindNonConvexBorder(ofstream *out, molecule* mol, class LinkedCell *LCList, const char *filename, const double RADIUS) 973 */ 974 void FindNonConvexBorder(ofstream *out, molecule* mol, class LinkedCell *LCList, const double RADIUS, const char *filename = NULL) 1086 975 { 1087 int N = 0;1088 976 bool freeLC = false; 1089 ofstream *tempstream = NULL;1090 char NumberName[255];1091 int TriangleFilesWritten = 0;1092 977 1093 978 *out << Verbose(1) << "Entering search for non convex hull. " << endl; … … 1103 988 LineMap::iterator testline; 1104 989 *out << Verbose(0) << "Begin of FindNonConvexBorder\n"; 1105 bool flag = false; // marks whether we went once through all baselines without finding any without two triangles 1106 bool failflag = false; 1107 990 bool OneLoopWithoutSuccessFlag = false; // marks whether we went once through all baselines without finding any without two triangles 991 bool TesselationFailFlag = false; 992 993 // initialise Linked Cell 1108 994 if (LCList == NULL) { 1109 995 LCList = new LinkedCell(mol, 2.*RADIUS); … … 1111 997 } 1112 998 999 // 1. get starting triangle 1113 1000 mol->TesselStruct->FindStartingTriangle(out, RADIUS, LCList); 1114 1001 1002 // 2. expand from there 1115 1003 baseline = mol->TesselStruct->LinesOnBoundary.begin(); 1116 // the outward most line is dangerous, as we may end up with wrapping up the starting triangle, hence 1117 // terminating the algorithm too early. 1118 if (baseline != mol->TesselStruct->LinesOnBoundary.end()) // skip first line as it its the outwardmost! 1119 baseline++; 1120 while ((baseline != mol->TesselStruct->LinesOnBoundary.end()) || (flag)) { 1004 baseline++; // skip first line 1005 while ((baseline != mol->TesselStruct->LinesOnBoundary.end()) || (OneLoopWithoutSuccessFlag)) { 1121 1006 if (baseline->second->triangles.size() == 1) { 1122 failflag = mol->TesselStruct->FindNextSuitableTriangle(out, *(baseline->second), *(((baseline->second->triangles.begin()))->second), RADIUS, N, LCList); //the line is there, so there is a triangle, but only one. 1123 flag = flag || failflag; 1124 if (!failflag) 1007 // 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. 1009 OneLoopWithoutSuccessFlag = OneLoopWithoutSuccessFlag || TesselationFailFlag; 1010 if (!TesselationFailFlag) 1125 1011 cerr << "WARNING: FindNextSuitableTriangle failed." << endl; 1012 1126 1013 // write temporary envelope 1127 if ((DoSingleStepOutput && (mol->TesselStruct->TrianglesOnBoundaryCount % SingleStepWidth == 0))) { // if we have a new triangle and want to output each new triangle configuration 1128 TriangleMap::iterator runner = mol->TesselStruct->TrianglesOnBoundary.end(); 1129 runner--; 1130 class BoundaryTriangleSet *triangle = runner->second; 1131 if (triangle != NULL) { 1132 sprintf(NumberName, "-%04d-%s_%s_%s", TriangleFilesWritten, triangle->endpoints[0]->node->Name, triangle->endpoints[1]->node->Name, triangle->endpoints[2]->node->Name); 1133 if (DoTecplotOutput) { 1134 string NameofTempFile(filename); 1135 NameofTempFile.append(NumberName); 1136 for(size_t npos = NameofTempFile.find_first_of(' '); npos != string::npos; npos = NameofTempFile.find(' ', npos)) 1137 NameofTempFile.erase(npos, 1); 1138 NameofTempFile.append(TecplotSuffix); 1139 *out << Verbose(1) << "Writing temporary non convex hull to file " << NameofTempFile << ".\n"; 1140 tempstream = new ofstream(NameofTempFile.c_str(), ios::trunc); 1141 WriteTecplotFile(out, tempstream, mol->TesselStruct, mol, TriangleFilesWritten); 1142 tempstream->close(); 1143 tempstream->flush(); 1144 delete(tempstream); 1145 } 1146 1147 if (DoRaster3DOutput) { 1148 string NameofTempFile(filename); 1149 NameofTempFile.append(NumberName); 1150 for(size_t npos = NameofTempFile.find_first_of(' '); npos != string::npos; npos = NameofTempFile.find(' ', npos)) 1151 NameofTempFile.erase(npos, 1); 1152 NameofTempFile.append(Raster3DSuffix); 1153 *out << Verbose(1) << "Writing temporary non convex hull to file " << NameofTempFile << ".\n"; 1154 tempstream = new ofstream(NameofTempFile.c_str(), ios::trunc); 1155 WriteRaster3dFile(out, tempstream, mol->TesselStruct, mol); 1156 // // include the current position of the virtual sphere in the temporary raster3d file 1157 // // make the circumsphere's center absolute again 1158 // helper.CopyVector(BaseRay->endpoints[0]->node->node); 1159 // helper.AddVector(BaseRay->endpoints[1]->node->node); 1160 // helper.Scale(0.5); 1161 // (*it)->OptCenter.AddVector(&helper); 1162 // Vector *center = mol->DetermineCenterOfAll(out); 1163 // (*it)->OptCenter.SubtractVector(center); 1164 // delete(center); 1165 // // and add to file plus translucency object 1166 // *tempstream << "# current virtual sphere\n"; 1167 // *tempstream << "8\n 25.0 0.6 -1.0 -1.0 -1.0 0.2 0 0 0 0\n"; 1168 // *tempstream << "2\n " << (*it)->OptCenter.x[0] << " " 1169 // << (*it)->OptCenter.x[1] << " " << (*it)->OptCenter.x[2] 1170 // << "\t" << RADIUS << "\t1 0 0\n"; 1171 // *tempstream << "9\n terminating special property\n"; 1172 tempstream->close(); 1173 tempstream->flush(); 1174 delete(tempstream); 1175 } 1176 } 1177 if (DoTecplotOutput || DoRaster3DOutput) 1178 TriangleFilesWritten++; 1014 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 configuration 1016 mol->TesselStruct->Output(out, filename, mol); 1017 } 1179 1018 } 1019 baseline = mol->TesselStruct->LinesOnBoundary.end(); 1020 *out << Verbose(2) << "Baseline set to end." << endl; 1180 1021 } else { 1181 1022 //cout << Verbose(1) << "Line " << *baseline->second << " has " << baseline->second->triangles.size() << " triangles adjacent" << endl; … … 1184 1025 } 1185 1026 1186 N++; 1027 if ((baseline == mol->TesselStruct->LinesOnBoundary.end()) && (OneLoopWithoutSuccessFlag)) { 1028 baseline = mol->TesselStruct->LinesOnBoundary.begin(); // restart if we reach end due to newly inserted lines 1029 OneLoopWithoutSuccessFlag = false; 1030 } 1187 1031 baseline++; 1188 if ((baseline == mol->TesselStruct->LinesOnBoundary.end()) && (flag)) { 1189 baseline = mol->TesselStruct->LinesOnBoundary.begin(); // restart if we reach end due to newly inserted lines 1190 flag = false; 1191 } 1192 } 1032 } 1033 // check envelope for consistency 1034 CheckListOfBaselines(out, mol->TesselStruct); 1035 1036 // look whether all points are inside of the convex envelope, otherwise add them via degenerated triangles 1037 //mol->TesselStruct->InsertStraddlingPoints(out, mol, LCList); 1038 // mol->GoToFirst(); 1039 // class TesselPoint *Runner = NULL; 1040 // while (!mol->IsEnd()) { 1041 // Runner = mol->GetPoint(); 1042 // *out << Verbose(1) << "Checking on " << Runner->Name << " ... " << endl; 1043 // if (!mol->TesselStruct->IsInnerPoint(out, Runner, LCList)) { 1044 // *out << Verbose(2) << Runner->Name << " is outside of envelope, adding via degenerated triangles." << endl; 1045 // mol->TesselStruct->AddBoundaryPointByDegeneratedTriangle(out, Runner, LCList); 1046 // } else { 1047 // *out << Verbose(2) << Runner->Name << " is inside of or on envelope." << endl; 1048 // } 1049 // mol->GoToNext(); 1050 // } 1193 1051 1194 1052 // Purges surplus triangles. 1195 1053 mol->TesselStruct->RemoveDegeneratedTriangles(); 1196 1054 1055 // check envelope for consistency 1056 CheckListOfBaselines(out, mol->TesselStruct); 1057 1197 1058 // write final envelope 1198 if (filename != 0) { 1199 *out << Verbose(1) << "Writing final tecplot file\n"; 1200 if (DoTecplotOutput) { 1201 string OutputName(filename); 1202 OutputName.append(TecplotSuffix); 1203 ofstream *tecplot = new ofstream(OutputName.c_str()); 1204 WriteTecplotFile(out, tecplot, mol->TesselStruct, mol, -1); 1205 tecplot->close(); 1206 delete(tecplot); 1207 } 1208 if (DoRaster3DOutput) { 1209 string OutputName(filename); 1210 OutputName.append(Raster3DSuffix); 1211 ofstream *raster = new ofstream(OutputName.c_str()); 1212 WriteRaster3dFile(out, raster, mol->TesselStruct, mol); 1213 raster->close(); 1214 delete(raster); 1215 } 1216 } else { 1217 cerr << "ERROR: Could definitively not find all necessary triangles!" << endl; 1218 } 1219 1220 cout << Verbose(2) << "Check: List of Baselines with not two connected triangles:" << endl; 1221 int counter = 0; 1222 for (testline = mol->TesselStruct->LinesOnBoundary.begin(); testline != mol->TesselStruct->LinesOnBoundary.end(); testline++) { 1223 if (testline->second->triangles.size() != 2) { 1224 cout << Verbose(2) << *testline->second << "\t" << testline->second->triangles.size() << endl; 1225 counter++; 1226 } 1227 } 1228 if (counter == 0) 1229 *out << Verbose(2) << "None." << endl; 1230 1231 // // Tests the IsInnerAtom() function. 1232 // Vector x (0, 0, 0); 1233 // *out << Verbose(0) << "Point to check: " << x << endl; 1234 // *out << Verbose(0) << "Check: IsInnerPoint() returns " << mol->TesselStruct->IsInnerPoint(out, x, LCList) 1235 // << "for vector " << x << "." << endl; 1236 // TesselPoint* a = mol->TesselStruct->PointsOnBoundary.begin()->second->node; 1237 // *out << Verbose(0) << "Point to check: " << *a << " (on boundary)." << endl; 1238 // *out << Verbose(0) << "Check: IsInnerAtom() returns " << mol->TesselStruct->IsInnerPoint(out, a, LCList) 1239 // << "for atom " << a << " (on boundary)." << endl; 1240 // LinkedNodes *List = NULL; 1241 // for (int i=0;i<NDIM;i++) { // each axis 1242 // LCList->n[i] = LCList->N[i]-1; // current axis is topmost cell 1243 // for (LCList->n[(i+1)%NDIM]=0;LCList->n[(i+1)%NDIM]<LCList->N[(i+1)%NDIM];LCList->n[(i+1)%NDIM]++) 1244 // for (LCList->n[(i+2)%NDIM]=0;LCList->n[(i+2)%NDIM]<LCList->N[(i+2)%NDIM];LCList->n[(i+2)%NDIM]++) { 1245 // List = LCList->GetCurrentCell(); 1246 // //cout << Verbose(2) << "Current cell is " << LC->n[0] << ", " << LC->n[1] << ", " << LC->n[2] << " with No. " << LC->index << "." << endl; 1247 // if (List != NULL) { 1248 // for (LinkedNodes::iterator Runner = List->begin();Runner != List->end();Runner++) { 1249 // if (mol->TesselStruct->PointsOnBoundary.find((*Runner)->nr) == mol->TesselStruct->PointsOnBoundary.end()) { 1250 // a = *Runner; 1251 // i=3; 1252 // for (int j=0;j<NDIM;j++) 1253 // LCList->n[j] = LCList->N[j]; 1254 // break; 1255 // } 1256 // } 1257 // } 1258 // } 1259 // } 1260 // *out << Verbose(0) << "Check: IsInnerPoint() returns " << mol->TesselStruct->IsInnerPoint(out, a, LCList) 1261 // << "for atom " << a << " (inside)." << endl; 1059 CalculateConcavityPerBoundaryPoint(out, mol->TesselStruct); 1060 StoreTrianglesinFile(out, mol, filename, ""); 1262 1061 1263 1062 if (freeLC) … … 1265 1064 *out << Verbose(0) << "End of FindNonConvexBorder\n"; 1266 1065 }; 1066 1267 1067 1268 1068 /** Finds a hole of sufficient size in \a this molecule to embed \a *srcmol into it. -
src/boundary.hpp
r87e2e39 rc111db 1 1 #ifndef BOUNDARY_HPP_ 2 2 #define BOUNDARY_HPP_ 3 4 using namespace std; 5 6 /*********************************************** includes ***********************************/ 3 7 4 8 // include config.h … … 7 11 #endif 8 12 13 #include <fstream> 14 #include <iostream> 15 9 16 // STL headers 10 17 #include <map> 11 18 12 #include "config.hpp" 13 #include "linkedcell.hpp" 14 #include "molecules.hpp" 15 #include "tesselation.hpp" 19 #include "defs.hpp" 20 21 /****************************************** forward declarations *****************************/ 22 23 class atom; 24 class BoundaryPointSet; 25 class BoundaryLineSet; 26 class BoundaryTriangleSet; 27 class config; 28 class LinkedCell; 29 class molecule; 30 class MoleculeListClass; 31 class Tesselation; 32 class Vector; 33 34 /********************************************** definitions *********************************/ 16 35 17 36 #define DEBUG 1 18 37 #define DoSingleStepOutput 0 19 38 #define SingleStepWidth 1 20 #define DoTecplotOutput 121 #define DoRaster3DOutput 122 #define DoVRMLOutput 123 #define TecplotSuffix ".dat"24 #define Raster3DSuffix ".r3d"25 #define VRMLSUffix ".wrl"26 39 27 40 #define DistancePair pair < double, atom* > … … 33 46 #define BoundariesTestPair pair< Boundaries::iterator, bool> 34 47 48 /********************************************** declarations *******************************/ 49 35 50 double VolumeOfConvexEnvelope(ofstream *out, class Tesselation *TesselStruct, class config *configuration); 36 51 double * GetDiametersOfCluster(ofstream *out, Boundaries *BoundaryPtr, molecule *mol, bool IsAngstroem); … … 38 53 molecule * FillBoxWithMolecule(ofstream *out, MoleculeListClass *List, molecule *filler, config &configuration, double distance[NDIM], double RandAtomDisplacement, double RandMolDisplacement, bool DoRandomRotation); 39 54 void FindConvexBorder(ofstream *out, molecule* mol, class LinkedCell *LCList, const char *filename); 40 void FindNonConvexBorder(ofstream *out, molecule* mol, class LinkedCell *LC, const char *tempbasename, const double RADIUS);55 void FindNonConvexBorder(ofstream *out, molecule* mol, class LinkedCell *LC, const double RADIUS, const char *tempbasename); 41 56 double ConvexizeNonconvexEnvelope(ofstream *out, class Tesselation *TesselStruct, molecule *mol, char *filename); 42 57 void FindNextSuitablePoint(class BoundaryTriangleSet *BaseTriangle, class BoundaryLineSet *BaseLine, atom*& OptCandidate, Vector *OptCandidateCenter, double *ShortestAngle, const double RADIUS, LinkedCell *LC); 43 58 Boundaries *GetBoundaryPoints(ofstream *out, molecule *mol); 44 void CalculateConcavityPerBoundaryPoint(ofstream *out, class Tesselation *TesselStruct);45 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); 46 61 47 62 -
src/builder.cpp
r87e2e39 rc111db 50 50 using namespace std; 51 51 52 #include "atom.hpp" 53 #include "bond.hpp" 52 54 #include "boundary.hpp" 55 #include "config.hpp" 56 #include "element.hpp" 53 57 #include "ellipsoid.hpp" 54 58 #include "helpers.hpp" 59 #include "leastsquaremin.hpp" 60 #include "linkedcell.hpp" 55 61 #include "memoryusageobserverunittest.hpp" 56 #include "molecules.hpp" 62 #include "molecule.hpp" 63 #include "periodentafel.hpp" 64 57 65 /********************************************* Subsubmenu routine ************************************/ 58 66 … … 1018 1026 cin >> nr; 1019 1027 count = 1; 1020 for( 1028 for(MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++) 1021 1029 if (nr == (*ListRunner)->IndexNr) { 1022 1030 mol = *ListRunner; 1023 1031 molecules->ListOfMolecules.erase(ListRunner); 1024 1032 delete(mol); 1033 break; 1025 1034 } 1026 1035 break; … … 1075 1084 1076 1085 case 'e': 1077 cout << Verbose(0) << "Not implemented yet." << endl; 1086 { 1087 int src, dest; 1088 molecule *srcmol = NULL, *destmol = NULL; 1089 do { 1090 cout << Verbose(0) << "Enter index of matrix molecule (the variable one): "; 1091 cin >> src; 1092 srcmol = molecules->ReturnIndex(src); 1093 } while ((srcmol == NULL) && (src != -1)); 1094 do { 1095 cout << Verbose(0) << "Enter index of molecule to merge into (the fixed one): "; 1096 cin >> dest; 1097 destmol = molecules->ReturnIndex(dest); 1098 } while ((destmol == NULL) && (dest != -1)); 1099 if ((src != -1) && (dest != -1)) 1100 molecules->EmbedMerge(destmol, srcmol); 1101 } 1078 1102 break; 1079 1103 … … 1366 1390 cout << "\t-p <file>\tParse given xyz file and create raw config file from it." << endl; 1367 1391 cout << "\t-P <file>\tParse given forces file and append as an MD step to config file via Verlet." << endl; 1368 cout << "\t-r \t\tConvert file from an old pcp syntax." << endl;1369 cout << "\t-R \t\tRemove all atoms out of sphere around a given one." << endl;1392 cout << "\t-r <id>\t\tRemove an atom with given id." << endl; 1393 cout << "\t-R <id> <radius>\t\tRemove all atoms out of sphere around a given one." << endl; 1370 1394 cout << "\t-s x1 x2 x3\tScale all atom coordinates by this vector (x1,x2,x3)." << endl; 1371 1395 cout << "\t-S <file> Store temperatures from the config file in <file>." << endl; … … 1464 1488 switch(argv[argptr-1][1]) { 1465 1489 case 'p': 1466 ExitFlag = 1;1490 if (ExitFlag == 0) ExitFlag = 1; 1467 1491 if ((argptr >= argc) || (argv[argptr][0] == '-')) { 1468 1492 ExitFlag = 255; … … 1480 1504 break; 1481 1505 case 'a': 1482 ExitFlag = 1;1506 if (ExitFlag == 0) ExitFlag = 1; 1483 1507 if ((argptr >= argc) || (argv[argptr][0] == '-') || (!IsValidNumber(argv[argptr+1]))) { 1484 1508 ExitFlag = 255; … … 1519 1543 break; 1520 1544 case 'D': 1521 ExitFlag = 1;1545 if (ExitFlag == 0) ExitFlag = 1; 1522 1546 { 1523 1547 cout << Verbose(1) << "Depth-First-Search Analysis." << endl; … … 1552 1576 break; 1553 1577 case 'E': 1554 ExitFlag = 1;1578 if (ExitFlag == 0) ExitFlag = 1; 1555 1579 if ((argptr+1 >= argc) || (!IsValidNumber(argv[argptr])) || (argv[argptr+1][0] == '-')) { 1556 1580 ExitFlag = 255; … … 1565 1589 break; 1566 1590 case 'F': 1567 ExitFlag = 1;1591 if (ExitFlag == 0) ExitFlag = 1; 1568 1592 if (argptr+5 >=argc) { 1569 1593 ExitFlag = 255; … … 1603 1627 break; 1604 1628 case 'A': 1605 ExitFlag = 1;1629 if (ExitFlag == 0) ExitFlag = 1; 1606 1630 if ((argptr >= argc) || (argv[argptr][0] == '-')) { 1607 1631 ExitFlag =255; … … 1616 1640 break; 1617 1641 case 'N': 1618 ExitFlag = 1;1642 if (ExitFlag == 0) ExitFlag = 1; 1619 1643 if ((argptr+1 >= argc) || (argv[argptr+1][0] == '-')){ 1620 1644 ExitFlag = 255; … … 1626 1650 cout << Verbose(0) << "Evaluating non-convex envelope."; 1627 1651 cout << Verbose(1) << "Using rolling ball of radius " << atof(argv[argptr]) << " and storing tecplot data in " << argv[argptr+1] << "." << endl; 1628 1652 start = clock(); 1629 1653 LinkedCell LCList(mol, atof(argv[argptr])*2.); 1630 FindNonConvexBorder((ofstream *)&cout, mol, &LCList, a rgv[argptr+1], atof(argv[argptr]));1654 FindNonConvexBorder((ofstream *)&cout, mol, &LCList, atof(argv[argptr]), argv[argptr+1]); 1631 1655 //FindDistributionOfEllipsoids((ofstream *)&cout, &T, &LCList, N, number, filename.c_str()); 1632 1633 1656 end = clock(); 1657 cout << Verbose(0) << "Clocks for this operation: " << (end-start) << ", time: " << ((double)(end-start)/CLOCKS_PER_SEC) << "s." << endl; 1634 1658 argptr+=2; 1635 1659 } 1636 1660 break; 1637 1661 case 'S': 1638 ExitFlag = 1;1662 if (ExitFlag == 0) ExitFlag = 1; 1639 1663 if ((argptr >= argc) || (argv[argptr][0] == '-')) { 1640 1664 ExitFlag = 255; … … 1653 1677 break; 1654 1678 case 'L': 1655 ExitFlag = 1; 1656 SaveFlag = true; 1657 cout << Verbose(1) << "Linear interpolation between configuration " << argv[argptr] << " and " << argv[argptr+1] << "." << endl; 1658 if (!mol->LinearInterpolationBetweenConfiguration((ofstream *)&cout, atoi(argv[argptr]), atoi(argv[argptr+1]), argv[argptr+2], configuration)) 1659 cout << Verbose(2) << "Could not store " << argv[argptr+2] << " files." << endl; 1660 else 1661 cout << Verbose(2) << "Steps created and " << argv[argptr+2] << " files stored." << endl; 1662 argptr+=3; 1679 if (ExitFlag == 0) ExitFlag = 1; 1680 if ((argptr >= argc) || (argv[argptr][0] == '-')) { 1681 ExitFlag = 255; 1682 cerr << "Not enough or invalid arguments given for storing tempature: -L <step0> <step1> <prefix> <identity mapping?>" << endl; 1683 } else { 1684 SaveFlag = true; 1685 cout << Verbose(1) << "Linear interpolation between configuration " << argv[argptr] << " and " << argv[argptr+1] << "." << endl; 1686 if (atoi(argv[argptr+3]) == 1) 1687 cout << Verbose(1) << "Using Identity for the permutation map." << endl; 1688 if (!mol->LinearInterpolationBetweenConfiguration((ofstream *)&cout, atoi(argv[argptr]), atoi(argv[argptr+1]), argv[argptr+2], configuration, atoi(argv[argptr+3])) == 1 ? true : false) 1689 cout << Verbose(2) << "Could not store " << argv[argptr+2] << " files." << endl; 1690 else 1691 cout << Verbose(2) << "Steps created and " << argv[argptr+2] << " files stored." << endl; 1692 argptr+=4; 1693 } 1663 1694 break; 1664 1695 case 'P': 1665 ExitFlag = 1;1696 if (ExitFlag == 0) ExitFlag = 1; 1666 1697 if ((argptr >= argc) || (argv[argptr][0] == '-')) { 1667 1698 ExitFlag = 255; … … 1678 1709 break; 1679 1710 case 'R': 1680 ExitFlag = 1;1681 if ((argptr+1 >= argc) || ( !IsValidNumber(argv[argptr])) || (!IsValidNumber(argv[argptr+1]))) {1711 if (ExitFlag == 0) ExitFlag = 1; 1712 if ((argptr+1 >= argc) || (argv[argptr][0] == '-') || (!IsValidNumber(argv[argptr])) || (!IsValidNumber(argv[argptr+1]))) { 1682 1713 ExitFlag = 255; 1683 1714 cerr << "Not enough or invalid arguments given for removing atoms: -R <id> <distance>" << endl; … … 1703 1734 break; 1704 1735 case 't': 1705 ExitFlag = 1;1706 if ((argptr+2 >= argc) || ( !IsValidNumber(argv[argptr])) || (!IsValidNumber(argv[argptr+1])) || (!IsValidNumber(argv[argptr+2])) ) {1736 if (ExitFlag == 0) ExitFlag = 1; 1737 if ((argptr+2 >= argc) || (argv[argptr][0] == '-') || (!IsValidNumber(argv[argptr])) || (!IsValidNumber(argv[argptr+1])) || (!IsValidNumber(argv[argptr+2])) ) { 1707 1738 ExitFlag = 255; 1708 1739 cerr << "Not enough or invalid arguments given for translation: -t <x> <y> <z>" << endl; 1709 1740 } else { 1710 ExitFlag = 1;1741 if (ExitFlag == 0) ExitFlag = 1; 1711 1742 SaveFlag = true; 1712 cout << Verbose(1) << "Translating all ions to new origin." << endl;1743 cout << Verbose(1) << "Translating all ions by given vector." << endl; 1713 1744 for (int i=NDIM;i--;) 1714 1745 x.x[i] = atof(argv[argptr+i]); … … 1716 1747 argptr+=3; 1717 1748 } 1749 break; 1718 1750 case 'T': 1719 ExitFlag = 1;1720 if ((argptr+2 >= argc) || ( !IsValidNumber(argv[argptr])) || (!IsValidNumber(argv[argptr+1])) || (!IsValidNumber(argv[argptr+2])) ) {1751 if (ExitFlag == 0) ExitFlag = 1; 1752 if ((argptr+2 >= argc) || (argv[argptr][0] == '-') || (!IsValidNumber(argv[argptr])) || (!IsValidNumber(argv[argptr+1])) || (!IsValidNumber(argv[argptr+2])) ) { 1721 1753 ExitFlag = 255; 1722 1754 cerr << "Not enough or invalid arguments given for periodic translation: -T <x> <y> <z>" << endl; 1723 1755 } else { 1724 ExitFlag = 1;1756 if (ExitFlag == 0) ExitFlag = 1; 1725 1757 SaveFlag = true; 1726 cout << Verbose(1) << "Translating all ions periodically to new origin." << endl;1758 cout << Verbose(1) << "Translating all ions periodically by given vector." << endl; 1727 1759 for (int i=NDIM;i--;) 1728 1760 x.x[i] = atof(argv[argptr+i]); … … 1732 1764 break; 1733 1765 case 's': 1734 ExitFlag = 1;1735 if ((argptr >= argc) || ( !IsValidNumber(argv[argptr])) ) {1766 if (ExitFlag == 0) ExitFlag = 1; 1767 if ((argptr >= argc) || (argv[argptr][0] == '-') || (!IsValidNumber(argv[argptr])) ) { 1736 1768 ExitFlag = 255; 1737 1769 cerr << "Not enough or invalid arguments given for scaling: -s <factor/[factor_x]> [factor_y] [factor_z]" << endl; … … 1759 1791 break; 1760 1792 case 'b': 1761 ExitFlag = 1;1762 if ((argptr+5 >= argc) || ( !IsValidNumber(argv[argptr])) || (!IsValidNumber(argv[argptr+1])) || (!IsValidNumber(argv[argptr+2])) || (!IsValidNumber(argv[argptr+3])) || (!IsValidNumber(argv[argptr+4])) || (!IsValidNumber(argv[argptr+5])) ) {1793 if (ExitFlag == 0) ExitFlag = 1; 1794 if ((argptr+5 >= argc) || (argv[argptr][0] == '-') || (!IsValidNumber(argv[argptr])) || (!IsValidNumber(argv[argptr+1])) || (!IsValidNumber(argv[argptr+2])) || (!IsValidNumber(argv[argptr+3])) || (!IsValidNumber(argv[argptr+4])) || (!IsValidNumber(argv[argptr+5])) ) { 1763 1795 ExitFlag = 255; 1764 1796 cerr << "Not enough or invalid arguments given for centering in box: -b <xx> <xy> <xz> <yy> <yz> <zz>" << endl; … … 1776 1808 break; 1777 1809 case 'B': 1778 ExitFlag = 1;1779 if ((argptr+5 >= argc) || ( !IsValidNumber(argv[argptr])) || (!IsValidNumber(argv[argptr+1])) || (!IsValidNumber(argv[argptr+2])) || (!IsValidNumber(argv[argptr+3])) || (!IsValidNumber(argv[argptr+4])) || (!IsValidNumber(argv[argptr+5])) ) {1810 if (ExitFlag == 0) ExitFlag = 1; 1811 if ((argptr+5 >= argc) || (argv[argptr][0] == '-') || (!IsValidNumber(argv[argptr])) || (!IsValidNumber(argv[argptr+1])) || (!IsValidNumber(argv[argptr+2])) || (!IsValidNumber(argv[argptr+3])) || (!IsValidNumber(argv[argptr+4])) || (!IsValidNumber(argv[argptr+5])) ) { 1780 1812 ExitFlag = 255; 1781 1813 cerr << "Not enough or invalid arguments given for bounding in box: -B <xx> <xy> <xz> <yy> <yz> <zz>" << endl; … … 1793 1825 break; 1794 1826 case 'c': 1795 ExitFlag = 1;1796 if ((argptr+2 >= argc) || ( !IsValidNumber(argv[argptr])) || (!IsValidNumber(argv[argptr+1])) || (!IsValidNumber(argv[argptr+2])) ) {1827 if (ExitFlag == 0) ExitFlag = 1; 1828 if ((argptr+2 >= argc) || (argv[argptr][0] == '-') || (!IsValidNumber(argv[argptr])) || (!IsValidNumber(argv[argptr+1])) || (!IsValidNumber(argv[argptr+2])) ) { 1797 1829 ExitFlag = 255; 1798 1830 cerr << "Not enough or invalid arguments given for centering with boundary: -c <boundary_x> <boundary_y> <boundary_z>" << endl; … … 1817 1849 break; 1818 1850 case 'O': 1819 ExitFlag = 1;1851 if (ExitFlag == 0) ExitFlag = 1; 1820 1852 SaveFlag = true; 1821 1853 cout << Verbose(1) << "Centering atoms on edge and setting box dimensions." << endl; … … 1826 1858 break; 1827 1859 case 'r': 1828 ExitFlag = 1; 1829 SaveFlag = true; 1830 cout << Verbose(1) << "Converting config file from supposed old to new syntax." << endl; 1860 if (ExitFlag == 0) ExitFlag = 1; 1861 if ((argptr >= argc) || (argv[argptr][0] == '-') || (!IsValidNumber(argv[argptr]))) { 1862 ExitFlag = 255; 1863 cerr << "Not enough or invalid arguments given for removing atoms: -r <id>" << endl; 1864 } else { 1865 SaveFlag = true; 1866 cout << Verbose(1) << "Removing atom " << argv[argptr] << "." << endl; 1867 atom *first = mol->FindAtom(atoi(argv[argptr])); 1868 mol->RemoveAtom(first); 1869 argptr+=1; 1870 } 1831 1871 break; 1832 1872 case 'f': 1833 ExitFlag = 1;1834 if ((argptr+1 >= argc) || ( !IsValidNumber(argv[argptr])) || (!IsValidNumber(argv[argptr+1]))) {1873 if (ExitFlag == 0) ExitFlag = 1; 1874 if ((argptr+1 >= argc) || (argv[argptr][0] == '-') || (!IsValidNumber(argv[argptr])) || (!IsValidNumber(argv[argptr+1]))) { 1835 1875 ExitFlag = 255; 1836 1876 cerr << "Not enough or invalid arguments for fragmentation: -f <max. bond distance> <bond order>" << endl; … … 1850 1890 break; 1851 1891 case 'm': 1852 ExitFlag = 1;1892 if (ExitFlag == 0) ExitFlag = 1; 1853 1893 j = atoi(argv[argptr++]); 1854 1894 if ((j<0) || (j>1)) { … … 1864 1904 break; 1865 1905 case 'o': 1866 ExitFlag = 1;1867 if ((argptr >= argc) || (argv[argptr][0] == '-')){1906 if (ExitFlag == 0) ExitFlag = 1; 1907 if ((argptr+1 >= argc) || (argv[argptr][0] == '-')){ 1868 1908 ExitFlag = 255; 1869 cerr << "Not enough or invalid arguments given for convex envelope: -o < tecplotoutput file>" << endl;1909 cerr << "Not enough or invalid arguments given for convex envelope: -o <convex output file> <non-convex output file>" << endl; 1870 1910 } else { 1871 1911 cout << Verbose(0) << "Evaluating volume of the convex envelope."; 1872 cout << Verbose(1) << "Storing tecplot data in " << argv[argptr] << "." << endl; 1912 cout << Verbose(1) << "Storing tecplot convex data in " << argv[argptr] << "." << endl; 1913 cout << Verbose(1) << "Storing tecplot non-convex data in " << argv[argptr+1] << "." << endl; 1873 1914 LinkedCell LCList(mol, 10.); 1874 1915 //FindConvexBorder((ofstream *)&cout, mol, &LCList, argv[argptr]); 1875 FindNonConvexBorder((ofstream *)&cout, mol, &LCList, argv[argptr], 10.);1876 1916 FindNonConvexBorder((ofstream *)&cout, mol, &LCList, 5., argv[argptr+1]); 1917 // RemoveAllBoundaryPoints((ofstream *)&cout, mol->TesselStruct, mol, argv[argptr]); 1877 1918 double volumedifference = ConvexizeNonconvexEnvelope((ofstream *)&cout, mol->TesselStruct, mol, argv[argptr]); 1878 1919 double clustervolume = VolumeOfConvexEnvelope((ofstream *)&cout, mol->TesselStruct, &configuration); 1879 1920 cout << Verbose(0) << "The tesselated volume area is " << clustervolume << " " << (configuration.GetIsAngstroem() ? "angstrom" : "atomiclength") << "^3." << endl; 1880 1921 cout << Verbose(0) << "The non-convex tesselated volume area is " << clustervolume-volumedifference << " " << (configuration.GetIsAngstroem() ? "angstrom" : "atomiclength") << "^3." << endl; 1881 argptr+= 1;1922 argptr+=2; 1882 1923 } 1883 1924 break; 1884 1925 case 'U': 1885 ExitFlag = 1;1886 if ((argptr+1 >= argc) || ( !IsValidNumber(argv[argptr])) || (!IsValidNumber(argv[argptr+1])) ) {1926 if (ExitFlag == 0) ExitFlag = 1; 1927 if ((argptr+1 >= argc) || (argv[argptr][0] == '-') || (!IsValidNumber(argv[argptr])) || (!IsValidNumber(argv[argptr+1])) ) { 1887 1928 ExitFlag = 255; 1888 1929 cerr << "Not enough or invalid arguments given for suspension with specified volume: -U <volume> <density>" << endl; … … 1893 1934 } 1894 1935 case 'u': 1895 ExitFlag = 1;1896 if ((argptr >= argc) || ( !IsValidNumber(argv[argptr])) ) {1936 if (ExitFlag == 0) ExitFlag = 1; 1937 if ((argptr >= argc) || (argv[argptr][0] == '-') || (!IsValidNumber(argv[argptr])) ) { 1897 1938 if (volume != -1) 1898 1939 ExitFlag = 255; … … 1917 1958 break; 1918 1959 case 'd': 1919 ExitFlag = 1;1920 if ((argptr+2 >= argc) || ( !IsValidNumber(argv[argptr])) || (!IsValidNumber(argv[argptr+1])) || (!IsValidNumber(argv[argptr+2])) ) {1960 if (ExitFlag == 0) ExitFlag = 1; 1961 if ((argptr+2 >= argc) || (argv[argptr][0] == '-') || (!IsValidNumber(argv[argptr])) || (!IsValidNumber(argv[argptr+1])) || (!IsValidNumber(argv[argptr+2])) ) { 1921 1962 ExitFlag = 255; 1922 1963 cerr << "Not enough or invalid arguments given for repeating cells: -d <repeat_x> <repeat_y> <repeat_z>" << endl; … … 2032 2073 return 0; 2033 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; 2034 2084 default: 2035 2085 break; -
src/config.cpp
r87e2e39 rc111db 5 5 */ 6 6 7 #include "atom.hpp" 7 8 #include "config.hpp" 9 #include "element.hpp" 8 10 #include "memoryallocator.hpp" 11 #include "molecule.hpp" 12 #include "periodentafel.hpp" 9 13 10 14 /******************************** Functions for class ConfigFileBuffer **********************/ … … 964 968 965 969 // check size of vectors 966 if ( mol->Trajectories[neues].R.size() <= (unsigned int)(repetition)) {970 if (neues->Trajectory.R.size() <= (unsigned int)(repetition)) { 967 971 //cout << "Increasing size for trajectory array of " << keyword << " to " << (repetition+10) << "." << endl; 968 mol->Trajectories[neues].R.resize(repetition+10);969 mol->Trajectories[neues].U.resize(repetition+10);970 mol->Trajectories[neues].F.resize(repetition+10);972 neues->Trajectory.R.resize(repetition+10); 973 neues->Trajectory.U.resize(repetition+10); 974 neues->Trajectory.F.resize(repetition+10); 971 975 } 972 976 973 977 // put into trajectories list 974 978 for (int d=0;d<NDIM;d++) 975 mol->Trajectories[neues].R.at(repetition).x[d] = neues->x.x[d];979 neues->Trajectory.R.at(repetition).x[d] = neues->x.x[d]; 976 980 977 981 // parse velocities if present … … 983 987 neues->v.x[2] = 0.; 984 988 for (int d=0;d<NDIM;d++) 985 mol->Trajectories[neues].U.at(repetition).x[d] = neues->v.x[d];989 neues->Trajectory.U.at(repetition).x[d] = neues->v.x[d]; 986 990 987 991 // parse forces if present … … 993 997 value[2] = 0.; 994 998 for (int d=0;d<NDIM;d++) 995 mol->Trajectories[neues].F.at(repetition).x[d] = value[d];999 neues->Trajectory.F.at(repetition).x[d] = value[d]; 996 1000 997 1001 // cout << "Parsed position of step " << (repetition) << ": ("; 998 1002 // for (int d=0;d<NDIM;d++) 999 // cout << mol->Trajectories[neues].R.at(repetition).x[d] << " "; // next step1003 // cout << neues->Trajectory.R.at(repetition).x[d] << " "; // next step 1000 1004 // cout << ")\t("; 1001 1005 // for (int d=0;d<NDIM;d++) 1002 // cout << mol->Trajectories[neues].U.at(repetition).x[d] << " "; // next step1006 // cout << neues->Trajectory.U.at(repetition).x[d] << " "; // next step 1003 1007 // cout << ")\t("; 1004 1008 // for (int d=0;d<NDIM;d++) 1005 // cout << mol->Trajectories[neues].F.at(repetition).x[d] << " "; // next step1009 // cout << neues->Trajectory.F.at(repetition).x[d] << " "; // next step 1006 1010 // cout << ")" << endl; 1007 1011 } … … 1011 1015 repetition--; 1012 1016 cout << "Found " << repetition << " trajectory steps." << endl; 1013 mol->MDSteps = repetition; 1017 if (repetition <= 1) // if onyl one step, desactivate use of trajectories 1018 mol->MDSteps = 0; 1019 else 1020 mol->MDSteps = repetition; 1014 1021 } else { 1015 1022 // find the maximum number of MD steps so that we may parse last one (Ion_Type1_1 must always be present, because is the first atom) -
src/config.hpp
r87e2e39 rc111db 11 11 using namespace std; 12 12 13 /*********************************************** includes ***********************************/ 14 13 15 // include config.h 14 16 #ifdef HAVE_CONFIG_H … … 16 18 #endif 17 19 18 #include "molecules.hpp" 19 #include "periodentafel.hpp" 20 #include <string> 21 22 /****************************************** forward declarations *****************************/ 23 24 class molecule; 25 class periodentafel; 26 27 /********************************************** declarations *******************************/ 20 28 21 29 class ConfigFileBuffer { -
src/datacreator.cpp
r87e2e39 rc111db 8 8 9 9 #include "datacreator.hpp" 10 #include "helpers.hpp" 11 #include "parser.hpp" 10 12 11 13 //=========================== FUNCTIONS============================ … … 49 51 /** Plots an energy vs. order. 50 52 * \param &Fragments EnergyMatrix class containing matrix values 51 * \param KeySet KeySetContainer class holding bond KeySetContainer::Order53 * \param KeySets KeySetContainer class holding bond KeySetContainer::Order 52 54 * \param *prefix prefix in filename (without ending) 53 55 * \param *msg message to be place in first line as a comment 54 56 * \return true if file was written successfully 55 57 */ 56 bool CreateDataEnergyOrder(class EnergyMatrix &Fragments, class KeySetsContainer &KeySet , const char *dir, const char *prefix, const char *msg, const char *datum)58 bool CreateDataEnergyOrder(class EnergyMatrix &Fragments, class KeySetsContainer &KeySets, const char *dir, const char *prefix, const char *msg, const char *datum) 57 59 { 58 60 stringstream filename; … … 64 66 output << "# " << msg << ", created on " << datum; 65 67 output << "#Order\tFrag.No.\t" << Fragments.Header[Fragments.MatrixCounter] << endl; 66 for (int BondOrder=0;BondOrder<KeySet .Order;BondOrder++) {67 for(int i=KeySet .FragmentsPerOrder[BondOrder];i--;) {68 for(int j=Fragments.RowCounter[ KeySet .OrderSet[BondOrder][i] ];j--;)69 for(int k=Fragments.ColumnCounter[ KeySet .OrderSet[BondOrder][i] ];k--;)70 Fragments.Matrix[Fragments.MatrixCounter][j][k] += Fragments.Matrix[ KeySet .OrderSet[BondOrder][i] ][j][k];71 } 72 output << BondOrder+1 << "\t" << KeySet .FragmentsPerOrder[BondOrder];68 for (int BondOrder=0;BondOrder<KeySets.Order;BondOrder++) { 69 for(int i=KeySets.FragmentsPerOrder[BondOrder];i--;) { 70 for(int j=Fragments.RowCounter[ KeySets.OrderSet[BondOrder][i] ];j--;) 71 for(int k=Fragments.ColumnCounter[ KeySets.OrderSet[BondOrder][i] ];k--;) 72 Fragments.Matrix[Fragments.MatrixCounter][j][k] += Fragments.Matrix[ KeySets.OrderSet[BondOrder][i] ][j][k]; 73 } 74 output << BondOrder+1 << "\t" << KeySets.FragmentsPerOrder[BondOrder]; 73 75 for (int l=0;l<Fragments.ColumnCounter[Fragments.MatrixCounter];l++) 74 76 output << scientific << "\t" << Fragments.Matrix[Fragments.MatrixCounter][ Fragments.RowCounter[Fragments.MatrixCounter]-1 ][l]; … … 82 84 * \param &Energy EnergyMatrix class containing reference values (in MatrixCounter matrix) 83 85 * \param &Fragments EnergyMatrix class containing matrix values 84 * \param KeySet KeySetContainer class holding bond KeySetContainer::Order86 * \param KeySets KeySetContainer class holding bond KeySetContainer::Order 85 87 * \param *prefix prefix in filename (without ending) 86 88 * \param *msg message to be place in first line as a comment 87 89 * \return true if file was written successfully 88 90 */ 89 bool CreateDataDeltaEnergyOrder(class EnergyMatrix &Energy, class EnergyMatrix &Fragments, class KeySetsContainer &KeySet , const char *dir, const char *prefix, const char *msg, const char *datum)91 bool CreateDataDeltaEnergyOrder(class EnergyMatrix &Energy, class EnergyMatrix &Fragments, class KeySetsContainer &KeySets, const char *dir, const char *prefix, const char *msg, const char *datum) 90 92 { 91 93 stringstream filename; … … 98 100 output << "#Order\tFrag.No.\t" << Fragments.Header[Fragments.MatrixCounter] << endl; 99 101 Fragments.SetLastMatrix(Energy.Matrix[Energy.MatrixCounter],0); 100 for (int BondOrder=0;BondOrder<KeySet .Order;BondOrder++) {101 for(int i=KeySet .FragmentsPerOrder[BondOrder];i--;) {102 for(int j=Fragments.RowCounter[ KeySet .OrderSet[BondOrder][i] ];j--;)103 for(int k=Fragments.ColumnCounter[ KeySet .OrderSet[BondOrder][i] ];k--;)104 Fragments.Matrix[Fragments.MatrixCounter][j][k] -= Fragments.Matrix[ KeySet .OrderSet[BondOrder][i] ][j][k];105 } 106 output << BondOrder+1 << "\t" << KeySet .FragmentsPerOrder[BondOrder];102 for (int BondOrder=0;BondOrder<KeySets.Order;BondOrder++) { 103 for(int i=KeySets.FragmentsPerOrder[BondOrder];i--;) { 104 for(int j=Fragments.RowCounter[ KeySets.OrderSet[BondOrder][i] ];j--;) 105 for(int k=Fragments.ColumnCounter[ KeySets.OrderSet[BondOrder][i] ];k--;) 106 Fragments.Matrix[Fragments.MatrixCounter][j][k] -= Fragments.Matrix[ KeySets.OrderSet[BondOrder][i] ][j][k]; 107 } 108 output << BondOrder+1 << "\t" << KeySets.FragmentsPerOrder[BondOrder]; 107 109 for (int l=0;l<Fragments.ColumnCounter[Energy.MatrixCounter];l++) 108 110 if (fabs(Energy.Matrix[Energy.MatrixCounter][ Energy.RowCounter[Energy.MatrixCounter]-1 ][l]) < MYEPSILON) … … 118 120 /** Plot forces vs. order. 119 121 * \param &Fragments ForceMatrix class containing matrix values 120 * \param KeySet KeySetContainer class holding bond KeySetContainer::Order122 * \param KeySets KeySetContainer class holding bond KeySetContainer::Order 121 123 * \param *prefix prefix in filename (without ending) 122 124 * \param *msg message to be place in first line as a comment … … 124 126 * \return true if file was written successfully 125 127 */ 126 bool CreateDataForcesOrder(class ForceMatrix &Fragments, class KeySetsContainer &KeySet , const char *dir, const char *prefix,const char *msg, const char *datum, void (*CreateForce)(class MatrixContainer &, int))128 bool CreateDataForcesOrder(class ForceMatrix &Fragments, class KeySetsContainer &KeySets, const char *dir, const char *prefix,const char *msg, const char *datum, void (*CreateForce)(class MatrixContainer &, int)) 127 129 { 128 130 stringstream filename; … … 135 137 output << "# Order\tFrag.No.\t" << Fragments.Header[Fragments.MatrixCounter] << endl; 136 138 Fragments.SetLastMatrix(0.,0); 137 for (int BondOrder=0;BondOrder<KeySet .Order;BondOrder++) {138 Fragments.SumSubForces(Fragments, KeySet , BondOrder, 1.);139 output << BondOrder+1 << "\t" << KeySet .FragmentsPerOrder[BondOrder];139 for (int BondOrder=0;BondOrder<KeySets.Order;BondOrder++) { 140 Fragments.SumSubForces(Fragments, KeySets, BondOrder, 1.); 141 output << BondOrder+1 << "\t" << KeySets.FragmentsPerOrder[BondOrder]; 140 142 CreateForce(Fragments, Fragments.MatrixCounter); 141 143 for (int l=0;l<Fragments.ColumnCounter[Fragments.MatrixCounter];l++) … … 150 152 * \param &Force ForceMatrix containing reference values (in MatrixCounter matrix) 151 153 * \param &Fragments ForceMatrix class containing matrix values 152 * \param KeySet KeySetContainer class holding bond KeySetContainer::Order154 * \param KeySets KeySetContainer class holding bond KeySetContainer::Order 153 155 * \param *prefix prefix in filename (without ending) 154 156 * \param *msg message to be place in first line as a comment … … 156 158 * \return true if file was written successfully 157 159 */ 158 bool CreateDataDeltaForcesOrder(class ForceMatrix &Force, class ForceMatrix &Fragments, class KeySetsContainer &KeySet , const char *dir, const char *prefix, const char *msg, const char *datum, void (*CreateForce)(class MatrixContainer &, int))160 bool CreateDataDeltaForcesOrder(class ForceMatrix &Force, class ForceMatrix &Fragments, class KeySetsContainer &KeySets, const char *dir, const char *prefix, const char *msg, const char *datum, void (*CreateForce)(class MatrixContainer &, int)) 159 161 { 160 162 stringstream filename; … … 167 169 output << "# Order\tFrag.No.\t" << Fragments.Header[Fragments.MatrixCounter] << endl; 168 170 Fragments.SetLastMatrix(Force.Matrix[Force.MatrixCounter],0); 169 for (int BondOrder=0;BondOrder<KeySet .Order;BondOrder++) {170 Fragments.SumSubForces(Fragments, KeySet , BondOrder, -1.);171 output << BondOrder+1 << "\t" << KeySet .FragmentsPerOrder[BondOrder];171 for (int BondOrder=0;BondOrder<KeySets.Order;BondOrder++) { 172 Fragments.SumSubForces(Fragments, KeySets, BondOrder, -1.); 173 output << BondOrder+1 << "\t" << KeySets.FragmentsPerOrder[BondOrder]; 172 174 CreateForce(Fragments, Fragments.MatrixCounter); 173 175 for (int l=0;l<Fragments.ColumnCounter[Fragments.MatrixCounter];l++) … … 182 184 * \param &Force ForceMatrix containing reference values (in MatrixCounter matrix) 183 185 * \param &Fragments ForceMatrix class containing matrix values 184 * \param KeySet KeySetContainer class holding bond KeySetContainer::Order186 * \param KeySets KeySetContainer class holding bond KeySetContainer::Order 185 187 * \param *prefix prefix in filename (without ending) 186 188 * \param *msg message to be place in first line as a comment … … 188 190 * \return true if file was written successfully 189 191 */ 190 bool CreateDataDeltaForcesOrderPerAtom(class ForceMatrix &Force, class ForceMatrix &Fragments, class KeySetsContainer &KeySet , const char *dir, const char *prefix, const char *msg, const char *datum)192 bool CreateDataDeltaForcesOrderPerAtom(class ForceMatrix &Force, class ForceMatrix &Fragments, class KeySetsContainer &KeySets, const char *dir, const char *prefix, const char *msg, const char *datum) 191 193 { 192 194 stringstream filename; … … 200 202 output << "# AtomNo\t" << Fragments.Header[Fragments.MatrixCounter] << endl; 201 203 Fragments.SetLastMatrix(Force.Matrix[Force.MatrixCounter], 0); 202 for (int BondOrder=0;BondOrder<KeySet .Order;BondOrder++) {204 for (int BondOrder=0;BondOrder<KeySets.Order;BondOrder++) { 203 205 //cout << "Current order is " << BondOrder << "." << endl; 204 Fragments.SumSubForces(Fragments, KeySet , BondOrder, -1.);206 Fragments.SumSubForces(Fragments, KeySets, BondOrder, -1.); 205 207 // errors per atom 206 208 output << endl << "#Order\t" << BondOrder+1 << endl; … … 229 231 /** Plot forces error vs. vs atom vs. order. 230 232 * \param &Fragments ForceMatrix class containing matrix values 231 * \param KeySet KeySetContainer class holding bond KeySetContainer::Order233 * \param KeySets KeySetContainer class holding bond KeySetContainer::Order 232 234 * \param *prefix prefix in filename (without ending) 233 235 * \param *msg message to be place in first line as a comment … … 235 237 * \return true if file was written successfully 236 238 */ 237 bool CreateDataForcesOrderPerAtom(class ForceMatrix &Fragments, class KeySetsContainer &KeySet , const char *dir, const char *prefix, const char *msg, const char *datum)239 bool CreateDataForcesOrderPerAtom(class ForceMatrix &Fragments, class KeySetsContainer &KeySets, const char *dir, const char *prefix, const char *msg, const char *datum) 238 240 { 239 241 stringstream filename; … … 245 247 output << "# " << msg << ", created on " << datum; 246 248 output << "# AtomNo\t" << Fragments.Header[Fragments.MatrixCounter] << endl; 247 for (int BondOrder=0;BondOrder<KeySet .Order;BondOrder++) {249 for (int BondOrder=0;BondOrder<KeySets.Order;BondOrder++) { 248 250 //cout << "Current order is " << BondOrder << "." << endl; 249 Fragments.SumSubForces(Fragments, KeySet , BondOrder, 1.);251 Fragments.SumSubForces(Fragments, KeySets, BondOrder, 1.); 250 252 // errors per atom 251 253 output << endl << "#Order\t" << BondOrder+1 << endl; … … 266 268 * \param &Hessian HessianMatrix containing reference values (in MatrixCounter matrix) 267 269 * \param &Fragments HessianMatrix class containing matrix values 268 * \param KeySet KeySetContainer class holding bond KeySetContainer::Order270 * \param KeySets KeySetContainer class holding bond KeySetContainer::Order 269 271 * \param *prefix prefix in filename (without ending) 270 272 * \param *msg message to be place in first line as a comment … … 272 274 * \return true if file was written successfully 273 275 */ 274 bool CreateDataDeltaHessianOrderPerAtom(class HessianMatrix &Hessian, class HessianMatrix &Fragments, class KeySetsContainer &KeySet , const char *dir, const char *prefix, const char *msg, const char *datum)276 bool CreateDataDeltaHessianOrderPerAtom(class HessianMatrix &Hessian, class HessianMatrix &Fragments, class KeySetsContainer &KeySets, const char *dir, const char *prefix, const char *msg, const char *datum) 275 277 { 276 278 stringstream filename; … … 283 285 output << "# AtomNo\t" << Fragments.Header[Fragments.MatrixCounter] << endl; 284 286 Fragments.SetLastMatrix(Hessian.Matrix[Hessian.MatrixCounter], 0); 285 for (int BondOrder=0;BondOrder<KeySet .Order;BondOrder++) {287 for (int BondOrder=0;BondOrder<KeySets.Order;BondOrder++) { 286 288 //cout << "Current order is " << BondOrder << "." << endl; 287 Fragments.SumSubHessians(Fragments, KeySet , BondOrder, -1.);289 Fragments.SumSubHessians(Fragments, KeySets, BondOrder, -1.); 288 290 // errors per atom 289 291 output << endl << "#Order\t" << BondOrder+1 << endl; … … 304 306 * \param &Hessian HessianMatrix containing reference values (in MatrixCounter matrix) 305 307 * \param &Fragments HessianMatrix class containing matrix values 306 * \param KeySet KeySetContainer class holding bond KeySetContainer::Order308 * \param KeySets KeySetContainer class holding bond KeySetContainer::Order 307 309 * \param *prefix prefix in filename (without ending) 308 310 * \param *msg message to be place in first line as a comment … … 310 312 * \return true if file was written successfully 311 313 */ 312 bool CreateDataDeltaFrobeniusOrderPerAtom(class HessianMatrix &Hessian, class HessianMatrix &Fragments, class KeySetsContainer &KeySet , const char *dir, const char *prefix, const char *msg, const char *datum)314 bool CreateDataDeltaFrobeniusOrderPerAtom(class HessianMatrix &Hessian, class HessianMatrix &Fragments, class KeySetsContainer &KeySets, const char *dir, const char *prefix, const char *msg, const char *datum) 313 315 { 314 316 stringstream filename; … … 323 325 output << "# AtomNo\t"; 324 326 Fragments.SetLastMatrix(Hessian.Matrix[Hessian.MatrixCounter], 0); 325 for (int BondOrder=0;BondOrder<KeySet .Order;BondOrder++) {327 for (int BondOrder=0;BondOrder<KeySets.Order;BondOrder++) { 326 328 output << "Order" << BondOrder+1 << "\t"; 327 329 } 328 330 output << endl; 329 331 output << Fragments.RowCounter[ Fragments.MatrixCounter ] << "\t"; 330 for (int BondOrder=0;BondOrder<KeySet .Order;BondOrder++) {332 for (int BondOrder=0;BondOrder<KeySets.Order;BondOrder++) { 331 333 //cout << "Current order is " << BondOrder << "." << endl; 332 Fragments.SumSubHessians(Fragments, KeySet , BondOrder, -1.);334 Fragments.SumSubHessians(Fragments, KeySets, BondOrder, -1.); 333 335 // frobenius norm of errors per atom 334 336 norm = 0.; … … 348 350 /** Plot hessian error vs. vs atom vs. order. 349 351 * \param &Fragments HessianMatrix class containing matrix values 350 * \param KeySet KeySetContainer class holding bond KeySetContainer::Order352 * \param KeySets KeySetContainer class holding bond KeySetContainer::Order 351 353 * \param *prefix prefix in filename (without ending) 352 354 * \param *msg message to be place in first line as a comment … … 354 356 * \return true if file was written successfully 355 357 */ 356 bool CreateDataHessianOrderPerAtom(class HessianMatrix &Fragments, class KeySetsContainer &KeySet , const char *dir, const char *prefix, const char *msg, const char *datum)358 bool CreateDataHessianOrderPerAtom(class HessianMatrix &Fragments, class KeySetsContainer &KeySets, const char *dir, const char *prefix, const char *msg, const char *datum) 357 359 { 358 360 stringstream filename; … … 365 367 output << "# AtomNo\t" << Fragments.Header[ Fragments.MatrixCounter ] << endl; 366 368 Fragments.SetLastMatrix(0., 0); 367 for (int BondOrder=0;BondOrder<KeySet .Order;BondOrder++) {369 for (int BondOrder=0;BondOrder<KeySets.Order;BondOrder++) { 368 370 //cout << "Current order is " << BondOrder << "." << endl; 369 Fragments.SumSubHessians(Fragments, KeySet , BondOrder, 1.);371 Fragments.SumSubHessians(Fragments, KeySets, BondOrder, 1.); 370 372 // errors per atom 371 373 output << endl << "#Order\t" << BondOrder+1 << endl; … … 384 386 /** Plot matrix vs. fragment. 385 387 */ 386 bool CreateDataFragment(class MatrixContainer &Fragment, class KeySetsContainer &KeySet , const char *dir, const char *prefix, const char *msg, const char *datum, void (*CreateFragment)(class MatrixContainer &, int))388 bool CreateDataFragment(class MatrixContainer &Fragment, class KeySetsContainer &KeySets, const char *dir, const char *prefix, const char *msg, const char *datum, void (*CreateFragment)(class MatrixContainer &, int)) 387 389 { 388 390 stringstream filename; … … 394 396 output << "# " << msg << ", created on " << datum << endl; 395 397 output << "#Order\tFrag.No.\t" << Fragment.Header[ Fragment.MatrixCounter ] << endl; 396 for (int BondOrder=0;BondOrder<KeySet .Order;BondOrder++) {397 for(int i=0;i<KeySet .FragmentsPerOrder[BondOrder];i++) {398 output << BondOrder+1 << "\t" << KeySet .OrderSet[BondOrder][i]+1;399 CreateFragment(Fragment, KeySet .OrderSet[BondOrder][i]);400 for (int l=0;l<Fragment.ColumnCounter[ KeySet .OrderSet[BondOrder][i] ];l++)401 output << scientific << "\t" << Fragment.Matrix[ KeySet .OrderSet[BondOrder][i] ][ Fragment.RowCounter[ KeySet.OrderSet[BondOrder][i] ] ][l];398 for (int BondOrder=0;BondOrder<KeySets.Order;BondOrder++) { 399 for(int i=0;i<KeySets.FragmentsPerOrder[BondOrder];i++) { 400 output << BondOrder+1 << "\t" << KeySets.OrderSet[BondOrder][i]+1; 401 CreateFragment(Fragment, KeySets.OrderSet[BondOrder][i]); 402 for (int l=0;l<Fragment.ColumnCounter[ KeySets.OrderSet[BondOrder][i] ];l++) 403 output << scientific << "\t" << Fragment.Matrix[ KeySets.OrderSet[BondOrder][i] ][ Fragment.RowCounter[ KeySets.OrderSet[BondOrder][i] ] ][l]; 402 404 output << endl; 403 405 } … … 409 411 /** Copies fragment energy values into last matrix of \a Matrix with greatest total energy. 410 412 * \param &Matrix MatrixContainer with all fragment energy values 411 * \param &KeySet KeySetsContainer with associations of each fragment to a bond order413 * \param &KeySets KeySetsContainer with associations of each fragment to a bond order 412 414 * \param BondOrder current bond order 413 415 */ 414 void CreateMaxFragmentOrder(class MatrixContainer &Fragments, class KeySetsContainer &KeySet , int BondOrder)416 void CreateMaxFragmentOrder(class MatrixContainer &Fragments, class KeySetsContainer &KeySets, int BondOrder) 415 417 { 416 418 for(int j=Fragments.RowCounter[ Fragments.MatrixCounter ];j--;) { 417 for(int i=KeySet .FragmentsPerOrder[BondOrder];i--;) {418 if (fabs(Fragments.Matrix[ Fragments.MatrixCounter ][j][1]) < fabs(Fragments.Matrix[ KeySet .OrderSet[BondOrder][i] ][j][1])) {419 for(int i=KeySets.FragmentsPerOrder[BondOrder];i--;) { 420 if (fabs(Fragments.Matrix[ Fragments.MatrixCounter ][j][1]) < fabs(Fragments.Matrix[ KeySets.OrderSet[BondOrder][i] ][j][1])) { 419 421 for (int k=Fragments.ColumnCounter[ Fragments.MatrixCounter ];k--;) 420 Fragments.Matrix[ Fragments.MatrixCounter ][j][k] = Fragments.Matrix[ KeySet .OrderSet[BondOrder][i] ][j][k];422 Fragments.Matrix[ Fragments.MatrixCounter ][j][k] = Fragments.Matrix[ KeySets.OrderSet[BondOrder][i] ][j][k]; 421 423 } 422 424 } … … 426 428 /** Copies fragment energy values into last matrix of \a Matrix with smallest total energy. 427 429 * \param &Matrix MatrixContainer with all fragment energy values 428 * \param &KeySet KeySetsContainer with associations of each fragment to a bond order430 * \param &KeySets KeySetsContainer with associations of each fragment to a bond order 429 431 * \param BondOrder current bond order 430 432 */ 431 void CreateMinFragmentOrder(class MatrixContainer &Fragments, class KeySetsContainer &KeySet , int BondOrder)433 void CreateMinFragmentOrder(class MatrixContainer &Fragments, class KeySetsContainer &KeySets, int BondOrder) 432 434 { 433 435 for(int j=0;j<Fragments.RowCounter[ Fragments.MatrixCounter ];j++) { … … 435 437 do { // first get a minimum value unequal to 0 436 438 for (int k=Fragments.ColumnCounter[ Fragments.MatrixCounter ];k--;) 437 Fragments.Matrix[ Fragments.MatrixCounter ][j][k] = Fragments.Matrix[ KeySet .OrderSet[BondOrder][i] ][j][k];439 Fragments.Matrix[ Fragments.MatrixCounter ][j][k] = Fragments.Matrix[ KeySets.OrderSet[BondOrder][i] ][j][k]; 438 440 i++; 439 } while ((fabs(Fragments.Matrix[ Fragments.MatrixCounter ][j][1]) < MYEPSILON) && (i<KeySet .FragmentsPerOrder[BondOrder]));440 for(;i<KeySet .FragmentsPerOrder[BondOrder];i++) { // then find lowest441 if (fabs(Fragments.Matrix[ Fragments.MatrixCounter ][j][1]) > fabs(Fragments.Matrix[ KeySet .OrderSet[BondOrder][i] ][j][1])) {441 } while ((fabs(Fragments.Matrix[ Fragments.MatrixCounter ][j][1]) < MYEPSILON) && (i<KeySets.FragmentsPerOrder[BondOrder])); 442 for(;i<KeySets.FragmentsPerOrder[BondOrder];i++) { // then find lowest 443 if (fabs(Fragments.Matrix[ Fragments.MatrixCounter ][j][1]) > fabs(Fragments.Matrix[ KeySets.OrderSet[BondOrder][i] ][j][1])) { 442 444 for (int k=Fragments.ColumnCounter[ Fragments.MatrixCounter ];k--;) 443 Fragments.Matrix[ Fragments.MatrixCounter ][j][k] = Fragments.Matrix[ KeySet .OrderSet[BondOrder][i] ][j][k];445 Fragments.Matrix[ Fragments.MatrixCounter ][j][k] = Fragments.Matrix[ KeySets.OrderSet[BondOrder][i] ][j][k]; 444 446 } 445 447 } … … 449 451 /** Plot matrix vs. fragment. 450 452 */ 451 bool CreateDataFragmentOrder(class MatrixContainer &Fragment, class KeySetsContainer &KeySet , const char *dir, const char *prefix, const char *msg, const char *datum, void (*CreateFragmentOrder)(class MatrixContainer &, class KeySetsContainer &, int))453 bool CreateDataFragmentOrder(class MatrixContainer &Fragment, class KeySetsContainer &KeySets, const char *dir, const char *prefix, const char *msg, const char *datum, void (*CreateFragmentOrder)(class MatrixContainer &, class KeySetsContainer &, int)) 452 454 { 453 455 stringstream filename; … … 460 462 output << "#Order\tFrag.No.\t" << Fragment.Header[ Fragment.MatrixCounter ] << endl; 461 463 // max 462 for (int BondOrder=0;BondOrder<KeySet .Order;BondOrder++) {464 for (int BondOrder=0;BondOrder<KeySets.Order;BondOrder++) { 463 465 Fragment.SetLastMatrix(0.,0); 464 CreateFragmentOrder(Fragment, KeySet , BondOrder);465 output << BondOrder+1 << "\t" << KeySet .FragmentsPerOrder[BondOrder];466 CreateFragmentOrder(Fragment, KeySets, BondOrder); 467 output << BondOrder+1 << "\t" << KeySets.FragmentsPerOrder[BondOrder]; 466 468 for (int l=0;l<Fragment.ColumnCounter[ Fragment.MatrixCounter ];l++) 467 469 output << scientific << "\t" << Fragment.Matrix[ Fragment.MatrixCounter ][ Fragment.RowCounter[ Fragment.MatrixCounter ]-1 ][l]; … … 618 620 /** Creates the pyxplotfile for energy data. 619 621 * \param Matrix MatrixContainer with matrix values 620 * \param KeySet contains bond order622 * \param KeySets contains bond order 621 623 * \param *dir directory 622 624 * \param *prefix prefix for all filenames (without ending) … … 635 637 * \return true if file was written successfully 636 638 */ 637 bool CreatePlotOrder(class MatrixContainer &Matrix, const class KeySetsContainer &KeySet , const char *dir, const char *prefix, const int keycolumns, const char *key, const char *logscale, const char *extraline, const int mxtics, const int xtics, const char *xlabel, const char *ylabel, const char *xrange, const char *yrange, const char *xargument, const char *uses, void (*CreatePlotLines)(ofstream &, class MatrixContainer &, const char *, const char *, const char *))639 bool CreatePlotOrder(class MatrixContainer &Matrix, const class KeySetsContainer &KeySets, const char *dir, const char *prefix, const int keycolumns, const char *key, const char *logscale, const char *extraline, const int mxtics, const int xtics, const char *xlabel, const char *ylabel, const char *xrange, const char *yrange, const char *xargument, const char *uses, void (*CreatePlotLines)(ofstream &, class MatrixContainer &, const char *, const char *, const char *)) 638 640 { 639 641 stringstream filename; -
src/datacreator.hpp
r87e2e39 rc111db 10 10 using namespace std; 11 11 12 //============================ INCLUDES =========================== 12 #include <iostream> 13 13 14 #include "helpers.hpp" 15 #include "parser.hpp" 14 /****************************************** forward declarations *****************************/ 16 15 17 //=========================== FUNCTIONS============================ 16 class EnergyMatrix; 17 class ForceMatrix; 18 class HessianMatrix; 19 class KeySetsContainer; 20 class MatrixContainer; 21 22 /********************************************** declarations *******************************/ 18 23 19 24 bool OpenOutputFile(ofstream &output, const char *dir, const char *filename); -
src/element.hpp
r87e2e39 rc111db 11 11 using namespace std; 12 12 13 /*********************************************** includes ***********************************/ 14 13 15 // include config.h 14 16 #ifdef HAVE_CONFIG_H … … 16 18 #endif 17 19 18 19 20 #include <iostream> 20 21 21 22 #include "defs.hpp" 23 24 /********************************************** declarations *******************************/ 22 25 23 26 /** Chemical element. -
src/ellipsoid.cpp
r87e2e39 rc111db 9 9 #include <gsl/gsl_vector.h> 10 10 11 #include <iomanip> 12 13 #include <set> 14 11 15 #include "boundary.hpp" 12 16 #include "ellipsoid.hpp" 17 #include "linkedcell.hpp" 18 #include "tesselation.hpp" 19 #include "vector.hpp" 20 #include "verbose.hpp" 13 21 14 22 /** Determines squared distance for a given point \a x to surface of ellipsoid. -
src/ellipsoid.hpp
r87e2e39 rc111db 9 9 #define ELLIPSOID_HPP_ 10 10 11 using namespace std; 12 13 /*********************************************** includes ***********************************/ 14 11 15 // include config.h 12 16 #ifdef HAVE_CONFIG_H … … 14 18 #endif 15 19 16 #include "linkedcell.hpp" 17 #include "vector.hpp" 20 #include <gsl/gsl_vector.h> 21 22 /****************************************** forward declarations *****************************/ 23 24 class LinkedCell; 25 class Vector; 26 27 /********************************************** declarations *******************************/ 18 28 19 29 double SquaredDistanceToEllipsoid(Vector &x, Vector &EllipsoidCenter, double *EllipsoidLength, double *EllipsoidAngle); -
src/graph.cpp
r87e2e39 rc111db 7 7 using namespace std; 8 8 9 #include "atom.hpp" 10 #include "bond.hpp" 11 #include "config.hpp" 9 12 #include "graph.hpp" 13 #include "molecule.hpp" 10 14 11 15 /***************************************** Implementations for graph classes ********************************/ 12 16 13 /** Constructor of class Graph. 17 ///** Constructor of class Graph. 18 // */ 19 //Graph::Graph() 20 //{ 21 //}; 22 // 23 ///** Destructor of class Graph. 24 // * Destructor does release memory for nodes and edges contained in its lists as well. 25 // */ 26 //Graph::~Graph() 27 //{ 28 //}; 29 // 30 ///** Constructor of class SubGraph. 31 // */ 32 //SubGraph::SubGraph() 33 //{ 34 //}; 35 // 36 ///** Destructor of class SubGraph. 37 // * Note that destructor does not deallocate either nodes or edges! (this is done by its subgraph!) 38 // */ 39 //SubGraph::~SubGraph() 40 //{ 41 //}; 42 // 43 ///** Constructor of class Node. 44 // */ 45 //Node::Node() 46 //{ 47 //}; 48 // 49 ///** Destructor of class Node. 50 // */ 51 //Node::~Node() 52 //{ 53 //}; 54 // 55 ///** Constructor of class Edge. 56 // */ 57 //Edge::Edge() 58 //{ 59 //}; 60 // 61 ///** Destructor of class Edge. 62 // */ 63 //Edge::~Edge() 64 //{ 65 //}; 66 67 68 //bool operator < (KeySet SubgraphA, KeySet SubgraphB) 69 //{ 70 // return KeyCompare(SubgraphA, SubgraphB); 71 //}; 72 73 /** Checking whether KeySet is not already present in Graph, if so just adds factor. 74 * \param *out output stream for debugging 75 * \param &set KeySet to insert 76 * \param &graph Graph to insert into 77 * \param *counter pointer to unique fragment count 78 * \param factor energy factor for the fragment 14 79 */ 15 Graph::Graph()80 void InsertFragmentIntoGraph(ofstream *out, struct UniqueFragments *Fragment) 16 81 { 82 GraphTestPair testGraphInsert; 83 84 testGraphInsert = Fragment->Leaflet->insert(GraphPair (*Fragment->FragmentSet,pair<int,double>(Fragment->FragmentCounter,Fragment->TEFactor))); // store fragment number and current factor 85 if (testGraphInsert.second) { 86 *out << Verbose(2) << "KeySet " << Fragment->FragmentCounter << " successfully inserted." << endl; 87 Fragment->FragmentCounter++; 88 } else { 89 *out << Verbose(2) << "KeySet " << Fragment->FragmentCounter << " failed to insert, present fragment is " << ((*(testGraphInsert.first)).second).first << endl; 90 ((*(testGraphInsert.first)).second).second += Fragment->TEFactor; // increase the "created" counter 91 *out << Verbose(2) << "New factor is " << ((*(testGraphInsert.first)).second).second << "." << endl; 92 } 93 }; 94 //void inline InsertIntoGraph(ofstream *out, KeyStack &stack, Graph &graph, int *counter, double factor) 95 //{ 96 // // copy stack contents to set and call overloaded function again 97 // KeySet set; 98 // for(KeyStack::iterator runner = stack.begin(); runner != stack.begin(); runner++) 99 // set.insert((*runner)); 100 // InsertIntoGraph(out, set, graph, counter, factor); 101 //}; 102 103 /** Inserts each KeySet in \a graph2 into \a graph1. 104 * \param *out output stream for debugging 105 * \param graph1 first (dest) graph 106 * \param graph2 second (source) graph 107 * \param *counter keyset counter that gets increased 108 */ 109 void InsertGraphIntoGraph(ofstream *out, Graph &graph1, Graph &graph2, int *counter) 110 { 111 GraphTestPair testGraphInsert; 112 113 for(Graph::iterator runner = graph2.begin(); runner != graph2.end(); runner++) { 114 testGraphInsert = graph1.insert(GraphPair ((*runner).first,pair<int,double>((*counter)++,((*runner).second).second))); // store fragment number and current factor 115 if (testGraphInsert.second) { 116 *out << Verbose(2) << "KeySet " << (*counter)-1 << " successfully inserted." << endl; 117 } else { 118 *out << Verbose(2) << "KeySet " << (*counter)-1 << " failed to insert, present fragment is " << ((*(testGraphInsert.first)).second).first << endl; 119 ((*(testGraphInsert.first)).second).second += (*runner).second.second; 120 *out << Verbose(2) << "New factor is " << (*(testGraphInsert.first)).second.second << "." << endl; 121 } 122 } 17 123 }; 18 124 19 /** Destructor of class Graph.20 * Destructor does release memory for nodes and edges contained in its lists as well.21 */22 Graph::~Graph()23 {24 };25 26 /** Constructor of class SubGraph.27 */28 SubGraph::SubGraph()29 {30 };31 32 /** Destructor of class SubGraph.33 * Note that destructor does not deallocate either nodes or edges! (this is done by its subgraph!)34 */35 SubGraph::~SubGraph()36 {37 };38 39 /** Constructor of class Node.40 */41 Node::Node()42 {43 };44 45 /** Destructor of class Node.46 */47 Node::~Node()48 {49 };50 51 /** Constructor of class Edge.52 */53 Edge::Edge()54 {55 };56 57 /** Destructor of class Edge.58 */59 Edge::~Edge()60 {61 };62 -
src/graph.hpp
r87e2e39 rc111db 8 8 #define GRAPH_HPP_ 9 9 10 /*********************************************** includes ***********************************/ 11 10 12 // include config.h 11 13 #ifdef HAVE_CONFIG_H … … 14 16 15 17 // STL headers 18 #include <deque> 16 19 #include <map> 17 #include < multimap>20 #include <set> 18 21 19 #include "molecules.hpp" 22 /****************************************** forward declarations *****************************/ 23 24 class atom; 25 class bond; 26 class config; 27 class molecule; 20 28 21 29 class Graph; … … 24 32 class Edge; 25 33 26 /***************************************** Various graph-related STL defines********************************/34 /********************************************** definitions *********************************/ 27 35 28 36 #define NodeMap pair < int, class Node* > 29 37 #define EdgeMap multimap < class Node*, class Edge* > 30 38 31 /***************************************** Definition for classes ********************************/ 39 #define KeyStack deque<int> 40 #define KeySet set<int> 41 #define NumberValuePair pair<int, double> 42 #define Graph map <KeySet, NumberValuePair, KeyCompare > 43 #define GraphPair pair <KeySet, NumberValuePair > 44 #define KeySetTestPair pair<KeySet::iterator, bool> 45 #define GraphTestPair pair<Graph::iterator, bool> 32 46 33 /** Graph class containing the graphs behind molecules. 34 */ 35 class Graph 47 48 /******************************** Some small functions and/or structures **********************************/ 49 50 struct KeyCompare 36 51 { 37 NodeMap ListOfNodes; //!< tree-list of all nodes in this graph 38 EdgeMap ListOfEdges; //!< tree-multi-list of all nodes, referenced to node id 52 bool operator() (const KeySet SubgraphA, const KeySet SubgraphB) const; 39 53 }; 40 54 41 /** Class describing subgraphs of the Class \a Graph. 42 * SubGraph has its own node and edge lists, however also a pointer to its father graph 43 * and hence access to its list as well. 55 //bool operator < (KeySet SubgraphA, KeySet SubgraphB); //note: this declaration is important, otherwise normal < is used (producing wrong order) 56 void InsertFragmentIntoGraph(ofstream *out, struct UniqueFragments *Fragment); // Insert a KeySet into a Graph 57 void InsertGraphIntoGraph(ofstream *out, Graph &graph1, Graph &graph2, int *counter); // Insert all KeySet's in a Graph into another Graph 58 59 /** Structure containing all values in power set combination generation. 44 60 */ 45 class SubGraph : class Graph 46 { 47 class Graph *FatherGraph; //!< Graph whose subgraph we are 61 struct UniqueFragments { 62 config *configuration; 63 atom *Root; 64 Graph *Leaflet; 65 KeySet *FragmentSet; 66 int ANOVAOrder; 67 int FragmentCounter; 68 int CurrentIndex; 69 double TEFactor; 70 int *ShortestPathList; 71 bool **UsedList; 72 bond **BondsPerSPList; 73 int *BondsPerSPCount; 48 74 }; 49 75 50 /** Class containing the nodes of a graph. 51 */ 52 class Node 53 { 54 int id; //!< individual id of the node 55 char *Name; //!< Name of the node for pretty printing 56 }; 76 /********************************************** declarations *******************************/ 57 77 58 /** Class containing egdes in a Graph strructure. 59 */ 60 class Edge 61 { 62 class Node *leftnode; //!< pointer to first node 63 class Node *atomnode; //!< pointer to second node 64 }; 78 ///** Graph class containing the graphs behind molecules. 79 // */ 80 //class Graph 81 //{ 82 // NodeMap ListOfNodes; //!< tree-list of all nodes in this graph 83 // EdgeMap ListOfEdges; //!< tree-multi-list of all nodes, referenced to node id 84 //}; 85 // 86 ///** Class describing subgraphs of the Class \a Graph. 87 // * SubGraph has its own node and edge lists, however also a pointer to its father graph 88 // * and hence access to its list as well. 89 // */ 90 //class SubGraph : class Graph 91 //{ 92 // class Graph *FatherGraph; //!< Graph whose subgraph we are 93 //}; 94 // 95 ///** Class containing the nodes of a graph. 96 // */ 97 //class Node 98 //{ 99 // int id; //!< individual id of the node 100 // char *Name; //!< Name of the node for pretty printing 101 //}; 102 // 103 ///** Class containing egdes in a Graph strructure. 104 // */ 105 //class Edge 106 //{ 107 // class Node *leftnode; //!< pointer to first node 108 // class Node *atomnode; //!< pointer to second node 109 //}; 65 110 66 111 -
src/helpers.cpp
r87e2e39 rc111db 6 6 7 7 #include "helpers.hpp" 8 #include "memoryusageobserver.hpp"9 8 10 9 /********************************************** helpful functions *********************************/ … … 118 117 }; 119 118 120 /** 121 * Allocates a memory range using malloc(). 119 /** Blows the 6-dimensional \a cell_size array up to a full NDIM by NDIM matrix. 120 * \param *symm 6-dim array of unique symmetric matrix components 121 * \return allocated NDIM*NDIM array with the symmetric matrix 122 */ 123 double * ReturnFullMatrixforSymmetric(double *symm) 124 { 125 double *matrix = Malloc<double>(NDIM * NDIM, "molecule::ReturnFullMatrixforSymmetric: *matrix"); 126 matrix[0] = symm[0]; 127 matrix[1] = symm[1]; 128 matrix[2] = symm[3]; 129 matrix[3] = symm[1]; 130 matrix[4] = symm[2]; 131 matrix[5] = symm[4]; 132 matrix[6] = symm[3]; 133 matrix[7] = symm[4]; 134 matrix[8] = symm[5]; 135 return matrix; 136 }; 137 138 /** Comparison function for GSL heapsort on distances in two molecules. 139 * \param *a 140 * \param *b 141 * \return <0, \a *a less than \a *b, ==0 if equal, >0 \a *a greater than \a *b 142 */ 143 int CompareDoubles (const void * a, const void * b) 144 { 145 if (*(double *)a > *(double *)b) 146 return -1; 147 else if (*(double *)a < *(double *)b) 148 return 1; 149 else 150 return 0; 151 }; 152 153 154 /** Allocates a memory range using malloc(). 122 155 * Prints the provided error message in case of a failure. 123 156 * … … 147 180 * Frees all memory registered by the memory observer and calls exit(225) afterwards. 148 181 */ 149 void performCriticalExit() {182 static void performCriticalExit() { 150 183 map<void*, size_t> pointers = MemoryUsageObserver::getInstance()->getPointersToAllocatedMemory(); 151 184 for (map<void*, size_t>::iterator runner = pointers.begin(); runner != pointers.end(); runner++) { -
src/helpers.hpp
r87e2e39 rc111db 9 9 using namespace std; 10 10 11 /*********************************************** includes ***********************************/ 12 11 13 // include config.h 12 14 #ifdef HAVE_CONFIG_H … … 14 16 #endif 15 17 16 #include <iostream>17 #include <iomanip>18 18 #include <fstream> 19 #include <sstream>20 #include <math.h>21 #include <string>22 19 23 #include "defs.hpp"24 #include "verbose.hpp"25 20 #include "memoryallocator.hpp" 26 21 … … 53 48 char *FixedDigitNumber(const int FragmentNumber, const int digits); 54 49 bool IsValidNumber( const char *string); 50 int CompareDoubles (const void * a, const void * b); 51 double * ReturnFullMatrixforSymmetric(double *cell_size); 55 52 static void performCriticalExit(); 56 53 … … 115 112 }; 116 113 117 /******************************** Some templates for list management ***********************************/118 119 /** Adds linking of an item to a list.120 * \param *walker121 * \return true - adding succeeded, false - error in list122 */123 template <typename X> void link(X *walker, X *end)124 {125 X *vorher = end->previous;126 if (vorher != NULL)127 vorher->next = walker;128 end->previous = walker;129 walker->previous = vorher;130 walker->next = end;131 };132 133 /** Removes linking of an item in a list.134 * \param *walker135 * \return true - removing succeeded, false - given item not found in list136 */137 template <typename X> void unlink(X *walker)138 {139 if (walker->next != NULL)140 walker->next->previous = walker->previous;141 if (walker->previous != NULL)142 walker->previous->next = walker->next;143 };144 145 /** Adds new item before an item \a *end in a list.146 * \param *pointer item to be added147 * \param *end end of list148 * \return true - addition succeeded, false - unable to add item to list149 */150 template <typename X> bool add(X *pointer, X *end)151 {152 if (end != NULL) {153 link(pointer, end);154 } else {155 pointer->previous = NULL;156 pointer->next = NULL;157 }158 return true;159 };160 161 /** Finds item in list162 * \param *suche search criteria163 * \param *start begin of list164 * \param *end end of list165 * \return X - if found, NULL - if not found166 */167 template <typename X, typename Y> X * find(Y *suche, X *start, X *end)168 {169 X *walker = start;170 while (walker->next != end) { // go through list171 walker = walker->next; // step onward beforehand172 if (*walker->sort == *suche) return (walker);173 }174 return NULL;175 };176 177 /** Removes an item from the list without check.178 * \param *walker item to be removed179 * \return true - removing succeeded, false - given item not found in list180 */181 template <typename X> void removewithoutcheck(X *walker)182 {183 if (walker != NULL) {184 unlink(walker);185 delete(walker);186 walker = NULL;187 }188 };189 190 /** Removes an item from the list, checks if exists.191 * Checks beforehand if atom is really within molecule list.192 * \param *pointer item to be removed193 * \param *start begin of list194 * \param *end end of list195 * \return true - removing succeeded, false - given item not found in list196 */197 template <typename X> bool remove(X *pointer, X *start, X *end)198 {199 X *walker = find (pointer->sort, start, end);200 /* while (walker->next != pointer) { // search through list201 walker = walker->next;202 if (walker == end) return false; // item not found in list203 }*/204 // atom found, now unlink205 if (walker != NULL)206 removewithoutcheck(walker);207 else208 return false;209 return true;210 };211 212 /** Cleans the whole list.213 * \param *start begin of list214 * \param *end end of list215 * \return true - list was cleaned successfully, false - error in list structure216 */217 template <typename X> bool cleanup(X *start, X *end)218 {219 X *pointer = start->next;220 X *walker;221 while (pointer != end) { // go through list222 walker = pointer; // mark current223 pointer = pointer->next; // step onward beforehand224 // remove walker225 unlink(walker);226 delete(walker);227 walker = NULL;228 }229 return true;230 };231 232 /** Returns the first marker in a chain list.233 * \param *me one arbitrary item in chain list234 * \return poiner to first marker235 */236 template <typename X> X *GetFirst(X *me)237 {238 X *Binder = me;239 while(Binder->previous != NULL)240 Binder = Binder->previous;241 return Binder;242 };243 244 /** Returns the last marker in a chain list.245 * \param *me one arbitrary item in chain list246 * \return poiner to last marker247 */248 template <typename X> X *GetLast(X *me)249 {250 X *Binder = me;251 while(Binder->next != NULL)252 Binder = Binder->next;253 return Binder;254 };255 256 114 /** Frees a two-dimensional array. 257 115 * \param *ptr pointer to array … … 269 127 }; 270 128 129 template <typename T> void Increment(T *value, T inc) 130 { 131 *value += inc; 132 }; 133 134 template <typename T> void AbsoluteValue(T *value, T abs) 135 { 136 *value = abs; 137 }; 138 139 271 140 272 141 -
src/leastsquaremin.cpp
r87e2e39 rc111db 6 6 */ 7 7 8 #include <iostream> 9 8 10 #include "leastsquaremin.hpp" 11 #include "vector.hpp" 9 12 10 13 /** Determines sum of squared distances of \a X to all \a **vectors. -
src/leastsquaremin.hpp
r87e2e39 rc111db 9 9 #define LEASTSQUAREMIN_HPP_ 10 10 11 #include "vector.hpp" 11 using namespace std; 12 13 /*********************************************** includes ***********************************/ 14 15 // include config.h 16 #ifdef HAVE_CONFIG_H 17 #include <config.h> 18 #endif 19 20 #include <gsl/gsl_vector.h> 21 22 /****************************************** forward declarations *****************************/ 12 23 13 24 class element; 14 25 class molecule; 26 class Vector; 27 28 /********************************************** declarations *******************************/ 15 29 16 30 /** Parameter structure for least square minimsation. -
src/linkedcell.cpp
r87e2e39 rc111db 6 6 7 7 8 #include "atom.hpp" 9 #include "helpers.hpp" 8 10 #include "linkedcell.hpp" 9 #include "molecule s.hpp"11 #include "molecule.hpp" 10 12 #include "tesselation.hpp" 13 #include "vector.hpp" 11 14 12 15 // ========================================================= class LinkedCell =========================================== … … 96 99 //cout << Verbose(2) << *Walker << " goes into cell " << n[0] << ", " << n[1] << ", " << n[2] << " with No. " << index << "." << endl; 97 100 set->GoToNext(); 101 } 102 cout << "done." << endl; 103 cout << Verbose(1) << "End of LinkedCell" << endl; 104 }; 105 106 107 /** Puts all atoms in \a *mol into a linked cell list with cell's lengths of \a RADIUS 108 * \param *set LCNodeSet class with all LCNode's 109 * \param RADIUS edge length of cells 110 */ 111 LinkedCell::LinkedCell(LinkedNodes *set, double radius) 112 { 113 class TesselPoint *Walker = NULL; 114 RADIUS = radius; 115 LC = NULL; 116 for(int i=0;i<NDIM;i++) 117 N[i] = 0; 118 index = -1; 119 max.Zero(); 120 min.Zero(); 121 cout << Verbose(1) << "Begin of LinkedCell" << endl; 122 if (set->empty()) { 123 cerr << "ERROR: set contains no linked cell nodes!" << endl; 124 return; 125 } 126 // 1. find max and min per axis of atoms 127 LinkedNodes::iterator Runner = set->begin(); 128 for (int i=0;i<NDIM;i++) { 129 max.x[i] = (*Runner)->node->x[i]; 130 min.x[i] = (*Runner)->node->x[i]; 131 } 132 for (LinkedNodes::iterator Runner = set->begin(); Runner != set->end(); Runner++) { 133 Walker = *Runner; 134 for (int i=0;i<NDIM;i++) { 135 if (max.x[i] < Walker->node->x[i]) 136 max.x[i] = Walker->node->x[i]; 137 if (min.x[i] > Walker->node->x[i]) 138 min.x[i] = Walker->node->x[i]; 139 } 140 } 141 cout << Verbose(2) << "Bounding box is " << min << " and " << max << "." << endl; 142 143 // 2. find then number of cells per axis 144 for (int i=0;i<NDIM;i++) { 145 N[i] = (int)floor((max.x[i] - min.x[i])/RADIUS)+1; 146 } 147 cout << Verbose(2) << "Number of cells per axis are " << N[0] << ", " << N[1] << " and " << N[2] << "." << endl; 148 149 // 3. allocate the lists 150 cout << Verbose(2) << "Allocating cells ... "; 151 if (LC != NULL) { 152 cout << Verbose(1) << "ERROR: Linked Cell list is already allocated, I do nothing." << endl; 153 return; 154 } 155 LC = new LinkedNodes[N[0]*N[1]*N[2]]; 156 for (index=0;index<N[0]*N[1]*N[2];index++) { 157 LC [index].clear(); 158 } 159 cout << "done." << endl; 160 161 // 4. put each atom into its respective cell 162 cout << Verbose(2) << "Filling cells ... "; 163 for (LinkedNodes::iterator Runner = set->begin(); Runner != set->end(); Runner++) { 164 Walker = *Runner; 165 for (int i=0;i<NDIM;i++) { 166 n[i] = (int)floor((Walker->node->x[i] - min.x[i])/RADIUS); 167 } 168 index = n[0] * N[1] * N[2] + n[1] * N[2] + n[2]; 169 LC[index].push_back(Walker); 170 //cout << Verbose(2) << *Walker << " goes into cell " << n[0] << ", " << n[1] << ", " << n[2] << " with No. " << index << "." << endl; 98 171 } 99 172 cout << "done." << endl; -
src/linkedcell.hpp
r87e2e39 rc111db 14 14 using namespace std; 15 15 16 /*********************************************** includes ***********************************/ 17 16 18 // include config.h 17 19 #ifdef HAVE_CONFIG_H … … 22 24 23 25 #include "defs.hpp" 24 #include "helpers.hpp"25 26 #include "vector.hpp" 26 27 28 /****************************************** forward declarations *****************************/ 29 30 class PointCloud; 27 31 class TesselPoint; 28 class PointCloud; 32 33 /********************************************** definitions *********************************/ 29 34 30 35 #define LinkedNodes list<TesselPoint *> 36 37 /********************************************** declarations *******************************/ 31 38 32 39 /** Linked Cell class for containing Vectors in real space efficiently. … … 44 51 LinkedCell(); 45 52 LinkedCell(PointCloud *set, double RADIUS); 53 LinkedCell(LinkedNodes *set, double radius); 46 54 ~LinkedCell(); 47 55 LinkedNodes* GetCurrentCell(); -
src/memoryallocator.hpp
r87e2e39 rc111db 8 8 9 9 using namespace std; 10 11 /*********************************************** includes ***********************************/ 10 12 11 13 // include config.h … … 26 28 #include "memoryusageobserver.hpp" 27 29 28 /******************* wrappers for memory allocation functions***********************/30 /********************************************** declarations *******************************/ 29 31 30 /** 31 * Allocates a memory range using malloc(). 32 /** Allocates a memory range using malloc(). 32 33 * Prints the provided error message in case of a failure. 33 34 * … … 54 55 template <> char* Malloc<char>(size_t size, const char* output); 55 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 * … … 77 77 }; 78 78 79 /** 80 * Reallocates a memory range using realloc(). If the provided pointer to the old 79 /** Reallocates a memory range using realloc(). If the provided pointer to the old 81 80 * memory range is NULL, malloc() is called instead. 82 81 * Prints the provided error message in case of a failure (of either malloc() or realloc()). … … 106 105 }; 107 106 108 /** 109 * Frees allocated memory range using free(). 107 /** Frees allocated memory range using free(). 110 108 * 111 109 * \param pointer to the allocated memory range to free; may be NULL, this function is a no-op then 110 * \param *msg optional error message 112 111 */ 113 112 template <typename X> void Free(X** buffer, const char *msg = NULL) -
src/memoryusageobserver.cpp
r87e2e39 rc111db 77 77 * 78 78 * \param pointer to the allocated piece of memory 79 * \param *msg optional error message 79 80 */ 80 81 void MemoryUsageObserver::removeMemory(void* pointer, const char *msg) { … … 83 84 if (current == memoryUsers.end()) { 84 85 cout << "WARNING: There is non-tracked memory to be freed. Pointer " 85 << pointer << " is not registered by MemoryUsageObserver ";86 << pointer << " is not registered by MemoryUsageObserver: "; 86 87 if (msg != NULL) 87 cout << ": " <<msg;88 cout << "." <<endl;88 cout << *msg; 89 cout << endl; 89 90 return; 90 91 } -
src/memoryusageobserver.hpp
r87e2e39 rc111db 8 8 9 9 using namespace std; 10 11 /*********************************************** includes ***********************************/ 10 12 11 13 // include config.h … … 22 24 #include <string> 23 25 #include <typeinfo> 26 27 /********************************************** declarations *******************************/ 24 28 25 29 class MemoryUsageObserver { -
src/moleculelist.cpp
r87e2e39 rc111db 5 5 */ 6 6 7 #include "atom.hpp" 8 #include "bond.hpp" 9 #include "boundary.hpp" 7 10 #include "config.hpp" 8 #include "molecules.hpp" 11 #include "element.hpp" 12 #include "helpers.hpp" 13 #include "linkedcell.hpp" 14 #include "molecule.hpp" 9 15 #include "memoryallocator.hpp" 16 #include "periodentafel.hpp" 10 17 11 18 /*********************************** Functions for class MoleculeListClass *************************/ … … 292 299 /** Embedding merge of a given set of molecules into one. 293 300 * Embedding merge inserts one molecule into the other. 294 * \param *mol destination molecule 295 * \param *srcmol source molecule 296 * \return true - merge successful, false - merge failed (probably due to non-existant indices 297 * \TODO find embedding center301 * \param *mol destination molecule (fixed one) 302 * \param *srcmol source molecule (variable one, where atoms are taken from) 303 * \return true - merge successful, false - merge failed (probably due to non-existant indices) 304 * \TODO linked cell dimensions for boundary points has to be as big as inner diameter! 298 305 */ 299 306 bool MoleculeListClass::EmbedMerge(molecule *mol, molecule *srcmol) 300 307 { 301 if (srcmol == NULL) 308 if ((srcmol == NULL) || (mol == NULL)) { 309 cout << Verbose(1) << "ERROR: Either fixed or variable molecule is given as NULL." << endl; 302 310 return false; 303 304 // calculate center for merge 305 srcmol->Center.CopyVector(mol->FindEmbeddingHole((ofstream *)&cout, srcmol)); 306 srcmol->Center.Zero(); 307 308 // perform simple merge 309 SimpleMerge(mol, srcmol); 311 } 312 313 // calculate envelope for *mol 314 LinkedCell *LCList = new LinkedCell(mol, 8.); 315 FindNonConvexBorder((ofstream *)&cout, mol, LCList, 4., NULL); 316 if (mol->TesselStruct == NULL) { 317 cout << Verbose(1) << "ERROR: Could not tesselate the fixed molecule." << endl; 318 return false; 319 } 320 delete(LCList); 321 LCList = new LinkedCell(mol->TesselStruct, 8.); // re-create with boundary points only! 322 323 // prepare index list for bonds 324 srcmol->CountAtoms((ofstream *)&cout); 325 atom ** CopyAtoms = new atom*[srcmol->AtomCount]; 326 for(int i=0;i<srcmol->AtomCount;i++) 327 CopyAtoms[i] = NULL; 328 329 // for each of the source atoms check whether we are in- or outside and add copy atom 330 atom *Walker = srcmol->start; 331 int nr=0; 332 while (Walker->next != srcmol->end) { 333 Walker = Walker->next; 334 cout << Verbose(2) << "INFO: Current Walker is " << *Walker << "." << endl; 335 if (!mol->TesselStruct->IsInnerPoint((ofstream *)&cout, Walker->x, LCList)) { 336 CopyAtoms[Walker->nr] = new atom(Walker); 337 mol->AddAtom(CopyAtoms[Walker->nr]); 338 nr++; 339 } else { 340 // do nothing 341 } 342 } 343 cout << Verbose(1) << nr << " of " << srcmol->AtomCount << " atoms have been merged."; 344 345 // go through all bonds and add as well 346 bond *Binder = srcmol->first; 347 while(Binder->next != srcmol->last) { 348 Binder = Binder->next; 349 cout << Verbose(3) << "Adding Bond between " << *CopyAtoms[Binder->leftatom->nr] << " and " << *CopyAtoms[Binder->rightatom->nr]<< "." << endl; 350 mol->AddBond(CopyAtoms[Binder->leftatom->nr], CopyAtoms[Binder->rightatom->nr], Binder->BondDegree); 351 } 352 delete(LCList); 310 353 return true; 311 354 }; -
src/parser.cpp
r87e2e39 rc111db 399 399 * Sums over "E"-terms to create the "F"-terms 400 400 * \param Matrix MatrixContainer with matrices (LevelCounter by *ColumnCounter) with all the energies. 401 * \param KeySet KeySetContainer with bond Order and association mapping of each fragment to an order401 * \param KeySets KeySetContainer with bond Order and association mapping of each fragment to an order 402 402 * \param Order bond order 403 403 * \return true if summing was successful 404 404 */ 405 bool MatrixContainer::SumSubManyBodyTerms(class MatrixContainer &MatrixValues, class KeySetsContainer &KeySet , int Order)405 bool MatrixContainer::SumSubManyBodyTerms(class MatrixContainer &MatrixValues, class KeySetsContainer &KeySets, int Order) 406 406 { 407 407 // go through each order 408 for (int CurrentFragment=0;CurrentFragment<KeySet .FragmentsPerOrder[Order];CurrentFragment++) {409 //cout << "Current Fragment is " << CurrentFragment << "/" << KeySet .OrderSet[Order][CurrentFragment] << "." << endl;408 for (int CurrentFragment=0;CurrentFragment<KeySets.FragmentsPerOrder[Order];CurrentFragment++) { 409 //cout << "Current Fragment is " << CurrentFragment << "/" << KeySets.OrderSet[Order][CurrentFragment] << "." << endl; 410 410 // then go per order through each suborder and pick together all the terms that contain this fragment 411 411 for(int SubOrder=0;SubOrder<=Order;SubOrder++) { // go through all suborders up to the desired order 412 for (int j=0;j<KeySet .FragmentsPerOrder[SubOrder];j++) { // go through all possible fragments of size suborder413 if (KeySet .Contains(KeySet.OrderSet[Order][CurrentFragment], KeySet.OrderSet[SubOrder][j])) {414 //cout << "Current other fragment is " << j << "/" << KeySet .OrderSet[SubOrder][j] << "." << endl;412 for (int j=0;j<KeySets.FragmentsPerOrder[SubOrder];j++) { // go through all possible fragments of size suborder 413 if (KeySets.Contains(KeySets.OrderSet[Order][CurrentFragment], KeySets.OrderSet[SubOrder][j])) { 414 //cout << "Current other fragment is " << j << "/" << KeySets.OrderSet[SubOrder][j] << "." << endl; 415 415 // if the fragment's indices are all in the current fragment 416 for(int k=0;k<RowCounter[ KeySet .OrderSet[SubOrder][j] ];k++) { // go through all atoms in this fragment417 int m = MatrixValues.Indices[ KeySet .OrderSet[SubOrder][j] ][k];416 for(int k=0;k<RowCounter[ KeySets.OrderSet[SubOrder][j] ];k++) { // go through all atoms in this fragment 417 int m = MatrixValues.Indices[ KeySets.OrderSet[SubOrder][j] ][k]; 418 418 //cout << "Current index is " << k << "/" << m << "." << endl; 419 419 if (m != -1) { // if it's not an added hydrogen 420 for (int l=0;l<RowCounter[ KeySet .OrderSet[Order][CurrentFragment] ];l++) { // look for the corresponding index in the current fragment421 //cout << "Comparing " << m << " with " << MatrixValues.Indices[ KeySet .OrderSet[Order][CurrentFragment] ][l] << "." << endl;422 if (m == MatrixValues.Indices[ KeySet .OrderSet[Order][CurrentFragment] ][l]) {420 for (int l=0;l<RowCounter[ KeySets.OrderSet[Order][CurrentFragment] ];l++) { // look for the corresponding index in the current fragment 421 //cout << "Comparing " << m << " with " << MatrixValues.Indices[ KeySets.OrderSet[Order][CurrentFragment] ][l] << "." << endl; 422 if (m == MatrixValues.Indices[ KeySets.OrderSet[Order][CurrentFragment] ][l]) { 423 423 m = l; 424 424 break; … … 426 426 } 427 427 //cout << "Corresponding index in CurrentFragment is " << m << "." << endl; 428 if (m > RowCounter[ KeySet .OrderSet[Order][CurrentFragment] ]) {429 cerr << "In fragment No. " << KeySet .OrderSet[Order][CurrentFragment] << " current force index " << m << " is greater than " << RowCounter[ KeySet.OrderSet[Order][CurrentFragment] ] << "!" << endl;428 if (m > RowCounter[ KeySets.OrderSet[Order][CurrentFragment] ]) { 429 cerr << "In fragment No. " << KeySets.OrderSet[Order][CurrentFragment] << " current force index " << m << " is greater than " << RowCounter[ KeySets.OrderSet[Order][CurrentFragment] ] << "!" << endl; 430 430 return false; 431 431 } 432 432 if (Order == SubOrder) { // equal order is always copy from Energies 433 for(int l=ColumnCounter[ KeySet .OrderSet[SubOrder][j] ];l--;) // then adds/subtract each column434 Matrix[ KeySet .OrderSet[Order][CurrentFragment] ][m][l] += MatrixValues.Matrix[ KeySet.OrderSet[SubOrder][j] ][k][l];433 for(int l=ColumnCounter[ KeySets.OrderSet[SubOrder][j] ];l--;) // then adds/subtract each column 434 Matrix[ KeySets.OrderSet[Order][CurrentFragment] ][m][l] += MatrixValues.Matrix[ KeySets.OrderSet[SubOrder][j] ][k][l]; 435 435 } else { 436 for(int l=ColumnCounter[ KeySet .OrderSet[SubOrder][j] ];l--;)437 Matrix[ KeySet .OrderSet[Order][CurrentFragment] ][m][l] -= Matrix[ KeySet.OrderSet[SubOrder][j] ][k][l];436 for(int l=ColumnCounter[ KeySets.OrderSet[SubOrder][j] ];l--;) 437 Matrix[ KeySets.OrderSet[Order][CurrentFragment] ][m][l] -= Matrix[ KeySets.OrderSet[SubOrder][j] ][k][l]; 438 438 } 439 439 } 440 //if ((ColumnCounter[ KeySet .OrderSet[SubOrder][j] ]>1) && (RowCounter[0]-1 >= 1))441 //cout << "Fragments[ KeySet .OrderSet[" << Order << "][" << CurrentFragment << "]=" << KeySet.OrderSet[Order][CurrentFragment] << " ][" << RowCounter[0]-1 << "][" << 1 << "] = " << Matrix[ KeySet.OrderSet[Order][CurrentFragment] ][RowCounter[0]-1][1] << endl;440 //if ((ColumnCounter[ KeySets.OrderSet[SubOrder][j] ]>1) && (RowCounter[0]-1 >= 1)) 441 //cout << "Fragments[ KeySets.OrderSet[" << Order << "][" << CurrentFragment << "]=" << KeySets.OrderSet[Order][CurrentFragment] << " ][" << RowCounter[0]-1 << "][" << 1 << "] = " << Matrix[ KeySets.OrderSet[Order][CurrentFragment] ][RowCounter[0]-1][1] << endl; 442 442 } 443 443 } else { 444 //cout << "Fragment " << KeySet .OrderSet[SubOrder][j] << " is not contained in fragment " << KeySet.OrderSet[Order][CurrentFragment] << "." << endl;444 //cout << "Fragment " << KeySets.OrderSet[SubOrder][j] << " is not contained in fragment " << KeySets.OrderSet[Order][CurrentFragment] << "." << endl; 445 445 } 446 446 } 447 447 } 448 //cout << "Final Fragments[ KeySet .OrderSet[" << Order << "][" << CurrentFragment << "]=" << KeySet.OrderSet[Order][CurrentFragment] << " ][" << KeySet.AtomCounter[0]-1 << "][" << 1 << "] = " << Matrix[ KeySet.OrderSet[Order][CurrentFragment] ][KeySet.AtomCounter[0]-1][1] << endl;448 //cout << "Final Fragments[ KeySets.OrderSet[" << Order << "][" << CurrentFragment << "]=" << KeySets.OrderSet[Order][CurrentFragment] << " ][" << KeySets.AtomCounter[0]-1 << "][" << 1 << "] = " << Matrix[ KeySets.OrderSet[Order][CurrentFragment] ][KeySets.AtomCounter[0]-1][1] << endl; 449 449 } 450 450 … … 534 534 * \param Matrix MatrixContainer with matrices (LevelCounter by *ColumnCounter) with all the energies. 535 535 * \param CorrectionFragments MatrixContainer with hydrogen saturation correction per fragments 536 * \param KeySet KeySetContainer with bond Order and association mapping of each fragment to an order536 * \param KeySets KeySetContainer with bond Order and association mapping of each fragment to an order 537 537 * \param Order bond order 538 538 * \parsm sign +1 or -1 539 539 * \return true if summing was successful 540 540 */ 541 bool EnergyMatrix::SumSubEnergy(class EnergyMatrix &Fragments, class EnergyMatrix *CorrectionFragments, class KeySetsContainer &KeySet , int Order, double sign)541 bool EnergyMatrix::SumSubEnergy(class EnergyMatrix &Fragments, class EnergyMatrix *CorrectionFragments, class KeySetsContainer &KeySets, int Order, double sign) 542 542 { 543 543 // sum energy 544 544 if (CorrectionFragments == NULL) 545 for(int i=KeySet .FragmentsPerOrder[Order];i--;)546 for(int j=RowCounter[ KeySet .OrderSet[Order][i] ];j--;)547 for(int k=ColumnCounter[ KeySet .OrderSet[Order][i] ];k--;)548 Matrix[MatrixCounter][j][k] += sign*Fragments.Matrix[ KeySet .OrderSet[Order][i] ][j][k];545 for(int i=KeySets.FragmentsPerOrder[Order];i--;) 546 for(int j=RowCounter[ KeySets.OrderSet[Order][i] ];j--;) 547 for(int k=ColumnCounter[ KeySets.OrderSet[Order][i] ];k--;) 548 Matrix[MatrixCounter][j][k] += sign*Fragments.Matrix[ KeySets.OrderSet[Order][i] ][j][k]; 549 549 else 550 for(int i=KeySet .FragmentsPerOrder[Order];i--;)551 for(int j=RowCounter[ KeySet .OrderSet[Order][i] ];j--;)552 for(int k=ColumnCounter[ KeySet .OrderSet[Order][i] ];k--;)553 Matrix[MatrixCounter][j][k] += sign*(Fragments.Matrix[ KeySet .OrderSet[Order][i] ][j][k] + CorrectionFragments->Matrix[ KeySet.OrderSet[Order][i] ][j][k]);550 for(int i=KeySets.FragmentsPerOrder[Order];i--;) 551 for(int j=RowCounter[ KeySets.OrderSet[Order][i] ];j--;) 552 for(int k=ColumnCounter[ KeySets.OrderSet[Order][i] ];k--;) 553 Matrix[MatrixCounter][j][k] += sign*(Fragments.Matrix[ KeySets.OrderSet[Order][i] ][j][k] + CorrectionFragments->Matrix[ KeySets.OrderSet[Order][i] ][j][k]); 554 554 return true; 555 555 }; … … 641 641 /** Sums the forces and puts into last element of \a ForceMatrix::Matrix. 642 642 * \param Matrix MatrixContainer with matrices (LevelCounter by *ColumnCounter) with all the energies. 643 * \param KeySet KeySetContainer with bond Order and association mapping of each fragment to an order643 * \param KeySets KeySetContainer with bond Order and association mapping of each fragment to an order 644 644 * \param Order bond order 645 645 * \param sign +1 or -1 646 646 * \return true if summing was successful 647 647 */ 648 bool ForceMatrix::SumSubForces(class ForceMatrix &Fragments, class KeySetsContainer &KeySet , int Order, double sign)648 bool ForceMatrix::SumSubForces(class ForceMatrix &Fragments, class KeySetsContainer &KeySets, int Order, double sign) 649 649 { 650 650 int FragmentNr; 651 651 // sum forces 652 for(int i=0;i<KeySet .FragmentsPerOrder[Order];i++) {653 FragmentNr = KeySet .OrderSet[Order][i];652 for(int i=0;i<KeySets.FragmentsPerOrder[Order];i++) { 653 FragmentNr = KeySets.OrderSet[Order][i]; 654 654 for(int l=0;l<RowCounter[ FragmentNr ];l++) { 655 655 int j = Indices[ FragmentNr ][l]; … … 778 778 /** Sums the hessian entries and puts into last element of \a HessianMatrix::Matrix. 779 779 * \param Matrix MatrixContainer with matrices (LevelCounter by *ColumnCounter) with all the energies. 780 * \param KeySet KeySetContainer with bond Order and association mapping of each fragment to an order780 * \param KeySets KeySetContainer with bond Order and association mapping of each fragment to an order 781 781 * \param Order bond order 782 782 * \param sign +1 or -1 783 783 * \return true if summing was successful 784 784 */ 785 bool HessianMatrix::SumSubHessians(class HessianMatrix &Fragments, class KeySetsContainer &KeySet , int Order, double sign)785 bool HessianMatrix::SumSubHessians(class HessianMatrix &Fragments, class KeySetsContainer &KeySets, int Order, double sign) 786 786 { 787 787 int FragmentNr; 788 788 // sum forces 789 for(int i=0;i<KeySet .FragmentsPerOrder[Order];i++) {790 FragmentNr = KeySet .OrderSet[Order][i];789 for(int i=0;i<KeySets.FragmentsPerOrder[Order];i++) { 790 FragmentNr = KeySets.OrderSet[Order][i]; 791 791 for(int l=0;l<RowCounter[ FragmentNr ];l++) { 792 792 int j = Indices[ FragmentNr ][l]; … … 823 823 * Sums over "E"-terms to create the "F"-terms 824 824 * \param Matrix MatrixContainer with matrices (LevelCounter by *ColumnCounter) with all the energies. 825 * \param KeySet KeySetContainer with bond Order and association mapping of each fragment to an order825 * \param KeySets KeySetContainer with bond Order and association mapping of each fragment to an order 826 826 * \param Order bond order 827 827 * \return true if summing was successful 828 828 */ 829 bool HessianMatrix::SumSubManyBodyTerms(class MatrixContainer &MatrixValues, class KeySetsContainer &KeySet , int Order)829 bool HessianMatrix::SumSubManyBodyTerms(class MatrixContainer &MatrixValues, class KeySetsContainer &KeySets, int Order) 830 830 { 831 831 // go through each order 832 for (int CurrentFragment=0;CurrentFragment<KeySet .FragmentsPerOrder[Order];CurrentFragment++) {833 //cout << "Current Fragment is " << CurrentFragment << "/" << KeySet .OrderSet[Order][CurrentFragment] << "." << endl;832 for (int CurrentFragment=0;CurrentFragment<KeySets.FragmentsPerOrder[Order];CurrentFragment++) { 833 //cout << "Current Fragment is " << CurrentFragment << "/" << KeySets.OrderSet[Order][CurrentFragment] << "." << endl; 834 834 // then go per order through each suborder and pick together all the terms that contain this fragment 835 835 for(int SubOrder=0;SubOrder<=Order;SubOrder++) { // go through all suborders up to the desired order 836 for (int j=0;j<KeySet .FragmentsPerOrder[SubOrder];j++) { // go through all possible fragments of size suborder837 if (KeySet .Contains(KeySet.OrderSet[Order][CurrentFragment], KeySet.OrderSet[SubOrder][j])) {838 //cout << "Current other fragment is " << j << "/" << KeySet .OrderSet[SubOrder][j] << "." << endl;836 for (int j=0;j<KeySets.FragmentsPerOrder[SubOrder];j++) { // go through all possible fragments of size suborder 837 if (KeySets.Contains(KeySets.OrderSet[Order][CurrentFragment], KeySets.OrderSet[SubOrder][j])) { 838 //cout << "Current other fragment is " << j << "/" << KeySets.OrderSet[SubOrder][j] << "." << endl; 839 839 // if the fragment's indices are all in the current fragment 840 for(int k=0;k<RowCounter[ KeySet .OrderSet[SubOrder][j] ];k++) { // go through all atoms in this fragment841 int m = MatrixValues.Indices[ KeySet .OrderSet[SubOrder][j] ][k];840 for(int k=0;k<RowCounter[ KeySets.OrderSet[SubOrder][j] ];k++) { // go through all atoms in this fragment 841 int m = MatrixValues.Indices[ KeySets.OrderSet[SubOrder][j] ][k]; 842 842 //cout << "Current row index is " << k << "/" << m << "." << endl; 843 843 if (m != -1) { // if it's not an added hydrogen 844 for (int l=0;l<RowCounter[ KeySet .OrderSet[Order][CurrentFragment] ];l++) { // look for the corresponding index in the current fragment845 //cout << "Comparing " << m << " with " << MatrixValues.Indices[ KeySet .OrderSet[Order][CurrentFragment] ][l] << "." << endl;846 if (m == MatrixValues.Indices[ KeySet .OrderSet[Order][CurrentFragment] ][l]) {844 for (int l=0;l<RowCounter[ KeySets.OrderSet[Order][CurrentFragment] ];l++) { // look for the corresponding index in the current fragment 845 //cout << "Comparing " << m << " with " << MatrixValues.Indices[ KeySets.OrderSet[Order][CurrentFragment] ][l] << "." << endl; 846 if (m == MatrixValues.Indices[ KeySets.OrderSet[Order][CurrentFragment] ][l]) { 847 847 m = l; 848 848 break; … … 850 850 } 851 851 //cout << "Corresponding row index for " << k << " in CurrentFragment is " << m << "." << endl; 852 if (m > RowCounter[ KeySet .OrderSet[Order][CurrentFragment] ]) {853 cerr << "In fragment No. " << KeySet .OrderSet[Order][CurrentFragment] << " current row index " << m << " is greater than " << RowCounter[ KeySet.OrderSet[Order][CurrentFragment] ] << "!" << endl;852 if (m > RowCounter[ KeySets.OrderSet[Order][CurrentFragment] ]) { 853 cerr << "In fragment No. " << KeySets.OrderSet[Order][CurrentFragment] << " current row index " << m << " is greater than " << RowCounter[ KeySets.OrderSet[Order][CurrentFragment] ] << "!" << endl; 854 854 return false; 855 855 } 856 856 857 for(int l=0;l<ColumnCounter[ KeySet .OrderSet[SubOrder][j] ];l++) {858 int n = MatrixValues.Indices[ KeySet .OrderSet[SubOrder][j] ][l];857 for(int l=0;l<ColumnCounter[ KeySets.OrderSet[SubOrder][j] ];l++) { 858 int n = MatrixValues.Indices[ KeySets.OrderSet[SubOrder][j] ][l]; 859 859 //cout << "Current column index is " << l << "/" << n << "." << endl; 860 860 if (n != -1) { // if it's not an added hydrogen 861 for (int p=0;p<ColumnCounter[ KeySet .OrderSet[Order][CurrentFragment] ];p++) { // look for the corresponding index in the current fragment862 //cout << "Comparing " << n << " with " << MatrixValues.Indices[ KeySet .OrderSet[Order][CurrentFragment] ][p] << "." << endl;863 if (n == MatrixValues.Indices[ KeySet .OrderSet[Order][CurrentFragment] ][p]) {861 for (int p=0;p<ColumnCounter[ KeySets.OrderSet[Order][CurrentFragment] ];p++) { // look for the corresponding index in the current fragment 862 //cout << "Comparing " << n << " with " << MatrixValues.Indices[ KeySets.OrderSet[Order][CurrentFragment] ][p] << "." << endl; 863 if (n == MatrixValues.Indices[ KeySets.OrderSet[Order][CurrentFragment] ][p]) { 864 864 n = p; 865 865 break; … … 867 867 } 868 868 //cout << "Corresponding column index for " << l << " in CurrentFragment is " << n << "." << endl; 869 if (n > ColumnCounter[ KeySet .OrderSet[Order][CurrentFragment] ]) {870 cerr << "In fragment No. " << KeySet .OrderSet[Order][CurrentFragment] << " current column index " << n << " is greater than " << ColumnCounter[ KeySet.OrderSet[Order][CurrentFragment] ] << "!" << endl;869 if (n > ColumnCounter[ KeySets.OrderSet[Order][CurrentFragment] ]) { 870 cerr << "In fragment No. " << KeySets.OrderSet[Order][CurrentFragment] << " current column index " << n << " is greater than " << ColumnCounter[ KeySets.OrderSet[Order][CurrentFragment] ] << "!" << endl; 871 871 return false; 872 872 } 873 873 if (Order == SubOrder) { // equal order is always copy from Energies 874 //cout << "Adding " << MatrixValues.Matrix[ KeySet .OrderSet[SubOrder][j] ][k][l] << " from [" << k << "][" << l << "] onto [" << m << "][" << n << "]." << endl;875 Matrix[ KeySet .OrderSet[Order][CurrentFragment] ][m][n] += MatrixValues.Matrix[ KeySet.OrderSet[SubOrder][j] ][k][l];874 //cout << "Adding " << MatrixValues.Matrix[ KeySets.OrderSet[SubOrder][j] ][k][l] << " from [" << k << "][" << l << "] onto [" << m << "][" << n << "]." << endl; 875 Matrix[ KeySets.OrderSet[Order][CurrentFragment] ][m][n] += MatrixValues.Matrix[ KeySets.OrderSet[SubOrder][j] ][k][l]; 876 876 } else { 877 //cout << "Subtracting " << Matrix[ KeySet .OrderSet[SubOrder][j] ][k][l] << " from [" << k << "][" << l << "] onto [" << m << "][" << n << "]." << endl;878 Matrix[ KeySet .OrderSet[Order][CurrentFragment] ][m][n] -= Matrix[ KeySet.OrderSet[SubOrder][j] ][k][l];877 //cout << "Subtracting " << Matrix[ KeySets.OrderSet[SubOrder][j] ][k][l] << " from [" << k << "][" << l << "] onto [" << m << "][" << n << "]." << endl; 878 Matrix[ KeySets.OrderSet[Order][CurrentFragment] ][m][n] -= Matrix[ KeySets.OrderSet[SubOrder][j] ][k][l]; 879 879 } 880 880 } 881 881 } 882 882 } 883 //if ((ColumnCounter[ KeySet .OrderSet[SubOrder][j] ]>1) && (RowCounter[0]-1 >= 1))884 //cout << "Fragments[ KeySet .OrderSet[" << Order << "][" << CurrentFragment << "]=" << KeySet.OrderSet[Order][CurrentFragment] << " ][" << RowCounter[0]-1 << "][" << 1 << "] = " << Matrix[ KeySet.OrderSet[Order][CurrentFragment] ][RowCounter[0]-1][1] << endl;883 //if ((ColumnCounter[ KeySets.OrderSet[SubOrder][j] ]>1) && (RowCounter[0]-1 >= 1)) 884 //cout << "Fragments[ KeySets.OrderSet[" << Order << "][" << CurrentFragment << "]=" << KeySets.OrderSet[Order][CurrentFragment] << " ][" << RowCounter[0]-1 << "][" << 1 << "] = " << Matrix[ KeySets.OrderSet[Order][CurrentFragment] ][RowCounter[0]-1][1] << endl; 885 885 } 886 886 } else { 887 //cout << "Fragment " << KeySet .OrderSet[SubOrder][j] << " is not contained in fragment " << KeySet.OrderSet[Order][CurrentFragment] << "." << endl;887 //cout << "Fragment " << KeySets.OrderSet[SubOrder][j] << " is not contained in fragment " << KeySets.OrderSet[Order][CurrentFragment] << "." << endl; 888 888 } 889 889 } 890 890 } 891 //cout << "Final Fragments[ KeySet .OrderSet[" << Order << "][" << CurrentFragment << "]=" << KeySet.OrderSet[Order][CurrentFragment] << " ][" << KeySet.AtomCounter[0]-1 << "][" << 1 << "] = " << Matrix[ KeySet.OrderSet[Order][CurrentFragment] ][KeySet.AtomCounter[0]-1][1] << endl;891 //cout << "Final Fragments[ KeySets.OrderSet[" << Order << "][" << CurrentFragment << "]=" << KeySets.OrderSet[Order][CurrentFragment] << " ][" << KeySets.AtomCounter[0]-1 << "][" << 1 << "] = " << Matrix[ KeySets.OrderSet[Order][CurrentFragment] ][KeySets.AtomCounter[0]-1][1] << endl; 892 892 } 893 893 -
src/parser.hpp
r87e2e39 rc111db 1 /** \file pars ing.hpp1 /** \file parser.hpp 2 2 * 3 3 * Definitions of various class functions for the parsing of value files. … … 6 6 7 7 8 #ifndef PARS ING_HPP_9 #define PARS ING_HPP_8 #ifndef PARSER_HPP_ 9 #define PARSER_HPP_ 10 10 11 11 using namespace std; 12 13 /*********************************************** includes ***********************************/ 12 14 13 15 // include config.h … … 16 18 #endif 17 19 18 // ======================================= DEFINES ========================================== 20 /****************************************** forward declarations *****************************/ 21 22 class EnergyMatrix; 23 class ForceMatrix; 24 class HessianMatrix; 25 class KeySetsContainer; 26 class MatrixContainer; 27 28 /********************************************** definitions *********************************/ 19 29 20 30 #define EnergySuffix ".energy.all" … … 42 52 bool TestParams(int argc, char **argv); 43 53 54 // ======================================= CLASS KeySetsContainer ============================= 55 56 class KeySetsContainer { 57 public: 58 int **KeySets; 59 int *AtomCounter; 60 int FragmentCounter; 61 int Order; 62 int *FragmentsPerOrder; 63 int **OrderSet; 64 65 KeySetsContainer(); 66 ~KeySetsContainer(); 67 68 bool ParseKeySets(const char *name, const int *ACounter, const int FCounter); 69 bool ParseManyBodyTerms(); 70 bool Contains(const int GreaterSet, const int SmallerSet); 71 }; 44 72 45 73 // ======================================= CLASS MatrixContainer ============================= … … 68 96 //bool ParseIndices(); 69 97 //bool SumSubValues(); 70 bool SumSubManyBodyTerms(class MatrixContainer &Matrix, class KeySetsContainer &KeySet , int Order);98 bool SumSubManyBodyTerms(class MatrixContainer &Matrix, class KeySetsContainer &KeySets, int Order); 71 99 bool WriteTotalFragments(const char *name, const char *prefix); 72 100 bool WriteLastMatrix(const char *name, const char *prefix, const char *suffix); … … 78 106 public: 79 107 bool ParseIndices(); 80 bool SumSubEnergy(class EnergyMatrix &Fragments, class EnergyMatrix *CorrectionFragments, class KeySetsContainer &KeySet , int Order, double sign);108 bool SumSubEnergy(class EnergyMatrix &Fragments, class EnergyMatrix *CorrectionFragments, class KeySetsContainer &KeySets, int Order, double sign); 81 109 bool ParseFragmentMatrix(const char *name, const char *prefix, string suffix, int skiplines, int skipcolumns); 82 110 }; … … 87 115 public: 88 116 bool ParseIndices(const char *name); 89 bool SumSubForces(class ForceMatrix &Fragments, class KeySetsContainer &KeySet , int Order, double sign);117 bool SumSubForces(class ForceMatrix &Fragments, class KeySetsContainer &KeySets, int Order, double sign); 90 118 bool ParseFragmentMatrix(const char *name, const char *prefix, string suffix, int skiplines, int skipcolumns); 91 119 }; … … 98 126 //~HessianMatrix(); 99 127 bool ParseIndices(char *name); 100 bool SumSubManyBodyTerms(class MatrixContainer &MatrixValues, class KeySetsContainer &KeySet , int Order);101 bool SumSubHessians(class HessianMatrix &Fragments, class KeySetsContainer &KeySet , int Order, double sign);128 bool SumSubManyBodyTerms(class MatrixContainer &MatrixValues, class KeySetsContainer &KeySets, int Order); 129 bool SumSubHessians(class HessianMatrix &Fragments, class KeySetsContainer &KeySets, int Order, double sign); 102 130 bool ParseFragmentMatrix(const char *name, const char *prefix, string suffix, int skiplines, int skipcolumns); 103 131 private: … … 105 133 }; 106 134 107 // ======================================= CLASS KeySetsContainer =============================108 109 class KeySetsContainer {110 public:111 int **KeySets;112 int *AtomCounter;113 int FragmentCounter;114 int Order;115 int *FragmentsPerOrder;116 int **OrderSet;117 118 KeySetsContainer();119 ~KeySetsContainer();120 121 bool ParseKeySets(const char *name, const int *ACounter, const int FCounter);122 bool ParseManyBodyTerms();123 bool Contains(const int GreaterSet, const int SmallerSet);124 };125 135 126 136 // ======================================= END ============================================= 127 137 128 #endif /*PARS ING_HPP_*/138 #endif /*PARSER_HPP_*/ -
src/periodentafel.cpp
r87e2e39 rc111db 10 10 #include <fstream> 11 11 12 #include "element.hpp" 12 13 #include "helpers.hpp" 14 #include "lists.hpp" 13 15 #include "periodentafel.hpp" 14 16 #include "verbose.hpp" -
src/periodentafel.hpp
r87e2e39 rc111db 3 3 4 4 using namespace std; 5 6 /*********************************************** includes ***********************************/ 5 7 6 8 // include config.h … … 12 14 13 15 #include "defs.hpp" 14 #include "element.hpp"15 16 16 // ====================================== class definitions ========================= 17 /****************************************** forward declarations *****************************/ 18 19 class element; 20 21 /********************************************** declarations *******************************/ 17 22 18 23 -
src/stackclass.hpp
r87e2e39 rc111db 2 2 #define STACKCLASS_HPP_ 3 3 4 using namespace std; 5 6 /*********************************************** includes ***********************************/ 7 8 // include config.h 9 #ifdef HAVE_CONFIG_H 10 #include <config.h> 11 #endif 12 4 13 #include "verbose.hpp" 5 14 #include "memoryallocator.hpp" 15 16 /****************************************** forward declarations *****************************/ 6 17 7 18 template <typename T> class StackClass; -
src/tesselation.cpp
r87e2e39 rc111db 6 6 */ 7 7 8 #include <fstream> 9 10 #include "linkedcell.hpp" 8 11 #include "tesselation.hpp" 9 #include "memoryallocator.hpp" 12 #include "tesselationhelpers.hpp" 13 #include "vector.hpp" 14 #include "verbose.hpp" 15 16 class molecule; 10 17 11 18 // ======================================== Points on Boundary ================================= … … 37 44 BoundaryPointSet::~BoundaryPointSet() 38 45 { 39 cout << Verbose(5) << "Erasing point nr. " << Nr << "." << endl;46 //cout << Verbose(5) << "Erasing point nr. " << Nr << "." << endl; 40 47 if (!lines.empty()) 41 48 cerr << "WARNING: Memory Leak! I " << *this << " am still connected to some lines." << endl; … … 67 74 ostream & operator <<(ostream &ost, BoundaryPointSet &a) 68 75 { 69 ost << "[" << a.Nr << "|" << a.node->Name << " ]";76 ost << "[" << a.Nr << "|" << a.node->Name << " at " << *a.node->node << "]"; 70 77 return ost; 71 78 } … … 125 132 for (LineMap::iterator Runner = erasor.first; Runner != erasor.second; Runner++) 126 133 if ((*Runner).second == this) { 127 cout << Verbose(5) << "Removing Line Nr. " << Nr << " in boundary point " << *endpoints[i] << "." << endl;134 //cout << Verbose(5) << "Removing Line Nr. " << Nr << " in boundary point " << *endpoints[i] << "." << endl; 128 135 endpoints[i]->lines.erase(Runner); 129 136 break; 130 137 } 131 138 } else { // there's just a single line left 132 if (endpoints[i]->lines.erase(Nr)) 133 cout << Verbose(5) << "Removing Line Nr. " << Nr << " in boundary point " << *endpoints[i] << "." << endl; 139 if (endpoints[i]->lines.erase(Nr)) { 140 //cout << Verbose(5) << "Removing Line Nr. " << Nr << " in boundary point " << *endpoints[i] << "." << endl; 141 } 134 142 } 135 143 if (endpoints[i]->lines.empty()) { 136 cout << Verbose(5) << *endpoints[i] << " has no more lines it's attached to, erasing." << endl;144 //cout << Verbose(5) << *endpoints[i] << " has no more lines it's attached to, erasing." << endl; 137 145 if (endpoints[i] != NULL) { 138 146 delete(endpoints[i]); … … 168 176 169 177 /** Checks whether the adjacent triangles of a baseline are convex or not. 170 * We sum the two angles of each normal vector with a ficticious normnal vector from this baselinbe pointing outwards.178 * We sum the two angles of each height vector with respect to the center of the baseline. 171 179 * If greater/equal M_PI than we are convex. 172 180 * \param *out output stream for debugging … … 178 186 // get the two triangles 179 187 if (triangles.size() != 2) { 180 *out << Verbose(1) << "ERROR: Baseline " << *this << " is connect to less than two triangles, Tesselation incomplete!" << endl;188 *out << Verbose(1) << "ERROR: Baseline " << *this << " is connected to less than two triangles, Tesselation incomplete!" << endl; 181 189 return true; 182 190 } … … 201 209 NormalCheck.Scale(sign); 202 210 sign = -sign; 203 BaseLineNormal.SubtractVector(&runner->second->NormalVector); // we subtract as BaseLineNormal has to point inward in direction of [pi,2pi] 211 if (runner->second->NormalVector.NormSquared() > MYEPSILON) 212 BaseLineNormal.CopyVector(&runner->second->NormalVector); // yes, copy second on top of first 213 else { 214 *out << Verbose(1) << "CRITICAL: Triangle " << *runner->second << " has zero normal vector!" << endl; 215 exit(255); 216 } 204 217 node = runner->second->GetThirdEndpoint(this); 205 218 if (node != NULL) { … … 211 224 i++; 212 225 } else { 213 //*out << Verbose(2) << " WARNING: I cannot find third node in triangle, something's wrong." << endl;226 //*out << Verbose(2) << "ERROR: I cannot find third node in triangle, something's wrong." << endl; 214 227 return true; 215 228 } … … 217 230 //*out << Verbose(3) << "INFO: BaselineNormal is " << BaseLineNormal << "." << endl; 218 231 if (NormalCheck.NormSquared() < MYEPSILON) { 219 *out << Verbose( 2) << "ACCEPT: Normalvectors of both triangles are the same: convex." << endl;232 *out << Verbose(3) << "ACCEPT: Normalvectors of both triangles are the same: convex." << endl; 220 233 return true; 221 234 } 235 BaseLineNormal.Scale(-1.); 222 236 double angle = GetAngle(helper[0], helper[1], BaseLineNormal); 223 237 if ((angle - M_PI) > -MYEPSILON) { 224 *out << Verbose( 2) << "ACCEPT: Angle is greater than pi: convex." << endl;238 *out << Verbose(3) << "ACCEPT: Angle is greater than pi: convex." << endl; 225 239 return true; 226 240 } else { 227 *out << Verbose( 2) << "REJECT: Angle is less than pi: concave." << endl;241 *out << Verbose(3) << "REJECT: Angle is less than pi: concave." << endl; 228 242 return false; 229 243 } … … 262 276 ostream & operator <<(ostream &ost, BoundaryLineSet &a) 263 277 { 264 ost << "[" << a.Nr << "|" << a.endpoints[0]->node->Name << " ," << a.endpoints[1]->node->Name << "]";278 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 << "]"; 265 279 return ost; 266 280 }; … … 332 346 for (int i = 0; i < 3; i++) { 333 347 if (lines[i] != NULL) { 334 if (lines[i]->triangles.erase(Nr)) 335 cout << Verbose(5) << "Triangle Nr." << Nr << " erased in line " << *lines[i] << "." << endl; 348 if (lines[i]->triangles.erase(Nr)) { 349 //cout << Verbose(5) << "Triangle Nr." << Nr << " erased in line " << *lines[i] << "." << endl; 350 } 336 351 if (lines[i]->triangles.empty()) { 337 cout << Verbose(5) << *lines[i] << " is no more attached to any triangle, erasing." << endl;352 //cout << Verbose(5) << *lines[i] << " is no more attached to any triangle, erasing." << endl; 338 353 delete (lines[i]); 339 354 lines[i] = NULL; … … 341 356 } 342 357 } 343 cout << Verbose(5) << "Erasing triangle Nr." << Nr << " itself." << endl;358 //cout << Verbose(5) << "Erasing triangle Nr." << Nr << " itself." << endl; 344 359 }; 345 360 … … 361 376 * We call Vector::GetIntersectionWithPlane() to receive the intersection point with the plane 362 377 * This we test if it's really on the plane and whether it's inside the triangle on the plane or not. 363 * The latter is done as follows: if it's really outside, then for any endpoint of the triangle and it's opposite364 * base line, the intersection between the line from endpoint to intersection and the base line will have a Vector::NormSquared()365 * smaller than the first line.378 * The latter is done as follows: We calculate the cross point of one of the triangle's baseline with the line 379 * given by the intersection and the third basepoint. Then, we check whether it's on the baseline (i.e. between 380 * the first two basepoints) or not. 366 381 * \param *out output stream for debugging 367 382 * \param *MolCenter offset vector of line … … 395 410 exit(255); 396 411 } 397 CrossPoint.SubtractVector(endpoints[i%3]->node->node); 412 CrossPoint.SubtractVector(endpoints[i%3]->node->node); // cross point was returned as absolute vector 398 413 399 414 // check whether intersection is inside or not by comparing length of intersection and length of cross point 400 if ((CrossPoint.NormSquared() - helper.NormSquared()) > -MYEPSILON) { // inside415 if ((CrossPoint.NormSquared() - helper.NormSquared()) < MYEPSILON) { // inside 401 416 return true; 402 417 } else { // outside! … … 426 441 for(int i=0;i<3;i++) 427 442 if (point == endpoints[i]) 443 return true; 444 return false; 445 }; 446 447 /** Checks whether point is any of the three endpoints this triangle contains. 448 * \param *point TesselPoint to test 449 * \return true - point is of the triangle, false - is not 450 */ 451 bool BoundaryTriangleSet::ContainsBoundaryPoint(class TesselPoint *point) 452 { 453 for(int i=0;i<3;i++) 454 if (point == endpoints[i]->node) 428 455 return true; 429 456 return false; … … 451 478 }; 452 479 480 /** Checks whether three given \a *Points coincide with triangle's endpoints. 481 * \param *Points[3] pointer to BoundaryPointSet 482 * \return true - is the very triangle, false - is not 483 */ 484 bool BoundaryTriangleSet::IsPresentTupel(class BoundaryTriangleSet *T) 485 { 486 return (((endpoints[0] == T->endpoints[0]) 487 || (endpoints[0] == T->endpoints[1]) 488 || (endpoints[0] == T->endpoints[2]) 489 ) && ( 490 (endpoints[1] == T->endpoints[0]) 491 || (endpoints[1] == T->endpoints[1]) 492 || (endpoints[1] == T->endpoints[2]) 493 ) && ( 494 (endpoints[2] == T->endpoints[0]) 495 || (endpoints[2] == T->endpoints[1]) 496 || (endpoints[2] == T->endpoints[2]) 497 498 )); 499 }; 500 453 501 /** Returns the endpoint which is not contained in the given \a *line. 454 502 * \param *line baseline defining two endpoints … … 485 533 ostream &operator <<(ostream &ost, BoundaryTriangleSet &a) 486 534 { 487 ost << "[" << a.Nr << "|" << a.endpoints[0]->node->Name << " ,"488 << a.endpoints[1]->node->Name << " ," << a.endpoints[2]->node->Name << "]";535 ost << "[" << a.Nr << "|" << a.endpoints[0]->node->Name << " at " << *a.endpoints[0]->node->node << "," 536 << a.endpoints[1]->node->Name << " at " << *a.endpoints[1]->node->node << "," << a.endpoints[2]->node->Name << " at " << *a.endpoints[2]->node->node << "]"; 489 537 return ost; 490 538 }; … … 505 553 TesselPoint::~TesselPoint() 506 554 { 507 Free(&Name);508 555 }; 509 556 … … 512 559 ostream & operator << (ostream &ost, const TesselPoint &a) 513 560 { 514 ost << "[" << (a.Name) << "|" << &a<< "]";561 ost << "[" << (a.Name) << "|" << a.Name << " at " << *a.node << "]"; 515 562 return ost; 516 563 }; … … 569 616 TrianglesOnBoundaryCount = 0; 570 617 InternalPointer = PointsOnBoundary.begin(); 618 LastTriangle = NULL; 619 TriangleFilesWritten = 0; 571 620 } 572 621 ; … … 585 634 cerr << "ERROR: The triangle " << runner->first << " has already been free'd." << endl; 586 635 } 636 cout << "This envelope was written to file " << TriangleFilesWritten << " times(s)." << endl; 587 637 } 588 638 ; … … 1052 1102 Vector *Center = cloud->GetCenter(out); 1053 1103 list<BoundaryTriangleSet*> *triangles = NULL; 1104 bool AddFlag = false; 1105 LinkedCell *BoundaryPoints = NULL; 1054 1106 1055 1107 *out << Verbose(1) << "Begin of InsertStraddlingPoints" << endl; 1056 1108 1057 1109 cloud->GoToFirst(); 1110 BoundaryPoints = new LinkedCell(this, 5.); 1058 1111 while (!cloud->IsEnd()) { // we only have to go once through all points, as boundary can become only bigger 1059 LinkedCell BoundaryPoints(this, 5.); 1112 if (AddFlag) { 1113 delete(BoundaryPoints); 1114 BoundaryPoints = new LinkedCell(this, 5.); 1115 AddFlag = false; 1116 } 1060 1117 Walker = cloud->GetPoint(); 1061 1118 *out << Verbose(2) << "Current point is " << *Walker << "." << endl; 1062 1119 // get the next triangle 1063 triangles = FindClosestTrianglesToPoint(out, Walker->node, &BoundaryPoints); 1064 if (triangles == NULL) { 1065 *out << Verbose(1) << "No triangles found, probably a tesselation point itself." << endl; 1120 triangles = FindClosestTrianglesToPoint(out, Walker->node, BoundaryPoints); 1121 BTS = triangles->front(); 1122 if ((triangles == NULL) || (BTS->ContainsBoundaryPoint(Walker))) { 1123 *out << Verbose(2) << "No triangles found, probably a tesselation point itself." << endl; 1066 1124 cloud->GoToNext(); 1067 1125 continue; 1068 1126 } else { 1069 BTS = triangles->front();1070 1127 } 1071 1128 *out << Verbose(2) << "Closest triangle is " << *BTS << "." << endl; … … 1090 1147 // add Walker to boundary points 1091 1148 *out << Verbose(2) << "Adding " << *Walker << " to BoundaryPoints." << endl; 1149 AddFlag = true; 1092 1150 if (AddBoundaryPoint(Walker,0)) 1093 1151 NewPoint = BPS[0]; … … 1180 1238 } else { 1181 1239 delete TPS[n]; 1182 cout << Verbose( 3) << "Node " << *((InsertUnique.first)->second->node) << " is already present in PointsOnBoundary." << endl;1240 cout << Verbose(4) << "Node " << *((InsertUnique.first)->second->node) << " is already present in PointsOnBoundary." << endl; 1183 1241 TPS[n] = (InsertUnique.first)->second; 1184 1242 } … … 1197 1255 1198 1256 if (a->lines.find(b->node->nr) != a->lines.end()) { 1199 LineMap::iterator FindLine ;1257 LineMap::iterator FindLine = a->lines.find(b->node->nr); 1200 1258 pair<LineMap::iterator,LineMap::iterator> FindPair; 1201 1259 FindPair = a->lines.equal_range(b->node->nr); 1202 1203 for (FindLine = FindPair.first; FindLine != FindPair.second; ++FindLine) { 1260 cout << Verbose(5) << "INFO: There is at least one line between " << *a << " and " << *b << ": " << *(FindLine->second) << "." << endl; 1261 1262 for (FindLine = FindPair.first; FindLine != FindPair.second; FindLine++) { 1204 1263 // If there is a line with less than two attached triangles, we don't need a new line. 1205 1264 if (FindLine->second->triangles.size() < 2) { 1206 1265 insertNewLine = false; 1207 cout << Verbose( 3) << "Using existing line " << *FindLine->second << endl;1266 cout << Verbose(4) << "Using existing line " << *FindLine->second << endl; 1208 1267 1209 1268 BPS[0] = FindLine->second->endpoints[0]; … … 1232 1291 void Tesselation::AlwaysAddTesselationTriangleLine(class BoundaryPointSet *a, class BoundaryPointSet *b, int n) 1233 1292 { 1234 cout << Verbose( 3) << "Adding line between" << *(a->node) << " and " << *(b->node) << "." << endl;1293 cout << Verbose(4) << "Adding line [" << LinesOnBoundaryCount << "|" << *(a->node) << " and " << *(b->node) << "." << endl; 1235 1294 BPS[0] = a; 1236 1295 BPS[1] = b; … … 1242 1301 }; 1243 1302 1244 /** Function tries to add Triangle just created to Triangle and remarks if already existent (Failure of algorithm).1245 * Furthermore it adds the triangle to all of its lines, in order to recognize those which are saturated later.1303 /** Function adds triangle to global list. 1304 * Furthermore, the triangle receives the next free id and id counter \a TrianglesOnBoundaryCount is increased. 1246 1305 */ 1247 1306 void Tesselation::AddTesselationTriangle() … … 1252 1311 TrianglesOnBoundary.insert(TrianglePair(TrianglesOnBoundaryCount, BTS)); 1253 1312 TrianglesOnBoundaryCount++; 1313 1314 // set as last new triangle 1315 LastTriangle = BTS; 1316 1317 // NOTE: add triangle to local maps is done in constructor of BoundaryTriangleSet 1318 }; 1319 1320 /** Function adds triangle to global list. 1321 * Furthermore, the triangle number is set to \a nr. 1322 * \param nr triangle number 1323 */ 1324 void Tesselation::AddTesselationTriangle(int nr) 1325 { 1326 cout << Verbose(1) << "Adding triangle to global TrianglesOnBoundary map." << endl; 1327 1328 // add triangle to global map 1329 TrianglesOnBoundary.insert(TrianglePair(nr, BTS)); 1330 1331 // set as last new triangle 1332 LastTriangle = BTS; 1254 1333 1255 1334 // NOTE: add triangle to local maps is done in constructor of BoundaryTriangleSet … … 1272 1351 cout << Verbose(5) << *triangle->lines[i] << " is no more attached to any triangle, erasing." << endl; 1273 1352 RemoveTesselationLine(triangle->lines[i]); 1274 triangle->lines[i] = NULL; 1275 } else 1276 cout << Verbose(5) << *triangle->lines[i] << " is still attached to another triangle." << endl; 1353 } else { 1354 cout << Verbose(5) << *triangle->lines[i] << " is still attached to another triangle: "; 1355 for(TriangleMap::iterator TriangleRunner = triangle->lines[i]->triangles.begin(); TriangleRunner != triangle->lines[i]->triangles.end(); TriangleRunner++) 1356 cout << "[" << (TriangleRunner->second)->Nr << "|" << *((TriangleRunner->second)->endpoints[0]) << ", " << *((TriangleRunner->second)->endpoints[1]) << ", " << *((TriangleRunner->second)->endpoints[2]) << "] \t"; 1357 cout << endl; 1358 // for (int j=0;j<2;j++) { 1359 // cout << Verbose(5) << "Lines of endpoint " << *(triangle->lines[i]->endpoints[j]) << ": "; 1360 // for(LineMap::iterator LineRunner = triangle->lines[i]->endpoints[j]->lines.begin(); LineRunner != triangle->lines[i]->endpoints[j]->lines.end(); LineRunner++) 1361 // cout << "[" << *(LineRunner->second) << "] \t"; 1362 // cout << endl; 1363 // } 1364 } 1365 triangle->lines[i] = NULL; // free'd or not: disconnect 1277 1366 } else 1278 1367 cerr << "ERROR: This line " << i << " has already been free'd." << endl; … … 1294 1383 if (line == NULL) 1295 1384 return; 1296 // get other endpoint number offinding copies of same line1385 // get other endpoint number for finding copies of same line 1297 1386 if (line->endpoints[1] != NULL) 1298 1387 Numbers[0] = line->endpoints[1]->Nr; … … 1321 1410 cout << Verbose(5) << *line->endpoints[i] << " has no more lines it's attached to, erasing." << endl; 1322 1411 RemoveTesselationPoint(line->endpoints[i]); 1323 line->endpoints[i] = NULL; 1324 } else 1325 cout << Verbose(5) << *line->endpoints[i] << " has still lines it's attached to." << endl; 1412 } else { 1413 cout << Verbose(5) << *line->endpoints[i] << " has still lines it's attached to: "; 1414 for(LineMap::iterator LineRunner = line->endpoints[i]->lines.begin(); LineRunner != line->endpoints[i]->lines.end(); LineRunner++) 1415 cout << "[" << *(LineRunner->second) << "] \t"; 1416 cout << endl; 1417 } 1418 line->endpoints[i] = NULL; // free'd or not: disconnect 1326 1419 } else 1327 1420 cerr << "ERROR: Endpoint " << i << " has already been free'd." << endl; … … 1390 1483 } 1391 1484 // Only one of the triangle lines must be considered for the triangle count. 1392 *out << Verbose(2) << "Found " << adjacentTriangleCount << " adjacent triangles for the point set." << endl;1393 return adjacentTriangleCount;1485 //*out << Verbose(2) << "Found " << adjacentTriangleCount << " adjacent triangles for the point set." << endl; 1486 //return adjacentTriangleCount; 1394 1487 } 1395 1488 } … … 1400 1493 *out << Verbose(2) << "End of CheckPresenceOfTriangle" << endl; 1401 1494 return adjacentTriangleCount; 1495 }; 1496 1497 /** Checks whether the triangle consisting of the three points is already present. 1498 * Searches for the points in Tesselation::PointsOnBoundary and checks their 1499 * lines. If any of the three edges already has two triangles attached, false is 1500 * returned. 1501 * \param *out output stream for debugging 1502 * \param *Candidates endpoints of the triangle candidate 1503 * \return NULL - none found or pointer to triangle 1504 */ 1505 class BoundaryTriangleSet * Tesselation::GetPresentTriangle(ofstream *out, TesselPoint *Candidates[3]) 1506 { 1507 class BoundaryTriangleSet *triangle = NULL; 1508 class BoundaryPointSet *Points[3]; 1509 1510 // builds a triangle point set (Points) of the end points 1511 for (int i = 0; i < 3; i++) { 1512 PointMap::iterator FindPoint = PointsOnBoundary.find(Candidates[i]->nr); 1513 if (FindPoint != PointsOnBoundary.end()) { 1514 Points[i] = FindPoint->second; 1515 } else { 1516 Points[i] = NULL; 1517 } 1518 } 1519 1520 // checks lines between the points in the Points for their adjacent triangles 1521 for (int i = 0; i < 3; i++) { 1522 if (Points[i] != NULL) { 1523 for (int j = i; j < 3; j++) { 1524 if (Points[j] != NULL) { 1525 LineMap::iterator FindLine = Points[i]->lines.find(Points[j]->node->nr); 1526 for (; (FindLine != Points[i]->lines.end()) && (FindLine->first == Points[j]->node->nr); FindLine++) { 1527 TriangleMap *triangles = &FindLine->second->triangles; 1528 for (TriangleMap::iterator FindTriangle = triangles->begin(); FindTriangle != triangles->end(); FindTriangle++) { 1529 if (FindTriangle->second->IsPresentTupel(Points)) { 1530 if ((triangle == NULL) || (triangle->Nr > FindTriangle->second->Nr)) 1531 triangle = FindTriangle->second; 1532 } 1533 } 1534 } 1535 // Only one of the triangle lines must be considered for the triangle count. 1536 //*out << Verbose(2) << "Found " << adjacentTriangleCount << " adjacent triangles for the point set." << endl; 1537 //return adjacentTriangleCount; 1538 } 1539 } 1540 } 1541 } 1542 1543 return triangle; 1402 1544 }; 1403 1545 … … 1461 1603 CandidateList *OptCandidates = new CandidateList(); 1462 1604 for (int k=0;k<NDIM;k++) { 1605 Oben.Zero(); 1463 1606 Oben.x[k] = 1.; 1464 1607 FirstPoint = MaxPoint[k]; … … 1469 1612 ShortestAngle = 999999.; // This will contain the angle, which will be always positive (when looking for second point), when looking for third point this will be the quadrant. 1470 1613 1471 FindSecondPointForTesselation(FirstPoint, NULL,Oben, OptCandidate, &ShortestAngle, RADIUS, LC); // we give same point as next candidate as its bonds are looked into in find_second_...1614 FindSecondPointForTesselation(FirstPoint, Oben, OptCandidate, &ShortestAngle, RADIUS, LC); // we give same point as next candidate as its bonds are looked into in find_second_... 1472 1615 SecondPoint = OptCandidate; 1473 1616 if (SecondPoint == NULL) // have we found a second point? 1474 1617 continue; 1475 else1476 cout << Verbose(1) << "Found second point is at " << *SecondPoint->node << ".\n";1477 1618 1478 1619 helper.CopyVector(FirstPoint->node); … … 1496 1637 1497 1638 // adding point 1 and point 2 and add the line between them 1639 cout << Verbose(1) << "Coordinates of start node at " << *FirstPoint->node << "." << endl; 1498 1640 AddTesselationPoint(FirstPoint, 0); 1641 cout << Verbose(1) << "Found second point is at " << *SecondPoint->node << ".\n"; 1499 1642 AddTesselationPoint(SecondPoint, 1); 1500 1643 AddTesselationLine(TPS[0], TPS[1], 0); … … 1569 1712 * @param *LC LinkedCell structure with neighbouring points 1570 1713 */ 1571 bool Tesselation::FindNextSuitableTriangle(ofstream *out, BoundaryLineSet &Line, BoundaryTriangleSet &T, const double& RADIUS, int N,LinkedCell *LC)1714 bool Tesselation::FindNextSuitableTriangle(ofstream *out, BoundaryLineSet &Line, BoundaryTriangleSet &T, const double& RADIUS, LinkedCell *LC) 1572 1715 { 1573 1716 cout << Verbose(0) << "Begin of FindNextSuitableTriangle\n"; … … 1604 1747 CircleRadius = RADIUS*RADIUS - radius/4.; 1605 1748 CirclePlaneNormal.Normalize(); 1606 cout << Verbose(2) << "INFO: CircleCenter is at " << CircleCenter << ", CirclePlaneNormal is " << CirclePlaneNormal << " with circle radius " << sqrt(CircleRadius) << "." << endl;1749 //cout << Verbose(2) << "INFO: CircleCenter is at " << CircleCenter << ", CirclePlaneNormal is " << CirclePlaneNormal << " with circle radius " << sqrt(CircleRadius) << "." << endl; 1607 1750 1608 1751 // construct old center … … 1691 1834 result = false; 1692 1835 } 1693 } else if ( existentTrianglesCount == 1) { // If there is a planar region within the structure, we need this triangle a second time.1836 } else if ((existentTrianglesCount >= 1) && (existentTrianglesCount <= 3)) { // If there is a planar region within the structure, we need this triangle a second time. 1694 1837 AddTesselationPoint((*it)->point, 0); 1695 1838 AddTesselationPoint(BaseRay->endpoints[0]->node, 1); … … 1732 1875 // set baseline to new ray from ref point (here endpoints[0]->node) to current candidate (here (*it)->point)) 1733 1876 BaseRay = BLS[0]; 1877 if ((BTS != NULL) && (BTS->NormalVector.NormSquared() < MYEPSILON)) { 1878 *out << Verbose(1) << "CRITICAL: Triangle " << *BTS << " has zero normal vector!" << endl; 1879 exit(255); 1880 } 1881 1734 1882 } 1735 1883 … … 1750 1898 * \param *out output stream for debugging 1751 1899 * \param *Base line to be flipped 1752 * \return NULL - con cave, otherwise endpoint that makes it concave1900 * \return NULL - convex, otherwise endpoint that makes it concave 1753 1901 */ 1754 1902 class BoundaryPointSet *Tesselation::IsConvexRectangle(ofstream *out, class BoundaryLineSet *Base) … … 1827 1975 * \param *out output stream for debugging 1828 1976 * \param *Base line to be flipped 1829 * \return true - line was changed, false - same line as before1830 */ 1831 boolTesselation::PickFarthestofTwoBaselines(ofstream *out, class BoundaryLineSet *Base)1977 * \return volume change due to flipping (0 - then no flipped occured) 1978 */ 1979 double Tesselation::PickFarthestofTwoBaselines(ofstream *out, class BoundaryLineSet *Base) 1832 1980 { 1833 1981 class BoundaryLineSet *OtherBase; 1834 1982 Vector *ClosestPoint[2]; 1983 double volume; 1835 1984 1836 1985 int m=0; … … 1852 2001 Distance.CopyVector(ClosestPoint[1]); 1853 2002 Distance.SubtractVector(ClosestPoint[0]); 2003 2004 // 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); 1854 2006 1855 2007 // delete the temporary other base line and the closest points … … 1866 2018 if (Base->triangles.size() < 2) { 1867 2019 *out << Verbose(2) << "ERROR: Less than two triangles are attached to this baseline!" << endl; 1868 return false;2020 return 0.; 1869 2021 } 1870 2022 for (TriangleMap::iterator runner = Base->triangles.begin(); runner != Base->triangles.end(); runner++) { … … 1876 2028 if (Distance.ScalarProduct(&BaseLineNormal) > MYEPSILON) { // Distance points outwards, hence OtherBase higher than Base -> flip 1877 2029 *out << Verbose(2) << "ACCEPT: Other base line would be higher: Flipping baseline." << endl; 1878 FlipBaseline(out, Base);1879 return true;2030 // calculate volume summand as a general tetraeder 2031 return volume; 1880 2032 } else { // Base higher than OtherBase -> do nothing 1881 2033 *out << Verbose(2) << "REJECT: Base line is higher: Nothing to do." << endl; 1882 return false; 1883 } 1884 } 1885 }; 1886 1887 /** Returns the closest point on \a *Base with respect to \a *OtherBase. 1888 * \param *out output stream for debugging 1889 * \param *Base reference line 1890 * \param *OtherBase other base line 1891 * \return Vector on reference line that has closest distance 1892 */ 1893 Vector * GetClosestPointBetweenLine(ofstream *out, class BoundaryLineSet *Base, class BoundaryLineSet *OtherBase) 1894 { 1895 // construct the plane of the two baselines (i.e. take both their directional vectors) 1896 Vector Normal; 1897 Vector Baseline, OtherBaseline; 1898 Baseline.CopyVector(Base->endpoints[1]->node->node); 1899 Baseline.SubtractVector(Base->endpoints[0]->node->node); 1900 OtherBaseline.CopyVector(OtherBase->endpoints[1]->node->node); 1901 OtherBaseline.SubtractVector(OtherBase->endpoints[0]->node->node); 1902 Normal.CopyVector(&Baseline); 1903 Normal.VectorProduct(&OtherBaseline); 1904 Normal.Normalize(); 1905 *out << Verbose(4) << "First direction is " << Baseline << ", second direction is " << OtherBaseline << ", normal of intersection plane is " << Normal << "." << endl; 1906 1907 // project one offset point of OtherBase onto this plane (and add plane offset vector) 1908 Vector NewOffset; 1909 NewOffset.CopyVector(OtherBase->endpoints[0]->node->node); 1910 NewOffset.SubtractVector(Base->endpoints[0]->node->node); 1911 NewOffset.ProjectOntoPlane(&Normal); 1912 NewOffset.AddVector(Base->endpoints[0]->node->node); 1913 Vector NewDirection; 1914 NewDirection.CopyVector(&NewOffset); 1915 NewDirection.AddVector(&OtherBaseline); 1916 1917 // calculate the intersection between this projected baseline and Base 1918 Vector *Intersection = new Vector; 1919 Intersection->GetIntersectionOfTwoLinesOnPlane(out, Base->endpoints[0]->node->node, Base->endpoints[1]->node->node, &NewOffset, &NewDirection, &Normal); 1920 Normal.CopyVector(Intersection); 1921 Normal.SubtractVector(Base->endpoints[0]->node->node); 1922 *out << Verbose(3) << "Found closest point on " << *Base << " at " << *Intersection << ", factor in line is " << fabs(Normal.ScalarProduct(&Baseline)/Baseline.NormSquared()) << "." << endl; 1923 1924 return Intersection; 2034 return 0.; 2035 } 2036 } 1925 2037 }; 1926 2038 … … 1930 2042 * \param *out output stream for debugging 1931 2043 * \param *Base line to be flipped 1932 * \return true - flipping successful, false- something went awry1933 */ 1934 boolTesselation::FlipBaseline(ofstream *out, class BoundaryLineSet *Base)2044 * \return pointer to allocated new baseline - flipping successful, NULL - something went awry 2045 */ 2046 class BoundaryLineSet * Tesselation::FlipBaseline(ofstream *out, class BoundaryLineSet *Base) 1935 2047 { 1936 2048 class BoundaryLineSet *OldLines[4], *NewLine; … … 1946 2058 if (Base->triangles.size() < 2) { 1947 2059 *out << Verbose(2) << "ERROR: Less than two triangles are attached to this baseline!" << endl; 1948 return false;2060 return NULL; 1949 2061 } 1950 2062 for (TriangleMap::iterator runner = Base->triangles.begin(); runner != Base->triangles.end(); runner++) { … … 1982 2094 if (i<4) { 1983 2095 *out << Verbose(1) << "ERROR: We have not gathered enough baselines!" << endl; 1984 return false;2096 return NULL; 1985 2097 } 1986 2098 for (int j=0;j<4;j++) 1987 2099 if (OldLines[j] == NULL) { 1988 2100 *out << Verbose(1) << "ERROR: We have not gathered enough baselines!" << endl; 1989 return false;2101 return NULL; 1990 2102 } 1991 2103 for (int j=0;j<2;j++) 1992 2104 if (OldPoints[j] == NULL) { 1993 2105 *out << Verbose(1) << "ERROR: We have not gathered enough endpoints!" << endl; 1994 return false;2106 return NULL; 1995 2107 } 1996 2108 … … 2024 2136 BTS = new class BoundaryTriangleSet(BLS, OldTriangleNrs[0]); 2025 2137 BTS->GetNormalVector(BaseLineNormal); 2026 TrianglesOnBoundary.insert(TrianglePair(OldTriangleNrs[0], BTS));2138 AddTesselationTriangle(OldTriangleNrs[0]); 2027 2139 *out << Verbose(3) << "INFO: Created new triangle " << *BTS << "." << endl; 2028 2140 … … 2032 2144 BTS = new class BoundaryTriangleSet(BLS, OldTriangleNrs[1]); 2033 2145 BTS->GetNormalVector(BaseLineNormal); 2034 TrianglesOnBoundary.insert(TrianglePair(OldTriangleNrs[1], BTS));2146 AddTesselationTriangle(OldTriangleNrs[1]); 2035 2147 *out << Verbose(3) << "INFO: Created new triangle " << *BTS << "." << endl; 2036 2148 } else { 2037 2149 *out << Verbose(1) << "The four old lines do not connect, something's utterly wrong here!" << endl; 2038 return false;2150 return NULL; 2039 2151 } 2040 2152 2041 2153 *out << Verbose(1) << "End of FlipBaseline" << endl; 2042 return true;2154 return NewLine; 2043 2155 }; 2044 2156 … … 2046 2158 /** Finds the second point of starting triangle. 2047 2159 * \param *a first node 2048 * \param *Candidate pointer to candidate node on return2049 2160 * \param Oben vector indicating the outside 2050 2161 * \param OptCandidate reference to recommended candidate on return … … 2053 2164 * \param *LC LinkedCell structure with neighbouring points 2054 2165 */ 2055 void Tesselation::FindSecondPointForTesselation(TesselPoint* a, TesselPoint* Candidate,Vector Oben, TesselPoint*& OptCandidate, double Storage[3], double RADIUS, LinkedCell *LC)2166 void Tesselation::FindSecondPointForTesselation(TesselPoint* a, Vector Oben, TesselPoint*& OptCandidate, double Storage[3], double RADIUS, LinkedCell *LC) 2056 2167 { 2057 2168 cout << Verbose(2) << "Begin of FindSecondPointForTesselation" << endl; 2058 2169 Vector AngleCheck; 2170 class TesselPoint* Candidate = NULL; 2059 2171 double norm = -1., angle; 2060 2172 LinkedNodes *List = NULL; … … 2191 2303 cout << Verbose(1) << "Begin of FindThirdPointForTesselation" << endl; 2192 2304 2193 //cout << Verbose(2) << "INFO: NormalVector of BaseTriangle is " << NormalVector << "." << endl;2305 cout << Verbose(2) << "INFO: NormalVector of BaseTriangle is " << NormalVector << "." << endl; 2194 2306 2195 2307 // construct center of circle … … 2216 2328 radius = OldSphereCenter.ScalarProduct(&OldSphereCenter); 2217 2329 if (fabs(radius - CircleRadius) < HULLEPSILON) { 2330 //cout << Verbose(2) << "INFO: OldSphereCenter is at " << OldSphereCenter << "." << endl; 2218 2331 2219 2332 // check SearchDirection … … 2392 2505 TesselPoint *trianglePoints[3]; 2393 2506 TesselPoint *SecondPoint = NULL; 2507 list<BoundaryTriangleSet*> *triangles = NULL; 2394 2508 2395 2509 if (LinesOnBoundary.empty()) { … … 2402 2516 // check whether closest point is "too close" :), then it's inside 2403 2517 if (trianglePoints[0] == NULL) { 2404 *out << Verbose( 1) << "Is the only point, no one else is closeby." << endl;2518 *out << Verbose(2) << "Is the only point, no one else is closeby." << endl; 2405 2519 return NULL; 2406 2520 } 2407 2521 if (trianglePoints[0]->node->DistanceSquared(x) < MYEPSILON) { 2408 *out << Verbose(1) << "Point is right on a tesselation point, no nearest triangle." << endl; 2409 return NULL; 2410 } 2411 list<TesselPoint*> *connectedPoints = GetCircleOfConnectedPoints(out, trianglePoints[0]); 2412 list<TesselPoint*> *connectedClosestPoints = GetNeighboursOnCircleOfConnectedPoints(out, connectedPoints, trianglePoints[0], x); 2413 delete(connectedPoints); 2414 trianglePoints[1] = connectedClosestPoints->front(); 2415 trianglePoints[2] = connectedClosestPoints->back(); 2416 for (int i=0;i<3;i++) { 2417 if (trianglePoints[i] == NULL) { 2418 *out << Verbose(1) << "IsInnerPoint encounters serious error, point " << i << " not found." << endl; 2419 } 2420 //*out << Verbose(1) << "List of possible points:" << endl; 2421 //*out << Verbose(2) << *trianglePoints[i] << endl; 2422 } 2423 2424 list<BoundaryTriangleSet*> *triangles = FindTriangles(trianglePoints); 2425 2426 delete(connectedClosestPoints); 2522 *out << Verbose(3) << "Point is right on a tesselation point, no nearest triangle." << endl; 2523 PointMap::iterator PointRunner = PointsOnBoundary.find(trianglePoints[0]->nr); 2524 triangles = new list<BoundaryTriangleSet*>; 2525 if (PointRunner != PointsOnBoundary.end()) { 2526 for(LineMap::iterator LineRunner = PointRunner->second->lines.begin(); LineRunner != PointRunner->second->lines.end(); LineRunner++) 2527 for(TriangleMap::iterator TriangleRunner = LineRunner->second->triangles.begin(); TriangleRunner != LineRunner->second->triangles.end(); TriangleRunner++) 2528 triangles->push_back(TriangleRunner->second); 2529 triangles->sort(); 2530 triangles->unique(); 2531 } else { 2532 PointRunner = PointsOnBoundary.find(SecondPoint->nr); 2533 trianglePoints[0] = SecondPoint; 2534 if (PointRunner != PointsOnBoundary.end()) { 2535 for(LineMap::iterator LineRunner = PointRunner->second->lines.begin(); LineRunner != PointRunner->second->lines.end(); LineRunner++) 2536 for(TriangleMap::iterator TriangleRunner = LineRunner->second->triangles.begin(); TriangleRunner != LineRunner->second->triangles.end(); TriangleRunner++) 2537 triangles->push_back(TriangleRunner->second); 2538 triangles->sort(); 2539 triangles->unique(); 2540 } else { 2541 *out << Verbose(1) << "ERROR: I cannot find a boundary point to the tessel point " << *trianglePoints[0] << "." << endl; 2542 return NULL; 2543 } 2544 } 2545 } else { 2546 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; 2552 } 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); 2563 } 2427 2564 2428 2565 if (triangles->empty()) { 2429 *out << Verbose(0) << "Error: There is no nearest triangle. Please check the tesselation structure."; 2566 *out << Verbose(0) << "ERROR: There is no nearest triangle. Please check the tesselation structure."; 2567 delete(triangles); 2430 2568 return NULL; 2431 2569 } else … … 2443 2581 class BoundaryTriangleSet *result = NULL; 2444 2582 list<BoundaryTriangleSet*> *triangles = FindClosestTrianglesToPoint(out, x, LC); 2583 Vector Center; 2445 2584 2446 2585 if (triangles == NULL) 2447 2586 return NULL; 2448 2587 2449 if (x->ScalarProduct(&triangles->front()->NormalVector) < 0) 2450 result = triangles->back(); 2451 else 2588 if (triangles->size() == 1) { // there is no degenerate case 2452 2589 result = triangles->front(); 2453 2590 *out << Verbose(2) << "Normal Vector of this triangle is " << result->NormalVector << "." << endl; 2591 } else { 2592 result = triangles->front(); 2593 result->GetCenter(&Center); 2594 Center.SubtractVector(x); 2595 *out << Verbose(2) << "Normal Vector of this front side is " << result->NormalVector << "." << endl; 2596 if (Center.ScalarProduct(&result->NormalVector) < 0) { 2597 result = triangles->back(); 2598 *out << Verbose(2) << "Normal Vector of this back side is " << result->NormalVector << "." << endl; 2599 if (Center.ScalarProduct(&result->NormalVector) < 0) { 2600 *out << Verbose(1) << "ERROR: Front and back side yield NormalVector in wrong direction!" << endl; 2601 } 2602 } 2603 } 2454 2604 delete(triangles); 2455 2605 return result; … … 2466 2616 { 2467 2617 class BoundaryTriangleSet *result = FindClosestTriangleToPoint(out, &Point, LC); 2468 if (result == NULL) 2618 Vector Center; 2619 2620 if (result == NULL) {// is boundary point or only point in point cloud? 2621 *out << Verbose(1) << Point << " is the only point in vicinity." << endl; 2622 return false; 2623 } 2624 2625 result->GetCenter(&Center); 2626 *out << Verbose(3) << "INFO: Central point of the triangle is " << Center << "." << endl; 2627 Center.SubtractVector(&Point); 2628 *out << Verbose(3) << "INFO: Vector from center to point to test is " << Center << "." << endl; 2629 if (Center.ScalarProduct(&result->NormalVector) > -MYEPSILON) { 2630 *out << Verbose(1) << Point << " is an inner point." << endl; 2469 2631 return true; 2470 if (Point.ScalarProduct(&result->NormalVector) < 0) 2471 return true; 2472 else 2632 } else { 2633 *out << Verbose(1) << Point << " is NOT an inner point." << endl; 2473 2634 return false; 2635 } 2474 2636 } 2475 2637 … … 2483 2645 bool Tesselation::IsInnerPoint(ofstream *out, TesselPoint *Point, LinkedCell* LC) 2484 2646 { 2485 class BoundaryTriangleSet *result = FindClosestTriangleToPoint(out, Point->node, LC); 2486 if (result == NULL) 2487 return true; 2488 if (Point->node->ScalarProduct(&result->NormalVector) < 0) 2489 return true; 2490 else 2491 return false; 2647 return IsInnerPoint(out, *(Point->node), LC); 2492 2648 } 2493 2649 … … 2496 2652 * @param *Point of which get all connected points 2497 2653 * 2498 * @return list of the all points linked to the provided one2499 */ 2500 list<TesselPoint*> * Tesselation::GetCircleOfConnectedPoints(ofstream *out, TesselPoint* Point)2501 { 2502 list<TesselPoint*> *connectedPoints = new list<TesselPoint*>;2654 * @return set of the all points linked to the provided one 2655 */ 2656 set<TesselPoint*> * Tesselation::GetAllConnectedPoints(ofstream *out, TesselPoint* Point) 2657 { 2658 set<TesselPoint*> *connectedPoints = new set<TesselPoint*>; 2503 2659 class BoundaryPointSet *ReferencePoint = NULL; 2504 2660 TesselPoint* current; … … 2510 2666 ReferencePoint = PointRunner->second; 2511 2667 } else { 2512 *out << Verbose(2) << " getCircleOfConnectedPoints() could not find the BoundaryPoint belonging to " << *Point << "." << endl;2668 *out << Verbose(2) << "GetAllConnectedPoints() could not find the BoundaryPoint belonging to " << *Point << "." << endl; 2513 2669 ReferencePoint = NULL; 2514 2670 } 2515 2671 2516 // little trick so that we look just through lines connect to the BoundaryPoint 2672 // little trick so that we look just through lines connect to the BoundaryPoint 2517 2673 // OR fall-back to look through all lines if there is no such BoundaryPoint 2518 2674 LineMap *Lines = &LinesOnBoundary; … … 2521 2677 LineMap::iterator findLines = Lines->begin(); 2522 2678 while (findLines != Lines->end()) { 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 *out << Verbose(3) << "INFO: Endpoint " << *current << " of line " << *(findLines->second) << " is taken into the circle." << endl;2535 connectedPoints->push_back(current);2536 2537 2538 2679 takePoint = false; 2680 2681 if (findLines->second->endpoints[0]->Nr == Point->nr) { 2682 takePoint = true; 2683 current = findLines->second->endpoints[1]->node; 2684 } else if (findLines->second->endpoints[1]->Nr == Point->nr) { 2685 takePoint = true; 2686 current = findLines->second->endpoints[0]->node; 2687 } 2688 2689 if (takePoint) { 2690 *out << Verbose(5) << "INFO: Endpoint " << *current << " of line " << *(findLines->second) << " is enlisted." << endl; 2691 connectedPoints->insert(current); 2692 } 2693 2694 findLines++; 2539 2695 } 2540 2696 … … 2543 2699 return NULL; 2544 2700 } 2701 2545 2702 return connectedPoints; 2546 } 2547 2548 /** Gets the two neighbouring points with respect to a reference line to the provided point. 2703 }; 2704 2705 2706 /** Gets all points connected to the provided point by triangulation lines, ordered such that we have the circle round the point. 2549 2707 * Maps them down onto the plane designated by the axis \a *Point and \a *Reference. The center of all points 2550 2708 * connected in the tesselation to \a *Point is mapped to spherical coordinates with the zero angle being given … … 2553 2711 * 2554 2712 * @param *out output stream for debugging 2555 * @param *connectedPoints list of connected points to the central \a *Point2556 2713 * @param *Point of which get all connected points 2557 * @param *Reference Vector to be checked whether it is an inner point 2558 * 2559 * @return list of the two points linked to the provided one and closest to the point to be checked, 2560 */ 2561 list<TesselPoint*> * Tesselation::GetNeighboursOnCircleOfConnectedPoints(ofstream *out, list<TesselPoint*> *connectedPoints, TesselPoint* Point, Vector* Reference) 2714 * @param *Reference Reference vector for zero angle or NULL for no preference 2715 * @return list of the all points linked to the provided one 2716 */ 2717 list<TesselPoint*> * Tesselation::GetCircleOfConnectedPoints(ofstream *out, TesselPoint* Point, Vector *Reference) 2562 2718 { 2563 2719 map<double, TesselPoint*> anglesOfPoints; 2564 map<double, TesselPoint*>::iterator runner; 2565 ; 2566 Vector center, PlaneNormal, OrthogonalVector, helper, AngleZero; 2567 2568 if (connectedPoints->size() == 0) { // if have not found any points 2569 *out << Verbose(1) << "ERROR: We have not found any connected points to " << *Point<< "." << endl; 2570 return NULL; 2571 } 2720 set<TesselPoint*> *connectedPoints = GetAllConnectedPoints(out, Point); 2721 list<TesselPoint*> *connectedCircle = new list<TesselPoint*>; 2722 Vector center; 2723 Vector PlaneNormal; 2724 Vector AngleZero; 2725 Vector OrthogonalVector; 2726 Vector helper; 2572 2727 2573 2728 // calculate central point 2574 for ( list<TesselPoint*>::iterator TesselRunner = connectedPoints->begin(); TesselRunner != connectedPoints->end(); TesselRunner++)2729 for (set<TesselPoint*>::iterator TesselRunner = connectedPoints->begin(); TesselRunner != connectedPoints->end(); TesselRunner++) 2575 2730 center.AddVector((*TesselRunner)->node); 2576 2731 //*out << "Summed vectors " << center << "; number of points " << connectedPoints.size() … … 2586 2741 2587 2742 // construct one orthogonal vector 2588 AngleZero.CopyVector(Reference); 2743 if (Reference != NULL) 2744 AngleZero.CopyVector(Reference); 2745 else 2746 AngleZero.CopyVector((*connectedPoints->begin())->node); 2589 2747 AngleZero.SubtractVector(Point->node); 2590 2748 AngleZero.ProjectOntoPlane(&PlaneNormal); … … 2594 2752 2595 2753 // go through all connected points and calculate angle 2596 for ( list<TesselPoint*>::iterator listRunner = connectedPoints->begin(); listRunner != connectedPoints->end(); listRunner++) {2754 for (set<TesselPoint*>::iterator listRunner = connectedPoints->begin(); listRunner != connectedPoints->end(); listRunner++) { 2597 2755 helper.CopyVector((*listRunner)->node); 2598 2756 helper.SubtractVector(Point->node); 2599 2757 helper.ProjectOntoPlane(&PlaneNormal); 2600 2758 double angle = GetAngle(helper, AngleZero, OrthogonalVector); 2601 *out << Verbose( 2) << "INFO: Calculated angle is " << angle << " for point " << **listRunner << "." << endl;2759 *out << Verbose(3) << "INFO: Calculated angle is " << angle << " for point " << **listRunner << "." << endl; 2602 2760 anglesOfPoints.insert(pair<double, TesselPoint*>(angle, (*listRunner))); 2603 2761 } 2604 2762 2605 list<TesselPoint*> *result = new list<TesselPoint*>; 2606 runner = anglesOfPoints.begin(); 2607 result->push_back(runner->second); 2608 runner = anglesOfPoints.end(); 2609 runner--; 2610 result->push_back(runner->second); 2611 2612 *out << Verbose(2) << "List of closest points has " << result->size() << " elements, which are " 2613 << *(result->front()) << " and " << *(result->back()) << endl; 2614 2615 return result; 2763 for(map<double, TesselPoint*>::iterator AngleRunner = anglesOfPoints.begin(); AngleRunner != anglesOfPoints.end(); AngleRunner++) { 2764 connectedCircle->push_back(AngleRunner->second); 2765 } 2766 2767 delete(connectedPoints); 2768 return connectedCircle; 2616 2769 } 2617 2770 2771 /** Gets all points connected to the provided point by triangulation lines, ordered such that we walk along a closed path. 2772 * 2773 * @param *out output stream for debugging 2774 * @param *Point of which get all connected points 2775 * @return list of the all points linked to the provided one 2776 */ 2777 list<list<TesselPoint*> *> * Tesselation::GetPathsOfConnectedPoints(ofstream *out, TesselPoint* Point) 2778 { 2779 map<double, TesselPoint*> anglesOfPoints; 2780 list<list<TesselPoint*> *> *ListOfPaths = new list<list<TesselPoint*> *>; 2781 list<TesselPoint*> *connectedPath = NULL; 2782 Vector center; 2783 Vector PlaneNormal; 2784 Vector AngleZero; 2785 Vector OrthogonalVector; 2786 Vector helper; 2787 class BoundaryPointSet *ReferencePoint = NULL; 2788 class BoundaryPointSet *CurrentPoint = NULL; 2789 class BoundaryTriangleSet *triangle = NULL; 2790 class BoundaryLineSet *CurrentLine = NULL; 2791 class BoundaryLineSet *StartLine = NULL; 2792 2793 // find the respective boundary point 2794 PointMap::iterator PointRunner = PointsOnBoundary.find(Point->nr); 2795 if (PointRunner != PointsOnBoundary.end()) { 2796 ReferencePoint = PointRunner->second; 2797 } else { 2798 *out << Verbose(2) << "ERROR: GetPathOfConnectedPoints() could not find the BoundaryPoint belonging to " << *Point << "." << endl; 2799 return NULL; 2800 } 2801 2802 map <class BoundaryLineSet *, bool> TouchedLine; 2803 map <class BoundaryTriangleSet *, bool> TouchedTriangle; 2804 map <class BoundaryLineSet *, bool>::iterator LineRunner; 2805 map <class BoundaryTriangleSet *, bool>::iterator TriangleRunner; 2806 for (LineMap::iterator Runner = ReferencePoint->lines.begin(); Runner != ReferencePoint->lines.end(); Runner++) { 2807 TouchedLine.insert( pair <class BoundaryLineSet *, bool>(Runner->second, false) ); 2808 for (TriangleMap::iterator Sprinter = Runner->second->triangles.begin(); Sprinter != Runner->second->triangles.end(); Sprinter++) 2809 TouchedTriangle.insert( pair <class BoundaryTriangleSet *, bool>(Sprinter->second, false) ); 2810 } 2811 if (!ReferencePoint->lines.empty()) { 2812 for (LineMap::iterator runner = ReferencePoint->lines.begin(); runner != ReferencePoint->lines.end(); runner++) { 2813 LineRunner = TouchedLine.find(runner->second); 2814 if (LineRunner == TouchedLine.end()) { 2815 *out << Verbose(2) << "ERROR: I could not find " << *runner->second << " in the touched list." << endl; 2816 } else if (!LineRunner->second) { 2817 LineRunner->second = true; 2818 connectedPath = new list<TesselPoint*>; 2819 triangle = NULL; 2820 CurrentLine = runner->second; 2821 StartLine = CurrentLine; 2822 CurrentPoint = CurrentLine->GetOtherEndpoint(ReferencePoint); 2823 *out << Verbose(3)<< "INFO: Beginning path retrieval at " << *CurrentPoint << " of line " << *CurrentLine << "." << endl; 2824 do { 2825 // push current one 2826 *out << Verbose(3) << "INFO: Putting " << *CurrentPoint << " at end of path." << endl; 2827 connectedPath->push_back(CurrentPoint->node); 2828 2829 // find next triangle 2830 for (TriangleMap::iterator Runner = CurrentLine->triangles.begin(); Runner != CurrentLine->triangles.end(); Runner++) { 2831 *out << Verbose(3) << "INFO: Inspecting triangle " << *Runner->second << "." << endl; 2832 if ((Runner->second != triangle)) { // look for first triangle not equal to old one 2833 triangle = Runner->second; 2834 TriangleRunner = TouchedTriangle.find(triangle); 2835 if (TriangleRunner != TouchedTriangle.end()) { 2836 if (!TriangleRunner->second) { 2837 TriangleRunner->second = true; 2838 *out << Verbose(3) << "INFO: Connecting triangle is " << *triangle << "." << endl; 2839 break; 2840 } else { 2841 *out << Verbose(3) << "INFO: Skipping " << *triangle << ", as we have already visited it." << endl; 2842 triangle = NULL; 2843 } 2844 } else { 2845 *out << Verbose(2) << "ERROR: I could not find " << *triangle << " in the touched list." << endl; 2846 triangle = NULL; 2847 } 2848 } 2849 } 2850 if (triangle == NULL) 2851 break; 2852 // find next line 2853 for (int i=0;i<3;i++) { 2854 if ((triangle->lines[i] != CurrentLine) && (triangle->lines[i]->ContainsBoundaryPoint(ReferencePoint))) { // not the current line and still containing Point 2855 CurrentLine = triangle->lines[i]; 2856 *out << Verbose(3) << "INFO: Connecting line is " << *CurrentLine << "." << endl; 2857 break; 2858 } 2859 } 2860 LineRunner = TouchedLine.find(CurrentLine); 2861 if (LineRunner == TouchedLine.end()) 2862 *out << Verbose(2) << "ERROR: I could not find " << *CurrentLine << " in the touched list." << endl; 2863 else 2864 LineRunner->second = true; 2865 // find next point 2866 CurrentPoint = CurrentLine->GetOtherEndpoint(ReferencePoint); 2867 2868 } while (CurrentLine != StartLine); 2869 // last point is missing, as it's on start line 2870 *out << Verbose(3) << "INFO: Putting " << *CurrentPoint << " at end of path." << endl; 2871 if (StartLine->GetOtherEndpoint(ReferencePoint)->node != connectedPath->back()) 2872 connectedPath->push_back(StartLine->GetOtherEndpoint(ReferencePoint)->node); 2873 2874 ListOfPaths->push_back(connectedPath); 2875 } else { 2876 *out << Verbose(3) << "INFO: Skipping " << *runner->second << ", as we have already visited it." << endl; 2877 } 2878 } 2879 } else { 2880 *out << Verbose(1) << "ERROR: There are no lines attached to " << *ReferencePoint << "." << endl; 2881 } 2882 2883 return ListOfPaths; 2884 } 2885 2886 /** Gets all closed paths on the circle of points connected to the provided point by triangulation lines, if this very point is removed. 2887 * From GetPathsOfConnectedPoints() extracts all single loops of intracrossing paths in the list of closed paths. 2888 * @param *out output stream for debugging 2889 * @param *Point of which get all connected points 2890 * @return list of the closed paths 2891 */ 2892 list<list<TesselPoint*> *> * Tesselation::GetClosedPathsOfConnectedPoints(ofstream *out, TesselPoint* Point) 2893 { 2894 list<list<TesselPoint*> *> *ListofPaths = GetPathsOfConnectedPoints(out, Point); 2895 list<list<TesselPoint*> *> *ListofClosedPaths = new list<list<TesselPoint*> *>; 2896 list<TesselPoint*> *connectedPath = NULL; 2897 list<TesselPoint*> *newPath = NULL; 2898 int count = 0; 2899 2900 2901 list<TesselPoint*>::iterator CircleRunner; 2902 list<TesselPoint*>::iterator CircleStart; 2903 2904 for(list<list<TesselPoint*> *>::iterator ListRunner = ListofPaths->begin(); ListRunner != ListofPaths->end(); ListRunner++) { 2905 connectedPath = *ListRunner; 2906 2907 *out << Verbose(2) << "INFO: Current path is " << connectedPath << "." << endl; 2908 2909 // go through list, look for reappearance of starting Point and count 2910 CircleStart = connectedPath->begin(); 2911 2912 // go through list, look for reappearance of starting Point and create list 2913 list<TesselPoint*>::iterator Marker = CircleStart; 2914 for (CircleRunner = CircleStart; CircleRunner != connectedPath->end(); CircleRunner++) { 2915 if ((*CircleRunner == *CircleStart) && (CircleRunner != CircleStart)) { // is not the very first point 2916 // we have a closed circle from Marker to new Marker 2917 *out << Verbose(3) << count+1 << ". closed path consists of: "; 2918 newPath = new list<TesselPoint*>; 2919 list<TesselPoint*>::iterator CircleSprinter = Marker; 2920 for (; CircleSprinter != CircleRunner; CircleSprinter++) { 2921 newPath->push_back(*CircleSprinter); 2922 *out << (**CircleSprinter) << " <-> "; 2923 } 2924 *out << ".." << endl; 2925 count++; 2926 Marker = CircleRunner; 2927 2928 // add to list 2929 ListofClosedPaths->push_back(newPath); 2930 } 2931 } 2932 } 2933 *out << Verbose(3) << "INFO: " << count << " closed additional path(s) have been created." << endl; 2934 2935 // delete list of paths 2936 while (!ListofPaths->empty()) { 2937 connectedPath = *(ListofPaths->begin()); 2938 ListofPaths->remove(connectedPath); 2939 delete(connectedPath); 2940 } 2941 delete(ListofPaths); 2942 2943 // exit 2944 return ListofClosedPaths; 2945 }; 2946 2947 2948 /** Gets all belonging triangles for a given BoundaryPointSet. 2949 * \param *out output stream for debugging 2950 * \param *Point BoundaryPoint 2951 * \return pointer to allocated list of triangles 2952 */ 2953 set<BoundaryTriangleSet*> *Tesselation::GetAllTriangles(ofstream *out, class BoundaryPointSet *Point) 2954 { 2955 set<BoundaryTriangleSet*> *connectedTriangles = new set<BoundaryTriangleSet*>; 2956 2957 if (Point == NULL) { 2958 *out << Verbose(1) << "ERROR: Point given is NULL." << endl; 2959 } else { 2960 // go through its lines and insert all triangles 2961 for (LineMap::iterator LineRunner = Point->lines.begin(); LineRunner != Point->lines.end(); LineRunner++) 2962 for (TriangleMap::iterator TriangleRunner = (LineRunner->second)->triangles.begin(); TriangleRunner != (LineRunner->second)->triangles.end(); TriangleRunner++) { 2963 connectedTriangles->insert(TriangleRunner->second); 2964 } 2965 } 2966 2967 return connectedTriangles; 2968 }; 2969 2970 2618 2971 /** Removes a boundary point from the envelope while keeping it closed. 2619 * We create new triangles and remove the old ones connected to the point. 2972 * We remove the old triangles connected to the point and re-create new triangles to close the surface following this ansatz: 2973 * -# a closed path(s) of boundary points surrounding the point to be removed is constructed 2974 * -# on each closed path, we pick three adjacent points, create a triangle with them and subtract the middle point from the path 2975 * -# we advance two points (i.e. the next triangle will start at the ending point of the last triangle) and continue as before 2976 * -# the surface is closed, when the path is empty 2977 * Thereby, we (hopefully) make sure that the removed points remains beneath the surface (this is checked via IsInnerPoint eventually). 2620 2978 * \param *out output stream for debugging 2621 2979 * \param *point point to be removed … … 2625 2983 class BoundaryLineSet *line = NULL; 2626 2984 class BoundaryTriangleSet *triangle = NULL; 2627 Vector OldPoint, TetraederVector[3];2985 Vector OldPoint, NormalVector; 2628 2986 double volume = 0; 2629 int *numbers = NULL;2630 2987 int count = 0; 2631 int i;2632 2988 2633 2989 if (point == NULL) { … … 2645 3001 return 0.; 2646 3002 } 2647 list<TesselPoint*> *CircleofPoints = GetCircleOfConnectedPoints(out, point->node); 2648 2649 // remove all triangles 3003 3004 list<list<TesselPoint*> *> *ListOfClosedPaths = GetClosedPathsOfConnectedPoints(out, point->node); 3005 list<TesselPoint*> *connectedPath = NULL; 3006 3007 // gather all triangles 2650 3008 for (LineMap::iterator LineRunner = point->lines.begin(); LineRunner != point->lines.end(); LineRunner++) 2651 3009 count+=LineRunner->second->triangles.size(); 2652 numbers = new int[count]; 2653 class BoundaryTriangleSet **Candidates = new BoundaryTriangleSet*[count]; 2654 i=0; 2655 for (LineMap::iterator LineRunner = point->lines.begin(); (point != NULL) && (LineRunner != point->lines.end()); LineRunner++) { 3010 map<class BoundaryTriangleSet *, int> Candidates; 3011 for (LineMap::iterator LineRunner = point->lines.begin(); LineRunner != point->lines.end(); LineRunner++) { 2656 3012 line = LineRunner->second; 2657 3013 for (TriangleMap::iterator TriangleRunner = line->triangles.begin(); TriangleRunner != line->triangles.end(); TriangleRunner++) { 2658 3014 triangle = TriangleRunner->second; 2659 Candidates[i] = triangle; 2660 numbers[i++] = triangle->Nr; 2661 } 2662 } 2663 for (int j=0;j<i;j++) { 2664 RemoveTesselationTriangle(Candidates[j]); 2665 } 2666 delete[](Candidates); 2667 *out << Verbose(1) << i << " triangles were removed." << endl; 2668 2669 // re-create all triangles by going through connected points list 2670 list<TesselPoint*>::iterator CircleRunner = CircleofPoints->begin(); 2671 list<TesselPoint*>::iterator OtherCircleRunner = CircleofPoints->begin(); 2672 class TesselPoint *CentralNode = *CircleRunner; 2673 // advance two with CircleRunner and one with OtherCircleRunner 2674 CircleRunner++; 2675 CircleRunner++; 2676 OtherCircleRunner++; 2677 i=0; 2678 cout << Verbose(2) << "INFO: CentralNode is " << *CentralNode << "." << endl; 2679 for (; (OtherCircleRunner != CircleofPoints->end()) && (CircleRunner != CircleofPoints->end()); (CircleRunner++), (OtherCircleRunner++)) { 2680 cout << Verbose(3) << "INFO: CircleRunner's node is " << **CircleRunner << "." << endl; 2681 cout << Verbose(3) << "INFO: OtherCircleRunner's node is " << **OtherCircleRunner << "." << endl; 2682 *out << Verbose(4) << "Adding new triangle points."<< endl; 2683 AddTesselationPoint(CentralNode, 0); 2684 AddTesselationPoint(*OtherCircleRunner, 1); 2685 AddTesselationPoint(*CircleRunner, 2); 2686 *out << Verbose(4) << "Adding new triangle lines."<< endl; 2687 AddTesselationLine(TPS[0], TPS[1], 0); 2688 AddTesselationLine(TPS[0], TPS[2], 1); 2689 AddTesselationLine(TPS[1], TPS[2], 2); 2690 BTS = new class BoundaryTriangleSet(BLS, numbers[i]); 2691 TrianglesOnBoundary.insert(TrianglePair(numbers[i], BTS)); 2692 *out << Verbose(4) << "Created triangle " << *BTS << "." << endl; 2693 // calculate volume summand as a general tetraeder 2694 for (int j=0;j<3;j++) { 2695 TetraederVector[j].CopyVector(TPS[j]->node->node); 2696 TetraederVector[j].SubtractVector(&OldPoint); 2697 } 2698 OldPoint.CopyVector(&TetraederVector[0]); 2699 OldPoint.VectorProduct(&TetraederVector[1]); 2700 volume += 1./6. * fabs(OldPoint.ScalarProduct(&TetraederVector[2])); 2701 // advance number 2702 i++; 2703 if (i >= count) 2704 *out << Verbose(2) << "WARNING: Maximum of numbers reached!" << endl; 2705 } 2706 *out << Verbose(1) << i << " triangles were created." << endl; 2707 2708 delete[](numbers); 2709 2710 return volume; 2711 }; 2712 2713 /** Checks for a new special triangle whether one of its edges is already present with one one triangle connected. 2714 * This enforces that special triangles (i.e. degenerated ones) should at last close the open-edge frontier and not 2715 * make it bigger (i.e. closing one (the baseline) and opening two new ones). 2716 * \param TPS[3] nodes of the triangle 2717 * \return true - there is such a line (i.e. creation of degenerated triangle is valid), false - no such line (don't create) 2718 */ 2719 bool CheckLineCriteriaForDegeneratedTriangle(class BoundaryPointSet *nodes[3]) 2720 { 2721 bool result = false; 2722 int counter = 0; 2723 2724 // check all three points 2725 for (int i=0;i<3;i++) 2726 for (int j=i+1; j<3; j++) { 2727 if (nodes[i]->lines.find(nodes[j]->node->nr) != nodes[i]->lines.end()) { // there already is a line 2728 LineMap::iterator FindLine; 2729 pair<LineMap::iterator,LineMap::iterator> FindPair; 2730 FindPair = nodes[i]->lines.equal_range(nodes[j]->node->nr); 2731 for (FindLine = FindPair.first; FindLine != FindPair.second; ++FindLine) { 2732 // If there is a line with less than two attached triangles, we don't need a new line. 2733 if (FindLine->second->triangles.size() < 2) { 2734 counter++; 2735 break; // increase counter only once per edge 2736 } 3015 Candidates.insert( pair<class BoundaryTriangleSet *, int> (triangle, triangle->Nr) ); 3016 } 3017 } 3018 3019 // remove all triangles 3020 count=0; 3021 NormalVector.Zero(); 3022 for (map<class BoundaryTriangleSet *, int>::iterator Runner = Candidates.begin(); Runner != Candidates.end(); Runner++) { 3023 *out << Verbose(3) << "INFO: Removing triangle " << *(Runner->first) << "." << endl; 3024 NormalVector.SubtractVector(&Runner->first->NormalVector); // has to point inward 3025 RemoveTesselationTriangle(Runner->first); 3026 count++; 3027 } 3028 *out << Verbose(1) << count << " triangles were removed." << endl; 3029 3030 list<list<TesselPoint*> *>::iterator ListAdvance = ListOfClosedPaths->begin(); 3031 list<list<TesselPoint*> *>::iterator ListRunner = ListAdvance; 3032 map<class BoundaryTriangleSet *, int>::iterator NumberRunner = Candidates.begin(); 3033 list<TesselPoint*>::iterator StartNode, MiddleNode, EndNode; 3034 double angle; 3035 double smallestangle; 3036 Vector Point, Reference, OrthogonalVector; 3037 if (count > 2) { // less than three triangles, then nothing will be created 3038 class TesselPoint *TriangleCandidates[3]; 3039 count = 0; 3040 for ( ; ListRunner != ListOfClosedPaths->end(); ListRunner = ListAdvance) { // go through all closed paths 3041 if (ListAdvance != ListOfClosedPaths->end()) 3042 ListAdvance++; 3043 3044 connectedPath = *ListRunner; 3045 3046 // re-create all triangles by going through connected points list 3047 list<class BoundaryLineSet *> NewLines; 3048 for (;!connectedPath->empty();) { 3049 // search middle node with widest angle to next neighbours 3050 EndNode = connectedPath->end(); 3051 smallestangle = 0.; 3052 for (MiddleNode = connectedPath->begin(); MiddleNode != connectedPath->end(); MiddleNode++) { 3053 cout << Verbose(3) << "INFO: MiddleNode is " << **MiddleNode << "." << endl; 3054 // construct vectors to next and previous neighbour 3055 StartNode = MiddleNode; 3056 if (StartNode == connectedPath->begin()) 3057 StartNode = connectedPath->end(); 3058 StartNode--; 3059 //cout << Verbose(3) << "INFO: StartNode is " << **StartNode << "." << endl; 3060 Point.CopyVector((*StartNode)->node); 3061 Point.SubtractVector((*MiddleNode)->node); 3062 StartNode = MiddleNode; 3063 StartNode++; 3064 if (StartNode == connectedPath->end()) 3065 StartNode = connectedPath->begin(); 3066 //cout << Verbose(3) << "INFO: EndNode is " << **StartNode << "." << endl; 3067 Reference.CopyVector((*StartNode)->node); 3068 Reference.SubtractVector((*MiddleNode)->node); 3069 OrthogonalVector.CopyVector((*MiddleNode)->node); 3070 OrthogonalVector.SubtractVector(&OldPoint); 3071 OrthogonalVector.MakeNormalVector(&Reference); 3072 angle = GetAngle(Point, Reference, OrthogonalVector); 3073 //if (angle < M_PI) // no wrong-sided triangles, please? 3074 if(fabs(angle - M_PI) < fabs(smallestangle - M_PI)) { // get straightest angle (i.e. construct those triangles with smallest area first) 3075 smallestangle = angle; 3076 EndNode = MiddleNode; 3077 } 2737 3078 } 2738 } else { // no line 2739 cout << Verbose(1) << "The line between " << nodes[i] << " and " << nodes[j] << " is not yet present, hence no need for a degenerate triangle." << endl; 2740 result = true; 3079 MiddleNode = EndNode; 3080 if (MiddleNode == connectedPath->end()) { 3081 cout << Verbose(1) << "CRITICAL: Could not find a smallest angle!" << endl; 3082 exit(255); 3083 } 3084 StartNode = MiddleNode; 3085 if (StartNode == connectedPath->begin()) 3086 StartNode = connectedPath->end(); 3087 StartNode--; 3088 EndNode++; 3089 if (EndNode == connectedPath->end()) 3090 EndNode = connectedPath->begin(); 3091 cout << Verbose(4) << "INFO: StartNode is " << **StartNode << "." << endl; 3092 cout << Verbose(4) << "INFO: MiddleNode is " << **MiddleNode << "." << endl; 3093 cout << Verbose(4) << "INFO: EndNode is " << **EndNode << "." << endl; 3094 *out << Verbose(3) << "INFO: Attempting to create triangle " << (*StartNode)->Name << ", " << (*MiddleNode)->Name << " and " << (*EndNode)->Name << "." << endl; 3095 TriangleCandidates[0] = *StartNode; 3096 TriangleCandidates[1] = *MiddleNode; 3097 TriangleCandidates[2] = *EndNode; 3098 triangle = GetPresentTriangle(out, TriangleCandidates); 3099 if (triangle != NULL) { 3100 cout << Verbose(1) << "WARNING: New triangle already present, skipping!" << endl; 3101 StartNode++; 3102 MiddleNode++; 3103 EndNode++; 3104 if (StartNode == connectedPath->end()) 3105 StartNode = connectedPath->begin(); 3106 if (MiddleNode == connectedPath->end()) 3107 MiddleNode = connectedPath->begin(); 3108 if (EndNode == connectedPath->end()) 3109 EndNode = connectedPath->begin(); 3110 continue; 3111 } 3112 *out << Verbose(5) << "Adding new triangle points."<< endl; 3113 AddTesselationPoint(*StartNode, 0); 3114 AddTesselationPoint(*MiddleNode, 1); 3115 AddTesselationPoint(*EndNode, 2); 3116 *out << Verbose(5) << "Adding new triangle lines."<< endl; 3117 AddTesselationLine(TPS[0], TPS[1], 0); 3118 AddTesselationLine(TPS[0], TPS[2], 1); 3119 NewLines.push_back(BLS[1]); 3120 AddTesselationLine(TPS[1], TPS[2], 2); 3121 BTS = new class BoundaryTriangleSet(BLS, TrianglesOnBoundaryCount); 3122 BTS->GetNormalVector(NormalVector); 3123 AddTesselationTriangle(); 3124 // calculate volume summand as a general tetraeder 3125 volume += CalculateVolumeofGeneralTetraeder(TPS[0]->node->node, TPS[1]->node->node, TPS[2]->node->node, &OldPoint); 3126 // advance number 3127 count++; 3128 3129 // prepare nodes for next triangle 3130 StartNode = EndNode; 3131 cout << Verbose(4) << "Removing " << **MiddleNode << " from closed path, remaining points: " << connectedPath->size() << "." << endl; 3132 connectedPath->remove(*MiddleNode); // remove the middle node (it is surrounded by triangles) 3133 if (connectedPath->size() == 2) { // we are done 3134 connectedPath->remove(*StartNode); // remove the start node 3135 connectedPath->remove(*EndNode); // remove the end node 3136 break; 3137 } else if (connectedPath->size() < 2) { // something's gone wrong! 3138 cout << Verbose(1) << "CRITICAL: There are only two endpoints left!" << endl; 3139 exit(255); 3140 } else { 3141 MiddleNode = StartNode; 3142 MiddleNode++; 3143 if (MiddleNode == connectedPath->end()) 3144 MiddleNode = connectedPath->begin(); 3145 EndNode = MiddleNode; 3146 EndNode++; 3147 if (EndNode == connectedPath->end()) 3148 EndNode = connectedPath->begin(); 3149 } 2741 3150 } 2742 } 2743 if (counter > 1) { 2744 cout << Verbose(2) << "INFO: Degenerate triangle is ok, at least two, here " << counter << ", existing lines are used." << endl; 2745 result = true; 2746 } 2747 return result; 2748 }; 2749 2750 2751 /** Sort function for the candidate list. 2752 */ 2753 bool SortCandidates(CandidateForTesselation* candidate1, CandidateForTesselation* candidate2) 2754 { 2755 Vector BaseLineVector, OrthogonalVector, helper; 2756 if (candidate1->BaseLine != candidate2->BaseLine) { // sanity check 2757 cout << Verbose(0) << "ERROR: sortCandidates was called for two different baselines: " << candidate1->BaseLine << " and " << candidate2->BaseLine << "." << endl; 2758 //return false; 2759 exit(1); 2760 } 2761 // create baseline vector 2762 BaseLineVector.CopyVector(candidate1->BaseLine->endpoints[1]->node->node); 2763 BaseLineVector.SubtractVector(candidate1->BaseLine->endpoints[0]->node->node); 2764 BaseLineVector.Normalize(); 2765 2766 // create normal in-plane vector to cope with acos() non-uniqueness on [0,2pi] (note that is pointing in the "right" direction already, hence ">0" test!) 2767 helper.CopyVector(candidate1->BaseLine->endpoints[0]->node->node); 2768 helper.SubtractVector(candidate1->point->node); 2769 OrthogonalVector.CopyVector(&helper); 2770 helper.VectorProduct(&BaseLineVector); 2771 OrthogonalVector.SubtractVector(&helper); 2772 OrthogonalVector.Normalize(); 2773 2774 // calculate both angles and correct with in-plane vector 2775 helper.CopyVector(candidate1->point->node); 2776 helper.SubtractVector(candidate1->BaseLine->endpoints[0]->node->node); 2777 double phi = BaseLineVector.Angle(&helper); 2778 if (OrthogonalVector.ScalarProduct(&helper) > 0) { 2779 phi = 2.*M_PI - phi; 2780 } 2781 helper.CopyVector(candidate2->point->node); 2782 helper.SubtractVector(candidate1->BaseLine->endpoints[0]->node->node); 2783 double psi = BaseLineVector.Angle(&helper); 2784 if (OrthogonalVector.ScalarProduct(&helper) > 0) { 2785 psi = 2.*M_PI - psi; 2786 } 2787 2788 cout << Verbose(2) << *candidate1->point << " has angle " << phi << endl; 2789 cout << Verbose(2) << *candidate2->point << " has angle " << psi << endl; 2790 2791 // return comparison 2792 return phi < psi; 2793 }; 2794 2795 /** 2796 * Finds the point which is second closest to the provided one. 2797 * 2798 * @param Point to which to find the second closest other point 2799 * @param linked cell structure 2800 * 2801 * @return point which is second closest to the provided one 2802 */ 2803 TesselPoint* FindSecondClosestPoint(const Vector* Point, LinkedCell* LC) 2804 { 2805 LinkedNodes *List = NULL; 2806 TesselPoint* closestPoint = NULL; 2807 TesselPoint* secondClosestPoint = NULL; 2808 double distance = 1e16; 2809 double secondDistance = 1e16; 2810 Vector helper; 2811 int N[NDIM], Nlower[NDIM], Nupper[NDIM]; 2812 2813 LC->SetIndexToVector(Point); // ignore status as we calculate bounds below sensibly 2814 for(int i=0;i<NDIM;i++) // store indices of this cell 2815 N[i] = LC->n[i]; 2816 cout << Verbose(2) << "INFO: Center cell is " << N[0] << ", " << N[1] << ", " << N[2] << " with No. " << LC->index << "." << endl; 2817 2818 LC->GetNeighbourBounds(Nlower, Nupper); 2819 //cout << endl; 2820 for (LC->n[0] = Nlower[0]; LC->n[0] <= Nupper[0]; LC->n[0]++) 2821 for (LC->n[1] = Nlower[1]; LC->n[1] <= Nupper[1]; LC->n[1]++) 2822 for (LC->n[2] = Nlower[2]; LC->n[2] <= Nupper[2]; LC->n[2]++) { 2823 List = LC->GetCurrentCell(); 2824 cout << Verbose(3) << "The current cell " << LC->n[0] << "," << LC->n[1] << "," << LC->n[2] << endl; 2825 if (List != NULL) { 2826 for (LinkedNodes::iterator Runner = List->begin(); Runner != List->end(); Runner++) { 2827 helper.CopyVector(Point); 2828 helper.SubtractVector((*Runner)->node); 2829 double currentNorm = helper. Norm(); 2830 if (currentNorm < distance) { 2831 // remember second point 2832 secondDistance = distance; 2833 secondClosestPoint = closestPoint; 2834 // mark down new closest point 2835 distance = currentNorm; 2836 closestPoint = (*Runner); 2837 cout << Verbose(2) << "INFO: New Nearest Neighbour is " << *closestPoint << "." << endl; 3151 // maximize the inner lines (we preferentially created lines with a huge angle, which is for the tesselation not wanted though useful for the closing) 3152 if (NewLines.size() > 1) { 3153 list<class BoundaryLineSet *>::iterator Candidate; 3154 class BoundaryLineSet *OtherBase = NULL; 3155 double tmp, maxgain; 3156 do { 3157 maxgain = 0; 3158 for(list<class BoundaryLineSet *>::iterator Runner = NewLines.begin(); Runner != NewLines.end(); Runner++) { 3159 tmp = PickFarthestofTwoBaselines(out, *Runner); 3160 if (maxgain < tmp) { 3161 maxgain = tmp; 3162 Candidate = Runner; 2838 3163 } 2839 3164 } 2840 } else { 2841 cerr << "ERROR: The current cell " << LC->n[0] << "," << LC->n[1] << "," 2842 << LC->n[2] << " is invalid!" << endl; 2843 } 3165 if (maxgain != 0) { 3166 volume += maxgain; 3167 cout << Verbose(3) << "Flipping baseline with highest volume" << **Candidate << "." << endl; 3168 OtherBase = FlipBaseline(out, *Candidate); 3169 NewLines.erase(Candidate); 3170 NewLines.push_back(OtherBase); 3171 } 3172 } while (maxgain != 0.); 2844 3173 } 2845 3174 2846 return secondClosestPoint; 2847 }; 2848 2849 /** 2850 * Finds the point which is closest to the provided one. 2851 * 2852 * @param Point to which to find the closest other point 2853 * @param SecondPoint the second closest other point on return, NULL if none found 2854 * @param linked cell structure 2855 * 2856 * @return point which is closest to the provided one, NULL if none found 2857 */ 2858 TesselPoint* FindClosestPoint(const Vector* Point, TesselPoint *&SecondPoint, LinkedCell* LC) 2859 { 2860 LinkedNodes *List = NULL; 2861 TesselPoint* closestPoint = NULL; 2862 SecondPoint = NULL; 2863 double distance = 1e16; 2864 double secondDistance = 1e16; 2865 Vector helper; 2866 int N[NDIM], Nlower[NDIM], Nupper[NDIM]; 2867 2868 LC->SetIndexToVector(Point); // ignore status as we calculate bounds below sensibly 2869 for(int i=0;i<NDIM;i++) // store indices of this cell 2870 N[i] = LC->n[i]; 2871 cout << Verbose(2) << "INFO: Center cell is " << N[0] << ", " << N[1] << ", " << N[2] << " with No. " << LC->index << "." << endl; 2872 2873 LC->GetNeighbourBounds(Nlower, Nupper); 2874 //cout << endl; 2875 for (LC->n[0] = Nlower[0]; LC->n[0] <= Nupper[0]; LC->n[0]++) 2876 for (LC->n[1] = Nlower[1]; LC->n[1] <= Nupper[1]; LC->n[1]++) 2877 for (LC->n[2] = Nlower[2]; LC->n[2] <= Nupper[2]; LC->n[2]++) { 2878 List = LC->GetCurrentCell(); 2879 cout << Verbose(3) << "The current cell " << LC->n[0] << "," << LC->n[1] << "," << LC->n[2] << endl; 2880 if (List != NULL) { 2881 for (LinkedNodes::iterator Runner = List->begin(); Runner != List->end(); Runner++) { 2882 helper.CopyVector(Point); 2883 helper.SubtractVector((*Runner)->node); 2884 double currentNorm = helper. Norm(); 2885 if (currentNorm < distance) { 2886 secondDistance = distance; 2887 SecondPoint = closestPoint; 2888 distance = currentNorm; 2889 closestPoint = (*Runner); 2890 cout << Verbose(2) << "INFO: New Nearest Neighbour is " << *closestPoint << "." << endl; 2891 } else if (currentNorm < secondDistance) { 2892 secondDistance = currentNorm; 2893 SecondPoint = (*Runner); 2894 cout << Verbose(2) << "INFO: New Second Nearest Neighbour is " << *SecondPoint << "." << endl; 2895 } 2896 } 2897 } else { 2898 cerr << "ERROR: The current cell " << LC->n[0] << "," << LC->n[1] << "," 2899 << LC->n[2] << " is invalid!" << endl; 2900 } 2901 } 2902 2903 return closestPoint; 2904 }; 3175 ListOfClosedPaths->remove(connectedPath); 3176 delete(connectedPath); 3177 } 3178 *out << Verbose(1) << count << " triangles were created." << endl; 3179 } else { 3180 while (!ListOfClosedPaths->empty()) { 3181 ListRunner = ListOfClosedPaths->begin(); 3182 connectedPath = *ListRunner; 3183 ListOfClosedPaths->remove(connectedPath); 3184 delete(connectedPath); 3185 } 3186 *out << Verbose(1) << "No need to create any triangles." << endl; 3187 } 3188 delete(ListOfClosedPaths); 3189 3190 *out << Verbose(1) << "Removed volume is " << volume << "." << endl; 3191 3192 return volume; 3193 }; 3194 3195 2905 3196 2906 3197 /** … … 2939 3230 FindTriangle = FindLine->second->triangles.begin(); 2940 3231 for (; FindTriangle != FindLine->second->triangles.end(); FindTriangle++) { 2941 if (( 2942 (FindTriangle->second->endpoints[0] == TrianglePoints[0]) 2943 || (FindTriangle->second->endpoints[0] == TrianglePoints[1]) 2944 || (FindTriangle->second->endpoints[0] == TrianglePoints[2]) 2945 ) && ( 2946 (FindTriangle->second->endpoints[1] == TrianglePoints[0]) 2947 || (FindTriangle->second->endpoints[1] == TrianglePoints[1]) 2948 || (FindTriangle->second->endpoints[1] == TrianglePoints[2]) 2949 ) && ( 2950 (FindTriangle->second->endpoints[2] == TrianglePoints[0]) 2951 || (FindTriangle->second->endpoints[2] == TrianglePoints[1]) 2952 || (FindTriangle->second->endpoints[2] == TrianglePoints[2]) 2953 ) 2954 ) { 3232 if (FindTriangle->second->IsPresentTupel(TrianglePoints)) { 2955 3233 result->push_back(FindTriangle->second); 2956 3234 } … … 2970 3248 2971 3249 /** 3250 * Finds all degenerated lines within the tesselation structure. 3251 * 3252 * @return map of keys of degenerated line pairs, each line occurs twice 3253 * in the list, once as key and once as value 3254 */ 3255 map<int, int> * Tesselation::FindAllDegeneratedLines() 3256 { 3257 map<int, class BoundaryLineSet *> AllLines; 3258 map<int, int> * DegeneratedLines = new map<int, int>; 3259 3260 // sanity check 3261 if (LinesOnBoundary.empty()) { 3262 cout << Verbose(1) << "Warning: FindAllDegeneratedTriangles() was called without any tesselation structure."; 3263 return DegeneratedLines; 3264 } 3265 3266 LineMap::iterator LineRunner1; 3267 pair<LineMap::iterator, bool> tester; 3268 for (LineRunner1 = LinesOnBoundary.begin(); LineRunner1 != LinesOnBoundary.end(); ++LineRunner1) { 3269 tester = AllLines.insert( pair<int,BoundaryLineSet *> (LineRunner1->second->endpoints[0]->Nr, LineRunner1->second) ); 3270 if ((!tester.second) && (tester.first->second->endpoints[1]->Nr == LineRunner1->second->endpoints[1]->Nr)) { // found degenerated line 3271 DegeneratedLines->insert ( pair<int, int> (LineRunner1->second->Nr, tester.first->second->Nr) ); 3272 DegeneratedLines->insert ( pair<int, int> (tester.first->second->Nr, LineRunner1->second->Nr) ); 3273 } 3274 } 3275 3276 AllLines.clear(); 3277 3278 cout << Verbose(1) << "FindAllDegeneratedLines() found " << DegeneratedLines->size() << " lines." << endl; 3279 map<int,int>::iterator it; 3280 for (it = DegeneratedLines->begin(); it != DegeneratedLines->end(); it++) 3281 cout << Verbose(2) << (*it).first << " => " << (*it).second << endl; 3282 3283 return DegeneratedLines; 3284 } 3285 3286 /** 2972 3287 * Finds all degenerated triangles within the tesselation structure. 2973 3288 * … … 2975 3290 * in the list, once as key and once as value 2976 3291 */ 2977 map<int, int> Tesselation::FindAllDegeneratedTriangles() 2978 { 2979 map<int, int> DegeneratedTriangles; 2980 2981 // sanity check 2982 if (LinesOnBoundary.empty()) { 2983 cout << Verbose(1) << "Warning: FindAllDegeneratedTriangles() was called without any tesselation structure."; 2984 return DegeneratedTriangles; 2985 } 2986 2987 LineMap::iterator LineRunner1, LineRunner2; 2988 2989 for (LineRunner1 = LinesOnBoundary.begin(); LineRunner1 != LinesOnBoundary.end(); ++LineRunner1) { 2990 for (LineRunner2 = LinesOnBoundary.begin(); LineRunner2 != LinesOnBoundary.end(); ++LineRunner2) { 2991 if ((LineRunner1->second != LineRunner2->second) 2992 && (LineRunner1->second->endpoints[0] == LineRunner2->second->endpoints[0]) 2993 && (LineRunner1->second->endpoints[1] == LineRunner2->second->endpoints[1]) 2994 ) { 2995 TriangleMap::iterator TriangleRunner1 = LineRunner1->second->triangles.begin(), 2996 TriangleRunner2 = LineRunner2->second->triangles.begin(); 2997 2998 for (; TriangleRunner1 != LineRunner1->second->triangles.end(); ++TriangleRunner1) { 2999 for (; TriangleRunner2 != LineRunner2->second->triangles.end(); ++TriangleRunner2) { 3000 if ((TriangleRunner1->second != TriangleRunner2->second) 3001 && (TriangleRunner1->second->endpoints[0] == TriangleRunner2->second->endpoints[0]) 3002 && (TriangleRunner1->second->endpoints[1] == TriangleRunner2->second->endpoints[1]) 3003 && (TriangleRunner1->second->endpoints[2] == TriangleRunner2->second->endpoints[2]) 3004 ) { 3005 DegeneratedTriangles[TriangleRunner1->second->Nr] = TriangleRunner2->second->Nr; 3006 DegeneratedTriangles[TriangleRunner2->second->Nr] = TriangleRunner1->second->Nr; 3007 } 3008 } 3292 map<int, int> * Tesselation::FindAllDegeneratedTriangles() 3293 { 3294 map<int, int> * DegeneratedLines = FindAllDegeneratedLines(); 3295 map<int, int> * DegeneratedTriangles = new map<int, int>; 3296 3297 TriangleMap::iterator TriangleRunner1, TriangleRunner2; 3298 LineMap::iterator Liner; 3299 class BoundaryLineSet *line1 = NULL, *line2 = NULL; 3300 3301 for (map<int, int>::iterator LineRunner = DegeneratedLines->begin(); LineRunner != DegeneratedLines->end(); ++LineRunner) { 3302 // run over both lines' triangles 3303 Liner = LinesOnBoundary.find(LineRunner->first); 3304 if (Liner != LinesOnBoundary.end()) 3305 line1 = Liner->second; 3306 Liner = LinesOnBoundary.find(LineRunner->second); 3307 if (Liner != LinesOnBoundary.end()) 3308 line2 = Liner->second; 3309 for (TriangleRunner1 = line1->triangles.begin(); TriangleRunner1 != line1->triangles.end(); ++TriangleRunner1) { 3310 for (TriangleRunner2 = line2->triangles.begin(); TriangleRunner2 != line2->triangles.end(); ++TriangleRunner2) { 3311 if ((TriangleRunner1->second != TriangleRunner2->second) 3312 && (TriangleRunner1->second->IsPresentTupel(TriangleRunner2->second))) { 3313 DegeneratedTriangles->insert( pair<int, int> (TriangleRunner1->second->Nr, TriangleRunner2->second->Nr) ); 3314 DegeneratedTriangles->insert( pair<int, int> (TriangleRunner2->second->Nr, TriangleRunner1->second->Nr) ); 3009 3315 } 3010 3316 } 3011 3317 } 3012 3318 } 3013 3014 cout << Verbose(1) << "FindAllDegeneratedTriangles() found " << DegeneratedTriangles.size() << " triangles." << endl; 3319 delete(DegeneratedLines); 3320 3321 cout << Verbose(1) << "FindAllDegeneratedTriangles() found " << DegeneratedTriangles->size() << " triangles:" << endl; 3015 3322 map<int,int>::iterator it; 3016 for (it = DegeneratedTriangles .begin(); it != DegeneratedTriangles.end(); it++)3323 for (it = DegeneratedTriangles->begin(); it != DegeneratedTriangles->end(); it++) 3017 3324 cout << Verbose(2) << (*it).first << " => " << (*it).second << endl; 3018 3325 … … 3026 3333 void Tesselation::RemoveDegeneratedTriangles() 3027 3334 { 3028 map<int, int> DegeneratedTriangles = FindAllDegeneratedTriangles(); 3029 3030 for (map<int, int>::iterator TriangleKeyRunner = DegeneratedTriangles.begin(); 3031 TriangleKeyRunner != DegeneratedTriangles.end(); ++TriangleKeyRunner 3335 map<int, int> * DegeneratedTriangles = FindAllDegeneratedTriangles(); 3336 TriangleMap::iterator finder; 3337 BoundaryTriangleSet *triangle = NULL, *partnerTriangle = NULL; 3338 int count = 0; 3339 3340 cout << Verbose(1) << "Begin of RemoveDegeneratedTriangles" << endl; 3341 3342 for (map<int, int>::iterator TriangleKeyRunner = DegeneratedTriangles->begin(); 3343 TriangleKeyRunner != DegeneratedTriangles->end(); ++TriangleKeyRunner 3032 3344 ) { 3033 BoundaryTriangleSet *triangle = TrianglesOnBoundary.find(TriangleKeyRunner->first)->second, 3034 *partnerTriangle = TrianglesOnBoundary.find(TriangleKeyRunner->second)->second; 3345 finder = TrianglesOnBoundary.find(TriangleKeyRunner->first); 3346 if (finder != TrianglesOnBoundary.end()) 3347 triangle = finder->second; 3348 else 3349 break; 3350 finder = TrianglesOnBoundary.find(TriangleKeyRunner->second); 3351 if (finder != TrianglesOnBoundary.end()) 3352 partnerTriangle = finder->second; 3353 else 3354 break; 3035 3355 3036 3356 bool trianglesShareLine = false; … … 3044 3364 && (triangle->endpoints[0]->LinesCount > 2) 3045 3365 ) { 3366 // check whether we have to fix lines 3367 BoundaryTriangleSet *Othertriangle = NULL; 3368 BoundaryTriangleSet *OtherpartnerTriangle = NULL; 3369 TriangleMap::iterator TriangleRunner; 3370 for (int i = 0; i < 3; ++i) 3371 for (int j = 0; j < 3; ++j) 3372 if (triangle->lines[i] != partnerTriangle->lines[j]) { 3373 // get the other two triangles 3374 for (TriangleRunner = triangle->lines[i]->triangles.begin(); TriangleRunner != triangle->lines[i]->triangles.end(); ++TriangleRunner) 3375 if (TriangleRunner->second != triangle) { 3376 Othertriangle = TriangleRunner->second; 3377 } 3378 for (TriangleRunner = partnerTriangle->lines[i]->triangles.begin(); TriangleRunner != partnerTriangle->lines[i]->triangles.end(); ++TriangleRunner) 3379 if (TriangleRunner->second != partnerTriangle) { 3380 OtherpartnerTriangle = TriangleRunner->second; 3381 } 3382 /// interchanges their lines so that triangle->lines[i] == partnerTriangle->lines[j] 3383 // the line of triangle receives the degenerated ones 3384 triangle->lines[i]->triangles.erase(Othertriangle->Nr); 3385 triangle->lines[i]->triangles.insert( TrianglePair( partnerTriangle->Nr, partnerTriangle) ); 3386 for (int k=0;k<3;k++) 3387 if (triangle->lines[i] == Othertriangle->lines[k]) { 3388 Othertriangle->lines[k] = partnerTriangle->lines[j]; 3389 break; 3390 } 3391 // the line of partnerTriangle receives the non-degenerated ones 3392 partnerTriangle->lines[j]->triangles.erase( partnerTriangle->Nr); 3393 partnerTriangle->lines[j]->triangles.insert( TrianglePair( Othertriangle->Nr, Othertriangle) ); 3394 partnerTriangle->lines[j] = triangle->lines[i]; 3395 } 3396 3397 // erase the pair 3398 count += (int) DegeneratedTriangles->erase(triangle->Nr); 3046 3399 cout << Verbose(1) << "RemoveDegeneratedTriangles() removes triangle " << *triangle << "." << endl; 3047 3400 RemoveTesselationTriangle(triangle); 3401 count += (int) DegeneratedTriangles->erase(partnerTriangle->Nr); 3048 3402 cout << Verbose(1) << "RemoveDegeneratedTriangles() removes triangle " << *partnerTriangle << "." << endl; 3049 3403 RemoveTesselationTriangle(partnerTriangle); 3050 DegeneratedTriangles.erase(DegeneratedTriangles.find(partnerTriangle->Nr));3051 3404 } else { 3052 3405 cout << Verbose(1) << "RemoveDegeneratedTriangles() does not remove triangle " << *triangle … … 3055 3408 } 3056 3409 } 3410 delete(DegeneratedTriangles); 3411 3412 cout << Verbose(1) << "RemoveDegeneratedTriangles() removed " << count << " triangles:" << endl; 3413 cout << Verbose(1) << "End of RemoveDegeneratedTriangles" << endl; 3057 3414 } 3058 3415 3059 /** Gets the angle between a point and a reference relative to the provided center. 3060 * We have two shanks point and reference between which the angle is calculated 3061 * and by scalar product with OrthogonalVector we decide the interval. 3062 * @param point to calculate the angle for 3063 * @param reference to which to calculate the angle 3064 * @param OrthogonalVector points in direction of [pi,2pi] interval 3065 * 3066 * @return angle between point and reference 3067 */ 3068 double GetAngle(const Vector &point, const Vector &reference, const Vector OrthogonalVector) 3069 { 3070 if (reference.IsZero()) 3071 return M_PI; 3072 3073 // calculate both angles and correct with in-plane vector 3074 if (point.IsZero()) 3075 return M_PI; 3076 double phi = point.Angle(&reference); 3077 if (OrthogonalVector.ScalarProduct(&point) > 0) { 3078 phi = 2.*M_PI - phi; 3079 } 3080 3081 cout << Verbose(3) << "INFO: " << point << " has angle " << phi << " with respect to reference " << reference << "." << endl; 3082 3083 return phi; 3084 } 3085 3416 /** Adds an outside Tesselpoint to the envelope via (two) degenerated triangles. 3417 * We look for the closest point on the boundary, we look through its connected boundary lines and 3418 * seek the one with the minimum angle between its center point and the new point and this base line. 3419 * We open up the line by adding a degenerated triangle, whose other side closes the base line again. 3420 * \param *out output stream for debugging 3421 * \param *point point to add 3422 * \param *LC Linked Cell structure to find nearest point 3423 */ 3424 void Tesselation::AddBoundaryPointByDegeneratedTriangle(ofstream *out, class TesselPoint *point, LinkedCell *LC) 3425 { 3426 *out << Verbose(2) << "Begin of AddBoundaryPointByDegeneratedTriangle" << endl; 3427 3428 // find nearest boundary point 3429 class TesselPoint *BackupPoint = NULL; 3430 class TesselPoint *NearestPoint = FindClosestPoint(point->node, BackupPoint, LC); 3431 class BoundaryPointSet *NearestBoundaryPoint = NULL; 3432 PointMap::iterator PointRunner; 3433 3434 if (NearestPoint == point) 3435 NearestPoint = BackupPoint; 3436 PointRunner = PointsOnBoundary.find(NearestPoint->nr); 3437 if (PointRunner != PointsOnBoundary.end()) { 3438 NearestBoundaryPoint = PointRunner->second; 3439 } else { 3440 *out << Verbose(1) << "ERROR: I cannot find the boundary point." << endl; 3441 return; 3442 } 3443 *out << Verbose(2) << "Nearest point on boundary is " << NearestPoint->Name << "." << endl; 3444 3445 // go through its lines and find the best one to split 3446 Vector CenterToPoint; 3447 Vector BaseLine; 3448 double angle, BestAngle = 0.; 3449 class BoundaryLineSet *BestLine = NULL; 3450 for (LineMap::iterator Runner = NearestBoundaryPoint->lines.begin(); Runner != NearestBoundaryPoint->lines.end(); Runner++) { 3451 BaseLine.CopyVector(Runner->second->endpoints[0]->node->node); 3452 BaseLine.SubtractVector(Runner->second->endpoints[1]->node->node); 3453 CenterToPoint.CopyVector(Runner->second->endpoints[0]->node->node); 3454 CenterToPoint.AddVector(Runner->second->endpoints[1]->node->node); 3455 CenterToPoint.Scale(0.5); 3456 CenterToPoint.SubtractVector(point->node); 3457 angle = CenterToPoint.Angle(&BaseLine); 3458 if (fabs(angle - M_PI/2.) < fabs(BestAngle - M_PI/2.)) { 3459 BestAngle = angle; 3460 BestLine = Runner->second; 3461 } 3462 } 3463 3464 // remove one triangle from the chosen line 3465 class BoundaryTriangleSet *TempTriangle = (BestLine->triangles.begin())->second; 3466 BestLine->triangles.erase(TempTriangle->Nr); 3467 int nr = -1; 3468 for (int i=0;i<3; i++) { 3469 if (TempTriangle->lines[i] == BestLine) { 3470 nr = i; 3471 break; 3472 } 3473 } 3474 3475 // create new triangle to connect point (connects automatically with the missing spot of the chosen line) 3476 *out << Verbose(5) << "Adding new triangle points."<< endl; 3477 AddTesselationPoint((BestLine->endpoints[0]->node), 0); 3478 AddTesselationPoint((BestLine->endpoints[1]->node), 1); 3479 AddTesselationPoint(point, 2); 3480 *out << Verbose(5) << "Adding new triangle lines."<< endl; 3481 AddTesselationLine(TPS[0], TPS[1], 0); 3482 AddTesselationLine(TPS[0], TPS[2], 1); 3483 AddTesselationLine(TPS[1], TPS[2], 2); 3484 BTS = new class BoundaryTriangleSet(BLS, TrianglesOnBoundaryCount); 3485 BTS->GetNormalVector(TempTriangle->NormalVector); 3486 BTS->NormalVector.Scale(-1.); 3487 *out << Verbose(3) << "INFO: NormalVector of new triangle is " << BTS->NormalVector << "." << endl; 3488 AddTesselationTriangle(); 3489 3490 // create other side of this triangle and close both new sides of the first created triangle 3491 *out << Verbose(5) << "Adding new triangle points."<< endl; 3492 AddTesselationPoint((BestLine->endpoints[0]->node), 0); 3493 AddTesselationPoint((BestLine->endpoints[1]->node), 1); 3494 AddTesselationPoint(point, 2); 3495 *out << Verbose(5) << "Adding new triangle lines."<< endl; 3496 AddTesselationLine(TPS[0], TPS[1], 0); 3497 AddTesselationLine(TPS[0], TPS[2], 1); 3498 AddTesselationLine(TPS[1], TPS[2], 2); 3499 BTS = new class BoundaryTriangleSet(BLS, TrianglesOnBoundaryCount); 3500 BTS->GetNormalVector(TempTriangle->NormalVector); 3501 *out << Verbose(3) << "INFO: NormalVector of other new triangle is " << BTS->NormalVector << "." << endl; 3502 AddTesselationTriangle(); 3503 3504 // add removed triangle to the last open line of the second triangle 3505 for (int i=0;i<3;i++) { // look for the same line as BestLine (only it's its degenerated companion) 3506 if ((BTS->lines[i]->ContainsBoundaryPoint(BestLine->endpoints[0])) && (BTS->lines[i]->ContainsBoundaryPoint(BestLine->endpoints[1]))) { 3507 if (BestLine == BTS->lines[i]){ 3508 *out << Verbose(1) << "CRITICAL: BestLine is same as found line, something's wrong here!" << endl; 3509 exit(255); 3510 } 3511 BTS->lines[i]->triangles.insert( pair<int, class BoundaryTriangleSet *> (TempTriangle->Nr, TempTriangle) ); 3512 TempTriangle->lines[nr] = BTS->lines[i]; 3513 break; 3514 } 3515 } 3516 3517 // exit 3518 *out << Verbose(2) << "End of AddBoundaryPointByDegeneratedTriangle" << endl; 3519 }; 3520 3521 /** Writes the envelope to file. 3522 * \param *out otuput stream for debugging 3523 * \param *filename basename of output file 3524 * \param *cloud PointCloud structure with all nodes 3525 */ 3526 void Tesselation::Output(ofstream *out, const char *filename, PointCloud *cloud) 3527 { 3528 ofstream *tempstream = NULL; 3529 string NameofTempFile; 3530 char NumberName[255]; 3531 3532 if (LastTriangle != NULL) { 3533 sprintf(NumberName, "-%04d-%s_%s_%s", (int)TrianglesOnBoundary.size(), LastTriangle->endpoints[0]->node->Name, LastTriangle->endpoints[1]->node->Name, LastTriangle->endpoints[2]->node->Name); 3534 if (DoTecplotOutput) { 3535 string NameofTempFile(filename); 3536 NameofTempFile.append(NumberName); 3537 for(size_t npos = NameofTempFile.find_first_of(' '); npos != string::npos; npos = NameofTempFile.find(' ', npos)) 3538 NameofTempFile.erase(npos, 1); 3539 NameofTempFile.append(TecplotSuffix); 3540 *out << Verbose(1) << "Writing temporary non convex hull to file " << NameofTempFile << ".\n"; 3541 tempstream = new ofstream(NameofTempFile.c_str(), ios::trunc); 3542 WriteTecplotFile(out, tempstream, this, cloud, TriangleFilesWritten); 3543 tempstream->close(); 3544 tempstream->flush(); 3545 delete(tempstream); 3546 } 3547 3548 if (DoRaster3DOutput) { 3549 string NameofTempFile(filename); 3550 NameofTempFile.append(NumberName); 3551 for(size_t npos = NameofTempFile.find_first_of(' '); npos != string::npos; npos = NameofTempFile.find(' ', npos)) 3552 NameofTempFile.erase(npos, 1); 3553 NameofTempFile.append(Raster3DSuffix); 3554 *out << Verbose(1) << "Writing temporary non convex hull to file " << NameofTempFile << ".\n"; 3555 tempstream = new ofstream(NameofTempFile.c_str(), ios::trunc); 3556 WriteRaster3dFile(out, tempstream, this, cloud); 3557 IncludeSphereinRaster3D(out, tempstream, this, cloud); 3558 tempstream->close(); 3559 tempstream->flush(); 3560 delete(tempstream); 3561 } 3562 } 3563 if (DoTecplotOutput || DoRaster3DOutput) 3564 TriangleFilesWritten++; 3565 }; -
src/tesselation.hpp
r87e2e39 rc111db 13 13 using namespace std; 14 14 15 /*********************************************** includes ***********************************/ 16 15 17 // include config.h 16 18 #ifdef HAVE_CONFIG_H … … 22 24 #include <set> 23 25 24 25 #include "helpers.hpp"26 #include "linkedcell.hpp"27 #include "tesselationhelpers.hpp"28 26 #include "vector.hpp" 27 28 /****************************************** forward declarations *****************************/ 29 29 30 30 class BoundaryPointSet; 31 31 class BoundaryLineSet; 32 32 class BoundaryTriangleSet; 33 class LinkedCell; 33 34 class TesselPoint; 34 35 class PointCloud; 35 36 class Tesselation; 37 38 /********************************************** definitions *********************************/ 39 40 #define DoTecplotOutput 1 41 #define DoRaster3DOutput 1 42 #define DoVRMLOutput 1 43 #define TecplotSuffix ".dat" 44 #define Raster3DSuffix ".r3d" 45 #define VRMLSUffix ".wrl" 36 46 37 47 // ======================================================= some template functions ========================================= … … 53 63 #define DistanceMultiMapPair pair <double, pair < PointMap::iterator, PointMap::iterator> > 54 64 55 65 /********************************************** declarations *******************************/ 56 66 57 67 template <typename T> void SetEndpointsOrdered(T endpoints[2], T endpoint1, T endpoint2) … … 115 125 116 126 void GetNormalVector(Vector &NormalVector); 127 void GetCenter(Vector *center); 117 128 bool GetIntersectionInsideTriangle(ofstream *out, Vector *MolCenter, Vector *x, Vector *Intersection); 118 129 bool ContainsBoundaryLine(class BoundaryLineSet *line); 119 130 bool ContainsBoundaryPoint(class BoundaryPointSet *point); 131 bool ContainsBoundaryPoint(class TesselPoint *point); 120 132 class BoundaryPointSet *GetThirdEndpoint(class BoundaryLineSet *line); 121 133 bool IsPresentTupel(class BoundaryPointSet *Points[3]); 122 void GetCenter(Vector *center);134 bool IsPresentTupel(class BoundaryTriangleSet *T); 123 135 124 136 class BoundaryPointSet *endpoints[3]; … … 196 208 void AlwaysAddTesselationTriangleLine(class BoundaryPointSet *a, class BoundaryPointSet *b, int n); 197 209 void AddTesselationTriangle(); 210 void AddTesselationTriangle(int nr); 198 211 void RemoveTesselationTriangle(class BoundaryTriangleSet *triangle); 199 212 void RemoveTesselationLine(class BoundaryLineSet *line); 200 213 void RemoveTesselationPoint(class BoundaryPointSet *point); 201 214 202 bool IsInside(Vector *pointer);203 215 class BoundaryPointSet *GetCommonEndpoint(class BoundaryLineSet * line1, class BoundaryLineSet * line2); 204 216 205 217 // concave envelope 206 218 void FindStartingTriangle(ofstream *out, const double RADIUS, class LinkedCell *LC); 207 void FindSecondPointForTesselation(class TesselPoint* a, class TesselPoint* Candidate,Vector Oben, class TesselPoint*& OptCandidate, double Storage[3], double RADIUS, class LinkedCell *LC);219 void FindSecondPointForTesselation(class TesselPoint* a, Vector Oben, class TesselPoint*& OptCandidate, double Storage[3], double RADIUS, class LinkedCell *LC); 208 220 void FindThirdPointForTesselation(Vector NormalVector, Vector SearchDirection, Vector OldSphereCenter, class BoundaryLineSet *BaseLine, class TesselPoint *ThirdNode, CandidateList* &candidates, double *ShortestAngle, const double RADIUS, class LinkedCell *LC); 209 bool FindNextSuitableTriangle(ofstream *out, BoundaryLineSet &Line, BoundaryTriangleSet &T, const double& RADIUS, int N,LinkedCell *LC);221 bool FindNextSuitableTriangle(ofstream *out, BoundaryLineSet &Line, BoundaryTriangleSet &T, const double& RADIUS, LinkedCell *LC); 210 222 int CheckPresenceOfTriangle(ofstream *out, class TesselPoint *Candidates[3]); 223 class BoundaryTriangleSet * GetPresentTriangle(ofstream *out, TesselPoint *Candidates[3]); 211 224 212 225 // convex envelope … … 215 228 bool InsertStraddlingPoints(ofstream *out, PointCloud *cloud, LinkedCell *LC); 216 229 double RemovePointFromTesselatedSurface(ofstream *out, class BoundaryPointSet *point); 217 boolFlipBaseline(ofstream *out, class BoundaryLineSet *Base);218 boolPickFarthestofTwoBaselines(ofstream *out, class BoundaryLineSet *Base);230 class BoundaryLineSet * FlipBaseline(ofstream *out, class BoundaryLineSet *Base); 231 double PickFarthestofTwoBaselines(ofstream *out, class BoundaryLineSet *Base); 219 232 class BoundaryPointSet *IsConvexRectangle(ofstream *out, class BoundaryLineSet *Base); 220 map<int, int> FindAllDegeneratedTriangles(); 233 map<int, int> * FindAllDegeneratedTriangles(); 234 map<int, int> * FindAllDegeneratedLines(); 221 235 void RemoveDegeneratedTriangles(); 222 223 list<TesselPoint*> * GetCircleOfConnectedPoints(ofstream *out, TesselPoint* Point); 224 list<TesselPoint*> * GetNeighboursOnCircleOfConnectedPoints(ofstream *out, list<TesselPoint*> *connectedPoints, TesselPoint* Point, Vector* Reference); 236 void AddBoundaryPointByDegeneratedTriangle(ofstream *out, class TesselPoint *point, LinkedCell *LC); 237 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); 225 243 list<BoundaryTriangleSet*> *FindTriangles(TesselPoint* Points[3]); 226 244 list<BoundaryTriangleSet*> * FindClosestTrianglesToPoint(ofstream *out, Vector *x, LinkedCell* LC); … … 235 253 void PrintAllBoundaryTriangles(ofstream *out); 236 254 255 // store envelope in file 256 void Output(ofstream *out, const char *filename, PointCloud *cloud); 237 257 238 258 PointMap PointsOnBoundary; … … 257 277 class BoundaryLineSet *BLS[3]; 258 278 class BoundaryTriangleSet *BTS; 279 class BoundaryTriangleSet *LastTriangle; 280 int TriangleFilesWritten; 259 281 260 282 private: … … 264 286 }; 265 287 266 bool CheckLineCriteriaForDegeneratedTriangle(class BoundaryPointSet *nodes[3]);267 bool SortCandidates(class CandidateForTesselation* candidate1, class CandidateForTesselation* candidate2);268 TesselPoint* FindClosestPoint(const Vector* Point, TesselPoint *&SecondPoint, LinkedCell* LC);269 TesselPoint* FindSecondClosestPoint(const Vector*, LinkedCell*);270 double GetAngle(const Vector &point, const Vector &reference, const Vector OrthogonalVector);271 Vector * GetClosestPointBetweenLine(ofstream *out, class BoundaryLineSet *Base, class BoundaryLineSet *OtherBase);272 288 273 289 #endif /* TESSELATION_HPP_ */ -
src/tesselationhelpers.cpp
r87e2e39 rc111db 6 6 */ 7 7 8 #include <fstream> 9 10 #include "linkedcell.hpp" 11 #include "tesselation.hpp" 8 12 #include "tesselationhelpers.hpp" 13 #include "vector.hpp" 14 #include "verbose.hpp" 9 15 10 16 double DetGet(gsl_matrix *A, int inPlace) { … … 386 392 387 393 return result; 394 }; 395 396 /** Gets the angle between a point and a reference relative to the provided center. 397 * We have two shanks point and reference between which the angle is calculated 398 * and by scalar product with OrthogonalVector we decide the interval. 399 * @param point to calculate the angle for 400 * @param reference to which to calculate the angle 401 * @param OrthogonalVector points in direction of [pi,2pi] interval 402 * 403 * @return angle between point and reference 404 */ 405 double GetAngle(const Vector &point, const Vector &reference, const Vector OrthogonalVector) 406 { 407 if (reference.IsZero()) 408 return M_PI; 409 410 // calculate both angles and correct with in-plane vector 411 if (point.IsZero()) 412 return M_PI; 413 double phi = point.Angle(&reference); 414 if (OrthogonalVector.ScalarProduct(&point) > 0) { 415 phi = 2.*M_PI - phi; 416 } 417 418 cout << Verbose(4) << "INFO: " << point << " has angle " << phi << " with respect to reference " << reference << "." << endl; 419 420 return phi; 388 421 } 389 422 423 424 /** Calculates the volume of a general tetraeder. 425 * \param *a first vector 426 * \param *a first vector 427 * \param *a first vector 428 * \param *a first vector 429 * \return \f$ \frac{1}{6} \cdot ((a-d) \times (a-c) \cdot (a-b)) \f$ 430 */ 431 double CalculateVolumeofGeneralTetraeder(Vector *a, Vector *b, Vector *c, Vector *d) 432 { 433 Vector Point, TetraederVector[3]; 434 double volume; 435 436 TetraederVector[0].CopyVector(a); 437 TetraederVector[1].CopyVector(b); 438 TetraederVector[2].CopyVector(c); 439 for (int j=0;j<3;j++) 440 TetraederVector[j].SubtractVector(d); 441 Point.CopyVector(&TetraederVector[0]); 442 Point.VectorProduct(&TetraederVector[1]); 443 volume = 1./6. * fabs(Point.ScalarProduct(&TetraederVector[2])); 444 return volume; 445 }; 446 447 448 /** Checks for a new special triangle whether one of its edges is already present with one one triangle connected. 449 * This enforces that special triangles (i.e. degenerated ones) should at last close the open-edge frontier and not 450 * make it bigger (i.e. closing one (the baseline) and opening two new ones). 451 * \param TPS[3] nodes of the triangle 452 * \return true - there is such a line (i.e. creation of degenerated triangle is valid), false - no such line (don't create) 453 */ 454 bool CheckLineCriteriaForDegeneratedTriangle(class BoundaryPointSet *nodes[3]) 455 { 456 bool result = false; 457 int counter = 0; 458 459 // check all three points 460 for (int i=0;i<3;i++) 461 for (int j=i+1; j<3; j++) { 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; 465 FindPair = nodes[i]->lines.equal_range(nodes[j]->node->nr); 466 for (FindLine = FindPair.first; FindLine != FindPair.second; ++FindLine) { 467 // If there is a line with less than two attached triangles, we don't need a new line. 468 if (FindLine->second->triangles.size() < 2) { 469 counter++; 470 break; // increase counter only once per edge 471 } 472 } 473 } else { // no line 474 cout << Verbose(1) << "The line between " << *nodes[i] << " and " << *nodes[j] << " is not yet present, hence no need for a degenerate triangle." << endl; 475 result = true; 476 } 477 } 478 if ((!result) && (counter > 1)) { 479 cout << Verbose(2) << "INFO: Degenerate triangle is ok, at least two, here " << counter << ", existing lines are used." << endl; 480 result = true; 481 } 482 return result; 483 }; 484 485 486 /** Sort function for the candidate list. 487 */ 488 bool SortCandidates(CandidateForTesselation* candidate1, CandidateForTesselation* candidate2) 489 { 490 Vector BaseLineVector, OrthogonalVector, helper; 491 if (candidate1->BaseLine != candidate2->BaseLine) { // sanity check 492 cout << Verbose(0) << "ERROR: sortCandidates was called for two different baselines: " << candidate1->BaseLine << " and " << candidate2->BaseLine << "." << endl; 493 //return false; 494 exit(1); 495 } 496 // create baseline vector 497 BaseLineVector.CopyVector(candidate1->BaseLine->endpoints[1]->node->node); 498 BaseLineVector.SubtractVector(candidate1->BaseLine->endpoints[0]->node->node); 499 BaseLineVector.Normalize(); 500 501 // create normal in-plane vector to cope with acos() non-uniqueness on [0,2pi] (note that is pointing in the "right" direction already, hence ">0" test!) 502 helper.CopyVector(candidate1->BaseLine->endpoints[0]->node->node); 503 helper.SubtractVector(candidate1->point->node); 504 OrthogonalVector.CopyVector(&helper); 505 helper.VectorProduct(&BaseLineVector); 506 OrthogonalVector.SubtractVector(&helper); 507 OrthogonalVector.Normalize(); 508 509 // calculate both angles and correct with in-plane vector 510 helper.CopyVector(candidate1->point->node); 511 helper.SubtractVector(candidate1->BaseLine->endpoints[0]->node->node); 512 double phi = BaseLineVector.Angle(&helper); 513 if (OrthogonalVector.ScalarProduct(&helper) > 0) { 514 phi = 2.*M_PI - phi; 515 } 516 helper.CopyVector(candidate2->point->node); 517 helper.SubtractVector(candidate1->BaseLine->endpoints[0]->node->node); 518 double psi = BaseLineVector.Angle(&helper); 519 if (OrthogonalVector.ScalarProduct(&helper) > 0) { 520 psi = 2.*M_PI - psi; 521 } 522 523 cout << Verbose(2) << *candidate1->point << " has angle " << phi << endl; 524 cout << Verbose(2) << *candidate2->point << " has angle " << psi << endl; 525 526 // return comparison 527 return phi < psi; 528 }; 529 530 /** 531 * Finds the point which is second closest to the provided one. 532 * 533 * @param Point to which to find the second closest other point 534 * @param linked cell structure 535 * 536 * @return point which is second closest to the provided one 537 */ 538 TesselPoint* FindSecondClosestPoint(const Vector* Point, LinkedCell* LC) 539 { 540 LinkedNodes *List = NULL; 541 TesselPoint* closestPoint = NULL; 542 TesselPoint* secondClosestPoint = NULL; 543 double distance = 1e16; 544 double secondDistance = 1e16; 545 Vector helper; 546 int N[NDIM], Nlower[NDIM], Nupper[NDIM]; 547 548 LC->SetIndexToVector(Point); // ignore status as we calculate bounds below sensibly 549 for(int i=0;i<NDIM;i++) // store indices of this cell 550 N[i] = LC->n[i]; 551 cout << Verbose(2) << "INFO: Center cell is " << N[0] << ", " << N[1] << ", " << N[2] << " with No. " << LC->index << "." << endl; 552 553 LC->GetNeighbourBounds(Nlower, Nupper); 554 //cout << endl; 555 for (LC->n[0] = Nlower[0]; LC->n[0] <= Nupper[0]; LC->n[0]++) 556 for (LC->n[1] = Nlower[1]; LC->n[1] <= Nupper[1]; LC->n[1]++) 557 for (LC->n[2] = Nlower[2]; LC->n[2] <= Nupper[2]; LC->n[2]++) { 558 List = LC->GetCurrentCell(); 559 //cout << Verbose(3) << "The current cell " << LC->n[0] << "," << LC->n[1] << "," << LC->n[2] << endl; 560 if (List != NULL) { 561 for (LinkedNodes::iterator Runner = List->begin(); Runner != List->end(); Runner++) { 562 helper.CopyVector(Point); 563 helper.SubtractVector((*Runner)->node); 564 double currentNorm = helper. Norm(); 565 if (currentNorm < distance) { 566 // remember second point 567 secondDistance = distance; 568 secondClosestPoint = closestPoint; 569 // mark down new closest point 570 distance = currentNorm; 571 closestPoint = (*Runner); 572 //cout << Verbose(2) << "INFO: New Second Nearest Neighbour is " << *secondClosestPoint << "." << endl; 573 } 574 } 575 } else { 576 cerr << "ERROR: The current cell " << LC->n[0] << "," << LC->n[1] << "," 577 << LC->n[2] << " is invalid!" << endl; 578 } 579 } 580 581 return secondClosestPoint; 582 }; 583 584 /** 585 * Finds the point which is closest to the provided one. 586 * 587 * @param Point to which to find the closest other point 588 * @param SecondPoint the second closest other point on return, NULL if none found 589 * @param linked cell structure 590 * 591 * @return point which is closest to the provided one, NULL if none found 592 */ 593 TesselPoint* FindClosestPoint(const Vector* Point, TesselPoint *&SecondPoint, LinkedCell* LC) 594 { 595 LinkedNodes *List = NULL; 596 TesselPoint* closestPoint = NULL; 597 SecondPoint = NULL; 598 double distance = 1e16; 599 double secondDistance = 1e16; 600 Vector helper; 601 int N[NDIM], Nlower[NDIM], Nupper[NDIM]; 602 603 LC->SetIndexToVector(Point); // ignore status as we calculate bounds below sensibly 604 for(int i=0;i<NDIM;i++) // store indices of this cell 605 N[i] = LC->n[i]; 606 cout << Verbose(3) << "INFO: Center cell is " << N[0] << ", " << N[1] << ", " << N[2] << " with No. " << LC->index << "." << endl; 607 608 LC->GetNeighbourBounds(Nlower, Nupper); 609 //cout << endl; 610 for (LC->n[0] = Nlower[0]; LC->n[0] <= Nupper[0]; LC->n[0]++) 611 for (LC->n[1] = Nlower[1]; LC->n[1] <= Nupper[1]; LC->n[1]++) 612 for (LC->n[2] = Nlower[2]; LC->n[2] <= Nupper[2]; LC->n[2]++) { 613 List = LC->GetCurrentCell(); 614 //cout << Verbose(3) << "The current cell " << LC->n[0] << "," << LC->n[1] << "," << LC->n[2] << endl; 615 if (List != NULL) { 616 for (LinkedNodes::iterator Runner = List->begin(); Runner != List->end(); Runner++) { 617 helper.CopyVector(Point); 618 helper.SubtractVector((*Runner)->node); 619 double currentNorm = helper. Norm(); 620 if (currentNorm < distance) { 621 secondDistance = distance; 622 SecondPoint = closestPoint; 623 distance = currentNorm; 624 closestPoint = (*Runner); 625 //cout << Verbose(2) << "INFO: New Nearest Neighbour is " << *closestPoint << "." << endl; 626 } else if (currentNorm < secondDistance) { 627 secondDistance = currentNorm; 628 SecondPoint = (*Runner); 629 //cout << Verbose(2) << "INFO: New Second Nearest Neighbour is " << *SecondPoint << "." << endl; 630 } 631 } 632 } else { 633 cerr << "ERROR: The current cell " << LC->n[0] << "," << LC->n[1] << "," 634 << LC->n[2] << " is invalid!" << endl; 635 } 636 } 637 638 return closestPoint; 639 }; 640 641 /** Returns the closest point on \a *Base with respect to \a *OtherBase. 642 * \param *out output stream for debugging 643 * \param *Base reference line 644 * \param *OtherBase other base line 645 * \return Vector on reference line that has closest distance 646 */ 647 Vector * GetClosestPointBetweenLine(ofstream *out, class BoundaryLineSet *Base, class BoundaryLineSet *OtherBase) 648 { 649 // construct the plane of the two baselines (i.e. take both their directional vectors) 650 Vector Normal; 651 Vector Baseline, OtherBaseline; 652 Baseline.CopyVector(Base->endpoints[1]->node->node); 653 Baseline.SubtractVector(Base->endpoints[0]->node->node); 654 OtherBaseline.CopyVector(OtherBase->endpoints[1]->node->node); 655 OtherBaseline.SubtractVector(OtherBase->endpoints[0]->node->node); 656 Normal.CopyVector(&Baseline); 657 Normal.VectorProduct(&OtherBaseline); 658 Normal.Normalize(); 659 *out << Verbose(4) << "First direction is " << Baseline << ", second direction is " << OtherBaseline << ", normal of intersection plane is " << Normal << "." << endl; 660 661 // project one offset point of OtherBase onto this plane (and add plane offset vector) 662 Vector NewOffset; 663 NewOffset.CopyVector(OtherBase->endpoints[0]->node->node); 664 NewOffset.SubtractVector(Base->endpoints[0]->node->node); 665 NewOffset.ProjectOntoPlane(&Normal); 666 NewOffset.AddVector(Base->endpoints[0]->node->node); 667 Vector NewDirection; 668 NewDirection.CopyVector(&NewOffset); 669 NewDirection.AddVector(&OtherBaseline); 670 671 // calculate the intersection between this projected baseline and Base 672 Vector *Intersection = new Vector; 673 Intersection->GetIntersectionOfTwoLinesOnPlane(out, Base->endpoints[0]->node->node, Base->endpoints[1]->node->node, &NewOffset, &NewDirection, &Normal); 674 Normal.CopyVector(Intersection); 675 Normal.SubtractVector(Base->endpoints[0]->node->node); 676 *out << Verbose(3) << "Found closest point on " << *Base << " at " << *Intersection << ", factor in line is " << fabs(Normal.ScalarProduct(&Baseline)/Baseline.NormSquared()) << "." << endl; 677 678 return Intersection; 679 }; 680 681 682 /** Creates the objects in a VRML file. 683 * \param *out output stream for debugging 684 * \param *vrmlfile output stream for tecplot data 685 * \param *Tess Tesselation structure with constructed triangles 686 * \param *mol molecule structure with atom positions 687 */ 688 void WriteVrmlFile(ofstream *out, ofstream *vrmlfile, class Tesselation *Tess, PointCloud *cloud) 689 { 690 TesselPoint *Walker = NULL; 691 int i; 692 Vector *center = cloud->GetCenter(out); 693 if (vrmlfile != NULL) { 694 //cout << Verbose(1) << "Writing Raster3D file ... "; 695 *vrmlfile << "#VRML V2.0 utf8" << endl; 696 *vrmlfile << "#Created by molecuilder" << endl; 697 *vrmlfile << "#All atoms as spheres" << endl; 698 cloud->GoToFirst(); 699 while (!cloud->IsEnd()) { 700 Walker = cloud->GetPoint(); 701 *vrmlfile << "Sphere {" << endl << " "; // 2 is sphere type 702 for (i=0;i<NDIM;i++) 703 *vrmlfile << Walker->node->x[i]-center->x[i] << " "; 704 *vrmlfile << "\t0.1\t1. 1. 1." << endl; // radius 0.05 and white as colour 705 cloud->GoToNext(); 706 } 707 708 *vrmlfile << "# All tesselation triangles" << endl; 709 for (TriangleMap::iterator TriangleRunner = Tess->TrianglesOnBoundary.begin(); TriangleRunner != Tess->TrianglesOnBoundary.end(); TriangleRunner++) { 710 *vrmlfile << "1" << endl << " "; // 1 is triangle type 711 for (i=0;i<3;i++) { // print each node 712 for (int j=0;j<NDIM;j++) // and for each node all NDIM coordinates 713 *vrmlfile << TriangleRunner->second->endpoints[i]->node->node->x[j]-center->x[j] << " "; 714 *vrmlfile << "\t"; 715 } 716 *vrmlfile << "1. 0. 0." << endl; // red as colour 717 *vrmlfile << "18" << endl << " 0.5 0.5 0.5" << endl; // 18 is transparency type for previous object 718 } 719 } else { 720 cerr << "ERROR: Given vrmlfile is " << vrmlfile << "." << endl; 721 } 722 delete(center); 723 }; 724 725 /** Writes additionally the current sphere (i.e. the last triangle to file). 726 * \param *out output stream for debugging 727 * \param *rasterfile output stream for tecplot data 728 * \param *Tess Tesselation structure with constructed triangles 729 * \param *mol molecule structure with atom positions 730 */ 731 void IncludeSphereinRaster3D(ofstream *out, ofstream *rasterfile, class Tesselation *Tess, PointCloud *cloud) 732 { 733 Vector helper; 734 // include the current position of the virtual sphere in the temporary raster3d file 735 Vector *center = cloud->GetCenter(out); 736 // make the circumsphere's center absolute again 737 helper.CopyVector(Tess->LastTriangle->endpoints[0]->node->node); 738 helper.AddVector(Tess->LastTriangle->endpoints[1]->node->node); 739 helper.AddVector(Tess->LastTriangle->endpoints[2]->node->node); 740 helper.Scale(1./3.); 741 helper.SubtractVector(center); 742 // and add to file plus translucency object 743 *rasterfile << "# current virtual sphere\n"; 744 *rasterfile << "8\n 25.0 0.6 -1.0 -1.0 -1.0 0.2 0 0 0 0\n"; 745 *rasterfile << "2\n " << helper.x[0] << " " << helper.x[1] << " " << helper.x[2] << "\t" << 5. << "\t1 0 0\n"; 746 *rasterfile << "9\n terminating special property\n"; 747 delete(center); 748 }; 749 750 /** Creates the objects in a raster3d file (renderable with a header.r3d). 751 * \param *out output stream for debugging 752 * \param *rasterfile output stream for tecplot data 753 * \param *Tess Tesselation structure with constructed triangles 754 * \param *mol molecule structure with atom positions 755 */ 756 void WriteRaster3dFile(ofstream *out, ofstream *rasterfile, class Tesselation *Tess, PointCloud *cloud) 757 { 758 TesselPoint *Walker = NULL; 759 int i; 760 Vector *center = cloud->GetCenter(out); 761 if (rasterfile != NULL) { 762 //cout << Verbose(1) << "Writing Raster3D file ... "; 763 *rasterfile << "# Raster3D object description, created by MoleCuilder" << endl; 764 *rasterfile << "@header.r3d" << endl; 765 *rasterfile << "# All atoms as spheres" << endl; 766 cloud->GoToFirst(); 767 while (!cloud->IsEnd()) { 768 Walker = cloud->GetPoint(); 769 *rasterfile << "2" << endl << " "; // 2 is sphere type 770 for (i=0;i<NDIM;i++) 771 *rasterfile << Walker->node->x[i]-center->x[i] << " "; 772 *rasterfile << "\t0.1\t1. 1. 1." << endl; // radius 0.05 and white as colour 773 cloud->GoToNext(); 774 } 775 776 *rasterfile << "# All tesselation triangles" << endl; 777 *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"; 778 for (TriangleMap::iterator TriangleRunner = Tess->TrianglesOnBoundary.begin(); TriangleRunner != Tess->TrianglesOnBoundary.end(); TriangleRunner++) { 779 *rasterfile << "1" << endl << " "; // 1 is triangle type 780 for (i=0;i<3;i++) { // print each node 781 for (int j=0;j<NDIM;j++) // and for each node all NDIM coordinates 782 *rasterfile << TriangleRunner->second->endpoints[i]->node->node->x[j]-center->x[j] << " "; 783 *rasterfile << "\t"; 784 } 785 *rasterfile << "1. 0. 0." << endl; // red as colour 786 //*rasterfile << "18" << endl << " 0.5 0.5 0.5" << endl; // 18 is transparency type for previous object 787 } 788 *rasterfile << "9\n# terminating special property\n"; 789 } else { 790 cerr << "ERROR: Given rasterfile is " << rasterfile << "." << endl; 791 } 792 IncludeSphereinRaster3D(out, rasterfile, Tess, cloud); 793 delete(center); 794 }; 795 796 /** This function creates the tecplot file, displaying the tesselation of the hull. 797 * \param *out output stream for debugging 798 * \param *tecplot output stream for tecplot data 799 * \param N arbitrary number to differentiate various zones in the tecplot format 800 */ 801 void WriteTecplotFile(ofstream *out, ofstream *tecplot, class Tesselation *TesselStruct, PointCloud *cloud, int N) 802 { 803 if ((tecplot != NULL) && (TesselStruct != NULL)) { 804 // write header 805 *tecplot << "TITLE = \"3D CONVEX SHELL\"" << endl; 806 *tecplot << "VARIABLES = \"X\" \"Y\" \"Z\" \"U\"" << endl; 807 *tecplot << "ZONE T=\"" << N << "-"; 808 for (int i=0;i<3;i++) 809 *tecplot << (i==0 ? "" : "_") << TesselStruct->LastTriangle->endpoints[i]->node->Name; 810 *tecplot << "\", N=" << TesselStruct->PointsOnBoundary.size() << ", E=" << TesselStruct->TrianglesOnBoundary.size() << ", DATAPACKING=POINT, ZONETYPE=FETRIANGLE" << endl; 811 int i=0; 812 for (cloud->GoToFirst(); !cloud->IsEnd(); cloud->GoToNext(), i++); 813 int *LookupList = new int[i]; 814 for (cloud->GoToFirst(), i=0; !cloud->IsEnd(); cloud->GoToNext(), i++) 815 LookupList[i] = -1; 816 817 // print atom coordinates 818 *out << Verbose(2) << "The following triangles were created:"; 819 int Counter = 1; 820 TesselPoint *Walker = NULL; 821 for (PointMap::iterator target = TesselStruct->PointsOnBoundary.begin(); target != TesselStruct->PointsOnBoundary.end(); target++) { 822 Walker = target->second->node; 823 LookupList[Walker->nr] = Counter++; 824 *tecplot << Walker->node->x[0] << " " << Walker->node->x[1] << " " << Walker->node->x[2] << " " << target->second->value << endl; 825 } 826 *tecplot << endl; 827 // print connectivity 828 for (TriangleMap::iterator runner = TesselStruct->TrianglesOnBoundary.begin(); runner != TesselStruct->TrianglesOnBoundary.end(); runner++) { 829 *out << " " << runner->second->endpoints[0]->node->Name << "<->" << runner->second->endpoints[1]->node->Name << "<->" << runner->second->endpoints[2]->node->Name; 830 *tecplot << LookupList[runner->second->endpoints[0]->node->nr] << " " << LookupList[runner->second->endpoints[1]->node->nr] << " " << LookupList[runner->second->endpoints[2]->node->nr] << endl; 831 } 832 delete[] (LookupList); 833 *out << endl; 834 } 835 }; 836 837 /** Calculates the concavity for each of the BoundaryPointSet's in a Tesselation. 838 * Sets BoundaryPointSet::value equal to the number of connected lines that are not convex. 839 * \param *out output stream for debugging 840 * \param *TesselStruct pointer to Tesselation structure 841 */ 842 void CalculateConcavityPerBoundaryPoint(ofstream *out, class Tesselation *TesselStruct) 843 { 844 class BoundaryPointSet *point = NULL; 845 class BoundaryLineSet *line = NULL; 846 847 //*out << Verbose(2) << "Begin of CalculateConcavityPerBoundaryPoint" << endl; 848 // calculate remaining concavity 849 for (PointMap::iterator PointRunner = TesselStruct->PointsOnBoundary.begin(); PointRunner != TesselStruct->PointsOnBoundary.end(); PointRunner++) { 850 point = PointRunner->second; 851 *out << Verbose(1) << "INFO: Current point is " << *point << "." << endl; 852 point->value = 0; 853 for (LineMap::iterator LineRunner = point->lines.begin(); LineRunner != point->lines.end(); LineRunner++) { 854 line = LineRunner->second; 855 //*out << Verbose(2) << "INFO: Current line of point " << *point << " is " << *line << "." << endl; 856 if (!line->CheckConvexityCriterion(out)) 857 point->value += 1; 858 } 859 } 860 //*out << Verbose(2) << "End of CalculateConcavityPerBoundaryPoint" << endl; 861 }; 862 863 864 /** Checks whether each BoundaryLineSet in the Tesselation has two triangles. 865 * \param *out output stream for debugging 866 * \param *TesselStruct 867 * \return true - all have exactly two triangles, false - some not, list is printed to screen 868 */ 869 bool CheckListOfBaselines(ofstream *out, Tesselation *TesselStruct) 870 { 871 LineMap::iterator testline; 872 bool result = false; 873 int counter = 0; 874 875 *out << Verbose(1) << "Check: List of Baselines with not two connected triangles:" << endl; 876 for (testline = TesselStruct->LinesOnBoundary.begin(); testline != TesselStruct->LinesOnBoundary.end(); testline++) { 877 if (testline->second->triangles.size() != 2) { 878 *out << Verbose(1) << *testline->second << "\t" << testline->second->triangles.size() << endl; 879 counter++; 880 } 881 } 882 if (counter == 0) { 883 *out << Verbose(1) << "None." << endl; 884 result = true; 885 } 886 return result; 887 } 888 -
src/tesselationhelpers.hpp
r87e2e39 rc111db 13 13 using namespace std; 14 14 15 /*********************************************** includes ***********************************/ 16 15 17 // include config.h 16 18 #ifdef HAVE_CONFIG_H 17 19 #include <config.h> 18 20 #endif 19 20 #define HULLEPSILON 1e-721 21 22 22 #include <gsl/gsl_linalg.h> … … 26 26 #include <gsl/gsl_vector.h> 27 27 28 #include "vector.hpp" 28 #include <iostream> 29 30 #include "defs.hpp" 31 32 /****************************************** forward declarations *****************************/ 33 34 class BoundaryPointSet; 35 class BoundaryLineSet; 36 class BoundaryTriangleSet; 37 class LinkedCell; 38 class TesselPoint; 39 class PointCloud; 40 class Tesselation; 41 class Vector; 42 43 /********************************************** definitions *********************************/ 44 45 #define HULLEPSILON 1e-10 46 47 /********************************************** declarations *******************************/ 29 48 30 49 double DetGet(gsl_matrix *A, int inPlace); … … 35 54 double MinIntersectDistance(const gsl_vector * x, void *params); 36 55 bool existsIntersection(Vector point1, Vector point2, Vector point3, Vector point4); 56 double CalculateVolumeofGeneralTetraeder(Vector *a, Vector *b, Vector *c, Vector *d); 57 double GetAngle(const Vector &point, const Vector &reference, const Vector OrthogonalVector); 58 59 bool CheckLineCriteriaForDegeneratedTriangle(class BoundaryPointSet *nodes[3]); 60 bool SortCandidates(class 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, class BoundaryLineSet *Base, class BoundaryLineSet *OtherBase); 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 71 bool CheckListOfBaselines(ofstream *out, Tesselation *TesselStruct); 72 37 73 38 74 #endif /* TESSELATIONHELPERS_HPP_ */ -
src/unittests/Makefile.am
r87e2e39 rc111db 1 1 INCLUDES = -I$(top_srcdir)/src 2 2 3 noinst_PROGRAMS = MemoryAllocatorUnitTest MemoryUsageObserverUnitTest VectorUnitTest3 noinst_PROGRAMS = ActOnAllTest MemoryAllocatorUnitTest MemoryUsageObserverUnitTest VectorUnitTest 4 4 5 TESTS = VectorUnitTest MemoryUsageObserverUnitTest MemoryAllocatorUnitTest5 TESTS = ActOnAllTest MemoryUsageObserverUnitTest MemoryAllocatorUnitTest VectorUnitTest 6 6 check_PROGRAMS = $(TESTS) 7 8 ActOnAllTest_SOURCES = ActOnAllTest.hpp ActOnAllUnitTest.cpp ActOnAllUnitTest.hpp memoryallocator.hpp 9 ActOnAllTest_CXXFLAGS = $(CPPUNIT_CFLAGS) 10 ActOnAllTest_LDFLAGS = $(CPPUNIT_LIBS) -ldl 11 ActOnAllTest_LDADD = ../libmolecuilder.a 12 7 13 8 14 VectorUnitTest_SOURCES = defs.hpp helpers.hpp leastsquaremin.hpp memoryallocator.hpp memoryusageobserver.hpp vectorunittest.cpp vectorunittest.hpp vector.hpp verbose.hpp -
src/unittests/tesselationunittest.cpp
-
Property mode
changed from
100755
to100644
r87e2e39 rc111db 84 84 delete(TesselStruct); 85 85 for (LinkedNodes::iterator Runner = Corners.begin(); Runner != Corners.end(); Runner++) { 86 delete ((*Runner)->Name);86 delete[]((*Runner)->Name); 87 87 delete((*Runner)->node); 88 88 delete(*Runner); … … 178 178 for (set<BoundaryTriangleSet*>::iterator TriangleRunner = triangles->begin(); TriangleRunner != triangles->end(); TriangleRunner++) 179 179 CPPUNIT_ASSERT_EQUAL( true, (*TriangleRunner)->ContainsBoundaryPoint(Walker) ); 180 delete(triangles); 180 181 } 181 182 } -
Property mode
changed from
-
src/unittests/tesselationunittest.hpp
-
Property mode
changed from
100755
to100644
r87e2e39 rc111db 9 9 #define TESSELATIONUNITTEST_HPP_ 10 10 11 /*********************************************** includes ***********************************/ 11 12 12 13 #include <cppunit/extensions/HelperMacros.h> 13 14 15 #include "linkedcell.hpp" 14 16 #include "tesselation.hpp" 15 17 -
Property mode
changed from
-
src/unittests/vectorunittest.cpp
r87e2e39 rc111db 13 13 #include <cppunit/ui/text/TestRunner.h> 14 14 15 #include "defs.hpp" 16 #include "vector.hpp" 15 17 #include "vectorunittest.hpp" 16 #include "vector.hpp"17 #include "defs.hpp"18 18 19 19 /********************************************** Test classes **************************************/ -
src/vector.cpp
r87e2e39 rc111db 225 225 Direction.CopyVector(LineVector); 226 226 Direction.SubtractVector(Origin); 227 Direction.Normalize(); 227 228 //*out << Verbose(4) << "INFO: Direction is " << Direction << "." << endl; 228 229 factor = Direction.ScalarProduct(PlaneNormal); … … 234 235 helper.SubtractVector(Origin); 235 236 factor = helper.ScalarProduct(PlaneNormal)/factor; 237 if (factor < MYEPSILON) { // Origin is in-plane 238 //*out << Verbose(2) << "Origin of line is in-plane, simple." << endl; 239 CopyVector(Origin); 240 return true; 241 } 236 242 //factor = Origin->ScalarProduct(PlaneNormal)*(-PlaneOffset->ScalarProduct(PlaneNormal))/(Direction.ScalarProduct(PlaneNormal)); 237 243 Direction.Scale(factor); … … 655 661 }; 656 662 663 /** Given a box by its matrix \a *M and its inverse *Minv the vector is made to point within that box. 664 * \param *M matrix of box 665 * \param *Minv inverse matrix 666 */ 667 void Vector::WrapPeriodically(const double *M, const double *Minv) 668 { 669 MatrixMultiplication(Minv); 670 // truncate to [0,1] for each axis 671 for (int i=0;i<NDIM;i++) { 672 x[i] += 0.5; // set to center of box 673 while (x[i] >= 1.) 674 x[i] -= 1.; 675 while (x[i] < 0.) 676 x[i] += 1.; 677 } 678 MatrixMultiplication(M); 679 }; 680 657 681 /** Do a matrix multiplication. 658 682 * \param *matrix NDIM_NDIM array 659 683 */ 660 void Vector::MatrixMultiplication( double *M)684 void Vector::MatrixMultiplication(const double *M) 661 685 { 662 686 Vector C; … … 700 724 * \param *matrix NDIM_NDIM array 701 725 */ 702 void Vector::InverseMatrixMultiplication( double *A)726 void Vector::InverseMatrixMultiplication(const double *A) 703 727 { 704 728 Vector C; -
src/vector.hpp
r87e2e39 rc111db 4 4 using namespace std; 5 5 6 #include "helpers.hpp" 6 /*********************************************** includes ***********************************/ 7 8 // include config.h 9 #ifdef HAVE_CONFIG_H 10 #include <config.h> 11 #endif 7 12 8 13 #include <gsl/gsl_vector.h> 9 14 #include <gsl/gsl_multimin.h> 10 15 11 class Vector; 16 #include "defs.hpp" 17 18 /********************************************** declarations *******************************/ 12 19 13 20 /** Single vector. … … 52 59 void Scale(double *factor); 53 60 void Scale(double factor); 54 void MatrixMultiplication( double *M);61 void MatrixMultiplication(const double *M); 55 62 double * InverseMatrix(double *A); 56 void InverseMatrixMultiplication( double *M);63 void InverseMatrixMultiplication(const double *M); 57 64 void KeepPeriodic(ofstream *out, double *matrix); 58 65 void LinearCombinationOfVectors(const Vector *x1, const Vector *x2, const Vector *x3, double *factors); … … 69 76 bool Output(ofstream *out) const; 70 77 bool IsInParallelepiped(Vector offset, double *parallelepiped); 78 void WrapPeriodically(const double *M, const double *Minv); 71 79 }; 72 80 -
src/verbose.cpp
r87e2e39 rc111db 1 #include "molecules.hpp" 1 using namespace std; 2 3 #include "verbose.hpp" 2 4 3 5 /** Prints the tabs according to verbosity stored in the temporary constructed class. -
src/verbose.hpp
r87e2e39 rc111db 8 8 #ifndef VERBOSE_HPP_ 9 9 #define VERBOSE_HPP_ 10 11 using namespace std; 12 13 /*********************************************** includes ***********************************/ 14 15 // include config.h 16 #ifdef HAVE_CONFIG_H 17 #include <config.h> 18 #endif 19 20 #include <iostream> 10 21 11 22 /************************************* Class Verbose & Binary *******************************/ -
tests/Makefile.am
r87e2e39 rc111db 1 1 AUTOM4TE = autom4te 2 EXTRA_DIST = testsuite.at $(TESTSUITE) atlocal.in 2 EXTRA_DIST = testsuite.at $(TESTSUITE) atlocal.in regression 3 3 TESTSUITE = $(srcdir)/testsuite 4 4 -
tests/testsuite.at
r87e2e39 rc111db 1 1 # Process with autom4te to create an -*- Autotest -*- test suite. 2 2 # 3 # see regression/... subdirs wherein for each of the cases and each check (enumerated) is a pre and post dir. 4 # In pre initial files are placed, in post results can be found to be checked by diff in this testsuite. 3 5 4 6 AT_INIT([Molecular Builder]) … … 7 9 AT_BANNER([MoleCuilder - standard options]) 8 10 AT_SETUP([Standard Options]) 11 AT_KEYWORDS([options]) 9 12 AT_CHECK([pwd],[ignore],[ignore]) 10 13 AT_CHECK([../../molecuilder -v], 0, [stdout], [ignore]) … … 18 21 AT_CLEANUP 19 22 23 20 24 AT_BANNER([MoleCuilder - molecular config creation from xyz file and atom adding]) 21 AT_SETUP([Simple configuration]) 22 # 1. create a fake element database with the only element we need 23 AT_DATA([elements.db],[# Covalent radius of each element in Angstroem from CSD (binding is: [Rcov(A)+Rcov(B)-t,Rcov(A)+Rcov(B)+t] with t = 0.4A 24 #Element Name Symbol Period Group Block Atomic Number AtomicWeight Covalent Radius vdW Radius 25 Hydrogen H 1 1 s 1 1.008 0.23 1.09 26 ]) 27 # 2. create some simplest molecular geometry 25 AT_KEYWORDS([Atom handling]) 26 # 1. create some simplest molecular geometry 27 AT_SETUP([Simple configuration - xyz file generation]) 28 28 AT_DATA([test.xyz], [[1 29 29 # test configuration, created by molecuilder test suite 30 30 H 10. 10. 10. 31 31 ]]) 32 # 3. make sure config is empty and not remnant from last test with broken dirs 33 AT_DATA([test.conf], []) 34 AT_CHECK([../../molecuilder test.conf -e ./ -p test.xyz], 0, [ignore], [ignore]) 35 AT_CHECK([fgrep "Ion_Type1_1" test.conf], 0, [Ion_Type1_1 10.000000000 10.000000000 10.000000000 0 # Number in molecule 0 32 AT_CHECK([file=test.xyz; diff $file ${abs_top_srcdir}/${AUTOTEST_PATH}/regression/Simple_configuration/1/post/$file], 0, [ignore], [ignore]) 33 AT_CLEANUP 34 35 # 2. parsing an xyz 36 AT_SETUP([Simple configuration - parsing xyz file]) 37 AT_CHECK([/bin/cp -f ${abs_top_srcdir}/${AUTOTEST_PATH}/regression/Simple_configuration/2/pre/test.xyz .], 0) 38 AT_CHECK([../../molecuilder test.conf -e ${abs_top_srcdir}/src/ -p test.xyz], 0, [ignore], [ignore]) 39 AT_CHECK([fgrep "Ion_Type1_1" test.conf], 0, [Ion_Type1_1 10.000000000 10.000000000 10.000000000 0 # molecule nr 0 36 40 ], [ignore]) 37 AT_CHECK([cp test.conf main_pcp_linux], 0, [ignore], [ignore]) 38 AT_DATA([input], [aa 10. 10. 10. 1 39 s 40 q 41 ]) 42 AT_CHECK([../../molecuilder -e ./ <input], 0, [ignore], [ignore]) 43 AT_CHECK([diff main_pcp_linux test.conf], 0, [ignore], [ignore]) 44 # 4. test some more configuration 45 AT_CHECK([../../molecuilder test.conf -e ./ -t -s -b -F -E -c -b -a -U -T -u], 0, [ignore], [stderr]) 46 AT_CHECK([fgrep -c "Not enough or invalid" stderr], 0, [10 41 AT_CHECK([file=test.conf; diff $file ${abs_top_srcdir}/${AUTOTEST_PATH}/regression/Simple_configuration/2/post/$file], 0, [ignore], [ignore]) 42 AT_CHECK([file=test.conf.in; diff $file ${abs_top_srcdir}/${AUTOTEST_PATH}/regression/Simple_configuration/2/post/$file], 0, [ignore], [ignore]) 43 AT_CHECK([file=test.conf.xyz; diff -I '.*Created by molecuilder.*' $file ${abs_top_srcdir}/${AUTOTEST_PATH}/regression/Simple_configuration/2/post/$file], 0, [ignore], [ignore]) 44 45 # 3. add atom 46 AT_CLEANUP 47 AT_SETUP([Simple configuration - adding atom]) 48 AT_CHECK([../../molecuilder test.conf -e ${abs_top_srcdir}/src/ -a 1 10. 10. 10.], 0, [ignore], [ignore]) 49 AT_CHECK([file=test.conf; diff $file ${abs_top_srcdir}/${AUTOTEST_PATH}/regression/Simple_configuration/3/post/$file], 0, [ignore], [ignore]) 50 AT_CHECK([file=test.conf.in; diff $file ${abs_top_srcdir}/${AUTOTEST_PATH}/regression/Simple_configuration/3/post/$file], 0, [ignore], [ignore]) 51 AT_CHECK([file=test.conf.xyz; diff -I '.*Created by molecuilder.*' $file ${abs_top_srcdir}/${AUTOTEST_PATH}/regression/Simple_configuration/3/post/$file], 0, [ignore], [ignore]) 52 AT_CLEANUP 53 54 # 4. change the element 55 AT_SETUP([Simple configuration - Changing element]) 56 AT_CHECK([/bin/cp -f ${abs_top_srcdir}/${AUTOTEST_PATH}/regression/Simple_configuration/4/pre/test.conf test.conf], 0) 57 AT_CHECK([../../molecuilder test.conf -e ${abs_top_srcdir}/src/ -E 0 6], 0, [ignore], [ignore]) 58 AT_CHECK([file=test.conf; diff $file ${abs_top_srcdir}/${AUTOTEST_PATH}/regression/Simple_configuration/4/post/$file], 0, [ignore], [ignore]) 59 AT_CLEANUP 60 61 # 5. remove atom 62 AT_SETUP([Simple configuration - Atom removal]) 63 AT_CHECK([/bin/cp -f ${abs_top_srcdir}/${AUTOTEST_PATH}/regression/Simple_configuration/5/pre/test.conf .], 0) 64 AT_CHECK([../../molecuilder test.conf -e ${abs_top_srcdir}/src/ -r 0], 0, [ignore], [ignore]) 65 AT_CHECK([file=test.conf; diff $file ${abs_top_srcdir}/${AUTOTEST_PATH}/regression/Simple_configuration/5/post/$file], 0, [ignore], [ignore]) 66 AT_CHECK([file=test.conf.in; diff $file ${abs_top_srcdir}/${AUTOTEST_PATH}/regression/Simple_configuration/5/post/$file], 0, [ignore], [ignore]) 67 AT_CHECK([file=test.conf.xyz; diff -I '.*Created by molecuilder.*' $file ${abs_top_srcdir}/${AUTOTEST_PATH}/regression/Simple_configuration/5/post/$file], 0, [ignore], [ignore]) 68 AT_CLEANUP 69 70 # 6. test some more configuration that all desire parameters and count how many complain 71 AT_SETUP([Simple configuration - invalid commands on empty configs]) 72 AT_CHECK([../../molecuilder empty.conf -e ${abs_top_srcdir}/src/ -t -s -b -E -c -b -a -U -T -u], 255, [ignore], [stderr]) 73 AT_CHECK([fgrep -c "Not enough or invalid" stderr], 0, [1 74 ], [ignore]) 75 AT_CLEANUP 76 77 # 7. test some more configuration that all need parameters and count how many complain 78 AT_SETUP([Simple configuration - invalid commands on present configs]) 79 AT_CHECK([/bin/cp -f ${abs_top_srcdir}/${AUTOTEST_PATH}/regression/Simple_configuration/7/pre/test.conf .], 0) 80 AT_CHECK([../../molecuilder test.conf -e ${abs_top_srcdir}/src/ -t -s -b -E -c -b -a -U -T -u], 255, [ignore], [stderr]) 81 AT_CHECK([fgrep -c "Not enough or invalid" stderr], 0, [9 82 ], [ignore]) 83 AT_CLEANUP 84 85 86 AT_BANNER([MoleCuilder - Graph routines test]) 87 AT_KEYWORDS([graph]) 88 AT_SETUP([Graph - DFS analysis]) 89 AT_CHECK([/bin/cp -f ${abs_top_srcdir}/${AUTOTEST_PATH}/regression/Graph/1/pre/test.conf .], 0) 90 AT_CHECK([../../molecuilder test.conf -e ${abs_top_srcdir}/src/ -D 2.], 0, [stdout], [stderr]) 91 AT_CHECK([fgrep -c "No rings were detected in the molecular structure." stdout], 0, [1 47 92 ], [ignore]) 48 93 AT_CLEANUP 49 94 50 95 AT_BANNER([MoleCuilder - Fragmentation and Re-fragmentation test]) 51 AT_SETUP([Fragmentation]) 52 # 1. create a fake element database with the only two elements we need 53 AT_DATA([elements.db],[# Covalent radius of each element in Angstroem from CSD (binding is: [Rcov(A)+Rcov(B)-t,Rcov(A)+Rcov(B)+t] with t = 0.4A 54 #Element Name Symbol Period Group Block Atomic Number AtomicWeight Covalent Radius vdW Radius 55 Hydrogen H 1 1 s 1 1.008 0.23 1.09 56 Carbon C 2 14 p 6 12.011 0.68 1.70 57 ]) 58 # 2. create molecular geometry 59 AT_DATA([test.xyz], [[11 60 # test configuration, created by molecuilder test suite 61 C 9.782085945 3.275186040 3.535886037 62 C 8.532785963 4.158586027 3.535886037 63 C 7.283585982 3.275186040 3.535886037 64 H 9.782085945 2.645886050 2.645886050 65 H 9.782085945 2.645886050 4.425886024 66 H 10.672039608 3.904536878 3.535886037 67 H 8.532785963 4.787886018 2.645886050 68 H 8.532785963 4.787886018 4.425886024 69 H 6.393632318 3.904536877 3.535886037 70 H 7.283585982 2.645886050 2.645886050 71 H 7.283585982 2.645886050 4.425886024 72 ]]) 73 # 3. make sure config is empty and not remnant from last test with broken dirs 74 AT_DATA([test.conf], []) 75 # 4. create the config and check it 76 AT_CHECK([../../molecuilder test.conf -e ./ -p test.xyz], 0, [ignore], [ignore]) 77 AT_CHECK([fgrep "Ion_Type1_4" test.conf], 0, [Ion_Type1_4 8.532785963 4.787886018 2.645886050 0 # Number in molecule 6 96 AT_KEYWORDS([fragmentation]) 97 # 1. check config 98 AT_SETUP([Fragmentation - Checking present config]) 99 AT_CHECK([/bin/cp -f ${abs_top_srcdir}/${AUTOTEST_PATH}/regression/Fragmentation/1/pre/test.conf .], 0) 100 AT_CHECK([fgrep "Ion_Type1_4" test.conf], 0, [Ion_Type1_4 8.532785963 4.787886018 2.645886050 0 # molecule nr 6 78 101 ], [ignore]) 79 102 AT_CHECK([fgrep "Ion_Type2_4" test.conf], 1, [ignore], [ignore]) 80 # 5. fragment the molecule and check the number of configs 81 AT_CHECK([../../molecuilder test.conf -e ./ -f 1.55 2], 0, [ignore], [ignore], [mkdir std; mv BondFragment*.conf* std/]) 103 AT_CLEANUP 104 # 2. fragment the molecule and check the number of configs 105 AT_SETUP([Fragmentation - Fragmentation]) 106 AT_CHECK([/bin/cp -f ${abs_top_srcdir}/${AUTOTEST_PATH}/regression/Fragmentation/2/pre/test.conf .], 0) 107 AT_CHECK([../../molecuilder test.conf -e ${abs_top_srcdir}/src/ -f 1.55 2], 0, [ignore], [ignore], [mkdir std; mv BondFragment*.conf* std/]) 82 108 AT_CHECK([mkdir std; mv BondFragment*.conf* std/], 0) 83 109 AT_CHECK([ls -l std/BondFragment*.conf | wc -l], 0, [5 84 110 ], [ignore]) 85 # 3a. check whether parsing of BondFragment files and re-rwriting config files is working (exit code is 2 as we don't need to continue wrt to ...OrderAtSite) 86 AT_CHECK([../../molecuilder test.conf -e ./ -f 1.55 2], 2, [ignore], [ignore], [mkdir new; mv BondFragment*.conf* new/]) 111 AT_CLEANUP 112 # 3. check whether parsing of BondFragment files and re-rwriting config files is working (exit code is 2 as we don't need to continue wrt to ...OrderAtSite) 113 AT_SETUP([Fragmentation - Fragmentation is at MaxOrder]) 114 AT_CHECK([/bin/cp -f ${abs_top_srcdir}/${AUTOTEST_PATH}/regression/Fragmentation/3/pre/* .], 0) 115 AT_CHECK([../../molecuilder test.conf -e ${abs_top_srcdir}/src/ -f 1.55 2], 2, [ignore], [ignore], [mkdir new; mv BondFragment*.conf* new/]) 87 116 AT_CHECK([mkdir new; mv BondFragment*.conf* new/], 0) 88 # 6. compare both dirs by diff'ing89 AT_CHECK([diff -I '.*Created by molecuilder.*' std/ new/], 0, [], [])90 117 AT_CLEANUP 91 118 119 120 AT_BANNER([MoleCuilder - Tesselation test]) 121 AT_KEYWORDS([Tesselation]) 122 # 1. Non convex tesselation 123 AT_SETUP([Tesselation - Non-Convex Envelope]) 124 AT_CHECK([/bin/cp -f ${abs_top_srcdir}/${AUTOTEST_PATH}/regression/Tesselation/1/pre/* .], 0) 125 AT_CHECK([../../molecuilder test.conf -e ${abs_top_srcdir}/src/ -N 4. NonConvexEnvelope], 0, [stdout], [stderr]) 126 AT_CHECK([file=NonConvexEnvelope.dat; diff $file ${abs_top_srcdir}/${AUTOTEST_PATH}/regression/Tesselation/1/post/$file], 0, [ignore], [ignore]) 127 AT_CHECK([file=NonConvexEnvelope.r3d; diff $file ${abs_top_srcdir}/${AUTOTEST_PATH}/regression/Tesselation/1/post/$file], 0, [ignore], [ignore]) 128 AT_CLEANUP 129 130 # 2. convex tesselation (where the non-convex is already convex) 131 AT_SETUP([Tesselation - Convex Envelope]) 132 AT_CHECK([/bin/cp -f ${abs_top_srcdir}/${AUTOTEST_PATH}/regression/Tesselation/2/pre/* .], 0) 133 AT_CHECK([../../molecuilder test.conf -e ${abs_top_srcdir}/src/ -o ConvexEnvelope NonConvexEnvelope], 0, [stdout], [stderr]) 134 AT_CHECK([file=ConvexEnvelope.dat; diff $file ${abs_top_srcdir}/${AUTOTEST_PATH}/regression/Tesselation/2/post/$file], 0, [ignore], [ignore]) 135 AT_CHECK([file=ConvexEnvelope.r3d; diff $file ${abs_top_srcdir}/${AUTOTEST_PATH}/regression/Tesselation/2/post/$file], 0, [ignore], [ignore]) 136 AT_CHECK([fgrep "RESULT: The summed volume is 16.401577 angstrom^3" stdout], 0, [ignore], [ignore]) 137 AT_CHECK([diff ConvexEnvelope.dat NonConvexEnvelope.dat], 0, [ignore], [ignore]) 138 AT_CLEANUP 139 140 # 3. Big Non convex tesselation 141 AT_SETUP([Tesselation - Big non-Convex Envelope]) 142 AT_CHECK([/bin/cp -f ${abs_top_srcdir}/${AUTOTEST_PATH}/regression/Tesselation/3/pre/* .], 0) 143 AT_CHECK([../../molecuilder test.conf -e ${abs_top_srcdir}/src/ -N 4. NonConvexEnvelope], 0, [stdout], [stderr]) 144 AT_CHECK([file=NonConvexEnvelope.dat; diff $file ${abs_top_srcdir}/${AUTOTEST_PATH}/regression/Tesselation/3/post/$file], 0, [ignore], [ignore]) 145 AT_CHECK([file=NonConvexEnvelope.r3d; diff $file ${abs_top_srcdir}/${AUTOTEST_PATH}/regression/Tesselation/3/post/$file], 0, [ignore], [ignore]) 146 AT_CLEANUP 147 148 # 4. Big convex tesselation - is not working yet 149 #AT_SETUP([Tesselation - big convex Envelope]) 150 #AT_CHECK([/bin/cp -f ${abs_top_srcdir}/${AUTOTEST_PATH}/regression/Tesselation/4/pre/* .], 0) 151 #AT_CHECK([../../molecuilder test.conf -e ${abs_top_srcdir}/src/ -o ConvexEnvelope NonConvexEnvelope], 0, [stdout], [stderr]) 152 #AT_CHECK([file=ConvexEnvelope.dat; diff $file ${abs_top_srcdir}/${AUTOTEST_PATH}/regression/Tesselation/4/post/$file], 0, [ignore], [ignore]) 153 #AT_CHECK([file=ConvexEnvelope.r3d; diff $file ${abs_top_srcdir}/${AUTOTEST_PATH}/regression/Tesselation/4/post/$file], 0, [ignore], [ignore]) 154 #AT_CHECK([fgrep "RESULT: The summed volume is 16.401577 angstrom^3" stdout], 0, [ignore], [ignore]) 155 #AT_CLEANUP 156
Note:
See TracChangeset
for help on using the changeset viewer.