Changes in src/molecule.cpp [952f38:822f01]
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/molecule.cpp
r952f38 r822f01 24 24 #include "element.hpp" 25 25 #include "graph.hpp" 26 #include " Helpers/helpers.hpp"26 #include "helpers.hpp" 27 27 #include "leastsquaremin.hpp" 28 28 #include "linkedcell.hpp" 29 29 #include "lists.hpp" 30 #include " Helpers/Log.hpp"30 #include "log.hpp" 31 31 #include "molecule.hpp" 32 32 … … 34 34 #include "stackclass.hpp" 35 35 #include "tesselation.hpp" 36 #include " LinearAlgebra/Vector.hpp"37 #include " LinearAlgebra/Matrix.hpp"36 #include "vector.hpp" 37 #include "Matrix.hpp" 38 38 #include "World.hpp" 39 39 #include "Box.hpp" 40 #include " LinearAlgebra/Plane.hpp"40 #include "Plane.hpp" 41 41 #include "Exceptions/LinearDependenceException.hpp" 42 42 … … 151 151 molecule::const_iterator molecule::erase( const_iterator loc ) 152 152 { 153 OBSERVE; 153 154 molecule::const_iterator iter = loc; 154 155 iter--; … … 156 157 atomIds.erase( atom->getId() ); 157 158 atoms.remove( atom ); 159 formula-=atom->type; 158 160 atom->removeFromMolecule(); 159 161 return iter; … … 162 164 molecule::const_iterator molecule::erase( atom * key ) 163 165 { 166 OBSERVE; 164 167 molecule::const_iterator iter = find(key); 165 168 if (iter != end()){ 166 169 atomIds.erase( key->getId() ); 167 170 atoms.remove( key ); 171 formula-=key->type; 168 172 key->removeFromMolecule(); 169 173 } … … 183 187 pair<molecule::iterator,bool> molecule::insert ( atom * const key ) 184 188 { 189 OBSERVE; 185 190 pair<atomIdSet::iterator,bool> res = atomIds.insert(key->getId()); 186 191 if (res.second) { // push atom if went well 187 192 atoms.push_back(key); 193 formula+=key->type; 188 194 return pair<iterator,bool>(molecule::iterator(--end()),res.second); 189 195 } else { … … 212 218 if(pointer->getName() == "Unknown"){ 213 219 stringstream sstr; 214 sstr << pointer->type-> symbol<< pointer->nr+1;220 sstr << pointer->type->getSymbol() << pointer->nr+1; 215 221 pointer->setName(sstr.str()); 216 222 } … … 233 239 if (pointer != NULL) { 234 240 atom *walker = pointer->clone(); 241 formula += walker->type; 235 242 walker->setName(pointer->getName()); 236 243 walker->nr = last_atom++; // increase number within molecule … … 619 626 { 620 627 molecule *copy = World::getInstance().createMolecule(); 621 atom *LeftAtom = NULL, *RightAtom = NULL;622 628 623 629 // copy all atoms 624 ActOnCopyWithEachAtom ( &molecule::AddCopyAtom, copy);630 for_each(atoms.begin(),atoms.end(),bind1st(mem_fun(&molecule::AddCopyAtom),copy)); 625 631 626 632 // copy all bonds 627 bond *Binder = NULL;628 bond *NewBond = NULL;629 633 for(molecule::iterator AtomRunner = begin(); AtomRunner != end(); ++AtomRunner) 630 634 for(BondList::iterator BondRunner = (*AtomRunner)->ListOfBonds.begin(); !(*AtomRunner)->ListOfBonds.empty(); BondRunner = (*AtomRunner)->ListOfBonds.begin()) 631 635 if ((*BondRunner)->leftatom == *AtomRunner) { 632 Binder = (*BondRunner);636 bond *Binder = (*BondRunner); 633 637 634 638 // get the pendant atoms of current bond in the copy molecule 635 copy->ActOnAllAtoms( &atom::EqualsFather, (const atom *)Binder->leftatom, (const atom **)&LeftAtom ); 636 copy->ActOnAllAtoms( &atom::EqualsFather, (const atom *)Binder->rightatom, (const atom **)&RightAtom ); 637 638 NewBond = copy->AddBond(LeftAtom, RightAtom, Binder->BondDegree); 639 atomSet::iterator leftiter=find_if(atoms.begin(),atoms.end(),bind2nd(mem_fun(&atom::isFather),Binder->leftatom)); 640 atomSet::iterator rightiter=find_if(atoms.begin(),atoms.end(),bind2nd(mem_fun(&atom::isFather),Binder->rightatom)); 641 ASSERT(leftiter!=atoms.end(),"No original left atom for bondcopy found"); 642 ASSERT(leftiter!=atoms.end(),"No original right atom for bondcopy found"); 643 atom *LeftAtom = *leftiter; 644 atom *RightAtom = *rightiter; 645 646 bond *NewBond = copy->AddBond(LeftAtom, RightAtom, Binder->BondDegree); 639 647 NewBond->Cyclic = Binder->Cyclic; 640 648 if (Binder->Cyclic) … … 643 651 } 644 652 // correct fathers 645 ActOnAllAtoms( &atom::CorrectFather);653 for_each(atoms.begin(),atoms.end(),mem_fun(&atom::CorrectFather)); 646 654 647 655 // copy values … … 852 860 * \param *out output stream 853 861 */ 854 bool molecule::Output(ofstream * const output) 855 { 856 int ElementNo[MAX_ELEMENTS], AtomNo[MAX_ELEMENTS]; 857 858 for (int i=0;i<MAX_ELEMENTS;++i) { 859 AtomNo[i] = 0; 860 ElementNo[i] = 0; 861 } 862 bool molecule::Output(ostream * const output) 863 { 862 864 if (output == NULL) { 863 865 return false; 864 866 } else { 867 int AtomNo[MAX_ELEMENTS]; 868 memset(AtomNo,0,(MAX_ELEMENTS-1)*sizeof(*AtomNo)); 869 enumeration<const element*> elementLookup = formula.enumerateElements(); 870 for(map<const element*,unsigned int>::iterator iter=elementLookup.there.begin(); 871 iter!=elementLookup.there.end();++iter){ 872 cout << "Enumerated element " << *iter->first << " with number " << iter->second << endl; 873 } 865 874 *output << "#Ion_TypeNr._Nr.R[0] R[1] R[2] MoveType (0 MoveIon, 1 FixedIon)" << endl; 866 SetIndexedArrayForEachAtomTo ( ElementNo, &element::Z, &AbsoluteValue, 1); 867 int current=1; 868 for (int i=0;i<MAX_ELEMENTS;++i) { 869 if (ElementNo[i] == 1) 870 ElementNo[i] = current++; 871 } 872 ActOnAllAtoms( &atom::OutputArrayIndexed, (ostream * const) output, (const int *)ElementNo, (int *)AtomNo, (const char *) NULL ); 875 for_each(atoms.begin(),atoms.end(),boost::bind(&atom::OutputArrayIndexed,_1,output,elementLookup,AtomNo,(const char*)0)); 873 876 return true; 874 877 } … … 913 916 { 914 917 DoLog(2) && (Log() << Verbose(2) << endl << "From Contents of ListOfBonds, all non-hydrogen atoms:" << endl); 915 ActOnAllAtoms (&atom::OutputBondOfAtom);918 for_each(atoms.begin(),atoms.end(),mem_fun(&atom::OutputBondOfAtom)); 916 919 DoLog(0) && (Log() << Verbose(0) << endl); 917 920 }; … … 936 939 for (int step=0;step<MDSteps;step++) { 937 940 *output << getAtomCount() << "\n\tCreated by molecuilder, step " << step << ", on " << ctime(&now); 938 ActOnAllAtoms( &atom::OutputTrajectoryXYZ, output, step);941 for_each(atoms.begin(),atoms.end(),boost::bind(&atom::OutputTrajectoryXYZ,_1,output,step)); 939 942 } 940 943 return true; … … 953 956 now = time((time_t *)NULL); // Get the system time and put it into 'now' as 'calender time' 954 957 *output << getAtomCount() << "\n\tCreated by molecuilder on " << ctime(&now); 955 ActOnAllAtoms( &atom::OutputXYZLine, output);958 for_each(atoms.begin(),atoms.end(),bind2nd(mem_fun(&atom::OutputXYZLine),output)); 956 959 return true; 957 960 } else … … 972 975 NoNonHydrogen++; 973 976 stringstream sstr; 974 sstr << (*iter)->type-> symbol<< (*iter)->nr+1;977 sstr << (*iter)->type->getSymbol() << (*iter)->nr+1; 975 978 (*iter)->setName(sstr.str()); 976 979 DoLog(3) && (Log() << Verbose(3) << "Naming atom nr. " << (*iter)->nr << " " << (*iter)->getName() << "." << endl); … … 978 981 } 979 982 return res; 980 };981 982 /** Determines whether two molecules actually contain the same atoms and coordination.983 * \param *out output stream for debugging984 * \param *OtherMolecule the molecule to compare this one to985 * \param threshold upper limit of difference when comparing the coordination.986 * \return NULL - not equal, otherwise an allocated (molecule::AtomCount) permutation map of the atom numbers (which corresponds to which)987 */988 int * molecule::IsEqualToWithinThreshold(molecule *OtherMolecule, double threshold)989 {990 int flag;991 double *Distances = NULL, *OtherDistances = NULL;992 Vector CenterOfGravity, OtherCenterOfGravity;993 size_t *PermMap = NULL, *OtherPermMap = NULL;994 int *PermutationMap = NULL;995 bool result = true; // status of comparison996 997 DoLog(3) && (Log() << Verbose(3) << "Begin of IsEqualToWithinThreshold." << endl);998 /// first count both their atoms and elements and update lists thereby ...999 //Log() << Verbose(0) << "Counting atoms, updating list" << endl;1000 1001 /// ... and compare:1002 /// -# AtomCount1003 if (result) {1004 if (getAtomCount() != OtherMolecule->getAtomCount()) {1005 DoLog(4) && (Log() << Verbose(4) << "AtomCounts don't match: " << getAtomCount() << " == " << OtherMolecule->getAtomCount() << endl);1006 result = false;1007 } else Log() << Verbose(4) << "AtomCounts match: " << getAtomCount() << " == " << OtherMolecule->getAtomCount() << endl;1008 }1009 /// -# Formula1010 if (result) {1011 if (formula != OtherMolecule->formula) {1012 DoLog(4) && (Log() << Verbose(4) << "Formulas don't match: " << formula << " == " << OtherMolecule->formula << endl);1013 result = false;1014 } else Log() << Verbose(4) << "Formulas match: " << formula << " == " << OtherMolecule->formula << endl;1015 }1016 /// then determine and compare center of gravity for each molecule ...1017 if (result) {1018 DoLog(5) && (Log() << Verbose(5) << "Calculating Centers of Gravity" << endl);1019 DeterminePeriodicCenter(CenterOfGravity);1020 OtherMolecule->DeterminePeriodicCenter(OtherCenterOfGravity);1021 DoLog(5) && (Log() << Verbose(5) << "Center of Gravity: " << CenterOfGravity << endl);1022 DoLog(5) && (Log() << Verbose(5) << "Other Center of Gravity: " << OtherCenterOfGravity << endl);1023 if (CenterOfGravity.DistanceSquared(OtherCenterOfGravity) > threshold*threshold) {1024 DoLog(4) && (Log() << Verbose(4) << "Centers of gravity don't match." << endl);1025 result = false;1026 }1027 }1028 1029 /// ... then make a list with the euclidian distance to this center for each atom of both molecules1030 if (result) {1031 DoLog(5) && (Log() << Verbose(5) << "Calculating distances" << endl);1032 Distances = new double[getAtomCount()];1033 OtherDistances = new double[getAtomCount()];1034 SetIndexedArrayForEachAtomTo ( Distances, &atom::nr, &atom::DistanceSquaredToVector, (const Vector &)CenterOfGravity);1035 SetIndexedArrayForEachAtomTo ( OtherDistances, &atom::nr, &atom::DistanceSquaredToVector, (const Vector &)CenterOfGravity);1036 for(int i=0;i<getAtomCount();i++) {1037 Distances[i] = 0.;1038 OtherDistances[i] = 0.;1039 }1040 1041 /// ... sort each list (using heapsort (o(N log N)) from GSL)1042 DoLog(5) && (Log() << Verbose(5) << "Sorting distances" << endl);1043 PermMap = new size_t[getAtomCount()];1044 OtherPermMap = new size_t[getAtomCount()];1045 for(int i=0;i<getAtomCount();i++) {1046 PermMap[i] = 0;1047 OtherPermMap[i] = 0;1048 }1049 gsl_heapsort_index (PermMap, Distances, getAtomCount(), sizeof(double), CompareDoubles);1050 gsl_heapsort_index (OtherPermMap, OtherDistances, getAtomCount(), sizeof(double), CompareDoubles);1051 PermutationMap = new int[getAtomCount()];1052 for(int i=0;i<getAtomCount();i++)1053 PermutationMap[i] = 0;1054 DoLog(5) && (Log() << Verbose(5) << "Combining Permutation Maps" << endl);1055 for(int i=getAtomCount();i--;)1056 PermutationMap[PermMap[i]] = (int) OtherPermMap[i];1057 1058 /// ... and compare them step by step, whether the difference is individually(!) below \a threshold for all1059 DoLog(4) && (Log() << Verbose(4) << "Comparing distances" << endl);1060 flag = 0;1061 for (int i=0;i<getAtomCount();i++) {1062 DoLog(5) && (Log() << Verbose(5) << "Distances squared: |" << Distances[PermMap[i]] << " - " << OtherDistances[OtherPermMap[i]] << "| = " << fabs(Distances[PermMap[i]] - OtherDistances[OtherPermMap[i]]) << " ?<? " << threshold << endl);1063 if (fabs(Distances[PermMap[i]] - OtherDistances[OtherPermMap[i]]) > threshold*threshold)1064 flag = 1;1065 }1066 1067 // free memory1068 delete[](PermMap);1069 delete[](OtherPermMap);1070 delete[](Distances);1071 delete[](OtherDistances);1072 if (flag) { // if not equal1073 delete[](PermutationMap);1074 result = false;1075 }1076 }1077 /// return pointer to map if all distances were below \a threshold1078 DoLog(3) && (Log() << Verbose(3) << "End of IsEqualToWithinThreshold." << endl);1079 if (result) {1080 DoLog(3) && (Log() << Verbose(3) << "Result: Equal." << endl);1081 return PermutationMap;1082 } else {1083 DoLog(3) && (Log() << Verbose(3) << "Result: Not equal." << endl);1084 return NULL;1085 }1086 983 }; 1087 984
Note:
See TracChangeset
for help on using the changeset viewer.