source: molecuilder/src/builder.cpp@ 45ff42

Last change on this file since 45ff42 was d20ed5, checked in by Frederik Heber <heber@…>, 16 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
RevLine 
[a0bcf1]1/** \file builder.cpp
[db177a]2 *
[a0bcf1]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
[db177a]8 *
[a0bcf1]9 */
10
11/*! \mainpage Molecuilder - a molecular set builder
[db177a]12 *
[a0bcf1]13 * This introductory shall briefly make aquainted with the program, helping in installing and a first run.
[db177a]14 *
[a0bcf1]15 * \section about About the Program
[db177a]16 *
[a048fa]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.
[db177a]20 *
[a048fa]21 * A configuration file may be written that is compatible to the format used by PCP - a parallel Car-Parrinello
22 * molecular dynamics implementation.
[db177a]23 *
[a0bcf1]24 * \section install Installation
[db177a]25 *
[a048fa]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
[db177a]30 *
[a048fa]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
[db177a]34 *
[a0bcf1]35 * \section run Running
[db177a]36 *
[a048fa]37 * The program can be executed by running: ./molecuilder
[db177a]38 *
[a048fa]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.
[db177a]42 *
[a0bcf1]43 * \section ref References
[db177a]44 *
[a048fa]45 * For the special configuration file format, see the documentation of pcp.
[db177a]46 *
[a0bcf1]47 */
48
49
50using namespace std;
51
[746bb4]52#include "analysis_correlation.hpp"
[17b3a5c]53#include "atom.hpp"
54#include "bond.hpp"
[5f697c]55#include "bondgraph.hpp"
[e08f45]56#include "boundary.hpp"
[17b3a5c]57#include "config.hpp"
58#include "element.hpp"
[e08f45]59#include "ellipsoid.hpp"
[a0bcf1]60#include "helpers.hpp"
[17b3a5c]61#include "leastsquaremin.hpp"
62#include "linkedcell.hpp"
[543ce4]63#include "log.hpp"
[39d983]64#include "memoryusageobserverunittest.hpp"
[f92d00]65#include "molecule.hpp"
[17b3a5c]66#include "periodentafel.hpp"
[7df43b]67#include "menu.hpp"
[8129de]68
[3ce105]69/** Parses the command line options.
70 * \param argc argument count
71 * \param **argv arguments array
[c830e8e]72 * \param *molecules list of molecules structure
[3ce105]73 * \param *periode elements structure
74 * \param configuration config file structure
75 * \param *ConfigFileName pointer to config file name in **argv
[8b486e]76 * \param *PathToDatabases pointer to db's path in **argv
[3ce105]77 * \return exit code (0 - successful, all else - something's wrong)
78 */
[7df43b]79static int ParseCommandLineOptions(int argc, char **argv, MoleculeListClass *&molecules, periodentafel *&periode,\
[d20ed5]80 config& configuration, char *&ConfigFileName, oldmenu *main_menu)
[a0bcf1]81{
[a048fa]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.;
[48cd93]92 enum ConfigStatus configPresent = absent;
[a048fa]93 clock_t start,end;
94 int argptr;
[a0fb02]95 molecule *mol = NULL;
[b84ab4]96 string BondGraphFileName("");
[418117a]97 int verbosity = 0;
[bd86e8]98 strncpy(configuration.databasepath, LocalPath, MAXSTRINGSIZE-1);
[e08f45]99
[a048fa]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] == '-') {
[543ce4]105 Log() << Verbose(0) << "Recognized command line argument: " << argv[argptr][1] << ".\n";
[a048fa]106 argptr++;
107 switch(argv[argptr-1][1]) {
108 case 'h':
109 case 'H':
110 case '?':
[543ce4]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;
[418117a]143 Log() << Verbose(0) << "\t-v\t\tsets verbosity (more is more)." << endl;
144 Log() << Verbose(0) << "\t-V\t\tGives version information." << endl;
[543ce4]145 Log() << Verbose(0) << "Note: config files must not begin with '-' !" << endl;
[a048fa]146 return (1);
147 break;
148 case 'v':
[418117a]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;
[a048fa]155 case 'V':
[543ce4]156 Log() << Verbose(0) << argv[0] << " " << VERSIONSTRING << endl;
157 Log() << Verbose(0) << "Build your own molecule position set." << endl;
[a048fa]158 return (1);
159 break;
160 case 'e':
161 if ((argptr >= argc) || (argv[argptr][0] == '-')) {
[543ce4]162 eLog() << Verbose(0) << "Not enough or invalid arguments for specifying element db: -e <db file>" << endl;
[3d4969]163 performCriticalExit();
[a048fa]164 } else {
[543ce4]165 Log() << Verbose(0) << "Using " << argv[argptr] << " as elements database." << endl;
[a048fa]166 strncpy (configuration.databasepath, argv[argptr], MAXSTRINGSIZE-1);
167 argptr+=1;
168 }
169 break;
[b84ab4]170 case 'g':
171 if ((argptr >= argc) || (argv[argptr][0] == '-')) {
[543ce4]172 eLog() << Verbose(0) << "Not enough or invalid arguments for specifying bond length table: -g <table file>" << endl;
[3d4969]173 performCriticalExit();
[b84ab4]174 } else {
175 BondGraphFileName = argv[argptr];
[543ce4]176 Log() << Verbose(0) << "Using " << BondGraphFileName << " as bond length table." << endl;
[b84ab4]177 argptr+=1;
178 }
179 break;
[a048fa]180 case 'n':
[543ce4]181 Log() << Verbose(0) << "I won't parse trajectories." << endl;
[a048fa]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
[b84ab4]192 // 3a. Parse the element database
[a048fa]193 if (periode->LoadPeriodentafel(configuration.databasepath)) {
[543ce4]194 Log() << Verbose(0) << "Element list loaded successfully." << endl;
195 //periode->Output();
[a048fa]196 } else {
[543ce4]197 Log() << Verbose(0) << "Element list loading failed." << endl;
[a048fa]198 return 1;
199 }
[245826]200 // 3b. Find config file name and parse if possible, also BondGraphFileName
[a048fa]201 if (argv[1][0] != '-') {
[a0fb02]202 // simply create a new molecule, wherein the config file is loaded and the manipulation takes place
[543ce4]203 Log() << Verbose(0) << "Config file given." << endl;
[a048fa]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) {
[543ce4]209 Log() << Verbose(1) << "Specified config file " << argv[1] << " not found." << endl;
[48cd93]210 configPresent = absent;
[a048fa]211 } else {
[543ce4]212 Log() << Verbose(0) << "Empty configuration file." << endl;
[a048fa]213 ConfigFileName = argv[1];
[48cd93]214 configPresent = empty;
[a048fa]215 output.close();
216 }
217 } else {
218 test.close();
219 ConfigFileName = argv[1];
[543ce4]220 Log() << Verbose(1) << "Specified config file found, parsing ... ";
[df0520]221 switch (configuration.TestSyntax(ConfigFileName, periode)) {
[a048fa]222 case 1:
[543ce4]223 Log() << Verbose(0) << "new syntax." << endl;
[df0520]224 configuration.Load(ConfigFileName, BondGraphFileName, periode, molecules);
[48cd93]225 configPresent = present;
[a048fa]226 break;
227 case 0:
[543ce4]228 Log() << Verbose(0) << "old syntax." << endl;
[df0520]229 configuration.LoadOld(ConfigFileName, BondGraphFileName, periode, molecules);
[48cd93]230 configPresent = present;
[a048fa]231 break;
232 default:
[543ce4]233 Log() << Verbose(0) << "Unknown syntax or empty, yet present file." << endl;
[48cd93]234 configPresent = empty;
[a048fa]235 }
236 }
237 } else
[48cd93]238 configPresent = absent;
[df0520]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
[a048fa]253 // 4. parse again through options, now for those depending on elements db and config presence
254 argptr = 1;
255 do {
[543ce4]256 Log() << Verbose(0) << "Current Command line argument: " << argv[argptr] << "." << endl;
[a048fa]257 if (argv[argptr][0] == '-') {
258 argptr++;
[48cd93]259 if ((configPresent == present) || (configPresent == empty)) {
[a048fa]260 switch(argv[argptr-1][1]) {
261 case 'p':
[a4644b]262 if (ExitFlag == 0) ExitFlag = 1;
[a048fa]263 if ((argptr >= argc) || (argv[argptr][0] == '-')) {
264 ExitFlag = 255;
[543ce4]265 eLog() << Verbose(0) << "Not enough arguments for parsing: -p <xyz file>" << endl;
[3d4969]266 performCriticalExit();
[a048fa]267 } else {
268 SaveFlag = true;
[543ce4]269 Log() << Verbose(1) << "Parsing xyz file for new atoms." << endl;
[a048fa]270 if (!mol->AddXYZFile(argv[argptr]))
[543ce4]271 Log() << Verbose(2) << "File not found." << endl;
[a048fa]272 else {
[543ce4]273 Log() << Verbose(2) << "File found and parsed." << endl;
[48cd93]274 configPresent = present;
[a048fa]275 }
276 }
277 break;
278 case 'a':
[a4644b]279 if (ExitFlag == 0) ExitFlag = 1;
[d70bf6]280 if ((argptr >= argc) || (argv[argptr][0] == '-') || (!IsValidNumber(argv[argptr+1])) || (!IsValidNumber(argv[argptr+2])) || (!IsValidNumber(argv[argptr+3]))) {
[a048fa]281 ExitFlag = 255;
[543ce4]282 eLog() << Verbose(0) << "Not enough or invalid arguments for adding atom: -a <element> <x> <y> <z>" << endl;
[3d4969]283 performCriticalExit();
[a048fa]284 } else {
285 SaveFlag = true;
[543ce4]286 Log() << Verbose(1) << "Adding new atom with element " << argv[argptr] << " at (" << argv[argptr+1] << "," << argv[argptr+2] << "," << argv[argptr+3] << "), ";
[a048fa]287 first = new atom;
288 first->type = periode->FindElement(atoi(argv[argptr]));
289 if (first->type != NULL)
[543ce4]290 Log() << Verbose(2) << "found element " << first->type->name << endl;
[a048fa]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
[48cd93]295 if ((configPresent == empty) && (mol->AtomCount != 0))
296 configPresent = present;
[a048fa]297 } else
[543ce4]298 eLog() << Verbose(1) << "Could not find the specified element." << endl;
[a048fa]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 }
[48cd93]306 if (configPresent == present) {
[a048fa]307 switch(argv[argptr-1][1]) {
[0fc0b5]308 case 'M':
[a048fa]309 if ((argptr >= argc) || (argv[argptr][0] == '-')) {
310 ExitFlag = 255;
[543ce4]311 eLog() << Verbose(0) << "Not enough or invalid arguments given for setting MPQC basis: -B <basis name>" << endl;
[3d4969]312 performCriticalExit();
[a048fa]313 } else {
314 configuration.basis = argv[argptr];
[543ce4]315 Log() << Verbose(1) << "Setting MPQC basis to " << configuration.basis << "." << endl;
[a048fa]316 argptr+=1;
317 }
318 break;
319 case 'D':
[a4644b]320 if (ExitFlag == 0) ExitFlag = 1;
[a048fa]321 {
[543ce4]322 Log() << Verbose(1) << "Depth-First-Search Analysis." << endl;
[a048fa]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;
[543ce4]328 mol->CreateAdjacencyList(atof(argv[argptr]), configuration.GetIsAngstroem(), &BondGraph::CovalentMinMaxDistance, NULL);
329 Subgraphs = mol->DepthFirstSearchAnalysis(BackEdgeStack);
[a048fa]330 if (Subgraphs != NULL) {
[8bc524]331 int FragmentCounter = 0;
[a048fa]332 while (Subgraphs->next != NULL) {
333 Subgraphs = Subgraphs->next;
[543ce4]334 Subgraphs->FillBondStructureFromReference(mol, FragmentCounter, ListOfLocalAtoms, false); // we want to keep the created ListOfLocalAtoms
[a048fa]335 LocalBackEdgeStack = new StackClass<bond *> (Subgraphs->Leaf->BondCount);
[543ce4]336 Subgraphs->Leaf->PickLocalBackEdges(ListOfLocalAtoms[FragmentCounter], BackEdgeStack, LocalBackEdgeStack);
337 Subgraphs->Leaf->CyclicStructureAnalysis(LocalBackEdgeStack, MinimumRingSize);
[a048fa]338 delete(LocalBackEdgeStack);
339 delete(Subgraphs->previous);
[8bc524]340 FragmentCounter++;
[a048fa]341 }
342 delete(Subgraphs);
343 for (int i=0;i<FragmentCounter;i++)
[8bc524]344 Free(&ListOfLocalAtoms[i]);
[39d983]345 Free(&ListOfLocalAtoms);
[a048fa]346 }
347 delete(BackEdgeStack);
348 delete[](MinimumRingSize);
349 }
350 //argptr+=1;
351 break;
[746bb4]352 case 'C':
353 if (ExitFlag == 0) ExitFlag = 1;
[a3ffb44]354 if ((argptr+2 >= argc) || (!IsValidNumber(argv[argptr])) || (argv[argptr][0] == '-') || (argv[argptr+1][0] == '-') || (argv[argptr+2][0] == '-')) {
[746bb4]355 ExitFlag = 255;
[543ce4]356 eLog() << Verbose(0) << "Not enough or invalid arguments given for pair correlation analysis: -C <Z> <output> <bin output>" << endl;
[3d4969]357 performCriticalExit();
[746bb4]358 } else {
359 SaveFlag = false;
[d70bf6]360 ofstream output(argv[argptr+1]);
361 ofstream binoutput(argv[argptr+2]);
[746bb4]362 const double radius = 5.;
[d70bf6]363
364 // get the boundary
[a3ffb44]365 class molecule *Boundary = NULL;
[a9b2a0a]366 class Tesselation *TesselStruct = NULL;
367 const LinkedCell *LCList = NULL;
[a3ffb44]368 // find biggest molecule
[e1900f]369 int counter = 0;
[a3ffb44]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 }
[e1900f]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;
[a3ffb44]381 }
[a9b2a0a]382 LCList = new LinkedCell(Boundary, 2.*radius);
[a3ffb44]383 element *elemental = periode->FindElement((const int) atoi(argv[argptr]));
[543ce4]384 FindNonConvexBorder(Boundary, TesselStruct, LCList, radius, NULL);
[5f1d021]385 int ranges[NDIM] = {1,1,1};
[543ce4]386 CorrelationToSurfaceMap *surfacemap = PeriodicCorrelationToSurface( molecules, elemental, TesselStruct, LCList, ranges );
387 BinPairMap *binmap = BinData( surfacemap, 0.5, 0., 0. );
[746bb4]388 OutputCorrelation ( &binoutput, binmap );
389 output.close();
390 binoutput.close();
[e1900f]391 for (MoleculeList::iterator BigFinder = molecules->ListOfMolecules.begin(); BigFinder != molecules->ListOfMolecules.end(); BigFinder++)
392 (*BigFinder)->ActiveFlag = Actives[counter];
393 Free(&Actives);
[a9b2a0a]394 delete(LCList);
395 delete(TesselStruct);
[d70bf6]396 argptr+=3;
[746bb4]397 }
398 break;
[a048fa]399 case 'E':
[a4644b]400 if (ExitFlag == 0) ExitFlag = 1;
[a048fa]401 if ((argptr+1 >= argc) || (!IsValidNumber(argv[argptr])) || (argv[argptr+1][0] == '-')) {
402 ExitFlag = 255;
[543ce4]403 eLog() << Verbose(0) << "Not enough or invalid arguments given for changing element: -E <atom nr.> <element>" << endl;
[3d4969]404 performCriticalExit();
[a048fa]405 } else {
406 SaveFlag = true;
[543ce4]407 Log() << Verbose(1) << "Changing atom " << argv[argptr] << " to element " << argv[argptr+1] << "." << endl;
[a048fa]408 first = mol->FindAtom(atoi(argv[argptr]));
409 first->type = periode->FindElement(atoi(argv[argptr+1]));
410 argptr+=2;
411 }
412 break;
[d93bb24]413 case 'F':
[a4644b]414 if (ExitFlag == 0) ExitFlag = 1;
[d93bb24]415 if (argptr+5 >=argc) {
416 ExitFlag = 255;
[543ce4]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;
[3d4969]418 performCriticalExit();
[d93bb24]419 } else {
420 SaveFlag = true;
[543ce4]421 Log() << Verbose(1) << "Filling Box with water molecules." << endl;
[d93bb24]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]);
[543ce4]444 Filling = FillBoxWithMolecule(molecules, filler, configuration, distance, atof(argv[argptr+3]), atof(argv[argptr+4]), atoi(argv[argptr+5]));
[d93bb24]445 if (Filling != NULL) {
446 molecules->insert(Filling);
447 }
448 delete(filler);
449 argptr+=6;
450 }
451 break;
[a048fa]452 case 'A':
[a4644b]453 if (ExitFlag == 0) ExitFlag = 1;
[a048fa]454 if ((argptr >= argc) || (argv[argptr][0] == '-')) {
455 ExitFlag =255;
[543ce4]456 eLog() << Verbose(0) << "Missing source file for bonds in molecule: -A <bond sourcefile>" << endl;
[3d4969]457 performCriticalExit();
[a048fa]458 } else {
[543ce4]459 Log() << Verbose(0) << "Parsing bonds from " << argv[argptr] << "." << endl;
[a048fa]460 ifstream *input = new ifstream(argv[argptr]);
[543ce4]461 mol->CreateAdjacencyListFromDbondFile(input);
[a048fa]462 input->close();
463 argptr+=1;
464 }
465 break;
466 case 'N':
[a4644b]467 if (ExitFlag == 0) ExitFlag = 1;
[a048fa]468 if ((argptr+1 >= argc) || (argv[argptr+1][0] == '-')){
469 ExitFlag = 255;
[543ce4]470 eLog() << Verbose(0) << "Not enough or invalid arguments given for non-convex envelope: -o <radius> <tecplot output file>" << endl;
[3d4969]471 performCriticalExit();
[a048fa]472 } else {
[a9b2a0a]473 class Tesselation *T = NULL;
474 const LinkedCell *LCList = NULL;
[2fbbc96]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.";
[543ce4]479 Log() << Verbose(1) << "Using rolling ball of radius " << atof(argv[argptr]) << " and storing tecplot data in " << argv[argptr+1] << "." << endl;
[2fbbc96]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;
[606dfb]490 start = clock();
[2fbbc96]491 LCList = new LinkedCell(Boundary, atof(argv[argptr])*2.);
492 FindNonConvexBorder(Boundary, T, LCList, atof(argv[argptr]), argv[argptr+1]);
[543ce4]493 //FindDistributionOfEllipsoids(T, &LCList, N, number, filename.c_str());
[606dfb]494 end = clock();
[543ce4]495 Log() << Verbose(0) << "Clocks for this operation: " << (end-start) << ", time: " << ((double)(end-start)/CLOCKS_PER_SEC) << "s." << endl;
[a9b2a0a]496 delete(LCList);
[a048fa]497 argptr+=2;
498 }
499 break;
500 case 'S':
[a4644b]501 if (ExitFlag == 0) ExitFlag = 1;
[a048fa]502 if ((argptr >= argc) || (argv[argptr][0] == '-')) {
503 ExitFlag = 255;
[543ce4]504 eLog() << Verbose(0) << "Not enough or invalid arguments given for storing tempature: -S <temperature file>" << endl;
[3d4969]505 performCriticalExit();
[a048fa]506 } else {
[543ce4]507 Log() << Verbose(1) << "Storing temperatures in " << argv[argptr] << "." << endl;
[a048fa]508 ofstream *output = new ofstream(argv[argptr], ios::trunc);
[543ce4]509 if (!mol->OutputTemperatureFromTrajectories(output, 0, mol->MDSteps))
510 Log() << Verbose(2) << "File could not be written." << endl;
[a048fa]511 else
[543ce4]512 Log() << Verbose(2) << "File stored." << endl;
[a048fa]513 output->close();
514 delete(output);
515 argptr+=1;
516 }
517 break;
[63b5c31]518 case 'L':
[a4644b]519 if (ExitFlag == 0) ExitFlag = 1;
[606dfb]520 if ((argptr >= argc) || (argv[argptr][0] == '-')) {
521 ExitFlag = 255;
[543ce4]522 eLog() << Verbose(0) << "Not enough or invalid arguments given for storing tempature: -L <step0> <step1> <prefix> <identity mapping?>" << endl;
[3d4969]523 performCriticalExit();
[606dfb]524 } else {
525 SaveFlag = true;
[543ce4]526 Log() << Verbose(1) << "Linear interpolation between configuration " << argv[argptr] << " and " << argv[argptr+1] << "." << endl;
[606dfb]527 if (atoi(argv[argptr+3]) == 1)
[543ce4]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;
[606dfb]531 else
[543ce4]532 Log() << Verbose(2) << "Steps created and " << argv[argptr+2] << " files stored." << endl;
[606dfb]533 argptr+=4;
534 }
[63b5c31]535 break;
[a048fa]536 case 'P':
[a4644b]537 if (ExitFlag == 0) ExitFlag = 1;
[a048fa]538 if ((argptr >= argc) || (argv[argptr][0] == '-')) {
539 ExitFlag = 255;
[543ce4]540 eLog() << Verbose(0) << "Not enough or invalid arguments given for parsing and integrating forces: -P <forces file>" << endl;
[3d4969]541 performCriticalExit();
[a048fa]542 } else {
543 SaveFlag = true;
[543ce4]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;
[a048fa]547 else
[543ce4]548 Log() << Verbose(2) << "File found and parsed." << endl;
[a048fa]549 argptr+=1;
550 }
551 break;
[ea9696]552 case 'R':
[a4644b]553 if (ExitFlag == 0) ExitFlag = 1;
554 if ((argptr+1 >= argc) || (argv[argptr][0] == '-') || (!IsValidNumber(argv[argptr])) || (!IsValidNumber(argv[argptr+1]))) {
[ea9696]555 ExitFlag = 255;
[543ce4]556 eLog() << Verbose(0) << "Not enough or invalid arguments given for removing atoms: -R <id> <distance>" << endl;
[3d4969]557 performCriticalExit();
[ea9696]558 } else {
559 SaveFlag = true;
[543ce4]560 Log() << Verbose(1) << "Removing atoms around " << argv[argptr] << " with radius " << argv[argptr+1] << "." << endl;
[ea9696]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 {
[418117a]573 eLog() << Verbose(1) << "Removal failed due to missing atoms on molecule or wrong id." << endl;
[ea9696]574 }
575 argptr+=2;
576 }
577 break;
[a048fa]578 case 't':
[a4644b]579 if (ExitFlag == 0) ExitFlag = 1;
[d70bf6]580 if ((argptr+2 >= argc) || (!IsValidNumber(argv[argptr])) || (!IsValidNumber(argv[argptr+1])) || (!IsValidNumber(argv[argptr+2])) ) {
[a048fa]581 ExitFlag = 255;
[543ce4]582 eLog() << Verbose(0) << "Not enough or invalid arguments given for translation: -t <x> <y> <z>" << endl;
[3d4969]583 performCriticalExit();
[a048fa]584 } else {
[a4644b]585 if (ExitFlag == 0) ExitFlag = 1;
[a048fa]586 SaveFlag = true;
[543ce4]587 Log() << Verbose(1) << "Translating all ions by given vector." << endl;
[a048fa]588 for (int i=NDIM;i--;)
589 x.x[i] = atof(argv[argptr+i]);
590 mol->Translate((const Vector *)&x);
591 argptr+=3;
592 }
[606dfb]593 break;
[6fb785]594 case 'T':
[a4644b]595 if (ExitFlag == 0) ExitFlag = 1;
[d70bf6]596 if ((argptr+2 >= argc) || (!IsValidNumber(argv[argptr])) || (!IsValidNumber(argv[argptr+1])) || (!IsValidNumber(argv[argptr+2])) ) {
[6fb785]597 ExitFlag = 255;
[543ce4]598 eLog() << Verbose(0) << "Not enough or invalid arguments given for periodic translation: -T <x> <y> <z>" << endl;
[3d4969]599 performCriticalExit();
[6fb785]600 } else {
[a4644b]601 if (ExitFlag == 0) ExitFlag = 1;
[6fb785]602 SaveFlag = true;
[543ce4]603 Log() << Verbose(1) << "Translating all ions periodically by given vector." << endl;
[6fb785]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;
[a048fa]610 case 's':
[a4644b]611 if (ExitFlag == 0) ExitFlag = 1;
[d70bf6]612 if ((argptr >= argc) || (!IsValidNumber(argv[argptr])) || (!IsValidNumber(argv[argptr+1])) || (!IsValidNumber(argv[argptr+2])) ) {
[a048fa]613 ExitFlag = 255;
[543ce4]614 eLog() << Verbose(0) << "Not enough or invalid arguments given for scaling: -s <factor_x> [factor_y] [factor_z]" << endl;
[3d4969]615 performCriticalExit();
[a048fa]616 } else {
617 SaveFlag = true;
618 j = -1;
[543ce4]619 Log() << Verbose(1) << "Scaling all ion positions by factor." << endl;
[a048fa]620 factor = new double[NDIM];
621 factor[0] = atof(argv[argptr]);
[d70bf6]622 factor[1] = atof(argv[argptr+1]);
623 factor[2] = atof(argv[argptr+2]);
[a9b2a0a]624 mol->Scale((const double ** const)&factor);
[a048fa]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);
[d70bf6]631 argptr+=3;
[a048fa]632 }
633 break;
634 case 'b':
[a4644b]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])) ) {
[a048fa]637 ExitFlag = 255;
[543ce4]638 eLog() << Verbose(0) << "Not enough or invalid arguments given for centering in box: -b <xx> <xy> <xz> <yy> <yz> <zz>" << endl;
[3d4969]639 performCriticalExit();
[a048fa]640 } else {
641 SaveFlag = true;
[136e89]642 j = -1;
[543ce4]643 Log() << Verbose(1) << "Centering atoms in config file within given simulation box." << endl;
[a048fa]644 for (int i=0;i<6;i++) {
645 mol->cell_size[i] = atof(argv[argptr+i]);
646 }
647 // center
[543ce4]648 mol->CenterInBox();
[6fb785]649 argptr+=6;
[a048fa]650 }
651 break;
[0fc0b5]652 case 'B':
[a4644b]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])) ) {
[0fc0b5]655 ExitFlag = 255;
[543ce4]656 eLog() << Verbose(0) << "Not enough or invalid arguments given for bounding in box: -B <xx> <xy> <xz> <yy> <yz> <zz>" << endl;
[3d4969]657 performCriticalExit();
[0fc0b5]658 } else {
659 SaveFlag = true;
660 j = -1;
[543ce4]661 Log() << Verbose(1) << "Centering atoms in config file within given simulation box." << endl;
[0fc0b5]662 for (int i=0;i<6;i++) {
663 mol->cell_size[i] = atof(argv[argptr+i]);
664 }
665 // center
[543ce4]666 mol->BoundInBox();
[0fc0b5]667 argptr+=6;
668 }
669 break;
[a048fa]670 case 'c':
[a4644b]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])) ) {
[a048fa]673 ExitFlag = 255;
[543ce4]674 eLog() << Verbose(0) << "Not enough or invalid arguments given for centering with boundary: -c <boundary_x> <boundary_y> <boundary_z>" << endl;
[3d4969]675 performCriticalExit();
[a048fa]676 } else {
677 SaveFlag = true;
678 j = -1;
[543ce4]679 Log() << Verbose(1) << "Centering atoms in config file within given additional boundary." << endl;
[a048fa]680 // make every coordinate positive
[543ce4]681 mol->CenterEdge(&x);
[a048fa]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;
[c3a303]688 x.x[i] = atof(argv[argptr+i]);
[a048fa]689 mol->cell_size[j] += x.x[i]*2.;
690 }
691 mol->Translate((const Vector *)&x);
[6fb785]692 argptr+=3;
[a048fa]693 }
694 break;
695 case 'O':
[a4644b]696 if (ExitFlag == 0) ExitFlag = 1;
[a048fa]697 SaveFlag = true;
[543ce4]698 Log() << Verbose(1) << "Centering atoms on edge and setting box dimensions." << endl;
[c3a303]699 x.Zero();
[543ce4]700 mol->CenterEdge(&x);
[a048fa]701 mol->SetBoxDimension(&x);
[6fb785]702 argptr+=0;
[a048fa]703 break;
704 case 'r':
[a4644b]705 if (ExitFlag == 0) ExitFlag = 1;
706 if ((argptr >= argc) || (argv[argptr][0] == '-') || (!IsValidNumber(argv[argptr]))) {
707 ExitFlag = 255;
[543ce4]708 eLog() << Verbose(0) << "Not enough or invalid arguments given for removing atoms: -r <id>" << endl;
[3d4969]709 performCriticalExit();
[a4644b]710 } else {
711 SaveFlag = true;
[543ce4]712 Log() << Verbose(1) << "Removing atom " << argv[argptr] << "." << endl;
[a4644b]713 atom *first = mol->FindAtom(atoi(argv[argptr]));
714 mol->RemoveAtom(first);
715 argptr+=1;
716 }
[a048fa]717 break;
718 case 'f':
[a4644b]719 if (ExitFlag == 0) ExitFlag = 1;
720 if ((argptr+1 >= argc) || (argv[argptr][0] == '-') || (!IsValidNumber(argv[argptr])) || (!IsValidNumber(argv[argptr+1]))) {
[a048fa]721 ExitFlag = 255;
[543ce4]722 eLog() << Verbose(0) << "Not enough or invalid arguments for fragmentation: -f <max. bond distance> <bond order>" << endl;
[3d4969]723 performCriticalExit();
[a048fa]724 } else {
[543ce4]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;
[a048fa]727 start = clock();
[543ce4]728 mol->CreateAdjacencyList(atof(argv[argptr++]), configuration.GetIsAngstroem(), &BondGraph::CovalentMinMaxDistance, NULL);
729 Log() << Verbose(0) << "Fragmenting molecule with current connection matrix ..." << endl;
[a048fa]730 if (mol->first->next != mol->last) {
[543ce4]731 ExitFlag = mol->FragmentMolecule(atoi(argv[argptr]), &configuration);
[a048fa]732 }
733 end = clock();
[543ce4]734 Log() << Verbose(0) << "Clocks for this operation: " << (end-start) << ", time: " << ((double)(end-start)/CLOCKS_PER_SEC) << "s." << endl;
[a048fa]735 argptr+=2;
736 }
737 break;
738 case 'm':
[a4644b]739 if (ExitFlag == 0) ExitFlag = 1;
[a048fa]740 j = atoi(argv[argptr++]);
741 if ((j<0) || (j>1)) {
[418117a]742 eLog() << Verbose(1) << "Argument of '-m' should be either 0 for no-rotate or 1 for rotate." << endl;
[a048fa]743 j = 0;
744 }
745 if (j) {
746 SaveFlag = true;
[543ce4]747 Log() << Verbose(0) << "Converting to prinicipal axis system." << endl;
[a048fa]748 } else
[543ce4]749 Log() << Verbose(0) << "Evaluating prinicipal axis." << endl;
750 mol->PrincipalAxisSystem((bool)j);
[a048fa]751 break;
752 case 'o':
[a4644b]753 if (ExitFlag == 0) ExitFlag = 1;
[606dfb]754 if ((argptr+1 >= argc) || (argv[argptr][0] == '-')){
[a048fa]755 ExitFlag = 255;
[543ce4]756 eLog() << Verbose(0) << "Not enough or invalid arguments given for convex envelope: -o <convex output file> <non-convex output file>" << endl;
[3d4969]757 performCriticalExit();
[a048fa]758 } else {
[a9b2a0a]759 class Tesselation *TesselStruct = NULL;
760 const LinkedCell *LCList = NULL;
[543ce4]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;
[a9b2a0a]764 LCList = new LinkedCell(mol, 10.);
[543ce4]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;
[a9b2a0a]772 delete(TesselStruct);
773 delete(LCList);
[606dfb]774 argptr+=2;
[a048fa]775 }
776 break;
777 case 'U':
[a4644b]778 if (ExitFlag == 0) ExitFlag = 1;
779 if ((argptr+1 >= argc) || (argv[argptr][0] == '-') || (!IsValidNumber(argv[argptr])) || (!IsValidNumber(argv[argptr+1])) ) {
[a048fa]780 ExitFlag = 255;
[543ce4]781 eLog() << Verbose(0) << "Not enough or invalid arguments given for suspension with specified volume: -U <volume> <density>" << endl;
[3d4969]782 performCriticalExit();
[a048fa]783 } else {
784 volume = atof(argv[argptr++]);
[543ce4]785 Log() << Verbose(0) << "Using " << volume << " angstrom^3 as the volume instead of convex envelope one's." << endl;
[a048fa]786 }
787 case 'u':
[a4644b]788 if (ExitFlag == 0) ExitFlag = 1;
789 if ((argptr >= argc) || (argv[argptr][0] == '-') || (!IsValidNumber(argv[argptr])) ) {
[a048fa]790 if (volume != -1)
791 ExitFlag = 255;
[543ce4]792 eLog() << Verbose(0) << "Not enough arguments given for suspension: -u <density>" << endl;
[3d4969]793 performCriticalExit();
[a048fa]794 } else {
795 double density;
796 SaveFlag = true;
[543ce4]797 Log() << Verbose(0) << "Evaluating necessary cell volume for a cluster suspended in water.";
[a048fa]798 density = atof(argv[argptr++]);
799 if (density < 1.0) {
[3d4969]800 eLog() << Verbose(1) << "Density must be greater than 1.0g/cm^3 !" << endl;
[a048fa]801 density = 1.3;
802 }
803// for(int i=0;i<NDIM;i++) {
804// repetition[i] = atoi(argv[argptr++]);
805// if (repetition[i] < 1)
[418117a]806// eLog() << Verbose(1) << "repetition value must be greater 1!" << endl;
[a048fa]807// repetition[i] = 1;
808// }
[543ce4]809 PrepareClustersinWater(&configuration, mol, volume, density); // if volume == 0, will calculate from ConvexEnvelope
[a048fa]810 }
811 break;
812 case 'd':
[a4644b]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])) ) {
[a048fa]815 ExitFlag = 255;
[543ce4]816 eLog() << Verbose(0) << "Not enough or invalid arguments given for repeating cells: -d <repeat_x> <repeat_y> <repeat_z>" << endl;
[3d4969]817 performCriticalExit();
[a048fa]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) {
[418117a]826 eLog() << Verbose(1) << "Repetition factor mus be greater than 1!" << endl;
[a048fa]827 faktor = 1;
828 }
[543ce4]829 mol->CountAtoms(); // recount atoms
[a048fa]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)
[418117a]843 eLog() << Verbose(1) << "AtomCount " << count << " is not equal to number of atoms in molecule " << j << "!" << endl;
[a048fa]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)
[7df43b]881 main_menu->SaveConfig(ConfigFileName, &configuration, periode, molecules);
[a048fa]882 } else { // no arguments, hence scan the elements db
883 if (periode->LoadPeriodentafel(configuration.databasepath))
[543ce4]884 Log() << Verbose(0) << "Element list loaded successfully." << endl;
[a048fa]885 else
[543ce4]886 Log() << Verbose(0) << "Element list loading failed." << endl;
[a048fa]887 configuration.RetrieveConfigPathAndName("main_pcp_linux");
888 }
889 return(ExitFlag);
[3ce105]890};
891
892/********************************************** Main routine **************************************/
[a0bcf1]893
[3ce105]894int main(int argc, char **argv)
895{
[7df43b]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;
[d20ed5]906 oldmenu *main_menu;
907 main_menu = new oldmenu;
[7df43b]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;
[c830e8e]927 }
[7df43b]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 }
[c830e8e]936 }
937
[7df43b]938 mol->ActiveFlag = true;
939 molecules->insert(mol);
940 }
[e08f45]941
942
943
[7df43b]944 main_menu->perform(molecules, configuration, periode, ConfigFileName);
[e08f45]945
[7df43b]946 if(periode->StorePeriodentafel(configuration->databasepath))
947 Log() << Verbose(0) << "Saving of elements.db successful." << endl;
[a048fa]948
[7df43b]949 else
950 Log() << Verbose(0) << "Saving of elements.db failed." << endl;
[a048fa]951
[7df43b]952 delete (molecules);
953 delete(periode);
[746bb4]954 delete(configuration);
[39d983]955
[543ce4]956 Log() << Verbose(0) << "Maximum of allocated memory: "
[39d983]957 << MemoryUsageObserver::getInstance()->getMaximumUsedMemory() << endl;
[543ce4]958 Log() << Verbose(0) << "Remaining non-freed memory: "
[39d983]959 << MemoryUsageObserver::getInstance()->getUsedMemorySize() << endl;
[746bb4]960 MemoryUsageObserver::purgeInstance();
[4ef101]961 logger::purgeInstance();
962 errorLogger::purgeInstance();
[39d983]963
[a048fa]964 return (0);
[a0bcf1]965}
966
967/********************************************** E N D **************************************************/
Note: See TracBrowser for help on using the repository browser.