source: src/Fragmentation/fragmentation_helpers.cpp@ f67817f

Action_Thermostats Add_AtomRandomPerturbation Add_FitFragmentPartialChargesAction Add_RotateAroundBondAction Add_SelectAtomByNameAction Added_ParseSaveFragmentResults AddingActions_SaveParseParticleParameters Adding_Graph_to_ChangeBondActions Adding_MD_integration_tests Adding_ParticleName_to_Atom Adding_StructOpt_integration_tests AtomFragments Automaking_mpqc_open AutomationFragmentation_failures Candidate_v1.5.4 Candidate_v1.6.0 Candidate_v1.6.1 ChangeBugEmailaddress ChangingTestPorts ChemicalSpaceEvaluator CombiningParticlePotentialParsing Combining_Subpackages Debian_Package_split Debian_package_split_molecuildergui_only Disabling_MemDebug Docu_Python_wait EmpiricalPotential_contain_HomologyGraph EmpiricalPotential_contain_HomologyGraph_documentation Enable_parallel_make_install Enhance_userguide Enhanced_StructuralOptimization Enhanced_StructuralOptimization_continued Example_ManyWaysToTranslateAtom Exclude_Hydrogens_annealWithBondGraph FitPartialCharges_GlobalError Fix_BoundInBox_CenterInBox_MoleculeActions Fix_ChargeSampling_PBC Fix_ChronosMutex Fix_FitPartialCharges Fix_FitPotential_needs_atomicnumbers Fix_ForceAnnealing Fix_IndependentFragmentGrids Fix_ParseParticles Fix_ParseParticles_split_forward_backward_Actions Fix_PopActions Fix_QtFragmentList_sorted_selection Fix_Restrictedkeyset_FragmentMolecule Fix_StatusMsg Fix_StepWorldTime_single_argument Fix_Verbose_Codepatterns Fix_fitting_potentials Fixes ForceAnnealing_goodresults ForceAnnealing_oldresults ForceAnnealing_tocheck ForceAnnealing_with_BondGraph ForceAnnealing_with_BondGraph_continued ForceAnnealing_with_BondGraph_continued_betteresults ForceAnnealing_with_BondGraph_contraction-expansion FragmentAction_writes_AtomFragments FragmentMolecule_checks_bonddegrees GeometryObjects Gui_Fixes Gui_displays_atomic_force_velocity ImplicitCharges IndependentFragmentGrids IndependentFragmentGrids_IndividualZeroInstances IndependentFragmentGrids_IntegrationTest IndependentFragmentGrids_Sole_NN_Calculation JobMarket_RobustOnKillsSegFaults JobMarket_StableWorkerPool JobMarket_unresolvable_hostname_fix MoreRobust_FragmentAutomation ODR_violation_mpqc_open PartialCharges_OrthogonalSummation PdbParser_setsAtomName PythonUI_with_named_parameters QtGui_reactivate_TimeChanged_changes Recreated_GuiChecks Rewrite_FitPartialCharges RotateToPrincipalAxisSystem_UndoRedo SaturateAtoms_findBestMatching SaturateAtoms_singleDegree StoppableMakroAction Subpackage_CodePatterns Subpackage_JobMarket Subpackage_LinearAlgebra Subpackage_levmar Subpackage_mpqc_open Subpackage_vmg Switchable_LogView ThirdParty_MPQC_rebuilt_buildsystem TrajectoryDependenant_MaxOrder TremoloParser_IncreasedPrecision TremoloParser_MultipleTimesteps TremoloParser_setsAtomName Ubuntu_1604_changes stable
Last change on this file since f67817f was f67817f, checked in by Frederik Heber <heber@…>, 13 years ago

Extracted power set generation into own class PowerSetGenerator.

  • Property mode set to 100644
