source: molecuilder/src/builder.cpp@ 3896fc

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

Changed dialog structure to use objects for queries.

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