Changes in src/boundary.cpp [b5c2d7:4fc93f]
- File:
-
- 1 edited
-
src/boundary.cpp (modified) (32 diffs, 1 prop)
Legend:
- Unmodified
- Added
- Removed
-
src/boundary.cpp
-
Property mode
changed from
100644to100755
rb5c2d7 r4fc93f 17 17 #include "tesselation.hpp" 18 18 #include "tesselationhelpers.hpp" 19 #include "World.hpp"20 19 21 20 #include<gsl/gsl_poly.h> 22 #include<time.h>23 21 24 22 // ========================================== F U N C T I O N S ================================= … … 57 55 } else { 58 56 BoundaryPoints = BoundaryPtr; 59 DoLog(0) && (Log() << Verbose(0) << "Using given boundary points set." << endl);57 Log() << Verbose(0) << "Using given boundary points set." << endl; 60 58 } 61 59 // determine biggest "diameter" of cluster for each axis … … 163 161 AngleReferenceNormalVector.x[(axis + 2) % NDIM] = 1.; 164 162 165 DoLog(1) && (Log() << Verbose(1) << "Axisvector is " << AxisVector << " and AngleReferenceVector is " << AngleReferenceVector << ", and AngleReferenceNormalVector is " << AngleReferenceNormalVector << "." << endl);163 Log() << Verbose(1) << "Axisvector is " << AxisVector << " and AngleReferenceVector is " << AngleReferenceVector << ", and AngleReferenceNormalVector is " << AngleReferenceNormalVector << "." << endl; 166 164 167 165 // 3b. construct set of all points, transformed into cylindrical system and with left and right neighbours … … 184 182 angle = 2. * M_PI - angle; 185 183 } 186 DoLog(1) && (Log() << Verbose(1) << "Inserting " << *Walker << ": (r, alpha) = (" << radius << "," << angle << "): " << ProjectedVector << endl);184 Log() << Verbose(1) << "Inserting " << *Walker << ": (r, alpha) = (" << radius << "," << angle << "): " << ProjectedVector << endl; 187 185 BoundaryTestPair = BoundaryPoints[axis].insert(BoundariesPair(angle, DistancePair (radius, Walker))); 188 186 if (!BoundaryTestPair.second) { // same point exists, check first r, then distance of original vectors to center of gravity 189 DoLog(2) && (Log() << Verbose(2) << "Encountered two vectors whose projection onto axis " << axis << " is equal: " << endl);190 DoLog(2) && (Log() << Verbose(2) << "Present vector: " << *BoundaryTestPair.first->second.second << endl);191 DoLog(2) && (Log() << Verbose(2) << "New vector: " << *Walker << endl);187 Log() << Verbose(2) << "Encountered two vectors whose projection onto axis " << axis << " is equal: " << endl; 188 Log() << Verbose(2) << "Present vector: " << *BoundaryTestPair.first->second.second << endl; 189 Log() << Verbose(2) << "New vector: " << *Walker << endl; 192 190 const double ProjectedVectorNorm = ProjectedVector.NormSquared(); 193 191 if ((ProjectedVectorNorm - BoundaryTestPair.first->second.first) > MYEPSILON) { 194 192 BoundaryTestPair.first->second.first = ProjectedVectorNorm; 195 193 BoundaryTestPair.first->second.second = Walker; 196 DoLog(2) && (Log() << Verbose(2) << "Keeping new vector due to larger projected distance " << ProjectedVectorNorm << "." << endl);194 Log() << Verbose(2) << "Keeping new vector due to larger projected distance " << ProjectedVectorNorm << "." << endl; 197 195 } else if (fabs(ProjectedVectorNorm - BoundaryTestPair.first->second.first) < MYEPSILON) { 198 196 helper.CopyVector(&Walker->x); … … 203 201 if (helper.NormSquared() < oldhelperNorm) { 204 202 BoundaryTestPair.first->second.second = Walker; 205 DoLog(2) && (Log() << Verbose(2) << "Keeping new vector due to larger distance to molecule center " << helper.NormSquared() << "." << endl);203 Log() << Verbose(2) << "Keeping new vector due to larger distance to molecule center " << helper.NormSquared() << "." << endl; 206 204 } else { 207 DoLog(2) && (Log() << Verbose(2) << "Keeping present vector due to larger distance to molecule center " << oldhelperNorm << "." << endl);205 Log() << Verbose(2) << "Keeping present vector due to larger distance to molecule center " << oldhelperNorm << "." << endl; 208 206 } 209 207 } else { 210 DoLog(2) && (Log() << Verbose(2) << "Keeping present vector due to larger projected distance " << ProjectedVectorNorm << "." << endl);208 Log() << Verbose(2) << "Keeping present vector due to larger projected distance " << ProjectedVectorNorm << "." << endl; 211 209 } 212 210 } … … 227 225 // 3c. throw out points whose distance is less than the mean of left and right neighbours 228 226 bool flag = false; 229 DoLog(1) && (Log() << Verbose(1) << "Looking for candidates to kick out by convex condition ... " << endl);227 Log() << Verbose(1) << "Looking for candidates to kick out by convex condition ... " << endl; 230 228 do { // do as long as we still throw one out per round 231 229 flag = false; … … 282 280 const double MinDistance = a * sin(beta) / (sin(delta)) * (((alpha < M_PI / 2.) || (gamma < M_PI / 2.)) ? 1. : -1.); 283 281 //Log() << Verbose(1) << " I calculated: a = " << a << ", h = " << h << ", beta(" << left->second.second->Name << "," << left->second.second->Name << "-" << right->second.second->Name << ") = " << beta << ", delta(" << left->second.second->Name << "," << runner->second.second->Name << ") = " << delta << ", Min = " << MinDistance << "." << endl; 284 DoLog(1) && (Log() << Verbose(1) << "Checking CoG distance of runner " << *runner->second.second << " " << h << " against triangle's side length spanned by (" << *left->second.second << "," << *right->second.second << ") of " << MinDistance << "." << endl);282 Log() << Verbose(1) << "Checking CoG distance of runner " << *runner->second.second << " " << h << " against triangle's side length spanned by (" << *left->second.second << "," << *right->second.second << ") of " << MinDistance << "." << endl; 285 283 if ((fabs(h / fabs(h) - MinDistance / fabs(MinDistance)) < MYEPSILON) && ((h - MinDistance)) < -MYEPSILON) { 286 284 // throw out point 287 DoLog(1) && (Log() << Verbose(1) << "Throwing out " << *runner->second.second << "." << endl);285 Log() << Verbose(1) << "Throwing out " << *runner->second.second << "." << endl; 288 286 BoundaryPoints[axis].erase(runner); 289 287 flag = true; … … 320 318 BoundaryPoints = GetBoundaryPoints(mol, TesselStruct); 321 319 } else { 322 DoLog(0) && (Log() << Verbose(0) << "Using given boundary points set." << endl);320 Log() << Verbose(0) << "Using given boundary points set." << endl; 323 321 } 324 322 … … 326 324 for (int axis=0; axis < NDIM; axis++) 327 325 { 328 DoLog(1) && (Log() << Verbose(1) << "Printing list of candidates for axis " << axis << " which we have inserted so far." << endl);326 Log() << Verbose(1) << "Printing list of candidates for axis " << axis << " which we have inserted so far." << endl; 329 327 int i=0; 330 328 for(Boundaries::iterator runner = BoundaryPoints[axis].begin(); runner != BoundaryPoints[axis].end(); runner++) { 331 329 if (runner != BoundaryPoints[axis].begin()) 332 DoLog(0) && (Log() << Verbose(0) << ", " << i << ": " << *runner->second.second);330 Log() << Verbose(0) << ", " << i << ": " << *runner->second.second; 333 331 else 334 DoLog(0) && (Log() << Verbose(0) << i << ": " << *runner->second.second);332 Log() << Verbose(0) << i << ": " << *runner->second.second; 335 333 i++; 336 334 } 337 DoLog(0) && (Log() << Verbose(0) << endl);335 Log() << Verbose(0) << endl; 338 336 } 339 337 … … 342 340 for (Boundaries::iterator runner = BoundaryPoints[axis].begin(); runner != BoundaryPoints[axis].end(); runner++) 343 341 if (!TesselStruct->AddBoundaryPoint(runner->second.second, 0)) 344 DoeLog(2) && (eLog()<< Verbose(2) << "Point " << *(runner->second.second) << " is already present!" << endl);345 346 DoLog(0) && (Log() << Verbose(0) << "I found " << TesselStruct->PointsOnBoundaryCount << " points on the convex boundary." << endl);342 eLog() << Verbose(2) << "Point " << *(runner->second.second) << " is already present!" << endl; 343 344 Log() << Verbose(0) << "I found " << TesselStruct->PointsOnBoundaryCount << " points on the convex boundary." << endl; 347 345 // now we have the whole set of edge points in the BoundaryList 348 346 … … 362 360 // 3c. check whether all atoms lay inside the boundary, if not, add to boundary points, segment triangle into three with the new point 363 361 if (!TesselStruct->InsertStraddlingPoints(mol, LCList)) 364 DoeLog(1) && (eLog()<< Verbose(1) << "Insertion of straddling points failed!" << endl);365 366 DoLog(0) && (Log() << Verbose(0) << "I created " << TesselStruct->TrianglesOnBoundary.size() << " intermediate triangles with " << TesselStruct->LinesOnBoundary.size() << " lines and " << TesselStruct->PointsOnBoundary.size() << " points." << endl);362 eLog() << Verbose(1) << "Insertion of straddling points failed!" << endl; 363 364 Log() << Verbose(0) << "I created " << TesselStruct->TrianglesOnBoundary.size() << " intermediate triangles with " << TesselStruct->LinesOnBoundary.size() << " lines and " << TesselStruct->PointsOnBoundary.size() << " points." << endl; 367 365 368 366 // 4. Store triangles in tecplot file … … 395 393 for (LineMap::iterator LineRunner = TesselStruct->LinesOnBoundary.begin(); LineRunner != TesselStruct->LinesOnBoundary.end(); LineRunner++) { 396 394 line = LineRunner->second; 397 DoLog(1) && (Log() << Verbose(1) << "INFO: Current line is " << *line << "." << endl);395 Log() << Verbose(1) << "INFO: Current line is " << *line << "." << endl; 398 396 if (!line->CheckConvexityCriterion()) { 399 DoLog(1) && (Log() << Verbose(1) << "... line " << *line << " is concave, flipping it." << endl);397 Log() << Verbose(1) << "... line " << *line << " is concave, flipping it." << endl; 400 398 401 399 // flip the line 402 400 if (TesselStruct->PickFarthestofTwoBaselines(line) == 0.) 403 DoeLog(1) && (eLog()<< Verbose(1) << "Correction of concave baselines failed!" << endl);401 eLog() << Verbose(1) << "Correction of concave baselines failed!" << endl; 404 402 else { 405 403 TesselStruct->FlipBaseline(line); 406 DoLog(1) && (Log() << Verbose(1) << "INFO: Correction of concave baselines worked." << endl);404 Log() << Verbose(1) << "INFO: Correction of concave baselines worked." << endl; 407 405 } 408 406 } … … 414 412 // Log() << Verbose(1) << "Correction of concave tesselpoints failed!" << endl; 415 413 416 DoLog(0) && (Log() << Verbose(0) << "I created " << TesselStruct->TrianglesOnBoundary.size() << " triangles with " << TesselStruct->LinesOnBoundary.size() << " lines and " << TesselStruct->PointsOnBoundary.size() << " points." << endl);414 Log() << Verbose(0) << "I created " << TesselStruct->TrianglesOnBoundary.size() << " triangles with " << TesselStruct->LinesOnBoundary.size() << " lines and " << TesselStruct->PointsOnBoundary.size() << " points." << endl; 417 415 418 416 // 4. Store triangles in tecplot file … … 456 454 457 455 if ((TesselStruct == NULL) || (TesselStruct->PointsOnBoundary.empty())) { 458 DoeLog(1) && (eLog()<< Verbose(1) << "TesselStruct is empty." << endl);456 eLog() << Verbose(1) << "TesselStruct is empty." << endl; 459 457 return false; 460 458 } … … 462 460 PointMap::iterator PointRunner; 463 461 while (!TesselStruct->PointsOnBoundary.empty()) { 464 DoLog(1) && (Log() << Verbose(1) << "Remaining points are: ");462 Log() << Verbose(1) << "Remaining points are: "; 465 463 for (PointMap::iterator PointSprinter = TesselStruct->PointsOnBoundary.begin(); PointSprinter != TesselStruct->PointsOnBoundary.end(); PointSprinter++) 466 DoLog(0) && (Log() << Verbose(0) << *(PointSprinter->second) << "\t");467 DoLog(0) && (Log() << Verbose(0) << endl);464 Log() << Verbose(0) << *(PointSprinter->second) << "\t"; 465 Log() << Verbose(0) << endl; 468 466 469 467 PointRunner = TesselStruct->PointsOnBoundary.begin(); … … 521 519 // check whether there is something to work on 522 520 if (TesselStruct == NULL) { 523 DoeLog(1) && (eLog()<< Verbose(1) << "TesselStruct is empty!" << endl);521 eLog() << Verbose(1) << "TesselStruct is empty!" << endl; 524 522 return volume; 525 523 } … … 537 535 PointAdvance++; 538 536 point = PointRunner->second; 539 DoLog(1) && (Log() << Verbose(1) << "INFO: Current point is " << *point << "." << endl);537 Log() << Verbose(1) << "INFO: Current point is " << *point << "." << endl; 540 538 for (LineMap::iterator LineRunner = point->lines.begin(); LineRunner != point->lines.end(); LineRunner++) { 541 539 line = LineRunner->second; 542 DoLog(1) && (Log() << Verbose(1) << "INFO: Current line of point " << *point << " is " << *line << "." << endl);540 Log() << Verbose(1) << "INFO: Current line of point " << *point << " is " << *line << "." << endl; 543 541 if (!line->CheckConvexityCriterion()) { 544 542 // remove the point if needed 545 DoLog(1) && (Log() << Verbose(1) << "... point " << *point << " cannot be on convex envelope." << endl);543 Log() << Verbose(1) << "... point " << *point << " cannot be on convex envelope." << endl; 546 544 volume += TesselStruct->RemovePointFromTesselatedSurface(point); 547 545 sprintf(dummy, "-first-%d", ++run); … … 564 562 LineAdvance++; 565 563 line = LineRunner->second; 566 DoLog(1) && (Log() << Verbose(1) << "INFO: Picking farthest baseline for line is " << *line << "." << endl);564 Log() << Verbose(1) << "INFO: Picking farthest baseline for line is " << *line << "." << endl; 567 565 // take highest of both lines 568 566 if (TesselStruct->IsConvexRectangle(line) == NULL) { … … 605 603 606 604 // end 607 DoLog(0) && (Log() << Verbose(0) << "Volume is " << volume << "." << endl);605 Log() << Verbose(0) << "Volume is " << volume << "." << endl; 608 606 return volume; 609 607 }; … … 656 654 * \param *out output stream for debugging 657 655 * \param *mol molecule with atoms and bonds 658 * \param * TesselStruct Tesselation with boundary triangles656 * \param *&TesselStruct Tesselation with boundary triangles 659 657 * \param *filename prefix of filename 660 658 * \param *extraSuffix intermediate suffix 661 659 */ 662 void StoreTrianglesinFile(const molecule * const mol, const Tesselation * constTesselStruct, const char *filename, const char *extraSuffix)660 void StoreTrianglesinFile(const molecule * const mol, const Tesselation *&TesselStruct, const char *filename, const char *extraSuffix) 663 661 { 664 662 Info FunctionInfo(__func__); … … 734 732 totalmass += Walker->type->mass; 735 733 } 736 DoLog(0) && (Log() << Verbose(0) << "RESULT: The summed mass is " << setprecision(10) << totalmass << " atomicmassunit." << endl);737 DoLog(0) && (Log() << Verbose(0) << "RESULT: The average density is " << setprecision(10) << totalmass / clustervolume << " atomicmassunit/" << (IsAngstroem ? "angstrom" : "atomiclength") << "^3." << endl);734 Log() << Verbose(0) << "RESULT: The summed mass is " << setprecision(10) << totalmass << " atomicmassunit." << endl; 735 Log() << Verbose(0) << "RESULT: The average density is " << setprecision(10) << totalmass / clustervolume << " atomicmassunit/" << (IsAngstroem ? "angstrom" : "atomiclength") << "^3." << endl; 738 736 739 737 // solve cubic polynomial 740 DoLog(1) && (Log() << Verbose(1) << "Solving equidistant suspension in water problem ..." << endl);738 Log() << Verbose(1) << "Solving equidistant suspension in water problem ..." << endl; 741 739 if (IsAngstroem) 742 740 cellvolume = (TotalNoClusters * totalmass / SOLVENTDENSITY_A - (totalmass / clustervolume)) / (celldensity - 1); 743 741 else 744 742 cellvolume = (TotalNoClusters * totalmass / SOLVENTDENSITY_a0 - (totalmass / clustervolume)) / (celldensity - 1); 745 DoLog(1) && (Log() << Verbose(1) << "Cellvolume needed for a density of " << celldensity << " g/cm^3 is " << cellvolume << " " << (IsAngstroem ? "angstrom" : "atomiclength") << "^3." << endl);743 Log() << Verbose(1) << "Cellvolume needed for a density of " << celldensity << " g/cm^3 is " << cellvolume << " " << (IsAngstroem ? "angstrom" : "atomiclength") << "^3." << endl; 746 744 747 745 double minimumvolume = TotalNoClusters * (GreatestDiameter[0] * GreatestDiameter[1] * GreatestDiameter[2]); 748 DoLog(1) && (Log() << Verbose(1) << "Minimum volume of the convex envelope contained in a rectangular box is " << minimumvolume << " atomicmassunit/" << (IsAngstroem ? "angstrom" : "atomiclength") << "^3." << endl);746 Log() << Verbose(1) << "Minimum volume of the convex envelope contained in a rectangular box is " << minimumvolume << " atomicmassunit/" << (IsAngstroem ? "angstrom" : "atomiclength") << "^3." << endl; 749 747 if (minimumvolume > cellvolume) { 750 DoeLog(1) && (eLog()<< Verbose(1) << "the containing box already has a greater volume than the envisaged cell volume!" << endl);751 DoLog(0) && (Log() << Verbose(0) << "Setting Box dimensions to minimum possible, the greatest diameters." << endl);748 eLog() << Verbose(1) << "the containing box already has a greater volume than the envisaged cell volume!" << endl; 749 Log() << Verbose(0) << "Setting Box dimensions to minimum possible, the greatest diameters." << endl; 752 750 for (int i = 0; i < NDIM; i++) 753 751 BoxLengths.x[i] = GreatestDiameter[i]; … … 761 759 double x2 = 0.; 762 760 if (gsl_poly_solve_cubic(BoxLengths.x[0], BoxLengths.x[1], BoxLengths.x[2], &x0, &x1, &x2) == 1) // either 1 or 3 on return 763 DoLog(0) && (Log() << Verbose(0) << "RESULT: The resulting spacing is: " << x0 << " ." << endl);761 Log() << Verbose(0) << "RESULT: The resulting spacing is: " << x0 << " ." << endl; 764 762 else { 765 DoLog(0) && (Log() << Verbose(0) << "RESULT: The resulting spacings are: " << x0 << " and " << x1 << " and " << x2 << " ." << endl);763 Log() << Verbose(0) << "RESULT: The resulting spacings are: " << x0 << " and " << x1 << " and " << x2 << " ." << endl; 766 764 x0 = x2; // sorted in ascending order 767 765 } … … 774 772 775 773 // set new box dimensions 776 DoLog(0) && (Log() << Verbose(0) << "Translating to box with these boundaries." << endl);774 Log() << Verbose(0) << "Translating to box with these boundaries." << endl; 777 775 mol->SetBoxDimension(&BoxLengths); 778 776 mol->CenterInBox(); … … 780 778 // update Box of atoms by boundary 781 779 mol->SetBoxDimension(&BoxLengths); 782 DoLog(0) && (Log() << Verbose(0) << "RESULT: The resulting cell dimensions are: " << BoxLengths.x[0] << " and " << BoxLengths.x[1] << " and " << BoxLengths.x[2] << " with total volume of " << cellvolume << " " << (IsAngstroem ? "angstrom" : "atomiclength") << "^3." << endl);780 Log() << Verbose(0) << "RESULT: The resulting cell dimensions are: " << BoxLengths.x[0] << " and " << BoxLengths.x[1] << " and " << BoxLengths.x[2] << " with total volume of " << cellvolume << " " << (IsAngstroem ? "angstrom" : "atomiclength") << "^3." << endl; 783 781 }; 784 782 … … 790 788 * \param *filler molecule which the box is to be filled with 791 789 * \param configuration contains box dimensions 792 * \param MaxDistance fills in molecules only up to this distance (set to -1 if whole of the domain)793 790 * \param distance[NDIM] distance between filling molecules in each direction 794 * \param boundary length of boundary zone between molecule and filling mollecules795 * \param epsilon distance to surface which is not filled796 791 * \param RandAtomDisplacement maximum distance for random displacement per atom 797 792 * \param RandMolDisplacement maximum distance for random displacement per filler molecule … … 799 794 * \return *mol pointer to new molecule with filled atoms 800 795 */ 801 molecule * FillBoxWithMolecule(MoleculeListClass *List, molecule *filler, config &configuration, const double MaxDistance, const double distance[NDIM], const double boundary, const double RandomAtomDisplacement, const double RandomMolDisplacement, constbool DoRandomRotation)796 molecule * FillBoxWithMolecule(MoleculeListClass *List, molecule *filler, config &configuration, double distance[NDIM], double RandomAtomDisplacement, double RandomMolDisplacement, bool DoRandomRotation) 802 797 { 803 798 Info FunctionInfo(__func__); … … 806 801 int N[NDIM]; 807 802 int n[NDIM]; 808 double *M = ReturnFullMatrixforSymmetric( World::get()->cell_size);803 double *M = ReturnFullMatrixforSymmetric(filler->cell_size); 809 804 double Rotations[NDIM*NDIM]; 810 double *MInverse = InverseMatrix(M);811 805 Vector AtomTranslations; 812 806 Vector FillerTranslations; 813 807 Vector FillerDistance; 814 Vector Inserter;815 808 double FillIt = false; 816 809 atom *Walker = NULL; 817 810 bond *Binder = NULL; 811 int i = 0; 812 LinkedCell *LCList[List->ListOfMolecules.size()]; 818 813 double phi[NDIM]; 819 map<molecule *, Tesselation *> TesselStruct; 820 map<molecule *, LinkedCell *> LCList; 821 822 for (MoleculeList::iterator ListRunner = List->ListOfMolecules.begin(); ListRunner != List->ListOfMolecules.end(); ListRunner++) 823 if ((*ListRunner)->AtomCount > 0) { 824 DoLog(1) && (Log() << Verbose(1) << "Pre-creating linked cell lists for molecule " << *ListRunner << "." << endl); 825 LCList[(*ListRunner)] = new LinkedCell((*ListRunner), 10.); // get linked cell list 826 DoLog(1) && (Log() << Verbose(1) << "Pre-creating tesselation for molecule " << *ListRunner << "." << endl); 827 TesselStruct[(*ListRunner)] = NULL; 828 FindNonConvexBorder((*ListRunner), TesselStruct[(*ListRunner)], (const LinkedCell *&)LCList[(*ListRunner)], 5., NULL); 829 } 814 class Tesselation *TesselStruct[List->ListOfMolecules.size()]; 815 816 i=0; 817 for (MoleculeList::iterator ListRunner = List->ListOfMolecules.begin(); ListRunner != List->ListOfMolecules.end(); ListRunner++) { 818 Log() << Verbose(1) << "Pre-creating linked cell lists for molecule " << *ListRunner << "." << endl; 819 LCList[i] = new LinkedCell((*ListRunner), 5.); // get linked cell list 820 if (TesselStruct[i] == NULL) { 821 Log() << Verbose(1) << "Pre-creating tesselation for molecule " << *ListRunner << "." << endl; 822 FindNonConvexBorder((*ListRunner), TesselStruct[i], (const LinkedCell *&)LCList[i], 5., NULL); 823 } 824 i++; 825 } 830 826 831 827 // Center filler at origin 832 filler->Center Edge(&Inserter);828 filler->CenterOrigin(); 833 829 filler->Center.Zero(); 834 DoLog(2) && (Log() << Verbose(2) << "INFO: Filler molecule has the following bonds:" << endl);835 Binder = filler->first;836 while(Binder->next != filler->last) {837 Binder = Binder->next;838 DoLog(2) && (Log() << Verbose(2) << " " << *Binder << endl);839 }840 830 841 831 filler->CountAtoms(); … … 845 835 FillerDistance.Init(distance[0], distance[1], distance[2]); 846 836 FillerDistance.InverseMatrixMultiplication(M); 847 for(int i=0;i<NDIM;i++) 837 Log() << Verbose(1) << "INFO: Grid steps are "; 838 for(int i=0;i<NDIM;i++) { 848 839 N[i] = (int) ceil(1./FillerDistance.x[i]); 849 DoLog(1) && (Log() << Verbose(1) << "INFO: Grid steps are " << N[0] << ", " << N[1] << ", " << N[2] << "." << endl); 850 851 // initialize seed of random number generator to current time 852 srand ( time(NULL) ); 840 Log() << Verbose(1) << N[i]; 841 if (i != NDIM-1) 842 Log() << Verbose(1)<< ", "; 843 else 844 Log() << Verbose(1) << "." << endl; 845 } 853 846 854 847 // go over [0,1]^3 filler grid … … 859 852 CurrentPosition.Init((double)n[0]/(double)N[0], (double)n[1]/(double)N[1], (double)n[2]/(double)N[2]); 860 853 CurrentPosition.MatrixMultiplication(M); 861 // create molecule random translation vector ... 862 for (int i=0;i<NDIM;i++) 863 FillerTranslations.x[i] = RandomMolDisplacement*(rand()/(RAND_MAX/2.) - 1.); 864 DoLog(2) && (Log() << Verbose(2) << "INFO: Current Position is " << CurrentPosition << "+" << FillerTranslations << "." << endl); 865 866 // go through all atoms 867 for (int i=0;i<filler->AtomCount;i++) 868 CopyAtoms[i] = NULL; 869 Walker = filler->start; 870 while (Walker->next != filler->end) { 871 Walker = Walker->next; 872 873 // create atomic random translation vector ... 854 Log() << Verbose(2) << "INFO: Current Position is " << CurrentPosition << "." << endl; 855 // Check whether point is in- or outside 856 FillIt = true; 857 i=0; 858 for (MoleculeList::iterator ListRunner = List->ListOfMolecules.begin(); ListRunner != List->ListOfMolecules.end(); ListRunner++) { 859 // get linked cell list 860 if (TesselStruct[i] == NULL) { 861 eLog() << Verbose(1) << "TesselStruct of " << (*ListRunner) << " is NULL. Didn't we pre-create it?" << endl; 862 FillIt = false; 863 } else { 864 FillIt = FillIt && (!TesselStruct[i]->IsInnerPoint(CurrentPosition, LCList[i])); 865 i++; 866 } 867 } 868 869 if (FillIt) { 870 // fill in Filler 871 Log() << Verbose(2) << "Space at " << CurrentPosition << " is unoccupied by any molecule, filling in." << endl; 872 873 // create molecule random translation vector ... 874 874 for (int i=0;i<NDIM;i++) 875 AtomTranslations.x[i] = RandomAtomDisplacement*(rand()/(RAND_MAX/2.) - 1.); 876 877 // ... and rotation matrix 878 if (DoRandomRotation) { 879 for (int i=0;i<NDIM;i++) { 880 phi[i] = rand()/(RAND_MAX/(2.*M_PI)); 881 } 882 883 Rotations[0] = cos(phi[0]) *cos(phi[2]) + (sin(phi[0])*sin(phi[1])*sin(phi[2])); 884 Rotations[3] = sin(phi[0]) *cos(phi[2]) - (cos(phi[0])*sin(phi[1])*sin(phi[2])); 885 Rotations[6] = cos(phi[1])*sin(phi[2]) ; 886 Rotations[1] = - sin(phi[0])*cos(phi[1]) ; 887 Rotations[4] = cos(phi[0])*cos(phi[1]) ; 888 Rotations[7] = sin(phi[1]) ; 889 Rotations[3] = - cos(phi[0]) *sin(phi[2]) + (sin(phi[0])*sin(phi[1])*cos(phi[2])); 890 Rotations[5] = - sin(phi[0]) *sin(phi[2]) - (cos(phi[0])*sin(phi[1])*cos(phi[2])); 891 Rotations[8] = cos(phi[1])*cos(phi[2]) ; 892 } 893 894 // ... and put at new position 895 Inserter.CopyVector(&(Walker->x)); 896 if (DoRandomRotation) 897 Inserter.MatrixMultiplication(Rotations); 898 Inserter.AddVector(&AtomTranslations); 899 Inserter.AddVector(&FillerTranslations); 900 Inserter.AddVector(&CurrentPosition); 901 902 // check whether inserter is inside box 903 Inserter.MatrixMultiplication(MInverse); 904 FillIt = true; 905 for (int i=0;i<NDIM;i++) 906 FillIt = FillIt && (Inserter.x[i] >= -MYEPSILON) && ((Inserter.x[i]-1.) <= MYEPSILON); 907 Inserter.MatrixMultiplication(M); 908 909 // Check whether point is in- or outside 910 for (MoleculeList::iterator ListRunner = List->ListOfMolecules.begin(); ListRunner != List->ListOfMolecules.end(); ListRunner++) { 911 // get linked cell list 912 if (TesselStruct[(*ListRunner)] != NULL) { 913 const double distance = (TesselStruct[(*ListRunner)]->GetDistanceToSurface(Inserter, LCList[(*ListRunner)])); 914 FillIt = FillIt && (distance > boundary) && ((MaxDistance < 0) || (MaxDistance > distance)); 915 } 916 } 917 // insert into Filling 918 if (FillIt) { 919 DoLog(1) && (Log() << Verbose(1) << "INFO: Position at " << Inserter << " is outer point." << endl); 875 FillerTranslations.x[i] = RandomMolDisplacement*(rand()/(RAND_MAX/2.) - 1.); 876 Log() << Verbose(2) << "INFO: Translating this filler by " << FillerTranslations << "." << endl; 877 878 // go through all atoms 879 Walker = filler->start; 880 while (Walker->next != filler->end) { 881 Walker = Walker->next; 920 882 // copy atom ... 921 883 CopyAtoms[Walker->nr] = new atom(Walker); 922 CopyAtoms[Walker->nr]->x.CopyVector(&Inserter); 884 885 // create atomic random translation vector ... 886 for (int i=0;i<NDIM;i++) 887 AtomTranslations.x[i] = RandomAtomDisplacement*(rand()/(RAND_MAX/2.) - 1.); 888 889 // ... and rotation matrix 890 if (DoRandomRotation) { 891 for (int i=0;i<NDIM;i++) { 892 phi[i] = rand()/(RAND_MAX/(2.*M_PI)); 893 } 894 895 Rotations[0] = cos(phi[0]) *cos(phi[2]) + (sin(phi[0])*sin(phi[1])*sin(phi[2])); 896 Rotations[3] = sin(phi[0]) *cos(phi[2]) - (cos(phi[0])*sin(phi[1])*sin(phi[2])); 897 Rotations[6] = cos(phi[1])*sin(phi[2]) ; 898 Rotations[1] = - sin(phi[0])*cos(phi[1]) ; 899 Rotations[4] = cos(phi[0])*cos(phi[1]) ; 900 Rotations[7] = sin(phi[1]) ; 901 Rotations[3] = - cos(phi[0]) *sin(phi[2]) + (sin(phi[0])*sin(phi[1])*cos(phi[2])); 902 Rotations[5] = - sin(phi[0]) *sin(phi[2]) - (cos(phi[0])*sin(phi[1])*cos(phi[2])); 903 Rotations[8] = cos(phi[1])*cos(phi[2]) ; 904 } 905 906 // ... and put at new position 907 if (DoRandomRotation) 908 CopyAtoms[Walker->nr]->x.MatrixMultiplication(Rotations); 909 CopyAtoms[Walker->nr]->x.AddVector(&AtomTranslations); 910 CopyAtoms[Walker->nr]->x.AddVector(&FillerTranslations); 911 CopyAtoms[Walker->nr]->x.AddVector(&CurrentPosition); 912 913 // insert into Filling 914 915 // FIXME: gives completely different results if CopyAtoms[..] used instead of Walker, why??? 916 Log() << Verbose(4) << "Filling atom " << *Walker << ", translated to " << AtomTranslations << ", at final position is " << (CopyAtoms[Walker->nr]->x) << "." << endl; 923 917 Filling->AddAtom(CopyAtoms[Walker->nr]); 924 DoLog(4) && (Log() << Verbose(4) << "Filling atom " << *Walker << ", translated to " << AtomTranslations << ", at final position is " << (CopyAtoms[Walker->nr]->x) << "." << endl);925 } else {926 DoLog(1) && (Log() << Verbose(1) << "INFO: Position at " << Inserter << " is inner point, within boundary or outside of MaxDistance." << endl);927 CopyAtoms[Walker->nr] = NULL;928 continue;929 918 } 930 } 931 // go through all bonds and add as well 932 Binder = filler->first; 933 while(Binder->next != filler->last) { 934 Binder = Binder->next; 935 if ((CopyAtoms[Binder->leftatom->nr] != NULL) && (CopyAtoms[Binder->rightatom->nr] != NULL)) { 936 Log() << Verbose(3) << "Adding Bond between " << *CopyAtoms[Binder->leftatom->nr] << " and " << *CopyAtoms[Binder->rightatom->nr]<< "." << endl; 919 920 // go through all bonds and add as well 921 Binder = filler->first; 922 while(Binder->next != filler->last) { 923 Binder = Binder->next; 924 Log() << Verbose(3) << "Adding Bond between " << *CopyAtoms[Binder->leftatom->nr] << " and " << *CopyAtoms[Binder->rightatom->nr]<< "." << endl; 937 925 Filling->AddBond(CopyAtoms[Binder->leftatom->nr], CopyAtoms[Binder->rightatom->nr], Binder->BondDegree); 938 926 } 927 } else { 928 // leave empty 929 Log() << Verbose(2) << "Space at " << CurrentPosition << " is occupied." << endl; 939 930 } 940 931 } 941 932 Free(&M); 942 Free(&MInverse); 943 933 for (size_t i=0;i<List->ListOfMolecules.size();i++) { 934 delete(LCList[i]); 935 delete(TesselStruct[i]); 936 } 944 937 return Filling; 945 938 }; … … 960 953 bool freeLC = false; 961 954 bool status = false; 962 CandidateForTesselation *baseline = NULL; 955 CandidateForTesselation *baseline; 956 LineMap::iterator testline; 963 957 bool OneLoopWithoutSuccessFlag = true; // marks whether we went once through all baselines without finding any without two triangles 964 958 bool TesselationFailFlag = false; 959 BoundaryTriangleSet *T = NULL; 965 960 966 961 if (TesselStruct == NULL) { 967 DoLog(1) && (Log() << Verbose(1) << "Allocating Tesselation struct ..." << endl);962 Log() << Verbose(1) << "Allocating Tesselation struct ..." << endl; 968 963 TesselStruct= new Tesselation; 969 964 } else { 970 965 delete(TesselStruct); 971 DoLog(1) && (Log() << Verbose(1) << "Re-Allocating Tesselation struct ..." << endl);966 Log() << Verbose(1) << "Re-Allocating Tesselation struct ..." << endl; 972 967 TesselStruct = new Tesselation; 973 968 } … … 980 975 981 976 // 1. get starting triangle 982 if (!TesselStruct->FindStartingTriangle(RADIUS, LCList)) { 983 DoeLog(0) && (eLog() << Verbose(0) << "No valid starting triangle found." << endl); 984 //performCriticalExit(); 985 } 986 if (filename != NULL) { 987 if ((DoSingleStepOutput && ((TesselStruct->TrianglesOnBoundary.size() % SingleStepWidth == 0)))) { // if we have a new triangle and want to output each new triangle configuration 988 TesselStruct->Output(filename, mol); 989 } 990 } 977 TesselStruct->FindStartingTriangle(RADIUS, LCList); 991 978 992 979 // 2. expand from there 993 980 while ((!TesselStruct->OpenLines.empty()) && (OneLoopWithoutSuccessFlag)) { 994 (cerr << "There are " << TesselStruct->TrianglesOnBoundary.size() << " triangles and " << TesselStruct->OpenLines.size() << " open lines to scan for candidates." << endl); 995 // 2a. print OpenLines without candidates 996 DoLog(1) && (Log() << Verbose(1) << "There are the following open lines to scan for a candidates:" << endl); 981 // 2a. fill all new OpenLines 982 Log() << Verbose(1) << "There are " << TesselStruct->OpenLines.size() << " open lines to scan for candidates:" << endl; 997 983 for (CandidateMap::iterator Runner = TesselStruct->OpenLines.begin(); Runner != TesselStruct->OpenLines.end(); Runner++) 998 if (Runner->second->pointlist.empty()) 999 DoLog(1) && (Log() << Verbose(1) << " " << *(Runner->second) << endl); 1000 1001 // 2b. find best candidate for each OpenLine 1002 TesselationFailFlag = TesselStruct->FindCandidatesforOpenLines(RADIUS, LCList); 1003 1004 // 2c. print OpenLines with candidates again 1005 DoLog(1) && (Log() << Verbose(1) << "There are " << TesselStruct->OpenLines.size() << " open lines to scan for the best candidates:" << endl); 984 Log() << Verbose(2) << *(Runner->second) << endl; 985 986 for (CandidateMap::iterator Runner = TesselStruct->OpenLines.begin(); Runner != TesselStruct->OpenLines.end(); Runner++) { 987 baseline = Runner->second; 988 if (baseline->pointlist.empty()) { 989 T = (((baseline->BaseLine->triangles.begin()))->second); 990 Log() << Verbose(1) << "Finding best candidate for open line " << *baseline->BaseLine << " of triangle " << *T << endl; 991 TesselationFailFlag = TesselStruct->FindNextSuitableTriangle(*baseline, *T, RADIUS, LCList); //the line is there, so there is a triangle, but only one. 992 } 993 } 994 995 // 2b. search for smallest ShortestAngle among all candidates 996 double ShortestAngle = 4.*M_PI; 997 Log() << Verbose(1) << "There are " << TesselStruct->OpenLines.size() << " open lines to scan for the best candidates:" << endl; 1006 998 for (CandidateMap::iterator Runner = TesselStruct->OpenLines.begin(); Runner != TesselStruct->OpenLines.end(); Runner++) 1007 DoLog(1) && (Log() << Verbose(1) << " " << *(Runner->second) << endl); 1008 1009 // 2d. search for smallest ShortestAngle among all candidates 1010 double ShortestAngle = 4.*M_PI; 999 Log() << Verbose(2) << *(Runner->second) << endl; 1000 1011 1001 for (CandidateMap::iterator Runner = TesselStruct->OpenLines.begin(); Runner != TesselStruct->OpenLines.end(); Runner++) { 1012 1002 if (Runner->second->ShortestAngle < ShortestAngle) { 1013 1003 baseline = Runner->second; 1014 1004 ShortestAngle = baseline->ShortestAngle; 1015 DoLog(1) && (Log() << Verbose(1) << "New best candidate is " << *baseline->BaseLine << " with point " << *(*baseline->pointlist.begin()) << " and angle " << baseline->ShortestAngle << endl);1005 //Log() << Verbose(1) << "New best candidate is " << *baseline->BaseLine << " with point " << *baseline->point << " and angle " << baseline->ShortestAngle << endl; 1016 1006 } 1017 1007 } 1018 // 2e. if we found one, add candidate1019 1008 if ((ShortestAngle == 4.*M_PI) || (baseline->pointlist.empty())) 1020 1009 OneLoopWithoutSuccessFlag = false; 1021 1010 else { 1022 TesselStruct->AddCandidate Polygon(*baseline, RADIUS, LCList);1023 } 1024 1025 // 2f.write temporary envelope1011 TesselStruct->AddCandidateTriangle(*baseline); 1012 } 1013 1014 // write temporary envelope 1026 1015 if (filename != NULL) { 1027 1016 if ((DoSingleStepOutput && ((TesselStruct->TrianglesOnBoundary.size() % SingleStepWidth == 0)))) { // if we have a new triangle and want to output each new triangle configuration … … 1055 1044 status = CheckListOfBaselines(TesselStruct); 1056 1045 1057 // store before correction1058 StoreTrianglesinFile(mol, (const Tesselation *&)TesselStruct, filename, "");1059 1060 // // correct degenerated polygons1061 // TesselStruct->CorrectAllDegeneratedPolygons();1062 //1063 // // check envelope for consistency1064 // status = CheckListOfBaselines(TesselStruct);1065 1066 1046 // write final envelope 1067 1047 CalculateConcavityPerBoundaryPoint(TesselStruct); -
Property mode
changed from
Note:
See TracChangeset
for help on using the changeset viewer.
