Changeset d52ea1b
- Timestamp:
- Jun 7, 2008, 1:21:53 PM (17 years ago)
- Branches:
- Action_Thermostats, Add_AtomRandomPerturbation, Add_FitFragmentPartialChargesAction, Add_RotateAroundBondAction, Add_SelectAtomByNameAction, Added_ParseSaveFragmentResults, AddingActions_SaveParseParticleParameters, Adding_Graph_to_ChangeBondActions, Adding_MD_integration_tests, Adding_ParticleName_to_Atom, Adding_StructOpt_integration_tests, AtomFragments, Automaking_mpqc_open, AutomationFragmentation_failures, Candidate_v1.5.4, Candidate_v1.6.0, Candidate_v1.6.1, ChangeBugEmailaddress, ChangingTestPorts, ChemicalSpaceEvaluator, CombiningParticlePotentialParsing, Combining_Subpackages, Debian_Package_split, Debian_package_split_molecuildergui_only, Disabling_MemDebug, Docu_Python_wait, EmpiricalPotential_contain_HomologyGraph, EmpiricalPotential_contain_HomologyGraph_documentation, Enable_parallel_make_install, Enhance_userguide, Enhanced_StructuralOptimization, Enhanced_StructuralOptimization_continued, Example_ManyWaysToTranslateAtom, Exclude_Hydrogens_annealWithBondGraph, FitPartialCharges_GlobalError, Fix_BoundInBox_CenterInBox_MoleculeActions, Fix_ChargeSampling_PBC, Fix_ChronosMutex, Fix_FitPartialCharges, Fix_FitPotential_needs_atomicnumbers, Fix_ForceAnnealing, Fix_IndependentFragmentGrids, Fix_ParseParticles, Fix_ParseParticles_split_forward_backward_Actions, Fix_PopActions, Fix_QtFragmentList_sorted_selection, Fix_Restrictedkeyset_FragmentMolecule, Fix_StatusMsg, Fix_StepWorldTime_single_argument, Fix_Verbose_Codepatterns, Fix_fitting_potentials, Fixes, ForceAnnealing_goodresults, ForceAnnealing_oldresults, ForceAnnealing_tocheck, ForceAnnealing_with_BondGraph, ForceAnnealing_with_BondGraph_continued, ForceAnnealing_with_BondGraph_continued_betteresults, ForceAnnealing_with_BondGraph_contraction-expansion, FragmentAction_writes_AtomFragments, FragmentMolecule_checks_bonddegrees, GeometryObjects, Gui_Fixes, Gui_displays_atomic_force_velocity, ImplicitCharges, IndependentFragmentGrids, IndependentFragmentGrids_IndividualZeroInstances, IndependentFragmentGrids_IntegrationTest, IndependentFragmentGrids_Sole_NN_Calculation, JobMarket_RobustOnKillsSegFaults, JobMarket_StableWorkerPool, JobMarket_unresolvable_hostname_fix, MoreRobust_FragmentAutomation, ODR_violation_mpqc_open, PartialCharges_OrthogonalSummation, PdbParser_setsAtomName, PythonUI_with_named_parameters, QtGui_reactivate_TimeChanged_changes, Recreated_GuiChecks, Rewrite_FitPartialCharges, RotateToPrincipalAxisSystem_UndoRedo, SaturateAtoms_findBestMatching, SaturateAtoms_singleDegree, StoppableMakroAction, Subpackage_CodePatterns, Subpackage_JobMarket, Subpackage_LinearAlgebra, Subpackage_levmar, Subpackage_mpqc_open, Subpackage_vmg, Switchable_LogView, ThirdParty_MPQC_rebuilt_buildsystem, TrajectoryDependenant_MaxOrder, TremoloParser_IncreasedPrecision, TremoloParser_MultipleTimesteps, TremoloParser_setsAtomName, Ubuntu_1604_changes, stable
- Children:
- 17ce5c
- Parents:
- 65684f
- Location:
- src
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
src/builder.cpp
r65684f rd52ea1b 484 484 * \param *mol the molecule with all the atoms 485 485 */ 486 static void MeasureAtoms(periodentafel *periode, molecule *mol )486 static void MeasureAtoms(periodentafel *periode, molecule *mol, config *configuration) 487 487 { 488 488 atom *first, *second, *third; … … 496 496 cout << Verbose(0) << " b - calculate bond length between two atoms" << endl; 497 497 cout << Verbose(0) << " c - calculate bond angle" << endl; 498 cout << Verbose(0) << " d - calculate principal axis of the system" << endl; 499 cout << Verbose(0) << " e - calculate volume of the convex envelope" << endl; 498 500 cout << Verbose(0) << "all else - go back" << endl; 499 501 cout << Verbose(0) << "===============================================" << endl; … … 553 555 cout << Verbose(0) << (acos(x.ScalarProduct((const vector *)&y)/(y.Norm()*x.Norm()))/M_PI*180.) << " degrees" << endl; 554 556 break; 557 case 'd': 558 cout << Verbose(0) << "Evaluating prinicipal axis." << endl; 559 cout << Verbose(0) << "Shall we rotate? [0/1]: "; 560 cin >> Z; 561 if ((Z >=0) && (Z <=1)) 562 mol->PrincipalAxisSystem((ofstream *)&cout, (bool)Z); 563 else 564 mol->PrincipalAxisSystem((ofstream *)&cout, false); 565 break; 566 case 'e': 567 cout << Verbose(0) << "Evaluating volume of the convex envelope."; 568 mol->VolumeOfConvexEnvelope((ofstream *)&cout, configuration->GetIsAngstroem()); 569 break; 555 570 } 556 571 }; … … 745 760 cout << "\t-f <dist> <order>\tFragments the molecule in BOSSANOVA manner and stores config files in same dir as config." << endl; 746 761 cout << "\t-h/-H/-?\tGive this help screen." << endl; 762 cout << "\t-m\tAlign in PAS with greatest EV along z axis." << endl; 747 763 cout << "\t-p <file>\tParse given xyz file and create raw config file from it." << endl; 748 764 cout << "\t-r\t\tConvert file from an old pcp syntax." << endl; … … 945 961 } 946 962 break; 963 case 'm': 964 ExitFlag = 1; 965 cout << Verbose(0) << "Evaluating prinicipal axis." << endl; 966 mol->PrincipalAxisSystem((ofstream *)&cout, true); 967 break; 947 968 default: // no match? Step on 948 969 argptr++; … … 1151 1172 1152 1173 case 'l': // measure distances or angles 1153 MeasureAtoms(periode, mol );1174 MeasureAtoms(periode, mol, &configuration); 1154 1175 break; 1155 1176 … … 1164 1185 mol->CreateAdjacencyList((ofstream *)&cout, tmp1, configuration.GetIsAngstroem()); 1165 1186 //mol->CreateListOfBondsPerAtom((ofstream *)&cout); 1166 Subgraphs = mol->DepthFirstSearchAnalysis((ofstream *)&cout, false,MinimumRingSize);1187 Subgraphs = mol->DepthFirstSearchAnalysis((ofstream *)&cout, MinimumRingSize); 1167 1188 while (Subgraphs->next != NULL) { 1168 1189 Subgraphs = Subgraphs->next; -
src/molecules.cpp
r65684f rd52ea1b 179 179 bond *FirstBond = NULL, *SecondBond = NULL; // Other bonds in double bond case to determine "other" plane 180 180 atom *FirstOtherAtom = NULL, *SecondOtherAtom = NULL, *ThirdOtherAtom = NULL; // pointer to hydrogen atoms to be added 181 int i; // loop variable182 181 double b,l,d,f,g, alpha, factors[NDIM]; // hold temporary values in triple bond case for coordination determination 183 182 vector OrthoVector1, OrthoVector2; // temporary vectors in coordination construction … … 253 252 case 2: 254 253 // determine two other bonds (warning if there are more than two other) plus valence sanity check 255 for (i =0;i<NumBond;i++) {254 for (int i=0;i<NumBond;i++) { 256 255 if (BondList[i] != TopBond) { 257 256 if (FirstBond == NULL) { … … 312 311 FirstOtherAtom->x.Zero(); 313 312 SecondOtherAtom->x.Zero(); 314 for(i =NDIM;i--;) { // rotate by half the bond angle in both directions (InBondVector is bondangle = 0 direction)313 for(int i=NDIM;i--;) { // rotate by half the bond angle in both directions (InBondVector is bondangle = 0 direction) 315 314 FirstOtherAtom->x.x[i] = InBondVector.x[i] * cos(bondangle) + OrthoVector1.x[i] * (sin(bondangle)); 316 315 SecondOtherAtom->x.x[i] = InBondVector.x[i] * cos(bondangle) + OrthoVector1.x[i] * (-sin(bondangle)); … … 319 318 SecondOtherAtom->x.Scale(&BondRescale); 320 319 //*out << Verbose(3) << "ReScaleCheck: " << FirstOtherAtom->x.Norm() << " and " << SecondOtherAtom->x.Norm() << "." << endl; 321 for(i =NDIM;i--;) { // and make relative to origin atom320 for(int i=NDIM;i--;) { // and make relative to origin atom 322 321 FirstOtherAtom->x.x[i] += TopOrigin->x.x[i]; 323 322 SecondOtherAtom->x.x[i] += TopOrigin->x.x[i]; … … 439 438 int NumberOfAtoms = 0; // atom number in xyz read 440 439 int i, j; // loop variables 441 atom * first= NULL; // pointer to added atom440 atom *Walker = NULL; // pointer to added atom 442 441 char shorthand[3]; // shorthand for atom name 443 442 ifstream xyzfile; // xyz file … … 457 456 458 457 for(i=0;i<NumberOfAtoms;i++){ 459 first= new atom;458 Walker = new atom; 460 459 getline(xyzfile,line,'\n'); 461 460 istringstream *item = new istringstream(line); … … 466 465 *item >> x[1]; 467 466 *item >> x[2]; 468 first->type = elemente->FindElement(shorthand);469 if ( first->type == NULL) {467 Walker->type = elemente->FindElement(shorthand); 468 if (Walker->type == NULL) { 470 469 cerr << "Could not parse the element at line: '" << line << "', setting to H."; 471 first->type = elemente->FindElement(1);470 Walker->type = elemente->FindElement(1); 472 471 } 473 472 for(j=NDIM;j--;) 474 first->x.x[j] = x[j];475 AddAtom( first); // add to molecule473 Walker->x.x[j] = x[j]; 474 AddAtom(Walker); // add to molecule 476 475 delete(item); 477 476 } … … 710 709 }; 711 710 712 /** Centers the center of gravity of the atoms at (0,0,0).711 /** Returns vector pointing to center of gravity. 713 712 * \param *out output stream for debugging 714 * \param *center return vector for translation vector 715 */ 716 void molecule::CenterGravity(ofstream *out, vector *center) 717 { 713 * \return pointer to center of gravity vector 714 */ 715 vector * molecule::DetermineCenterOfGravity(ofstream *out) 716 { 717 atom *ptr = start->next; // start at first in list 718 vector *a = new vector(); 719 vector tmp; 718 720 double Num = 0; 719 atom *ptr = start->next; // start at first in list 720 vector tmp; 721 722 for(int i=NDIM;i--;) // zero center vector 723 center->x[i] = 0.; 724 721 722 a->Zero(); 723 725 724 if (ptr != end) { //list not empty? 726 725 while (ptr->next != end) { // continue with second if present … … 729 728 tmp.CopyVector(&ptr->x); 730 729 tmp.Scale(ptr->type->mass); // scale by mass 731 center->AddVector(&tmp); 732 } 733 center->Scale(-1./Num); // divide through total mass (and sign for direction) 730 a->AddVector(&tmp); 731 } 732 a->Scale(-1./Num); // divide through total mass (and sign for direction) 733 } 734 *out << Verbose(1) << "Resulting center of gravity: "; 735 a->Output(out); 736 *out << endl; 737 return a; 738 }; 739 740 /** Centers the center of gravity of the atoms at (0,0,0). 741 * \param *out output stream for debugging 742 * \param *center return vector for translation vector 743 */ 744 void molecule::CenterGravity(ofstream *out, vector *center) 745 { 746 if (center == NULL) { 747 DetermineCenter(*center); 748 Translate(center); 749 delete(center); 750 } else { 734 751 Translate(center); 735 752 } … … 775 792 }; 776 793 777 /** Determines center of gravity(yet not considering atom masses).778 * \param Center OfGravityreference to return vector779 */ 780 void molecule::DetermineCenter OfGravity(vector &CenterOfGravity)794 /** Determines center of molecule (yet not considering atom masses). 795 * \param Center reference to return vector 796 */ 797 void molecule::DetermineCenter(vector &Center) 781 798 { 782 799 atom *Walker = start; … … 788 805 789 806 do { 790 Center OfGravity.Zero();807 Center.Zero(); 791 808 flag = true; 792 809 while (Walker->next != end) { … … 815 832 TestVector.AddVector(&TranslationVector); 816 833 TestVector.MatrixMultiplication(matrix); 817 Center OfGravity.AddVector(&TestVector);834 Center.AddVector(&TestVector); 818 835 cout << Verbose(1) << "Vector is: "; 819 836 TestVector.Output((ofstream *)&cout); … … 828 845 TestVector.AddVector(&TranslationVector); 829 846 TestVector.MatrixMultiplication(matrix); 830 Center OfGravity.AddVector(&TestVector);847 Center.AddVector(&TestVector); 831 848 cout << Verbose(1) << "Hydrogen Vector is: "; 832 849 TestVector.Output((ofstream *)&cout); … … 838 855 } 839 856 } while (!flag); 840 Free((void **)&matrix, "molecule::DetermineCenterOfGravity: *matrix"); 841 CenterOfGravity.Scale(1./(double)AtomCount); 857 Free((void **)&matrix, "molecule::DetermineCenter: *matrix"); 858 Center.Scale(1./(double)AtomCount); 859 }; 860 861 /** Transforms/Rotates the given molecule into its principal axis system. 862 * \param *out output stream for debugging 863 * \param DoRotate whether to rotate (true) or only to determine the PAS. 864 */ 865 void molecule::PrincipalAxisSystem(ofstream *out, bool DoRotate) 866 { 867 atom *ptr = start; // start at first in list 868 double InertiaTensor[NDIM*NDIM]; 869 vector *CenterOfGravity = DetermineCenterOfGravity(out); 870 871 CenterGravity(out, CenterOfGravity); 872 873 // reset inertia tensor 874 for(int i=0;i<NDIM*NDIM;i++) 875 InertiaTensor[i] = 0.; 876 877 // sum up inertia tensor 878 while (ptr->next != end) { 879 ptr = ptr->next; 880 vector x; 881 x.CopyVector(&ptr->x); 882 //x.SubtractVector(CenterOfGravity); 883 InertiaTensor[0] += ptr->type->mass*(x.x[1]*x.x[1] + x.x[2]*x.x[2]); 884 InertiaTensor[1] += ptr->type->mass*(-x.x[0]*x.x[1]); 885 InertiaTensor[2] += ptr->type->mass*(-x.x[0]*x.x[2]); 886 InertiaTensor[3] += ptr->type->mass*(-x.x[1]*x.x[0]); 887 InertiaTensor[4] += ptr->type->mass*(x.x[0]*x.x[0] + x.x[2]*x.x[2]); 888 InertiaTensor[5] += ptr->type->mass*(-x.x[1]*x.x[2]); 889 InertiaTensor[6] += ptr->type->mass*(-x.x[2]*x.x[0]); 890 InertiaTensor[7] += ptr->type->mass*(-x.x[2]*x.x[1]); 891 InertiaTensor[8] += ptr->type->mass*(x.x[0]*x.x[0] + x.x[1]*x.x[1]); 892 } 893 // print InertiaTensor for debugging 894 *out << "The inertia tensor is:" << endl; 895 for(int i=0;i<NDIM;i++) { 896 for(int j=0;j<NDIM;j++) 897 *out << InertiaTensor[i*NDIM+j] << " "; 898 *out << endl; 899 } 900 *out << endl; 901 902 // diagonalize to determine principal axis system 903 gsl_eigen_symmv_workspace *T = gsl_eigen_symmv_alloc(NDIM); 904 gsl_matrix_view m = gsl_matrix_view_array(InertiaTensor, NDIM, NDIM); 905 gsl_vector *eval = gsl_vector_alloc(NDIM); 906 gsl_matrix *evec = gsl_matrix_alloc(NDIM, NDIM); 907 gsl_eigen_symmv(&m.matrix, eval, evec, T); 908 gsl_eigen_symmv_free(T); 909 gsl_eigen_symmv_sort(eval, evec, GSL_EIGEN_SORT_ABS_DESC); 910 911 for(int i=0;i<NDIM;i++) { 912 *out << Verbose(1) << "eigenvalue = " << gsl_vector_get(eval, i); 913 *out << ", eigenvector = (" << evec->data[i * evec->tda + 0] << "," << evec->data[i * evec->tda + 1] << "," << evec->data[i * evec->tda + 2] << ")" << endl; 914 } 915 916 // check whether we rotate or not 917 if (DoRotate) { 918 *out << Verbose(1) << "Transforming molecule into PAS ... "; 919 // the eigenvectors specify the transformation matrix 920 ptr = start; 921 while (ptr->next != end) { 922 ptr = ptr->next; 923 ptr->x.MatrixMultiplication(evec->data); 924 } 925 *out << "done." << endl; 926 927 // summing anew for debugging (resulting matrix has to be diagonal!) 928 // reset inertia tensor 929 for(int i=0;i<NDIM*NDIM;i++) 930 InertiaTensor[i] = 0.; 931 932 // sum up inertia tensor 933 ptr = start; 934 while (ptr->next != end) { 935 ptr = ptr->next; 936 vector x; 937 x.CopyVector(&ptr->x); 938 //x.SubtractVector(CenterOfGravity); 939 InertiaTensor[0] += ptr->type->mass*(x.x[1]*x.x[1] + x.x[2]*x.x[2]); 940 InertiaTensor[1] += ptr->type->mass*(-x.x[0]*x.x[1]); 941 InertiaTensor[2] += ptr->type->mass*(-x.x[0]*x.x[2]); 942 InertiaTensor[3] += ptr->type->mass*(-x.x[1]*x.x[0]); 943 InertiaTensor[4] += ptr->type->mass*(x.x[0]*x.x[0] + x.x[2]*x.x[2]); 944 InertiaTensor[5] += ptr->type->mass*(-x.x[1]*x.x[2]); 945 InertiaTensor[6] += ptr->type->mass*(-x.x[2]*x.x[0]); 946 InertiaTensor[7] += ptr->type->mass*(-x.x[2]*x.x[1]); 947 InertiaTensor[8] += ptr->type->mass*(x.x[0]*x.x[0] + x.x[1]*x.x[1]); 948 } 949 // print InertiaTensor for debugging 950 *out << "The inertia tensor is:" << endl; 951 for(int i=0;i<NDIM;i++) { 952 for(int j=0;j<NDIM;j++) 953 *out << InertiaTensor[i*NDIM+j] << " "; 954 *out << endl; 955 } 956 *out << endl; 957 } 958 959 // free everything 960 delete(CenterOfGravity); 961 gsl_vector_free(eval); 962 gsl_matrix_free(evec); 842 963 }; 843 964 … … 1234 1355 if ((Binder->next != last) && (Binder->next->Type == Undetermined)) { 1235 1356 *out << Verbose(0) << "No Depth-First-Search analysis performed so far, calling ..." << endl; 1236 Subgraphs = DepthFirstSearchAnalysis(out, false,MinimumRingSize);1357 Subgraphs = DepthFirstSearchAnalysis(out, MinimumRingSize); 1237 1358 while (Subgraphs->next != NULL) { 1238 1359 Subgraphs = Subgraphs->next; … … 1248 1369 } 1249 1370 return No; 1371 }; 1372 1373 /** Determines the volume of a cluster. 1374 * Determines first the convex envelope, then tesselates it and calculates its volume. 1375 * \param *out output stream for debugging 1376 * \param IsAngstroem for the units on output 1377 */ 1378 double molecule::VolumeOfConvexEnvelope(ofstream *out, bool IsAngstroem) 1379 { 1380 atom *Walker = NULL; 1381 1382 // 1. calculate center of gravity 1383 vector *CenterOfGravity = DetermineCenterOfGravity(out); 1384 1385 // 2. calculate distance of each atom and sort into hash table 1386 // map<double, int> DistanceSet; 1387 // 1388 // Walker = start; 1389 // while (Walker->next != end) { 1390 // Walker = Walker->next; 1391 // DistanceSet.insert( pair<double, int>(ptr->x.distance(CenterOfGravity), ptr->nr) ); 1392 // } 1393 1394 // 3. Find all points on the boundary 1395 Boundaries BoundaryPoints[NDIM]; // first is alpha, second is (r, nr) 1396 BoundariesTestPair BoundaryTestPair; 1397 vector AxisVector; 1398 // 3a. Go through every axis 1399 for (int axis=0; axis<NDIM; axis++) { 1400 AxisVector.Zero(); 1401 AxisVector.x[axis] = 1.; 1402 // 3b. construct set of all points, transformed into cylindrical system and with left and right neighbours 1403 Walker = start; 1404 while (Walker->next != end) { 1405 Walker = Walker->next; 1406 vector ProjectedVector; 1407 ProjectedVector.CopyVector(&Walker->x); 1408 ProjectedVector.Scale(-1.*Walker->x.Projection(&AxisVector)); 1409 ProjectedVector.AddVector(&Walker->x); // subtract projection from vector 1410 BoundaryTestPair = BoundaryPoints[axis].insert( BoundariesPair (ProjectedVector.Angle(&AxisVector), DistanceNrPair (ProjectedVector.Norm(), Walker) ) ); 1411 if (BoundaryTestPair.second) { // successfully inserted 1412 } else { // same point exists, check first r, then distance of original vectors to centers of gravity 1413 *out << Verbose(2) << "Encountered two vectors whose projection onto axis " << axis << " is equal: " << endl; 1414 *out << Verbose(2) << "Present vector: "; 1415 BoundaryTestPair.first->second.second->x.Output(out); 1416 *out << endl; 1417 *out << Verbose(2) << "New vector: "; 1418 Walker->x.Output(out); 1419 *out << endl; 1420 double tmp = ProjectedVector.Norm(); 1421 if (tmp > BoundaryTestPair.first->second.first) { 1422 BoundaryTestPair.first->second.first = tmp; 1423 BoundaryTestPair.first->second.second = Walker; 1424 *out << Verbose(2) << "Keeping new vector." << endl; 1425 } else if (tmp == BoundaryTestPair.first->second.first) { 1426 if (BoundaryTestPair.first->second.second->x.Distance(CenterOfGravity) < Walker->x.Distance(CenterOfGravity)) { 1427 BoundaryTestPair.first->second.second = Walker; 1428 *out << Verbose(2) << "Keeping new vector." << endl; 1429 } else { 1430 *out << Verbose(2) << "Keeping present vector." << endl; 1431 } 1432 } else { 1433 *out << Verbose(2) << "Keeping present vector." << endl; 1434 } 1435 } 1436 } 1437 // 3c. throw out points whose distance is less than the mean of left and right neighbours 1438 bool flag = false; 1439 do { // do as long as we still throw one out per round 1440 flag = false; 1441 Boundaries::iterator left = BoundaryPoints[axis].end(); 1442 Boundaries::iterator right = BoundaryPoints[axis].end(); 1443 for(Boundaries::iterator runner = BoundaryPoints[axis].begin(); runner != BoundaryPoints[axis].end(); runner++) { 1444 // set neighbours correctly 1445 if (runner == BoundaryPoints[axis].begin()) { 1446 left = BoundaryPoints[axis].end(); 1447 } else { 1448 left = runner; 1449 } 1450 left--; 1451 right = runner; 1452 right++; 1453 if (right == BoundaryPoints[axis].end()) { 1454 right = BoundaryPoints[axis].begin(); 1455 } 1456 // check distance 1457 if (runner->second.first < (left->second.first + right->second.first)/2. ) { 1458 // throw out point 1459 BoundaryPoints[axis].erase(runner); 1460 flag = true; 1461 } 1462 } 1463 } while (flag); 1464 } 1465 // 3d. put into boundary set only those points appearing in each of the NDIM sets 1466 int *AtomList = new int[AtomCount]; 1467 for (int j=0; j<AtomCount; j++) // reset list 1468 AtomList[j] = 0; 1469 for (int axis=0; axis<NDIM; axis++) { // increase whether it's present 1470 for(Boundaries::iterator runner = BoundaryPoints[axis].begin(); runner != BoundaryPoints[axis].end(); runner++) { 1471 AtomList[runner->second.second->nr]++; 1472 } 1473 } 1474 int BoundaryPointCount = 0; 1475 Walker = start; 1476 while (Walker->next != end) { 1477 Walker = Walker->next; 1478 if (AtomList[Walker->nr] < NDIM) { // enter all neighbouring points 1479 BoundaryPointCount++; 1480 } 1481 } 1482 1483 // 3e. Points no more in the total list, have to be thrown out of each axis lists too! 1484 for (int axis=0; axis<NDIM; axis++) { 1485 for(Boundaries::iterator runner = BoundaryPoints[axis].begin(); runner != BoundaryPoints[axis].end(); runner++) { 1486 if (AtomList[runner->second.second->nr] < NDIM) 1487 BoundaryPoints[axis].erase(runner); 1488 } 1489 } 1490 1491 *out << Verbose(2) << "I found " << BoundaryPointCount << " points on the convex boundary." << endl; 1492 // now we have the whole set of edge points in the BoundaryList 1493 1494 // 4. Create each possible line, number them and put them into a list (3 * AtomCount possible) 1495 struct lines { 1496 atom *x[2]; 1497 int nr; 1498 } LinesList[3 * AtomCount]; 1499 1500 // initialise reference storage (needed lateron) 1501 int **AtomLines = new int *[AtomCount]; 1502 Walker = start; 1503 while (Walker->next != end) { // go through all points 1504 Walker = Walker->next; 1505 if (AtomList[Walker->nr] == NDIM) { // if this is a boundary point 1506 AtomLines[Walker->nr] = new int[NDIM]; 1507 for(int axis=0;axis<NDIM;axis++) { 1508 AtomLines[Walker->nr][2*axis+0] = -1; 1509 AtomLines[Walker->nr][2*axis+1] = -1; 1510 } 1511 } 1512 } 1513 1514 // then create each line 1515 int LineCount = 0; 1516 for(int axis=0;axis<NDIM;axis++) { // go through every axis 1517 for(Boundaries::iterator runner = BoundaryPoints[axis].begin(); runner != BoundaryPoints[axis].end(); runner++) { 1518 // get left and right neighbours 1519 Boundaries::iterator NN[2] = runner; 1520 if (NN[0] == BoundaryPoints[axis].begin()) 1521 NN[0] = BoundaryPoints[axis].end(); 1522 NN[0]--; 1523 NN[1] = runner; 1524 NN[1]++; 1525 if (NN[1] == BoundaryPoints[axis].end()) 1526 NN[1] = BoundaryPoints[axis].begin(); 1527 // check those neighbours for their atomic index 1528 for (int k=0;k<2;k++) { 1529 if (runner->second.second->nr > NN[k]->second.second->nr) { // check left neighbour on this projected axis 1530 LinesList[LineCount].x[0] = runner->second.second; 1531 LinesList[LineCount].x[1] = NN[k]->second.second; 1532 if (AtomLines[LinesList[LineCount].x[0]->nr][axis] == -1) { 1533 AtomLines[LinesList[LineCount].x[0]->nr][axis] = LineCount; 1534 } else if (AtomLines[LinesList[LineCount].x[1]->nr][axis] == -1) { 1535 AtomLines[LinesList[LineCount].x[1]->nr][axis] = LineCount; 1536 } else { 1537 *out << Verbose(2) << "Could not store line number " << LineCount << "." << endl; 1538 } 1539 LineCount++; 1540 } 1541 } 1542 } 1543 } 1544 *out << Verbose(2) << "I created " << LineCount << " edges." << endl; 1545 1546 // 5. Create every possible triangle from the lines (numbering of each line must be i < j < k) 1547 struct triangles { 1548 atom *x1; 1549 atom *x2; 1550 atom *x3; 1551 int nr; 1552 } TriangleList[2 * 3 * AtomCount]; // each line can be part in at most 2 triangles 1553 int TriangleCount = 0; 1554 for (int i=0; i<LineCount; i++) { // go through every line 1555 LinetoAtomMap LinetoAtom; 1556 // we have two points, check the lines at either end, whether they share a common endpoint 1557 for (int endpoint=0;endpoint<2;endpoint++) { 1558 Walker = LinesList[LineCount].x[endpoint]; 1559 for (int axis=0;axis<NDIM;axis++) { 1560 LinetoAtomTestPair LinetoAtomTest; 1561 LinetoAtomPair InsertionPair = LinetoAtomPair(-1, NULL); 1562 struct lines *TempLine = &LinesList[ AtomLines[Walker->nr][axis] ]; 1563 if (AtomLines[Walker->nr][axis] != LineCount) { 1564 if (TempLine->x[0] != Walker) { 1565 InsertionPair = LinetoAtomPair(TempLine->x[0]->nr, TempLine->x[0]); 1566 } else if (TempLine->x[1] != Walker) { 1567 InsertionPair = LinetoAtomPair(TempLine->x[1]->nr, TempLine->x[0]); 1568 } else { 1569 *out << Verbose(2) << "Atom " << *Walker << "is both the end of line " << AtomLines[Walker->nr][axis] << "." << endl; 1570 } 1571 if (InsertionPair.first != -1) // insert if present 1572 LinetoAtomTest = LinetoAtom.insert( InsertionPair ); 1573 if (!LinetoAtomTest.second) { 1574 // atom is already present in list, hence we have found a possible triangle 1575 if ((Walker->nr < LinetoAtomTest.first->first) && (LinetoAtomTest.first->first < InsertionPair.first)) { // check if numbering is in correct order for uniqueness, if so add 1576 TriangleList[TriangleCount].x1 = Walker; 1577 TriangleList[TriangleCount].x2 = LinetoAtomTest.first->second; 1578 TriangleList[TriangleCount].x3 = InsertionPair.second; 1579 TriangleCount++; 1580 } 1581 } //else { // check if insertion was successful 1582 // successfully inserted, hence nothing found yet 1583 //} 1584 } 1585 } 1586 } 1587 } 1588 *out << Verbose(2) << "I created " << TriangleCount << " triangles." << endl; 1589 1590 // 6. Every triangle forms a pyramid with the center of gravity as its peak, sum up the volumes 1591 double volume = 0.; 1592 double PyramidVolume = 0.; 1593 double G,h; 1594 vector x,y; 1595 double a,b,c; 1596 for (int i=0; i<TriangleCount; i++) { // go through every triangle, calculate volume of its pyramid with CoG as peak 1597 x.CopyVector(&TriangleList[TriangleCount].x1->x); 1598 x.SubtractVector(&TriangleList[TriangleCount].x2->x); 1599 y.CopyVector(&TriangleList[TriangleCount].x1->x); 1600 y.SubtractVector(&TriangleList[TriangleCount].x3->x); 1601 a = sqrt(TriangleList[TriangleCount].x1->x.Distance(&TriangleList[TriangleCount].x2->x)); 1602 b = sqrt(TriangleList[TriangleCount].x1->x.Distance(&TriangleList[TriangleCount].x3->x)); 1603 c = sqrt(TriangleList[TriangleCount].x3->x.Distance(&TriangleList[TriangleCount].x2->x)); 1604 G = c * (sin(x.Angle(&y))*a); // area of tesselated triangle 1605 x.MakeNormalVector(&TriangleList[TriangleCount].x1->x, &TriangleList[TriangleCount].x2->x, &TriangleList[TriangleCount].x3->x); 1606 y.CopyVector(&x); 1607 x.Scale(CenterOfGravity->Projection(&x)); 1608 h = x.Norm(); // distance of CoG to triangle 1609 PyramidVolume = (1./3.) * G * h; // this formula holds for _all_ pyramids (independent of n-edge base or (not) centered peak) 1610 volume += PyramidVolume; 1611 } 1612 *out << Verbose(1) << "The summed volume is " << volume << " " << (IsAngstroem ? "A^3" : "a_0^3") << "." << endl; 1613 1614 // free reference lists 1615 delete[](AtomList); 1616 for(int i=0;i<AtomCount;i++) 1617 delete[](AtomLines[i]); 1618 delete[](AtomLines); 1619 1620 return volume; 1250 1621 }; 1251 1622 … … 1490 1861 * We use the algorithm from [Even, Graph Algorithms, p.62]. 1491 1862 * \param *out output stream for debugging 1492 * \param ReturnStack true - return pointer to atom stack of separable components, false - return NULL1493 1863 * \param *&MinimumRingSize contains smallest ring size in molecular structure on return or -1 if no rings were found 1494 1864 * \return list of each disconnected subgraph as an individual molecule class structure 1495 1865 */ 1496 MoleculeLeafClass * molecule::DepthFirstSearchAnalysis(ofstream *out, bool ReturnStack,int *&MinimumRingSize)1866 MoleculeLeafClass * molecule::DepthFirstSearchAnalysis(ofstream *out, int *&MinimumRingSize) 1497 1867 { 1498 1868 class StackClass<atom *> *AtomStack; … … 2006 2376 * \param *path path to file 2007 2377 * \param *FragmentList empty, filled on return 2008 * \param IsAngstroem whether we have Ansgtroem or bohrradius2009 2378 * \return true - parsing successfully, false - failure on parsing (FragmentList will be NULL) 2010 2379 */ 2011 bool molecule::ParseKeySetFile(ofstream *out, char *path, Graph *&FragmentList , bool IsAngstroem)2380 bool molecule::ParseKeySetFile(ofstream *out, char *path, Graph *&FragmentList) 2012 2381 { 2013 2382 bool status = true; … … 2186 2555 { 2187 2556 ifstream File; 2188 stringstream line;2557 stringstream filename; 2189 2558 bool status = true; 2190 2559 char *buffer = (char *) Malloc(sizeof(char)*MAXSTRINGSIZE, "molecule::CheckAdjacencyFileAgainstMolecule: *buffer"); 2191 2560 2192 line << path << "/" << FRAGMENTPREFIX << ADJACENCYFILE;2193 File.open( line.str().c_str(), ios::out);2561 filename << path << "/" << FRAGMENTPREFIX << ADJACENCYFILE; 2562 File.open(filename.str().c_str(), ios::out); 2194 2563 *out << Verbose(1) << "Looking at bond structure stored in adjacency file and comparing to present one ... "; 2195 2564 if (File != NULL) { … … 2493 2862 2494 2863 // ===== 2. perform a DFS analysis to gather info on cyclic structure and a list of disconnected subgraphs ===== 2495 Subgraphs = DepthFirstSearchAnalysis(out, false,MinimumRingSize);2864 Subgraphs = DepthFirstSearchAnalysis(out, MinimumRingSize); 2496 2865 // fill the bond structure of the individually stored subgraphs 2497 2866 Subgraphs->next->FillBondStructureFromReference(out, this, (FragmentCounter = 0), ListOfLocalAtoms, false); // we want to keep the created ListOfLocalAtoms 2498 2867 2499 2868 // ===== 3. if structure still valid, parse key set file and others ===== 2500 FragmentationToDo = FragmentationToDo && ParseKeySetFile(out, configuration->configpath, ParsedFragmentList , configuration->GetIsAngstroem());2869 FragmentationToDo = FragmentationToDo && ParseKeySetFile(out, configuration->configpath, ParsedFragmentList); 2501 2870 2502 2871 // ===== 4. check globally whether there's something to do actually (first adaptivity check) … … 3421 3790 KeyStack AtomStack; 3422 3791 atom **PredecessorList = (atom **) Malloc(sizeof(atom *)*AtomCount, "molecule::PowerSetGenerator: **PredecessorList"); 3423 KeySet::iterator runner;3424 3792 int RootKeyNr = FragmentSearch.Root->nr; 3425 3793 int Counter = FragmentSearch.FragmentCounter; … … 3816 4184 { 3817 4185 Graph ***FragmentLowerOrdersList = NULL; 3818 int Order,NumLevels, NumMolecules, TotalNumMolecules = 0, *NumMoleculesOfOrder = NULL;3819 int counter = 0 ;4186 int NumLevels, NumMolecules, TotalNumMolecules = 0, *NumMoleculesOfOrder = NULL; 4187 int counter = 0, Order; 3820 4188 int UpgradeCount = RootStack.size(); 3821 4189 KeyStack FragmentRootStack; … … 3831 4199 3832 4200 // initialise the fragments structure 3833 FragmentSearch.BondsPerSPList = (bond **) Malloc(sizeof(bond *)*Order*2, "molecule::PowerSetGenerator: ***BondsPerSPList");3834 FragmentSearch.BondsPerSPCount = (int *) Malloc(sizeof(int)*Order, "molecule::PowerSetGenerator: *BondsPerSPCount");3835 4201 FragmentSearch.ShortestPathList = (int *) Malloc(sizeof(int)*AtomCount, "molecule::PowerSetGenerator: *ShortestPathList"); 3836 4202 FragmentSearch.Labels = (int *) Malloc(sizeof(int)*AtomCount, "molecule::PowerSetGenerator: *Labels"); … … 4059 4425 if (result) { 4060 4426 *out << Verbose(5) << "Calculating Centers of Gravity" << endl; 4061 DetermineCenter OfGravity(CenterOfGravity);4062 OtherMolecule->DetermineCenter OfGravity(OtherCenterOfGravity);4427 DetermineCenter(CenterOfGravity); 4428 OtherMolecule->DetermineCenter(OtherCenterOfGravity); 4063 4429 *out << Verbose(5) << "Center of Gravity: "; 4064 4430 CenterOfGravity.Output(out); -
src/molecules.hpp
r65684f rd52ea1b 13 13 #include <gsl/gsl_vector.h> 14 14 #include <gsl/gsl_matrix.h> 15 #include <gsl/gsl_eigen.h> 15 16 #include <gsl/gsl_heapsort.h> 16 17 … … 43 44 #define KeySetTestPair pair<KeySet::iterator, bool> 44 45 #define GraphTestPair pair<Graph::iterator, bool> 46 47 #define DistanceNrPair pair< double, atom* > 48 #define Boundaries map <double, DistanceNrPair > 49 #define BoundariesPair pair<double, DistanceNrPair > 50 #define BoundariesTestPair pair<Boundaries::iterator, bool> 51 #define LinetoAtomMap map < int, atom * > 52 #define LinetoAtomPair pair < int, atom * > 53 #define LinetoAtomTestPair pair < LinetoAtomMap::iterator, bool> 45 54 46 55 struct KeyCompare … … 265 274 void CenterEdge(ofstream *out, vector *max); 266 275 void CenterOrigin(ofstream *out, vector *max); 267 void CenterGravity(ofstream *out, vector *max); 276 void CenterGravity(ofstream *out, vector *max); 268 277 void Translate(const vector *x); 269 278 void Mirror(const vector *x); 270 279 void Align(vector *n); 271 280 void Scale(double **factor); 272 void DetermineCenterOfGravity(vector &CenterOfGravity); 281 void DetermineCenter(vector ¢er); 282 vector * DetermineCenterOfGravity(ofstream *out); 273 283 void SetBoxDimension(vector *dim); 274 284 double * ReturnFullMatrixforSymmetric(double *cell_size); 275 285 void ScanForPeriodicCorrection(ofstream *out); 276 286 void PrincipalAxisSystem(ofstream *out, bool DoRotate); 287 double VolumeOfConvexEnvelope(ofstream *out, bool IsAngstroem); 288 277 289 bool CheckBounds(const vector *x) const; 278 290 void GetAlignVector(struct lsq_params * par) const; … … 283 295 284 296 // Graph analysis 285 MoleculeLeafClass * DepthFirstSearchAnalysis(ofstream *out, bool ReturnStack,int *&MinimumRingSize);297 MoleculeLeafClass * DepthFirstSearchAnalysis(ofstream *out, int *&MinimumRingSize); 286 298 void CyclicStructureAnalysis(ofstream *out, class StackClass<bond *> *BackEdgeStack, int *&MinimumRingSize); 287 299 bond * FindNextUnused(atom *vertex); … … 303 315 bool ParseOrderAtSiteFromFile(ofstream *out, char *path); 304 316 bool StoreOrderAtSiteFile(ofstream *out, char *path); 305 bool ParseKeySetFile(ofstream *out, char *filename, Graph *&FragmentList , bool IsAngstroem);317 bool ParseKeySetFile(ofstream *out, char *filename, Graph *&FragmentList); 306 318 bool StoreKeySetFile(ofstream *out, Graph &KeySetList, char *path); 307 319 bool StoreForcesFile(ofstream *out, MoleculeListClass *BondFragments, char *path, int *SortIndex);
Note:
See TracChangeset
for help on using the changeset viewer.