source: molecuilder/src/builder.cpp@ 3e8325

Last change on this file since 3e8325 was 3e8325, checked in by Tillmann Crueger <crueger@…>, 16 years ago

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

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