source: molecuilder/src/builder.cpp@ 1120b7

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

Seperated building of mainWindow and contained Menus

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