source: src/builder.cpp@ 65b6e0

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

Added basic menu and action framework

  • Added action base class
  • Added class to make actions from methods
  • Added Menu base class
  • Added TextMenu class to produce text menus
  • Added MenuItem base class for menu items
  • Added ActionMenuItem for menu items using an action
  • Added SubMenuItem class for menu items presenting a submenu
  • Added SeperatorItem class for menu seperators without functioninality

Signed-off-by: Tillmann Crueger <crueger@…>

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