Ignore:
Timestamp:
Aug 18, 2008, 8:57:58 AM (17 years ago)
Author:
Frederik Heber <heber@…>
Children:
04c868
Parents:
e6971b
Message:

Adaptivity fixes, MD by VerletForceIntegration introduced, MD molecule::Trajectories, atom Max::Order, no more recursive going down the fragmentation level

MD
==
molecule::Trajectories is now a map to a struct trajectory list of all the MD steps.
struct Trajectory contains STL vectors of coordinates, velocities and forces. Both are needed for the new VerletForceIntegration.
Parsing of coordinates, velocities and forces from the config file was completely rewritten:

  • in the FastParsing case, we just scan for IonType1_1 to find the last step, set the file pointer there and scan all remaining ones
  • in the other case, we create the atoms in the first step and put them in a hash for lookup on later steps and read in sequentially (with file pointer moving on).
  • This is a lot faster than the old variant.

VerletForceIntegration() implemented in a working manner with force smoothing (mean of actual and last one).
OutputTrajectoriesXYZ() now concatenates the single MD steps into one xyz file, so that the animation can be viewed with e.g. jmol or vmd
config:Deltat is now public (lazy me) and set to 1 instead of 0 initially, also Deltat is parsed accordingly (if not present, defaults to 1)
MatrixContainer::ParseMatrix from parser.cpp is used during VerletForceIntegration() to parse the forces file. Consequently, we have included parser.* in the Makefile.am.
Fix: MoleculeListClass::OutputConfigForListOfFragments() stores config file under config::configpath, before it backup'd the path twice to PathBackup.

Adaptivity
==========
Adaptivity (CheckOrderAtSite()) had compared not absolute, but real values which caused sign problems and faulty behaviour.
Adapatvity (CheckOrderAtSite()) had included atoms by Order (desired one) not by FragOrder (current one) into the list of candidates, which caused faulty behaviour.
CheckOrderAtSite() did single stepping wrong as the mask bit (last in AtomMask) was checked for true not false! Also bit was not set to false initially in FragmentMolecule().
Adaptivity: FragmentMolecule now returns 1 - continue, 2 - don't ... to tell whether we still have to continue with the adaptive cycle (is given as return value from molecuilder)
introduced atom::MaxOrder
StoreOrderAtSiteFile() now also stores the MaxOrder and ParseOrderAtSiteFromFile() parses it back into atom class

