Changeset 266237


Ignore:
Timestamp:
Oct 18, 2009, 2:51:38 PM (15 years ago)
Author:
Frederik Heber <heber@…>
Branches:
Action_Thermostats, Add_AtomRandomPerturbation, Add_FitFragmentPartialChargesAction, Add_RotateAroundBondAction, Add_SelectAtomByNameAction, Added_ParseSaveFragmentResults, AddingActions_SaveParseParticleParameters, Adding_Graph_to_ChangeBondActions, Adding_MD_integration_tests, Adding_ParticleName_to_Atom, Adding_StructOpt_integration_tests, AtomFragments, Automaking_mpqc_open, AutomationFragmentation_failures, Candidate_v1.5.4, Candidate_v1.6.0, Candidate_v1.6.1, ChangeBugEmailaddress, ChangingTestPorts, ChemicalSpaceEvaluator, CombiningParticlePotentialParsing, Combining_Subpackages, Debian_Package_split, Debian_package_split_molecuildergui_only, Disabling_MemDebug, Docu_Python_wait, EmpiricalPotential_contain_HomologyGraph, EmpiricalPotential_contain_HomologyGraph_documentation, Enable_parallel_make_install, Enhance_userguide, Enhanced_StructuralOptimization, Enhanced_StructuralOptimization_continued, Example_ManyWaysToTranslateAtom, Exclude_Hydrogens_annealWithBondGraph, FitPartialCharges_GlobalError, Fix_BoundInBox_CenterInBox_MoleculeActions, Fix_ChargeSampling_PBC, Fix_ChronosMutex, Fix_FitPartialCharges, Fix_FitPotential_needs_atomicnumbers, Fix_ForceAnnealing, Fix_IndependentFragmentGrids, Fix_ParseParticles, Fix_ParseParticles_split_forward_backward_Actions, Fix_PopActions, Fix_QtFragmentList_sorted_selection, Fix_Restrictedkeyset_FragmentMolecule, Fix_StatusMsg, Fix_StepWorldTime_single_argument, Fix_Verbose_Codepatterns, Fix_fitting_potentials, Fixes, ForceAnnealing_goodresults, ForceAnnealing_oldresults, ForceAnnealing_tocheck, ForceAnnealing_with_BondGraph, ForceAnnealing_with_BondGraph_continued, ForceAnnealing_with_BondGraph_continued_betteresults, ForceAnnealing_with_BondGraph_contraction-expansion, FragmentAction_writes_AtomFragments, FragmentMolecule_checks_bonddegrees, GeometryObjects, Gui_Fixes, Gui_displays_atomic_force_velocity, ImplicitCharges, IndependentFragmentGrids, IndependentFragmentGrids_IndividualZeroInstances, IndependentFragmentGrids_IntegrationTest, IndependentFragmentGrids_Sole_NN_Calculation, JobMarket_RobustOnKillsSegFaults, JobMarket_StableWorkerPool, JobMarket_unresolvable_hostname_fix, MoreRobust_FragmentAutomation, ODR_violation_mpqc_open, PartialCharges_OrthogonalSummation, PdbParser_setsAtomName, PythonUI_with_named_parameters, QtGui_reactivate_TimeChanged_changes, Recreated_GuiChecks, Rewrite_FitPartialCharges, RotateToPrincipalAxisSystem_UndoRedo, SaturateAtoms_findBestMatching, SaturateAtoms_singleDegree, StoppableMakroAction, Subpackage_CodePatterns, Subpackage_JobMarket, Subpackage_LinearAlgebra, Subpackage_levmar, Subpackage_mpqc_open, Subpackage_vmg, Switchable_LogView, ThirdParty_MPQC_rebuilt_buildsystem, TrajectoryDependenant_MaxOrder, TremoloParser_IncreasedPrecision, TremoloParser_MultipleTimesteps, TremoloParser_setsAtomName, Ubuntu_1604_changes, stable
Children:
174e0e
Parents:
b8b75d
git-author:
Frederik Heber <heber@…> (10/18/09 14:15:37)
git-committer:
Frederik Heber <heber@…> (10/18/09 14:51:38)
Message:

Huge refactoring: molecule::ListOfBondsPerAtom and molecule::NumberOfBondsPerAtom removed, atom::ListOfBonds introduced. Unit Test for ListOfBonds manipulation introduced.

  • changes to builder.cpp: removed CreateListOfBondsPerAtom() calls, as the creation of the global arrays is not necessary anymore
  • changes to LinkedCell: LinkedCell::CheckBounds(int[NDIM]) does not admonish out of bonds as this is not desired for the local offset which may become out of bounds.
  • changes to lists.hpp templates: BUGFIX: unlink() now sets ->next and ->previous to NULL, cleanup() uses removedwithoutcheck()
  • new templates for molecule.hpp: SumPerAtom() allows for summation of the return value of atom:...() member fiunctions. This is needed e.g. for atom::CorrectBondDegree()

Signed-off-by: Frederik Heber <heber@…>

Location:
src
Files:
2 added
15 edited

Legend:

