Changes in src/molecule.cpp [f8e486:7baf4a]
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/molecule.cpp
rf8e486 r7baf4a 5 5 */ 6 6 7 #ifdef HAVE_CONFIG_H 8 #include <config.h> 9 #endif 10 7 11 #include "Helpers/MemDebug.hpp" 8 12 9 13 #include <cstring> 10 14 #include <boost/bind.hpp> 15 #include <boost/foreach.hpp> 16 17 #include <gsl/gsl_inline.h> 18 #include <gsl/gsl_heapsort.h> 11 19 12 20 #include "World.hpp" … … 22 30 #include "log.hpp" 23 31 #include "molecule.hpp" 24 #include "memoryallocator.hpp" 32 25 33 #include "periodentafel.hpp" 26 34 #include "stackclass.hpp" 27 35 #include "tesselation.hpp" 28 36 #include "vector.hpp" 37 #include "Matrix.hpp" 29 38 #include "World.hpp" 39 #include "Box.hpp" 30 40 #include "Plane.hpp" 31 41 #include "Exceptions/LinearDependenceException.hpp" … … 39 49 molecule::molecule(const periodentafel * const teil) : 40 50 Observable("molecule"), 41 elemente(teil), MDSteps(0), BondCount(0), ElementCount(0),NoNonHydrogen(0), NoNonBonds(0),51 elemente(teil), MDSteps(0), BondCount(0), NoNonHydrogen(0), NoNonBonds(0), 42 52 NoCyclicBonds(0), BondDistance(0.), ActiveFlag(false), IndexNr(-1), 43 formula(this,boost::bind(&molecule::calcFormula,this),"formula"), 44 AtomCount(this,boost::bind(&molecule::doCountAtoms,this),"AtomCount"), last_atom(0), InternalPointer(begin()) 45 { 46 47 // other stuff 48 for(int i=MAX_ELEMENTS;i--;) 49 ElementsInMolecule[i] = 0; 50 strcpy(name,World::getInstance().getDefaultName()); 53 AtomCount(this,boost::bind(&molecule::doCountAtoms,this),"AtomCount"), last_atom(0), InternalPointer(atoms.begin()) 54 { 55 56 strcpy(name,World::getInstance().getDefaultName().c_str()); 51 57 }; 52 58 … … 79 85 void molecule::setName(const std::string _name){ 80 86 OBSERVE; 87 cout << "Set name of molecule " << getId() << " to " << _name << endl; 81 88 strncpy(name,_name.c_str(),MAXSTRINGSIZE); 82 89 } … … 90 97 } 91 98 92 const std::string molecule::getFormula(){ 93 return *formula; 94 } 95 96 std::string molecule::calcFormula(){ 97 std::map<atomicNumber_t,unsigned int> counts; 98 stringstream sstr; 99 periodentafel *periode = World::getInstance().getPeriode(); 100 for (molecule::const_iterator iter = begin(); iter != end(); ++iter) { 101 counts[(*iter)->type->getNumber()]++; 102 } 103 std::map<atomicNumber_t,unsigned int>::reverse_iterator iter; 104 for(iter = counts.rbegin(); iter != counts.rend(); ++iter) { 105 atomicNumber_t Z = (*iter).first; 106 sstr << periode->FindElement(Z)->symbol << (*iter).second; 107 } 108 return sstr.str(); 99 const Formula &molecule::getFormula(){ 100 return formula; 101 } 102 103 unsigned int molecule::getElementCount(){ 104 return formula.getElementCount(); 105 } 106 107 bool molecule::hasElement(const element *element) const{ 108 return formula.hasElement(element); 109 } 110 111 bool molecule::hasElement(atomicNumber_t Z) const{ 112 return formula.hasElement(Z); 113 } 114 115 bool molecule::hasElement(const string &shorthand) const{ 116 return formula.hasElement(shorthand); 109 117 } 110 118 … … 143 151 molecule::const_iterator molecule::erase( const_iterator loc ) 144 152 { 153 OBSERVE; 145 154 molecule::const_iterator iter = loc; 146 155 iter--; 147 156 atom* atom = *loc; 148 atoms.erase( loc ); 157 atomIds.erase( atom->getId() ); 158 atoms.remove( atom ); 159 formula-=atom->type; 149 160 atom->removeFromMolecule(); 150 161 return iter; … … 153 164 molecule::const_iterator molecule::erase( atom * key ) 154 165 { 155 cout << "trying to erase atom" << endl;166 OBSERVE; 156 167 molecule::const_iterator iter = find(key); 157 168 if (iter != end()){ 158 atoms.erase( iter++ ); 169 atomIds.erase( key->getId() ); 170 atoms.remove( key ); 171 formula-=key->type; 159 172 key->removeFromMolecule(); 160 173 } … … 164 177 molecule::const_iterator molecule::find ( atom * key ) const 165 178 { 166 return atoms.find( key ); 179 molecule::const_iterator iter; 180 for (molecule::const_iterator Runner = begin(); Runner != end(); ++Runner) { 181 if (*Runner == key) 182 return molecule::const_iterator(Runner); 183 } 184 return molecule::const_iterator(atoms.end()); 167 185 } 168 186 169 187 pair<molecule::iterator,bool> molecule::insert ( atom * const key ) 170 188 { 171 pair<atomSet::iterator,bool> res = atoms.insert(key); 172 return pair<iterator,bool>(iterator(res.first,this),res.second); 189 OBSERVE; 190 pair<atomIdSet::iterator,bool> res = atomIds.insert(key->getId()); 191 if (res.second) { // push atom if went well 192 atoms.push_back(key); 193 formula+=key->type; 194 return pair<iterator,bool>(molecule::iterator(--end()),res.second); 195 } else { 196 return pair<iterator,bool>(molecule::iterator(end()),res.second); 197 } 173 198 } 174 199 175 200 bool molecule::containsAtom(atom* key){ 176 return atoms.count(key);201 return (find(key) != end()); 177 202 } 178 203 … … 188 213 pointer->sort = &pointer->nr; 189 214 if (pointer->type != NULL) { 190 if (ElementsInMolecule[pointer->type->Z] == 0) 191 ElementCount++; 192 ElementsInMolecule[pointer->type->Z]++; // increase number of elements 215 formula += pointer->type; 193 216 if (pointer->type->Z != 1) 194 217 NoNonHydrogen++; … … 216 239 if (pointer != NULL) { 217 240 atom *walker = pointer->clone(); 241 formula += walker->type; 218 242 walker->setName(pointer->getName()); 219 243 walker->nr = last_atom++; // increase number within molecule … … 272 296 Vector Orthovector1, Orthovector2; // temporary vectors in coordination construction 273 297 Vector InBondvector; // vector in direction of *Bond 274 double *matrix = NULL;298 const Matrix &matrix = World::getInstance().getDomain().getM(); 275 299 bond *Binder = NULL; 276 double * const cell_size = World::getInstance().getDomain();277 300 278 301 // Log() << Verbose(3) << "Begin of AddHydrogenReplacementAtom." << endl; … … 295 318 } // (signs are correct, was tested!) 296 319 } 297 matrix = ReturnFullMatrixforSymmetric(cell_size); 298 Orthovector1.MatrixMultiplication(matrix); 320 Orthovector1 *= matrix; 299 321 InBondvector -= Orthovector1; // subtract just the additional translation 300 delete[](matrix);301 322 bondlength = InBondvector.Norm(); 302 323 // Log() << Verbose(4) << "Corrected InBondvector is now: "; … … 529 550 break; 530 551 } 531 delete[](matrix);532 552 533 553 // Log() << Verbose(3) << "End of AddHydrogenReplacementAtom." << endl; … … 606 626 { 607 627 molecule *copy = World::getInstance().createMolecule(); 608 atom *LeftAtom = NULL, *RightAtom = NULL;609 628 610 629 // copy all atoms 611 ActOnCopyWithEachAtom ( &molecule::AddCopyAtom, copy);630 for_each(atoms.begin(),atoms.end(),bind1st(mem_fun(&molecule::AddCopyAtom),copy)); 612 631 613 632 // copy all bonds 614 bond *Binder = NULL;615 bond *NewBond = NULL;616 633 for(molecule::iterator AtomRunner = begin(); AtomRunner != end(); ++AtomRunner) 617 634 for(BondList::iterator BondRunner = (*AtomRunner)->ListOfBonds.begin(); !(*AtomRunner)->ListOfBonds.empty(); BondRunner = (*AtomRunner)->ListOfBonds.begin()) 618 635 if ((*BondRunner)->leftatom == *AtomRunner) { 619 Binder = (*BondRunner);636 bond *Binder = (*BondRunner); 620 637 621 638 // get the pendant atoms of current bond in the copy molecule 622 copy->ActOnAllAtoms( &atom::EqualsFather, (const atom *)Binder->leftatom, (const atom **)&LeftAtom ); 623 copy->ActOnAllAtoms( &atom::EqualsFather, (const atom *)Binder->rightatom, (const atom **)&RightAtom ); 624 625 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); 626 647 NewBond->Cyclic = Binder->Cyclic; 627 648 if (Binder->Cyclic) … … 630 651 } 631 652 // correct fathers 632 ActOnAllAtoms( &atom::CorrectFather);653 for_each(atoms.begin(),atoms.end(),mem_fun(&atom::CorrectFather)); 633 654 634 655 // copy values 635 copy->CountElements();636 656 if (hasBondStructure()) { // if adjaceny list is present 637 657 copy->BondDistance = BondDistance; … … 648 668 * @param three vectors forming the matrix that defines the shape of the parallelpiped 649 669 */ 650 molecule* molecule::CopyMoleculeFromSubRegion(const Vector offset, const double *parallelepiped) const {670 molecule* molecule::CopyMoleculeFromSubRegion(const Shape ®ion) const { 651 671 molecule *copy = World::getInstance().createMolecule(); 652 672 653 ActOnCopyWithEachAtomIfTrue ( &molecule::AddCopyAtom, copy, &atom::IsInParallelepiped, offset, parallelepiped ); 673 BOOST_FOREACH(atom *iter,atoms){ 674 if(iter->IsInShape(region)){ 675 copy->AddCopyAtom(iter); 676 } 677 } 654 678 655 679 //TODO: copy->BuildInducedSubgraph(this); … … 728 752 else 729 753 length = strlen(molname) - strlen(endname); 754 cout << "Set name of molecule " << getId() << " to " << molname << endl; 730 755 strncpy(name, molname, length); 731 756 name[length]='\0'; … … 737 762 void molecule::SetBoxDimension(Vector *dim) 738 763 { 739 double * const cell_size = World::getInstance().getDomain(); 740 cell_size[0] = dim->at(0); 741 cell_size[1] = 0.; 742 cell_size[2] = dim->at(1); 743 cell_size[3] = 0.; 744 cell_size[4] = 0.; 745 cell_size[5] = dim->at(2); 764 Matrix domain; 765 for(int i =0; i<NDIM;++i) 766 domain.at(i,i) = dim->at(i); 767 World::getInstance().setDomain(domain); 746 768 }; 747 769 … … 754 776 ASSERT(pointer, "Null pointer passed to molecule::RemoveAtom()."); 755 777 OBSERVE; 756 if (ElementsInMolecule[pointer->type->Z] != 0) { // this would indicate an error 757 ElementsInMolecule[pointer->type->Z]--; // decrease number of atom of this element 758 } else 759 DoeLog(1) && (eLog()<< Verbose(1) << "Atom " << pointer->getName() << " is of element " << pointer->type->Z << " but the entry in the table of the molecule is 0!" << endl); 760 if (ElementsInMolecule[pointer->type->Z] == 0) // was last atom of this element? 761 ElementCount--; 778 formula-=pointer->type; 762 779 RemoveBonds(pointer); 763 780 erase(pointer); … … 773 790 if (pointer == NULL) 774 791 return false; 775 if (ElementsInMolecule[pointer->type->Z] != 0) // this would indicate an error 776 ElementsInMolecule[pointer->type->Z]--; // decrease number of atom of this element 777 else 778 DoeLog(1) && (eLog()<< Verbose(1) << "Atom " << pointer->getName() << " is of element " << pointer->type->Z << " but the entry in the table of the molecule is 0!" << endl); 779 if (ElementsInMolecule[pointer->type->Z] == 0) // was last atom of this element? 780 ElementCount--; 792 formula-=pointer->type; 781 793 erase(pointer); 782 794 return true; … … 790 802 for (molecule::iterator iter = begin(); !empty(); iter = begin()) 791 803 erase(iter); 804 return empty(); 792 805 }; 793 806 … … 835 848 bool molecule::CheckBounds(const Vector *x) const 836 849 { 837 double * const cell_size = World::getInstance().getDomain();850 const Matrix &domain = World::getInstance().getDomain().getM(); 838 851 bool result = true; 839 int j =-1;840 852 for (int i=0;i<NDIM;i++) { 841 j += i+1; 842 result = result && ((x->at(i) >= 0) && (x->at(i) < cell_size[j])); 853 result = result && ((x->at(i) >= 0) && (x->at(i) < domain.at(i,i))); 843 854 } 844 855 //return result; … … 849 860 * \param *out output stream 850 861 */ 851 bool molecule::Output(ofstream * const output) 852 { 853 int ElementNo[MAX_ELEMENTS], AtomNo[MAX_ELEMENTS]; 854 CountElements(); 855 856 for (int i=0;i<MAX_ELEMENTS;++i) { 857 AtomNo[i] = 0; 858 ElementNo[i] = 0; 859 } 862 bool molecule::Output(ostream * const output) 863 { 860 864 if (output == NULL) { 861 865 return false; 862 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 } 863 874 *output << "#Ion_TypeNr._Nr.R[0] R[1] R[2] MoveType (0 MoveIon, 1 FixedIon)" << endl; 864 SetIndexedArrayForEachAtomTo ( ElementNo, &element::Z, &AbsoluteValue, 1); 865 int current=1; 866 for (int i=0;i<MAX_ELEMENTS;++i) { 867 if (ElementNo[i] == 1) 868 ElementNo[i] = current++; 869 } 870 ActOnAllAtoms( &atom::OutputArrayIndexed, 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)); 871 876 return true; 872 877 } … … 879 884 { 880 885 int ElementNo[MAX_ELEMENTS], AtomNo[MAX_ELEMENTS]; 881 CountElements();882 886 883 887 if (output == NULL) { … … 912 916 { 913 917 DoLog(2) && (Log() << Verbose(2) << endl << "From Contents of ListOfBonds, all non-hydrogen atoms:" << endl); 914 ActOnAllAtoms (&atom::OutputBondOfAtom);918 for_each(atoms.begin(),atoms.end(),mem_fun(&atom::OutputBondOfAtom)); 915 919 DoLog(0) && (Log() << Verbose(0) << endl); 916 920 }; … … 921 925 bool molecule::Checkout(ofstream * const output) const 922 926 { 923 return elemente->Checkout(output, ElementsInMolecule);927 return formula.checkOut(output); 924 928 }; 925 929 … … 935 939 for (int step=0;step<MDSteps;step++) { 936 940 *output << getAtomCount() << "\n\tCreated by molecuilder, step " << step << ", on " << ctime(&now); 937 ActOnAllAtoms( &atom::OutputTrajectoryXYZ, output, step);941 for_each(atoms.begin(),atoms.end(),boost::bind(&atom::OutputTrajectoryXYZ,_1,output,step)); 938 942 } 939 943 return true; … … 952 956 now = time((time_t *)NULL); // Get the system time and put it into 'now' as 'calender time' 953 957 *output << getAtomCount() << "\n\tCreated by molecuilder on " << ctime(&now); 954 ActOnAllAtoms( &atom::OutputXYZLine, output);958 for_each(atoms.begin(),atoms.end(),bind2nd(mem_fun(&atom::OutputXYZLine),output)); 955 959 return true; 956 960 } else … … 979 983 }; 980 984 981 /** Brings molecule::ElementCount and molecule::ElementsInMolecule up-to-date.982 */983 void molecule::CountElements()984 {985 for(int i=MAX_ELEMENTS;i--;)986 ElementsInMolecule[i] = 0;987 ElementCount = 0;988 989 SetIndexedArrayForEachAtomTo ( ElementsInMolecule, &element::Z, &Increment, 1);990 991 for(int i=MAX_ELEMENTS;i--;)992 ElementCount += (ElementsInMolecule[i] != 0 ? 1 : 0);993 };994 995 996 /** Counts necessary number of valence electrons and returns number and SpinType.997 * \param configuration containing everything998 */999 void molecule::CalculateOrbitals(class config &configuration)1000 {1001 configuration.MaxPsiDouble = configuration.PsiMaxNoDown = configuration.PsiMaxNoUp = configuration.PsiType = 0;1002 for(int i=MAX_ELEMENTS;i--;) {1003 if (ElementsInMolecule[i] != 0) {1004 //Log() << Verbose(0) << "CalculateOrbitals: " << elemente->FindElement(i)->name << " has a valence of " << (int)elemente->FindElement(i)->Valence << " and there are " << ElementsInMolecule[i] << " of it." << endl;1005 configuration.MaxPsiDouble += ElementsInMolecule[i]*((int)elemente->FindElement(i)->Valence);1006 }1007 }1008 configuration.PsiMaxNoDown = configuration.MaxPsiDouble/2 + (configuration.MaxPsiDouble % 2);1009 configuration.PsiMaxNoUp = configuration.MaxPsiDouble/2;1010 configuration.MaxPsiDouble /= 2;1011 configuration.PsiType = (configuration.PsiMaxNoDown == configuration.PsiMaxNoUp) ? 0 : 1;1012 if ((configuration.PsiType == 1) && (configuration.ProcPEPsi < 2)) {1013 configuration.ProcPEGamma /= 2;1014 configuration.ProcPEPsi *= 2;1015 } else {1016 configuration.ProcPEGamma *= configuration.ProcPEPsi;1017 configuration.ProcPEPsi = 1;1018 }1019 configuration.InitMaxMinStopStep = configuration.MaxMinStopStep = configuration.MaxPsiDouble;1020 };1021 1022 985 /** Determines whether two molecules actually contain the same atoms and coordination. 1023 986 * \param *out output stream for debugging … … 1038 1001 /// first count both their atoms and elements and update lists thereby ... 1039 1002 //Log() << Verbose(0) << "Counting atoms, updating list" << endl; 1040 CountElements();1041 OtherMolecule->CountElements();1042 1003 1043 1004 /// ... and compare: … … 1049 1010 } else Log() << Verbose(4) << "AtomCounts match: " << getAtomCount() << " == " << OtherMolecule->getAtomCount() << endl; 1050 1011 } 1051 /// -# ElementCount1012 /// -# Formula 1052 1013 if (result) { 1053 if ( ElementCount != OtherMolecule->ElementCount) {1054 DoLog(4) && (Log() << Verbose(4) << " ElementCount don't match: " << ElementCount << " == " << OtherMolecule->ElementCount<< endl);1014 if (formula != OtherMolecule->formula) { 1015 DoLog(4) && (Log() << Verbose(4) << "Formulas don't match: " << formula << " == " << OtherMolecule->formula << endl); 1055 1016 result = false; 1056 } else Log() << Verbose(4) << "ElementCount match: " << ElementCount << " == " << OtherMolecule->ElementCount << endl; 1057 } 1058 /// -# ElementsInMolecule 1059 if (result) { 1060 for (flag=MAX_ELEMENTS;flag--;) { 1061 //Log() << Verbose(5) << "Element " << flag << ": " << ElementsInMolecule[flag] << " <-> " << OtherMolecule->ElementsInMolecule[flag] << "." << endl; 1062 if (ElementsInMolecule[flag] != OtherMolecule->ElementsInMolecule[flag]) 1063 break; 1064 } 1065 if (flag < MAX_ELEMENTS) { 1066 DoLog(4) && (Log() << Verbose(4) << "ElementsInMolecule don't match." << endl); 1067 result = false; 1068 } else Log() << Verbose(4) << "ElementsInMolecule match." << endl; 1017 } else Log() << Verbose(4) << "Formulas match: " << formula << " == " << OtherMolecule->formula << endl; 1069 1018 } 1070 1019 /// then determine and compare center of gravity for each molecule ...
Note:
See TracChangeset
for help on using the changeset viewer.