Removed Fragmentation Recursion
===============================
As we switched in the prelude of the adaptivity to a monotonous increase from order 1 to the desired one, we don't need to recursively go down each level from a given current bond order, as all these fragments have already been created on the lower orders. Consequently, FragmentBOSSANOVA does not contain NumLevels or alike anymore. This simplified the code a bit, but probably is not yet completely done. (but is working, checked on heptan).
SPFragmentGenerator() does not need Labels anymore, global ones are used for checks. Consequently, PowerSetGenerator() and FragmentSearch structure don't initialise/contain them anymore. We always compare against ...->GetTrueFather()->nr.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • molecuilder/src/molecules.cpp

    re6971b r644ba1  
    455455  getline(xyzfile,line,'\n'); // Read comment
    456456  cout << Verbose(1) << "Comment: " << line << endl;
    457 
     457 
     458  if (MDSteps == 0) // no atoms yet present
     459    MDSteps++;
    458460  for(i=0;i<NumberOfAtoms;i++){
    459461    Walker = new atom;
     
    471473      Walker->type = elemente->FindElement(1);
    472474    }
    473     for(j=NDIM;j--;)
     475    if (Trajectories[Walker].R.size() <= (unsigned int)MDSteps) {
     476      Trajectories[Walker].R.resize(MDSteps+10);
     477      Trajectories[Walker].U.resize(MDSteps+10);
     478      Trajectories[Walker].F.resize(MDSteps+10);
     479    }
     480    for(j=NDIM;j--;) {
    474481      Walker->x.x[j] = x[j];
    475      AddAtom(Walker);  // add to molecule
     482      Trajectories[Walker].R.at(MDSteps-1).x[j] = x[j];
     483      Trajectories[Walker].U.at(MDSteps-1).x[j] = 0;
     484      Trajectories[Walker].F.at(MDSteps-1).x[j] = 0;
     485    }
     486    AddAtom(Walker);  // add to molecule
    476487    delete(item);
    477488  }
     
    965976
    966977/** Parses nuclear forces from file and performs Verlet integration.
     978 * Note that we assume the parsed forces to be in atomic units (hence, if coordinates are in angstroem, we
     979 * have to transform them).
    967980 * This adds a new MD step to the config file.
    968981 * \param *file filename
    969982 * \param delta_t time step width in atomic units
     983 * \param IsAngstroem whether coordinates are in angstroem (true) or bohrradius (false)
    970984 * \return true - file found and parsed, false - file not found or imparsable
    971985 */
    972 bool molecule::VerletForceIntegration(char *file, double delta_t)
    973 {
    974   bool status = true;
     986bool molecule::VerletForceIntegration(char *file, double delta_t, bool IsAngstroem)
     987{
    975988  element *runner = elemente->start;
    976989  atom *walker = NULL;
    977   int ElementNo, AtomNo;
     990  int AtomNo;
    978991  ifstream input(file);
    979   double Forcesvector[3];
    980   double dummy;
    981992  string token;
    982   size_t oldpos, newpos;
    983993  stringstream item;
    984   int i, Ion[2];
    985   double a, IonMass;
    986   unsigned int size;
     994  double a, IonMass, Vector[NDIM];
     995  ForceMatrix Force;
    987996
    988997  CountElements();  // make sure ElementsInMolecule is up to date
     
    9921001    return false;
    9931002  } else {
    994     ElementNo = 0;
     1003    // parse file into ForceMatrix
     1004    if (!Force.ParseMatrix(file, 0,0,0)) {
     1005      cerr << "Could not parse Force Matrix file " << file << "." << endl;
     1006      return false;
     1007    }
     1008    if (Force.RowCounter[0] != AtomCount) {
     1009      cerr << "Mismatch between number of atoms in file " << Force.RowCounter[0] << " and in molecule " << AtomCount << "." << endl;
     1010      return false;
     1011    }
     1012    // correct Forces
     1013    for(int d=0;d<NDIM;d++)
     1014      Vector[d] = 0.;
     1015    for(int i=0;i<AtomCount;i++)
     1016      for(int d=0;d<NDIM;d++) {
     1017        Vector[d] += Force.Matrix[0][i][d+5];
     1018      }
     1019    for(int i=0;i<AtomCount;i++)
     1020      for(int d=0;d<NDIM;d++) {
     1021        Force.Matrix[0][i][d+5] -= Vector[d]/(double)AtomCount;
     1022      }
     1023    // and perform Verlet integration for each atom with position, velocity and force vector
     1024    runner = elemente->start;
    9951025    while (runner->next != elemente->end) { // go through every element
    9961026      runner = runner->next;
    9971027      IonMass = runner->mass;
     1028      a = delta_t*0.5/IonMass;        // (F+F_old)/2m = a and thus: v = (F+F_old)/2m * t = (F + F_old) * a
    9981029      if (ElementsInMolecule[runner->Z]) { // if this element got atoms
    999         ElementNo++;
    10001030        AtomNo = 0;
    10011031        walker = start;
     
    10031033          walker = walker->next;
    10041034          if (walker->type == runner) { // if this atom fits to element
    1005             AtomNo++;
    1006             // parse Forcevector for this ion
    1007             getline (input, token, '\n');
    1008             newpos = oldpos = i = 0;
    1009             while ((newpos = token.find( '\t', oldpos)) != oldpos) {
    1010               i++;
    1011               item.str();
    1012               switch (i) {
    1013                 case 1:
    1014                 case 2:
    1015                   item >> Ion[i-1];
    1016                   break;
    1017                 case 6:
    1018                 case 7:
    1019                 case 8:
    1020                   item >> Forcesvector[i-6];
    1021                   break;
    1022                 case 3:
    1023                   if ((Ion[0] != ElementNo) || (Ion[1] != AtomNo))
    1024                     cout << "ERROR: Expected " << ElementNo << ", " << AtomNo << "but parsed " << Ion[0] << ", " << Ion[1] << "." << endl;
    1025                   // still parse into dummy! Hence no break here ...
    1026                 default:
    1027                   item >> dummy;
    1028               }
    1029               oldpos = newpos;
     1035            // check size of vectors
     1036            if (Trajectories[walker].R.size() <= (unsigned int)(MDSteps)) {
     1037              //cout << "Increasing size for trajectory array of " << *walker << " to " << (size+10) << "." << endl;
     1038              Trajectories[walker].R.resize(MDSteps+10);
     1039              Trajectories[walker].U.resize(MDSteps+10);
     1040              Trajectories[walker].F.resize(MDSteps+10);
    10301041            }
    10311042           
    1032             // perform Verlet integration for this atom with position, velocity and force vector
    1033            
    1034             // UpdateR
    1035 //            for (int d=0; d<NDIM; d++) {
    1036 //              R_old_old[d] = R_old[d];        // shift old values
    1037 //              R_old[d] = R[d];
    1038 //              R[d] += delta_t*(U[d]+a*FIon[d]);     // F = m * a and s = 0.5 * a * t^2
    1039 //              FIon_old[d] = FIon[d];          // store old force
    1040 //            }
    1041 //            // UpdateU
    1042 //            a = delta_t*0.5/IonMass;        // (F+F_old)/2m = a and thus: v = (F+F_old)/2m * t = (F + F_old) * a
    1043 //            for (int d=0; d<NDIM; d++) {
    1044 //                U[d] += a * (FIon[d]+FIon_old[d]);
    1045 //            }
    1046            
    1047            
    1048             // check size of vectors
    1049             size = Trajectories[walker].R.size();
    1050             if (size <= (unsigned int)(MDSteps)) {
    1051               cout << "Increasing size for trajectory array of " << *walker << " to " << (size+10) << "." << endl;
    1052               Trajectories[walker].R.resize(size+10);
    1053               Trajectories[walker].U.resize(size+10);
    1054               Trajectories[walker].F.resize(size+10);
     1043            // Update R (and F)
     1044            for (int d=0; d<NDIM; d++) {
     1045              Trajectories[walker].F.at(MDSteps).x[d] = -Force.Matrix[0][AtomNo][d+5]*(IsAngstroem ? AtomicLengthToAngstroem : 1.);
     1046              Trajectories[walker].R.at(MDSteps).x[d] = Trajectories[walker].R.at(MDSteps-1).x[d];
     1047              Trajectories[walker].R.at(MDSteps).x[d] += delta_t*(Trajectories[walker].U.at(MDSteps-1).x[d]);
     1048              Trajectories[walker].R.at(MDSteps).x[d] += delta_t*a*(Trajectories[walker].F.at(MDSteps).x[d]);     // F = m * a and s = 0.5 * F/m * t^2 = F * a * t
    10551049            }
    1056             // add trajectory point
    1057 
     1050            // Update U
     1051            for (int d=0; d<NDIM; d++) {
     1052              Trajectories[walker].U.at(MDSteps).x[d] = Trajectories[walker].U.at(MDSteps-1).x[d];
     1053              Trajectories[walker].U.at(MDSteps).x[d] += a * (Trajectories[walker].F.at(MDSteps).x[d]+Trajectories[walker].F.at(MDSteps-1).x[d]);
     1054            }
     1055//            cout << "Integrated position&velocity of step " << (MDSteps) << ": (";
     1056//            for (int d=0;d<NDIM;d++)
     1057//              cout << Trajectories[walker].R.at(MDSteps).x[d] << " ";          // next step
     1058//            cout << ")\t(";
     1059//            for (int d=0;d<NDIM;d++)
     1060//              cout << Trajectories[walker].U.at(MDSteps).x[d] << " ";          // next step
     1061//            cout << ")" << endl;
     1062            // next atom
     1063            AtomNo++;
    10581064          }
    10591065        }
    10601066      }
    10611067    }
    1062     return true;
    1063   }
     1068  }
     1069//  // correct velocities (rather momenta) so that center of mass remains motionless
     1070//  for(int d=0;d<NDIM;d++)
     1071//    Vector[d] = 0.;
     1072//  IonMass = 0.;
     1073//  walker = start;
     1074//  while (walker->next != end) { // go through every atom
     1075//    walker = walker->next;
     1076//    IonMass += walker->type->mass;  // sum up total mass
     1077//    for(int d=0;d<NDIM;d++) {
     1078//      Vector[d] += Trajectories[walker].U.at(MDSteps).x[d]*walker->type->mass;
     1079//    }
     1080//  }
     1081//  walker = start;
     1082//  while (walker->next != end) { // go through every atom of this element
     1083//    walker = walker->next;
     1084//    for(int d=0;d<NDIM;d++) {
     1085//      Trajectories[walker].U.at(MDSteps).x[d] -= Vector[d]*walker->type->mass/IonMass;
     1086//    }
     1087//  }
     1088  MDSteps++;
     1089
    10641090 
    10651091  // exit
    1066   return status;
     1092  return true;
    10671093};
    10681094
     
    13721398              if (Trajectories[walker].F.at(step).Norm() > MYEPSILON)
    13731399                *out << "\t" << scientific << setprecision(6) << Trajectories[walker].F.at(step).x[0] << "\t" << Trajectories[walker].F.at(step).x[1] << "\t" << Trajectories[walker].F.at(step).x[2] << "\t";
    1374               *out << " # Number in molecule " << walker->nr << endl;
     1400              *out << "\t# Number in molecule " << walker->nr << endl;
    13751401            }
    13761402          }
     
    14131439};
    14141440
     1441/** Prints molecule with all its trajectories to *out as xyz file.
     1442 * \param *out output stream
     1443 */
     1444bool molecule::OutputTrajectoriesXYZ(ofstream *out)
     1445{
     1446  atom *walker = NULL;
     1447  int No = 0;
     1448  time_t now;
     1449 
     1450  now = time((time_t *)NULL);   // Get the system time and put it into 'now' as 'calender time'
     1451  walker = start;
     1452  while (walker->next != end) { // go through every atom and count
     1453    walker = walker->next;
     1454    No++;
     1455  }
     1456  if (out != NULL) {
     1457    for (int step=0;step<MDSteps;step++) {
     1458      *out << No << "\n\tCreated by molecuilder, step " << step << ", on " << ctime(&now);
     1459      walker = start;
     1460      while (walker->next != end) { // go through every atom of this element
     1461        walker = walker->next;
     1462        *out << walker->type->symbol << "\t" << Trajectories[walker].R.at(step).x[0] << "\t" << Trajectories[walker].R.at(step).x[1] << "\t" << Trajectories[walker].R.at(step).x[2] << endl;
     1463      }
     1464    }
     1465    return true;
     1466  } else
     1467    return false;
     1468};
     1469
    14151470/** Prints molecule to *out as xyz file.
    1416  * \param *out output stream
     1471* \param *out output stream
    14171472 */
    14181473bool molecule::OutputXYZ(ofstream *out) const
     
    26152670        lines++;
    26162671      }
    2617       *out << Verbose(2) << "Scanned " << lines-1 << " lines." << endl;   // one endline too much
     2672      //*out << Verbose(2) << "Scanned " << lines-1 << " lines." << endl;   // one endline too much
    26182673      InputFile.clear();
    26192674      InputFile.seekg(ios::beg);
     
    26272682        InputFile.getline(buffer, MAXSTRINGSIZE);
    26282683        if (strlen(buffer) > 2) {
    2629           //*out << Verbose(2) << "Scanning: " << buffer;
     2684          //*out << Verbose(2) << "Scanning: " << buffer << endl;
    26302685          stringstream line(buffer);
    26312686          line >> FragOrder;
     
    26342689          line >> ws >> Value;
    26352690          No -= 1;  // indices start at 1 in file, not 0
    2636           //*out << Verbose(2) << " - yields (" << No << "," << Value << ")" << endl;
     2691          //*out << Verbose(2) << " - yields (" << No << "," << Value << ", " << FragOrder << ")" << endl;
    26372692
    26382693          // clean the list of those entries that have been superceded by higher order terms already
    26392694          map<int,KeySet>::iterator marker = IndexKeySetList.find(No);    // find keyset to Frag No.
    26402695          if (marker != IndexKeySetList.end()) {  // if found
     2696            Value *= 1 + MYEPSILON*(*((*marker).second.begin()));     // in case of equal energies this makes em not equal without changing anything actually
    26412697            // as the smallest number in each set has always been the root (we use global id to keep the doubles away), seek smallest and insert into AtomMask
    2642             pair <map<int, pair<double,int> >::iterator, bool> InsertedElement = AdaptiveCriteriaList.insert( make_pair(*((*marker).second.begin()), pair<double,int>( Value, Order) ));
     2698            pair <map<int, pair<double,int> >::iterator, bool> InsertedElement = AdaptiveCriteriaList.insert( make_pair(*((*marker).second.begin()), pair<double,int>( fabs(Value), FragOrder) ));
    26432699            map<int, pair<double,int> >::iterator PresentItem = InsertedElement.first;
    26442700            if (!InsertedElement.second) { // this root is already present
     
    26462702                //if ((*PresentItem).second.first < (*runner).first)    // as higher-order terms are not always better, we skip this part (which would always include this site into adaptive increase)
    26472703                {  // if value is smaller, update value and order
    2648                 (*PresentItem).second.first = Value;
     2704                (*PresentItem).second.first = fabs(Value);
    26492705                (*PresentItem).second.second = FragOrder;
    26502706                *out << Verbose(2) << "Updated element (" <<  (*PresentItem).first << ",[" << (*PresentItem).second.first << "," << (*PresentItem).second.second << "])." << endl;
     2707              } else {
     2708                *out << Verbose(2) << "Did not update element " <<  (*PresentItem).first << " as " << FragOrder << " is less than or equal to " << (*PresentItem).second.second << "." << endl;
    26512709              }
    26522710            } else {
     
    26642722        Walker = FindAtom((*runner).first);
    26652723        if (Walker != NULL) {
    2666           if ((*runner).second.second >= Walker->AdaptiveOrder) { // only insert if this is an "active" root site for the current order
     2724          //if ((*runner).second.second >= Walker->AdaptiveOrder) { // only insert if this is an "active" root site for the current order
     2725          if (!Walker->MaxOrder) {
    26672726            *out << Verbose(2) << "(" << (*runner).first << ",[" << (*runner).second.first << "," << (*runner).second.second << "])" << endl;
    26682727            FinalRootCandidates.insert( make_pair( (*runner).second.first, pair<int,int>((*runner).first, (*runner).second.second) ) );
     2728          } else {
     2729            *out << Verbose(2) << "Excluding (" << *Walker << ", " << (*runner).first << ",[" << (*runner).second.first << "," << (*runner).second.second << "]), as it has reached its maximum order." << endl;
    26692730          }
    26702731        } else {
     
    27132774      }
    27142775    }
    2715     if ((Order == 0) && (AtomMask[AtomCount] == true))  // single stepping, just check
     2776    if ((Order == 0) && (AtomMask[AtomCount] == false))  // single stepping, just check
    27162777      status = true;
    27172778     
    2718     if (!status)
    2719       *out << Verbose(1) << "Order at every site is already equal or above desired order " << Order << "." << endl;
     2779    if (!status) {
     2780      if (Order == 0)
     2781        *out << Verbose(1) << "Single stepping done." << endl;
     2782      else
     2783        *out << Verbose(1) << "Order at every site is already equal or above desired order " << Order << "." << endl;
     2784    }
    27202785  }
    27212786 
     
    27322797};
    27332798
    2734 /** Create a SortIndex to map from BFS labels to the sequence in which the atoms are given in the config file.
     2799/** Create a SortIndex to map from atomic labels to the sequence in which the atoms are given in the config file.
    27352800 * \param *out output stream for debugging
    27362801 * \param *&SortIndex Mapping array of size molecule::AtomCount
     
    27812846 * \param *configuration configuration for writing config files for each fragment
    27822847 */
    2783 void molecule::FragmentMolecule(ofstream *out, int Order, config *configuration)
     2848int molecule::FragmentMolecule(ofstream *out, int Order, config *configuration)
    27842849{
    27852850        MoleculeListClass *BondFragments = NULL;
     
    27912856  fstream File;
    27922857  bool FragmentationToDo = true;
     2858  bool CheckOrder = false;
    27932859  Graph **FragmentList = NULL;
    27942860  Graph *ParsedFragmentList = NULL;
     
    28372903  KeyStack *RootStack = new KeyStack[Subgraphs->next->Count()];
    28382904  AtomMask = new bool[AtomCount+1];
    2839   while (CheckOrderAtSite(out, AtomMask, ParsedFragmentList, Order, MinimumRingSize, configuration->configpath)) {
     2905  AtomMask[AtomCount] = false;
     2906  FragmentationToDo = false;  // if CheckOrderAtSite just ones recommends fragmentation, we will save fragments afterwards
     2907  while ((CheckOrder = CheckOrderAtSite(out, AtomMask, ParsedFragmentList, Order, MinimumRingSize, configuration->configpath))) {
     2908    FragmentationToDo = FragmentationToDo || CheckOrder;
    28402909    AtomMask[AtomCount] = true;   // last plus one entry is used as marker that we have been through this loop once already in CheckOrderAtSite()
    28412910    // ===== 6b. fill RootStack for each subgraph (second adaptivity check) =====
     
    28892958
    28902959  // ===== 8b. gather keyset lists (graphs) from all subgraphs and transform into MoleculeListClass =====
    2891   // allocate memory for the pointer array and transmorph graphs into full molecular fragments
    2892   BondFragments = new MoleculeListClass(TotalGraph.size(), AtomCount);
    2893   int k=0;
    2894   for(Graph::iterator runner = TotalGraph.begin(); runner != TotalGraph.end(); runner++) {
    2895     KeySet test = (*runner).first;
    2896     *out << "Fragment No." << (*runner).second.first << " with TEFactor " << (*runner).second.second << "." << endl;
    2897     BondFragments->ListOfMolecules[k] = StoreFragmentFromKeySet(out, test, configuration);
    2898     k++;
    2899   }
    2900   *out << k << "/" << BondFragments->NumberOfMolecules << " fragments generated from the keysets." << endl;
    2901  
    2902   // ===== 9. Save fragments' configuration and keyset files et al to disk ===
    2903   if (BondFragments->NumberOfMolecules != 0) {
    2904     // create the SortIndex from BFS labels to order in the config file
    2905     CreateMappingLabelsToConfigSequence(out, SortIndex);
     2960  //if (FragmentationToDo) {    // we should always store the fragments again as coordination might have changed slightly without changing bond structure
     2961    // allocate memory for the pointer array and transmorph graphs into full molecular fragments
     2962    BondFragments = new MoleculeListClass(TotalGraph.size(), AtomCount);
     2963    int k=0;
     2964    for(Graph::iterator runner = TotalGraph.begin(); runner != TotalGraph.end(); runner++) {
     2965      KeySet test = (*runner).first;
     2966      *out << "Fragment No." << (*runner).second.first << " with TEFactor " << (*runner).second.second << "." << endl;
     2967      BondFragments->ListOfMolecules[k] = StoreFragmentFromKeySet(out, test, configuration);
     2968      k++;
     2969    }
     2970    *out << k << "/" << BondFragments->NumberOfMolecules << " fragments generated from the keysets." << endl;
    29062971   
    2907     *out << Verbose(1) << "Writing " << BondFragments->NumberOfMolecules << " possible bond fragmentation configs" << endl;
    2908     if (BondFragments->OutputConfigForListOfFragments(out, configuration, SortIndex))
    2909       *out << Verbose(1) << "All configs written." << endl;
    2910     else
    2911       *out << Verbose(1) << "Some config writing failed." << endl;
    2912 
    2913     // store force index reference file
    2914     BondFragments->StoreForcesFile(out, configuration->configpath, SortIndex);
    2915    
    2916     // store keysets file
    2917     StoreKeySetFile(out, TotalGraph, configuration->configpath);
    2918 
    2919     // store Adjacency file
    2920     StoreAdjacencyToFile(out, configuration->configpath);
    2921 
    2922     // store Hydrogen saturation correction file
    2923     BondFragments->AddHydrogenCorrection(out, configuration->configpath);
    2924    
    2925     // store adaptive orders into file
    2926     StoreOrderAtSiteFile(out, configuration->configpath);
    2927    
    2928     // restore orbital and Stop values
    2929     CalculateOrbitals(*configuration);
    2930    
    2931     // free memory for bond part
    2932     *out << Verbose(1) << "Freeing bond memory" << endl;
    2933     delete(FragmentList); // remove bond molecule from memory
    2934     Free((void **)&SortIndex, "molecule::FragmentMolecule: *SortIndex");
    2935   } else
    2936     *out << Verbose(1) << "FragmentList is zero on return, splitting failed." << endl;
    2937  
     2972    // ===== 9. Save fragments' configuration and keyset files et al to disk ===
     2973    if (BondFragments->NumberOfMolecules != 0) {
     2974      // create the SortIndex from BFS labels to order in the config file
     2975      CreateMappingLabelsToConfigSequence(out, SortIndex);
     2976     
     2977      *out << Verbose(1) << "Writing " << BondFragments->NumberOfMolecules << " possible bond fragmentation configs" << endl;
     2978      if (BondFragments->OutputConfigForListOfFragments(out, configuration, SortIndex))
     2979        *out << Verbose(1) << "All configs written." << endl;
     2980      else
     2981        *out << Verbose(1) << "Some config writing failed." << endl;
     2982 
     2983      // store force index reference file
     2984      BondFragments->StoreForcesFile(out, configuration->configpath, SortIndex);
     2985     
     2986      // store keysets file
     2987      StoreKeySetFile(out, TotalGraph, configuration->configpath);
     2988 
     2989      // store Adjacency file
     2990      StoreAdjacencyToFile(out, configuration->configpath);
     2991 
     2992      // store Hydrogen saturation correction file
     2993      BondFragments->AddHydrogenCorrection(out, configuration->configpath);
     2994     
     2995      // store adaptive orders into file
     2996      StoreOrderAtSiteFile(out, configuration->configpath);
     2997     
     2998      // restore orbital and Stop values
     2999      CalculateOrbitals(*configuration);
     3000     
     3001      // free memory for bond part
     3002      *out << Verbose(1) << "Freeing bond memory" << endl;
     3003      delete(FragmentList); // remove bond molecule from memory
     3004      Free((void **)&SortIndex, "molecule::FragmentMolecule: *SortIndex");
     3005    } else
     3006      *out << Verbose(1) << "FragmentList is zero on return, splitting failed." << endl;
     3007  //} else
     3008  //  *out << Verbose(1) << "No fragments to store." << endl;
    29383009  *out << Verbose(0) << "End of bond fragmentation." << endl;
     3010
     3011  return ((int)(!FragmentationToDo)+1);    // 1 - continue, 2 - stop (no fragmentation occured)
    29393012};
    29403013
     
    29573030    while (Walker->next != end) {
    29583031      Walker = Walker->next;
    2959       file << Walker->nr << "\t" << (int)Walker->AdaptiveOrder << endl;
    2960       *out << Verbose(2) << "Storing: " << Walker->nr << "\t" << (int)Walker->AdaptiveOrder << "." << endl;
     3032      file << Walker->nr << "\t" << (int)Walker->AdaptiveOrder << "\t" << (int)Walker->MaxOrder << endl;
     3033      *out << Verbose(2) << "Storing: " << Walker->nr << "\t" << (int)Walker->AdaptiveOrder << "\t" << (int)Walker->MaxOrder << "." << endl;
    29613034    }
    29623035    file.close();
     
    29793052{
    29803053  unsigned char *OrderArray = (unsigned char *) Malloc(sizeof(unsigned char)*AtomCount, "molecule::ParseOrderAtSiteFromFile - *OrderArray");
     3054  bool *MaxArray = (bool *) Malloc(sizeof(bool)*AtomCount, "molecule::ParseOrderAtSiteFromFile - *MaxArray");
    29813055  bool status;
    2982   int AtomNr;
     3056  int AtomNr, value;
    29833057  stringstream line;
    29843058  ifstream file;
    2985   int Order;
    29863059
    29873060  *out << Verbose(1) << "Begin of ParseOrderAtSiteFromFile" << endl;
     
    29913064  file.open(line.str().c_str());
    29923065  if (file != NULL) {
    2993     for (int i=AtomCount;i--;) // initialise with 0
     3066    for (int i=AtomCount;i--;) { // initialise with 0
    29943067      OrderArray[i] = 0;
     3068      MaxArray[i] = 0;
     3069    }
    29953070    while (!file.eof()) { // parse from file
     3071      AtomNr = -1;
    29963072      file >> AtomNr;
    2997       file >> Order;
    2998       OrderArray[AtomNr] = (unsigned char) Order;
    2999       //*out << Verbose(2) << "AtomNr " << AtomNr << " with order " << (int)OrderArray[AtomNr] << "." << endl;
     3073      if (AtomNr != -1) {   // test whether we really parsed something (this is necessary, otherwise last atom is set twice and to 0 on second time)
     3074        file >> value;
     3075        OrderArray[AtomNr] = value;
     3076        file >> value;
     3077        MaxArray[AtomNr] = value;
     3078        //*out << Verbose(2) << "AtomNr " << AtomNr << " with order " << (int)OrderArray[AtomNr] << " and max order set to " << (int)MaxArray[AtomNr] << "." << endl;
     3079      }
    30003080    }
    30013081    atom *Walker = start;
     
    30033083      Walker = Walker->next;
    30043084      Walker->AdaptiveOrder = OrderArray[Walker->nr];
    3005       *out << Verbose(2) << *Walker << " gets order " << (int)Walker->AdaptiveOrder << "." << endl;
     3085      Walker->MaxOrder = MaxArray[Walker->nr];
     3086      *out << Verbose(2) << *Walker << " gets order " << (int)Walker->AdaptiveOrder << " and is " << (!Walker->MaxOrder ? "not " : " ") << "maxed." << endl;
    30063087    }
    30073088    file.close();
     
    30133094  }
    30143095  Free((void **)&OrderArray, "molecule::ParseOrderAtSiteFromFile - *OrderArray");
     3096  Free((void **)&MaxArray, "molecule::ParseOrderAtSiteFromFile - *MaxArray");
    30153097 
    30163098  *out << Verbose(1) << "End of ParseOrderAtSiteFromFile" << endl;
     
    36023684  int FragmentCounter;
    36033685  int CurrentIndex;
    3604   int *Labels;
    36053686  double TEFactor;
    36063687  int *ShortestPathList;
     
    36703751                OtherWalker = BondsSet[j]->rightatom;   // rightatom is always the one more distant, i.e. the one to add
    36713752          //*out << Verbose(1+verbosity) << "Current Bond is " << ListOfBondsPerAtom[Walker->nr][i] << ", checking on " << *OtherWalker << "." << endl;
    3672           //if ((!FragmentSearch->UsedList[OtherWalker->nr][i]) && (FragmentSearch->Labels[OtherWalker->nr] > FragmentSearch->Labels[FragmentSearch->Root->nr])) {
    3673             //*out << Verbose(2+verbosity) << "Not used so far, label " << FragmentSearch->Labels[OtherWalker->nr] << " is bigger than Root's " << FragmentSearch->Labels[FragmentSearch->Root->nr] << "." << endl;
    36743753          *out << Verbose(2+verbosity) << "Adding " << *OtherWalker << " with nr " << OtherWalker->nr << "." << endl;
    36753754          TestKeySetInsert = FragmentSearch->FragmentSet->insert(OtherWalker->nr);
     
    37303809        InsertFragmentIntoGraph(out, FragmentSearch);
    37313810        //Removal = LookForRemovalCandidate(out, FragmentSearch->FragmentSet, FragmentSearch->ShortestPathList);
    3732         //Removal = StoreFragmentFromStack(out, FragmentSearch->Root, FragmentSearch->Leaflet, FragmentSearch->FragmentStack, FragmentSearch->ShortestPathList,FragmentSearch->Labels, &FragmentSearch->FragmentCounter, FragmentSearch->configuration);
     3811        //Removal = StoreFragmentFromStack(out, FragmentSearch->Root, FragmentSearch->Leaflet, FragmentSearch->FragmentStack, FragmentSearch->ShortestPathList, &FragmentSearch->FragmentCounter, FragmentSearch->configuration);
    37333812      }
    37343813     
     
    38213900int molecule::PowerSetGenerator(ofstream *out, int Order, struct UniqueFragments &FragmentSearch, KeySet RestrictedKeySet)
    38223901{
    3823   int SP, UniqueIndex, AtomKeyNr;
     3902  int SP, AtomKeyNr;
    38243903  atom *Walker = NULL, *OtherWalker = NULL, *Predecessor = NULL;
    38253904  bond *Binder = NULL;
    38263905  bond *CurrentEdge = NULL;
    38273906  bond **BondsList = NULL;
    3828   int RootKeyNr = FragmentSearch.Root->nr;
     3907  int RootKeyNr = FragmentSearch.Root->GetTrueFather()->nr;
    38293908  int Counter = FragmentSearch.FragmentCounter;
    38303909  int RemainingWalkers;
     
    38343913
    38353914  // prepare Label and SP arrays of the BFS search
    3836   UniqueIndex = 0;
    3837   if (FragmentSearch.Labels[RootKeyNr] == -1)
    3838     FragmentSearch.Labels[RootKeyNr] = UniqueIndex++;
    3839   FragmentSearch.ShortestPathList[RootKeyNr] = 0;
     3915  FragmentSearch.ShortestPathList[FragmentSearch.Root->nr] = 0;
    38403916
    38413917  // prepare root level (SP = 0) and a loop bond denoting Root
     
    38713947      Predecessor = CurrentEdge->leftatom;    // ... and leftatom is predecessor
    38723948      AtomKeyNr = Walker->nr;
    3873       *out << Verbose(0) << "Current Walker is: " << *Walker << " with nr " << Walker->nr << " and label " << FragmentSearch.Labels[AtomKeyNr] << " and SP of " << SP << ", with " << RemainingWalkers << " remaining walkers on this level." << endl;
     3949      *out << Verbose(0) << "Current Walker is: " << *Walker << " with nr " << Walker->nr << " and SP of " << SP << ", with " << RemainingWalkers << " remaining walkers on this level." << endl;
    38743950      // check for new sp level
    38753951      // go through all its bonds
     
    38853961          *out << Verbose(2) << "Current partner is " << *OtherWalker << " with nr " << OtherWalker->nr << " in bond " << *Binder << "." << endl;
    38863962          // set the label if not set (and push on root stack as well)
    3887           if (FragmentSearch.Labels[OtherWalker->nr] == -1) {
    3888             FragmentSearch.Labels[OtherWalker->nr] = UniqueIndex++;
    3889             *out << Verbose(3) << "Set label to " << FragmentSearch.Labels[OtherWalker->nr] << "." << endl;
    3890           } else {
    3891             *out << Verbose(3) << "Label is already " << FragmentSearch.Labels[OtherWalker->nr] << "." << endl;
    3892           }
    3893           if ((OtherWalker != Predecessor) && (OtherWalker->nr > RootKeyNr)) { // only pass through those with label bigger than Root's
     3963          if ((OtherWalker != Predecessor) && (OtherWalker->GetTrueFather()->nr > RootKeyNr)) { // only pass through those with label bigger than Root's
    38943964            FragmentSearch.ShortestPathList[OtherWalker->nr] = SP+1;
    38953965            *out << Verbose(3) << "Set Shortest Path to " << FragmentSearch.ShortestPathList[OtherWalker->nr] << "." << endl;
     
    38993969            FragmentSearch.BondsPerSPCount[SP+1]++;
    39003970            *out << Verbose(3) << "Added its bond to SP list, having now " << FragmentSearch.BondsPerSPCount[SP+1] << " item(s)." << endl;
    3901           } else *out << Verbose(3) << "Not passing on, as index of " << *OtherWalker << " " << OtherWalker->nr << " is smaller than that of Root " << RootKeyNr << " or this is my predecessor " << *Predecessor << "." << endl;
     3971          } else {
     3972            if (OtherWalker != Predecessor)
     3973              *out << Verbose(3) << "Not passing on, as index of " << *OtherWalker << " " << OtherWalker->GetTrueFather()->nr << " is smaller than that of Root " << RootKeyNr << "." << endl;
     3974            else
     3975              *out << Verbose(3) << "This is my predecessor " << *Predecessor << "." << endl;
     3976          }
    39023977        } else *out << Verbose(2) << "Is not in the restricted keyset or skipping hydrogen " << *OtherWalker << "." << endl;
    39033978      }
     
    40034078      for (int i=NDIM;i--;) {
    40044079        tmp = fabs(Binder->leftatom->x.x[i] - Binder->rightatom->x.x[i]);
    4005         //*out << Verbose(3) << "Checking " << i << "th distance of " << *Binder->leftatom << " to " << *Binder->rightatom << ": " << tmp << "." << endl;
     4080        *out << Verbose(3) << "Checking " << i << "th distance of " << *Binder->leftatom << " to " << *Binder->rightatom << ": " << tmp << "." << endl;
    40064081        if (tmp > BondDistance) {
    40074082          OtherBinder = Binder->next; // note down binding partner for later re-insertion
    40084083          unlink(Binder);   // unlink bond
    4009           //*out << Verbose(2) << "Correcting at bond " << *Binder << "." << endl;
     4084          *out << Verbose(2) << "Correcting at bond " << *Binder << "." << endl;
    40104085          flag = true;
    40114086          break;
     
    41954270  // initialise the fragments structure
    41964271  FragmentSearch.ShortestPathList = (int *) Malloc(sizeof(int)*AtomCount, "molecule::PowerSetGenerator: *ShortestPathList");
    4197   FragmentSearch.Labels = (int *) Malloc(sizeof(int)*AtomCount, "molecule::PowerSetGenerator: *Labels");
    41984272  FragmentSearch.FragmentCounter = 0;
    41994273  FragmentSearch.FragmentSet = new KeySet;
    42004274  FragmentSearch.Root = FindAtom(RootKeyNr);
    42014275  for (int i=AtomCount;i--;) {
    4202     FragmentSearch.Labels[i] = -1;
    42034276    FragmentSearch.ShortestPathList[i] = -1;
    42044277  }
     
    42494322      // create top order where nothing is reduced
    42504323      *out << Verbose(0) << "==============================================================================================================" << endl;
    4251       *out << Verbose(0) << "Creating KeySets of Bond Order " << Order << " for " << *Walker << ", NumLevels is " << NumLevels << ", " << (RootStack.size()-RootNr) << " Roots remaining." << endl;
     4324      *out << Verbose(0) << "Creating KeySets of Bond Order " << Order << " for " << *Walker << ", " << (RootStack.size()-RootNr) << " Roots remaining." << endl; // , NumLevels is " << NumLevels << "
    42524325 
    42534326      // Create list of Graphs of current Bond Order (i.e. F_{ij})
     
    42604333      if (NumMoleculesOfOrder[RootNr] != 0) {
    42614334        NumMolecules = 0;
     4335
     4336        // we don't have to dive into suborders! These keysets are all already created on lower orders!
     4337        // this was all ancient stuff, when we still depended on the TEFactors (and for those the suborders were needed)
    42624338       
    4263         if ((NumLevels >> 1) > 0) {
    4264           // create lower order fragments
    4265           *out << Verbose(0) << "Creating list of unique fragments of lower Bond Order terms to be subtracted." << endl;
    4266           Order = Walker->AdaptiveOrder;
    4267           for (int source=0;source<(NumLevels >> 1);source++) { // 1-terms don't need any more splitting, that's why only half is gone through (shift again)
    4268             // step down to next order at (virtual) boundary of powers of 2 in array
    4269             while (source >= (1 << (Walker->AdaptiveOrder-Order))) // (int)pow(2,Walker->AdaptiveOrder-Order))   
    4270               Order--;
    4271             *out << Verbose(0) << "Current Order is: " << Order << "." << endl;
    4272             for (int SubOrder=Order-1;SubOrder>0;SubOrder--) {
    4273               int dest = source + (1 << (Walker->AdaptiveOrder-(SubOrder+1)));
    4274               *out << Verbose(0) << "--------------------------------------------------------------------------------------------------------------" << endl;
    4275               *out << Verbose(0) << "Current SubOrder is: " << SubOrder << " with source " << source << " to destination " << dest << "." << endl;
    4276        
    4277               // every molecule is split into a list of again (Order - 1) molecules, while counting all molecules
    4278               //*out << Verbose(1) << "Splitting the " << (*FragmentLowerOrdersList[RootNr][source]).size() << " molecules of the " << source << "th cell in the array." << endl;
    4279               //NumMolecules = 0;
    4280               FragmentLowerOrdersList[RootNr][dest] = new Graph;
    4281               for(Graph::iterator runner = (*FragmentLowerOrdersList[RootNr][source]).begin();runner != (*FragmentLowerOrdersList[RootNr][source]).end(); runner++) {
    4282                 for (KeySet::iterator sprinter = (*runner).first.begin();sprinter != (*runner).first.end(); sprinter++) {
    4283                   Graph TempFragmentList;
    4284                   FragmentSearch.TEFactor = -(*runner).second.second;
    4285                   FragmentSearch.Leaflet = &TempFragmentList;      // set to insertion graph
    4286                   FragmentSearch.Root = FindAtom(*sprinter);
    4287                   NumMoleculesOfOrder[RootNr] += PowerSetGenerator(out, SubOrder, FragmentSearch, (*runner).first);
    4288                   // insert new keysets FragmentList into FragmentLowerOrdersList[Walker->AdaptiveOrder-1][dest]
    4289                   *out << Verbose(1) << "Merging resulting key sets with those present in destination " << dest << "." << endl;
    4290                   InsertGraphIntoGraph(out, *FragmentLowerOrdersList[RootNr][dest], TempFragmentList, &NumMolecules);
    4291                 }
    4292               }
    4293               *out << Verbose(1) << "Number of resulting molecules for SubOrder " << SubOrder << " is: " << NumMolecules << "." << endl;
    4294             }
    4295           }
    4296         }
     4339//        if ((NumLevels >> 1) > 0) {
     4340//          // create lower order fragments
     4341//          *out << Verbose(0) << "Creating list of unique fragments of lower Bond Order terms to be subtracted." << endl;
     4342//          Order = Walker->AdaptiveOrder;
     4343//          for (int source=0;source<(NumLevels >> 1);source++) { // 1-terms don't need any more splitting, that's why only half is gone through (shift again)
     4344//            // step down to next order at (virtual) boundary of powers of 2 in array
     4345//            while (source >= (1 << (Walker->AdaptiveOrder-Order))) // (int)pow(2,Walker->AdaptiveOrder-Order))   
     4346//              Order--;
     4347//            *out << Verbose(0) << "Current Order is: " << Order << "." << endl;
     4348//            for (int SubOrder=Order-1;SubOrder>0;SubOrder--) {
     4349//              int dest = source + (1 << (Walker->AdaptiveOrder-(SubOrder+1)));
     4350//              *out << Verbose(0) << "--------------------------------------------------------------------------------------------------------------" << endl;
     4351//              *out << Verbose(0) << "Current SubOrder is: " << SubOrder << " with source " << source << " to destination " << dest << "." << endl;
     4352//       
     4353//              // every molecule is split into a list of again (Order - 1) molecules, while counting all molecules
     4354//              //*out << Verbose(1) << "Splitting the " << (*FragmentLowerOrdersList[RootNr][source]).size() << " molecules of the " << source << "th cell in the array." << endl;
     4355//              //NumMolecules = 0;
     4356//              FragmentLowerOrdersList[RootNr][dest] = new Graph;
     4357//              for(Graph::iterator runner = (*FragmentLowerOrdersList[RootNr][source]).begin();runner != (*FragmentLowerOrdersList[RootNr][source]).end(); runner++) {
     4358//                for (KeySet::iterator sprinter = (*runner).first.begin();sprinter != (*runner).first.end(); sprinter++) {
     4359//                  Graph TempFragmentList;
     4360//                  FragmentSearch.TEFactor = -(*runner).second.second;
     4361//                  FragmentSearch.Leaflet = &TempFragmentList;      // set to insertion graph
     4362//                  FragmentSearch.Root = FindAtom(*sprinter);
     4363//                  NumMoleculesOfOrder[RootNr] += PowerSetGenerator(out, SubOrder, FragmentSearch, (*runner).first);
     4364//                  // insert new keysets FragmentList into FragmentLowerOrdersList[Walker->AdaptiveOrder-1][dest]
     4365//                  *out << Verbose(1) << "Merging resulting key sets with those present in destination " << dest << "." << endl;
     4366//                  InsertGraphIntoGraph(out, *FragmentLowerOrdersList[RootNr][dest], TempFragmentList, &NumMolecules);
     4367//                }
     4368//              }
     4369//              *out << Verbose(1) << "Number of resulting molecules for SubOrder " << SubOrder << " is: " << NumMolecules << "." << endl;
     4370//            }
     4371//          }
     4372//        }
    42974373      } else {
    4298         *out << Verbose(1) << "Hence, we don't dive into SubOrders ... " << endl;
     4374        Walker->GetTrueFather()->MaxOrder = true;
     4375//        *out << Verbose(1) << "Hence, we don't dive into SubOrders ... " << endl;
    42994376      }
    43004377      // now, we have completely filled each cell of FragmentLowerOrdersList[] for the current Walker->AdaptiveOrder
    43014378      //NumMoleculesOfOrder[Walker->AdaptiveOrder-1] = NumMolecules;
    43024379      TotalNumMolecules += NumMoleculesOfOrder[RootNr];
    4303       *out << Verbose(1) << "Number of resulting molecules for Order " << (int)Walker->GetTrueFather()->AdaptiveOrder << " is: " << NumMoleculesOfOrder[RootNr] << "." << endl;
     4380//      *out << Verbose(1) << "Number of resulting molecules for Order " << (int)Walker->GetTrueFather()->AdaptiveOrder << " is: " << NumMoleculesOfOrder[RootNr] << "." << endl;
    43044381      RootStack.push_back(RootKeyNr); // put back on stack
    43054382      RootNr++;
     
    43204397  // cleanup FragmentSearch structure
    43214398  Free((void **)&FragmentSearch.ShortestPathList, "molecule::PowerSetGenerator: *ShortestPathList");
    4322   Free((void **)&FragmentSearch.Labels, "molecule::PowerSetGenerator: *Labels");
    43234399  delete(FragmentSearch.FragmentSet);
    43244400 
Note: See TracChangeset for help on using the changeset viewer.