File size: 20.0 KB
Line 
1/*
2 * Project: MoleCuilder
3 * Description: creates and alters molecular systems
4 * Copyright (C) 2010 University of Bonn. All rights reserved.
5 * Please see the LICENSE file or "Copyright notice" in builder.cpp for details.
6 */
7
8/*
9 * fragmentation_helpers.cpp
10 *
11 * Created on: Oct 18, 2011
12 * Author: heber
13 */
14
15// include config.h
16#ifdef HAVE_CONFIG_H
17#include <config.h>
18#endif
19
20#include "CodePatterns/MemDebug.hpp"
21
22#include "fragmentation_helpers.hpp"
23
24#include <sstream>
25
26#include "CodePatterns/Log.hpp"
27
28#include "atom.hpp"
29#include "Bond/bond.hpp"
30#include "Element/element.hpp"
31#include "Helpers/defs.hpp"
32#include "Helpers/helpers.hpp"
33#include "molecule.hpp"
34
35using namespace std;
36
37/** Scans a single line for number and puts them into \a KeySet.
38 * \param *out output stream for debugging
39 * \param *buffer buffer to scan
40 * \param &CurrentSet filled KeySet on return
41 * \return true - at least one valid atom id parsed, false - CurrentSet is empty
42 */
43bool ScanBufferIntoKeySet(char *buffer, KeySet &CurrentSet)
44{
45 stringstream line;
46 int AtomNr;
47 int status = 0;
48
49 line.str(buffer);
50 while (!line.eof()) {
51 line >> AtomNr;
52 if (AtomNr >= 0) {
53 CurrentSet.insert(AtomNr); // insert at end, hence in same order as in file!
54 status++;
55 } // else it's "-1" or else and thus must not be added
56 }
57 DoLog(1) && (Log() << Verbose(1) << "The scanned KeySet is ");
58 for(KeySet::iterator runner = CurrentSet.begin(); runner != CurrentSet.end(); runner++) {
59 DoLog(0) && (Log() << Verbose(0) << (*runner) << "\t");
60 }
61 DoLog(0) && (Log() << Verbose(0) << endl);
62 return (status != 0);
63};
64
65/** Parses the KeySet file and fills \a *FragmentList from the known molecule structure.
66 * Does two-pass scanning:
67 * -# Scans the keyset file and initialises a temporary graph
68 * -# Scans TEFactors file and sets the TEFactor of each key set in the temporary graph accordingly
69 * Finally, the temporary graph is inserted into the given \a FragmentList for return.
70 * \param &path path to file
71 * \param *FragmentList empty, filled on return
72 * \return true - parsing successfully, false - failure on parsing (FragmentList will be NULL)
73 */
74bool ParseKeySetFile(std::string &path, Graph *&FragmentList)
75{
76 bool status = true;
77 ifstream InputFile;
78 stringstream line;
79 GraphTestPair testGraphInsert;
80 int NumberOfFragments = 0;
81 string filename;
82
83 if (FragmentList == NULL) { // check list pointer
84 FragmentList = new Graph;
85 }
86
87 // 1st pass: open file and read
88 DoLog(1) && (Log() << Verbose(1) << "Parsing the KeySet file ... " << endl);
89 filename = path + KEYSETFILE;
90 InputFile.open(filename.c_str());
91 if (InputFile.good()) {
92 // each line represents a new fragment
93 char buffer[MAXSTRINGSIZE];
94 // 1. parse keysets and insert into temp. graph
95 while (!InputFile.eof()) {
96 InputFile.getline(buffer, MAXSTRINGSIZE);
97 KeySet CurrentSet;
98 if ((strlen(buffer) > 0) && (ScanBufferIntoKeySet(buffer, CurrentSet))) { // if at least one valid atom was added, write config
99 testGraphInsert = FragmentList->insert(GraphPair (CurrentSet,pair<int,double>(NumberOfFragments++,1))); // store fragment number and current factor
100 if (!testGraphInsert.second) {
101 DoeLog(0) && (eLog()<< Verbose(0) << "KeySet file must be corrupt as there are two equal key sets therein!" << endl);
102 performCriticalExit();
103 }
104 }
105 }
106 // 2. Free and done
107 InputFile.close();
108 InputFile.clear();
109 DoLog(1) && (Log() << Verbose(1) << "\t ... done." << endl);
110 } else {
111 DoLog(1) && (Log() << Verbose(1) << "\t ... File " << filename << " not found." << endl);
112 status = false;
113 }
114
115 return status;
116};
117
118/** Parses the TE factors file and fills \a *FragmentList from the known molecule structure.
119 * -# Scans TEFactors file and sets the TEFactor of each key set in the temporary graph accordingly
120 * \param *out output stream for debugging
121 * \param *path path to file
122 * \param *FragmentList graph whose nodes's TE factors are set on return
123 * \return true - parsing successfully, false - failure on parsing
124 */
125bool ParseTEFactorsFile(char *path, Graph *FragmentList)
126{
127 bool status = true;
128 ifstream InputFile;
129 stringstream line;
130 GraphTestPair testGraphInsert;
131 int NumberOfFragments = 0;
132 double TEFactor;
133 char filename[MAXSTRINGSIZE];
134
135 if (FragmentList == NULL) { // check list pointer
136 FragmentList = new Graph;
137 }
138
139 // 2nd pass: open TEFactors file and read
140 DoLog(1) && (Log() << Verbose(1) << "Parsing the TEFactors file ... " << endl);
141 sprintf(filename, "%s/%s%s", path, FRAGMENTPREFIX, TEFACTORSFILE);
142 InputFile.open(filename);
143 if (InputFile != NULL) {
144 // 3. add found TEFactors to each keyset
145 NumberOfFragments = 0;
146 for(Graph::iterator runner = FragmentList->begin();runner != FragmentList->end(); runner++) {
147 if (!InputFile.eof()) {
148 InputFile >> TEFactor;
149 (*runner).second.second = TEFactor;
150 DoLog(2) && (Log() << Verbose(2) << "Setting " << ++NumberOfFragments << " fragment's TEFactor to " << (*runner).second.second << "." << endl);
151 } else {
152 status = false;
153 break;
154 }
155 }
156 // 4. Free and done
157 InputFile.close();
158 DoLog(1) && (Log() << Verbose(1) << "done." << endl);
159 } else {
160 DoLog(1) && (Log() << Verbose(1) << "File " << filename << " not found." << endl);
161 status = false;
162 }
163
164 return status;
165};
166
167/** Stores key sets to file.
168 * \param KeySetList Graph with Keysets
169 * \param &path path to file
170 * \return true - file written successfully, false - writing failed
171 */
172bool StoreKeySetFile(Graph &KeySetList, std::string &path)
173{
174 bool status = true;
175 string line = path + KEYSETFILE;
176 ofstream output(line.c_str());
177
178 // open KeySet file
179 DoLog(1) && (Log() << Verbose(1) << "Saving key sets of the total graph ... ");
180 if(output.good()) {
181 for(Graph::iterator runner = KeySetList.begin(); runner != KeySetList.end(); runner++) {
182 for (KeySet::iterator sprinter = (*runner).first.begin();sprinter != (*runner).first.end(); sprinter++) {
183 if (sprinter != (*runner).first.begin())
184 output << "\t";
185 output << *sprinter;
186 }
187 output << endl;
188 }
189 DoLog(0) && (Log() << Verbose(0) << "done." << endl);
190 } else {
191 DoeLog(0) && (eLog()<< Verbose(0) << "Unable to open " << line << " for writing keysets!" << endl);
192 performCriticalExit();
193 status = false;
194 }
195 output.close();
196 output.clear();
197
198 return status;
199};
200
201
202/** Stores TEFactors to file.
203 * \param *out output stream for debugging
204 * \param KeySetList Graph with factors
205 * \param *path path to file
206 * \return true - file written successfully, false - writing failed
207 */
208bool StoreTEFactorsFile(Graph &KeySetList, char *path)
209{
210 ofstream output;
211 bool status = true;
212 string line;
213
214 // open TEFactors file
215 line = path;
216 line.append("/");
217 line += FRAGMENTPREFIX;
218 line += TEFACTORSFILE;
219 output.open(line.c_str(), ios::out);
220 DoLog(1) && (Log() << Verbose(1) << "Saving TEFactors of the total graph ... ");
221 if(output != NULL) {
222 for(Graph::iterator runner = KeySetList.begin(); runner != KeySetList.end(); runner++)
223 output << (*runner).second.second << endl;
224 DoLog(1) && (Log() << Verbose(1) << "done." << endl);
225 } else {
226 DoLog(1) && (Log() << Verbose(1) << "failed to open " << line << "." << endl);
227 status = false;
228 }
229 output.close();
230
231 return status;
232};
233
234/** For a given graph, sorts KeySets into a (index, keyset) map.
235 * \param *GlobalKeySetList list of keysets with global ids (valid in "this" molecule) needed for adaptive increase
236 * \return map from index to keyset
237 */
238std::map<int,KeySet> * GraphToIndexedKeySet(Graph *GlobalKeySetList)
239{
240 map<int,KeySet> *IndexKeySetList = new map<int,KeySet>;
241 for(Graph::iterator runner = GlobalKeySetList->begin(); runner != GlobalKeySetList->end(); runner++) {
242 IndexKeySetList->insert( pair<int,KeySet>(runner->second.first,runner->first) );
243 }
244 return IndexKeySetList;
245};
246
247/** Inserts a (\a No, \a value) pair into the list, overwriting present one.
248 * Note if values are equal, No will decided on which is first
249 * \param *out output stream for debugging
250 * \param &AdaptiveCriteriaList list to insert into
251 * \param &IndexedKeySetList list to find key set for a given index \a No
252 * \param FragOrder current bond order of fragment
253 * \param No index of keyset
254 * \param value energy value
255 */
256void InsertIntoAdaptiveCriteriaList(std::map<int, pair<double,int> > *AdaptiveCriteriaList, std::map<int,KeySet> &IndexKeySetList, int FragOrder, int No, double Value)
257{
258 map<int,KeySet>::iterator marker = IndexKeySetList.find(No); // find keyset to Frag No.
259 if (marker != IndexKeySetList.end()) { // if found
260 Value *= 1 + MYEPSILON*(*((*marker).second.begin())); // in case of equal energies this makes them not equal without changing anything actually
261 // 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
262 pair <map<int, pair<double,int> >::iterator, bool> InsertedElement = AdaptiveCriteriaList->insert( make_pair(*((*marker).second.begin()), pair<double,int>( fabs(Value), FragOrder) ));
263 map<int, pair<double,int> >::iterator PresentItem = InsertedElement.first;
264 if (!InsertedElement.second) { // this root is already present
265 if ((*PresentItem).second.second < FragOrder) // if order there is lower, update entry with higher-order term
266 //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)
267 { // if value is smaller, update value and order
268 (*PresentItem).second.first = fabs(Value);
269 (*PresentItem).second.second = FragOrder;
270 DoLog(2) && (Log() << Verbose(2) << "Updated element (" << (*PresentItem).first << ",[" << (*PresentItem).second.first << "," << (*PresentItem).second.second << "])." << endl);
271 } else {
272 DoLog(2) && (Log() << Verbose(2) << "Did not update element " << (*PresentItem).first << " as " << FragOrder << " is less than or equal to " << (*PresentItem).second.second << "." << endl);
273 }
274 } else {
275 DoLog(2) && (Log() << Verbose(2) << "Inserted element (" << (*PresentItem).first << ",[" << (*PresentItem).second.first << "," << (*PresentItem).second.second << "])." << endl);
276 }
277 } else {
278 DoLog(1) && (Log() << Verbose(1) << "No Fragment under No. " << No << "found." << endl);
279 }
280};
281
282/** Counts lines in file.
283 * Note we are scanning lines from current position, not from beginning.
284 * \param InputFile file to be scanned.
285 */
286int CountLinesinFile(std::ifstream &InputFile)
287{
288 char *buffer = new char[MAXSTRINGSIZE];
289 int lines=0;
290
291 int PositionMarker = InputFile.tellg(); // not needed as Inputfile is copied, given by value, not by ref
292 // count the number of lines, i.e. the number of fragments
293 InputFile.getline(buffer, MAXSTRINGSIZE); // skip comment lines
294 InputFile.getline(buffer, MAXSTRINGSIZE);
295 while(!InputFile.eof()) {
296 InputFile.getline(buffer, MAXSTRINGSIZE);
297 lines++;
298 }
299 InputFile.seekg(PositionMarker, ios::beg);
300 delete[](buffer);
301 return lines;
302};
303
304
305/** Scans the adaptive order file and insert (index, value) into map.
306 * \param &path path to ENERGYPERFRAGMENT file (may be NULL if Order is non-negative)
307 * \param &IndexedKeySetList list to find key set for a given index \a No
308 * \return adaptive criteria list from file
309 */
310std::map<int, std::pair<double,int> > * ScanAdaptiveFileIntoMap(std::string &path, std::map<int,KeySet> &IndexKeySetList)
311{
312 map<int, pair<double,int> > *AdaptiveCriteriaList = new map<int, pair<double,int> >;
313 int No = 0, FragOrder = 0;
314 double Value = 0.;
315 char buffer[MAXSTRINGSIZE];
316 string filename = path + ENERGYPERFRAGMENT;
317 ifstream InputFile(filename.c_str());
318
319 if (InputFile.fail()) {
320 DoeLog(1) && (eLog() << Verbose(1) << "Cannot find file " << filename << "." << endl);
321 return AdaptiveCriteriaList;
322 }
323
324 if (CountLinesinFile(InputFile) > 0) {
325 // each line represents a fragment root (Atom::Nr) id and its energy contribution
326 InputFile.getline(buffer, MAXSTRINGSIZE); // skip comment lines
327 InputFile.getline(buffer, MAXSTRINGSIZE);
328 while(!InputFile.eof()) {
329 InputFile.getline(buffer, MAXSTRINGSIZE);
330 if (strlen(buffer) > 2) {
331 //Log() << Verbose(2) << "Scanning: " << buffer << endl;
332 stringstream line(buffer);
333 line >> FragOrder;
334 line >> ws >> No;
335 line >> ws >> Value; // skip time entry
336 line >> ws >> Value;
337 No -= 1; // indices start at 1 in file, not 0
338 //Log() << Verbose(2) << " - yields (" << No << "," << Value << ", " << FragOrder << ")" << endl;
339
340 // clean the list of those entries that have been superceded by higher order terms already
341 InsertIntoAdaptiveCriteriaList(AdaptiveCriteriaList, IndexKeySetList, FragOrder, No, Value);
342 }
343 }
344 // close and done
345 InputFile.close();
346 InputFile.clear();
347 }
348
349 return AdaptiveCriteriaList;
350};
351
352/** Maps adaptive criteria list back onto (Value, (Root Nr., Order))
353 * (i.e. sorted by value to pick the highest ones)
354 * \param *out output stream for debugging
355 * \param &AdaptiveCriteriaList list to insert into
356 * \param *mol molecule with atoms
357 * \return remapped list
358 */
359std::map<double, std::pair<int,int> > * ReMapAdaptiveCriteriaListToValue(std::map<int, std::pair<double,int> > *AdaptiveCriteriaList, molecule *mol)
360{
361 atom *Walker = NULL;
362 map<double, pair<int,int> > *FinalRootCandidates = new map<double, pair<int,int> > ;
363 DoLog(1) && (Log() << Verbose(1) << "Root candidate list is: " << endl);
364 for(map<int, pair<double,int> >::iterator runner = AdaptiveCriteriaList->begin(); runner != AdaptiveCriteriaList->end(); runner++) {
365 Walker = mol->FindAtom((*runner).first);
366 if (Walker != NULL) {
367 //if ((*runner).second.second >= Walker->AdaptiveOrder) { // only insert if this is an "active" root site for the current order
368 if (!Walker->MaxOrder) {
369 DoLog(2) && (Log() << Verbose(2) << "(" << (*runner).first << ",[" << (*runner).second.first << "," << (*runner).second.second << "])" << endl);
370 FinalRootCandidates->insert( make_pair( (*runner).second.first, pair<int,int>((*runner).first, (*runner).second.second) ) );
371 } else {
372 DoLog(2) && (Log() << Verbose(2) << "Excluding (" << *Walker << ", " << (*runner).first << ",[" << (*runner).second.first << "," << (*runner).second.second << "]), as it has reached its maximum order." << endl);
373 }
374 } else {
375 DoeLog(0) && (eLog()<< Verbose(0) << "Atom No. " << (*runner).second.first << " was not found in this molecule." << endl);
376 performCriticalExit();
377 }
378 }
379 return FinalRootCandidates;
380};
381
382/** Marks all candidate sites for update if below adaptive threshold.
383 * Picks a given number of highest values and set *AtomMask to true.
384 * \param *out output stream for debugging
385 * \param *AtomMask defines true/false per global Atom::Nr to mask in/out each nuclear site, used to activate given number of site to increment order adaptively
386 * \param FinalRootCandidates list candidates to check
387 * \param Order desired order
388 * \param *mol molecule with atoms
389 * \return true - if update is necessary, false - not
390 */
391bool MarkUpdateCandidates(bool *AtomMask, std::map<double, std::pair<int,int> > &FinalRootCandidates, int Order, molecule *mol)
392{
393 atom *Walker = NULL;
394 int No = -1;
395 bool status = false;
396 for(map<double, pair<int,int> >::iterator runner = FinalRootCandidates.upper_bound(pow(10.,Order)); runner != FinalRootCandidates.end(); runner++) {
397 No = (*runner).second.first;
398 Walker = mol->FindAtom(No);
399 //if (Walker->AdaptiveOrder < MinimumRingSize[Walker->getNr()]) {
400 DoLog(2) && (Log() << Verbose(2) << "Root " << No << " is still above threshold (10^{" << Order <<"}: " << runner->first << ", setting entry " << No << " of Atom mask to true." << endl);
401 AtomMask[No] = true;
402 status = true;
403 //} else
404 //Log() << Verbose(2) << "Root " << No << " is still above threshold (10^{" << Order <<"}: " << runner->first << ", however MinimumRingSize of " << MinimumRingSize[Walker->getNr()] << " does not allow further adaptive increase." << endl;
405 }
406 return status;
407};
408
409/** print atom mask for debugging.
410 * \param *out output stream for debugging
411 * \param *AtomMask defines true/false per global Atom::Nr to mask in/out each nuclear site, used to activate given number of site to increment order adaptively
412 * \param AtomCount number of entries in \a *AtomMask
413 */
414void PrintAtomMask(bool *AtomMask, int AtomCount)
415{
416 DoLog(2) && (Log() << Verbose(2) << " ");
417 for(int i=0;i<AtomCount;i++)
418 DoLog(0) && (Log() << Verbose(0) << (i % 10));
419 DoLog(0) && (Log() << Verbose(0) << endl);
420 DoLog(2) && (Log() << Verbose(2) << "Atom mask is: ");
421 for(int i=0;i<AtomCount;i++)
422 DoLog(0) && (Log() << Verbose(0) << (AtomMask[i] ? "t" : "f"));
423 DoLog(0) && (Log() << Verbose(0) << endl);
424};
425
426
427
428bool KeyCompare::operator() (const KeySet SubgraphA, const KeySet SubgraphB) const
429{
430 //Log() << Verbose(0) << "my check is used." << endl;
431 if (SubgraphA.size() < SubgraphB.size()) {
432 return true;
433 } else {
434 if (SubgraphA.size() > SubgraphB.size()) {
435 return false;
436 } else {
437 KeySet::iterator IteratorA = SubgraphA.begin();
438 KeySet::iterator IteratorB = SubgraphB.begin();
439 while ((IteratorA != SubgraphA.end()) && (IteratorB != SubgraphB.end())) {
440 if ((*IteratorA) < (*IteratorB))
441 return true;
442 else if ((*IteratorA) > (*IteratorB)) {
443 return false;
444 } // else, go on to next index
445 IteratorA++;
446 IteratorB++;
447 } // end of while loop
448 }// end of check in case of equal sizes
449 }
450 return false; // if we reach this point, they are equal
451};
452
453/** Combines all KeySets from all orders into single ones (with just unique entries).
454 * \param *out output stream for debugging
455 * \param *&FragmentList list to fill
456 * \param ***FragmentLowerOrdersList
457 * \param &RootStack stack with all root candidates (unequal to each atom in complete molecule if adaptive scheme is applied)
458 * \param *mol molecule with atoms and bonds
459 */
460int CombineAllOrderListIntoOne(Graph *&FragmentList, Graph ***FragmentLowerOrdersList, KeyStack &RootStack, molecule *mol)
461{
462 int RootNr = 0;
463 int RootKeyNr = 0;
464 int StartNr = 0;
465 int counter = 0;
466 int NumLevels = 0;
467 atom *Walker = NULL;
468
469 DoLog(0) && (Log() << Verbose(0) << "Combining the lists of all orders per order and finally into a single one." << endl);
470 if (FragmentList == NULL) {
471 FragmentList = new Graph;
472 counter = 0;
473 } else {
474 counter = FragmentList->size();
475 }
476
477 StartNr = RootStack.back();
478 do {
479 RootKeyNr = RootStack.front();
480 RootStack.pop_front();
481 Walker = mol->FindAtom(RootKeyNr);
482 NumLevels = 1 << (Walker->AdaptiveOrder - 1);
483 for(int i=0;i<NumLevels;i++) {
484 if (FragmentLowerOrdersList[RootNr][i] != NULL) {
485 InsertGraphIntoGraph(*FragmentList, (*FragmentLowerOrdersList[RootNr][i]), &counter);
486 }
487 }
488 RootStack.push_back(Walker->getNr());
489 RootNr++;
490 } while (RootKeyNr != StartNr);
491 return counter;
492};
493
494/** Free's memory allocated for all KeySets from all orders.
495 * \param *out output stream for debugging
496 * \param ***FragmentLowerOrdersList
497 * \param &RootStack stack with all root candidates (unequal to each atom in complete molecule if adaptive scheme is applied)
498 * \param *mol molecule with atoms and bonds
499 */
500void FreeAllOrdersList(Graph ***FragmentLowerOrdersList, KeyStack &RootStack, molecule *mol)
501{
502 DoLog(1) && (Log() << Verbose(1) << "Free'ing the lists of all orders per order." << endl);
503 int RootNr = 0;
504 int RootKeyNr = 0;
505 int NumLevels = 0;
506 atom *Walker = NULL;
507 while (!RootStack.empty()) {
508 RootKeyNr = RootStack.front();
509 RootStack.pop_front();
510 Walker = mol->FindAtom(RootKeyNr);
511 NumLevels = 1 << (Walker->AdaptiveOrder - 1);
512 for(int i=0;i<NumLevels;i++) {
513 if (FragmentLowerOrdersList[RootNr][i] != NULL) {
514 delete(FragmentLowerOrdersList[RootNr][i]);
515 }
516 }
517 delete[](FragmentLowerOrdersList[RootNr]);
518 RootNr++;
519 }
520 delete[](FragmentLowerOrdersList);
521};
522
Note: See TracBrowser for help on using the repository browser.