source: src/builder.cpp@ cc04b7

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 cc04b7 was cc04b7, checked in by Tillmann Crueger <crueger@…>, 15 years ago

Added a central registry that allows access to actions by name.

  • Property mode set to 100755
File size: 48.3 KB
Line 
1/** \file builder.cpp
2 *
3 * By stating absolute positions or binding angles and distances atomic positions of a molecule can be constructed.
4 * The output is the complete configuration file for PCP for direct use.
5 * Features:
6 * -# Atomic data is retrieved from a file, if not found requested and stored there for later re-use
7 * -# step-by-step construction of the molecule beginning either at a centre of with a certain atom
8 *
9 */
10
11/*! \mainpage Molecuilder - a molecular set builder
12 *
13 * This introductory shall briefly make aquainted with the program, helping in installing and a first run.
14 *
15 * \section about About the Program
16 *
17 * Molecuilder is a short program, written in C++, that enables the construction of a coordinate set for the
18 * atoms making up an molecule by the successive statement of binding angles and distances and referencing to
19 * already constructed atoms.
20 *
21 * A configuration file may be written that is compatible to the format used by PCP - a parallel Car-Parrinello
22 * molecular dynamics implementation.
23 *
24 * \section install Installation
25 *
26 * Installation should without problems succeed as follows:
27 * -# ./configure (or: mkdir build;mkdir run;cd build; ../configure --bindir=../run)
28 * -# make
29 * -# make install
30 *
31 * Further useful commands are
32 * -# make clean uninstall: deletes .o-files and removes executable from the given binary directory\n
33 * -# make doxygen-doc: Creates these html pages out of the documented source
34 *
35 * \section run Running
36 *
37 * The program can be executed by running: ./molecuilder
38 *
39 * Note, that it uses a database, called "elements.db", in the executable's directory. If the file is not found,
40 * it is created and any given data on elements of the periodic table will be stored therein and re-used on
41 * later re-execution.
42 *
43 * \section ref References
44 *
45 * For the special configuration file format, see the documentation of pcp.
46 *
47 */
48
49
50using namespace std;
51
52#include "analysis_correlation.hpp"
53#include "atom.hpp"
54#include "bond.hpp"
55#include "bondgraph.hpp"
56#include "boundary.hpp"
57#include "config.hpp"
58#include "element.hpp"
59#include "ellipsoid.hpp"
60#include "helpers.hpp"
61#include "leastsquaremin.hpp"
62#include "linkedcell.hpp"
63#include "log.hpp"
64#include "memoryusageobserverunittest.hpp"
65#include "molecule.hpp"
66#include "periodentafel.hpp"
67#include "UIElements/UIFactory.hpp"
68#include "UIElements/MainWindow.hpp"
69
70/** Parses the command line options.
71 * \param argc argument count
72 * \param **argv arguments array
73 * \param *molecules list of molecules structure
74 * \param *periode elements structure
75 * \param configuration config file structure
76 * \param *ConfigFileName pointer to config file name in **argv
77 * \param *PathToDatabases pointer to db's path in **argv
78 * \return exit code (0 - successful, all else - something's wrong)
79 */
80static int ParseCommandLineOptions(int argc, char **argv, MoleculeListClass *&molecules, periodentafel *&periode,\
81 config& configuration, char *&ConfigFileName)
82{
83 Vector x,y,z,n; // coordinates for absolute point in cell volume
84 double *factor; // unit factor if desired
85 ifstream test;
86 ofstream output;
87 string line;
88 atom *first;
89 bool SaveFlag = false;
90 int ExitFlag = 0;
91 int j;
92 double volume = 0.;
93 enum ConfigStatus configPresent = absent;
94 clock_t start,end;
95 int argptr;
96 molecule *mol = NULL;
97 string BondGraphFileName("");
98 int verbosity = 0;
99 strncpy(configuration.databasepath, LocalPath, MAXSTRINGSIZE-1);
100
101 if (argc > 1) { // config file specified as option
102 // 1. : Parse options that just set variables or print help
103 argptr = 1;
104 do {
105 if (argv[argptr][0] == '-') {
106 Log() << Verbose(0) << "Recognized command line argument: " << argv[argptr][1] << ".\n";
107 argptr++;
108 switch(argv[argptr-1][1]) {
109 case 'h':
110 case 'H':
111 case '?':
112 Log() << Verbose(0) << "MoleCuilder suite" << endl << "==================" << endl << endl;
113 Log() << Verbose(0) << "Usage: " << argv[0] << "[config file] [-{acefpsthH?vfrp}] [further arguments]" << endl;
114 Log() << Verbose(0) << "or simply " << argv[0] << " without arguments for interactive session." << endl;
115 Log() << Verbose(0) << "\t-a Z x1 x2 x3\tAdd new atom of element Z at coordinates (x1,x2,x3)." << endl;
116 Log() << Verbose(0) << "\t-A <source>\tCreate adjacency list from bonds parsed from 'dbond'-style file." <<endl;
117 Log() << Verbose(0) << "\t-b xx xy xz yy yz zz\tCenter atoms in domain with given symmetric matrix of (xx,xy,xz,yy,yz,zz)." << endl;
118 Log() << Verbose(0) << "\t-B xx xy xz yy yz zz\tBound atoms by domain with given symmetric matrix of (xx,xy,xz,yy,yz,zz)." << endl;
119 Log() << Verbose(0) << "\t-c x1 x2 x3\tCenter atoms in domain with a minimum distance to boundary of (x1,x2,x3)." << endl;
120 Log() << Verbose(0) << "\t-C\tPair Correlation analysis." << endl;
121 Log() << Verbose(0) << "\t-d x1 x2 x3\tDuplicate cell along each axis by given factor." << endl;
122 Log() << Verbose(0) << "\t-D <bond distance>\tDepth-First-Search Analysis of the molecule, giving cycles and tree/back edges." << endl;
123 Log() << Verbose(0) << "\t-e <file>\tSets the databases path to be parsed (default: ./)." << endl;
124 Log() << Verbose(0) << "\t-E <id> <Z>\tChange atom <id>'s element to <Z>, <id> begins at 0." << endl;
125 Log() << Verbose(0) << "\t-f/F <dist> <order>\tFragments the molecule in BOSSANOVA manner (with/out rings compressed) and stores config files in same dir as config (return code 0 - fragmented, 2 - no fragmentation necessary)." << endl;
126 Log() << Verbose(0) << "\t-g <file>\tParses a bond length table from the given file." << endl;
127 Log() << Verbose(0) << "\t-h/-H/-?\tGive this help screen." << endl;
128 Log() << Verbose(0) << "\t-L <step0> <step1> <prefix>\tStore a linear interpolation between two configurations <step0> and <step1> into single config files with prefix <prefix> and as Trajectories into the current config file." << endl;
129 Log() << Verbose(0) << "\t-m <0/1>\tCalculate (0)/ Align in(1) PAS with greatest EV along z axis." << endl;
130 Log() << Verbose(0) << "\t-M <basis>\tSetting basis to store to MPQC config files." << endl;
131 Log() << Verbose(0) << "\t-n\tFast parsing (i.e. no trajectories are looked for)." << endl;
132 Log() << Verbose(0) << "\t-N <radius> <file>\tGet non-convex-envelope." << endl;
133 Log() << Verbose(0) << "\t-o <out>\tGet volume of the convex envelope (and store to tecplot file)." << endl;
134 Log() << Verbose(0) << "\t-O\tCenter atoms in origin." << endl;
135 Log() << Verbose(0) << "\t-p <file>\tParse given xyz file and create raw config file from it." << endl;
136 Log() << Verbose(0) << "\t-P <file>\tParse given forces file and append as an MD step to config file via Verlet." << endl;
137 Log() << Verbose(0) << "\t-r <id>\t\tRemove an atom with given id." << endl;
138 Log() << Verbose(0) << "\t-R <id> <radius>\t\tRemove all atoms out of sphere around a given one." << endl;
139 Log() << Verbose(0) << "\t-s x1 x2 x3\tScale all atom coordinates by this vector (x1,x2,x3)." << endl;
140 Log() << Verbose(0) << "\t-S <file> Store temperatures from the config file in <file>." << endl;
141 Log() << Verbose(0) << "\t-t x1 x2 x3\tTranslate all atoms by this vector (x1,x2,x3)." << endl;
142 Log() << Verbose(0) << "\t-T x1 x2 x3\tTranslate periodically all atoms by this vector (x1,x2,x3)." << endl;
143 Log() << Verbose(0) << "\t-u rho\tsuspend in water solution and output necessary cell lengths, average density rho and repetition." << endl;
144 Log() << Verbose(0) << "\t-v\t\tsets verbosity (more is more)." << endl;
145 Log() << Verbose(0) << "\t-V\t\tGives version information." << endl;
146 Log() << Verbose(0) << "Note: config files must not begin with '-' !" << endl;
147 return (1);
148 break;
149 case 'v':
150 while (argv[argptr-1][verbosity+1] == 'v') {
151 verbosity++;
152 }
153 setVerbosity(verbosity);
154 Log() << Verbose(0) << "Setting verbosity to " << verbosity << "." << endl;
155 break;
156 case 'V':
157 Log() << Verbose(0) << argv[0] << " " << VERSIONSTRING << endl;
158 Log() << Verbose(0) << "Build your own molecule position set." << endl;
159 return (1);
160 break;
161 case 'e':
162 if ((argptr >= argc) || (argv[argptr][0] == '-')) {
163 eLog() << Verbose(0) << "Not enough or invalid arguments for specifying element db: -e <db file>" << endl;
164 performCriticalExit();
165 } else {
166 Log() << Verbose(0) << "Using " << argv[argptr] << " as elements database." << endl;
167 strncpy (configuration.databasepath, argv[argptr], MAXSTRINGSIZE-1);
168 argptr+=1;
169 }
170 break;
171 case 'g':
172 if ((argptr >= argc) || (argv[argptr][0] == '-')) {
173 eLog() << Verbose(0) << "Not enough or invalid arguments for specifying bond length table: -g <table file>" << endl;
174 performCriticalExit();
175 } else {
176 BondGraphFileName = argv[argptr];
177 Log() << Verbose(0) << "Using " << BondGraphFileName << " as bond length table." << endl;
178 argptr+=1;
179 }
180 break;
181 case 'n':
182 Log() << Verbose(0) << "I won't parse trajectories." << endl;
183 configuration.FastParsing = true;
184 break;
185 default: // no match? Step on
186 argptr++;
187 break;
188 }
189 } else
190 argptr++;
191 } while (argptr < argc);
192
193 // 3a. Parse the element database
194 if (periode->LoadPeriodentafel(configuration.databasepath)) {
195 Log() << Verbose(0) << "Element list loaded successfully." << endl;
196 //periode->Output();
197 } else {
198 Log() << Verbose(0) << "Element list loading failed." << endl;
199 return 1;
200 }
201 // 3b. Find config file name and parse if possible, also BondGraphFileName
202 if (argv[1][0] != '-') {
203 // simply create a new molecule, wherein the config file is loaded and the manipulation takes place
204 Log() << Verbose(0) << "Config file given." << endl;
205 test.open(argv[1], ios::in);
206 if (test == NULL) {
207 //return (1);
208 output.open(argv[1], ios::out);
209 if (output == NULL) {
210 Log() << Verbose(1) << "Specified config file " << argv[1] << " not found." << endl;
211 configPresent = absent;
212 } else {
213 Log() << Verbose(0) << "Empty configuration file." << endl;
214 ConfigFileName = argv[1];
215 configPresent = empty;
216 output.close();
217 }
218 } else {
219 test.close();
220 ConfigFileName = argv[1];
221 Log() << Verbose(1) << "Specified config file found, parsing ... ";
222 switch (configuration.TestSyntax(ConfigFileName, periode)) {
223 case 1:
224 Log() << Verbose(0) << "new syntax." << endl;
225 configuration.Load(ConfigFileName, BondGraphFileName, periode, molecules);
226 configPresent = present;
227 break;
228 case 0:
229 Log() << Verbose(0) << "old syntax." << endl;
230 configuration.LoadOld(ConfigFileName, BondGraphFileName, periode, molecules);
231 configPresent = present;
232 break;
233 default:
234 Log() << Verbose(0) << "Unknown syntax or empty, yet present file." << endl;
235 configPresent = empty;
236 }
237 }
238 } else
239 configPresent = absent;
240 // set mol to first active molecule
241 if (molecules->ListOfMolecules.size() != 0) {
242 for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++)
243 if ((*ListRunner)->ActiveFlag) {
244 mol = *ListRunner;
245 break;
246 }
247 }
248 if (mol == NULL) {
249 mol = new molecule(periode);
250 mol->ActiveFlag = true;
251 molecules->insert(mol);
252 }
253
254 // 4. parse again through options, now for those depending on elements db and config presence
255 argptr = 1;
256 do {
257 Log() << Verbose(0) << "Current Command line argument: " << argv[argptr] << "." << endl;
258 if (argv[argptr][0] == '-') {
259 argptr++;
260 if ((configPresent == present) || (configPresent == empty)) {
261 switch(argv[argptr-1][1]) {
262 case 'p':
263 if (ExitFlag == 0) ExitFlag = 1;
264 if ((argptr >= argc) || (argv[argptr][0] == '-')) {
265 ExitFlag = 255;
266 eLog() << Verbose(0) << "Not enough arguments for parsing: -p <xyz file>" << endl;
267 performCriticalExit();
268 } else {
269 SaveFlag = true;
270 Log() << Verbose(1) << "Parsing xyz file for new atoms." << endl;
271 if (!mol->AddXYZFile(argv[argptr]))
272 Log() << Verbose(2) << "File not found." << endl;
273 else {
274 Log() << Verbose(2) << "File found and parsed." << endl;
275 configPresent = present;
276 }
277 }
278 break;
279 case 'a':
280 if (ExitFlag == 0) ExitFlag = 1;
281 if ((argptr >= argc) || (argv[argptr][0] == '-') || (!IsValidNumber(argv[argptr+1])) || (!IsValidNumber(argv[argptr+2])) || (!IsValidNumber(argv[argptr+3]))) {
282 ExitFlag = 255;
283 eLog() << Verbose(0) << "Not enough or invalid arguments for adding atom: -a <element> <x> <y> <z>" << endl;
284 performCriticalExit();
285 } else {
286 SaveFlag = true;
287 Log() << Verbose(1) << "Adding new atom with element " << argv[argptr] << " at (" << argv[argptr+1] << "," << argv[argptr+2] << "," << argv[argptr+3] << "), ";
288 first = new atom;
289 first->type = periode->FindElement(atoi(argv[argptr]));
290 if (first->type != NULL)
291 Log() << Verbose(2) << "found element " << first->type->name << endl;
292 for (int i=NDIM;i--;)
293 first->x.x[i] = atof(argv[argptr+1+i]);
294 if (first->type != NULL) {
295 mol->AddAtom(first); // add to molecule
296 if ((configPresent == empty) && (mol->AtomCount != 0))
297 configPresent = present;
298 } else
299 eLog() << Verbose(1) << "Could not find the specified element." << endl;
300 argptr+=4;
301 }
302 break;
303 default: // no match? Don't step on (this is done in next switch's default)
304 break;
305 }
306 }
307 if (configPresent == present) {
308 switch(argv[argptr-1][1]) {
309 case 'M':
310 if ((argptr >= argc) || (argv[argptr][0] == '-')) {
311 ExitFlag = 255;
312 eLog() << Verbose(0) << "Not enough or invalid arguments given for setting MPQC basis: -B <basis name>" << endl;
313 performCriticalExit();
314 } else {
315 configuration.basis = argv[argptr];
316 Log() << Verbose(1) << "Setting MPQC basis to " << configuration.basis << "." << endl;
317 argptr+=1;
318 }
319 break;
320 case 'D':
321 if (ExitFlag == 0) ExitFlag = 1;
322 {
323 Log() << Verbose(1) << "Depth-First-Search Analysis." << endl;
324 MoleculeLeafClass *Subgraphs = NULL; // list of subgraphs from DFS analysis
325 int *MinimumRingSize = new int[mol->AtomCount];
326 atom ***ListOfLocalAtoms = NULL;
327 class StackClass<bond *> *BackEdgeStack = NULL;
328 class StackClass<bond *> *LocalBackEdgeStack = NULL;
329 mol->CreateAdjacencyList(atof(argv[argptr]), configuration.GetIsAngstroem(), &BondGraph::CovalentMinMaxDistance, NULL);
330 Subgraphs = mol->DepthFirstSearchAnalysis(BackEdgeStack);
331 if (Subgraphs != NULL) {
332 int FragmentCounter = 0;
333 while (Subgraphs->next != NULL) {
334 Subgraphs = Subgraphs->next;
335 Subgraphs->FillBondStructureFromReference(mol, FragmentCounter, ListOfLocalAtoms, false); // we want to keep the created ListOfLocalAtoms
336 LocalBackEdgeStack = new StackClass<bond *> (Subgraphs->Leaf->BondCount);
337 Subgraphs->Leaf->PickLocalBackEdges(ListOfLocalAtoms[FragmentCounter], BackEdgeStack, LocalBackEdgeStack);
338 Subgraphs->Leaf->CyclicStructureAnalysis(LocalBackEdgeStack, MinimumRingSize);
339 delete(LocalBackEdgeStack);
340 delete(Subgraphs->previous);
341 FragmentCounter++;
342 }
343 delete(Subgraphs);
344 for (int i=0;i<FragmentCounter;i++)
345 Free(&ListOfLocalAtoms[i]);
346 Free(&ListOfLocalAtoms);
347 }
348 delete(BackEdgeStack);
349 delete[](MinimumRingSize);
350 }
351 //argptr+=1;
352 break;
353 case 'C':
354 if (ExitFlag == 0) ExitFlag = 1;
355 if ((argptr+2 >= argc) || (!IsValidNumber(argv[argptr])) || (argv[argptr][0] == '-') || (argv[argptr+1][0] == '-') || (argv[argptr+2][0] == '-')) {
356 ExitFlag = 255;
357 eLog() << Verbose(0) << "Not enough or invalid arguments given for pair correlation analysis: -C <Z> <output> <bin output>" << endl;
358 performCriticalExit();
359 } else {
360 SaveFlag = false;
361 ofstream output(argv[argptr+1]);
362 ofstream binoutput(argv[argptr+2]);
363 const double radius = 5.;
364
365 // get the boundary
366 class molecule *Boundary = NULL;
367 class Tesselation *TesselStruct = NULL;
368 const LinkedCell *LCList = NULL;
369 // find biggest molecule
370 int counter = 0;
371 for (MoleculeList::iterator BigFinder = molecules->ListOfMolecules.begin(); BigFinder != molecules->ListOfMolecules.end(); BigFinder++) {
372 if ((Boundary == NULL) || (Boundary->AtomCount < (*BigFinder)->AtomCount)) {
373 Boundary = *BigFinder;
374 }
375 counter++;
376 }
377 bool *Actives = Malloc<bool>(counter, "ParseCommandLineOptions() - case C -- *Actives");
378 counter = 0;
379 for (MoleculeList::iterator BigFinder = molecules->ListOfMolecules.begin(); BigFinder != molecules->ListOfMolecules.end(); BigFinder++) {
380 Actives[counter] = (*BigFinder)->ActiveFlag;
381 (*BigFinder)->ActiveFlag = (*BigFinder == Boundary) ? false : true;
382 }
383 LCList = new LinkedCell(Boundary, 2.*radius);
384 element *elemental = periode->FindElement((const int) atoi(argv[argptr]));
385 FindNonConvexBorder(Boundary, TesselStruct, LCList, radius, NULL);
386 int ranges[NDIM] = {1,1,1};
387 CorrelationToSurfaceMap *surfacemap = PeriodicCorrelationToSurface( molecules, elemental, TesselStruct, LCList, ranges );
388 BinPairMap *binmap = BinData( surfacemap, 0.5, 0., 0. );
389 OutputCorrelation ( &binoutput, binmap );
390 output.close();
391 binoutput.close();
392 for (MoleculeList::iterator BigFinder = molecules->ListOfMolecules.begin(); BigFinder != molecules->ListOfMolecules.end(); BigFinder++)
393 (*BigFinder)->ActiveFlag = Actives[counter];
394 Free(&Actives);
395 delete(LCList);
396 delete(TesselStruct);
397 argptr+=3;
398 }
399 break;
400 case 'E':
401 if (ExitFlag == 0) ExitFlag = 1;
402 if ((argptr+1 >= argc) || (!IsValidNumber(argv[argptr])) || (argv[argptr+1][0] == '-')) {
403 ExitFlag = 255;
404 eLog() << Verbose(0) << "Not enough or invalid arguments given for changing element: -E <atom nr.> <element>" << endl;
405 performCriticalExit();
406 } else {
407 SaveFlag = true;
408 Log() << Verbose(1) << "Changing atom " << argv[argptr] << " to element " << argv[argptr+1] << "." << endl;
409 first = mol->FindAtom(atoi(argv[argptr]));
410 first->type = periode->FindElement(atoi(argv[argptr+1]));
411 argptr+=2;
412 }
413 break;
414 case 'F':
415 if (ExitFlag == 0) ExitFlag = 1;
416 if (argptr+5 >=argc) {
417 ExitFlag = 255;
418 eLog() << Verbose(0) << "Not enough or invalid arguments given for filling box with water: -F <dist_x> <dist_y> <dist_z> <randatom> <randmol> <DoRotate>" << endl;
419 performCriticalExit();
420 } else {
421 SaveFlag = true;
422 Log() << Verbose(1) << "Filling Box with water molecules." << endl;
423 // construct water molecule
424 molecule *filler = new molecule(periode);;
425 molecule *Filling = NULL;
426 atom *second = NULL, *third = NULL;
427 first = new atom();
428 first->type = periode->FindElement(1);
429 first->x.Init(0.441, -0.143, 0.);
430 filler->AddAtom(first);
431 second = new atom();
432 second->type = periode->FindElement(1);
433 second->x.Init(-0.464, 1.137, 0.0);
434 filler->AddAtom(second);
435 third = new atom();
436 third->type = periode->FindElement(8);
437 third->x.Init(-0.464, 0.177, 0.);
438 filler->AddAtom(third);
439 filler->AddBond(first, third, 1);
440 filler->AddBond(second, third, 1);
441 // call routine
442 double distance[NDIM];
443 for (int i=0;i<NDIM;i++)
444 distance[i] = atof(argv[argptr+i]);
445 Filling = FillBoxWithMolecule(molecules, filler, configuration, distance, atof(argv[argptr+3]), atof(argv[argptr+4]), atoi(argv[argptr+5]));
446 if (Filling != NULL) {
447 molecules->insert(Filling);
448 }
449 delete(filler);
450 argptr+=6;
451 }
452 break;
453 case 'A':
454 if (ExitFlag == 0) ExitFlag = 1;
455 if ((argptr >= argc) || (argv[argptr][0] == '-')) {
456 ExitFlag =255;
457 eLog() << Verbose(0) << "Missing source file for bonds in molecule: -A <bond sourcefile>" << endl;
458 performCriticalExit();
459 } else {
460 Log() << Verbose(0) << "Parsing bonds from " << argv[argptr] << "." << endl;
461 ifstream *input = new ifstream(argv[argptr]);
462 mol->CreateAdjacencyListFromDbondFile(input);
463 input->close();
464 argptr+=1;
465 }
466 break;
467 case 'N':
468 if (ExitFlag == 0) ExitFlag = 1;
469 if ((argptr+1 >= argc) || (argv[argptr+1][0] == '-')){
470 ExitFlag = 255;
471 eLog() << Verbose(0) << "Not enough or invalid arguments given for non-convex envelope: -o <radius> <tecplot output file>" << endl;
472 performCriticalExit();
473 } else {
474 class Tesselation *T = NULL;
475 const LinkedCell *LCList = NULL;
476 molecule * Boundary = NULL;
477 //string filename(argv[argptr+1]);
478 //filename.append(".csv");
479 Log() << Verbose(0) << "Evaluating non-convex envelope of biggest molecule.";
480 Log() << Verbose(1) << "Using rolling ball of radius " << atof(argv[argptr]) << " and storing tecplot data in " << argv[argptr+1] << "." << endl;
481 // find biggest molecule
482 int counter = 0;
483 for (MoleculeList::iterator BigFinder = molecules->ListOfMolecules.begin(); BigFinder != molecules->ListOfMolecules.end(); BigFinder++) {
484 (*BigFinder)->CountAtoms();
485 if ((Boundary == NULL) || (Boundary->AtomCount < (*BigFinder)->AtomCount)) {
486 Boundary = *BigFinder;
487 }
488 counter++;
489 }
490 Log() << Verbose(1) << "Biggest molecule has " << Boundary->AtomCount << " atoms." << endl;
491 start = clock();
492 LCList = new LinkedCell(Boundary, atof(argv[argptr])*2.);
493 FindNonConvexBorder(Boundary, T, LCList, atof(argv[argptr]), argv[argptr+1]);
494 //FindDistributionOfEllipsoids(T, &LCList, N, number, filename.c_str());
495 end = clock();
496 Log() << Verbose(0) << "Clocks for this operation: " << (end-start) << ", time: " << ((double)(end-start)/CLOCKS_PER_SEC) << "s." << endl;
497 delete(LCList);
498 argptr+=2;
499 }
500 break;
501 case 'S':
502 if (ExitFlag == 0) ExitFlag = 1;
503 if ((argptr >= argc) || (argv[argptr][0] == '-')) {
504 ExitFlag = 255;
505 eLog() << Verbose(0) << "Not enough or invalid arguments given for storing tempature: -S <temperature file>" << endl;
506 performCriticalExit();
507 } else {
508 Log() << Verbose(1) << "Storing temperatures in " << argv[argptr] << "." << endl;
509 ofstream *output = new ofstream(argv[argptr], ios::trunc);
510 if (!mol->OutputTemperatureFromTrajectories(output, 0, mol->MDSteps))
511 Log() << Verbose(2) << "File could not be written." << endl;
512 else
513 Log() << Verbose(2) << "File stored." << endl;
514 output->close();
515 delete(output);
516 argptr+=1;
517 }
518 break;
519 case 'L':
520 if (ExitFlag == 0) ExitFlag = 1;
521 if ((argptr >= argc) || (argv[argptr][0] == '-')) {
522 ExitFlag = 255;
523 eLog() << Verbose(0) << "Not enough or invalid arguments given for storing tempature: -L <step0> <step1> <prefix> <identity mapping?>" << endl;
524 performCriticalExit();
525 } else {
526 SaveFlag = true;
527 Log() << Verbose(1) << "Linear interpolation between configuration " << argv[argptr] << " and " << argv[argptr+1] << "." << endl;
528 if (atoi(argv[argptr+3]) == 1)
529 Log() << Verbose(1) << "Using Identity for the permutation map." << endl;
530 if (!mol->LinearInterpolationBetweenConfiguration(atoi(argv[argptr]), atoi(argv[argptr+1]), argv[argptr+2], configuration, atoi(argv[argptr+3])) == 1 ? true : false)
531 Log() << Verbose(2) << "Could not store " << argv[argptr+2] << " files." << endl;
532 else
533 Log() << Verbose(2) << "Steps created and " << argv[argptr+2] << " files stored." << endl;
534 argptr+=4;
535 }
536 break;
537 case 'P':
538 if (ExitFlag == 0) ExitFlag = 1;
539 if ((argptr >= argc) || (argv[argptr][0] == '-')) {
540 ExitFlag = 255;
541 eLog() << Verbose(0) << "Not enough or invalid arguments given for parsing and integrating forces: -P <forces file>" << endl;
542 performCriticalExit();
543 } else {
544 SaveFlag = true;
545 Log() << Verbose(1) << "Parsing forces file and Verlet integrating." << endl;
546 if (!mol->VerletForceIntegration(argv[argptr], configuration))
547 Log() << Verbose(2) << "File not found." << endl;
548 else
549 Log() << Verbose(2) << "File found and parsed." << endl;
550 argptr+=1;
551 }
552 break;
553 case 'R':
554 if (ExitFlag == 0) ExitFlag = 1;
555 if ((argptr+1 >= argc) || (argv[argptr][0] == '-') || (!IsValidNumber(argv[argptr])) || (!IsValidNumber(argv[argptr+1]))) {
556 ExitFlag = 255;
557 eLog() << Verbose(0) << "Not enough or invalid arguments given for removing atoms: -R <id> <distance>" << endl;
558 performCriticalExit();
559 } else {
560 SaveFlag = true;
561 Log() << Verbose(1) << "Removing atoms around " << argv[argptr] << " with radius " << argv[argptr+1] << "." << endl;
562 double tmp1 = atof(argv[argptr+1]);
563 atom *third = mol->FindAtom(atoi(argv[argptr]));
564 atom *first = mol->start;
565 if ((third != NULL) && (first != mol->end)) {
566 atom *second = first->next;
567 while(second != mol->end) {
568 first = second;
569 second = first->next;
570 if (first->x.DistanceSquared((const Vector *)&third->x) > tmp1*tmp1) // distance to first above radius ...
571 mol->RemoveAtom(first);
572 }
573 } else {
574 eLog() << Verbose(1) << "Removal failed due to missing atoms on molecule or wrong id." << endl;
575 }
576 argptr+=2;
577 }
578 break;
579 case 't':
580 if (ExitFlag == 0) ExitFlag = 1;
581 if ((argptr+2 >= argc) || (!IsValidNumber(argv[argptr])) || (!IsValidNumber(argv[argptr+1])) || (!IsValidNumber(argv[argptr+2])) ) {
582 ExitFlag = 255;
583 eLog() << Verbose(0) << "Not enough or invalid arguments given for translation: -t <x> <y> <z>" << endl;
584 performCriticalExit();
585 } else {
586 if (ExitFlag == 0) ExitFlag = 1;
587 SaveFlag = true;
588 Log() << Verbose(1) << "Translating all ions by given vector." << endl;
589 for (int i=NDIM;i--;)
590 x.x[i] = atof(argv[argptr+i]);
591 mol->Translate((const Vector *)&x);
592 argptr+=3;
593 }
594 break;
595 case 'T':
596 if (ExitFlag == 0) ExitFlag = 1;
597 if ((argptr+2 >= argc) || (!IsValidNumber(argv[argptr])) || (!IsValidNumber(argv[argptr+1])) || (!IsValidNumber(argv[argptr+2])) ) {
598 ExitFlag = 255;
599 eLog() << Verbose(0) << "Not enough or invalid arguments given for periodic translation: -T <x> <y> <z>" << endl;
600 performCriticalExit();
601 } else {
602 if (ExitFlag == 0) ExitFlag = 1;
603 SaveFlag = true;
604 Log() << Verbose(1) << "Translating all ions periodically by given vector." << endl;
605 for (int i=NDIM;i--;)
606 x.x[i] = atof(argv[argptr+i]);
607 mol->TranslatePeriodically((const Vector *)&x);
608 argptr+=3;
609 }
610 break;
611 case 's':
612 if (ExitFlag == 0) ExitFlag = 1;
613 if ((argptr >= argc) || (!IsValidNumber(argv[argptr])) || (!IsValidNumber(argv[argptr+1])) || (!IsValidNumber(argv[argptr+2])) ) {
614 ExitFlag = 255;
615 eLog() << Verbose(0) << "Not enough or invalid arguments given for scaling: -s <factor_x> [factor_y] [factor_z]" << endl;
616 performCriticalExit();
617 } else {
618 SaveFlag = true;
619 j = -1;
620 Log() << Verbose(1) << "Scaling all ion positions by factor." << endl;
621 factor = new double[NDIM];
622 factor[0] = atof(argv[argptr]);
623 factor[1] = atof(argv[argptr+1]);
624 factor[2] = atof(argv[argptr+2]);
625 mol->Scale((const double ** const)&factor);
626 for (int i=0;i<NDIM;i++) {
627 j += i+1;
628 x.x[i] = atof(argv[NDIM+i]);
629 mol->cell_size[j]*=factor[i];
630 }
631 delete[](factor);
632 argptr+=3;
633 }
634 break;
635 case 'b':
636 if (ExitFlag == 0) ExitFlag = 1;
637 if ((argptr+5 >= argc) || (argv[argptr][0] == '-') || (!IsValidNumber(argv[argptr])) || (!IsValidNumber(argv[argptr+1])) || (!IsValidNumber(argv[argptr+2])) || (!IsValidNumber(argv[argptr+3])) || (!IsValidNumber(argv[argptr+4])) || (!IsValidNumber(argv[argptr+5])) ) {
638 ExitFlag = 255;
639 eLog() << Verbose(0) << "Not enough or invalid arguments given for centering in box: -b <xx> <xy> <xz> <yy> <yz> <zz>" << endl;
640 performCriticalExit();
641 } else {
642 SaveFlag = true;
643 j = -1;
644 Log() << Verbose(1) << "Centering atoms in config file within given simulation box." << endl;
645 for (int i=0;i<6;i++) {
646 mol->cell_size[i] = atof(argv[argptr+i]);
647 }
648 // center
649 mol->CenterInBox();
650 argptr+=6;
651 }
652 break;
653 case 'B':
654 if (ExitFlag == 0) ExitFlag = 1;
655 if ((argptr+5 >= argc) || (argv[argptr][0] == '-') || (!IsValidNumber(argv[argptr])) || (!IsValidNumber(argv[argptr+1])) || (!IsValidNumber(argv[argptr+2])) || (!IsValidNumber(argv[argptr+3])) || (!IsValidNumber(argv[argptr+4])) || (!IsValidNumber(argv[argptr+5])) ) {
656 ExitFlag = 255;
657 eLog() << Verbose(0) << "Not enough or invalid arguments given for bounding in box: -B <xx> <xy> <xz> <yy> <yz> <zz>" << endl;
658 performCriticalExit();
659 } else {
660 SaveFlag = true;
661 j = -1;
662 Log() << Verbose(1) << "Centering atoms in config file within given simulation box." << endl;
663 for (int i=0;i<6;i++) {
664 mol->cell_size[i] = atof(argv[argptr+i]);
665 }
666 // center
667 mol->BoundInBox();
668 argptr+=6;
669 }
670 break;
671 case 'c':
672 if (ExitFlag == 0) ExitFlag = 1;
673 if ((argptr+2 >= argc) || (argv[argptr][0] == '-') || (!IsValidNumber(argv[argptr])) || (!IsValidNumber(argv[argptr+1])) || (!IsValidNumber(argv[argptr+2])) ) {
674 ExitFlag = 255;
675 eLog() << Verbose(0) << "Not enough or invalid arguments given for centering with boundary: -c <boundary_x> <boundary_y> <boundary_z>" << endl;
676 performCriticalExit();
677 } else {
678 SaveFlag = true;
679 j = -1;
680 Log() << Verbose(1) << "Centering atoms in config file within given additional boundary." << endl;
681 // make every coordinate positive
682 mol->CenterEdge(&x);
683 // update Box of atoms by boundary
684 mol->SetBoxDimension(&x);
685 // translate each coordinate by boundary
686 j=-1;
687 for (int i=0;i<NDIM;i++) {
688 j += i+1;
689 x.x[i] = atof(argv[argptr+i]);
690 mol->cell_size[j] += x.x[i]*2.;
691 }
692 mol->Translate((const Vector *)&x);
693 argptr+=3;
694 }
695 break;
696 case 'O':
697 if (ExitFlag == 0) ExitFlag = 1;
698 SaveFlag = true;
699 Log() << Verbose(1) << "Centering atoms on edge and setting box dimensions." << endl;
700 x.Zero();
701 mol->CenterEdge(&x);
702 mol->SetBoxDimension(&x);
703 argptr+=0;
704 break;
705 case 'r':
706 if (ExitFlag == 0) ExitFlag = 1;
707 if ((argptr >= argc) || (argv[argptr][0] == '-') || (!IsValidNumber(argv[argptr]))) {
708 ExitFlag = 255;
709 eLog() << Verbose(0) << "Not enough or invalid arguments given for removing atoms: -r <id>" << endl;
710 performCriticalExit();
711 } else {
712 SaveFlag = true;
713 Log() << Verbose(1) << "Removing atom " << argv[argptr] << "." << endl;
714 atom *first = mol->FindAtom(atoi(argv[argptr]));
715 mol->RemoveAtom(first);
716 argptr+=1;
717 }
718 break;
719 case 'f':
720 if (ExitFlag == 0) ExitFlag = 1;
721 if ((argptr+1 >= argc) || (argv[argptr][0] == '-') || (!IsValidNumber(argv[argptr])) || (!IsValidNumber(argv[argptr+1]))) {
722 ExitFlag = 255;
723 eLog() << Verbose(0) << "Not enough or invalid arguments for fragmentation: -f <max. bond distance> <bond order>" << endl;
724 performCriticalExit();
725 } else {
726 Log() << Verbose(0) << "Fragmenting molecule with bond distance " << argv[argptr] << " angstroem, order of " << argv[argptr+1] << "." << endl;
727 Log() << Verbose(0) << "Creating connection matrix..." << endl;
728 start = clock();
729 mol->CreateAdjacencyList(atof(argv[argptr++]), configuration.GetIsAngstroem(), &BondGraph::CovalentMinMaxDistance, NULL);
730 Log() << Verbose(0) << "Fragmenting molecule with current connection matrix ..." << endl;
731 if (mol->first->next != mol->last) {
732 ExitFlag = mol->FragmentMolecule(atoi(argv[argptr]), &configuration);
733 }
734 end = clock();
735 Log() << Verbose(0) << "Clocks for this operation: " << (end-start) << ", time: " << ((double)(end-start)/CLOCKS_PER_SEC) << "s." << endl;
736 argptr+=2;
737 }
738 break;
739 case 'm':
740 if (ExitFlag == 0) ExitFlag = 1;
741 j = atoi(argv[argptr++]);
742 if ((j<0) || (j>1)) {
743 eLog() << Verbose(1) << "Argument of '-m' should be either 0 for no-rotate or 1 for rotate." << endl;
744 j = 0;
745 }
746 if (j) {
747 SaveFlag = true;
748 Log() << Verbose(0) << "Converting to prinicipal axis system." << endl;
749 } else
750 Log() << Verbose(0) << "Evaluating prinicipal axis." << endl;
751 mol->PrincipalAxisSystem((bool)j);
752 break;
753 case 'o':
754 if (ExitFlag == 0) ExitFlag = 1;
755 if ((argptr+1 >= argc) || (argv[argptr][0] == '-')){
756 ExitFlag = 255;
757 eLog() << Verbose(0) << "Not enough or invalid arguments given for convex envelope: -o <convex output file> <non-convex output file>" << endl;
758 performCriticalExit();
759 } else {
760 class Tesselation *TesselStruct = NULL;
761 const LinkedCell *LCList = NULL;
762 Log() << Verbose(0) << "Evaluating volume of the convex envelope.";
763 Log() << Verbose(1) << "Storing tecplot convex data in " << argv[argptr] << "." << endl;
764 Log() << Verbose(1) << "Storing tecplot non-convex data in " << argv[argptr+1] << "." << endl;
765 LCList = new LinkedCell(mol, 10.);
766 //FindConvexBorder(mol, LCList, argv[argptr]);
767 FindNonConvexBorder(mol, TesselStruct, LCList, 5., argv[argptr+1]);
768// RemoveAllBoundaryPoints(TesselStruct, mol, argv[argptr]);
769 double volumedifference = ConvexizeNonconvexEnvelope(TesselStruct, mol, argv[argptr]);
770 double clustervolume = VolumeOfConvexEnvelope(TesselStruct, &configuration);
771 Log() << Verbose(0) << "The tesselated volume area is " << clustervolume << " " << (configuration.GetIsAngstroem() ? "angstrom" : "atomiclength") << "^3." << endl;
772 Log() << Verbose(0) << "The non-convex tesselated volume area is " << clustervolume-volumedifference << " " << (configuration.GetIsAngstroem() ? "angstrom" : "atomiclength") << "^3." << endl;
773 delete(TesselStruct);
774 delete(LCList);
775 argptr+=2;
776 }
777 break;
778 case 'U':
779 if (ExitFlag == 0) ExitFlag = 1;
780 if ((argptr+1 >= argc) || (argv[argptr][0] == '-') || (!IsValidNumber(argv[argptr])) || (!IsValidNumber(argv[argptr+1])) ) {
781 ExitFlag = 255;
782 eLog() << Verbose(0) << "Not enough or invalid arguments given for suspension with specified volume: -U <volume> <density>" << endl;
783 performCriticalExit();
784 } else {
785 volume = atof(argv[argptr++]);
786 Log() << Verbose(0) << "Using " << volume << " angstrom^3 as the volume instead of convex envelope one's." << endl;
787 }
788 case 'u':
789 if (ExitFlag == 0) ExitFlag = 1;
790 if ((argptr >= argc) || (argv[argptr][0] == '-') || (!IsValidNumber(argv[argptr])) ) {
791 if (volume != -1)
792 ExitFlag = 255;
793 eLog() << Verbose(0) << "Not enough arguments given for suspension: -u <density>" << endl;
794 performCriticalExit();
795 } else {
796 double density;
797 SaveFlag = true;
798 Log() << Verbose(0) << "Evaluating necessary cell volume for a cluster suspended in water.";
799 density = atof(argv[argptr++]);
800 if (density < 1.0) {
801 eLog() << Verbose(1) << "Density must be greater than 1.0g/cm^3 !" << endl;
802 density = 1.3;
803 }
804// for(int i=0;i<NDIM;i++) {
805// repetition[i] = atoi(argv[argptr++]);
806// if (repetition[i] < 1)
807// eLog() << Verbose(1) << "repetition value must be greater 1!" << endl;
808// repetition[i] = 1;
809// }
810 PrepareClustersinWater(&configuration, mol, volume, density); // if volume == 0, will calculate from ConvexEnvelope
811 }
812 break;
813 case 'd':
814 if (ExitFlag == 0) ExitFlag = 1;
815 if ((argptr+2 >= argc) || (argv[argptr][0] == '-') || (!IsValidNumber(argv[argptr])) || (!IsValidNumber(argv[argptr+1])) || (!IsValidNumber(argv[argptr+2])) ) {
816 ExitFlag = 255;
817 eLog() << Verbose(0) << "Not enough or invalid arguments given for repeating cells: -d <repeat_x> <repeat_y> <repeat_z>" << endl;
818 performCriticalExit();
819 } else {
820 SaveFlag = true;
821 for (int axis = 1; axis <= NDIM; axis++) {
822 int faktor = atoi(argv[argptr++]);
823 int count;
824 element ** Elements;
825 Vector ** vectors;
826 if (faktor < 1) {
827 eLog() << Verbose(1) << "Repetition factor mus be greater than 1!" << endl;
828 faktor = 1;
829 }
830 mol->CountAtoms(); // recount atoms
831 if (mol->AtomCount != 0) { // if there is more than none
832 count = mol->AtomCount; // is changed becausing of adding, thus has to be stored away beforehand
833 Elements = new element *[count];
834 vectors = new Vector *[count];
835 j = 0;
836 first = mol->start;
837 while (first->next != mol->end) { // make a list of all atoms with coordinates and element
838 first = first->next;
839 Elements[j] = first->type;
840 vectors[j] = &first->x;
841 j++;
842 }
843 if (count != j)
844 eLog() << Verbose(1) << "AtomCount " << count << " is not equal to number of atoms in molecule " << j << "!" << endl;
845 x.Zero();
846 y.Zero();
847 y.x[abs(axis)-1] = mol->cell_size[(abs(axis) == 2) ? 2 : ((abs(axis) == 3) ? 5 : 0)] * abs(axis)/axis; // last term is for sign, first is for magnitude
848 for (int i=1;i<faktor;i++) { // then add this list with respective translation factor times
849 x.AddVector(&y); // per factor one cell width further
850 for (int k=count;k--;) { // go through every atom of the original cell
851 first = new atom(); // create a new body
852 first->x.CopyVector(vectors[k]); // use coordinate of original atom
853 first->x.AddVector(&x); // translate the coordinates
854 first->type = Elements[k]; // insert original element
855 mol->AddAtom(first); // and add to the molecule (which increments ElementsInMolecule, AtomCount, ...)
856 }
857 }
858 // free memory
859 delete[](Elements);
860 delete[](vectors);
861 // correct cell size
862 if (axis < 0) { // if sign was negative, we have to translate everything
863 x.Zero();
864 x.AddVector(&y);
865 x.Scale(-(faktor-1));
866 mol->Translate(&x);
867 }
868 mol->cell_size[(abs(axis) == 2) ? 2 : ((abs(axis) == 3) ? 5 : 0)] *= faktor;
869 }
870 }
871 }
872 break;
873 default: // no match? Step on
874 if ((argptr < argc) && (argv[argptr][0] != '-')) // if it started with a '-' we've already made a step!
875 argptr++;
876 break;
877 }
878 }
879 } else argptr++;
880 } while (argptr < argc);
881 if (SaveFlag)
882 configuration.SaveAll(ConfigFileName, periode, molecules);
883 } else { // no arguments, hence scan the elements db
884 if (periode->LoadPeriodentafel(configuration.databasepath))
885 Log() << Verbose(0) << "Element list loaded successfully." << endl;
886 else
887 Log() << Verbose(0) << "Element list loading failed." << endl;
888 configuration.RetrieveConfigPathAndName("main_pcp_linux");
889 }
890 return(ExitFlag);
891};
892
893/********************************************** Main routine **************************************/
894
895int main(int argc, char **argv)
896{
897 periodentafel *periode = new periodentafel;
898 MoleculeListClass *molecules = new MoleculeListClass;
899 molecule *mol = NULL;
900 config *configuration = new config;
901 Vector x, y, z, n;
902 ifstream test;
903 ofstream output;
904 string line;
905 char *ConfigFileName = NULL;
906 int j;
907 setVerbosity(0);
908 /* structure of ParseCommandLineOptions will be refactored later */
909 j = ParseCommandLineOptions(argc, argv, molecules, periode, *configuration, ConfigFileName);
910 switch (j){
911 case 255:
912 case 2:
913 case 1:
914 delete (molecules);
915 delete (periode);
916 delete (configuration);
917 Log() << Verbose(0) << "Maximum of allocated memory: " << MemoryUsageObserver::getInstance()->getMaximumUsedMemory() << endl;
918 Log() << Verbose(0) << "Remaining non-freed memory: " << MemoryUsageObserver::getInstance()->getUsedMemorySize() << endl;
919 MemoryUsageObserver::getInstance()->purgeInstance();
920 logger::purgeInstance();
921 errorLogger::purgeInstance();
922 return (j == 1 ? 0 : j);
923 default:
924 break;
925 }
926 if(molecules->ListOfMolecules.size() == 0){
927 mol = new molecule(periode);
928 if(mol->cell_size[0] == 0.){
929 Log() << Verbose(0) << "enter lower tridiagonal form of basis matrix" << endl << endl;
930 for(int i = 0;i < 6;i++){
931 Log() << Verbose(1) << "Cell size" << i << ": ";
932 cin >> mol->cell_size[i];
933 }
934 }
935
936 mol->ActiveFlag = true;
937 molecules->insert(mol);
938 }
939
940
941 UIFactory::makeUserInterface(UIFactory::Text);
942 MainWindow *mainWindow = UIFactory::get()->makeMainWindow();
943 mainWindow->display(molecules, configuration, periode, ConfigFileName);
944
945 if(periode->StorePeriodentafel(configuration->databasepath))
946 Log() << Verbose(0) << "Saving of elements.db successful." << endl;
947
948 else
949 Log() << Verbose(0) << "Saving of elements.db failed." << endl;
950
951 delete (molecules);
952 delete(periode);
953 delete(configuration);
954
955 delete mainWindow;
956
957 Log() << Verbose(0) << "Maximum of allocated memory: "
958 << MemoryUsageObserver::getInstance()->getMaximumUsedMemory() << endl;
959 Log() << Verbose(0) << "Remaining non-freed memory: "
960 << MemoryUsageObserver::getInstance()->getUsedMemorySize() << endl;
961 MemoryUsageObserver::purgeInstance();
962 logger::purgeInstance();
963 errorLogger::purgeInstance();
964 UIFactory::purgeInstance();
965 return (0);
966}
967
968/********************************************** E N D **************************************************/
Note: See TracBrowser for help on using the repository browser.