Changeset 644ba1 for molecuilder/src/molecules.cpp
- Timestamp:
- Aug 18, 2008, 8:57:58 AM (17 years ago)
- Children:
- 04c868
- Parents:
- e6971b
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
molecuilder/src/molecules.cpp
re6971b r644ba1 455 455 getline(xyzfile,line,'\n'); // Read comment 456 456 cout << Verbose(1) << "Comment: " << line << endl; 457 457 458 if (MDSteps == 0) // no atoms yet present 459 MDSteps++; 458 460 for(i=0;i<NumberOfAtoms;i++){ 459 461 Walker = new atom; … … 471 473 Walker->type = elemente->FindElement(1); 472 474 } 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--;) { 474 481 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 476 487 delete(item); 477 488 } … … 965 976 966 977 /** 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). 967 980 * This adds a new MD step to the config file. 968 981 * \param *file filename 969 982 * \param delta_t time step width in atomic units 983 * \param IsAngstroem whether coordinates are in angstroem (true) or bohrradius (false) 970 984 * \return true - file found and parsed, false - file not found or imparsable 971 985 */ 972 bool molecule::VerletForceIntegration(char *file, double delta_t) 973 { 974 bool status = true; 986 bool molecule::VerletForceIntegration(char *file, double delta_t, bool IsAngstroem) 987 { 975 988 element *runner = elemente->start; 976 989 atom *walker = NULL; 977 int ElementNo,AtomNo;990 int AtomNo; 978 991 ifstream input(file); 979 double Forcesvector[3];980 double dummy;981 992 string token; 982 size_t oldpos, newpos;983 993 stringstream item; 984 int i, Ion[2]; 985 double a, IonMass; 986 unsigned int size; 994 double a, IonMass, Vector[NDIM]; 995 ForceMatrix Force; 987 996 988 997 CountElements(); // make sure ElementsInMolecule is up to date … … 992 1001 return false; 993 1002 } 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; 995 1025 while (runner->next != elemente->end) { // go through every element 996 1026 runner = runner->next; 997 1027 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 998 1029 if (ElementsInMolecule[runner->Z]) { // if this element got atoms 999 ElementNo++;1000 1030 AtomNo = 0; 1001 1031 walker = start; … … 1003 1033 walker = walker->next; 1004 1034 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); 1030 1041 } 1031 1042 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 1055 1049 } 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++; 1058 1064 } 1059 1065 } 1060 1066 } 1061 1067 } 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 1064 1090 1065 1091 // exit 1066 return status;1092 return true; 1067 1093 }; 1068 1094 … … 1372 1398 if (Trajectories[walker].F.at(step).Norm() > MYEPSILON) 1373 1399 *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 << " 1400 *out << "\t# Number in molecule " << walker->nr << endl; 1375 1401 } 1376 1402 } … … 1413 1439 }; 1414 1440 1441 /** Prints molecule with all its trajectories to *out as xyz file. 1442 * \param *out output stream 1443 */ 1444 bool 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 1415 1470 /** Prints molecule to *out as xyz file. 1416 1471 * \param *out output stream 1417 1472 */ 1418 1473 bool molecule::OutputXYZ(ofstream *out) const … … 2615 2670 lines++; 2616 2671 } 2617 *out << Verbose(2) << "Scanned " << lines-1 << " lines." << endl; // one endline too much2672 //*out << Verbose(2) << "Scanned " << lines-1 << " lines." << endl; // one endline too much 2618 2673 InputFile.clear(); 2619 2674 InputFile.seekg(ios::beg); … … 2627 2682 InputFile.getline(buffer, MAXSTRINGSIZE); 2628 2683 if (strlen(buffer) > 2) { 2629 //*out << Verbose(2) << "Scanning: " << buffer ;2684 //*out << Verbose(2) << "Scanning: " << buffer << endl; 2630 2685 stringstream line(buffer); 2631 2686 line >> FragOrder; … … 2634 2689 line >> ws >> Value; 2635 2690 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; 2637 2692 2638 2693 // clean the list of those entries that have been superceded by higher order terms already 2639 2694 map<int,KeySet>::iterator marker = IndexKeySetList.find(No); // find keyset to Frag No. 2640 2695 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 2641 2697 // 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) )); 2643 2699 map<int, pair<double,int> >::iterator PresentItem = InsertedElement.first; 2644 2700 if (!InsertedElement.second) { // this root is already present … … 2646 2702 //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) 2647 2703 { // if value is smaller, update value and order 2648 (*PresentItem).second.first = Value;2704 (*PresentItem).second.first = fabs(Value); 2649 2705 (*PresentItem).second.second = FragOrder; 2650 2706 *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; 2651 2709 } 2652 2710 } else { … … 2664 2722 Walker = FindAtom((*runner).first); 2665 2723 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) { 2667 2726 *out << Verbose(2) << "(" << (*runner).first << ",[" << (*runner).second.first << "," << (*runner).second.second << "])" << endl; 2668 2727 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; 2669 2730 } 2670 2731 } else { … … 2713 2774 } 2714 2775 } 2715 if ((Order == 0) && (AtomMask[AtomCount] == true)) // single stepping, just check2776 if ((Order == 0) && (AtomMask[AtomCount] == false)) // single stepping, just check 2716 2777 status = true; 2717 2778 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 } 2720 2785 } 2721 2786 … … 2732 2797 }; 2733 2798 2734 /** Create a SortIndex to map from BFSlabels 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. 2735 2800 * \param *out output stream for debugging 2736 2801 * \param *&SortIndex Mapping array of size molecule::AtomCount … … 2781 2846 * \param *configuration configuration for writing config files for each fragment 2782 2847 */ 2783 voidmolecule::FragmentMolecule(ofstream *out, int Order, config *configuration)2848 int molecule::FragmentMolecule(ofstream *out, int Order, config *configuration) 2784 2849 { 2785 2850 MoleculeListClass *BondFragments = NULL; … … 2791 2856 fstream File; 2792 2857 bool FragmentationToDo = true; 2858 bool CheckOrder = false; 2793 2859 Graph **FragmentList = NULL; 2794 2860 Graph *ParsedFragmentList = NULL; … … 2837 2903 KeyStack *RootStack = new KeyStack[Subgraphs->next->Count()]; 2838 2904 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; 2840 2909 AtomMask[AtomCount] = true; // last plus one entry is used as marker that we have been through this loop once already in CheckOrderAtSite() 2841 2910 // ===== 6b. fill RootStack for each subgraph (second adaptivity check) ===== … … 2889 2958 2890 2959 // ===== 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; 2906 2971 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; 2938 3009 *out << Verbose(0) << "End of bond fragmentation." << endl; 3010 3011 return ((int)(!FragmentationToDo)+1); // 1 - continue, 2 - stop (no fragmentation occured) 2939 3012 }; 2940 3013 … … 2957 3030 while (Walker->next != end) { 2958 3031 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; 2961 3034 } 2962 3035 file.close(); … … 2979 3052 { 2980 3053 unsigned char *OrderArray = (unsigned char *) Malloc(sizeof(unsigned char)*AtomCount, "molecule::ParseOrderAtSiteFromFile - *OrderArray"); 3054 bool *MaxArray = (bool *) Malloc(sizeof(bool)*AtomCount, "molecule::ParseOrderAtSiteFromFile - *MaxArray"); 2981 3055 bool status; 2982 int AtomNr ;3056 int AtomNr, value; 2983 3057 stringstream line; 2984 3058 ifstream file; 2985 int Order;2986 3059 2987 3060 *out << Verbose(1) << "Begin of ParseOrderAtSiteFromFile" << endl; … … 2991 3064 file.open(line.str().c_str()); 2992 3065 if (file != NULL) { 2993 for (int i=AtomCount;i--;) // initialise with 03066 for (int i=AtomCount;i--;) { // initialise with 0 2994 3067 OrderArray[i] = 0; 3068 MaxArray[i] = 0; 3069 } 2995 3070 while (!file.eof()) { // parse from file 3071 AtomNr = -1; 2996 3072 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 } 3000 3080 } 3001 3081 atom *Walker = start; … … 3003 3083 Walker = Walker->next; 3004 3084 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; 3006 3087 } 3007 3088 file.close(); … … 3013 3094 } 3014 3095 Free((void **)&OrderArray, "molecule::ParseOrderAtSiteFromFile - *OrderArray"); 3096 Free((void **)&MaxArray, "molecule::ParseOrderAtSiteFromFile - *MaxArray"); 3015 3097 3016 3098 *out << Verbose(1) << "End of ParseOrderAtSiteFromFile" << endl; … … 3602 3684 int FragmentCounter; 3603 3685 int CurrentIndex; 3604 int *Labels;3605 3686 double TEFactor; 3606 3687 int *ShortestPathList; … … 3670 3751 OtherWalker = BondsSet[j]->rightatom; // rightatom is always the one more distant, i.e. the one to add 3671 3752 //*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;3674 3753 *out << Verbose(2+verbosity) << "Adding " << *OtherWalker << " with nr " << OtherWalker->nr << "." << endl; 3675 3754 TestKeySetInsert = FragmentSearch->FragmentSet->insert(OtherWalker->nr); … … 3730 3809 InsertFragmentIntoGraph(out, FragmentSearch); 3731 3810 //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); 3733 3812 } 3734 3813 … … 3821 3900 int molecule::PowerSetGenerator(ofstream *out, int Order, struct UniqueFragments &FragmentSearch, KeySet RestrictedKeySet) 3822 3901 { 3823 int SP, UniqueIndex,AtomKeyNr;3902 int SP, AtomKeyNr; 3824 3903 atom *Walker = NULL, *OtherWalker = NULL, *Predecessor = NULL; 3825 3904 bond *Binder = NULL; 3826 3905 bond *CurrentEdge = NULL; 3827 3906 bond **BondsList = NULL; 3828 int RootKeyNr = FragmentSearch.Root-> nr;3907 int RootKeyNr = FragmentSearch.Root->GetTrueFather()->nr; 3829 3908 int Counter = FragmentSearch.FragmentCounter; 3830 3909 int RemainingWalkers; … … 3834 3913 3835 3914 // 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; 3840 3916 3841 3917 // prepare root level (SP = 0) and a loop bond denoting Root … … 3871 3947 Predecessor = CurrentEdge->leftatom; // ... and leftatom is predecessor 3872 3948 AtomKeyNr = Walker->nr; 3873 *out << Verbose(0) << "Current Walker is: " << *Walker << " with nr " << Walker->nr << " and label " << FragmentSearch.Labels[AtomKeyNr] << " andSP 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; 3874 3950 // check for new sp level 3875 3951 // go through all its bonds … … 3885 3961 *out << Verbose(2) << "Current partner is " << *OtherWalker << " with nr " << OtherWalker->nr << " in bond " << *Binder << "." << endl; 3886 3962 // 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 3894 3964 FragmentSearch.ShortestPathList[OtherWalker->nr] = SP+1; 3895 3965 *out << Verbose(3) << "Set Shortest Path to " << FragmentSearch.ShortestPathList[OtherWalker->nr] << "." << endl; … … 3899 3969 FragmentSearch.BondsPerSPCount[SP+1]++; 3900 3970 *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 } 3902 3977 } else *out << Verbose(2) << "Is not in the restricted keyset or skipping hydrogen " << *OtherWalker << "." << endl; 3903 3978 } … … 4003 4078 for (int i=NDIM;i--;) { 4004 4079 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; 4006 4081 if (tmp > BondDistance) { 4007 4082 OtherBinder = Binder->next; // note down binding partner for later re-insertion 4008 4083 unlink(Binder); // unlink bond 4009 //*out << Verbose(2) << "Correcting at bond " << *Binder << "." << endl;4084 *out << Verbose(2) << "Correcting at bond " << *Binder << "." << endl; 4010 4085 flag = true; 4011 4086 break; … … 4195 4270 // initialise the fragments structure 4196 4271 FragmentSearch.ShortestPathList = (int *) Malloc(sizeof(int)*AtomCount, "molecule::PowerSetGenerator: *ShortestPathList"); 4197 FragmentSearch.Labels = (int *) Malloc(sizeof(int)*AtomCount, "molecule::PowerSetGenerator: *Labels");4198 4272 FragmentSearch.FragmentCounter = 0; 4199 4273 FragmentSearch.FragmentSet = new KeySet; 4200 4274 FragmentSearch.Root = FindAtom(RootKeyNr); 4201 4275 for (int i=AtomCount;i--;) { 4202 FragmentSearch.Labels[i] = -1;4203 4276 FragmentSearch.ShortestPathList[i] = -1; 4204 4277 } … … 4249 4322 // create top order where nothing is reduced 4250 4323 *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 << " 4252 4325 4253 4326 // Create list of Graphs of current Bond Order (i.e. F_{ij}) … … 4260 4333 if (NumMoleculesOfOrder[RootNr] != 0) { 4261 4334 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) 4262 4338 4263 if ((NumLevels >> 1) > 0) {4264 // create lower order fragments4265 *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 array4269 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 molecules4278 //*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 graph4286 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 // } 4297 4373 } 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; 4299 4376 } 4300 4377 // now, we have completely filled each cell of FragmentLowerOrdersList[] for the current Walker->AdaptiveOrder 4301 4378 //NumMoleculesOfOrder[Walker->AdaptiveOrder-1] = NumMolecules; 4302 4379 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; 4304 4381 RootStack.push_back(RootKeyNr); // put back on stack 4305 4382 RootNr++; … … 4320 4397 // cleanup FragmentSearch structure 4321 4398 Free((void **)&FragmentSearch.ShortestPathList, "molecule::PowerSetGenerator: *ShortestPathList"); 4322 Free((void **)&FragmentSearch.Labels, "molecule::PowerSetGenerator: *Labels");4323 4399 delete(FragmentSearch.FragmentSet); 4324 4400
Note:
See TracChangeset
for help on using the changeset viewer.