Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/moleculelist.cpp

    rf66195 rc9bce3e  
    1212#include "helpers.hpp"
    1313#include "linkedcell.hpp"
     14#include "lists.hpp"
    1415#include "molecule.hpp"
    1516#include "memoryallocator.hpp"
     
    306307bool MoleculeListClass::EmbedMerge(molecule *mol, molecule *srcmol)
    307308{
     309  LinkedCell *LCList = NULL;
     310  Tesselation *TesselStruct = NULL;
    308311  if ((srcmol == NULL) || (mol == NULL)) {
    309312    cout << Verbose(1) << "ERROR: Either fixed or variable molecule is given as NULL." << endl;
     
    312315
    313316  // calculate envelope for *mol
    314   LinkedCell *LCList = new LinkedCell(mol, 8.);
    315   FindNonConvexBorder((ofstream *)&cout, mol, LCList, 4., NULL);
    316   if (mol->TesselStruct == NULL) {
     317  LCList = new LinkedCell(mol, 8.);
     318  FindNonConvexBorder((ofstream *)&cout, mol, TesselStruct, (const LinkedCell *&)LCList, 4., NULL);
     319  if (TesselStruct == NULL) {
    317320    cout << Verbose(1) << "ERROR: Could not tesselate the fixed molecule." << endl;
    318321    return false;
    319322  }
    320323  delete(LCList);
    321   LCList = new LinkedCell(mol->TesselStruct, 8.);  // re-create with boundary points only!
     324  LCList = new LinkedCell(TesselStruct, 8.);  // re-create with boundary points only!
    322325
    323326  // prepare index list for bonds
     
    333336    Walker = Walker->next;
    334337    cout << Verbose(2) << "INFO: Current Walker is " << *Walker << "." << endl;
    335     if (!mol->TesselStruct->IsInnerPoint((ofstream *)&cout, Walker->x, LCList)) {
     338    if (!TesselStruct->IsInnerPoint((ofstream *)&cout, Walker->x, LCList)) {
    336339      CopyAtoms[Walker->nr] = new atom(Walker);
    337340      mol->AddAtom(CopyAtoms[Walker->nr]);
     
    376379  atom *Walker = NULL;
    377380  atom *Runner = NULL;
     381  bond *Binder = NULL;
    378382  double ***FitConstant = NULL, **correction = NULL;
    379383  int a, b;
     
    419423
    420424  // 0b. allocate memory for constants
    421   FitConstant = Malloc<double**>(3, "MoleculeListClass::AddHydrogenCorrection: ***FitConstant");
     425  FitConstant = Calloc<double**>(3, "MoleculeListClass::AddHydrogenCorrection: ***FitConstant");
    422426  for (int k = 0; k < 3; k++) {
    423     FitConstant[k] = Malloc<double*>(a, "MoleculeListClass::AddHydrogenCorrection: **FitConstant[]");
     427    FitConstant[k] = Calloc<double*>(a, "MoleculeListClass::AddHydrogenCorrection: **FitConstant[]");
    424428    for (int i = a; i--;) {
    425       FitConstant[k][i] = Malloc<double>(b, "MoleculeListClass::AddHydrogenCorrection: *FitConstant[][]");
     429      FitConstant[k][i] = Calloc<double>(b, "MoleculeListClass::AddHydrogenCorrection: *FitConstant[][]");
    426430    }
    427431  }
     
    468472
    469473  // 0d. allocate final correction matrix
    470   correction = Malloc<double*>(a, "MoleculeListClass::AddHydrogenCorrection: **correction");
     474  correction = Calloc<double*>(a, "MoleculeListClass::AddHydrogenCorrection: **correction");
    471475  for (int i = a; i--;)
    472     correction[i] = Malloc<double>(b, "MoleculeListClass::AddHydrogenCorrection: *correction[]");
     476    correction[i] = Calloc<double>(b, "MoleculeListClass::AddHydrogenCorrection: *correction[]");
    473477
    474478  // 1a. go through every molecule in the list
     
    482486    while (Walker->next != (*ListRunner)->end) {
    483487      Walker = Walker->next;
    484       //cout << Verbose(1) << "Walker: " << *Walker << " with first bond " << *(*Runner)->ListOfBondsPerAtom[Walker->nr][0] << "." << endl;
     488      //cout << Verbose(1) << "Walker: " << *Walker << " with first bond " << *(Walker->ListOfBonds.begin()) << "." << endl;
    485489      if ((Walker->type->Z == 1) && ((Walker->father == NULL)
    486490          || (Walker->father->type->Z != 1))) { // if it's a hydrogen
     
    488492        while (Runner->next != (*ListRunner)->end) {
    489493          Runner = Runner->next;
    490           //cout << Verbose(2) << "Runner: " << *Runner << " with first bond " << *(*Runner)->ListOfBondsPerAtom[Runner->nr][0] << "." << endl;
     494          //cout << Verbose(2) << "Runner: " << *Runner << " with first bond " << *(Walker->ListOfBonds.begin()) << "." << endl;
    491495          // 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!)
     496          Binder = *(Runner->ListOfBonds.begin());
     497          if ((Runner->type->Z == 1) && (Runner->nr > Walker->nr) && (Binder->GetOtherAtom(Runner) != Binder->GetOtherAtom(Walker))) { // (hydrogens have only one bonding partner!)
    493498            // 4. evaluate the morse potential for each matrix component and add up
    494499            distance = Runner->x.Distance(&Walker->x);
     
    544549  output.close();
    545550  // 6. free memory of parsed matrices
    546   FitConstant = Malloc<double**>(a, "MoleculeListClass::AddHydrogenCorrection: ***FitConstant");
    547551  for (int k = 0; k < 3; k++) {
    548     FitConstant[k] = Malloc<double*>(a, "MoleculeListClass::AddHydrogenCorrection: **FitConstant[]");
    549552    for (int i = a; i--;) {
    550       FitConstant[k][i] = Malloc<double>(b, "MoleculeListClass::AddHydrogenCorrection: *FitConstant[][]");
    551     }
    552   }
     553      Free(&FitConstant[k][i]);
     554    }
     555    Free(&FitConstant[k]);
     556  }
     557  Free(&FitConstant);
    553558  cout << "done." << endl;
    554559  return true;
     
    708713    //outputFragment.close();
    709714    //outputFragment.clear();
    710     delete (FragmentNumber);
    711     //Free(&FragmentNumber);
     715    Free(&FragmentNumber);
    712716  }
    713717  cout << " done." << endl;
     
    730734};
    731735
     736/** Dissects given \a *mol into connected subgraphs and inserts them as new molecules but with old atoms into \a this.
     737 * \param *out output stream for debugging
     738 * \param *mol molecule with atoms to dissect
     739 * \param *configuration config with BondGraph
     740 */
     741void MoleculeListClass::DissectMoleculeIntoConnectedSubgraphs(ofstream * const out, molecule * const mol, config * const configuration)
     742{
     743  // 1. dissect the molecule into connected subgraphs
     744  configuration ->BG->ConstructBondGraph(out, mol);
     745
     746  // 2. scan for connected subgraphs
     747  MoleculeLeafClass *Subgraphs = NULL;      // list of subgraphs from DFS analysis
     748  class StackClass<bond *> *BackEdgeStack = NULL;
     749  Subgraphs = mol->DepthFirstSearchAnalysis(out, BackEdgeStack);
     750  delete(BackEdgeStack);
     751
     752  // 3. dissect (the following construct is needed to have the atoms not in the order of the DFS, but in
     753  // the original one as parsed in)
     754  // TODO: Optimize this, when molecules just contain pointer list of global atoms!
     755
     756  // 4a. create array of molecules to fill
     757  const int MolCount = Subgraphs->next->Count();
     758  molecule **molecules = Malloc<molecule *>(MolCount, "config::Load() - **molecules");
     759  for (int i=0;i<MolCount;i++) {
     760    molecules[i] = (molecule*) new molecule(mol->elemente);
     761    molecules[i]->ActiveFlag = true;
     762    insert(molecules[i]);
     763  }
     764
     765  // 4b. create and fill map of which atom is associated to which connected molecule (note, counting starts at 1)
     766  int FragmentCounter = 0;
     767  int *MolMap = Calloc<int>(mol->AtomCount, "config::Load() - *MolMap");
     768  MoleculeLeafClass *MolecularWalker = Subgraphs;
     769  atom *Walker = NULL;
     770  while (MolecularWalker->next != NULL) {
     771    MolecularWalker = MolecularWalker->next;
     772    Walker = MolecularWalker->Leaf->start;
     773    while (Walker->next != MolecularWalker->Leaf->end) {
     774      Walker = Walker->next;
     775      MolMap[Walker->GetTrueFather()->nr] = FragmentCounter+1;
     776    }
     777    FragmentCounter++;
     778  }
     779
     780  // 4c. relocate atoms to new molecules and remove from Leafs
     781  Walker = mol->start;
     782  while (mol->start->next != mol->end) {
     783    Walker = mol->start->next;
     784    if ((Walker->nr <0) || (Walker->nr >= mol->AtomCount)) {
     785      cerr << "Index of atom " << *Walker << " is invalid!" << endl;
     786      performCriticalExit();
     787    }
     788    FragmentCounter = MolMap[Walker->nr];
     789    if (FragmentCounter != 0) {
     790      cout << Verbose(3) << "Re-linking " << *Walker << "..." << endl;
     791      unlink(Walker);
     792      molecules[FragmentCounter-1]->AddAtom(Walker);    // counting starts at 1
     793    } else {
     794      cerr << "Atom " << *Walker << " not associated to molecule!" << endl;
     795      performCriticalExit();
     796    }
     797  }
     798  // 4d. we don't need to redo bonds, as they are connected subgraphs and still maintained their ListOfBonds
     799  // 4e. free Leafs
     800  MolecularWalker = Subgraphs;
     801  while (MolecularWalker->next != NULL) {
     802    MolecularWalker = MolecularWalker->next;
     803    delete(MolecularWalker->previous);
     804  }
     805  delete(MolecularWalker);
     806  Free(&MolMap);
     807  Free(&molecules);
     808  cout << Verbose(1) << "I scanned " << FragmentCounter << " molecules." << endl;
     809};
    732810
    733811/******************************************* Class MoleculeLeafClass ************************************************/
     
    810888 * \return true - success, false - faoilure
    811889 */
    812 bool MoleculeLeafClass::FillBondStructureFromReference(ofstream *out, molecule *reference, int &FragmentCounter, atom ***&ListOfLocalAtoms, bool FreeList)
    813 {
    814   atom *Walker = NULL, *OtherWalker = NULL;
    815   bond *Binder = NULL;
     890bool MoleculeLeafClass::FillBondStructureFromReference(ofstream *out, const molecule * const reference, int &FragmentCounter, atom ***&ListOfLocalAtoms, bool FreeList)
     891{
     892  atom *Walker = NULL;
     893  atom *OtherWalker = NULL;
     894  atom *Father = NULL;
    816895  bool status = true;
    817896  int AtomNo;
     
    825904
    826905  if (status) {
    827     *out << Verbose(1) << "Creating adjacency list for subgraph " << this
    828         << "." << endl;
     906    *out << Verbose(1) << "Creating adjacency list for subgraph " << Leaf << "." << endl;
     907    // remove every bond from the list
     908    bond *Binder = NULL;
     909    while (Leaf->last->previous != Leaf->first) {
     910      Binder = Leaf->last->previous;
     911      Binder->leftatom->UnregisterBond(Binder);
     912      Binder->rightatom->UnregisterBond(Binder);
     913      removewithoutcheck(Binder);
     914    }
     915
    829916    Walker = Leaf->start;
    830917    while (Walker->next != Leaf->end) {
    831918      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
     919      Father = Walker->GetTrueFather();
     920      AtomNo = Father->nr; // global id of the current walker
     921      for (BondList::const_iterator Runner = Father->ListOfBonds.begin(); Runner != Father->ListOfBonds.end(); (++Runner)) {
     922        OtherWalker = ListOfLocalAtoms[FragmentCounter][(*Runner)->GetOtherAtom(Walker->GetTrueFather())->nr]; // local copy of current bond partner of walker
    836923        if (OtherWalker != NULL) {
    837924          if (OtherWalker->nr > Walker->nr)
    838             Leaf->AddBond(Walker, OtherWalker, Binder->BondDegree);
     925            Leaf->AddBond(Walker, OtherWalker, (*Runner)->BondDegree);
    839926        } else {
    840           *out << Verbose(1) << "OtherWalker = ListOfLocalAtoms[" << FragmentCounter << "][" << Binder->GetOtherAtom(Walker->GetTrueFather())->nr << "] is NULL!" << endl;
     927          *out << Verbose(1) << "OtherWalker = ListOfLocalAtoms[" << FragmentCounter << "][" << (*Runner)->GetOtherAtom(Walker->GetTrueFather())->nr << "] is NULL!" << endl;
    841928          status = false;
    842929        }
    843930      }
    844931    }
    845     Leaf->CreateListOfBondsPerAtom(out);
    846     FragmentCounter++;
    847     if (next != NULL)
    848       status = next->FillBondStructureFromReference(out, reference, FragmentCounter, ListOfLocalAtoms);
    849     FragmentCounter--;
    850932  }
    851933
     
    856938      Free(&ListOfLocalAtoms);
    857939  }
    858   FragmentCounter--;
    859940  *out << Verbose(1) << "End of FillBondStructureFromReference." << endl;
    860941  return status;
     
    903984
    904985/** Fills a lookup list of father's Atom::nr -> atom for each subgraph.
    905  * \param *out output stream fro debugging
     986 * \param *out output stream from debugging
    906987 * \param ***ListOfLocalAtoms Lookup table for each subgraph and index of each atom in global molecule, may be NULL on start, then it is filled
    907988 * \param FragmentCounter counts the fragments as we move along the list
    908989 * \param GlobalAtomCount number of atoms in the complete molecule
    909990 * \param &FreeList true - ***ListOfLocalAtoms is free'd before return, false - it is not
    910  * \return true - succes, false - failure
     991 * \return true - success, false - failure
    911992 */
    912993bool MoleculeLeafClass::FillListOfLocalAtoms(ofstream *out, atom ***&ListOfLocalAtoms, const int FragmentCounter, const int GlobalAtomCount, bool &FreeList)
     
    914995  bool status = true;
    915996
    916   int Counter = Count();
    917997  if (ListOfLocalAtoms == NULL) { // allocated initial pointer
    918998    // allocate and set each field to NULL
    919     ListOfLocalAtoms = Malloc<atom**>(Counter, "MoleculeLeafClass::FillBondStructureFromReference - ***ListOfLocalAtoms");
    920     if (ListOfLocalAtoms != NULL) {
    921       for (int i = Counter; i--;)
    922         ListOfLocalAtoms[i] = NULL;
    923       FreeList = FreeList && true;
    924     } else
     999    const int Counter = Count();
     1000    ListOfLocalAtoms = Calloc<atom**>(Counter, "MoleculeLeafClass::FillListOfLocalAtoms - ***ListOfLocalAtoms");
     1001    if (ListOfLocalAtoms == NULL) {
     1002      FreeList = FreeList && false;
    9251003      status = false;
     1004    }
    9261005  }
    9271006
     
    9611040  if (FragmentList == NULL) {
    9621041    KeySetCounter = Count();
    963     FragmentList = Malloc<Graph*>(KeySetCounter, "MoleculeLeafClass::AssignKeySetsToFragment - **FragmentList");
    964     for (int i = KeySetCounter; i--;)
    965       FragmentList[i] = NULL;
     1042    FragmentList = Calloc<Graph*>(KeySetCounter, "MoleculeLeafClass::AssignKeySetsToFragment - **FragmentList");
    9661043    KeySetCounter = 0;
    9671044  }
Note: See TracChangeset for help on using the changeset viewer.