Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/molecule.cpp

    rbab12a rf8e486  
    44 *
    55 */
     6
     7#include "Helpers/MemDebug.hpp"
    68
    79#include <cstring>
     
    3537 * Initialises molecule list with correctly referenced start and end, and sets molecule::last_atom to zero.
    3638 */
    37 molecule::molecule(const periodentafel * const teil) : elemente(teil), start(World::getInstance().createAtom()), end(World::getInstance().createAtom()),
    38   first(new bond(start, end, 1, -1)), last(new bond(start, end, 1, -1)), MDSteps(0), AtomCount(0),
    39   BondCount(0), ElementCount(0), NoNonHydrogen(0), NoNonBonds(0), NoCyclicBonds(0), BondDistance(0.),
    40   ActiveFlag(false), IndexNr(-1),
    41   formula(this,boost::bind(&molecule::calcFormula,this)),
    42   last_atom(0),
    43   InternalPointer(start)
    44 {
    45   // init atom chain list
    46   start->father = NULL;
    47   end->father = NULL;
    48   link(start,end);
    49 
    50   // init bond chain list
    51   link(first,last);
     39molecule::molecule(const periodentafel * const teil) :
     40  Observable("molecule"),
     41  elemente(teil),  MDSteps(0),  BondCount(0), ElementCount(0), NoNonHydrogen(0), NoNonBonds(0),
     42  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{
    5246
    5347  // other stuff
     
    6761{
    6862  CleanupMolecule();
    69   delete(first);
    70   delete(last);
    71   end->getWorld()->destroyAtom(end);
    72   start->getWorld()->destroyAtom(start);
    7363};
    7464
     
    8171const std::string molecule::getName(){
    8272  return std::string(name);
     73}
     74
     75int molecule::getAtomCount() const{
     76  return *AtomCount;
    8377}
    8478
     
    10498  stringstream sstr;
    10599  periodentafel *periode = World::getInstance().getPeriode();
    106   for(atom *Walker = start; Walker != end; Walker = Walker->next) {
    107     counts[Walker->type->getNumber()]++;
     100  for (molecule::const_iterator iter = begin(); iter != end(); ++iter) {
     101    counts[(*iter)->type->getNumber()]++;
    108102  }
    109103  std::map<atomicNumber_t,unsigned int>::reverse_iterator iter;
     
    115109}
    116110
     111/************************** Access to the List of Atoms ****************/
     112
     113
     114molecule::iterator molecule::begin(){
     115  return molecule::iterator(atoms.begin(),this);
     116}
     117
     118molecule::const_iterator molecule::begin() const{
     119  return atoms.begin();
     120}
     121
     122molecule::iterator molecule::end(){
     123  return molecule::iterator(atoms.end(),this);
     124}
     125
     126molecule::const_iterator molecule::end() const{
     127  return atoms.end();
     128}
     129
     130bool molecule::empty() const
     131{
     132  return (begin() == end());
     133}
     134
     135size_t molecule::size() const
     136{
     137  size_t counter = 0;
     138  for (molecule::const_iterator iter = begin(); iter != end (); ++iter)
     139    counter++;
     140  return counter;
     141}
     142
     143molecule::const_iterator molecule::erase( const_iterator loc )
     144{
     145  molecule::const_iterator iter = loc;
     146  iter--;
     147  atom* atom = *loc;
     148  atoms.erase( loc );
     149  atom->removeFromMolecule();
     150  return iter;
     151}
     152
     153molecule::const_iterator molecule::erase( atom * key )
     154{
     155  cout << "trying to erase atom" << endl;
     156  molecule::const_iterator iter = find(key);
     157  if (iter != end()){
     158    atoms.erase( iter++ );
     159    key->removeFromMolecule();
     160  }
     161  return iter;
     162}
     163
     164molecule::const_iterator molecule::find ( atom * key ) const
     165{
     166  return atoms.find( key );
     167}
     168
     169pair<molecule::iterator,bool> molecule::insert ( atom * const key )
     170{
     171  pair<atomSet::iterator,bool> res = atoms.insert(key);
     172  return pair<iterator,bool>(iterator(res.first,this),res.second);
     173}
     174
     175bool molecule::containsAtom(atom* key){
     176  return atoms.count(key);
     177}
    117178
    118179/** Adds given atom \a *pointer from molecule list.
     
    123184bool molecule::AddAtom(atom *pointer)
    124185{
    125   bool retval = false;
    126186  OBSERVE;
    127187  if (pointer != NULL) {
    128188    pointer->sort = &pointer->nr;
    129     pointer->nr = last_atom++;  // increase number within molecule
    130     AtomCount++;
    131189    if (pointer->type != NULL) {
    132190      if (ElementsInMolecule[pointer->type->Z] == 0)
     
    141199      }
    142200    }
    143     retval = add(pointer, end);
    144   }
    145   return retval;
     201    insert(pointer);
     202    pointer->setMolecule(this);
     203  }
     204  return true;
    146205};
    147206
     
    157216  if (pointer != NULL) {
    158217    atom *walker = pointer->clone();
    159     stringstream sstr;
    160     sstr << pointer->getName();
    161     walker->setName(sstr.str());
     218    walker->setName(pointer->getName());
    162219    walker->nr = last_atom++;  // increase number within molecule
    163     add(walker, end);
     220    insert(walker);
    164221    if ((pointer->type != NULL) && (pointer->type->Z != 1))
    165222      NoNonHydrogen++;
    166     AtomCount++;
    167223    retval=walker;
    168224  }
     
    242298    Orthovector1.MatrixMultiplication(matrix);
    243299    InBondvector -= Orthovector1; // subtract just the additional translation
    244     Free(&matrix);
     300    delete[](matrix);
    245301    bondlength = InBondvector.Norm();
    246302//    Log() << Verbose(4) << "Corrected InBondvector is now: ";
     
    251307  InBondvector.Normalize();
    252308  // get typical bond length and store as scale factor for later
     309  ASSERT(TopOrigin->type != NULL, "AddHydrogenReplacementAtom: element of TopOrigin is not given.");
    253310  BondRescale = TopOrigin->type->HBondDistance[TopBond->BondDegree-1];
    254311  if (BondRescale == -1) {
     
    472529      break;
    473530  }
    474   Free(&matrix);
     531  delete[](matrix);
    475532
    476533//  Log() << Verbose(3) << "End of AddHydrogenReplacementAtom." << endl;
     
    555612
    556613  // copy all bonds
    557   bond *Binder = first;
     614  bond *Binder = NULL;
    558615  bond *NewBond = NULL;
    559   while(Binder->next != last) {
    560     Binder = Binder->next;
    561 
    562     // get the pendant atoms of current bond in the copy molecule
    563     copy->ActOnAllAtoms( &atom::EqualsFather, (const atom *)Binder->leftatom, (const atom **)&LeftAtom );
    564     copy->ActOnAllAtoms( &atom::EqualsFather, (const atom *)Binder->rightatom, (const atom **)&RightAtom );
    565 
    566     NewBond = copy->AddBond(LeftAtom, RightAtom, Binder->BondDegree);
    567     NewBond->Cyclic = Binder->Cyclic;
    568     if (Binder->Cyclic)
    569       copy->NoCyclicBonds++;
    570     NewBond->Type = Binder->Type;
    571   }
     616  for(molecule::iterator AtomRunner = begin(); AtomRunner != end(); ++AtomRunner)
     617    for(BondList::iterator BondRunner = (*AtomRunner)->ListOfBonds.begin(); !(*AtomRunner)->ListOfBonds.empty(); BondRunner = (*AtomRunner)->ListOfBonds.begin())
     618      if ((*BondRunner)->leftatom == *AtomRunner) {
     619        Binder = (*BondRunner);
     620
     621        // 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);
     626        NewBond->Cyclic = Binder->Cyclic;
     627        if (Binder->Cyclic)
     628          copy->NoCyclicBonds++;
     629        NewBond->Type = Binder->Type;
     630      }
    572631  // correct fathers
    573632  ActOnAllAtoms( &atom::CorrectFather );
    574633
    575634  // copy values
    576   copy->CountAtoms();
    577635  copy->CountElements();
    578   if (first->next != last) {  // if adjaceny list is present
     636  if (hasBondStructure()) {  // if adjaceny list is present
    579637    copy->BondDistance = BondDistance;
    580638  }
     
    608666bond * molecule::AddBond(atom *atom1, atom *atom2, int degree)
    609667{
     668  OBSERVE;
    610669  bond *Binder = NULL;
    611   if ((atom1 != NULL) && (FindAtom(atom1->nr) != NULL) && (atom2 != NULL) && (FindAtom(atom2->nr) != NULL)) {
    612     Binder = new bond(atom1, atom2, degree, BondCount++);
    613     atom1->RegisterBond(Binder);
    614     atom2->RegisterBond(Binder);
    615     if ((atom1->type != NULL) && (atom1->type->Z != 1) && (atom2->type != NULL) && (atom2->type->Z != 1))
    616       NoNonBonds++;
    617     add(Binder, last);
    618   } else {
    619     DoeLog(1) && (eLog()<< Verbose(1) << "Could not add bond between " << atom1->getName() << " and " << atom2->getName() << " as one or both are not present in the molecule." << endl);
    620   }
     670
     671  // some checks to make sure we are able to create the bond
     672  ASSERT(atom1, "First atom in bond-creation was an invalid pointer");
     673  ASSERT(atom2, "Second atom in bond-creation was an invalid pointer");
     674  ASSERT(FindAtom(atom1->nr),"First atom in bond-creation was not part of molecule");
     675  ASSERT(FindAtom(atom2->nr),"Second atom in bond-creation was not parto of molecule");
     676
     677  Binder = new bond(atom1, atom2, degree, BondCount++);
     678  atom1->RegisterBond(Binder);
     679  atom2->RegisterBond(Binder);
     680  if ((atom1->type != NULL) && (atom1->type->Z != 1) && (atom2->type != NULL) && (atom2->type->Z != 1))
     681    NoNonBonds++;
     682
    621683  return Binder;
    622684};
     
    630692{
    631693  //DoeLog(1) && (eLog()<< Verbose(1) << "molecule::RemoveBond: Function not implemented yet." << endl);
    632   pointer->leftatom->RegisterBond(pointer);
    633   pointer->rightatom->RegisterBond(pointer);
    634   removewithoutcheck(pointer);
     694  delete(pointer);
    635695  return true;
    636696};
     
    692752bool molecule::RemoveAtom(atom *pointer)
    693753{
     754  ASSERT(pointer, "Null pointer passed to molecule::RemoveAtom().");
     755  OBSERVE;
    694756  if (ElementsInMolecule[pointer->type->Z] != 0)  { // this would indicate an error
    695757    ElementsInMolecule[pointer->type->Z]--;  // decrease number of atom of this element
    696     AtomCount--;
    697758  } else
    698759    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);
     
    700761    ElementCount--;
    701762  RemoveBonds(pointer);
    702   return remove(pointer, start, end);
     763  erase(pointer);
     764  return true;
    703765};
    704766
     
    717779  if (ElementsInMolecule[pointer->type->Z] == 0)  // was last atom of this element?
    718780    ElementCount--;
    719   unlink(pointer);
     781  erase(pointer);
    720782  return true;
    721783};
     
    726788bool molecule::CleanupMolecule()
    727789{
    728   return (cleanup(first,last) && cleanup(start,end));
     790  for (molecule::iterator iter = begin(); !empty(); iter = begin())
     791      erase(iter);
    729792};
    730793
     
    733796 * \return pointer to atom or NULL
    734797 */
    735 atom * molecule::FindAtom(int Nr)  const{
    736   atom * walker = find(&Nr, start,end);
    737   if (walker != NULL) {
     798atom * molecule::FindAtom(int Nr)  const
     799{
     800  molecule::const_iterator iter = begin();
     801  for (; iter != end(); ++iter)
     802    if ((*iter)->nr == Nr)
     803      break;
     804  if (iter != end()) {
    738805    //Log() << Verbose(0) << "Found Atom Nr. " << walker->nr << endl;
    739     return walker;
     806    return (*iter);
    740807  } else {
    741808    DoLog(0) && (Log() << Verbose(0) << "Atom not found in list." << endl);
     
    867934    now = time((time_t *)NULL);   // Get the system time and put it into 'now' as 'calender time'
    868935    for (int step=0;step<MDSteps;step++) {
    869       *output << AtomCount << "\n\tCreated by molecuilder, step " << step << ", on " << ctime(&now);
     936      *output << getAtomCount() << "\n\tCreated by molecuilder, step " << step << ", on " << ctime(&now);
    870937      ActOnAllAtoms( &atom::OutputTrajectoryXYZ, output, step );
    871938    }
     
    884951  if (output != NULL) {
    885952    now = time((time_t *)NULL);   // Get the system time and put it into 'now' as 'calender time'
    886     *output << AtomCount << "\n\tCreated by molecuilder on " << ctime(&now);
     953    *output << getAtomCount() << "\n\tCreated by molecuilder on " << ctime(&now);
    887954    ActOnAllAtoms( &atom::OutputXYZLine, output );
    888955    return true;
     
    894961 * \param *out output stream for debugging
    895962 */
    896 void molecule::CountAtoms()
    897 {
     963int molecule::doCountAtoms()
     964{
     965  int res = size();
    898966  int i = 0;
    899   atom *Walker = start;
    900   while (Walker->next != end) {
    901     Walker = Walker->next;
     967  NoNonHydrogen = 0;
     968  for (molecule::const_iterator iter = atoms.begin(); iter != atoms.end(); ++iter) {
     969    (*iter)->nr = i;   // update number in molecule (for easier referencing in FragmentMolecule lateron)
     970    if ((*iter)->type->Z != 1) // count non-hydrogen atoms whilst at it
     971      NoNonHydrogen++;
     972    stringstream sstr;
     973    sstr << (*iter)->type->symbol << (*iter)->nr+1;
     974    (*iter)->setName(sstr.str());
     975    DoLog(3) && (Log() << Verbose(3) << "Naming atom nr. " << (*iter)->nr << " " << (*iter)->getName() << "." << endl);
    902976    i++;
    903977  }
    904   if ((AtomCount == 0) || (i != AtomCount)) {
    905     DoLog(3) && (Log() << Verbose(3) << "Mismatch in AtomCount " << AtomCount << " and recounted number " << i << ", renaming all." << endl);
    906     AtomCount = i;
    907 
    908     // count NonHydrogen atoms and give each atom a unique name
    909     if (AtomCount != 0) {
    910       i=0;
    911       NoNonHydrogen = 0;
    912       Walker = start;
    913       while (Walker->next != end) {
    914         Walker = Walker->next;
    915         Walker->nr = i;   // update number in molecule (for easier referencing in FragmentMolecule lateron)
    916         if (Walker->type->Z != 1) // count non-hydrogen atoms whilst at it
    917           NoNonHydrogen++;
    918         stringstream sstr;
    919         sstr << Walker->type->symbol << Walker->nr+1;
    920         Walker->setName(sstr.str());
    921         DoLog(3) && (Log() << Verbose(3) << "Naming atom nr. " << Walker->nr << " " << Walker->getName() << "." << endl);
    922         i++;
    923       }
    924     } else
    925       DoLog(3) && (Log() << Verbose(3) << "AtomCount is still " << AtomCount << ", thus counting nothing." << endl);
    926   }
     978  return res;
    927979};
    928980
     
    9861038  /// first count both their atoms and elements and update lists thereby ...
    9871039  //Log() << Verbose(0) << "Counting atoms, updating list" << endl;
    988   CountAtoms();
    989   OtherMolecule->CountAtoms();
    9901040  CountElements();
    9911041  OtherMolecule->CountElements();
     
    9941044  /// -# AtomCount
    9951045  if (result) {
    996     if (AtomCount != OtherMolecule->AtomCount) {
    997       DoLog(4) && (Log() << Verbose(4) << "AtomCounts don't match: " << AtomCount << " == " << OtherMolecule->AtomCount << endl);
     1046    if (getAtomCount() != OtherMolecule->getAtomCount()) {
     1047      DoLog(4) && (Log() << Verbose(4) << "AtomCounts don't match: " << getAtomCount() << " == " << OtherMolecule->getAtomCount() << endl);
    9981048      result = false;
    999     } else Log() << Verbose(4) << "AtomCounts match: " << AtomCount << " == " << OtherMolecule->AtomCount << endl;
     1049    } else Log() << Verbose(4) << "AtomCounts match: " << getAtomCount() << " == " << OtherMolecule->getAtomCount() << endl;
    10001050  }
    10011051  /// -# ElementCount
     
    10341084  if (result) {
    10351085    DoLog(5) && (Log() << Verbose(5) << "Calculating distances" << endl);
    1036     Distances = Calloc<double>(AtomCount, "molecule::IsEqualToWithinThreshold: Distances");
    1037     OtherDistances = Calloc<double>(AtomCount, "molecule::IsEqualToWithinThreshold: OtherDistances");
     1086    Distances = new double[getAtomCount()];
     1087    OtherDistances = new double[getAtomCount()];
    10381088    SetIndexedArrayForEachAtomTo ( Distances, &atom::nr, &atom::DistanceSquaredToVector, (const Vector &)CenterOfGravity);
    10391089    SetIndexedArrayForEachAtomTo ( OtherDistances, &atom::nr, &atom::DistanceSquaredToVector, (const Vector &)CenterOfGravity);
     1090    for(int i=0;i<getAtomCount();i++) {
     1091      Distances[i] = 0.;
     1092      OtherDistances[i] = 0.;
     1093    }
    10401094
    10411095    /// ... sort each list (using heapsort (o(N log N)) from GSL)
    10421096    DoLog(5) && (Log() << Verbose(5) << "Sorting distances" << endl);
    1043     PermMap = Calloc<size_t>(AtomCount, "molecule::IsEqualToWithinThreshold: *PermMap");
    1044     OtherPermMap = Calloc<size_t>(AtomCount, "molecule::IsEqualToWithinThreshold: *OtherPermMap");
    1045     gsl_heapsort_index (PermMap, Distances, AtomCount, sizeof(double), CompareDoubles);
    1046     gsl_heapsort_index (OtherPermMap, OtherDistances, AtomCount, sizeof(double), CompareDoubles);
    1047     PermutationMap = Calloc<int>(AtomCount, "molecule::IsEqualToWithinThreshold: *PermutationMap");
     1097    PermMap = new size_t[getAtomCount()];
     1098    OtherPermMap = new size_t[getAtomCount()];
     1099    for(int i=0;i<getAtomCount();i++) {
     1100      PermMap[i] = 0;
     1101      OtherPermMap[i] = 0;
     1102    }
     1103    gsl_heapsort_index (PermMap, Distances, getAtomCount(), sizeof(double), CompareDoubles);
     1104    gsl_heapsort_index (OtherPermMap, OtherDistances, getAtomCount(), sizeof(double), CompareDoubles);
     1105    PermutationMap = new int[getAtomCount()];
     1106    for(int i=0;i<getAtomCount();i++)
     1107      PermutationMap[i] = 0;
    10481108    DoLog(5) && (Log() << Verbose(5) << "Combining Permutation Maps" << endl);
    1049     for(int i=AtomCount;i--;)
     1109    for(int i=getAtomCount();i--;)
    10501110      PermutationMap[PermMap[i]] = (int) OtherPermMap[i];
    10511111
     
    10531113    DoLog(4) && (Log() << Verbose(4) << "Comparing distances" << endl);
    10541114    flag = 0;
    1055     for (int i=0;i<AtomCount;i++) {
     1115    for (int i=0;i<getAtomCount();i++) {
    10561116      DoLog(5) && (Log() << Verbose(5) << "Distances squared: |" << Distances[PermMap[i]] << " - " << OtherDistances[OtherPermMap[i]] << "| = " << fabs(Distances[PermMap[i]] - OtherDistances[OtherPermMap[i]]) << " ?<? " <<  threshold << endl);
    10571117      if (fabs(Distances[PermMap[i]] - OtherDistances[OtherPermMap[i]]) > threshold*threshold)
     
    10601120
    10611121    // free memory
    1062     Free(&PermMap);
    1063     Free(&OtherPermMap);
    1064     Free(&Distances);
    1065     Free(&OtherDistances);
     1122    delete[](PermMap);
     1123    delete[](OtherPermMap);
     1124    delete[](Distances);
     1125    delete[](OtherDistances);
    10661126    if (flag) { // if not equal
    1067       Free(&PermutationMap);
     1127      delete[](PermutationMap);
    10681128      result = false;
    10691129    }
     
    10891149int * molecule::GetFatherSonAtomicMap(molecule *OtherMolecule)
    10901150{
    1091   atom *Walker = NULL, *OtherWalker = NULL;
    10921151  DoLog(3) && (Log() << Verbose(3) << "Begin of GetFatherAtomicMap." << endl);
    1093   int *AtomicMap = Malloc<int>(AtomCount, "molecule::GetAtomicMap: *AtomicMap");
    1094   for (int i=AtomCount;i--;)
     1152  int *AtomicMap = new int[getAtomCount()];
     1153  for (int i=getAtomCount();i--;)
    10951154    AtomicMap[i] = -1;
    10961155  if (OtherMolecule == this) {  // same molecule
    1097     for (int i=AtomCount;i--;) // no need as -1 means already that there is trivial correspondence
     1156    for (int i=getAtomCount();i--;) // no need as -1 means already that there is trivial correspondence
    10981157      AtomicMap[i] = i;
    10991158    DoLog(4) && (Log() << Verbose(4) << "Map is trivial." << endl);
    11001159  } else {
    11011160    DoLog(4) && (Log() << Verbose(4) << "Map is ");
    1102     Walker = start;
    1103     while (Walker->next != end) {
    1104       Walker = Walker->next;
    1105       if (Walker->father == NULL) {
    1106         AtomicMap[Walker->nr] = -2;
     1161    for (molecule::const_iterator iter = begin(); iter != end(); ++iter) {
     1162      if ((*iter)->father == NULL) {
     1163        AtomicMap[(*iter)->nr] = -2;
    11071164      } else {
    1108         OtherWalker = OtherMolecule->start;
    1109         while (OtherWalker->next != OtherMolecule->end) {
    1110           OtherWalker = OtherWalker->next;
     1165        for (molecule::const_iterator runner = OtherMolecule->begin(); runner != OtherMolecule->end(); ++runner) {
    11111166      //for (int i=0;i<AtomCount;i++) { // search atom
    1112         //for (int j=0;j<OtherMolecule->AtomCount;j++) {
    1113           //Log() << Verbose(4) << "Comparing father " << Walker->father << " with the other one " << OtherWalker->father << "." << endl;
    1114           if (Walker->father == OtherWalker)
    1115             AtomicMap[Walker->nr] = OtherWalker->nr;
     1167        //for (int j=0;j<OtherMolecule->getAtomCount();j++) {
     1168          //Log() << Verbose(4) << "Comparing father " << (*iter)->father << " with the other one " << (*runner)->father << "." << endl;
     1169          if ((*iter)->father == (*runner))
     1170            AtomicMap[(*iter)->nr] = (*runner)->nr;
    11161171        }
    11171172      }
    1118       DoLog(0) && (Log() << Verbose(0) << AtomicMap[Walker->nr] << "\t");
     1173      DoLog(0) && (Log() << Verbose(0) << AtomicMap[(*iter)->nr] << "\t");
    11191174    }
    11201175    DoLog(0) && (Log() << Verbose(0) << endl);
     
    11501205void molecule::SetIndexedArrayForEachAtomTo ( atom **array, int ParticleInfo::*index) const
    11511206{
    1152   atom *Walker = start;
    1153   while (Walker->next != end) {
    1154     Walker = Walker->next;
    1155     array[(Walker->*index)] = Walker;
     1207  for (molecule::const_iterator iter = begin(); iter != end(); ++iter) {
     1208    array[((*iter)->*index)] = (*iter);
    11561209  }
    11571210};
Note: See TracChangeset for help on using the changeset viewer.