source: src/builder.cpp@ 65b6e0

Action_Thermostats Add_AtomRandomPerturbation Add_FitFragmentPartialChargesAction Add_RotateAroundBondAction Add_SelectAtomByNameAction Added_ParseSaveFragmentResults AddingActions_SaveParseParticleParameters Adding_Graph_to_ChangeBondActions Adding_MD_integration_tests Adding_ParticleName_to_Atom Adding_StructOpt_integration_tests AtomFragments Automaking_mpqc_open AutomationFragmentation_failures Candidate_v1.5.4 Candidate_v1.6.0 Candidate_v1.6.1 ChangeBugEmailaddress ChangingTestPorts ChemicalSpaceEvaluator CombiningParticlePotentialParsing Combining_Subpackages Debian_Package_split Debian_package_split_molecuildergui_only Disabling_MemDebug Docu_Python_wait EmpiricalPotential_contain_HomologyGraph EmpiricalPotential_contain_HomologyGraph_documentation Enable_parallel_make_install Enhance_userguide Enhanced_StructuralOptimization Enhanced_StructuralOptimization_continued Example_ManyWaysToTranslateAtom Exclude_Hydrogens_annealWithBondGraph FitPartialCharges_GlobalError Fix_BoundInBox_CenterInBox_MoleculeActions Fix_ChargeSampling_PBC Fix_ChronosMutex Fix_FitPartialCharges Fix_FitPotential_needs_atomicnumbers Fix_ForceAnnealing Fix_IndependentFragmentGrids Fix_ParseParticles Fix_ParseParticles_split_forward_backward_Actions Fix_PopActions Fix_QtFragmentList_sorted_selection Fix_Restrictedkeyset_FragmentMolecule Fix_StatusMsg Fix_StepWorldTime_single_argument Fix_Verbose_Codepatterns Fix_fitting_potentials Fixes ForceAnnealing_goodresults ForceAnnealing_oldresults ForceAnnealing_tocheck ForceAnnealing_with_BondGraph ForceAnnealing_with_BondGraph_continued ForceAnnealing_with_BondGraph_continued_betteresults ForceAnnealing_with_BondGraph_contraction-expansion FragmentAction_writes_AtomFragments FragmentMolecule_checks_bonddegrees GeometryObjects Gui_Fixes Gui_displays_atomic_force_velocity ImplicitCharges IndependentFragmentGrids IndependentFragmentGrids_IndividualZeroInstances IndependentFragmentGrids_IntegrationTest IndependentFragmentGrids_Sole_NN_Calculation JobMarket_RobustOnKillsSegFaults JobMarket_StableWorkerPool JobMarket_unresolvable_hostname_fix MoreRobust_FragmentAutomation ODR_violation_mpqc_open PartialCharges_OrthogonalSummation PdbParser_setsAtomName PythonUI_with_named_parameters QtGui_reactivate_TimeChanged_changes Recreated_GuiChecks Rewrite_FitPartialCharges RotateToPrincipalAxisSystem_UndoRedo SaturateAtoms_findBestMatching SaturateAtoms_singleDegree StoppableMakroAction Subpackage_CodePatterns Subpackage_JobMarket Subpackage_LinearAlgebra Subpackage_levmar Subpackage_mpqc_open Subpackage_vmg Switchable_LogView ThirdParty_MPQC_rebuilt_buildsystem TrajectoryDependenant_MaxOrder TremoloParser_IncreasedPrecision TremoloParser_MultipleTimesteps TremoloParser_setsAtomName Ubuntu_1604_changes stable
Last change on this file since 65b6e0 was 65b6e0, checked in by Frederik Heber <heber@…>, 15 years ago

Added basic menu and action framework

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

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

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