Unmodified
Added
Removed
  • src/atom.cpp

    rb8b75d r266237  
    99#include "config.hpp"
    1010#include "element.hpp"
     11#include "lists.hpp"
    1112#include "memoryallocator.hpp"
    1213#include "parser.hpp"
     
    6768atom::~atom()
    6869{
     70  BondList::const_iterator Runner;
     71  while (!ListOfBonds.empty()) {
     72    Runner = ListOfBonds.begin();
     73    removewithoutcheck(*Runner);
     74  }
     75  unlink(this);
    6976  Free<int>(&ComponentNr, "atom::~atom: *ComponentNr");
    7077  Free<char>(&Name, "atom::~atom: *Name");
     
    118125{
    119126  return (node->IsInParallelepiped(offset, parallelepiped));
     127};
     128
     129/** Counts the number of bonds weighted by bond::BondDegree.
     130 * \param bonds times bond::BondDegree
     131 */
     132int atom::CountBonds() const
     133{
     134  int NoBonds = 0;
     135  for (BondList::const_iterator Runner = ListOfBonds.begin(); Runner != ListOfBonds.end(); (++Runner))
     136    NoBonds += (*Runner)->BondDegree;
     137  return NoBonds;
    120138};
    121139
     
    215233};
    216234
    217 /** Prints all bonds of this atom from given global lists.
     235/** Output graph info of this atom.
     236 * \param *out output stream
     237 */
     238void atom::OutputGraphInfo(ofstream *out) const
     239{
     240  *out << Verbose(2) << "Atom " << Name << " is " << ((SeparationVertex) ? "a" : "not a") << " separation vertex, components are ";
     241  OutputComponentNumber(out);
     242  *out << " with Lowpoint " << LowpointNr << " and Graph Nr. " << GraphNr << "." << endl;
     243};
     244
     245/** Output a list of flags, stating whether the bond was visited or not.
     246 * Note, we make use of the last entry of the ComponentNr always being -1 if allocated.
     247 * \param *out output stream for debugging
     248 */
     249void atom::OutputComponentNumber(ofstream *out) const
     250{
     251  if (ComponentNr != NULL) {
     252    for (int i=0; ComponentNr[i] != -1; i++)
     253      *out << ComponentNr[i] << " ";
     254  }
     255};
     256
     257
     258/** Prints all bonds of this atom with total degree.
    218259 * \param *out stream to output to
    219  * \param *NumberOfBondsPerAtom array with number of bonds per atomic index
    220  * \param ***ListOfBondsPerAtom array per atomic index of array with pointer to bond
    221260 * \return true - \a *out present, false - \a *out is NULL
    222261 */
    223 bool atom::OutputBondOfAtom(ofstream *out, int *NumberOfBondsPerAtom, bond ***ListOfBondsPerAtom) const
     262bool atom::OutputBondOfAtom(ofstream *out) const
    224263{
    225264  if (out != NULL) {
     
    227266    if (type->Z != 1) {   // regard only non-hydrogen
    228267#endif
    229       *out << Verbose(4) << "Atom " << Name << "/" << nr << " with " << NumberOfBondsPerAtom[nr] << " bonds: ";
     268      *out << Verbose(4) << "Atom " << Name << "/" << nr << " with " << ListOfBonds.size() << " bonds: ";
    230269      int TotalDegree = 0;
    231       for (int j=0;j<NumberOfBondsPerAtom[nr];j++) {
    232         *out << *ListOfBondsPerAtom[nr][j] << "\t";
    233         TotalDegree += ListOfBondsPerAtom[nr][j]->BondDegree;
     270      for (BondList::const_iterator Runner = ListOfBonds.begin(); Runner != ListOfBonds.end(); ++Runner) {
     271        *out << **Runner << "\t";
     272        TotalDegree += (*Runner)->BondDegree;
    234273      }
    235274      *out << " -- TotalDegree: " << TotalDegree << endl;
     
    240279  } else
    241280    return false;
     281};
     282
     283/** Output of atom::nr along with all bond partners.
     284 * \param *AdjacencyFile output stream
     285 */
     286void atom::OutputAdjacency(ofstream *AdjacencyFile) const
     287{
     288  *AdjacencyFile << nr << "\t";
     289  for (BondList::const_iterator Runner = ListOfBonds.begin(); Runner != ListOfBonds.end(); (++Runner))
     290    *AdjacencyFile << (*Runner)->GetOtherAtom(this)->nr << "\t";
     291  *AdjacencyFile << endl;
     292};
     293
     294/** Puts a given bond into atom::ListOfBonds.
     295 * \param *Binder bond to insert
     296 */
     297bool atom::RegisterBond(bond *Binder)
     298{
     299  bool status = false;
     300  if (Binder != NULL) {
     301    if (Binder->Contains(this)) {
     302      ListOfBonds.push_back(Binder);
     303      status = true;
     304    } else {
     305      cout << Verbose(1) << "ERROR: " << *Binder << " does not contain " << *this << "." << endl;
     306    }
     307  } else {
     308    cout << Verbose(1) << "ERROR: Binder is " << Binder << "." << endl;
     309  }
     310  return status;
     311};
     312
     313/** Removes a given bond from atom::ListOfBonds.
     314 * \param *Binder bond to remove
     315 */
     316bool atom::UnregisterBond(bond *Binder)
     317{
     318  bool status = false;
     319  if (Binder != NULL) {
     320    if (Binder->Contains(this)) {
     321      ListOfBonds.remove(Binder);
     322      status = true;
     323    } else {
     324      cout << Verbose(1) << "ERROR: " << *Binder << " does not contain " << *this << "." << endl;
     325    }
     326  } else {
     327    cout << Verbose(1) << "ERROR: Binder is " << Binder << "." << endl;
     328  }
     329  return status;
     330};
     331
     332/** Removes all bonds from atom::ListOfBonds.
     333 * \note Does not do any memory de-allocation.
     334 */
     335void atom::UnregisterAllBond()
     336{
     337  ListOfBonds.clear();
     338};
     339
     340/** Corrects the bond degree by one at most if necessary.
     341 * \param *out output stream for debugging
     342 */
     343int atom::CorrectBondDegree(ofstream *out)
     344{
     345  int NoBonds = 0;
     346  int OtherNoBonds = 0;
     347  int FalseBondDegree = 0;
     348  atom *OtherWalker = NULL;
     349  bond *CandidateBond = NULL;
     350
     351  *out << Verbose(3) << "Walker " << *this << ": " << (int)this->type->NoValenceOrbitals << " > " << NoBonds << "?" << endl;
     352  NoBonds = CountBonds();
     353  if ((int)(type->NoValenceOrbitals) > NoBonds) { // we have a mismatch, check all bonding partners for mismatch
     354    for (BondList::const_iterator Runner = ListOfBonds.begin(); Runner != ListOfBonds.end(); (++Runner)) {
     355      OtherWalker = (*Runner)->GetOtherAtom(this);
     356      OtherNoBonds = OtherWalker->CountBonds();
     357      *out << Verbose(3) << "OtherWalker " << *OtherWalker << ": " << (int)OtherWalker->type->NoValenceOrbitals << " > " << NoBonds << "?" << endl;
     358      if ((int)(OtherWalker->type->NoValenceOrbitals) > NoBonds) { // check if possible candidate
     359        if ((CandidateBond == NULL) || (ListOfBonds.size() > OtherWalker->ListOfBonds.size())) { // pick the one with fewer number of bonds first
     360          CandidateBond = (*Runner);
     361          *out << Verbose(3) << "New candidate is " << *CandidateBond << "." << endl;
     362        }
     363      }
     364    }
     365    if ((CandidateBond != NULL)) {
     366      CandidateBond->BondDegree++;
     367      *out << Verbose(2) << "Increased bond degree for bond " << *CandidateBond << "." << endl;
     368    } else {
     369      *out << Verbose(2) << "Could not find correct degree for atom " << *this << "." << endl;
     370      FalseBondDegree++;
     371    }
     372  }
     373  return FalseBondDegree;
    242374};
    243375
     
    345477{
    346478  *file << nr << "\t" << (int)AdaptiveOrder << "\t" << (int)MaxOrder << endl;
    347   //cout << Verbose(2) << "Storing: " << Walker->nr << "\t" << (int)Walker->AdaptiveOrder << "\t" << (int)Walker->MaxOrder << "." << endl;
     479  //cout << Verbose(2) << "Storing: " << nr << "\t" << (int)AdaptiveOrder << "\t" << (int)MaxOrder << "." << endl;
    348480}
    349481
  • src/atom.hpp

    rb8b75d r266237  
    1919
    2020#include <iostream>
     21#include <list>
    2122#include <vector>
    2223
     
    3233class ForceMatrix;
    3334class Vector;
     35
     36#define BondList list<bond *>
    3437
    3538/********************************************** declarations *******************************/
     
    5053    Vector v;       //!< velocity vector of atom, giving last velocity within cell
    5154    Vector F;       //!< Force vector of atom, giving last force within cell
     55    BondList ListOfBonds; //!< list of all bonds
    5256    element *type;  //!< pointing to element
    5357    atom *previous; //!< previous atom in molecule list
     
    7680  bool OutputTrajectory(ofstream *out, int *ElementNo, int *AtomNo, int step) const;
    7781  bool OutputTrajectoryXYZ(ofstream *out, int step) const;
    78   bool OutputBondOfAtom(ofstream *out, int *NumberOfBondsPerAtom, bond ***ListOfBondsPerAtom) const;
     82  bool OutputBondOfAtom(ofstream *out) const;
     83  void OutputAdjacency(ofstream *AdjacencyFile) const;
     84
    7985
    8086  void EqualsFather ( atom *ptr, atom **res );
     
    96102  // bond order stuff
    97103  void OutputOrder(ofstream *file);
     104  void OutputGraphInfo(ofstream *out) const;
     105  void OutputComponentNumber(ofstream *out) const;
     106  int CountBonds() const;
     107  int CorrectBondDegree(ofstream *out);
     108
     109  bool RegisterBond(bond *Binder);
     110  bool UnregisterBond(bond *Binder);
     111  void UnregisterAllBond();
    98112
    99113  // constraint potential and dynamics stuff
  • src/bond.cpp

    rb8b75d r266237  
    5353  Cyclic = false;
    5454};
     55
    5556bond::bond(atom *left, atom *right)
    5657{
     
    7778{
    7879  // remove this node from the list structure
    79   if (previous != NULL) {
    80     previous->next = next;
    81   }
    82   if (next != NULL) {
    83     next->previous = previous;
    84   }
     80  if (leftatom != NULL)
     81    leftatom->UnregisterBond(this);
     82  if (rightatom != NULL)
     83  rightatom->UnregisterBond(this);
     84  unlink(this);
    8585};
    8686
     
    9595 * \return pointer to the other atom in the bond, NULL if no match (indicates something's wrong with the bond)
    9696 */
    97 atom * bond::GetOtherAtom(atom *Atom) const
     97atom * bond::GetOtherAtom(const atom *Atom) const
    9898{
    9999  if(leftatom == Atom)
     
    105105};
    106106
    107 /** Get the other atom in a bond if one is specified.
    108  * \param *Atom the pointer to the one atom
    109  * \return pointer to the other atom in the bond, NULL if no match (indicates something's wrong with the bond)
    110  */
    111 bond * bond::GetFirstBond()
    112 {
    113   return GetFirst(this);
    114 };
    115 
    116 /** Get the other atom in a bond if one is specified.
    117  * \param *Atom the pointer to the one atom
    118  * \return pointer to the other atom in the bond, NULL if no match (indicates something's wrong with the bond)
    119  */
    120 bond * bond::GetLastBond()
    121 {
    122   return GetLast(this);
    123 };
    124107
    125108/** Returns whether vertex was used in DFS.
  • src/bond.hpp

    rb8b75d r266237  
    2525
    2626/** Bonds between atoms.
    27  * Class incorporates bonds between atoms in a molecule,
    28  * used to derive tge fragments in many-body bond order
    29  * calculations.
     27 * Class incorporates bonds between atoms in a molecule.
     28 * Note that we regard bond always as something in a molecule,
     29 * as it is the glue making up the connected subgrapgh and
     30 * hence the molecule. Thus, bonds belong globally to the molecule
     31 * (and are free'd there) and only locally to the atom classs.
    3032 */
    3133class bond {
     
    4143    enum EdgeType Type;//!< whether this is a tree or back edge
    4244
    43   atom * GetOtherAtom(atom *Atom) const;
    44   bond * GetFirstBond();
    45   bond * GetLastBond();
     45  atom * GetOtherAtom(const atom *Atom) const;
    4646
    4747  bool MarkUsed(enum Shading color);
  • src/builder.cpp

    rb8b75d r266237  
    895895          start = clock();
    896896          mol->CreateAdjacencyList((ofstream *)&cout, bonddistance, configuration->GetIsAngstroem());
    897           mol->CreateListOfBondsPerAtom((ofstream *)&cout);
    898897          end = clock();
    899898          cout << Verbose(0) << "Clocks for this operation: " << (end-start) << ", time: " << ((double)(end-start)/CLOCKS_PER_SEC) << "s." << endl;
     
    15551554                class StackClass<bond *> *LocalBackEdgeStack = NULL;
    15561555                mol->CreateAdjacencyList((ofstream *)&cout, atof(argv[argptr]), configuration.GetIsAngstroem());
    1557                 mol->CreateListOfBondsPerAtom((ofstream *)&cout);
    15581556                Subgraphs = mol->DepthFirstSearchAnalysis((ofstream *)&cout, BackEdgeStack);
    15591557                if (Subgraphs != NULL) {
  • src/linkedcell.cpp

    rb8b75d r266237  
    203203
    204204/** Checks whether LinkedCell::n[] plus relative offset is each within [0,N[]].
     205 * Note that for this check we don't admonish if out of bounds.
    205206 * \param relative[NDIM] relative offset to current cell
    206207 * \return if all in intervals - true, else -false
     
    211212  for(int i=0;i<NDIM;i++)
    212213    status = status && ((n[i]+relative[i] >=0) && (n[i]+relative[i] < N[i]));
    213   if (!status)
    214   cerr << "ERROR: indices are out of bounds!" << endl;
    215214  return status;
    216215};
  • src/lists.hpp

    rb8b75d r266237  
    3535  if (walker->previous != NULL)
    3636    walker->previous->next = walker->next;
     37  walker->next = NULL;
     38  walker->previous= NULL;
    3739};
    3840
     
    112114{
    113115  X *pointer = start->next;
    114   X *walker;
     116  X *walker = NULL;
    115117  while (pointer != end) { // go through list
    116118    walker = pointer; // mark current
    117119    pointer = pointer->next; // step onward beforehand
    118120    // remove walker
    119     unlink(walker);
    120     delete(walker);
    121     walker = NULL;
     121    removewithoutcheck(walker);
    122122  }
    123123  return true;
  • src/molecule.cpp

    rb8b75d r266237  
    4848  NoNonHydrogen = 0;
    4949  NoCyclicBonds = 0;
    50   ListOfBondsPerAtom = NULL;
    51   NumberOfBondsPerAtom = NULL;
    5250  ElementCount = 0;
    5351  for(int i=MAX_ELEMENTS;i--;)
     
    6664molecule::~molecule()
    6765{
    68   if (ListOfBondsPerAtom != NULL)
    69     for(int i=AtomCount;i--;)
    70       Free(&ListOfBondsPerAtom[i]);
    71   Free(&ListOfBondsPerAtom);
    72   Free(&NumberOfBondsPerAtom);
    7366  if (TesselStruct != NULL)
    7467    delete(TesselStruct);
     
    160153 * \param *origin pointer to atom which acts as the origin for scaling the added hydrogen to correct bond length
    161154 * \param *replacement pointer to the atom which shall be copied as a hydrogen atom in this molecule
    162  * \param **BondList list of bonds \a *replacement has (necessary to determine plane for double and triple bonds)
    163  * \param NumBond  number of bonds in \a **BondList
    164155 * \param isAngstroem whether the coordination of the given atoms is in AtomicLength (false) or Angstrom(true)
    165156 * \return number of atoms added, if < bond::BondDegree then something went wrong
    166157 * \todo double and triple bonds splitting (always use the tetraeder angle!)
    167158 */
    168 bool molecule::AddHydrogenReplacementAtom(ofstream *out, bond *TopBond, atom *BottomOrigin, atom *TopOrigin, atom *TopReplacement, bond **BondList, int NumBond, bool IsAngstroem)
     159bool molecule::AddHydrogenReplacementAtom(ofstream *out, bond *TopBond, atom *BottomOrigin, atom *TopOrigin, atom *TopReplacement, bool IsAngstroem)
    169160{
    170161  double bondlength;  // bond length of the bond to be replaced/cut
     
    177168  Vector Orthovector1, Orthovector2;  // temporary vectors in coordination construction
    178169  Vector InBondvector;    // vector in direction of *Bond
     170  double *matrix;
    179171  bond *Binder = NULL;
    180   double *matrix;
    181172
    182173//  *out << Verbose(3) << "Begin of AddHydrogenReplacementAtom." << endl;
     
    248239    case 2:
    249240      // determine two other bonds (warning if there are more than two other) plus valence sanity check
    250       for (int i=0;i<NumBond;i++) {
    251         if (BondList[i] != TopBond) {
     241      for (BondList::const_iterator Runner = TopOrigin->ListOfBonds.begin(); Runner != TopOrigin->ListOfBonds.end(); (++Runner)) {
     242        if ((*Runner) != TopBond) {
    252243          if (FirstBond == NULL) {
    253             FirstBond = BondList[i];
    254             FirstOtherAtom = BondList[i]->GetOtherAtom(TopOrigin);
     244            FirstBond = (*Runner);
     245            FirstOtherAtom = (*Runner)->GetOtherAtom(TopOrigin);
    255246          } else if (SecondBond == NULL) {
    256             SecondBond = BondList[i];
    257             SecondOtherAtom = BondList[i]->GetOtherAtom(TopOrigin);
     247            SecondBond = (*Runner);
     248            SecondOtherAtom = (*Runner)->GetOtherAtom(TopOrigin);
    258249          } else {
    259250            *out << Verbose(3) << "WARNING: Detected more than four bonds for atom " << TopOrigin->Name;
     
    523514  if (first->next != last) {  // if adjaceny list is present
    524515    copy->BondDistance = BondDistance;
    525     copy->CreateListOfBondsPerAtom((ofstream *)&cout);
    526516  }
    527517
     
    557547  if ((atom1 != NULL) && (FindAtom(atom1->nr) != NULL) && (atom2 != NULL) && (FindAtom(atom2->nr) != NULL)) {
    558548    Binder = new bond(atom1, atom2, degree, BondCount++);
     549    atom1->RegisterBond(Binder);
     550    atom2->RegisterBond(Binder);
    559551    if ((atom1->type != NULL) && (atom1->type->Z != 1) && (atom2->type != NULL) && (atom2->type->Z != 1))
    560552      NoNonBonds++;
     
    585577bool molecule::RemoveBonds(atom *BondPartner)
    586578{
    587   cerr << Verbose(1) << "molecule::RemoveBond: Function not implemented yet." << endl;
     579  //cerr << Verbose(1) << "molecule::RemoveBond: Function not implemented yet." << endl;
     580  BondList::const_iterator ForeRunner;
     581  while (!BondPartner->ListOfBonds.empty()) {
     582    ForeRunner = BondPartner->ListOfBonds.begin();
     583    RemoveBond(*ForeRunner);
     584  }
    588585  return false;
    589586};
     
    635632  if (ElementsInMolecule[pointer->type->Z] == 0)  // was last atom of this element?
    636633    ElementCount--;
     634  RemoveBonds(pointer);
    637635  return remove(pointer, start, end);
    638636};
     
    661659bool molecule::CleanupMolecule()
    662660{
    663   return (cleanup(start,end) && cleanup(first,last));
     661  return (cleanup(first,last) && cleanup(start,end));
    664662};
    665663
     
    773771};
    774772
    775 /** Outputs contents of molecule::ListOfBondsPerAtom.
     773/** Outputs contents of each atom::ListOfBonds.
    776774 * \param *out output stream
    777775 */
    778776void molecule::OutputListOfBonds(ofstream *out) const
    779777{
    780   *out << Verbose(2) << endl << "From Contents of ListOfBondsPerAtom, all non-hydrogen atoms:" << endl;
    781   ActOnAllAtoms (&atom::OutputBondOfAtom, out, NumberOfBondsPerAtom, ListOfBondsPerAtom);
     778  *out << Verbose(2) << endl << "From Contents of ListOfBonds, all non-hydrogen atoms:" << endl;
     779  ActOnAllAtoms (&atom::OutputBondOfAtom, out);
    782780  *out << endl;
    783781};
     
    900898  }
    901899  configuration.InitMaxMinStopStep = configuration.MaxMinStopStep = configuration.MaxPsiDouble;
    902 };
    903 
    904 
    905 /** Creates an 2d array of pointer with an entry for each atom and each bond it has.
    906  * Updates molecule::ListOfBondsPerAtom, molecule::NumberOfBondsPerAtom by parsing through
    907  * bond chain list, using molecule::AtomCount and molecule::BondCount.
    908  * Allocates memory, fills the array and exits
    909  * \param *out output stream for debugging
    910  */
    911 void molecule::CreateListOfBondsPerAtom(ofstream *out)
    912 {
    913   bond *Binder = NULL;
    914   *out << Verbose(1) << "Begin of Creating ListOfBondsPerAtom: AtomCount = " << AtomCount << "\tBondCount = " << BondCount << "\tNoNonBonds = " << NoNonBonds << "." << endl;
    915 
    916   // re-allocate memory
    917   *out << Verbose(2) << "(Re-)Allocating memory." << endl;
    918   if (ListOfBondsPerAtom != NULL) {
    919     for(int i=AtomCount;i--;)
    920       Free(&ListOfBondsPerAtom[i]);
    921     Free(&ListOfBondsPerAtom);
    922   }
    923   if (NumberOfBondsPerAtom != NULL)
    924     Free(&NumberOfBondsPerAtom);
    925   ListOfBondsPerAtom = Malloc<bond**>(AtomCount, "molecule::CreateListOfBondsPerAtom: ***ListOfBondsPerAtom");
    926   NumberOfBondsPerAtom = Malloc<int>(AtomCount, "molecule::CreateListOfBondsPerAtom: *NumberOfBondsPerAtom");
    927 
    928   // reset bond counts per atom
    929   for(int i=AtomCount;i--;)
    930     NumberOfBondsPerAtom[i] = 0;
    931   // count bonds per atom
    932   Binder = first;
    933   while (Binder->next != last) {
    934     Binder = Binder->next;
    935     NumberOfBondsPerAtom[Binder->leftatom->nr]++;
    936     NumberOfBondsPerAtom[Binder->rightatom->nr]++;
    937   }
    938   for(int i=AtomCount;i--;) {
    939     // allocate list of bonds per atom
    940     ListOfBondsPerAtom[i] = Malloc<bond*>(NumberOfBondsPerAtom[i], "molecule::CreateListOfBondsPerAtom: **ListOfBondsPerAtom[]");
    941     // clear the list again, now each NumberOfBondsPerAtom marks current free field
    942     NumberOfBondsPerAtom[i] = 0;
    943   }
    944   // fill the list
    945   Binder = first;
    946   while (Binder->next != last) {
    947     Binder = Binder->next;
    948     ListOfBondsPerAtom[Binder->leftatom->nr][NumberOfBondsPerAtom[Binder->leftatom->nr]++] = Binder;
    949     ListOfBondsPerAtom[Binder->rightatom->nr][NumberOfBondsPerAtom[Binder->rightatom->nr]++] = Binder;
    950   }
    951 
    952   // output list for debugging
    953   *out << Verbose(3) << "ListOfBondsPerAtom for each atom:" << endl;
    954   ActOnAllAtoms( &atom::OutputBondOfAtom, out, NumberOfBondsPerAtom, ListOfBondsPerAtom );
    955 
    956   *out << Verbose(1) << "End of Creating ListOfBondsPerAtom." << endl << endl;
    957900};
    958901
  • src/molecule.hpp

    rb8b75d r266237  
    8686    bond *first;        //!< start of bond list
    8787    bond *last;         //!< end of bond list
    88     bond ***ListOfBondsPerAtom; //!< pointer list for each atom and each bond it has
    8988    int MDSteps;        //!< The number of MD steps in Trajectories
    90     int *NumberOfBondsPerAtom;  //!< Number of Bonds each atom has
    9189    int AtomCount;          //!< number of atoms, brought up-to-date by CountAtoms()
    9290    int BondCount;          //!< number of atoms, brought up-to-date by CountBonds()
     
    190188  template <typename T> void SetAtomValueToIndexedArray ( T *array, int element::*index, T atom::*value );
    191189
     190  template <typename res> res SumPerAtom(res (atom::*f)() );
     191  template <typename res> res SumPerAtom(res (atom::*f)() const );
     192  template <typename res> res SumPerAtom(res (atom::*f)() ) const;
     193  template <typename res> res SumPerAtom(res (atom::*f)() const ) const;
     194  template <typename T, typename res> res SumPerAtom(res (atom::*f)(T) , T t );
     195  template <typename T, typename res> res SumPerAtom(res (atom::*f)(T) const, T t );
     196  template <typename T, typename res> res SumPerAtom(res (atom::*f)(T) , T t ) const;
     197  template <typename T, typename res> res SumPerAtom(res (atom::*f)(T) const, T t ) const;
     198
    192199  /// remove atoms from molecule.
    193200  bool AddAtom(atom *pointer);
     
    199206  atom * AddCopyAtom(atom *pointer);
    200207  bool AddXYZFile(string filename);
    201   bool AddHydrogenReplacementAtom(ofstream *out, bond *Bond, atom *BottomOrigin, atom *TopOrigin, atom *TopReplacement, bond **BondList, int NumBond, bool IsAngstroem);
     208  bool AddHydrogenReplacementAtom(ofstream *out, bond *Bond, atom *BottomOrigin, atom *TopOrigin, atom *TopReplacement, bool IsAngstroem);
    202209  bond * AddBond(atom *first, atom *second, int degree = 1);
    203210  bool RemoveBond(bond *pointer);
     
    247254  void CreateAdjacencyListFromDbondFile(ofstream *out, ifstream *output);
    248255  void CreateAdjacencyList(ofstream *out, double bonddistance, bool IsAngstroem);
    249   void CreateListOfBondsPerAtom(ofstream *out);
    250256  int CorrectBondDegree(ofstream *out);
    251257  void OutputBondsList(ofstream *out);
    252   int CountAtomsBonds(int nr);
     258  void CyclicBondAnalysis();
     259  void OutputGraphInfoPerAtom(ofstream *out);
     260  void OutputGraphInfoPerBond(ofstream *out);
    253261
    254262
     
    260268  void SetNextComponentNumber(atom *vertex, int nr);
    261269  void InitComponentNumbers();
    262   void OutputComponentNumber(ofstream *out, atom *vertex);
    263270  void ResetAllBondsToUnused();
    264271  void ResetAllAtomNumbers();
     
    266273  bool CheckForConnectedSubgraph(ofstream *out, KeySet *Fragment);
    267274  string GetColor(enum Shading color);
     275  bond * CopyBond(atom *left, atom *right, bond *CopyBond);
     276
    268277
    269278  molecule *CopyMolecule();
  • src/molecule_fragmentation.cpp

    rb8b75d r266237  
    3131int molecule::GuesstimateFragmentCount(ofstream *out, int order)
    3232{
    33   int c = 0;
     33  size_t c = 0;
    3434  int FragmentCount;
    3535  // get maximum bond degree
     
    3737  while (Walker->next != end) {
    3838    Walker = Walker->next;
    39     c = (NumberOfBondsPerAtom[Walker->nr] > c) ? NumberOfBondsPerAtom[Walker->nr] : c;
     39    c = (Walker->ListOfBonds.size() > c) ? Walker->ListOfBonds.size() : c;
    4040  }
    4141  FragmentCount = NoNonHydrogen*(1 << (c*order));
     
    564564
    565565  // ===== 1. Check whether bond structure is same as stored in files ====
    566 
    567   // fill the adjacency list
    568   CreateListOfBondsPerAtom(out);
    569566
    570567  // create lookup table for Atom::nr
     
    630627      MolecularWalker = MolecularWalker->next;
    631628      *out << Verbose(1) << "Fragmenting subgraph " << MolecularWalker << "." << endl;
    632       //MolecularWalker->Leaf->OutputListOfBonds(out);  // output ListOfBondsPerAtom for debugging
     629      //MolecularWalker->Leaf->OutputListOfBonds(out);  // output atom::ListOfBonds for debugging
    633630      if (MolecularWalker->Leaf->first->next != MolecularWalker->Leaf->last) {
    634631        // call BOSSANOVA method
     
    879876    if (SonList[FatherOfRunner->nr] != NULL)  {  // check if this, our father, is present in list
    880877      // create all bonds
    881       for (int i=0;i<mol->NumberOfBondsPerAtom[FatherOfRunner->nr];i++) { // go through every bond of father
    882         OtherFather = mol->ListOfBondsPerAtom[FatherOfRunner->nr][i]->GetOtherAtom(FatherOfRunner);
     878      for (BondList::const_iterator BondRunner = FatherOfRunner->ListOfBonds.begin(); BondRunner != FatherOfRunner->ListOfBonds.end(); (++BondRunner)) {
     879        OtherFather = (*BondRunner)->GetOtherAtom(FatherOfRunner);
    883880//        *out << Verbose(2) << "Father " << *FatherOfRunner << " of son " << *SonList[FatherOfRunner->nr] << " is bound to " << *OtherFather;
    884881        if (SonList[OtherFather->nr] != NULL) {
     
    887884//            *out << Verbose(3) << "Adding Bond: ";
    888885//            *out <<
    889             Leaf->AddBond(Runner, SonList[OtherFather->nr], mol->ListOfBondsPerAtom[FatherOfRunner->nr][i]->BondDegree);
     886            Leaf->AddBond(Runner, SonList[OtherFather->nr], (*BondRunner)->BondDegree);
    890887//            *out << "." << endl;
    891888            //NumBonds[Runner->nr]++;
     
    898895#ifdef ADDHYDROGEN
    899896          //*out << Verbose(3) << "Adding Hydrogen to " << Runner->Name << " and a bond in between." << endl;
    900           if(!Leaf->AddHydrogenReplacementAtom(out, mol->ListOfBondsPerAtom[FatherOfRunner->nr][i], Runner, FatherOfRunner, OtherFather, mol->ListOfBondsPerAtom[FatherOfRunner->nr],mol->NumberOfBondsPerAtom[FatherOfRunner->nr], IsAngstroem))
     897          if(!Leaf->AddHydrogenReplacementAtom(out, (*BondRunner), Runner, FatherOfRunner, OtherFather, IsAngstroem))
    901898            exit(1);
    902899#endif
    903           //NumBonds[Runner->nr] += ListOfBondsPerAtom[FatherOfRunner->nr][i]->BondDegree;
     900          //NumBonds[Runner->nr] += Binder->BondDegree;
    904901        }
    905902      }
     
    936933  CreateInducedSubgraphOfFragment(out, this, Leaf, SonList, IsAngstroem);
    937934
    938   Leaf->CreateListOfBondsPerAtom(out);
    939935  //Leaflet->Leaf->ScanForPeriodicCorrection(out);
    940936  Free(&SonList);
     
    981977    if (bit) {  // if bit is set, we add this bond partner
    982978      OtherWalker = BondsSet[j]->rightatom;  // rightatom is always the one more distant, i.e. the one to add
    983       //*out << Verbose(1+verbosity) << "Current Bond is " << ListOfBondsPerAtom[Walker->nr][CurrentCombination] << ", checking on " << *OtherWalker << "." << endl;
     979      //*out << Verbose(1+verbosity) << "Current Bond is " << BondsSet[j] << ", checking on " << *OtherWalker << "." << endl;
    984980      *out << Verbose(2+verbosity) << "Adding " << *OtherWalker << " with nr " << OtherWalker->nr << "." << endl;
    985981      TestKeySetInsert = FragmentSet->insert(OtherWalker->nr);
     
    10891085  NumCombinations = 1 << SetDimension;
    10901086
    1091   // Hier muessen von 1 bis NumberOfBondsPerAtom[Walker->nr] alle Kombinationen
    1092   // von Endstuecken (aus den Bonds) hinzugefuegt werden und fuer verbleibende ANOVAOrder
    1093   // rekursiv GraphCrawler in der naechsten Ebene aufgerufen werden
     1087  // here for all bonds of Walker all combinations of end pieces (from the bonds)
     1088  // have to be added and for the remaining ANOVA order GraphCrawler be called
     1089  // recursively for the next level
    10941090
    10951091  *out << Verbose(1+verbosity) << "Begin of SPFragmentGenerator." << endl;
     
    12581254  atom *OtherWalker = NULL;
    12591255  atom *Predecessor = NULL;
     1256  bond *CurrentEdge = NULL;
    12601257  bond *Binder = NULL;
    1261   bond *CurrentEdge = NULL;
    12621258  int RootKeyNr = FragmentSearch.Root->GetTrueFather()->nr;
    12631259  int RemainingWalkers = -1;
     
    12851281      // go through all its bonds
    12861282      *out << Verbose(1) << "Going through all bonds of Walker." << endl;
    1287       for (int i=0;i<mol->NumberOfBondsPerAtom[AtomKeyNr];i++) {
    1288         Binder = mol->ListOfBondsPerAtom[AtomKeyNr][i];
    1289         OtherWalker = Binder->GetOtherAtom(Walker);
     1283      for (BondList::const_iterator Runner = Walker->ListOfBonds.begin(); Runner != Walker->ListOfBonds.end(); (++Runner)) {
     1284        OtherWalker = (*Runner)->GetOtherAtom(Walker);
    12901285        if ((RestrictedKeySet.find(OtherWalker->nr) != RestrictedKeySet.end())
    12911286  #ifdef ADDHYDROGEN
     
    12931288  #endif
    12941289                                                              ) {  // skip hydrogens and restrict to fragment
    1295           *out << Verbose(2) << "Current partner is " << *OtherWalker << " with nr " << OtherWalker->nr << " in bond " << *Binder << "." << endl;
     1290          *out << Verbose(2) << "Current partner is " << *OtherWalker << " with nr " << OtherWalker->nr << " in bond " << *(*Runner) << "." << endl;
    12961291          // set the label if not set (and push on root stack as well)
    12971292          if ((OtherWalker != Predecessor) && (OtherWalker->GetTrueFather()->nr > RootKeyNr)) { // only pass through those with label bigger than Root's
     
    17121707        ColorList[Walker->nr] = black;    // mark as explored
    17131708        Walker->x.AddVector(&Translationvector); // translate
    1714         for (int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++) {  // go through all binding partners
    1715           if (ListOfBondsPerAtom[Walker->nr][i] != Binder) {
    1716             OtherWalker = ListOfBondsPerAtom[Walker->nr][i]->GetOtherAtom(Walker);
     1709        for (BondList::const_iterator Runner = Walker->ListOfBonds.begin(); Runner != Walker->ListOfBonds.end(); (++Runner)) {
     1710          if ((*Runner) != Binder) {
     1711            OtherWalker = (*Runner)->GetOtherAtom(Walker);
    17171712            if (ColorList[OtherWalker->nr] == white) {
    17181713              AtomStack->Push(OtherWalker); // push if yet unexplored
  • src/molecule_geometry.cpp

    rb8b75d r266237  
    258258{
    259259  atom *Walker = start;
    260   bond *Binder = NULL;
    261260  double *matrix = ReturnFullMatrixforSymmetric(cell_size);
    262261  double tmp;
     
    275274        Testvector.InverseMatrixMultiplication(matrix);
    276275        Translationvector.Zero();
    277         for (int i=0;i<NumberOfBondsPerAtom[Walker->nr]; i++) {
    278           Binder = ListOfBondsPerAtom[Walker->nr][i];
    279           if (Walker->nr < Binder->GetOtherAtom(Walker)->nr) // otherwise we shift one to, the other fro and gain nothing
     276        for (BondList::const_iterator Runner = Walker->ListOfBonds.begin(); Runner != Walker->ListOfBonds.end(); (++Runner)) {
     277         if (Walker->nr < (*Runner)->GetOtherAtom(Walker)->nr) // otherwise we shift one to, the other fro and gain nothing
    280278            for (int j=0;j<NDIM;j++) {
    281               tmp = Walker->x.x[j] - Binder->GetOtherAtom(Walker)->x.x[j];
     279              tmp = Walker->x.x[j] - (*Runner)->GetOtherAtom(Walker)->x.x[j];
    282280              if ((fabs(tmp)) > BondDistance) {
    283281                flag = false;
    284                 cout << Verbose(0) << "Hit: atom " << Walker->Name << " in bond " << *Binder << " has to be shifted due to " << tmp << "." << endl;
     282                cout << Verbose(0) << "Hit: atom " << Walker->Name << " in bond " << *(*Runner) << " has to be shifted due to " << tmp << "." << endl;
    285283                if (tmp > 0)
    286284                  Translationvector.x[j] -= 1.;
     
    298296#ifdef ADDHYDROGEN
    299297        // now also change all hydrogens
    300         for (int i=0;i<NumberOfBondsPerAtom[Walker->nr]; i++) {
    301           Binder = ListOfBondsPerAtom[Walker->nr][i];
    302           if (Binder->GetOtherAtom(Walker)->type->Z == 1) {
    303             Testvector.CopyVector(&Binder->GetOtherAtom(Walker)->x);
     298        for (BondList::const_iterator Runner = Walker->ListOfBonds.begin(); Runner != Walker->ListOfBonds.end(); (++Runner)) {
     299          if ((*Runner)->GetOtherAtom(Walker)->type->Z == 1) {
     300            Testvector.CopyVector(&(*Runner)->GetOtherAtom(Walker)->x);
    304301            Testvector.InverseMatrixMultiplication(matrix);
    305302            Testvector.AddVector(&Translationvector);
  • src/molecule_graph.cpp

    rb8b75d r266237  
    4848    AddBond(Walker, OtherWalker); //Add the bond between the two atoms with respective indices.
    4949  }
    50 
    51   CreateListOfBondsPerAtom(out);
    5250};
    5351
     
    6462 *  -# put each atom into its corresponding cell
    6563 *  -# go through every cell, check the atoms therein against all possible bond partners in the 27 adjacent cells, add bond if true
    66  *  -# create the list of bonds via CreateListOfBondsPerAtom()
    6764 *  -# correct the bond degree iteratively (single->double->triple bond)
    6865 *  -# finally print the bond list to \a *out if desired
     
    148145    *out << Verbose(1) << "I detected " << BondCount << " bonds in the molecule with distance " << BondDistance << "." << endl;
    149146
    150     // create the adjacency list per atom
    151     CreateListOfBondsPerAtom(out);
    152 
    153147    // correct bond degree by comparing valence and bond degree
    154148    CorrectBondDegree(out);
    155149
    156150    // output bonds for debugging (if bond chain list was correctly installed)
    157     OutputBondsList(out);
     151    ActOnAllAtoms( &atom::OutputBondOfAtom, out );
    158152  } else
    159153    *out << Verbose(1) << "AtomCount is " << AtomCount << ", thus no bonds, no connections!." << endl;
     
    173167  }
    174168  *out << endl;
    175 };
    176 
    177 /** Sums up the number of bonds times bond::BondDegree the atom with index \a nr has.
    178  * \param nr indexof atom
    179  * \return number of bonds each weighted with its bond::BondDegree
    180  */
    181 int molecule::CountAtomsBonds(int nr)
    182 {
    183   int NoBonds = 0;
    184   for(int j=0;j<NumberOfBondsPerAtom[nr];j++)
    185     NoBonds += ListOfBondsPerAtom[nr][j]->BondDegree;
    186   return NoBonds;
    187169};
    188170
     
    198180{
    199181  int No = 0;
    200   int NoBonds = 0;
    201   int CandidateBondNo = 0;
    202   int FalseBondDegree = 0;
    203   atom *Walker = NULL;
    204   atom *Candidate = NULL;
    205   atom *OtherWalker = NULL;
    206182
    207183  if (BondCount != 0) {
    208     NoCyclicBonds = 0;
    209     *out << Verbose(1) << "Correcting Bond degree of each bond ... ";
     184    *out << Verbose(1) << "Correcting Bond degree of each bond ... " << endl;
    210185    do {
    211       No = 0; // No acts as breakup flag (if 1 we still continue)
    212       Walker = start;
    213       while (Walker->next != end) { // go through every atom
    214         Walker = Walker->next;
    215 
    216         NoBonds = CountAtomsBonds(Walker->nr);
    217         *out << Verbose(3) << "Walker " << *Walker << ": " << (int)Walker->type->NoValenceOrbitals << " > " << NoBonds << "?" << endl;
    218         if ((int)(Walker->type->NoValenceOrbitals) > NoBonds) { // we have a mismatch, check all bonding partners for mismatch
    219           Candidate = NULL;
    220           CandidateBondNo = -1;
    221           for(int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++) { // go through each of its bond partners
    222             OtherWalker = ListOfBondsPerAtom[Walker->nr][i]->GetOtherAtom(Walker);
    223             NoBonds = CountAtomsBonds(OtherWalker->nr);
    224             *out << Verbose(3) << "OtherWalker " << *OtherWalker << ": " << (int)OtherWalker->type->NoValenceOrbitals << " > " << NoBonds << "?" << endl;
    225             if ((int)(OtherWalker->type->NoValenceOrbitals) > NoBonds) { // check if possible candidate
    226               if ((Candidate == NULL) || (NumberOfBondsPerAtom[Candidate->nr] > NumberOfBondsPerAtom[OtherWalker->nr])) { // pick the one with fewer number of bonds first
    227                 Candidate = OtherWalker;
    228                 CandidateBondNo = i;
    229                 *out << Verbose(3) << "New candidate is " << *Candidate << "." << endl;
    230               }
    231             }
    232           }
    233           if ((Candidate != NULL) && (CandidateBondNo != -1)) {
    234             ListOfBondsPerAtom[Walker->nr][CandidateBondNo]->BondDegree++;
    235             *out << Verbose(2) << "Increased bond degree for bond " << *ListOfBondsPerAtom[Walker->nr][CandidateBondNo] << "." << endl;
    236           } else {
    237             *out << Verbose(2) << "Could not find correct degree for atom " << *Walker << "." << endl;
    238             FalseBondDegree++;
    239           }
    240         }
    241       }
     186      No = SumPerAtom( &atom::CorrectBondDegree, out );
    242187    } while (No);
    243188    *out << " done." << endl;
     
    245190    *out << Verbose(1) << "BondCount is " << BondCount << ", no bonds between any of the " << AtomCount << " atoms." << endl;
    246191  }
    247   *out << FalseBondDegree << " bonds could not be corrected." << endl;
    248 
    249   return (FalseBondDegree);
     192  *out << No << " bonds could not be corrected." << endl;
     193
     194  return (No);
    250195};
    251196
     
    257202int molecule::CountCyclicBonds(ofstream *out)
    258203{
    259   int No = 0;
     204  NoCyclicBonds = 0;
    260205  int *MinimumRingSize = NULL;
    261206  MoleculeLeafClass *Subgraphs = NULL;
     
    275220    Binder = Binder->next;
    276221    if (Binder->Cyclic)
    277       No++;
     222      NoCyclicBonds++;
    278223  }
    279224  delete(BackEdgeStack);
    280   return No;
     225  return NoCyclicBonds;
    281226};
    282227
     
    459404  }
    460405  // set cyclic bond criterium on "same LP" basis
    461   Binder = first;
     406  CyclicBondAnalysis();
     407
     408  OutputGraphInfoPerAtom(out);
     409
     410  OutputGraphInfoPerBond(out);
     411
     412  // free all and exit
     413  delete(AtomStack);
     414  *out << Verbose(0) << "End of DepthFirstSearchAnalysis" << endl;
     415  return SubGraphs;
     416};
     417
     418/** Scans through all bonds and set bond::Cyclic to true where atom::LowpointNr of both ends is equal: LP criterion.
     419 */
     420void molecule::CyclicBondAnalysis()
     421{
     422  NoCyclicBonds = 0;
     423  bond *Binder = first;
    462424  while(Binder->next != last) {
    463425    Binder = Binder->next;
     
    467429    }
    468430  }
    469 
    470 
     431};
     432
     433/** Output graph information per atom.
     434 * \param *out output stream
     435 */
     436void molecule::OutputGraphInfoPerAtom(ofstream *out)
     437{
    471438  *out << Verbose(1) << "Final graph info for each atom is:" << endl;
    472   Walker = start;
    473   while (Walker->next != end) {
    474     Walker = Walker->next;
    475     *out << Verbose(2) << "Atom " << Walker->Name << " is " << ((Walker->SeparationVertex) ? "a" : "not a") << " separation vertex, components are ";
    476     OutputComponentNumber(out, Walker);
    477     *out << " with Lowpoint " << Walker->LowpointNr << " and Graph Nr. " << Walker->GraphNr << "." << endl;
    478   }
    479 
     439  ActOnAllAtoms( &atom::OutputGraphInfo, out );
     440};
     441
     442/** Output graph information per bond.
     443 * \param *out output stream
     444 */
     445void molecule::OutputGraphInfoPerBond(ofstream *out)
     446{
    480447  *out << Verbose(1) << "Final graph info for each bond is:" << endl;
    481   Binder = first;
     448  bond *Binder = first;
    482449  while(Binder->next != last) {
    483450    Binder = Binder->next;
    484451    *out << Verbose(2) << ((Binder->Type == TreeEdge) ? "TreeEdge " : "BackEdge ") << *Binder << ": <";
    485452    *out << ((Binder->leftatom->SeparationVertex) ? "SP," : "") << "L" << Binder->leftatom->LowpointNr << " G" << Binder->leftatom->GraphNr << " Comp.";
    486     OutputComponentNumber(out, Binder->leftatom);
     453    Binder->leftatom->OutputComponentNumber(out);
    487454    *out << " ===  ";
    488455    *out << ((Binder->rightatom->SeparationVertex) ? "SP," : "") << "L" << Binder->rightatom->LowpointNr << " G" << Binder->rightatom->GraphNr << " Comp.";
    489     OutputComponentNumber(out, Binder->rightatom);
     456    Binder->rightatom->OutputComponentNumber(out);
    490457    *out << ">." << endl;
    491458    if (Binder->Cyclic) // cyclic ??
    492459      *out << Verbose(3) << "Lowpoint at each side are equal: CYCLIC!" << endl;
    493460  }
    494 
    495   // free all and exit
    496   delete(AtomStack);
    497   *out << Verbose(0) << "End of DepthFirstSearchAnalysis" << endl;
    498   return SubGraphs;
    499461};
    500462
     
    547509      Walker = BFSStack->PopFirst();
    548510      *out << Verbose(2) << "Current Walker is " << *Walker << ", we look for SP to Root " << *Root << "." << endl;
    549       for(int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++) {
    550         Binder = ListOfBondsPerAtom[Walker->nr][i];
    551         if (Binder != BackEdge) { // only walk along DFS spanning tree (otherwise we always find SP of one being backedge Binder)
    552           OtherAtom = Binder->GetOtherAtom(Walker);
     511      for (BondList::const_iterator Runner = Walker->ListOfBonds.begin(); Runner != Walker->ListOfBonds.end(); (++Runner)) {
     512        if ((*Runner) != BackEdge) { // only walk along DFS spanning tree (otherwise we always find SP of one being backedge Binder)
     513          OtherAtom = (*Runner)->GetOtherAtom(Walker);
    553514#ifdef ADDHYDROGEN
    554515          if (OtherAtom->type->Z != 1) {
     
    662623          Walker = BFSStack->PopFirst();
    663624          //*out << Verbose(2) << "Current Walker is " << *Walker << ", we look for SP to Root " << *Root << "." << endl;
    664           for(int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++) {
    665             Binder = ListOfBondsPerAtom[Walker->nr][i];
    666             if ((Binder != BackEdge) || (NumberOfBondsPerAtom[Walker->nr] == 1)) { // only walk along DFS spanning tree (otherwise we always find SP of 1 being backedge Binder), but terminal hydrogens may be connected via backedge, hence extra check
    667               OtherAtom = Binder->GetOtherAtom(Walker);
     625          for (BondList::const_iterator Runner = Walker->ListOfBonds.begin(); Runner != Walker->ListOfBonds.end(); (++Runner)) {
     626            if (((*Runner) != BackEdge) || (Walker->ListOfBonds.size() == 1)) { // only walk along DFS spanning tree (otherwise we always find SP of 1 being backedge Binder), but terminal hydrogens may be connected via backedge, hence extra check
     627              OtherAtom = (*Runner)->GetOtherAtom(Walker);
    668628              //*out << Verbose(2) << "Current OtherAtom is: " << OtherAtom->Name << " for bond " << *Binder << "." << endl;
    669629              if (ColorList[OtherAtom->nr] == white) {
     
    717677void molecule::SetNextComponentNumber(atom *vertex, int nr)
    718678{
    719   int i=0;
     679  size_t i=0;
    720680  if (vertex != NULL) {
    721     for(;i<NumberOfBondsPerAtom[vertex->nr];i++) {
     681    for(;i<vertex->ListOfBonds.size();i++) {
    722682      if (vertex->ComponentNr[i] == -1) {   // check if not yet used
    723683        vertex->ComponentNr[i] = nr;
     
    727687        break;  // breaking here will not cause error!
    728688    }
    729     if (i == NumberOfBondsPerAtom[vertex->nr])
     689    if (i == vertex->ListOfBonds.size())
    730690      cerr << "Error: All Component entries are already occupied!" << endl;
    731691  } else
    732692      cerr << "Error: Given vertex is NULL!" << endl;
    733 };
    734 
    735 /** Output a list of flags, stating whether the bond was visited or not.
    736  * \param *out output stream for debugging
    737  */
    738 void molecule::OutputComponentNumber(ofstream *out, atom *vertex)
    739 {
    740   for(int i=0;i<NumberOfBondsPerAtom[vertex->nr];i++)
    741     *out << vertex->ComponentNr[i] << "  ";
    742693};
    743694
     
    751702    if (Walker->ComponentNr != NULL)
    752703      Free(&Walker->ComponentNr);
    753     Walker->ComponentNr = Malloc<int>(NumberOfBondsPerAtom[Walker->nr], "molecule::InitComponentNumbers: *Walker->ComponentNr");
    754     for (int i=NumberOfBondsPerAtom[Walker->nr];i--;)
     704    Walker->ComponentNr = Malloc<int>(Walker->ListOfBonds.size()+1, "molecule::InitComponentNumbers: *Walker->ComponentNr");
     705    for (int i=Walker->ListOfBonds.size()+1;i--;)
    755706      Walker->ComponentNr[i] = -1;
    756707  }
     
    763714bond * molecule::FindNextUnused(atom *vertex)
    764715{
    765   for(int i=0;i<NumberOfBondsPerAtom[vertex->nr];i++)
    766     if (ListOfBondsPerAtom[vertex->nr][i]->IsUsed() == white)
    767       return(ListOfBondsPerAtom[vertex->nr][i]);
     716  for (BondList::const_iterator Runner = vertex->ListOfBonds.begin(); Runner != vertex->ListOfBonds.end(); (++Runner))
     717    if ((*Runner)->IsUsed() == white)
     718      return((*Runner));
    768719  return NULL;
    769720};
     
    813764{
    814765  ofstream AdjacencyFile;
    815   atom *Walker = NULL;
    816766  stringstream line;
    817767  bool status = true;
     
    821771  *out << Verbose(1) << "Saving adjacency list ... ";
    822772  if (AdjacencyFile != NULL) {
    823     Walker = start;
    824     while(Walker->next != end) {
    825       Walker = Walker->next;
    826       AdjacencyFile << Walker->nr << "\t";
    827       for (int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++)
    828         AdjacencyFile << ListOfBondsPerAtom[Walker->nr][i]->GetOtherAtom(Walker)->nr << "\t";
    829       AdjacencyFile << endl;
    830     }
     773    ActOnAllAtoms( &atom::OutputAdjacency, &AdjacencyFile );
    831774    AdjacencyFile.close();
    832775    *out << Verbose(1) << "done." << endl;
     
    850793  stringstream filename;
    851794  bool status = true;
     795  atom *Walker = NULL;
    852796  char *buffer = Malloc<char>(MAXSTRINGSIZE, "molecule::CheckAdjacencyFileAgainstMolecule: *buffer");
    853797
     
    859803    int NonMatchNumber = 0;   // will number of atoms with differing bond structure
    860804    int *CurrentBonds = Malloc<int>(8, "molecule::CheckAdjacencyFileAgainstMolecule - CurrentBonds"); // contains parsed bonds of current atom
    861     int CurrentBondsOfAtom;
     805    size_t CurrentBondsOfAtom;
    862806
    863807    // Parse the file line by line and count the bonds
     
    871815      // parse into structure
    872816      if ((AtomNr >= 0) && (AtomNr < AtomCount)) {
     817        Walker = ListOfAtoms[AtomNr];
    873818        while (!line.eof())
    874819          line >> CurrentBonds[ ++CurrentBondsOfAtom ];
    875820        // compare against present bonds
    876821        //cout << Verbose(2) << "Walker is " << *Walker << ", bond partners: ";
    877         if (CurrentBondsOfAtom == NumberOfBondsPerAtom[AtomNr]) {
    878           for(int i=0;i<NumberOfBondsPerAtom[AtomNr];i++) {
    879             int id = ListOfBondsPerAtom[AtomNr][i]->GetOtherAtom(ListOfAtoms[AtomNr])->nr;
    880             int j = 0;
     822        if (CurrentBondsOfAtom == Walker->ListOfBonds.size()) {
     823          for (BondList::const_iterator Runner = Walker->ListOfBonds.begin(); Runner != Walker->ListOfBonds.end(); (++Runner)) {
     824            int id = (*Runner)->GetOtherAtom(Walker)->nr;
     825            size_t j = 0;
    881826            for (;(j<CurrentBondsOfAtom) && (CurrentBonds[j++] != id);); // check against all parsed bonds
    882827            if (CurrentBonds[j-1] != id) { // no match ? Then mark in ListOfAtoms
     
    891836          //out << endl;
    892837        } else {
    893           *out << "Number of bonds for Atom " << *ListOfAtoms[AtomNr] << " does not match, parsed " << CurrentBondsOfAtom << " against " << NumberOfBondsPerAtom[AtomNr] << "." << endl;
     838          *out << "Number of bonds for Atom " << *Walker << " does not match, parsed " << CurrentBondsOfAtom << " against " << Walker->ListOfBonds.size() << "." << endl;
    894839          status = false;
    895840        }
     
    937882    Walker = ListOfLocalAtoms[Binder->leftatom->nr];  // get one atom in the reference molecule
    938883    if (Walker != NULL) // if this Walker exists in the subgraph ...
    939       for(int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++) {    // go through the local list of bonds
    940         OtherAtom = ListOfBondsPerAtom[Walker->nr][i]->GetOtherAtom(Walker);
    941         if (OtherAtom == ListOfLocalAtoms[Binder->rightatom->nr]) { // found the bond
    942           LocalStack->Push(ListOfBondsPerAtom[Walker->nr][i]);
    943           *out << Verbose(3) << "Found local edge " << *(ListOfBondsPerAtom[Walker->nr][i]) << "." << endl;
     884      for (BondList::const_iterator Runner = Walker->ListOfBonds.begin(); Runner != Walker->ListOfBonds.end(); (++Runner)) {
     885        OtherAtom = (*Runner)->GetOtherAtom(Walker);
     886        if (OtherAtom == ListOfLocalAtoms[(*Runner)->rightatom->nr]) { // found the bond
     887          LocalStack->Push((*Runner));
     888          *out << Verbose(3) << "Found local edge " << *(*Runner) << "." << endl;
    944889          break;
    945890        }
     
    973918  class StackClass<atom *> *AtomStack = new StackClass<atom *>(AtomCount);
    974919  atom *Walker = NULL, *OtherAtom = NULL;
    975   bond *Binder = NULL;
    976920
    977921  // add Root if not done yet
     
    999943    // followed by n+1 till top of stack.
    1000944    Walker = AtomStack->PopFirst(); // pop oldest added
    1001     *out << Verbose(1) << "Current Walker is: " << Walker->Name << ", and has " << NumberOfBondsPerAtom[Walker->nr] << " bonds." << endl;
    1002     for(int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++) {
    1003       Binder = ListOfBondsPerAtom[Walker->nr][i];
    1004       if (Binder != NULL) { // don't look at bond equal NULL
    1005         OtherAtom = Binder->GetOtherAtom(Walker);
    1006         *out << Verbose(2) << "Current OtherAtom is: " << OtherAtom->Name << " for bond " << *Binder << "." << endl;
     945    *out << Verbose(1) << "Current Walker is: " << Walker->Name << ", and has " << Walker->ListOfBonds.size() << " bonds." << endl;
     946    for (BondList::const_iterator Runner = Walker->ListOfBonds.begin(); Runner != Walker->ListOfBonds.end(); (++Runner)) {
     947      if ((*Runner) != NULL) { // don't look at bond equal NULL
     948        OtherAtom = (*Runner)->GetOtherAtom(Walker);
     949        *out << Verbose(2) << "Current OtherAtom is: " << OtherAtom->Name << " for bond " << *(*Runner) << "." << endl;
    1007950        if (ColorList[OtherAtom->nr] == white) {
    1008           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)
     951          if ((*Runner) != 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)
    1009952            ColorList[OtherAtom->nr] = lightgray;
    1010953          PredecessorList[OtherAtom->nr] = Walker;  // Walker is the predecessor
    1011954          ShortestPathList[OtherAtom->nr] = ShortestPathList[Walker->nr]+1;
    1012955          *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;
    1013           if ((((ShortestPathList[OtherAtom->nr] < BondOrder) && (Binder != Bond))) ) { // Check for maximum distance
     956          if ((((ShortestPathList[OtherAtom->nr] < BondOrder) && ((*Runner) != Bond))) ) { // Check for maximum distance
    1014957            *out << Verbose(3);
    1015958            if (AddedAtomList[OtherAtom->nr] == NULL) { // add if it's not been so far
    1016959              AddedAtomList[OtherAtom->nr] = Mol->AddCopyAtom(OtherAtom);
    1017960              *out << "Added OtherAtom " << OtherAtom->Name;
    1018               AddedBondList[Binder->nr] = Mol->AddBond(AddedAtomList[Walker->nr], AddedAtomList[OtherAtom->nr], Binder->BondDegree);
    1019               AddedBondList[Binder->nr]->Cyclic = Binder->Cyclic;
    1020               AddedBondList[Binder->nr]->Type = Binder->Type;
    1021               *out << " and bond " << *(AddedBondList[Binder->nr]) << ", ";
     961              AddedBondList[(*Runner)->nr] = Mol->CopyBond(AddedAtomList[Walker->nr], AddedAtomList[OtherAtom->nr], (*Runner));
     962              *out << " and bond " << *(AddedBondList[(*Runner)->nr]) << ", ";
    1022963            } else {  // this code should actually never come into play (all white atoms are not yet present in BondMolecule, that's why they are white in the first place)
    1023964              *out << "Not adding OtherAtom " << OtherAtom->Name;
    1024               if (AddedBondList[Binder->nr] == NULL) {
    1025                 AddedBondList[Binder->nr] = Mol->AddBond(AddedAtomList[Walker->nr], AddedAtomList[OtherAtom->nr], Binder->BondDegree);
    1026                 AddedBondList[Binder->nr]->Cyclic = Binder->Cyclic;
    1027                 AddedBondList[Binder->nr]->Type = Binder->Type;
    1028                 *out << ", added Bond " << *(AddedBondList[Binder->nr]);
     965              if (AddedBondList[(*Runner)->nr] == NULL) {
     966                AddedBondList[(*Runner)->nr] = Mol->CopyBond(AddedAtomList[Walker->nr], AddedAtomList[OtherAtom->nr], (*Runner));
     967                *out << ", added Bond " << *(AddedBondList[(*Runner)->nr]);
    1029968              } else
    1030969                *out << ", not added Bond ";
     
    1033972            AtomStack->Push(OtherAtom);
    1034973          } else { // out of bond order, then replace
    1035             if ((AddedAtomList[OtherAtom->nr] == NULL) && (Binder->Cyclic))
     974            if ((AddedAtomList[OtherAtom->nr] == NULL) && ((*Runner)->Cyclic))
    1036975              ColorList[OtherAtom->nr] = white; // unmark if it has not been queued/added, to make it available via its other bonds (cyclic)
    1037             if (Binder == Bond)
     976            if ((*Runner) == Bond)
    1038977              *out << Verbose(3) << "Not Queueing, is the Root bond";
    1039978            else if (ShortestPathList[OtherAtom->nr] >= BondOrder)
    1040979              *out << Verbose(3) << "Not Queueing, is out of Bond Count of " << BondOrder;
    1041             if (!Binder->Cyclic)
     980            if (!(*Runner)->Cyclic)
    1042981              *out << ", is not part of a cyclic bond, saturating bond with Hydrogen." << endl;
    1043             if (AddedBondList[Binder->nr] == NULL) {
     982            if (AddedBondList[(*Runner)->nr] == NULL) {
    1044983              if ((AddedAtomList[OtherAtom->nr] != NULL)) { // .. whether we add or saturate
    1045                 AddedBondList[Binder->nr] = Mol->AddBond(AddedAtomList[Walker->nr], AddedAtomList[OtherAtom->nr], Binder->BondDegree);
    1046                 AddedBondList[Binder->nr]->Cyclic = Binder->Cyclic;
    1047                 AddedBondList[Binder->nr]->Type = Binder->Type;
     984                AddedBondList[(*Runner)->nr] = Mol->CopyBond(AddedAtomList[Walker->nr], AddedAtomList[OtherAtom->nr], (*Runner));
    1048985              } else {
    1049986#ifdef ADDHYDROGEN
    1050                 if (!Mol->AddHydrogenReplacementAtom(out, Binder, AddedAtomList[Walker->nr], Walker, OtherAtom, ListOfBondsPerAtom[Walker->nr], NumberOfBondsPerAtom[Walker->nr], IsAngstroem))
     987                if (!Mol->AddHydrogenReplacementAtom(out, (*Runner), AddedAtomList[Walker->nr], Walker, OtherAtom, IsAngstroem))
    1051988                  exit(1);
    1052989#endif
     
    1057994          *out << Verbose(3) << "Not Adding, has already been visited." << endl;
    1058995          // This has to be a cyclic bond, check whether it's present ...
    1059           if (AddedBondList[Binder->nr] == NULL) {
    1060             if ((Binder != Bond) && (Binder->Cyclic) && (((ShortestPathList[Walker->nr]+1) < BondOrder))) {
    1061               AddedBondList[Binder->nr] = Mol->AddBond(AddedAtomList[Walker->nr], AddedAtomList[OtherAtom->nr], Binder->BondDegree);
    1062               AddedBondList[Binder->nr]->Cyclic = Binder->Cyclic;
    1063               AddedBondList[Binder->nr]->Type = Binder->Type;
     996          if (AddedBondList[(*Runner)->nr] == NULL) {
     997            if (((*Runner) != Bond) && ((*Runner)->Cyclic) && (((ShortestPathList[Walker->nr]+1) < BondOrder))) {
     998              AddedBondList[(*Runner)->nr] = Mol->CopyBond(AddedAtomList[Walker->nr], AddedAtomList[OtherAtom->nr], (*Runner));
    1064999            } else { // if it's root bond it has to broken (otherwise we would not create the fragments)
    10651000#ifdef ADDHYDROGEN
    1066               if(!Mol->AddHydrogenReplacementAtom(out, Binder, AddedAtomList[Walker->nr], Walker, OtherAtom, ListOfBondsPerAtom[Walker->nr], NumberOfBondsPerAtom[Walker->nr], IsAngstroem))
     1001              if(!Mol->AddHydrogenReplacementAtom(out, (*Runner), AddedAtomList[Walker->nr], Walker, OtherAtom, IsAngstroem))
    10671002                exit(1);
    10681003#endif
     
    10801015  delete(AtomStack);
    10811016};
     1017
     1018/** Adds a bond as a copy to a given one
     1019 * \param *left leftatom of new bond
     1020 * \param *right rightatom of new bond
     1021 * \param *CopyBond rest of fields in bond are copied from this
     1022 * \return pointer to new bond
     1023 */
     1024bond * molecule::CopyBond(atom *left, atom *right, bond *CopyBond)
     1025{
     1026  bond *Binder = AddBond(left, right, CopyBond->BondDegree);
     1027  Binder->Cyclic = CopyBond->Cyclic;
     1028  Binder->Type = CopyBond->Type;
     1029  return Binder;
     1030};
     1031
    10821032
    10831033/** Adds bond structure to this molecule from \a Father molecule.
     
    11221072        status = false;
    11231073      } else {
    1124         for (int i=0;i<Father->NumberOfBondsPerAtom[Walker->nr];i++) {
    1125           OtherAtom = Father->ListOfBondsPerAtom[Walker->nr][i]->GetOtherAtom(Walker);
     1074        for (BondList::const_iterator Runner = Walker->ListOfBonds.begin(); Runner != Walker->ListOfBonds.end(); (++Runner)) {
     1075          OtherAtom = (*Runner)->GetOtherAtom(Walker);
    11261076          if (ParentList[OtherAtom->nr] != NULL) { // if otheratom is also a father of an atom on this molecule, create the bond
    1127             *out << Verbose(4) << "Endpoints of Bond " << Father->ListOfBondsPerAtom[Walker->nr][i] << " are both present: " << ParentList[Walker->nr]->Name << " and " << ParentList[OtherAtom->nr]->Name << "." << endl;
    1128             AddBond(ParentList[Walker->nr], ParentList[OtherAtom->nr], Father->ListOfBondsPerAtom[Walker->nr][i]->BondDegree);
     1077            *out << Verbose(4) << "Endpoints of Bond " << (*Runner) << " are both present: " << ParentList[Walker->nr]->Name << " and " << ParentList[OtherAtom->nr]->Name << "." << endl;
     1078            AddBond(ParentList[Walker->nr], ParentList[OtherAtom->nr], (*Runner)->BondDegree);
    11291079          }
    11301080        }
     
    11641114      for(KeySet::iterator runners = Fragment->begin(); runners != Fragment->end(); runners++) {
    11651115        Walker2 = FindAtom(*runners);
    1166         for (int i=0;i<NumberOfBondsPerAtom[Walker->nr]; i++) {
    1167           if (ListOfBondsPerAtom[Walker->nr][i]->GetOtherAtom(Walker) == Walker2) {
     1116        for (BondList::const_iterator Runner = Walker->ListOfBonds.begin(); Runner != Walker->ListOfBonds.end(); (++Runner)) {
     1117          if ((*Runner)->GetOtherAtom(Walker) == Walker2) {
    11681118            BondStatus = true;
    11691119            break;
  • src/molecule_template.hpp

    rb8b75d r266237  
    153153};
    154154
     155// ========================= Summing over each Atoms =================================== //
     156
     157// zero arguments
     158template <typename res> res molecule::SumPerAtom(res (atom::*f)() )
     159{
     160  res result = 0;
     161  atom *Walker = start;
     162  while (Walker->next != end) {
     163    Walker = Walker->next;
     164    result += (Walker->*f)();
     165  }
     166  return result;
     167};
     168template <typename res> res molecule::SumPerAtom(res (atom::*f)() const )
     169{
     170  res result = 0;
     171  atom *Walker = start;
     172  while (Walker->next != end) {
     173    Walker = Walker->next;
     174    result += (Walker->*f)();
     175  }
     176  return result;
     177};
     178template <typename res> res molecule::SumPerAtom(res (atom::*f)() ) const
     179{
     180  res result = 0;
     181  atom *Walker = start;
     182  while (Walker->next != end) {
     183    Walker = Walker->next;
     184    result += (Walker->*f)();
     185  }
     186  return result;
     187};
     188template <typename res> res molecule::SumPerAtom(res (atom::*f)() const ) const
     189{
     190  res result = 0;
     191  atom *Walker = start;
     192  while (Walker->next != end) {
     193    Walker = Walker->next;
     194    result += (Walker->*f)();
     195  }
     196  return result;
     197};
     198// one argument
     199template <typename T, typename res> res molecule::SumPerAtom(res (atom::*f)(T), T t )
     200{
     201  res result = 0;
     202  atom *Walker = start;
     203  while (Walker->next != end) {
     204    Walker = Walker->next;
     205    result += (Walker->*f)(t);
     206  }
     207  return result;
     208};
     209template <typename T, typename res> res molecule::SumPerAtom(res (atom::*f)(T) const, T t )
     210{
     211  res result = 0;
     212  atom *Walker = start;
     213  while (Walker->next != end) {
     214    Walker = Walker->next;
     215    result += (Walker->*f)(t);
     216  }
     217  return result;
     218};
     219template <typename T, typename res> res molecule::SumPerAtom(res (atom::*f)(T), T t ) const
     220{
     221  res result = 0;
     222  atom *Walker = start;
     223  while (Walker->next != end) {
     224    Walker = Walker->next;
     225    result += (Walker->*f)(t);
     226  }
     227  return result;
     228};
     229template <typename T, typename res> res molecule::SumPerAtom(res (atom::*f)(T) const, T t ) const
     230{
     231  res result = 0;
     232  atom *Walker = start;
     233  while (Walker->next != end) {
     234    Walker = Walker->next;
     235    result += (Walker->*f)(t);
     236  }
     237  return result;
     238};
     239
     240
    155241// ================== Acting with each Atoms on same molecule ========================== //
    156242
  • src/moleculelist.cpp

    rb8b75d r266237  
    376376  atom *Walker = NULL;
    377377  atom *Runner = NULL;
     378  bond *Binder = NULL;
    378379  double ***FitConstant = NULL, **correction = NULL;
    379380  int a, b;
     
    482483    while (Walker->next != (*ListRunner)->end) {
    483484      Walker = Walker->next;
    484       //cout << Verbose(1) << "Walker: " << *Walker << " with first bond " << *(*Runner)->ListOfBondsPerAtom[Walker->nr][0] << "." << endl;
     485      //cout << Verbose(1) << "Walker: " << *Walker << " with first bond " << *(Walker->ListOfBonds.begin()) << "." << endl;
    485486      if ((Walker->type->Z == 1) && ((Walker->father == NULL)
    486487          || (Walker->father->type->Z != 1))) { // if it's a hydrogen
     
    488489        while (Runner->next != (*ListRunner)->end) {
    489490          Runner = Runner->next;
    490           //cout << Verbose(2) << "Runner: " << *Runner << " with first bond " << *(*Runner)->ListOfBondsPerAtom[Runner->nr][0] << "." << endl;
     491          //cout << Verbose(2) << "Runner: " << *Runner << " with first bond " << *(Walker->ListOfBonds.begin()) << "." << endl;
    491492          // 3. take every other hydrogen that is the not the first and not bound to same bonding partner
    492           if ((Runner->type->Z == 1) && (Runner->nr > Walker->nr) && ((*ListRunner)->ListOfBondsPerAtom[Runner->nr][0]->GetOtherAtom(Runner) != (*ListRunner)->ListOfBondsPerAtom[Walker->nr][0]->GetOtherAtom(Walker))) { // (hydrogens have only one bonding partner!)
     493          Binder = *(Runner->ListOfBonds.begin());
     494          if ((Runner->type->Z == 1) && (Runner->nr > Walker->nr) && (Binder->GetOtherAtom(Runner) != Binder->GetOtherAtom(Walker))) { // (hydrogens have only one bonding partner!)
    493495            // 4. evaluate the morse potential for each matrix component and add up
    494496            distance = Runner->x.Distance(&Walker->x);
     
    812814bool MoleculeLeafClass::FillBondStructureFromReference(ofstream *out, molecule *reference, int &FragmentCounter, atom ***&ListOfLocalAtoms, bool FreeList)
    813815{
    814   atom *Walker = NULL, *OtherWalker = NULL;
    815   bond *Binder = NULL;
     816  atom *Walker = NULL;
     817  atom *OtherWalker = NULL;
     818  atom *Father = NULL;
    816819  bool status = true;
    817820  int AtomNo;
     
    830833    while (Walker->next != Leaf->end) {
    831834      Walker = Walker->next;
    832       AtomNo = Walker->GetTrueFather()->nr; // global id of the current walker
    833       for (int i = 0; i < reference->NumberOfBondsPerAtom[AtomNo]; i++) { // go through father's bonds and copy them all
    834         Binder = reference->ListOfBondsPerAtom[AtomNo][i];
    835         OtherWalker = ListOfLocalAtoms[FragmentCounter][Binder->GetOtherAtom(Walker->GetTrueFather())->nr]; // local copy of current bond partner of walker
     835      Father = Walker->GetTrueFather();
     836      AtomNo = Father->nr; // global id of the current walker
     837      for (BondList::const_iterator Runner = Father->ListOfBonds.begin(); Runner != Father->ListOfBonds.end(); (++Runner)) {
     838        OtherWalker = ListOfLocalAtoms[FragmentCounter][(*Runner)->GetOtherAtom(Walker->GetTrueFather())->nr]; // local copy of current bond partner of walker
    836839        if (OtherWalker != NULL) {
    837840          if (OtherWalker->nr > Walker->nr)
    838             Leaf->AddBond(Walker, OtherWalker, Binder->BondDegree);
     841            Leaf->AddBond(Walker, OtherWalker, (*Runner)->BondDegree);
    839842        } else {
    840           *out << Verbose(1) << "OtherWalker = ListOfLocalAtoms[" << FragmentCounter << "][" << Binder->GetOtherAtom(Walker->GetTrueFather())->nr << "] is NULL!" << endl;
     843          *out << Verbose(1) << "OtherWalker = ListOfLocalAtoms[" << FragmentCounter << "][" << (*Runner)->GetOtherAtom(Walker->GetTrueFather())->nr << "] is NULL!" << endl;
    841844          status = false;
    842845        }
    843846      }
    844847    }
    845     Leaf->CreateListOfBondsPerAtom(out);
    846848    FragmentCounter++;
    847849    if (next != NULL)
  • src/unittests/Makefile.am

    rb8b75d r266237  
    11INCLUDES = -I$(top_srcdir)/src
    22
    3 noinst_PROGRAMS =  ActOnAllUnitTest AnalysisCorrelationToPointUnitTest AnalysisCorrelationToSurfaceUnitTest AnalysisPairCorrelationUnitTest MemoryAllocatorUnitTest MemoryUsageObserverUnitTest VectorUnitTest
     3noinst_PROGRAMS =  ActOnAllUnitTest AnalysisCorrelationToPointUnitTest AnalysisCorrelationToSurfaceUnitTest AnalysisPairCorrelationUnitTest ListOfBondsUnitTest MemoryAllocatorUnitTest MemoryUsageObserverUnitTest VectorUnitTest
    44
    5 TESTS = ActOnAllUnitTest AnalysisCorrelationToPointUnitTest AnalysisCorrelationToSurfaceUnitTest AnalysisPairCorrelationUnitTest MemoryUsageObserverUnitTest MemoryAllocatorUnitTest VectorUnitTest
     5TESTS = ActOnAllUnitTest AnalysisCorrelationToPointUnitTest AnalysisCorrelationToSurfaceUnitTest AnalysisPairCorrelationUnitTest ListOfBondsUnitTest MemoryUsageObserverUnitTest MemoryAllocatorUnitTest VectorUnitTest
    66check_PROGRAMS = $(TESTS)
    77
     
    2626AnalysisPairCorrelationUnitTest_LDADD = ../libmolecuilder.a
    2727
     28ListOfBondsUnitTest_SOURCES = listofbondsunittest.cpp listofbondsunittest.hpp
     29ListOfBondsUnitTest_CXXFLAGS = $(CPPUNIT_CFLAGS)
     30ListOfBondsUnitTest_LDFLAGS = $(CPPUNIT_LIBS) -ldl
     31ListOfBondsUnitTest_LDADD = ../libmolecuilder.a
     32
    2833VectorUnitTest_SOURCES = defs.hpp helpers.hpp leastsquaremin.hpp memoryallocator.hpp memoryusageobserver.hpp vectorunittest.cpp vectorunittest.hpp vector.hpp verbose.hpp
    2934VectorUnitTest_CXXFLAGS = $(CPPUNIT_CFLAGS)
Note: See TracChangeset for help on using the changeset viewer.