Changes in molecuilder/src/molecules.cpp [848729:f5d7e1]
- File:
-
- 1 edited
-
molecuilder/src/molecules.cpp (modified) (209 diffs, 1 prop)
Legend:
- Unmodified
- Added
- Removed
-
molecuilder/src/molecules.cpp
-
Property mode
changed from
100755to100644
r848729 rf5d7e1 1 1 /** \file molecules.cpp 2 * 2 * 3 3 * Functions for the class molecule. 4 * 4 * 5 5 */ 6 6 … … 25 25 sum += (gsl_vector_get(x,j) - (vectors[i])->x[j])*(gsl_vector_get(x,j) - (vectors[i])->x[j]); 26 26 } 27 27 28 28 return sum; 29 29 }; … … 34 34 * Initialises molecule list with correctly referenced start and end, and sets molecule::last_atom to zero. 35 35 */ 36 molecule::molecule(periodentafel *teil) 37 { 36 molecule::molecule(periodentafel *teil) 37 { 38 38 // init atom chain list 39 start = new atom; 39 start = new atom; 40 40 end = new atom; 41 start->father = NULL; 41 start->father = NULL; 42 42 end->father = NULL; 43 43 link(start,end); … … 46 46 last = new bond(start, end, 1, -1); 47 47 link(first,last); 48 // other stuff 48 // other stuff 49 49 MDSteps = 0; 50 last_atom = 0; 50 last_atom = 0; 51 51 elemente = teil; 52 52 AtomCount = 0; … … 67 67 * Initialises molecule list with correctly referenced start and end, and sets molecule::last_atom to zero. 68 68 */ 69 molecule::~molecule() 69 molecule::~molecule() 70 70 { 71 71 if (ListOfBondsPerAtom != NULL) … … 78 78 delete(last); 79 79 delete(end); 80 delete(start); 80 delete(start); 81 81 }; 82 82 83 83 /** Adds given atom \a *pointer from molecule list. 84 * Increases molecule::last_atom and gives last number to added atom and names it according to its element::abbrev and molecule::AtomCount 84 * Increases molecule::last_atom and gives last number to added atom and names it according to its element::abbrev and molecule::AtomCount 85 85 * \param *pointer allocated and set atom 86 86 * \return true - succeeded, false - atom not found in list 87 87 */ 88 88 bool molecule::AddAtom(atom *pointer) 89 { 89 { 90 90 if (pointer != NULL) { 91 pointer->sort = &pointer->nr; 91 pointer->sort = &pointer->nr; 92 92 pointer->nr = last_atom++; // increase number within molecule 93 93 AtomCount++; … … 106 106 return add(pointer, end); 107 107 } else 108 return false; 108 return false; 109 109 }; 110 110 … … 115 115 */ 116 116 atom * molecule::AddCopyAtom(atom *pointer) 117 { 117 { 118 118 if (pointer != NULL) { 119 119 atom *walker = new atom(); … … 122 122 walker->v.CopyVector(&pointer->v); // copy velocity 123 123 walker->FixedIon = pointer->FixedIon; 124 walker->sort = &walker->nr; 124 walker->sort = &walker->nr; 125 125 walker->nr = last_atom++; // increase number within molecule 126 126 walker->father = pointer; //->GetTrueFather(); … … 133 133 return walker; 134 134 } else 135 return NULL; 135 return NULL; 136 136 }; 137 137 … … 156 156 * The lengths for these are \f$f\f$ and \f$g\f$ (from triangle H1-H2-(center of H1-H2-H3)) with knowledge that 157 157 * the median lines in an isosceles triangle meet in the center point with a ratio 2:1. 158 * \f[ f = \frac{b}{\sqrt{3}} \qquad g = \frac{b}{2} 158 * \f[ f = \frac{b}{\sqrt{3}} \qquad g = \frac{b}{2} 159 159 * \f] 160 * as the coordination of all three atoms in the coordinate system of these three vectors: 160 * as the coordination of all three atoms in the coordinate system of these three vectors: 161 161 * \f$\pmatrix{d & f & 0}\f$, \f$\pmatrix{d & -0.5 \cdot f & g}\f$ and \f$\pmatrix{d & -0.5 \cdot f & -g}\f$. 162 * 162 * 163 163 * \param *out output stream for debugging 164 * \param *Bond pointer to bond between \a *origin and \a *replacement 165 * \param *TopOrigin son of \a *origin of upper level molecule (the atom added to this molecule as a copy of \a *origin) 164 * \param *Bond pointer to bond between \a *origin and \a *replacement 165 * \param *TopOrigin son of \a *origin of upper level molecule (the atom added to this molecule as a copy of \a *origin) 166 166 * \param *origin pointer to atom which acts as the origin for scaling the added hydrogen to correct bond length 167 167 * \param *replacement pointer to the atom which shall be copied as a hydrogen atom in this molecule … … 191 191 InBondvector.SubtractVector(&TopOrigin->x); 192 192 bondlength = InBondvector.Norm(); 193 193 194 194 // is greater than typical bond distance? Then we have to correct periodically 195 195 // the problem is not the H being out of the box, but InBondvector have the wrong direction 196 // due to TopReplacement or Origin being on the wrong side! 197 if (bondlength > BondDistance) { 196 // due to TopReplacement or Origin being on the wrong side! 197 if (bondlength > BondDistance) { 198 198 // *out << Verbose(4) << "InBondvector is: "; 199 199 // InBondvector.Output(out); … … 215 215 // *out << endl; 216 216 } // periodic correction finished 217 217 218 218 InBondvector.Normalize(); 219 219 // get typical bond length and store as scale factor for later … … 222 222 cerr << Verbose(3) << "ERROR: There is no typical hydrogen bond distance in replacing bond (" << TopOrigin->Name << "<->" << TopReplacement->Name << ") of degree " << TopBond->BondDegree << "!" << endl; 223 223 return false; 224 BondRescale = bondlength; 224 BondRescale = bondlength; 225 225 } else { 226 226 if (!IsAngstroem) … … 273 273 if (FirstOtherAtom != NULL) { // then we just have this double bond and the plane does not matter at all 274 274 // *out << Verbose(3) << "Regarding the double bond (" << TopOrigin->Name << "<->" << TopReplacement->Name << ") to be constructed: Taking " << FirstOtherAtom->Name << " and " << SecondOtherAtom->Name << " along with " << TopOrigin->Name << " to determine orthogonal plane." << endl; 275 275 276 276 // determine the plane of these two with the *origin 277 277 AllWentWell = AllWentWell && Orthovector1.MakeNormalVector(&TopOrigin->x, &FirstOtherAtom->x, &SecondOtherAtom->x); … … 286 286 Orthovector1.Normalize(); 287 287 //*out << Verbose(3) << "ReScaleCheck: " << Orthovector1.Norm() << " and " << InBondvector.Norm() << "." << endl; 288 288 289 289 // create the two Hydrogens ... 290 290 FirstOtherAtom = new atom(); … … 318 318 SecondOtherAtom->x.x[i] = InBondvector.x[i] * cos(bondangle) + Orthovector1.x[i] * (-sin(bondangle)); 319 319 } 320 FirstOtherAtom->x.Scale(&BondRescale); // rescale by correct BondDistance 320 FirstOtherAtom->x.Scale(&BondRescale); // rescale by correct BondDistance 321 321 SecondOtherAtom->x.Scale(&BondRescale); 322 322 //*out << Verbose(3) << "ReScaleCheck: " << FirstOtherAtom->x.Norm() << " and " << SecondOtherAtom->x.Norm() << "." << endl; 323 323 for(int i=NDIM;i--;) { // and make relative to origin atom 324 FirstOtherAtom->x.x[i] += TopOrigin->x.x[i]; 324 FirstOtherAtom->x.x[i] += TopOrigin->x.x[i]; 325 325 SecondOtherAtom->x.x[i] += TopOrigin->x.x[i]; 326 326 } … … 365 365 // *out << endl; 366 366 AllWentWell = AllWentWell && Orthovector2.MakeNormalVector(&InBondvector, &Orthovector1); 367 // *out << Verbose(3) << "Orthovector2: "; 367 // *out << Verbose(3) << "Orthovector2: "; 368 368 // Orthovector2.Output(out); 369 369 // *out << endl; 370 370 371 371 // create correct coordination for the three atoms 372 372 alpha = (TopOrigin->type->HBondAngle[2])/180.*M_PI/2.; // retrieve triple bond angle from database … … 380 380 factors[0] = d; 381 381 factors[1] = f; 382 factors[2] = 0.; 382 factors[2] = 0.; 383 383 FirstOtherAtom->x.LinearCombinationOfVectors(&InBondvector, &Orthovector1, &Orthovector2, factors); 384 384 factors[1] = -0.5*f; 385 factors[2] = g; 385 factors[2] = g; 386 386 SecondOtherAtom->x.LinearCombinationOfVectors(&InBondvector, &Orthovector1, &Orthovector2, factors); 387 factors[2] = -g; 387 factors[2] = -g; 388 388 ThirdOtherAtom->x.LinearCombinationOfVectors(&InBondvector, &Orthovector1, &Orthovector2, factors); 389 389 … … 437 437 */ 438 438 bool molecule::AddXYZFile(string filename) 439 { 439 { 440 440 istringstream *input = NULL; 441 441 int NumberOfAtoms = 0; // atom number in xyz read … … 446 446 string line; // currently parsed line 447 447 double x[3]; // atom coordinates 448 448 449 449 xyzfile.open(filename.c_str()); 450 450 if (!xyzfile) … … 454 454 input = new istringstream(line); 455 455 *input >> NumberOfAtoms; 456 cout << Verbose(0) << "Parsing " << NumberOfAtoms << " atoms in file." << endl; 456 cout << Verbose(0) << "Parsing " << NumberOfAtoms << " atoms in file." << endl; 457 457 getline(xyzfile,line,'\n'); // Read comment 458 458 cout << Verbose(1) << "Comment: " << line << endl; 459 459 460 460 if (MDSteps == 0) // no atoms yet present 461 461 MDSteps++; … … 491 491 xyzfile.close(); 492 492 delete(input); 493 return true; 493 return true; 494 494 }; 495 495 … … 503 503 atom *LeftAtom = NULL, *RightAtom = NULL; 504 504 atom *Walker = NULL; 505 505 506 506 // copy all atoms 507 507 Walker = start; … … 510 510 CurrentAtom = copy->AddCopyAtom(Walker); 511 511 } 512 512 513 513 // copy all bonds 514 514 bond *Binder = first; … … 534 534 copy->NoCyclicBonds++; 535 535 NewBond->Type = Binder->Type; 536 } 536 } 537 537 // correct fathers 538 538 Walker = copy->start; … … 551 551 copy->CreateListOfBondsPerAtom((ofstream *)&cout); 552 552 } 553 553 554 554 return copy; 555 555 }; … … 576 576 577 577 /** Remove bond from bond chain list. 578 * \todo Function not implemented yet 578 * \todo Function not implemented yet 579 579 * \param *pointer bond pointer 580 580 * \return true - bound found and removed, false - bond not found/removed … … 588 588 589 589 /** Remove every bond from bond chain list that atom \a *BondPartner is a constituent of. 590 * \todo Function not implemented yet 590 * \todo Function not implemented yet 591 591 * \param *BondPartner atom to be removed 592 592 * \return true - bounds found and removed, false - bonds not found/removed … … 621 621 Vector *min = new Vector; 622 622 Vector *max = new Vector; 623 623 624 624 // gather min and max for each axis 625 625 ptr = start->next; // start at first in list … … 667 667 { 668 668 Vector *min = new Vector; 669 669 670 670 // *out << Verbose(3) << "Begin of CenterEdge." << endl; 671 671 atom *ptr = start->next; // start at first in list … … 683 683 } 684 684 } 685 // *out << Verbose(4) << "Maximum is "; 685 // *out << Verbose(4) << "Maximum is "; 686 686 // max->Output(out); 687 687 // *out << ", Minimum is "; … … 691 691 max->AddVector(min); 692 692 Translate(min); 693 } 693 } 694 694 delete(min); 695 695 // *out << Verbose(3) << "End of CenterEdge." << endl; 696 }; 696 }; 697 697 698 698 /** Centers the center of the atoms at (0,0,0). … … 704 704 int Num = 0; 705 705 atom *ptr = start->next; // start at first in list 706 706 707 707 for(int i=NDIM;i--;) // zero center vector 708 708 center->x[i] = 0.; 709 709 710 710 if (ptr != end) { //list not empty? 711 711 while (ptr->next != end) { // continue with second if present 712 712 ptr = ptr->next; 713 713 Num++; 714 center->AddVector(&ptr->x); 714 center->AddVector(&ptr->x); 715 715 } 716 716 center->Scale(-1./Num); // divide through total number (and sign for direction) 717 717 Translate(center); 718 718 } 719 }; 719 }; 720 720 721 721 /** Returns vector pointing to center of gravity. … … 729 729 Vector tmp; 730 730 double Num = 0; 731 731 732 732 a->Zero(); 733 733 … … 737 737 Num += 1.; 738 738 tmp.CopyVector(&ptr->x); 739 a->AddVector(&tmp); 739 a->AddVector(&tmp); 740 740 } 741 741 a->Scale(-1./Num); // divide through total mass (and sign for direction) … … 757 757 Vector tmp; 758 758 double Num = 0; 759 759 760 760 a->Zero(); 761 761 … … 766 766 tmp.CopyVector(&ptr->x); 767 767 tmp.Scale(ptr->type->mass); // scale by mass 768 a->AddVector(&tmp); 768 a->AddVector(&tmp); 769 769 } 770 770 a->Scale(-1./Num); // divide through total mass (and sign for direction) … … 789 789 Translate(center); 790 790 } 791 }; 791 }; 792 792 793 793 /** Scales all atoms by \a *factor. … … 803 803 Trajectories[ptr].R.at(j).Scale(factor); 804 804 ptr->x.Scale(factor); 805 } 806 }; 807 808 /** Translate all atoms by given vector. 805 } 806 }; 807 808 /** Translate all atoms by given vector. 809 809 * \param trans[] translation vector. 810 810 */ … … 818 818 Trajectories[ptr].R.at(j).Translate(trans); 819 819 ptr->x.Translate(trans); 820 } 821 }; 822 823 /** Mirrors all atoms against a given plane. 820 } 821 }; 822 823 /** Mirrors all atoms against a given plane. 824 824 * \param n[] normal vector of mirror plane. 825 825 */ … … 833 833 Trajectories[ptr].R.at(j).Mirror(n); 834 834 ptr->x.Mirror(n); 835 } 835 } 836 836 }; 837 837 … … 847 847 bool flag; 848 848 Vector Testvector, Translationvector; 849 849 850 850 do { 851 851 Center.Zero(); … … 863 863 if (Walker->nr < Binder->GetOtherAtom(Walker)->nr) // otherwise we shift one to, the other fro and gain nothing 864 864 for (int j=0;j<NDIM;j++) { 865 tmp = Walker->x.x[j] - Binder->GetOtherAtom(Walker)->x.x[j]; 865 tmp = Walker->x.x[j] - Binder->GetOtherAtom(Walker)->x.x[j]; 866 866 if ((fabs(tmp)) > BondDistance) { 867 867 flag = false; … … 879 879 cout << Verbose(1) << "vector is: "; 880 880 Testvector.Output((ofstream *)&cout); 881 cout << endl; 881 cout << endl; 882 882 #ifdef ADDHYDROGEN 883 883 // now also change all hydrogens … … 892 892 cout << Verbose(1) << "Hydrogen vector is: "; 893 893 Testvector.Output((ofstream *)&cout); 894 cout << endl; 894 cout << endl; 895 895 } 896 896 } … … 914 914 915 915 CenterGravity(out, CenterOfGravity); 916 917 // reset inertia tensor 916 917 // reset inertia tensor 918 918 for(int i=0;i<NDIM*NDIM;i++) 919 919 InertiaTensor[i] = 0.; 920 920 921 921 // sum up inertia tensor 922 922 while (ptr->next != end) { … … 943 943 } 944 944 *out << endl; 945 945 946 946 // diagonalize to determine principal axis system 947 947 gsl_eigen_symmv_workspace *T = gsl_eigen_symmv_alloc(NDIM); … … 952 952 gsl_eigen_symmv_free(T); 953 953 gsl_eigen_symmv_sort(eval, evec, GSL_EIGEN_SORT_ABS_DESC); 954 954 955 955 for(int i=0;i<NDIM;i++) { 956 956 *out << Verbose(1) << "eigenvalue = " << gsl_vector_get(eval, i); 957 957 *out << ", eigenvector = (" << evec->data[i * evec->tda + 0] << "," << evec->data[i * evec->tda + 1] << "," << evec->data[i * evec->tda + 2] << ")" << endl; 958 958 } 959 959 960 960 // check whether we rotate or not 961 961 if (DoRotate) { 962 *out << Verbose(1) << "Transforming molecule into PAS ... "; 962 *out << Verbose(1) << "Transforming molecule into PAS ... "; 963 963 // the eigenvectors specify the transformation matrix 964 964 ptr = start; … … 972 972 973 973 // summing anew for debugging (resulting matrix has to be diagonal!) 974 // reset inertia tensor 974 // reset inertia tensor 975 975 for(int i=0;i<NDIM*NDIM;i++) 976 976 InertiaTensor[i] = 0.; 977 977 978 978 // sum up inertia tensor 979 979 ptr = start; … … 1002 1002 *out << endl; 1003 1003 } 1004 1004 1005 1005 // free everything 1006 1006 delete(CenterOfGravity); … … 1031 1031 1032 1032 CountElements(); // make sure ElementsInMolecule is up to date 1033 1033 1034 1034 // check file 1035 1035 if (input == NULL) { … … 1087 1087 Trajectories[walker].U.at(MDSteps).x[d] += 0.5*delta_t*(Trajectories[walker].F.at(MDSteps-1).x[d]+Trajectories[walker].F.at(MDSteps).x[d])/IonMass; 1088 1088 } 1089 // cout << "Integrated position&velocity of step " << (MDSteps) << ": ("; 1089 // cout << "Integrated position&velocity of step " << (MDSteps) << ": ("; 1090 1090 // for (int d=0;d<NDIM;d++) 1091 1091 // cout << Trajectories[walker].R.at(MDSteps).x[d] << " "; // next step … … 1121 1121 MDSteps++; 1122 1122 1123 1123 1124 1124 // exit 1125 1125 return true; 1126 1126 }; 1127 1127 1128 /** Align all atoms in such a manner that given vector \a *n is along z axis. 1128 /** Align all atoms in such a manner that given vector \a *n is along z axis. 1129 1129 * \param n[] alignment vector. 1130 1130 */ … … 1145 1145 ptr = ptr->next; 1146 1146 tmp = ptr->x.x[0]; 1147 ptr->x.x[0] = cos(alpha) * tmp + sin(alpha) * ptr->x.x[2]; 1147 ptr->x.x[0] = cos(alpha) * tmp + sin(alpha) * ptr->x.x[2]; 1148 1148 ptr->x.x[2] = -sin(alpha) * tmp + cos(alpha) * ptr->x.x[2]; 1149 1149 for (int j=0;j<MDSteps;j++) { 1150 1150 tmp = Trajectories[ptr].R.at(j).x[0]; 1151 Trajectories[ptr].R.at(j).x[0] = cos(alpha) * tmp + sin(alpha) * Trajectories[ptr].R.at(j).x[2]; 1151 Trajectories[ptr].R.at(j).x[0] = cos(alpha) * tmp + sin(alpha) * Trajectories[ptr].R.at(j).x[2]; 1152 1152 Trajectories[ptr].R.at(j).x[2] = -sin(alpha) * tmp + cos(alpha) * Trajectories[ptr].R.at(j).x[2]; 1153 1153 } 1154 } 1154 } 1155 1155 // rotate n vector 1156 1156 tmp = n->x[0]; … … 1160 1160 n->Output((ofstream *)&cout); 1161 1161 cout << endl; 1162 1162 1163 1163 // rotate on z-y plane 1164 1164 ptr = start; … … 1168 1168 ptr = ptr->next; 1169 1169 tmp = ptr->x.x[1]; 1170 ptr->x.x[1] = cos(alpha) * tmp + sin(alpha) * ptr->x.x[2]; 1170 ptr->x.x[1] = cos(alpha) * tmp + sin(alpha) * ptr->x.x[2]; 1171 1171 ptr->x.x[2] = -sin(alpha) * tmp + cos(alpha) * ptr->x.x[2]; 1172 1172 for (int j=0;j<MDSteps;j++) { 1173 1173 tmp = Trajectories[ptr].R.at(j).x[1]; 1174 Trajectories[ptr].R.at(j).x[1] = cos(alpha) * tmp + sin(alpha) * Trajectories[ptr].R.at(j).x[2]; 1174 Trajectories[ptr].R.at(j).x[1] = cos(alpha) * tmp + sin(alpha) * Trajectories[ptr].R.at(j).x[2]; 1175 1175 Trajectories[ptr].R.at(j).x[2] = -sin(alpha) * tmp + cos(alpha) * Trajectories[ptr].R.at(j).x[2]; 1176 1176 } 1177 } 1177 } 1178 1178 // rotate n vector (for consistency check) 1179 1179 tmp = n->x[1]; 1180 1180 n->x[1] = cos(alpha) * tmp + sin(alpha) * n->x[2]; 1181 1181 n->x[2] = -sin(alpha) * tmp + cos(alpha) * n->x[2]; 1182 1182 1183 1183 cout << Verbose(1) << "alignment vector after second rotation: "; 1184 1184 n->Output((ofstream *)&cout); … … 1191 1191 * \return true - succeeded, false - atom not found in list 1192 1192 */ 1193 bool molecule::RemoveAtom(atom *pointer) 1194 { 1193 bool molecule::RemoveAtom(atom *pointer) 1194 { 1195 1195 if (ElementsInMolecule[pointer->type->Z] != 0) // this would indicate an error 1196 1196 ElementsInMolecule[pointer->type->Z]--; // decrease number of atom of this element 1197 1197 else 1198 cerr << "ERROR: Atom " << pointer->Name << " is of element " << pointer->type->Z << " but the entry in the table of the molecule is 0!" << endl; 1198 cerr << "ERROR: Atom " << pointer->Name << " is of element " << pointer->type->Z << " but the entry in the table of the molecule is 0!" << endl; 1199 1199 if (ElementsInMolecule[pointer->type->Z] == 0) // was last atom of this element? 1200 1200 ElementCount--; … … 1206 1206 * \return true - succeeded, false - atom not found in list 1207 1207 */ 1208 bool molecule::CleanupMolecule() 1209 { 1210 return (cleanup(start,end) && cleanup(first,last)); 1208 bool molecule::CleanupMolecule() 1209 { 1210 return (cleanup(start,end) && cleanup(first,last)); 1211 1211 }; 1212 1212 … … 1222 1222 } else { 1223 1223 cout << Verbose(0) << "Atom not found in list." << endl; 1224 return NULL; 1224 return NULL; 1225 1225 } 1226 1226 }; … … 1271 1271 struct lsq_params *par = (struct lsq_params *)params; 1272 1272 atom *ptr = par->mol->start; 1273 1273 1274 1274 // initialize vectors 1275 1275 a.x[0] = gsl_vector_get(x,0); … … 1301 1301 { 1302 1302 int np = 6; 1303 1303 1304 1304 const gsl_multimin_fminimizer_type *T = 1305 1305 gsl_multimin_fminimizer_nmsimplex; … … 1307 1307 gsl_vector *ss; 1308 1308 gsl_multimin_function minex_func; 1309 1309 1310 1310 size_t iter = 0, i; 1311 1311 int status; 1312 1312 double size; 1313 1313 1314 1314 /* Initial vertex size vector */ 1315 1315 ss = gsl_vector_alloc (np); 1316 1316 1317 1317 /* Set all step sizes to 1 */ 1318 1318 gsl_vector_set_all (ss, 1.0); 1319 1319 1320 1320 /* Starting point */ 1321 1321 par->x = gsl_vector_alloc (np); 1322 1322 par->mol = this; 1323 1323 1324 1324 gsl_vector_set (par->x, 0, 0.0); // offset 1325 1325 gsl_vector_set (par->x, 1, 0.0); … … 1328 1328 gsl_vector_set (par->x, 4, 0.0); 1329 1329 gsl_vector_set (par->x, 5, 1.0); 1330 1330 1331 1331 /* Initialize method and iterate */ 1332 1332 minex_func.f = &LeastSquareDistance; 1333 1333 minex_func.n = np; 1334 1334 minex_func.params = (void *)par; 1335 1335 1336 1336 s = gsl_multimin_fminimizer_alloc (T, np); 1337 1337 gsl_multimin_fminimizer_set (s, &minex_func, par->x, ss); 1338 1338 1339 1339 do 1340 1340 { 1341 1341 iter++; 1342 1342 status = gsl_multimin_fminimizer_iterate(s); 1343 1343 1344 1344 if (status) 1345 1345 break; 1346 1346 1347 1347 size = gsl_multimin_fminimizer_size (s); 1348 1348 status = gsl_multimin_test_size (size, 1e-2); 1349 1349 1350 1350 if (status == GSL_SUCCESS) 1351 1351 { 1352 1352 printf ("converged to minimum at\n"); 1353 1353 } 1354 1354 1355 1355 printf ("%5d ", (int)iter); 1356 1356 for (i = 0; i < (size_t)np; i++) … … 1361 1361 } 1362 1362 while (status == GSL_CONTINUE && iter < 100); 1363 1363 1364 1364 for (i=0;i<(size_t)np;i++) 1365 1365 gsl_vector_set(par->x, i, gsl_vector_get(s->x, i)); … … 1378 1378 int ElementNo, AtomNo; 1379 1379 CountElements(); 1380 1380 1381 1381 if (out == NULL) { 1382 1382 return false; … … 1413 1413 int ElementNo, AtomNo; 1414 1414 CountElements(); 1415 1415 1416 1416 if (out == NULL) { 1417 1417 return false; … … 1460 1460 atom *Walker = start; 1461 1461 while (Walker->next != end) { 1462 Walker = Walker->next; 1462 Walker = Walker->next; 1463 1463 #ifdef ADDHYDROGEN 1464 1464 if (Walker->type->Z != 1) { // regard only non-hydrogen … … 1491 1491 int No = 0; 1492 1492 time_t now; 1493 1493 1494 1494 now = time((time_t *)NULL); // Get the system time and put it into 'now' as 'calender time' 1495 1495 walker = start; … … 1518 1518 { 1519 1519 atom *walker = NULL; 1520 int AtomNo = 0, ElementNo;1520 int No = 0; 1521 1521 time_t now; 1522 element *runner = NULL; 1523 1522 1524 1523 now = time((time_t *)NULL); // Get the system time and put it into 'now' as 'calender time' 1525 1524 walker = start; 1526 1525 while (walker->next != end) { // go through every atom and count 1527 1526 walker = walker->next; 1528 AtomNo++;1527 No++; 1529 1528 } 1530 1529 if (out != NULL) { 1531 *out << AtomNo << "\n\tCreated by molecuilder on " << ctime(&now); 1532 ElementNo = 0; 1533 runner = elemente->start; 1534 while (runner->next != elemente->end) { // go through every element 1535 runner = runner->next; 1536 if (ElementsInMolecule[runner->Z]) { // if this element got atoms 1537 ElementNo++; 1538 walker = start; 1539 while (walker->next != end) { // go through every atom of this element 1540 walker = walker->next; 1541 if (walker->type == runner) { // if this atom fits to element 1542 walker->OutputXYZLine(out); 1543 } 1544 } 1545 } 1530 *out << No << "\n\tCreated by molecuilder on " << ctime(&now); 1531 walker = start; 1532 while (walker->next != end) { // go through every atom of this element 1533 walker = walker->next; 1534 walker->OutputXYZLine(out); 1546 1535 } 1547 1536 return true; … … 1574 1563 Walker->nr = i; // update number in molecule (for easier referencing in FragmentMolecule lateron) 1575 1564 if (Walker->type->Z != 1) // count non-hydrogen atoms whilst at it 1576 NoNonHydrogen++; 1565 NoNonHydrogen++; 1577 1566 Free((void **)&Walker->Name, "molecule::CountAtoms: *walker->Name"); 1578 1567 Walker->Name = (char *) Malloc(sizeof(char)*6, "molecule::CountAtoms: *walker->Name"); … … 1582 1571 } 1583 1572 } else 1584 *out << Verbose(3) << "AtomCount is still " << AtomCount << ", thus counting nothing." << endl; 1573 *out << Verbose(3) << "AtomCount is still " << AtomCount << ", thus counting nothing." << endl; 1585 1574 } 1586 1575 }; … … 1594 1583 ElementsInMolecule[i] = 0; 1595 1584 ElementCount = 0; 1596 1585 1597 1586 atom *walker = start; 1598 1587 while (walker->next != end) { … … 1630 1619 Binder = Binder->next; 1631 1620 if (Binder->Cyclic) 1632 No++; 1621 No++; 1633 1622 } 1634 1623 delete(BackEdgeStack); … … 1688 1677 1689 1678 /** Creates an adjacency list of the molecule. 1690 * We obtain an outside file with the indices of atoms which are bondmembers.1691 */1692 void molecule::CreateAdjacencyList2(ofstream *out, ifstream *input)1693 {1694 1695 // 1 We will parse bonds out of the dbond file created by tremolo.1696 int atom1, atom2, temp;1697 atom *Walker, *OtherWalker;1698 1699 if (!input)1700 {1701 cout << Verbose(1) << "Opening silica failed \n";1702 };1703 1704 *input >> ws >> atom1;1705 *input >> ws >> atom2;1706 cout << Verbose(1) << "Scanning file\n";1707 while (!input->eof()) // Check whether we read everything already1708 {1709 *input >> ws >> atom1;1710 *input >> ws >> atom2;1711 if(atom2<atom1) //Sort indices of atoms in order1712 {1713 temp=atom1;1714 atom1=atom2;1715 atom2=temp;1716 };1717 1718 Walker=start;1719 while(Walker-> nr != atom1) // Find atom corresponding to first index1720 {1721 Walker = Walker->next;1722 };1723 OtherWalker = Walker->next;1724 while(OtherWalker->nr != atom2) // Find atom corresponding to second index1725 {1726 OtherWalker= OtherWalker->next;1727 };1728 AddBond(Walker, OtherWalker); //Add the bond between the two atoms with respective indices.1729 1730 }1731 1732 CreateListOfBondsPerAtom(out);1733 1734 };1735 1736 1737 /** Creates an adjacency list of the molecule.1738 1679 * Generally, we use the CSD approach to bond recognition, that is the the distance 1739 1680 * between two atoms A and B must be within [Rcov(A)+Rcov(B)-t,Rcov(A)+Rcov(B)+t] with 1740 * a threshold t = 0.4 Angstroem. 1681 * a threshold t = 0.4 Angstroem. 1741 1682 * To make it O(N log N) the function uses the linked-cell technique as follows: 1742 1683 * The procedure is step-wise: … … 1755 1696 void molecule::CreateAdjacencyList(ofstream *out, double bonddistance, bool IsAngstroem) 1756 1697 { 1757 1758 1698 atom *Walker = NULL, *OtherWalker = NULL, *Candidate = NULL; 1759 1699 int No, NoBonds, CandidateBondNo; … … 1764 1704 Vector x; 1765 1705 int FalseBondDegree = 0; 1766 1706 1767 1707 BondDistance = bonddistance; // * ((IsAngstroem) ? 1. : 1./AtomicLengthToAngstroem); 1768 1708 *out << Verbose(0) << "Begin of CreateAdjacencyList." << endl; … … 1771 1711 cleanup(first,last); 1772 1712 } 1773 1713 1774 1714 // count atoms in molecule = dimension of matrix (also give each unique name and continuous numbering) 1775 1715 CountAtoms(out); … … 1790 1730 for (int i=NumberCells;i--;) 1791 1731 CellList[i] = NULL; 1792 1732 1793 1733 // 2b. put all atoms into its corresponding list 1794 1734 Walker = start; … … 1811 1751 if (CellList[index] == NULL) // allocate molecule if not done 1812 1752 CellList[index] = new molecule(elemente); 1813 OtherWalker = CellList[index]->AddCopyAtom(Walker); // add a copy of walker to this atom, father will be walker for later reference 1814 //*out << Verbose(1) << "Copy Atom is " << *OtherWalker << "." << endl; 1753 OtherWalker = CellList[index]->AddCopyAtom(Walker); // add a copy of walker to this atom, father will be walker for later reference 1754 //*out << Verbose(1) << "Copy Atom is " << *OtherWalker << "." << endl; 1815 1755 } 1816 1756 //for (int i=0;i<NumberCells;i++) 1817 1757 //*out << Verbose(1) << "Cell number " << i << ": " << CellList[i] << "." << endl; 1818 1819 1758 1820 1759 // 3a. go through every cell 1821 1760 for (N[0]=divisor[0];N[0]--;) … … 1830 1769 Walker = Walker->next; 1831 1770 //*out << Verbose(0) << "Current Atom is " << *Walker << "." << endl; 1832 // 3c. check for possible bond between each atom in this and every one in the 27 cells 1771 // 3c. check for possible bond between each atom in this and every one in the 27 cells 1833 1772 for (n[0]=-1;n[0]<=1;n[0]++) 1834 1773 for (n[1]=-1;n[1]<=1;n[1]++) … … 1862 1801 } 1863 1802 } 1864 1865 1866 1867 1803 // 4. free the cell again 1868 1804 for (int i=NumberCells;i--;) … … 1871 1807 } 1872 1808 Free((void **)&CellList, "molecule::CreateAdjacencyList - ** CellList"); 1873 1809 1874 1810 // create the adjacency list per atom 1875 1811 CreateListOfBondsPerAtom(out); 1876 1812 1877 1813 // correct Bond degree of each bond by checking both bond partners for a mismatch between valence and current sum of bond degrees, 1878 1814 // iteratively increase the one first where the other bond partner has the fewest number of bonds (i.e. in general bonds oxygene … … 1923 1859 *out << Verbose(1) << "BondCount is " << BondCount << ", no bonds between any of the " << AtomCount << " atoms." << endl; 1924 1860 *out << Verbose(1) << "I detected " << BondCount << " bonds in the molecule with distance " << bonddistance << ", " << FalseBondDegree << " bonds could not be corrected." << endl; 1925 1861 1926 1862 // output bonds for debugging (if bond chain list was correctly installed) 1927 1863 *out << Verbose(1) << endl << "From contents of bond chain list:"; … … 1933 1869 *out << endl; 1934 1870 } else 1935 *out << Verbose(1) << "AtomCount is " << AtomCount << ", thus no bonds, no connections!." << endl; 1871 *out << Verbose(1) << "AtomCount is " << AtomCount << ", thus no bonds, no connections!." << endl; 1936 1872 *out << Verbose(0) << "End of CreateAdjacencyList." << endl; 1937 1873 Free((void **)&matrix, "molecule::CreateAdjacencyList: *matrix"); 1938 1939 }; 1940 1941 1874 }; 1942 1875 1943 1876 /** Performs a Depth-First search on this molecule. … … 1960 1893 bond *Binder = NULL; 1961 1894 bool BackStepping = false; 1962 1895 1963 1896 *out << Verbose(0) << "Begin of DepthFirstSearchAnalysis" << endl; 1964 1897 1965 1898 ResetAllBondsToUnused(); 1966 1899 ResetAllAtomNumbers(); … … 1975 1908 LeafWalker->Leaf = new molecule(elemente); 1976 1909 LeafWalker->Leaf->AddCopyAtom(Root); 1977 1910 1978 1911 OldGraphNr = CurrentGraphNr; 1979 1912 Walker = Root; … … 1986 1919 AtomStack->Push(Walker); 1987 1920 CurrentGraphNr++; 1988 } 1921 } 1989 1922 do { // (3) if Walker has no unused egdes, go to (5) 1990 1923 BackStepping = false; // reset backstepping flag for (8) … … 2020 1953 Binder = NULL; 2021 1954 } while (1); // (2) 2022 1955 2023 1956 // if we came from backstepping, yet there were no more unused bonds, we end up here with no Ancestor, because Walker is Root! Then we are finished! 2024 1957 if ((Walker == Root) && (Binder == NULL)) 2025 1958 break; 2026 2027 // (5) if Ancestor of Walker is ... 1959 1960 // (5) if Ancestor of Walker is ... 2028 1961 *out << Verbose(1) << "(5) Number of Walker[" << Walker->Name << "]'s Ancestor[" << Walker->Ancestor->Name << "] is " << Walker->Ancestor->GraphNr << "." << endl; 2029 1962 if (Walker->Ancestor->GraphNr != Root->GraphNr) { … … 2068 2001 } while (OtherAtom != Walker); 2069 2002 ComponentNumber++; 2070 2003 2071 2004 // (11) Root is separation vertex, set Walker to Root and go to (4) 2072 2005 Walker = Root; … … 2081 2014 2082 2015 // From OldGraphNr to CurrentGraphNr ranges an disconnected subgraph 2083 *out << Verbose(0) << "Disconnected subgraph ranges from " << OldGraphNr << " to " << CurrentGraphNr << "." << endl; 2016 *out << Verbose(0) << "Disconnected subgraph ranges from " << OldGraphNr << " to " << CurrentGraphNr << "." << endl; 2084 2017 LeafWalker->Leaf->Output(out); 2085 2018 *out << endl; … … 2089 2022 //*out << Verbose(1) << "Current next subgraph root candidate is " << Root->Name << "." << endl; 2090 2023 if (Root->GraphNr != -1) // if already discovered, step on 2091 Root = Root->next; 2024 Root = Root->next; 2092 2025 } 2093 2026 } … … 2111 2044 *out << " with Lowpoint " << Walker->LowpointNr << " and Graph Nr. " << Walker->GraphNr << "." << endl; 2112 2045 } 2113 2046 2114 2047 *out << Verbose(1) << "Final graph info for each bond is:" << endl; 2115 2048 Binder = first; … … 2122 2055 *out << ((Binder->rightatom->SeparationVertex) ? "SP," : "") << "L" << Binder->rightatom->LowpointNr << " G" << Binder->rightatom->GraphNr << " Comp."; 2123 2056 OutputComponentNumber(out, Binder->rightatom); 2124 *out << ">." << endl; 2057 *out << ">." << endl; 2125 2058 if (Binder->Cyclic) // cyclic ?? 2126 2059 *out << Verbose(3) << "Lowpoint at each side are equal: CYCLIC!" << endl; … … 2137 2070 * the other our initial Walker - and do a Breadth First Search for the Root. We mark down each Predecessor and as soon as 2138 2071 * we have found the Root via BFS, we may climb back the closed cycle via the Predecessors. Thereby we mark atoms and bonds 2139 * as cyclic and print out the cycles. 2072 * as cyclic and print out the cycles. 2140 2073 * \param *out output stream for debugging 2141 2074 * \param *BackEdgeStack stack with all back edges found during DFS scan. Beware: This stack contains the bonds from the total molecule, not from the subgraph! … … 2148 2081 int *ShortestPathList = (int *) Malloc(sizeof(int)*AtomCount, "molecule::CyclicStructureAnalysis: *ShortestPathList"); 2149 2082 enum Shading *ColorList = (enum Shading *) Malloc(sizeof(enum Shading)*AtomCount, "molecule::CyclicStructureAnalysis: *ColorList"); 2150 class StackClass<atom *> *BFSStack = new StackClass<atom *> (AtomCount); // will hold the current ring 2083 class StackClass<atom *> *BFSStack = new StackClass<atom *> (AtomCount); // will hold the current ring 2151 2084 class StackClass<atom *> *TouchedStack = new StackClass<atom *> (AtomCount); // contains all "touched" atoms (that need to be reset after BFS loop) 2152 2085 atom *Walker = NULL, *OtherAtom = NULL, *Root = NULL; … … 2160 2093 ColorList[i] = white; 2161 2094 } 2162 2095 2163 2096 *out << Verbose(1) << "Back edge list - "; 2164 2097 BackEdgeStack->Output(out); 2165 2098 2166 2099 *out << Verbose(1) << "Analysing cycles ... " << endl; 2167 2100 NumCycles = 0; … … 2169 2102 BackEdge = BackEdgeStack->PopFirst(); 2170 2103 // this is the target 2171 Root = BackEdge->leftatom; 2104 Root = BackEdge->leftatom; 2172 2105 // this is the source point 2173 Walker = BackEdge->rightatom; 2106 Walker = BackEdge->rightatom; 2174 2107 ShortestPathList[Walker->nr] = 0; 2175 2108 BFSStack->ClearStack(); // start with empty BFS stack … … 2185 2118 if (Binder != BackEdge) { // only walk along DFS spanning tree (otherwise we always find SP of one being backedge Binder) 2186 2119 OtherAtom = Binder->GetOtherAtom(Walker); 2187 #ifdef ADDHYDROGEN 2120 #ifdef ADDHYDROGEN 2188 2121 if (OtherAtom->type->Z != 1) { 2189 2122 #endif … … 2194 2127 PredecessorList[OtherAtom->nr] = Walker; // Walker is the predecessor 2195 2128 ShortestPathList[OtherAtom->nr] = ShortestPathList[Walker->nr]+1; 2196 *out << Verbose(2) << "Coloring OtherAtom " << OtherAtom->Name << " lightgray, its predecessor is " << Walker->Name << " and its Shortest Path is " << ShortestPathList[OtherAtom->nr] << " egde(s) long." << endl; 2129 *out << Verbose(2) << "Coloring OtherAtom " << OtherAtom->Name << " lightgray, its predecessor is " << Walker->Name << " and its Shortest Path is " << ShortestPathList[OtherAtom->nr] << " egde(s) long." << endl; 2197 2130 //if (ShortestPathList[OtherAtom->nr] < MinimumRingSize[Walker->GetTrueFather()->nr]) { // Check for maximum distance 2198 2131 *out << Verbose(3) << "Putting OtherAtom into queue." << endl; … … 2204 2137 if (OtherAtom == Root) 2205 2138 break; 2206 #ifdef ADDHYDROGEN 2139 #ifdef ADDHYDROGEN 2207 2140 } else { 2208 2141 *out << Verbose(2) << "Skipping hydrogen atom " << *OtherAtom << "." << endl; … … 2242 2175 } 2243 2176 } while ((!BFSStack->IsEmpty()) && (OtherAtom != Root) && (OtherAtom != NULL)); // || (ShortestPathList[OtherAtom->nr] < MinimumRingSize[Walker->GetTrueFather()->nr]))); 2244 2177 2245 2178 if (OtherAtom == Root) { 2246 2179 // now climb back the predecessor list and thus find the cycle members … … 2270 2203 *out << Verbose(1) << "No ring containing " << *Root << " with length equal to or smaller than " << MinimumRingSize[Walker->GetTrueFather()->nr] << " found." << endl; 2271 2204 } 2272 2205 2273 2206 // now clean the lists 2274 2207 while (!TouchedStack->IsEmpty()){ … … 2280 2213 } 2281 2214 if (MinRingSize != -1) { 2282 // go over all atoms 2215 // go over all atoms 2283 2216 Root = start; 2284 2217 while(Root->next != end) { 2285 2218 Root = Root->next; 2286 2219 2287 2220 if (MinimumRingSize[Root->GetTrueFather()->nr] == AtomCount) { // check whether MinimumRingSize is set, if not BFS to next where it is 2288 2221 Walker = Root; … … 2321 2254 } 2322 2255 ColorList[Walker->nr] = black; 2323 //*out << Verbose(1) << "Coloring Walker " << Walker->Name << " black." << endl; 2256 //*out << Verbose(1) << "Coloring Walker " << Walker->Name << " black." << endl; 2324 2257 } 2325 2258 2326 2259 // now clean the lists 2327 2260 while (!TouchedStack->IsEmpty()){ … … 2372 2305 void molecule::OutputComponentNumber(ofstream *out, atom *vertex) 2373 2306 { 2374 for(int i=0;i<NumberOfBondsPerAtom[vertex->nr];i++) 2307 for(int i=0;i<NumberOfBondsPerAtom[vertex->nr];i++) 2375 2308 *out << vertex->ComponentNr[i] << " "; 2376 2309 }; … … 2450 2383 { 2451 2384 int c = 0; 2452 int FragmentCount; 2385 int FragmentCount; 2453 2386 // get maximum bond degree 2454 2387 atom *Walker = start; … … 2460 2393 *out << Verbose(1) << "Upper limit for this subgraph is " << FragmentCount << " for " << NoNonHydrogen << " non-H atoms with maximum bond degree of " << c << "." << endl; 2461 2394 return FragmentCount; 2462 }; 2395 }; 2463 2396 2464 2397 /** Scans a single line for number and puts them into \a KeySet. 2465 2398 * \param *out output stream for debugging 2466 2399 * \param *buffer buffer to scan 2467 * \param &CurrentSet filled KeySet on return 2400 * \param &CurrentSet filled KeySet on return 2468 2401 * \return true - at least one valid atom id parsed, false - CurrentSet is empty 2469 2402 */ … … 2473 2406 int AtomNr; 2474 2407 int status = 0; 2475 2408 2476 2409 line.str(buffer); 2477 2410 while (!line.eof()) { … … 2509 2442 double TEFactor; 2510 2443 char *filename = (char *) Malloc(sizeof(char)*MAXSTRINGSIZE, "molecule::ParseKeySetFile - filename"); 2511 2444 2512 2445 if (FragmentList == NULL) { // check list pointer 2513 2446 FragmentList = new Graph; 2514 2447 } 2515 2448 2516 2449 // 1st pass: open file and read 2517 2450 *out << Verbose(1) << "Parsing the KeySet file ... " << endl; … … 2542 2475 status = false; 2543 2476 } 2544 2477 2545 2478 // 2nd pass: open TEFactors file and read 2546 2479 *out << Verbose(1) << "Parsing the TEFactors file ... " << endl; … … 2554 2487 InputFile >> TEFactor; 2555 2488 (*runner).second.second = TEFactor; 2556 *out << Verbose(2) << "Setting " << ++NumberOfFragments << " fragment's TEFactor to " << (*runner).second.second << "." << endl; 2489 *out << Verbose(2) << "Setting " << ++NumberOfFragments << " fragment's TEFactor to " << (*runner).second.second << "." << endl; 2557 2490 } else { 2558 2491 status = false; … … 2595 2528 if(output != NULL) { 2596 2529 for(Graph::iterator runner = KeySetList.begin(); runner != KeySetList.end(); runner++) { 2597 for (KeySet::iterator sprinter = (*runner).first.begin();sprinter != (*runner).first.end(); sprinter++) { 2530 for (KeySet::iterator sprinter = (*runner).first.begin();sprinter != (*runner).first.end(); sprinter++) { 2598 2531 if (sprinter != (*runner).first.begin()) 2599 2532 output << "\t"; … … 2661 2594 status = false; 2662 2595 } 2663 2596 2664 2597 return status; 2665 2598 }; … … 2670 2603 * \param **ListOfAtoms allocated (molecule::AtomCount) and filled lookup table for ids (Atom::nr) to *Atom 2671 2604 * \return true - structure is equal, false - not equivalence 2672 */ 2605 */ 2673 2606 bool molecule::CheckAdjacencyFileAgainstMolecule(ofstream *out, char *path, atom **ListOfAtoms) 2674 2607 { … … 2677 2610 bool status = true; 2678 2611 char *buffer = (char *) Malloc(sizeof(char)*MAXSTRINGSIZE, "molecule::CheckAdjacencyFileAgainstMolecule: *buffer"); 2679 2612 2680 2613 filename << path << "/" << FRAGMENTPREFIX << ADJACENCYFILE; 2681 2614 File.open(filename.str().c_str(), ios::out); … … 2736 2669 *out << endl; 2737 2670 Free((void **)&buffer, "molecule::CheckAdjacencyFileAgainstMolecule: *buffer"); 2738 2671 2739 2672 return status; 2740 2673 }; … … 2758 2691 for(int i=AtomCount;i--;) 2759 2692 AtomMask[i] = false; 2760 2693 2761 2694 if (Order < 0) { // adaptive increase of BondOrder per site 2762 2695 if (AtomMask[AtomCount] == true) // break after one step … … 2798 2731 line >> ws >> Value; // skip time entry 2799 2732 line >> ws >> Value; 2800 No -= 1; // indices start at 1 in file, not 0 2733 No -= 1; // indices start at 1 in file, not 0 2801 2734 //*out << Verbose(2) << " - yields (" << No << "," << Value << ", " << FragOrder << ")" << endl; 2802 2735 … … 2807 2740 // as the smallest number in each set has always been the root (we use global id to keep the doubles away), seek smallest and insert into AtomMask 2808 2741 pair <map<int, pair<double,int> >::iterator, bool> InsertedElement = AdaptiveCriteriaList.insert( make_pair(*((*marker).second.begin()), pair<double,int>( fabs(Value), FragOrder) )); 2809 map<int, pair<double,int> >::iterator PresentItem = InsertedElement.first; 2742 map<int, pair<double,int> >::iterator PresentItem = InsertedElement.first; 2810 2743 if (!InsertedElement.second) { // this root is already present 2811 if ((*PresentItem).second.second < FragOrder) // if order there is lower, update entry with higher-order term 2812 //if ((*PresentItem).second.first < (*runner).first) // as higher-order terms are not always better, we skip this part (which would always include this site into adaptive increase) 2744 if ((*PresentItem).second.second < FragOrder) // if order there is lower, update entry with higher-order term 2745 //if ((*PresentItem).second.first < (*runner).first) // as higher-order terms are not always better, we skip this part (which would always include this site into adaptive increase) 2813 2746 { // if value is smaller, update value and order 2814 2747 (*PresentItem).second.first = fabs(Value); … … 2848 2781 Walker = FindAtom(No); 2849 2782 //if (Walker->AdaptiveOrder < MinimumRingSize[Walker->nr]) { 2850 *out << Verbose(2) << "Root " << No << " is still above threshold (10^{" << Order <<"}: " << runner->first << ", setting entry " << No << " of Atom mask to true." << endl; 2783 *out << Verbose(2) << "Root " << No << " is still above threshold (10^{" << Order <<"}: " << runner->first << ", setting entry " << No << " of Atom mask to true." << endl; 2851 2784 AtomMask[No] = true; 2852 2785 status = true; 2853 2786 //} else 2854 //*out << Verbose(2) << "Root " << No << " is still above threshold (10^{" << Order <<"}: " << runner->first << ", however MinimumRingSize of " << MinimumRingSize[Walker->nr] << " does not allow further adaptive increase." << endl; 2787 //*out << Verbose(2) << "Root " << No << " is still above threshold (10^{" << Order <<"}: " << runner->first << ", however MinimumRingSize of " << MinimumRingSize[Walker->nr] << " does not allow further adaptive increase." << endl; 2855 2788 } 2856 2789 // close and done … … 2886 2819 if ((Order == 0) && (AtomMask[AtomCount] == false)) // single stepping, just check 2887 2820 status = true; 2888 2821 2889 2822 if (!status) { 2890 2823 if (Order == 0) … … 2894 2827 } 2895 2828 } 2896 2829 2897 2830 // print atom mask for debugging 2898 2831 *out << " "; … … 2903 2836 *out << (AtomMask[i] ? "t" : "f"); 2904 2837 *out << endl; 2905 2838 2906 2839 return status; 2907 2840 }; … … 2917 2850 int AtomNo = 0; 2918 2851 atom *Walker = NULL; 2919 2852 2920 2853 if (SortIndex != NULL) { 2921 2854 *out << Verbose(1) << "SortIndex is " << SortIndex << " and not NULL as expected." << endl; … … 2975 2908 atom **ListOfAtoms = NULL; 2976 2909 atom ***ListOfLocalAtoms = NULL; 2977 bool *AtomMask = NULL; 2978 2910 bool *AtomMask = NULL; 2911 2979 2912 *out << endl; 2980 2913 #ifdef ADDHYDROGEN … … 2985 2918 2986 2919 // ++++++++++++++++++++++++++++ INITIAL STUFF: Bond structure analysis, file parsing, ... ++++++++++++++++++++++++++++++++++++++++++ 2987 2920 2988 2921 // ===== 1. Check whether bond structure is same as stored in files ==== 2989 2922 2990 2923 // fill the adjacency list 2991 2924 CreateListOfBondsPerAtom(out); … … 2993 2926 // create lookup table for Atom::nr 2994 2927 FragmentationToDo = FragmentationToDo && CreateFatherLookupTable(out, start, end, ListOfAtoms, AtomCount); 2995 2928 2996 2929 // === compare it with adjacency file === 2997 FragmentationToDo = FragmentationToDo && CheckAdjacencyFileAgainstMolecule(out, configuration->configpath, ListOfAtoms); 2930 FragmentationToDo = FragmentationToDo && CheckAdjacencyFileAgainstMolecule(out, configuration->configpath, ListOfAtoms); 2998 2931 Free((void **)&ListOfAtoms, "molecule::FragmentMolecule - **ListOfAtoms"); 2999 2932 … … 3024 2957 delete(LocalBackEdgeStack); 3025 2958 } 3026 2959 3027 2960 // ===== 3. if structure still valid, parse key set file and others ===== 3028 2961 FragmentationToDo = FragmentationToDo && ParseKeySetFile(out, configuration->configpath, ParsedFragmentList); … … 3030 2963 // ===== 4. check globally whether there's something to do actually (first adaptivity check) 3031 2964 FragmentationToDo = FragmentationToDo && ParseOrderAtSiteFromFile(out, configuration->configpath); 3032 3033 // =================================== Begin of FRAGMENTATION =============================== 3034 // ===== 6a. assign each keyset to its respective subgraph ===== 2965 2966 // =================================== Begin of FRAGMENTATION =============================== 2967 // ===== 6a. assign each keyset to its respective subgraph ===== 3035 2968 Subgraphs->next->AssignKeySetsToFragment(out, this, ParsedFragmentList, ListOfLocalAtoms, FragmentList, (FragmentCounter = 0), true); 3036 2969 … … 3043 2976 FragmentationToDo = FragmentationToDo || CheckOrder; 3044 2977 AtomMask[AtomCount] = true; // last plus one entry is used as marker that we have been through this loop once already in CheckOrderAtSite() 3045 // ===== 6b. fill RootStack for each subgraph (second adaptivity check) ===== 2978 // ===== 6b. fill RootStack for each subgraph (second adaptivity check) ===== 3046 2979 Subgraphs->next->FillRootStackForSubgraphs(out, RootStack, AtomMask, (FragmentCounter = 0)); 3047 2980 … … 3067 3000 delete(ParsedFragmentList); 3068 3001 delete[](MinimumRingSize); 3069 3002 3070 3003 3071 3004 // ==================================== End of FRAGMENTATION ============================================ … … 3073 3006 // ===== 8a. translate list into global numbers (i.e. ones that are valid in "this" molecule, not in MolecularWalker->Leaf) 3074 3007 Subgraphs->next->TranslateIndicesToGlobalIDs(out, FragmentList, (FragmentCounter = 0), TotalNumberOfKeySets, TotalGraph); 3075 3008 3076 3009 // free subgraph memory again 3077 3010 FragmentCounter = 0; … … 3098 3031 } 3099 3032 *out << k << "/" << BondFragments->NumberOfMolecules << " fragments generated from the keysets." << endl; 3100 3033 3101 3034 // ===== 9. Save fragments' configuration and keyset files et al to disk === 3102 3035 if (BondFragments->NumberOfMolecules != 0) { 3103 3036 // create the SortIndex from BFS labels to order in the config file 3104 3037 CreateMappingLabelsToConfigSequence(out, SortIndex); 3105 3038 3106 3039 *out << Verbose(1) << "Writing " << BondFragments->NumberOfMolecules << " possible bond fragmentation configs" << endl; 3107 3040 if (BondFragments->OutputConfigForListOfFragments(out, configuration, SortIndex)) … … 3109 3042 else 3110 3043 *out << Verbose(1) << "Some config writing failed." << endl; 3111 3044 3112 3045 // store force index reference file 3113 3046 BondFragments->StoreForcesFile(out, configuration->configpath, SortIndex); 3114 3115 // store keysets file 3047 3048 // store keysets file 3116 3049 StoreKeySetFile(out, TotalGraph, configuration->configpath); 3117 3118 // store Adjacency file 3050 3051 // store Adjacency file 3119 3052 StoreAdjacencyToFile(out, configuration->configpath); 3120 3053 3121 3054 // store Hydrogen saturation correction file 3122 3055 BondFragments->AddHydrogenCorrection(out, configuration->configpath); 3123 3056 3124 3057 // store adaptive orders into file 3125 3058 StoreOrderAtSiteFile(out, configuration->configpath); 3126 3059 3127 3060 // restore orbital and Stop values 3128 3061 CalculateOrbitals(*configuration); 3129 3062 3130 3063 // free memory for bond part 3131 3064 *out << Verbose(1) << "Freeing bond memory" << endl; 3132 3065 delete(FragmentList); // remove bond molecule from memory 3133 Free((void **)&SortIndex, "molecule::FragmentMolecule: *SortIndex"); 3066 Free((void **)&SortIndex, "molecule::FragmentMolecule: *SortIndex"); 3134 3067 } else 3135 3068 *out << Verbose(1) << "FragmentList is zero on return, splitting failed." << endl; 3136 //} else 3069 //} else 3137 3070 // *out << Verbose(1) << "No fragments to store." << endl; 3138 3071 *out << Verbose(0) << "End of bond fragmentation." << endl; … … 3160 3093 atom *Walker = NULL, *OtherAtom = NULL; 3161 3094 ReferenceStack->Push(Binder); 3162 3095 3163 3096 do { // go through all bonds and push local ones 3164 3097 Walker = ListOfLocalAtoms[Binder->leftatom->nr]; // get one atom in the reference molecule 3165 if (Walker != NULL) // if this Walker exists in the subgraph ... 3098 if (Walker != NULL) // if this Walker exists in the subgraph ... 3166 3099 for(int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++) { // go through the local list of bonds 3167 3100 OtherAtom = ListOfBondsPerAtom[Walker->nr][i]->GetOtherAtom(Walker); … … 3176 3109 ReferenceStack->Push(Binder); 3177 3110 } while (FirstBond != Binder); 3178 3111 3179 3112 return status; 3180 3113 }; … … 3252 3185 Walker->AdaptiveOrder = OrderArray[Walker->nr]; 3253 3186 Walker->MaxOrder = MaxArray[Walker->nr]; 3254 *out << Verbose(2) << *Walker << " gets order " << (int)Walker->AdaptiveOrder << " and is " << (!Walker->MaxOrder ? "not " : " ") << "maxed." << endl; 3187 *out << Verbose(2) << *Walker << " gets order " << (int)Walker->AdaptiveOrder << " and is " << (!Walker->MaxOrder ? "not " : " ") << "maxed." << endl; 3255 3188 } 3256 3189 file.close(); … … 3263 3196 Free((void **)&OrderArray, "molecule::ParseOrderAtSiteFromFile - *OrderArray"); 3264 3197 Free((void **)&MaxArray, "molecule::ParseOrderAtSiteFromFile - *MaxArray"); 3265 3198 3266 3199 *out << Verbose(1) << "End of ParseOrderAtSiteFromFile" << endl; 3267 3200 return status; … … 3321 3254 Walker = start; 3322 3255 while (Walker->next != end) { 3323 Walker = Walker->next; 3256 Walker = Walker->next; 3324 3257 *out << Verbose(4) << "Atom " << Walker->Name << "/" << Walker->nr << " with " << NumberOfBondsPerAtom[Walker->nr] << " bonds: "; 3325 3258 TotalDegree = 0; … … 3329 3262 } 3330 3263 *out << " -- TotalDegree: " << TotalDegree << endl; 3331 } 3264 } 3332 3265 *out << Verbose(1) << "End of Creating ListOfBondsPerAtom." << endl << endl; 3333 3266 }; … … 3335 3268 /** Adds atoms up to \a BondCount distance from \a *Root and notes them down in \a **AddedAtomList. 3336 3269 * Gray vertices are always enqueued in an StackClass<atom *> FIFO queue, the rest is usual BFS with adding vertices found was 3337 * white and putting into queue. 3270 * white and putting into queue. 3338 3271 * \param *out output stream for debugging 3339 3272 * \param *Mol Molecule class to add atoms to … … 3344 3277 * \param BondOrder maximum distance for vertices to add 3345 3278 * \param IsAngstroem lengths are in angstroem or bohrradii 3346 */ 3279 */ 3347 3280 void molecule::BreadthFirstSearchAdd(ofstream *out, molecule *Mol, atom **&AddedAtomList, bond **&AddedBondList, atom *Root, bond *Bond, int BondOrder, bool IsAngstroem) 3348 3281 { … … 3370 3303 } 3371 3304 ShortestPathList[Root->nr] = 0; 3372 3305 3373 3306 // and go on ... Queue always contains all lightgray vertices 3374 3307 while (!AtomStack->IsEmpty()) { … … 3378 3311 // followed by n+1 till top of stack. 3379 3312 Walker = AtomStack->PopFirst(); // pop oldest added 3380 *out << Verbose(1) << "Current Walker is: " << Walker->Name << ", and has " << NumberOfBondsPerAtom[Walker->nr] << " bonds." << endl; 3313 *out << Verbose(1) << "Current Walker is: " << Walker->Name << ", and has " << NumberOfBondsPerAtom[Walker->nr] << " bonds." << endl; 3381 3314 for(int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++) { 3382 3315 Binder = ListOfBondsPerAtom[Walker->nr][i]; … … 3385 3318 *out << Verbose(2) << "Current OtherAtom is: " << OtherAtom->Name << " for bond " << *Binder << "." << endl; 3386 3319 if (ColorList[OtherAtom->nr] == white) { 3387 if (Binder != Bond) // let other atom white if it's via Root bond. In case it's cyclic it has to be reached again (yet Root is from OtherAtom already black, thus no problem) 3320 if (Binder != Bond) // let other atom white if it's via Root bond. In case it's cyclic it has to be reached again (yet Root is from OtherAtom already black, thus no problem) 3388 3321 ColorList[OtherAtom->nr] = lightgray; 3389 3322 PredecessorList[OtherAtom->nr] = Walker; // Walker is the predecessor 3390 3323 ShortestPathList[OtherAtom->nr] = ShortestPathList[Walker->nr]+1; 3391 *out << Verbose(2) << "Coloring OtherAtom " << OtherAtom->Name << " " << ((ColorList[OtherAtom->nr] == white) ? "white" : "lightgray") << ", its predecessor is " << Walker->Name << " and its Shortest Path is " << ShortestPathList[OtherAtom->nr] << " egde(s) long." << endl; 3324 *out << Verbose(2) << "Coloring OtherAtom " << OtherAtom->Name << " " << ((ColorList[OtherAtom->nr] == white) ? "white" : "lightgray") << ", its predecessor is " << Walker->Name << " and its Shortest Path is " << ShortestPathList[OtherAtom->nr] << " egde(s) long." << endl; 3392 3325 if ((((ShortestPathList[OtherAtom->nr] < BondOrder) && (Binder != Bond))) ) { // Check for maximum distance 3393 3326 *out << Verbose(3); … … 3437 3370 // This has to be a cyclic bond, check whether it's present ... 3438 3371 if (AddedBondList[Binder->nr] == NULL) { 3439 if ((Binder != Bond) && (Binder->Cyclic) && (((ShortestPathList[Walker->nr]+1) < BondOrder))) { 3372 if ((Binder != Bond) && (Binder->Cyclic) && (((ShortestPathList[Walker->nr]+1) < BondOrder))) { 3440 3373 AddedBondList[Binder->nr] = Mol->AddBond(AddedAtomList[Walker->nr], AddedAtomList[OtherAtom->nr], Binder->BondDegree); 3441 3374 AddedBondList[Binder->nr]->Cyclic = Binder->Cyclic; … … 3452 3385 } 3453 3386 ColorList[Walker->nr] = black; 3454 *out << Verbose(1) << "Coloring Walker " << Walker->Name << " black." << endl; 3387 *out << Verbose(1) << "Coloring Walker " << Walker->Name << " black." << endl; 3455 3388 } 3456 3389 Free((void **)&PredecessorList, "molecule::BreadthFirstSearchAdd: **PredecessorList"); … … 3476 3409 3477 3410 *out << Verbose(2) << "Begin of BuildInducedSubgraph." << endl; 3478 3411 3479 3412 // reset parent list 3480 3413 *out << Verbose(3) << "Resetting ParentList." << endl; 3481 3414 for (int i=Father->AtomCount;i--;) 3482 3415 ParentList[i] = NULL; 3483 3416 3484 3417 // fill parent list with sons 3485 3418 *out << Verbose(3) << "Filling Parent List." << endl; … … 3522 3455 * \param *&Leaf KeySet to look through 3523 3456 * \param *&ShortestPathList list of the shortest path to decide which atom to suggest as removal candidate in the end 3524 * \param index of the atom suggested for removal 3457 * \param index of the atom suggested for removal 3525 3458 */ 3526 3459 int molecule::LookForRemovalCandidate(ofstream *&out, KeySet *&Leaf, int *&ShortestPathList) … … 3528 3461 atom *Runner = NULL; 3529 3462 int SP, Removal; 3530 3463 3531 3464 *out << Verbose(2) << "Looking for removal candidate." << endl; 3532 3465 SP = -1; //0; // not -1, so that Root is never removed … … 3546 3479 /** Stores a fragment from \a KeySet into \a molecule. 3547 3480 * First creates the minimal set of atoms from the KeySet, then creates the bond structure from the complete 3548 * molecule and adds missing hydrogen where bonds were cut. 3481 * molecule and adds missing hydrogen where bonds were cut. 3549 3482 * \param *out output stream for debugging messages 3550 * \param &Leaflet pointer to KeySet structure 3483 * \param &Leaflet pointer to KeySet structure 3551 3484 * \param IsAngstroem whether we have Ansgtroem or bohrradius 3552 3485 * \return pointer to constructed molecule … … 3559 3492 bool LonelyFlag = false; 3560 3493 int size; 3561 3494 3562 3495 // *out << Verbose(1) << "Begin of StoreFragmentFromKeyset." << endl; 3563 3496 3564 3497 Leaf->BondDistance = BondDistance; 3565 3498 for(int i=NDIM*2;i--;) 3566 Leaf->cell_size[i] = cell_size[i]; 3499 Leaf->cell_size[i] = cell_size[i]; 3567 3500 3568 3501 // initialise SonList (indicates when we need to replace a bond with hydrogen instead) … … 3577 3510 size++; 3578 3511 } 3579 3512 3580 3513 // create the bonds between all: Make it an induced subgraph and add hydrogen 3581 3514 // *out << Verbose(2) << "Creating bonds from father graph (i.e. induced subgraph creation)." << endl; … … 3587 3520 if (SonList[FatherOfRunner->nr] != NULL) { // check if this, our father, is present in list 3588 3521 // create all bonds 3589 for (int i=0;i<NumberOfBondsPerAtom[FatherOfRunner->nr];i++) { // go through every bond of father 3522 for (int i=0;i<NumberOfBondsPerAtom[FatherOfRunner->nr];i++) { // go through every bond of father 3590 3523 OtherFather = ListOfBondsPerAtom[FatherOfRunner->nr][i]->GetOtherAtom(FatherOfRunner); 3591 3524 // *out << Verbose(2) << "Father " << *FatherOfRunner << " of son " << *SonList[FatherOfRunner->nr] << " is bound to " << *OtherFather; 3592 3525 if (SonList[OtherFather->nr] != NULL) { 3593 // *out << ", whose son is " << *SonList[OtherFather->nr] << "." << endl; 3526 // *out << ", whose son is " << *SonList[OtherFather->nr] << "." << endl; 3594 3527 if (OtherFather->nr > FatherOfRunner->nr) { // add bond (nr check is for adding only one of both variants: ab, ba) 3595 3528 // *out << Verbose(3) << "Adding Bond: "; 3596 // *out << 3529 // *out << 3597 3530 Leaf->AddBond(Runner, SonList[OtherFather->nr], ListOfBondsPerAtom[FatherOfRunner->nr][i]->BondDegree); 3598 3531 // *out << "." << endl; 3599 3532 //NumBonds[Runner->nr]++; 3600 } else { 3533 } else { 3601 3534 // *out << Verbose(3) << "Not adding bond, labels in wrong order." << endl; 3602 3535 } 3603 3536 LonelyFlag = false; 3604 3537 } else { 3605 // *out << ", who has no son in this fragment molecule." << endl; 3538 // *out << ", who has no son in this fragment molecule." << endl; 3606 3539 #ifdef ADDHYDROGEN 3607 3540 //*out << Verbose(3) << "Adding Hydrogen to " << Runner->Name << " and a bond in between." << endl; … … 3621 3554 while ((Runner->next != Leaf->end) && (Runner->next->type->Z == 1)) // skip added hydrogen 3622 3555 Runner = Runner->next; 3623 #endif 3556 #endif 3624 3557 } 3625 3558 Leaf->CreateListOfBondsPerAtom(out); … … 3654 3587 StackClass<atom *> *TouchedStack = new StackClass<atom *>((int)pow(4,Order)+2); // number of atoms reached from one with maximal 4 bonds plus Root itself 3655 3588 StackClass<atom *> *SnakeStack = new StackClass<atom *>(Order+1); // equal to Order is not possible, as then the StackClass<atom *> cannot discern between full and empty stack! 3656 MoleculeLeafClass *Leaflet = NULL, *TempLeaf = NULL; 3589 MoleculeLeafClass *Leaflet = NULL, *TempLeaf = NULL; 3657 3590 MoleculeListClass *FragmentList = NULL; 3658 3591 atom *Walker = NULL, *OtherAtom = NULL, *Root = NULL, *Removal = NULL; … … 3704 3637 // clear snake stack 3705 3638 SnakeStack->ClearStack(); 3706 //SnakeStack->TestImplementation(out, start->next); 3639 //SnakeStack->TestImplementation(out, start->next); 3707 3640 3708 3641 ///// INNER LOOP //////////// … … 3725 3658 } 3726 3659 if (ShortestPathList[Walker->nr] == -1) { 3727 ShortestPathList[Walker->nr] = ShortestPathList[PredecessorList[Walker->nr]->nr]+1; 3660 ShortestPathList[Walker->nr] = ShortestPathList[PredecessorList[Walker->nr]->nr]+1; 3728 3661 TouchedStack->Push(Walker); // mark every atom for lists cleanup later, whose shortest path has been changed 3729 3662 } … … 3763 3696 OtherAtom = Binder->GetOtherAtom(Walker); 3764 3697 if ((Labels[OtherAtom->nr] != -1) && (Labels[OtherAtom->nr] < Labels[Root->nr])) { // we don't step up to labels bigger than us 3765 *out << "Label " << Labels[OtherAtom->nr] << " is smaller than Root's " << Labels[Root->nr] << "." << endl; 3698 *out << "Label " << Labels[OtherAtom->nr] << " is smaller than Root's " << Labels[Root->nr] << "." << endl; 3766 3699 //ColorVertexList[OtherAtom->nr] = lightgray; // mark as explored 3767 3700 } else { // otherwise check its colour and element 3768 3701 if ( 3769 3702 #ifdef ADDHYDROGEN 3770 (OtherAtom->type->Z != 1) && 3703 (OtherAtom->type->Z != 1) && 3771 3704 #endif 3772 3705 (ColorEdgeList[Binder->nr] == white)) { // skip hydrogen, look for unexplored vertices … … 3778 3711 //} else { 3779 3712 // *out << Verbose(3) << "Predecessor of " << OtherAtom->Name << " is " << PredecessorList[OtherAtom->nr]->Name << "." << endl; 3780 //} 3713 //} 3781 3714 Walker = OtherAtom; 3782 3715 break; 3783 3716 } else { 3784 if (OtherAtom->type->Z == 1) 3717 if (OtherAtom->type->Z == 1) 3785 3718 *out << "Links to a hydrogen atom." << endl; 3786 else 3719 else 3787 3720 *out << "Bond has not white but " << GetColor(ColorEdgeList[Binder->nr]) << " color." << endl; 3788 3721 } … … 3794 3727 *out << Verbose(3) << "We have gone too far, stepping back to " << Walker->Name << "." << endl; 3795 3728 } 3796 if (Walker != OtherAtom) { // if no white neighbours anymore, color it black 3729 if (Walker != OtherAtom) { // if no white neighbours anymore, color it black 3797 3730 *out << Verbose(2) << "Coloring " << Walker->Name << " black." << endl; 3798 3731 ColorVertexList[Walker->nr] = black; … … 3801 3734 } 3802 3735 } while ((Walker != Root) || (ColorVertexList[Root->nr] != black)); 3803 *out << Verbose(2) << "Inner Looping is finished." << endl; 3736 *out << Verbose(2) << "Inner Looping is finished." << endl; 3804 3737 3805 3738 // if we reset all AtomCount atoms, we have again technically O(N^2) ... … … 3817 3750 } 3818 3751 } 3819 *out << Verbose(1) << "Outer Looping over all vertices is done." << endl; 3752 *out << Verbose(1) << "Outer Looping over all vertices is done." << endl; 3820 3753 3821 3754 // copy together 3822 *out << Verbose(1) << "Copying all fragments into MoleculeList structure." << endl; 3755 *out << Verbose(1) << "Copying all fragments into MoleculeList structure." << endl; 3823 3756 FragmentList = new MoleculeListClass(FragmentCounter, AtomCount); 3824 3757 RunningIndex = 0; … … 3891 3824 3892 3825 NumCombinations = 1 << SetDimension; 3893 3826 3894 3827 // Hier muessen von 1 bis NumberOfBondsPerAtom[Walker->nr] alle Kombinationen 3895 3828 // von Endstuecken (aus den Bonds) hinzugefᅵᅵgt werden und fᅵᅵr verbleibende ANOVAOrder 3896 3829 // rekursiv GraphCrawler in der nᅵᅵchsten Ebene aufgerufen werden 3897 3830 3898 3831 *out << Verbose(1+verbosity) << "Begin of SPFragmentGenerator." << endl; 3899 3832 *out << Verbose(1+verbosity) << "We are " << RootDistance << " away from Root, which is " << *FragmentSearch->Root << ", SubOrder is " << SubOrder << ", SetDimension is " << SetDimension << " and this means " << NumCombinations-1 << " combination(s)." << endl; 3900 3833 3901 // initialised touched list (stores added atoms on this level) 3834 // initialised touched list (stores added atoms on this level) 3902 3835 *out << Verbose(1+verbosity) << "Clearing touched list." << endl; 3903 3836 for (TouchedIndex=SubOrder+1;TouchedIndex--;) // empty touched list 3904 3837 TouchedList[TouchedIndex] = -1; 3905 3838 TouchedIndex = 0; 3906 3839 3907 3840 // create every possible combination of the endpieces 3908 3841 *out << Verbose(1+verbosity) << "Going through all combinations of the power set." << endl; … … 3912 3845 for (int j=SetDimension;j--;) 3913 3846 bits += (i & (1 << j)) >> j; 3914 3847 3915 3848 *out << Verbose(1+verbosity) << "Current set is " << Binary(i | (1 << SetDimension)) << ", number of bits is " << bits << "." << endl; 3916 3849 if (bits <= SubOrder) { // if not greater than additional atoms allowed on stack, continue … … 3920 3853 bit = ((i & (1 << j)) != 0); // mask the bit for the j-th bond 3921 3854 if (bit) { // if bit is set, we add this bond partner 3922 OtherWalker = BondsSet[j]->rightatom; // rightatom is always the one more distant, i.e. the one to add 3855 OtherWalker = BondsSet[j]->rightatom; // rightatom is always the one more distant, i.e. the one to add 3923 3856 //*out << Verbose(1+verbosity) << "Current Bond is " << ListOfBondsPerAtom[Walker->nr][i] << ", checking on " << *OtherWalker << "." << endl; 3924 3857 *out << Verbose(2+verbosity) << "Adding " << *OtherWalker << " with nr " << OtherWalker->nr << "." << endl; 3925 TestKeySetInsert = FragmentSearch->FragmentSet->insert(OtherWalker->nr); 3858 TestKeySetInsert = FragmentSearch->FragmentSet->insert(OtherWalker->nr); 3926 3859 if (TestKeySetInsert.second) { 3927 3860 TouchedList[TouchedIndex++] = OtherWalker->nr; // note as added … … 3936 3869 } 3937 3870 } 3938 3939 SpaceLeft = SubOrder - Added ;// SubOrder - bits; // due to item's maybe being already present, this does not work anymore 3871 3872 SpaceLeft = SubOrder - Added ;// SubOrder - bits; // due to item's maybe being already present, this does not work anymore 3940 3873 if (SpaceLeft > 0) { 3941 3874 *out << Verbose(1+verbosity) << "There's still some space left on stack: " << SpaceLeft << "." << endl; … … 3965 3898 } 3966 3899 *out << Verbose(2+verbosity) << "Calling subset generator " << SP << " away from root " << *FragmentSearch->Root << " with sub set dimension " << SubSetDimension << "." << endl; 3967 SPFragmentGenerator(out, FragmentSearch, SP, BondsList, SubSetDimension, SubOrder-bits); 3900 SPFragmentGenerator(out, FragmentSearch, SP, BondsList, SubSetDimension, SubOrder-bits); 3968 3901 Free((void **)&BondsList, "molecule::SPFragmentGenerator: **BondsList"); 3969 3902 } … … 3974 3907 *out << Verbose(2) << "Found a new fragment[" << FragmentSearch->FragmentCounter << "], local nr.s are: "; 3975 3908 for(KeySet::iterator runner = FragmentSearch->FragmentSet->begin(); runner != FragmentSearch->FragmentSet->end(); runner++) 3976 *out << (*runner) << " "; 3909 *out << (*runner) << " "; 3977 3910 *out << endl; 3978 3911 //if (!CheckForConnectedSubgraph(out, FragmentSearch->FragmentSet)) … … 3982 3915 //Removal = StoreFragmentFromStack(out, FragmentSearch->Root, FragmentSearch->Leaflet, FragmentSearch->FragmentStack, FragmentSearch->ShortestPathList, &FragmentSearch->FragmentCounter, FragmentSearch->configuration); 3983 3916 } 3984 3917 3985 3918 // --3-- remove all added items in this level from snake stack 3986 3919 *out << Verbose(1+verbosity) << "Removing all items that were added on this SP level " << RootDistance << "." << endl; … … 3993 3926 *out << Verbose(2) << "Remaining local nr.s on snake stack are: "; 3994 3927 for(KeySet::iterator runner = FragmentSearch->FragmentSet->begin(); runner != FragmentSearch->FragmentSet->end(); runner++) 3995 *out << (*runner) << " "; 3928 *out << (*runner) << " "; 3996 3929 *out << endl; 3997 3930 TouchedIndex = 0; // set Index to 0 for list of atoms added on this level … … 4000 3933 } 4001 3934 } 4002 Free((void **)&TouchedList, "molecule::SPFragmentGenerator: *TouchedList"); 3935 Free((void **)&TouchedList, "molecule::SPFragmentGenerator: *TouchedList"); 4003 3936 *out << Verbose(1+verbosity) << "End of SPFragmentGenerator, " << RootDistance << " away from Root " << *FragmentSearch->Root << " and SubOrder is " << SubOrder << "." << endl; 4004 3937 }; … … 4009 3942 * \return true - connected, false - disconnected 4010 3943 * \note this is O(n^2) for it's just a bug checker not meant for permanent use! 4011 */ 3944 */ 4012 3945 bool molecule::CheckForConnectedSubgraph(ofstream *out, KeySet *Fragment) 4013 3946 { … … 4015 3948 bool BondStatus = false; 4016 3949 int size; 4017 3950 4018 3951 *out << Verbose(1) << "Begin of CheckForConnectedSubgraph" << endl; 4019 3952 *out << Verbose(2) << "Disconnected atom: "; 4020 3953 4021 3954 // count number of atoms in graph 4022 3955 size = 0; … … 4064 3997 * \param *out output stream for debugging 4065 3998 * \param Order bond order (limits BFS exploration and "number of digits" in power set generation 4066 * \param FragmentSearch UniqueFragments structure containing TEFactor, root atom and so on 3999 * \param FragmentSearch UniqueFragments structure containing TEFactor, root atom and so on 4067 4000 * \param RestrictedKeySet Restricted vertex set to use in context of molecule 4068 4001 * \return number of inserted fragments 4069 4002 * \note ShortestPathList in FragmentSearch structure is probably due to NumberOfAtomsSPLevel and SP not needed anymore 4070 4003 */ 4071 int molecule::PowerSetGenerator(ofstream *out, int Order, struct UniqueFragments &FragmentSearch, KeySet RestrictedKeySet) 4004 int molecule::PowerSetGenerator(ofstream *out, int Order, struct UniqueFragments &FragmentSearch, KeySet RestrictedKeySet) 4072 4005 { 4073 4006 int SP, AtomKeyNr; … … 4090 4023 FragmentSearch.BondsPerSPCount[i] = 0; 4091 4024 FragmentSearch.BondsPerSPCount[0] = 1; 4092 Binder = new bond(FragmentSearch.Root, FragmentSearch.Root); 4025 Binder = new bond(FragmentSearch.Root, FragmentSearch.Root); 4093 4026 add(Binder, FragmentSearch.BondsPerSPList[1]); 4094 4027 4095 4028 // do a BFS search to fill the SP lists and label the found vertices 4096 4029 // Actually, we should construct a spanning tree vom the root atom and select all edges therefrom and put them into 4097 4030 // according shortest path lists. However, we don't. Rather we fill these lists right away, as they do form a spanning 4098 4031 // tree already sorted into various SP levels. That's why we just do loops over the depth (CurrentSP) and breadth 4099 // (EdgeinSPLevel) of this tree ... 4032 // (EdgeinSPLevel) of this tree ... 4100 4033 // In another picture, the bonds always contain a direction by rightatom being the one more distant from root and hence 4101 4034 // naturally leftatom forming its predecessor, preventing the BFS"seeker" from continuing in the wrong direction. … … 4150 4083 } 4151 4084 } 4152 4085 4153 4086 // outputting all list for debugging 4154 4087 *out << Verbose(0) << "Printing all found lists." << endl; … … 4159 4092 Binder = Binder->next; 4160 4093 *out << Verbose(2) << *Binder << endl; 4161 } 4162 } 4163 4094 } 4095 } 4096 4164 4097 // creating fragments with the found edge sets (may be done in reverse order, faster) 4165 4098 SP = -1; // the Root <-> Root edge must be subtracted! … … 4168 4101 while (Binder->next != FragmentSearch.BondsPerSPList[2*i+1]) { 4169 4102 Binder = Binder->next; 4170 SP ++; 4103 SP ++; 4171 4104 } 4172 4105 } … … 4175 4108 // start with root (push on fragment stack) 4176 4109 *out << Verbose(0) << "Starting fragment generation with " << *FragmentSearch.Root << ", local nr is " << FragmentSearch.Root->nr << "." << endl; 4177 FragmentSearch.FragmentSet->clear(); 4110 FragmentSearch.FragmentSet->clear(); 4178 4111 *out << Verbose(0) << "Preparing subset for this root and calling generator." << endl; 4179 4112 // prepare the subset and call the generator 4180 4113 BondsList = (bond **) Malloc(sizeof(bond *)*FragmentSearch.BondsPerSPCount[0], "molecule::PowerSetGenerator: **BondsList"); 4181 4114 BondsList[0] = FragmentSearch.BondsPerSPList[0]->next; // on SP level 0 there's only the root bond 4182 4115 4183 4116 SPFragmentGenerator(out, &FragmentSearch, 0, BondsList, FragmentSearch.BondsPerSPCount[0], Order); 4184 4117 4185 4118 Free((void **)&BondsList, "molecule::PowerSetGenerator: **BondsList"); 4186 4119 } else { … … 4191 4124 // remove root from stack 4192 4125 *out << Verbose(0) << "Removing root again from stack." << endl; 4193 FragmentSearch.FragmentSet->erase(FragmentSearch.Root->nr); 4126 FragmentSearch.FragmentSet->erase(FragmentSearch.Root->nr); 4194 4127 4195 4128 // free'ing the bonds lists … … 4210 4143 } 4211 4144 4212 // return list 4145 // return list 4213 4146 *out << Verbose(0) << "End of PowerSetGenerator." << endl; 4214 4147 return (FragmentSearch.FragmentCounter - Counter); … … 4241 4174 // remove bonds that are beyond bonddistance 4242 4175 for(int i=NDIM;i--;) 4243 Translationvector.x[i] = 0.; 4176 Translationvector.x[i] = 0.; 4244 4177 // scan all bonds 4245 4178 Binder = first; … … 4288 4221 } 4289 4222 } 4290 // re-add bond 4223 // re-add bond 4291 4224 link(Binder, OtherBinder); 4292 4225 } else { … … 4342 4275 IteratorB++; 4343 4276 } // end of while loop 4344 }// end of check in case of equal sizes 4277 }// end of check in case of equal sizes 4345 4278 } 4346 4279 return false; // if we reach this point, they are equal … … 4386 4319 * \param graph1 first (dest) graph 4387 4320 * \param graph2 second (source) graph 4388 * \param *counter keyset counter that gets increased 4321 * \param *counter keyset counter that gets increased 4389 4322 */ 4390 4323 inline void InsertGraphIntoGraph(ofstream *out, Graph &graph1, Graph &graph2, int *counter) … … 4431 4364 int RootKeyNr, RootNr; 4432 4365 struct UniqueFragments FragmentSearch; 4433 4366 4434 4367 *out << Verbose(0) << "Begin of FragmentBOSSANOVA." << endl; 4435 4368 … … 4454 4387 Walker = Walker->next; 4455 4388 CompleteMolecule.insert(Walker->GetTrueFather()->nr); 4456 } 4389 } 4457 4390 4458 4391 // this can easily be seen: if Order is 5, then the number of levels for each lower order is the total sum of the number of levels above, as … … 4468 4401 //if ((MinimumRingSize[Walker->GetTrueFather()->nr] != -1) && (Walker->GetTrueFather()->AdaptiveOrder+1 > MinimumRingSize[Walker->GetTrueFather()->nr])) { 4469 4402 // *out << Verbose(0) << "Bond order " << Walker->GetTrueFather()->AdaptiveOrder << " of Root " << *Walker << " greater than or equal to Minimum Ring size of " << MinimumRingSize << " found is not allowed." << endl; 4470 //} else 4403 //} else 4471 4404 { 4472 4405 // increase adaptive order by one 4473 4406 Walker->GetTrueFather()->AdaptiveOrder++; 4474 4407 Order = Walker->AdaptiveOrder = Walker->GetTrueFather()->AdaptiveOrder; 4475 4408 4476 4409 // initialise Order-dependent entries of UniqueFragments structure 4477 4410 FragmentSearch.BondsPerSPList = (bond **) Malloc(sizeof(bond *)*Order*2, "molecule::PowerSetGenerator: ***BondsPerSPList"); … … 4480 4413 FragmentSearch.BondsPerSPList[2*i] = new bond(); // start node 4481 4414 FragmentSearch.BondsPerSPList[2*i+1] = new bond(); // end node 4482 FragmentSearch.BondsPerSPList[2*i]->next = FragmentSearch.BondsPerSPList[2*i+1]; // intertwine these two 4415 FragmentSearch.BondsPerSPList[2*i]->next = FragmentSearch.BondsPerSPList[2*i+1]; // intertwine these two 4483 4416 FragmentSearch.BondsPerSPList[2*i+1]->previous = FragmentSearch.BondsPerSPList[2*i]; 4484 4417 FragmentSearch.BondsPerSPCount[i] = 0; 4485 } 4486 4418 } 4419 4487 4420 // allocate memory for all lower level orders in this 1D-array of ptrs 4488 4421 NumLevels = 1 << (Order-1); // (int)pow(2,Order); … … 4490 4423 for (int i=0;i<NumLevels;i++) 4491 4424 FragmentLowerOrdersList[RootNr][i] = NULL; 4492 4425 4493 4426 // create top order where nothing is reduced 4494 4427 *out << Verbose(0) << "==============================================================================================================" << endl; 4495 4428 *out << Verbose(0) << "Creating KeySets of Bond Order " << Order << " for " << *Walker << ", " << (RootStack.size()-RootNr) << " Roots remaining." << endl; // , NumLevels is " << NumLevels << " 4496 4429 4497 4430 // Create list of Graphs of current Bond Order (i.e. F_{ij}) 4498 4431 FragmentLowerOrdersList[RootNr][0] = new Graph; … … 4507 4440 // we don't have to dive into suborders! These keysets are all already created on lower orders! 4508 4441 // this was all ancient stuff, when we still depended on the TEFactors (and for those the suborders were needed) 4509 4442 4510 4443 // if ((NumLevels >> 1) > 0) { 4511 4444 // // create lower order fragments … … 4514 4447 // for (int source=0;source<(NumLevels >> 1);source++) { // 1-terms don't need any more splitting, that's why only half is gone through (shift again) 4515 4448 // // step down to next order at (virtual) boundary of powers of 2 in array 4516 // while (source >= (1 << (Walker->AdaptiveOrder-Order))) // (int)pow(2,Walker->AdaptiveOrder-Order)) 4449 // while (source >= (1 << (Walker->AdaptiveOrder-Order))) // (int)pow(2,Walker->AdaptiveOrder-Order)) 4517 4450 // Order--; 4518 4451 // *out << Verbose(0) << "Current Order is: " << Order << "." << endl; … … 4521 4454 // *out << Verbose(0) << "--------------------------------------------------------------------------------------------------------------" << endl; 4522 4455 // *out << Verbose(0) << "Current SubOrder is: " << SubOrder << " with source " << source << " to destination " << dest << "." << endl; 4523 // 4456 // 4524 4457 // // every molecule is split into a list of again (Order - 1) molecules, while counting all molecules 4525 4458 // //*out << Verbose(1) << "Splitting the " << (*FragmentLowerOrdersList[RootNr][source]).size() << " molecules of the " << source << "th cell in the array." << endl; … … 4552 4485 RootStack.push_back(RootKeyNr); // put back on stack 4553 4486 RootNr++; 4554 4487 4555 4488 // free Order-dependent entries of UniqueFragments structure for next loop cycle 4556 4489 Free((void **)&FragmentSearch.BondsPerSPCount, "molecule::PowerSetGenerator: *BondsPerSPCount"); … … 4558 4491 delete(FragmentSearch.BondsPerSPList[2*i]); 4559 4492 delete(FragmentSearch.BondsPerSPList[2*i+1]); 4560 } 4493 } 4561 4494 Free((void **)&FragmentSearch.BondsPerSPList, "molecule::PowerSetGenerator: ***BondsPerSPList"); 4562 4495 } … … 4569 4502 Free((void **)&FragmentSearch.ShortestPathList, "molecule::PowerSetGenerator: *ShortestPathList"); 4570 4503 delete(FragmentSearch.FragmentSet); 4571 4572 // now, FragmentLowerOrdersList is complete, it looks - for BondOrder 5 - as this (number is the ANOVA Order of the terms therein) 4504 4505 // now, FragmentLowerOrdersList is complete, it looks - for BondOrder 5 - as this (number is the ANOVA Order of the terms therein) 4573 4506 // 5433222211111111 4574 4507 // 43221111 … … 4590 4523 RootKeyNr = RootStack.front(); 4591 4524 RootStack.pop_front(); 4592 Walker = FindAtom(RootKeyNr); 4525 Walker = FindAtom(RootKeyNr); 4593 4526 NumLevels = 1 << (Walker->AdaptiveOrder - 1); 4594 4527 for(int i=0;i<NumLevels;i++) { … … 4603 4536 Free((void **)&FragmentLowerOrdersList, "molecule::FragmentBOSSANOVA: ***FragmentLowerOrdersList"); 4604 4537 Free((void **)&NumMoleculesOfOrder, "molecule::FragmentBOSSANOVA: *NumMoleculesOfOrder"); 4605 4538 4606 4539 *out << Verbose(0) << "End of FragmentBOSSANOVA." << endl; 4607 4540 }; … … 4637 4570 atom *Walker = NULL; 4638 4571 bool result = true; // status of comparison 4639 4640 *out << Verbose(3) << "Begin of IsEqualToWithinThreshold." << endl; 4572 4573 *out << Verbose(3) << "Begin of IsEqualToWithinThreshold." << endl; 4641 4574 /// first count both their atoms and elements and update lists thereby ... 4642 4575 //*out << Verbose(0) << "Counting atoms, updating list" << endl; … … 4685 4618 if (CenterOfGravity.Distance(&OtherCenterOfGravity) > threshold) { 4686 4619 *out << Verbose(4) << "Centers of gravity don't match." << endl; 4687 result = false; 4688 } 4689 } 4690 4620 result = false; 4621 } 4622 } 4623 4691 4624 /// ... then make a list with the euclidian distance to this center for each atom of both molecules 4692 4625 if (result) { … … 4704 4637 OtherDistances[Walker->nr] = OtherCenterOfGravity.Distance(&Walker->x); 4705 4638 } 4706 4639 4707 4640 /// ... sort each list (using heapsort (o(N log N)) from GSL) 4708 4641 *out << Verbose(5) << "Sorting distances" << endl; … … 4715 4648 for(int i=AtomCount;i--;) 4716 4649 PermutationMap[PermMap[i]] = (int) OtherPermMap[i]; 4717 4650 4718 4651 /// ... and compare them step by step, whether the difference is individiually(!) below \a threshold for all 4719 4652 *out << Verbose(4) << "Comparing distances" << endl; … … 4726 4659 Free((void **)&PermMap, "molecule::IsEqualToWithinThreshold: *PermMap"); 4727 4660 Free((void **)&OtherPermMap, "molecule::IsEqualToWithinThreshold: *OtherPermMap"); 4728 4661 4729 4662 /// free memory 4730 4663 Free((void **)&Distances, "molecule::IsEqualToWithinThreshold: Distances"); … … 4734 4667 result = false; 4735 4668 } 4736 } 4669 } 4737 4670 /// return pointer to map if all distances were below \a threshold 4738 4671 *out << Verbose(3) << "End of IsEqualToWithinThreshold." << endl; … … 4743 4676 *out << Verbose(3) << "Result: Not equal." << endl; 4744 4677 return NULL; 4745 } 4678 } 4746 4679 }; 4747 4680 … … 4798 4731 * \param *output output stream of temperature file 4799 4732 * \return file written (true), failure on writing file (false) 4800 */ 4733 */ 4801 4734 bool molecule::OutputTemperatureFromTrajectories(ofstream *out, int startstep, int endstep, ofstream *output) 4802 4735 { … … 4806 4739 if (output == NULL) 4807 4740 return false; 4808 else 4741 else 4809 4742 *output << "# Step Temperature [K] Temperature [a.u.]" << endl; 4810 4743 for (int step=startstep;step < endstep; step++) { // loop over all time steps -
Property mode
changed from
Note:
See TracChangeset
for help on using the changeset viewer.
