source: src/Fragmentation/fragmentation_helpers.cpp@ dadc74

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

Extracted Graph (map of KeySets) into own class from graph.hpp.

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