source: src/Fragmentation/fragmentation_helpers.cpp@ ba94c5

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 ba94c5 was ba94c5, checked in by Frederik Heber <heber@…>, 14 years ago

Removed modules graph.[ch]pp.

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