Changeset 04488a for src/builder.cpp
- Timestamp:
- Jun 25, 2010, 9:57:15 AM (15 years ago)
- Branches:
- 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
- Children:
- b6dbff
- Parents:
- ce4487 (diff), 0d1ad0 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/builder.cpp
rce4487 r04488a 1 1 /** \file builder.cpp 2 2 * 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 3 * date: Jan 1, 2007 4 * author: heber 8 5 * 9 6 */ 10 7 11 /*! \mainpage Mole cuilder - a molecular set builder12 * 13 * This introductory shall briefly make a quainted with the program, helping in installing and a first run.8 /*! \mainpage MoleCuilder - a molecular set builder 9 * 10 * This introductory shall briefly make acquainted with the program, helping in installing and a first run. 14 11 * 15 12 * \section about About the Program 16 13 * 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. 20 * 21 * A configuration file may be written that is compatible to the format used by PCP - a parallel Car-Parrinello 22 * molecular dynamics implementation. 14 * MoleCuilder is a program, written entirely in C++, that enables the construction of a coordinate set for the 15 * atoms making up an molecule. It allows for both building of simple molecules by adding atom-wise giving bond 16 * angles and distances or absolute coordinates, but also using them as templates. Regions can be specified and 17 * ordered to be filled with a molecule in a certain manner. Greater conglomerations of molecules can be tesselated 18 * and recognized as a region themselves to be subsequently surrounded by other (surface solvated) molecules. 19 * In the end, MoleCuilder allows the construction of arbitrary nano structures, whether they be crystalline or 20 * amorphic in nature. 21 * 23 22 * 24 23 * \section install Installation … … 32 31 * -# make clean uninstall: deletes .o-files and removes executable from the given binary directory\n 33 32 * -# make doxygen-doc: Creates these html pages out of the documented source 33 * -# make check: Runs an extensive set of unit tests and a testsuite which also gives a good overview on the set of 34 * functions. 34 35 * 35 36 * \section run Running … … 37 38 * The program can be executed by running: ./molecuilder 38 39 * 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. 42 * 43 * \section ref References 44 * 45 * For the special configuration file format, see the documentation of pcp. 40 * MoleCuilder has three interfaces at your disposal: 41 * -# Textmenu: A simple interactive console-based menu, where awaits your choices and inputs in order to set atoms 42 * as you like 43 * -# CommandLineUI: Every command can also be chained up as a sequence of actions on the command line to be executed 44 * with any user interaction. 45 * -# GraphicalUI: A graphical user interface that also display the molecular structure being built and lots of other 46 * informations to ease the construction of bigger geometries. 47 * 48 * The supported output formats right now are: 49 * -# mpqc: Configuration files of the Massively Parallel Quantum Chemistry package (Sandia labs) 50 * -# pcp: Configuration files of the Parallel Car-Parrinello program (Institute for Numerical Simulation) 51 * -# tremolo: Configuration files of TREMOLO (Institute for Numerical Simulation) 52 * -# xyz: the most basic format for the 3d arrangement of atoms consisting of a list of element and 3 coordinates. 46 53 * 47 54 */ … … 49 56 #include "Helpers/MemDebug.hpp" 50 57 51 #include <boost/bind.hpp>52 53 using namespace std;54 55 #include <cstring>56 #include <cstdlib>57 58 #include "analysis_bonds.hpp"59 #include "analysis_correlation.hpp"60 #include "atom.hpp"61 #include "bond.hpp"62 58 #include "bondgraph.hpp" 63 #include "boundary.hpp"64 59 #include "CommandLineParser.hpp" 65 60 #include "config.hpp" 66 #include "element.hpp"67 #include "ellipsoid.hpp"68 #include "helpers.hpp"69 #include "leastsquaremin.hpp"70 #include "linkedcell.hpp"71 61 #include "log.hpp" 72 62 #include "memoryusageobserver.hpp" … … 82 72 #include "UIElements/Dialog.hpp" 83 73 #include "Menu/ActionMenuItem.hpp" 74 #include "verbose.hpp" 75 #include "World.hpp" 76 84 77 #include "Actions/ActionRegistry.hpp" 85 78 #include "Actions/ActionHistory.hpp" 86 79 #include "Actions/MapOfActions.hpp" 87 #include "Actions/MethodAction.hpp" 88 #include "Actions/MoleculeAction/ChangeNameAction.hpp" 89 #include "World.hpp" 80 81 #include "Parser/ChangeTracker.hpp" 82 #include "Parser/FormatParserStorage.hpp" 83 84 #include "UIElements/UIFactory.hpp" 85 #include "UIElements/TextUI/TextUIFactory.hpp" 86 #include "UIElements/CommandLineUI/CommandLineUIFactory.hpp" 87 #include "UIElements/MainWindow.hpp" 88 #include "UIElements/Dialog.hpp" 89 90 90 #include "version.h" 91 #include "World.hpp" 92 93 94 /********************************************* Subsubmenu routine ************************************/ 95 #if 0 96 /** Submenu for adding atoms to the molecule. 97 * \param *periode periodentafel 98 * \param *molecule molecules with atoms 99 */ 100 static void AddAtoms(periodentafel *periode, molecule *mol) 101 { 102 atom *first, *second, *third, *fourth; 103 Vector **atoms; 104 Vector x,y,z,n; // coordinates for absolute point in cell volume 105 double a,b,c; 106 char choice; // menu choice char 107 bool valid; 108 109 cout << Verbose(0) << "===========ADD ATOM============================" << endl; 110 cout << Verbose(0) << " a - state absolute coordinates of atom" << endl; 111 cout << Verbose(0) << " b - state relative coordinates of atom wrt to reference point" << endl; 112 cout << Verbose(0) << " c - state relative coordinates of atom wrt to already placed atom" << endl; 113 cout << Verbose(0) << " d - state two atoms, two angles and a distance" << endl; 114 cout << Verbose(0) << " e - least square distance position to a set of atoms" << endl; 115 cout << Verbose(0) << "all else - go back" << endl; 116 cout << Verbose(0) << "===============================================" << endl; 117 cout << Verbose(0) << "Note: Specifiy angles in degrees not multiples of Pi!" << endl; 118 cout << Verbose(0) << "INPUT: "; 119 cin >> choice; 120 121 switch (choice) { 122 default: 123 DoeLog(2) && (eLog()<< Verbose(2) << "Not a valid choice." << endl); 124 break; 125 case 'a': // absolute coordinates of atom 126 cout << Verbose(0) << "Enter absolute coordinates." << endl; 127 first = new atom; 128 first->x.AskPosition(World::getInstance().getDomain(), false); 129 first->type = periode->AskElement(); // give type 130 mol->AddAtom(first); // add to molecule 131 break; 132 133 case 'b': // relative coordinates of atom wrt to reference point 134 first = new atom; 135 valid = true; 136 do { 137 if (!valid) DoeLog(2) && (eLog()<< Verbose(2) << "Resulting position out of cell." << endl); 138 cout << Verbose(0) << "Enter reference coordinates." << endl; 139 x.AskPosition(World::getInstance().getDomain(), true); 140 cout << Verbose(0) << "Enter relative coordinates." << endl; 141 first->x.AskPosition(World::getInstance().getDomain(), false); 142 first->x.AddVector((const Vector *)&x); 143 cout << Verbose(0) << "\n"; 144 } while (!(valid = mol->CheckBounds((const Vector *)&first->x))); 145 first->type = periode->AskElement(); // give type 146 mol->AddAtom(first); // add to molecule 147 break; 148 149 case 'c': // relative coordinates of atom wrt to already placed atom 150 first = new atom; 151 valid = true; 152 do { 153 if (!valid) DoeLog(2) && (eLog()<< Verbose(2) << "Resulting position out of cell." << endl); 154 second = mol->AskAtom("Enter atom number: "); 155 DoLog(0) && (Log() << Verbose(0) << "Enter relative coordinates." << endl); 156 first->x.AskPosition(World::getInstance().getDomain(), false); 157 for (int i=NDIM;i--;) { 158 first->x.x[i] += second->x.x[i]; 159 } 160 } while (!(valid = mol->CheckBounds((const Vector *)&first->x))); 161 first->type = periode->AskElement(); // give type 162 mol->AddAtom(first); // add to molecule 163 break; 164 165 case 'd': // two atoms, two angles and a distance 166 first = new atom; 167 valid = true; 168 do { 169 if (!valid) { 170 DoeLog(2) && (eLog()<< Verbose(2) << "Resulting coordinates out of cell - " << first->x << endl); 171 } 172 cout << Verbose(0) << "First, we need two atoms, the first atom is the central, while the second is the outer one." << endl; 173 second = mol->AskAtom("Enter central atom: "); 174 third = mol->AskAtom("Enter second atom (specifying the axis for first angle): "); 175 fourth = mol->AskAtom("Enter third atom (specifying a plane for second angle): "); 176 a = ask_value("Enter distance between central (first) and new atom: "); 177 b = ask_value("Enter angle between new, first and second atom (degrees): "); 178 b *= M_PI/180.; 179 bound(&b, 0., 2.*M_PI); 180 c = ask_value("Enter second angle between new and normal vector of plane defined by first, second and third atom (degrees): "); 181 c *= M_PI/180.; 182 bound(&c, -M_PI, M_PI); 183 cout << Verbose(0) << "radius: " << a << "\t phi: " << b*180./M_PI << "\t theta: " << c*180./M_PI << endl; 184 /* 185 second->Output(1,1,(ofstream *)&cout); 186 third->Output(1,2,(ofstream *)&cout); 187 fourth->Output(1,3,(ofstream *)&cout); 188 n.MakeNormalvector((const vector *)&second->x, (const vector *)&third->x, (const vector *)&fourth->x); 189 x.Copyvector(&second->x); 190 x.SubtractVector(&third->x); 191 x.Copyvector(&fourth->x); 192 x.SubtractVector(&third->x); 193 194 if (!z.SolveSystem(&x,&y,&n, b, c, a)) { 195 coutg() << Verbose(0) << "Failure solving self-dependent linear system!" << endl; 196 continue; 197 } 198 DoLog(0) && (Log() << Verbose(0) << "resulting relative coordinates: "); 199 z.Output(); 200 DoLog(0) && (Log() << Verbose(0) << endl); 201 */ 202 // calc axis vector 203 x.CopyVector(&second->x); 204 x.SubtractVector(&third->x); 205 x.Normalize(); 206 Log() << Verbose(0) << "x: ", 207 x.Output(); 208 DoLog(0) && (Log() << Verbose(0) << endl); 209 z.MakeNormalVector(&second->x,&third->x,&fourth->x); 210 Log() << Verbose(0) << "z: ", 211 z.Output(); 212 DoLog(0) && (Log() << Verbose(0) << endl); 213 y.MakeNormalVector(&x,&z); 214 Log() << Verbose(0) << "y: ", 215 y.Output(); 216 DoLog(0) && (Log() << Verbose(0) << endl); 217 218 // rotate vector around first angle 219 first->x.CopyVector(&x); 220 first->x.RotateVector(&z,b - M_PI); 221 Log() << Verbose(0) << "Rotated vector: ", 222 first->x.Output(); 223 DoLog(0) && (Log() << Verbose(0) << endl); 224 // remove the projection onto the rotation plane of the second angle 225 n.CopyVector(&y); 226 n.Scale(first->x.ScalarProduct(&y)); 227 Log() << Verbose(0) << "N1: ", 228 n.Output(); 229 DoLog(0) && (Log() << Verbose(0) << endl); 230 first->x.SubtractVector(&n); 231 Log() << Verbose(0) << "Subtracted vector: ", 232 first->x.Output(); 233 DoLog(0) && (Log() << Verbose(0) << endl); 234 n.CopyVector(&z); 235 n.Scale(first->x.ScalarProduct(&z)); 236 Log() << Verbose(0) << "N2: ", 237 n.Output(); 238 DoLog(0) && (Log() << Verbose(0) << endl); 239 first->x.SubtractVector(&n); 240 Log() << Verbose(0) << "2nd subtracted vector: ", 241 first->x.Output(); 242 DoLog(0) && (Log() << Verbose(0) << endl); 243 244 // rotate another vector around second angle 245 n.CopyVector(&y); 246 n.RotateVector(&x,c - M_PI); 247 Log() << Verbose(0) << "2nd Rotated vector: ", 248 n.Output(); 249 DoLog(0) && (Log() << Verbose(0) << endl); 250 251 // add the two linear independent vectors 252 first->x.AddVector(&n); 253 first->x.Normalize(); 254 first->x.Scale(a); 255 first->x.AddVector(&second->x); 256 257 DoLog(0) && (Log() << Verbose(0) << "resulting coordinates: "); 258 first->x.Output(); 259 DoLog(0) && (Log() << Verbose(0) << endl); 260 } while (!(valid = mol->CheckBounds((const Vector *)&first->x))); 261 first->type = periode->AskElement(); // give type 262 mol->AddAtom(first); // add to molecule 263 break; 264 265 case 'e': // least square distance position to a set of atoms 266 first = new atom; 267 atoms = new (Vector*[128]); 268 valid = true; 269 for(int i=128;i--;) 270 atoms[i] = NULL; 271 int i=0, j=0; 272 cout << Verbose(0) << "Now we need at least three molecules.\n"; 273 do { 274 cout << Verbose(0) << "Enter " << i+1 << "th atom: "; 275 cin >> j; 276 if (j != -1) { 277 second = mol->FindAtom(j); 278 atoms[i++] = &(second->x); 279 } 280 } while ((j != -1) && (i<128)); 281 if (i >= 2) { 282 first->x.LSQdistance((const Vector **)atoms, i); 283 first->x.Output(); 284 first->type = periode->AskElement(); // give type 285 mol->AddAtom(first); // add to molecule 286 } else { 287 delete first; 288 cout << Verbose(0) << "Please enter at least two vectors!\n"; 289 } 290 break; 291 }; 292 }; 293 294 /** Submenu for centering the atoms in the molecule. 295 * \param *mol molecule with all the atoms 296 */ 297 static void CenterAtoms(molecule *mol) 298 { 299 Vector x, y, helper; 300 char choice; // menu choice char 301 302 cout << Verbose(0) << "===========CENTER ATOMS=========================" << endl; 303 cout << Verbose(0) << " a - on origin" << endl; 304 cout << Verbose(0) << " b - on center of gravity" << endl; 305 cout << Verbose(0) << " c - within box with additional boundary" << endl; 306 cout << Verbose(0) << " d - within given simulation box" << endl; 307 cout << Verbose(0) << "all else - go back" << endl; 308 cout << Verbose(0) << "===============================================" << endl; 309 cout << Verbose(0) << "INPUT: "; 310 cin >> choice; 311 312 switch (choice) { 313 default: 314 cout << Verbose(0) << "Not a valid choice." << endl; 315 break; 316 case 'a': 317 cout << Verbose(0) << "Centering atoms in config file on origin." << endl; 318 mol->CenterOrigin(); 319 break; 320 case 'b': 321 cout << Verbose(0) << "Centering atoms in config file on center of gravity." << endl; 322 mol->CenterPeriodic(); 323 break; 324 case 'c': 325 cout << Verbose(0) << "Centering atoms in config file within given additional boundary." << endl; 326 for (int i=0;i<NDIM;i++) { 327 cout << Verbose(0) << "Enter axis " << i << " boundary: "; 328 cin >> y.x[i]; 329 } 330 mol->CenterEdge(&x); // make every coordinate positive 331 mol->Center.AddVector(&y); // translate by boundary 332 helper.CopyVector(&y); 333 helper.Scale(2.); 334 helper.AddVector(&x); 335 mol->SetBoxDimension(&helper); // update Box of atoms by boundary 336 break; 337 case 'd': 338 cout << Verbose(1) << "Centering atoms in config file within given simulation box." << endl; 339 for (int i=0;i<NDIM;i++) { 340 cout << Verbose(0) << "Enter axis " << i << " boundary: "; 341 cin >> x.x[i]; 342 } 343 // update Box of atoms by boundary 344 mol->SetBoxDimension(&x); 345 // center 346 mol->CenterInBox(); 347 break; 348 } 349 }; 350 351 /** Submenu for aligning the atoms in the molecule. 352 * \param *periode periodentafel 353 * \param *mol molecule with all the atoms 354 */ 355 static void AlignAtoms(periodentafel *periode, molecule *mol) 356 { 357 atom *first, *second, *third; 358 Vector x,n; 359 char choice; // menu choice char 360 361 cout << Verbose(0) << "===========ALIGN ATOMS=========================" << endl; 362 cout << Verbose(0) << " a - state three atoms defining align plane" << endl; 363 cout << Verbose(0) << " b - state alignment vector" << endl; 364 cout << Verbose(0) << " c - state two atoms in alignment direction" << endl; 365 cout << Verbose(0) << " d - align automatically by least square fit" << endl; 366 cout << Verbose(0) << "all else - go back" << endl; 367 cout << Verbose(0) << "===============================================" << endl; 368 cout << Verbose(0) << "INPUT: "; 369 cin >> choice; 370 371 switch (choice) { 372 default: 373 case 'a': // three atoms defining mirror plane 374 first = mol->AskAtom("Enter first atom: "); 375 second = mol->AskAtom("Enter second atom: "); 376 third = mol->AskAtom("Enter third atom: "); 377 378 n.MakeNormalVector((const Vector *)&first->x,(const Vector *)&second->x,(const Vector *)&third->x); 379 break; 380 case 'b': // normal vector of mirror plane 381 cout << Verbose(0) << "Enter normal vector of mirror plane." << endl; 382 n.AskPosition(World::getInstance().getDomain(),0); 383 n.Normalize(); 384 break; 385 case 'c': // three atoms defining mirror plane 386 first = mol->AskAtom("Enter first atom: "); 387 second = mol->AskAtom("Enter second atom: "); 388 389 n.CopyVector((const Vector *)&first->x); 390 n.SubtractVector((const Vector *)&second->x); 391 n.Normalize(); 392 break; 393 case 'd': 394 char shorthand[4]; 395 Vector a; 396 struct lsq_params param; 397 do { 398 fprintf(stdout, "Enter the element of atoms to be chosen: "); 399 fscanf(stdin, "%3s", shorthand); 400 } while ((param.type = periode->FindElement(shorthand)) == NULL); 401 cout << Verbose(0) << "Element is " << param.type->name << endl; 402 mol->GetAlignvector(¶m); 403 for (int i=NDIM;i--;) { 404 x.x[i] = gsl_vector_get(param.x,i); 405 n.x[i] = gsl_vector_get(param.x,i+NDIM); 406 } 407 gsl_vector_free(param.x); 408 cout << Verbose(0) << "Offset vector: "; 409 x.Output(); 410 DoLog(0) && (Log() << Verbose(0) << endl); 411 n.Normalize(); 412 break; 413 }; 414 DoLog(0) && (Log() << Verbose(0) << "Alignment vector: "); 415 n.Output(); 416 DoLog(0) && (Log() << Verbose(0) << endl); 417 mol->Align(&n); 418 }; 419 420 /** Submenu for mirroring the atoms in the molecule. 421 * \param *mol molecule with all the atoms 422 */ 423 static void MirrorAtoms(molecule *mol) 424 { 425 atom *first, *second, *third; 426 Vector n; 427 char choice; // menu choice char 428 429 DoLog(0) && (Log() << Verbose(0) << "===========MIRROR ATOMS=========================" << endl); 430 DoLog(0) && (Log() << Verbose(0) << " a - state three atoms defining mirror plane" << endl); 431 DoLog(0) && (Log() << Verbose(0) << " b - state normal vector of mirror plane" << endl); 432 DoLog(0) && (Log() << Verbose(0) << " c - state two atoms in normal direction" << endl); 433 DoLog(0) && (Log() << Verbose(0) << "all else - go back" << endl); 434 DoLog(0) && (Log() << Verbose(0) << "===============================================" << endl); 435 DoLog(0) && (Log() << Verbose(0) << "INPUT: "); 436 cin >> choice; 437 438 switch (choice) { 439 default: 440 case 'a': // three atoms defining mirror plane 441 first = mol->AskAtom("Enter first atom: "); 442 second = mol->AskAtom("Enter second atom: "); 443 third = mol->AskAtom("Enter third atom: "); 444 445 n.MakeNormalVector((const Vector *)&first->x,(const Vector *)&second->x,(const Vector *)&third->x); 446 break; 447 case 'b': // normal vector of mirror plane 448 DoLog(0) && (Log() << Verbose(0) << "Enter normal vector of mirror plane." << endl); 449 n.AskPosition(World::getInstance().getDomain(),0); 450 n.Normalize(); 451 break; 452 case 'c': // three atoms defining mirror plane 453 first = mol->AskAtom("Enter first atom: "); 454 second = mol->AskAtom("Enter second atom: "); 455 456 n.CopyVector((const Vector *)&first->x); 457 n.SubtractVector((const Vector *)&second->x); 458 n.Normalize(); 459 break; 460 }; 461 DoLog(0) && (Log() << Verbose(0) << "Normal vector: "); 462 n.Output(); 463 DoLog(0) && (Log() << Verbose(0) << endl); 464 mol->Mirror((const Vector *)&n); 465 }; 466 467 /** Submenu for removing the atoms from the molecule. 468 * \param *mol molecule with all the atoms 469 */ 470 static void RemoveAtoms(molecule *mol) 471 { 472 atom *first, *second; 473 int axis; 474 double tmp1, tmp2; 475 char choice; // menu choice char 476 477 DoLog(0) && (Log() << Verbose(0) << "===========REMOVE ATOMS=========================" << endl); 478 DoLog(0) && (Log() << Verbose(0) << " a - state atom for removal by number" << endl); 479 DoLog(0) && (Log() << Verbose(0) << " b - keep only in radius around atom" << endl); 480 DoLog(0) && (Log() << Verbose(0) << " c - remove this with one axis greater value" << endl); 481 DoLog(0) && (Log() << Verbose(0) << "all else - go back" << endl); 482 DoLog(0) && (Log() << Verbose(0) << "===============================================" << endl); 483 DoLog(0) && (Log() << Verbose(0) << "INPUT: "); 484 cin >> choice; 485 486 switch (choice) { 487 default: 488 case 'a': 489 if (mol->RemoveAtom(mol->AskAtom("Enter number of atom within molecule: "))) 490 DoLog(1) && (Log() << Verbose(1) << "Atom removed." << endl); 491 else 492 DoLog(1) && (Log() << Verbose(1) << "Atom not found." << endl); 493 break; 494 case 'b': 495 second = mol->AskAtom("Enter number of atom as reference point: "); 496 DoLog(0) && (Log() << Verbose(0) << "Enter radius: "); 497 cin >> tmp1; 498 first = mol->start; 499 second = first->next; 500 while(second != mol->end) { 501 first = second; 502 second = first->next; 503 if (first->x.DistanceSquared((const Vector *)&second->x) > tmp1*tmp1) // distance to first above radius ... 504 mol->RemoveAtom(first); 505 } 506 break; 507 case 'c': 508 DoLog(0) && (Log() << Verbose(0) << "Which axis is it: "); 509 cin >> axis; 510 DoLog(0) && (Log() << Verbose(0) << "Lower boundary: "); 511 cin >> tmp1; 512 DoLog(0) && (Log() << Verbose(0) << "Upper boundary: "); 513 cin >> tmp2; 514 first = mol->start; 515 second = first->next; 516 while(second != mol->end) { 517 first = second; 518 second = first->next; 519 if ((first->x.x[axis] < tmp1) || (first->x.x[axis] > tmp2)) {// out of boundary ... 520 //Log() << Verbose(0) << "Atom " << *first << " with " << first->x.x[axis] << " on axis " << axis << " is out of bounds [" << tmp1 << "," << tmp2 << "]." << endl; 521 mol->RemoveAtom(first); 522 } 523 } 524 break; 525 }; 526 //mol->Output(); 527 choice = 'r'; 528 }; 529 530 /** Submenu for measuring out the atoms in the molecule. 531 * \param *periode periodentafel 532 * \param *mol molecule with all the atoms 533 */ 534 static void MeasureAtoms(periodentafel *periode, molecule *mol, config *configuration) 535 { 536 atom *first, *second, *third; 537 Vector x,y; 538 double min[256], tmp1, tmp2, tmp3; 539 int Z; 540 char choice; // menu choice char 541 542 DoLog(0) && (Log() << Verbose(0) << "===========MEASURE ATOMS=========================" << endl); 543 DoLog(0) && (Log() << Verbose(0) << " a - calculate bond length between one atom and all others" << endl); 544 DoLog(0) && (Log() << Verbose(0) << " b - calculate bond length between two atoms" << endl); 545 DoLog(0) && (Log() << Verbose(0) << " c - calculate bond angle" << endl); 546 DoLog(0) && (Log() << Verbose(0) << " d - calculate principal axis of the system" << endl); 547 DoLog(0) && (Log() << Verbose(0) << " e - calculate volume of the convex envelope" << endl); 548 DoLog(0) && (Log() << Verbose(0) << " f - calculate temperature from current velocity" << endl); 549 DoLog(0) && (Log() << Verbose(0) << " g - output all temperatures per step from velocities" << endl); 550 DoLog(0) && (Log() << Verbose(0) << "all else - go back" << endl); 551 DoLog(0) && (Log() << Verbose(0) << "===============================================" << endl); 552 DoLog(0) && (Log() << Verbose(0) << "INPUT: "); 553 cin >> choice; 554 555 switch(choice) { 556 default: 557 DoLog(1) && (Log() << Verbose(1) << "Not a valid choice." << endl); 558 break; 559 case 'a': 560 first = mol->AskAtom("Enter first atom: "); 561 for (int i=MAX_ELEMENTS;i--;) 562 min[i] = 0.; 563 564 second = mol->start; 565 while ((second->next != mol->end)) { 566 second = second->next; // advance 567 Z = second->type->Z; 568 tmp1 = 0.; 569 if (first != second) { 570 x.CopyVector((const Vector *)&first->x); 571 x.SubtractVector((const Vector *)&second->x); 572 tmp1 = x.Norm(); 573 } 574 if ((tmp1 != 0.) && ((min[Z] == 0.) || (tmp1 < min[Z]))) min[Z] = tmp1; 575 //Log() << Verbose(0) << "Bond length between Atom " << first->nr << " and " << second->nr << ": " << tmp1 << " a.u." << endl; 576 } 577 for (int i=MAX_ELEMENTS;i--;) 578 if (min[i] != 0.) Log() << Verbose(0) << "Minimum Bond length between " << first->type->name << " Atom " << first->nr << " and next Ion of type " << (periode->FindElement(i))->name << ": " << min[i] << " a.u." << endl; 579 break; 580 581 case 'b': 582 first = mol->AskAtom("Enter first atom: "); 583 second = mol->AskAtom("Enter second atom: "); 584 for (int i=NDIM;i--;) 585 min[i] = 0.; 586 x.CopyVector((const Vector *)&first->x); 587 x.SubtractVector((const Vector *)&second->x); 588 tmp1 = x.Norm(); 589 DoLog(1) && (Log() << Verbose(1) << "Distance vector is "); 590 x.Output(); 591 DoLog(0) && (Log() << Verbose(0) << "." << endl << "Norm of distance is " << tmp1 << "." << endl); 592 break; 593 594 case 'c': 595 DoLog(0) && (Log() << Verbose(0) << "Evaluating bond angle between three - first, central, last - atoms." << endl); 596 first = mol->AskAtom("Enter first atom: "); 597 second = mol->AskAtom("Enter central atom: "); 598 third = mol->AskAtom("Enter last atom: "); 599 tmp1 = tmp2 = tmp3 = 0.; 600 x.CopyVector((const Vector *)&first->x); 601 x.SubtractVector((const Vector *)&second->x); 602 y.CopyVector((const Vector *)&third->x); 603 y.SubtractVector((const Vector *)&second->x); 604 DoLog(0) && (Log() << Verbose(0) << "Bond angle between first atom Nr." << first->nr << ", central atom Nr." << second->nr << " and last atom Nr." << third->nr << ": "); 605 DoLog(0) && (Log() << Verbose(0) << (acos(x.ScalarProduct((const Vector *)&y)/(y.Norm()*x.Norm()))/M_PI*180.) << " degrees" << endl); 606 break; 607 case 'd': 608 DoLog(0) && (Log() << Verbose(0) << "Evaluating prinicipal axis." << endl); 609 DoLog(0) && (Log() << Verbose(0) << "Shall we rotate? [0/1]: "); 610 cin >> Z; 611 if ((Z >=0) && (Z <=1)) 612 mol->PrincipalAxisSystem((bool)Z); 613 else 614 mol->PrincipalAxisSystem(false); 615 break; 616 case 'e': 617 { 618 DoLog(0) && (Log() << Verbose(0) << "Evaluating volume of the convex envelope."); 619 class Tesselation *TesselStruct = NULL; 620 const LinkedCell *LCList = NULL; 621 LCList = new LinkedCell(mol, 10.); 622 FindConvexBorder(mol, TesselStruct, LCList, NULL); 623 double clustervolume = VolumeOfConvexEnvelope(TesselStruct, configuration); 624 DoLog(0) && (Log() << Verbose(0) << "The tesselated surface area is " << clustervolume << "." << endl);\ 625 delete(LCList); 626 delete(TesselStruct); 627 } 628 break; 629 case 'f': 630 mol->OutputTemperatureFromTrajectories((ofstream *)&cout, mol->MDSteps-1, mol->MDSteps); 631 break; 632 case 'g': 633 { 634 char filename[255]; 635 DoLog(0) && (Log() << Verbose(0) << "Please enter filename: " << endl); 636 cin >> filename; 637 DoLog(1) && (Log() << Verbose(1) << "Storing temperatures in " << filename << "." << endl); 638 ofstream *output = new ofstream(filename, ios::trunc); 639 if (!mol->OutputTemperatureFromTrajectories(output, 0, mol->MDSteps)) 640 DoLog(2) && (Log() << Verbose(2) << "File could not be written." << endl); 641 else 642 DoLog(2) && (Log() << Verbose(2) << "File stored." << endl); 643 output->close(); 644 delete(output); 645 } 646 break; 647 } 648 }; 649 650 /** Submenu for measuring out the atoms in the molecule. 651 * \param *mol molecule with all the atoms 652 * \param *configuration configuration structure for the to be written config files of all fragments 653 */ 654 static void FragmentAtoms(molecule *mol, config *configuration) 655 { 656 int Order1; 657 clock_t start, end; 658 659 DoLog(0) && (Log() << Verbose(0) << "Fragmenting molecule with current connection matrix ..." << endl); 660 DoLog(0) && (Log() << Verbose(0) << "What's the desired bond order: "); 661 cin >> Order1; 662 if (mol->first->next != mol->last) { // there are bonds 663 start = clock(); 664 mol->FragmentMolecule(Order1, configuration); 665 end = clock(); 666 DoLog(0) && (Log() << Verbose(0) << "Clocks for this operation: " << (end-start) << ", time: " << ((double)(end-start)/CLOCKS_PER_SEC) << "s." << endl); 667 } else 668 DoLog(0) && (Log() << Verbose(0) << "Connection matrix has not yet been generated!" << endl); 669 }; 670 671 /********************************************** Submenu routine **************************************/ 672 673 /** Submenu for manipulating atoms. 674 * \param *periode periodentafel 675 * \param *molecules list of molecules whose atoms are to be manipulated 676 */ 677 static void ManipulateAtoms(periodentafel *periode, MoleculeListClass *molecules, config *configuration) 678 { 679 atom *first, *second, *third; 680 molecule *mol = NULL; 681 Vector x,y,z,n; // coordinates for absolute point in cell volume 682 double *factor; // unit factor if desired 683 double bond, minBond; 684 char choice; // menu choice char 685 bool valid; 686 687 DoLog(0) && (Log() << Verbose(0) << "=========MANIPULATE ATOMS======================" << endl); 688 DoLog(0) && (Log() << Verbose(0) << "a - add an atom" << endl); 689 DoLog(0) && (Log() << Verbose(0) << "r - remove an atom" << endl); 690 DoLog(0) && (Log() << Verbose(0) << "b - scale a bond between atoms" << endl); 691 DoLog(0) && (Log() << Verbose(0) << "t - turn an atom round another bond" << endl); 692 DoLog(0) && (Log() << Verbose(0) << "u - change an atoms element" << endl); 693 DoLog(0) && (Log() << Verbose(0) << "l - measure lengths, angles, ... for an atom" << endl); 694 DoLog(0) && (Log() << Verbose(0) << "all else - go back" << endl); 695 DoLog(0) && (Log() << Verbose(0) << "===============================================" << endl); 696 if (molecules->NumberOfActiveMolecules() > 1) 697 DoeLog(2) && (eLog()<< Verbose(2) << "There is more than one molecule active! Atoms will be added to each." << endl); 698 DoLog(0) && (Log() << Verbose(0) << "INPUT: "); 699 cin >> choice; 700 701 switch (choice) { 702 default: 703 DoLog(0) && (Log() << Verbose(0) << "Not a valid choice." << endl); 704 break; 705 706 case 'a': // add atom 707 for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++) 708 if ((*ListRunner)->ActiveFlag) { 709 mol = *ListRunner; 710 DoLog(0) && (Log() << Verbose(0) << "Current molecule is: " << mol->IndexNr << "\t" << mol->name << endl); 711 AddAtoms(periode, mol); 712 } 713 break; 714 715 case 'b': // scale a bond 716 for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++) 717 if ((*ListRunner)->ActiveFlag) { 718 mol = *ListRunner; 719 DoLog(0) && (Log() << Verbose(0) << "Current molecule is: " << mol->IndexNr << "\t" << mol->name << endl); 720 DoLog(0) && (Log() << Verbose(0) << "Scaling bond length between two atoms." << endl); 721 first = mol->AskAtom("Enter first (fixed) atom: "); 722 second = mol->AskAtom("Enter second (shifting) atom: "); 723 minBond = 0.; 724 for (int i=NDIM;i--;) 725 minBond += (first->x.x[i]-second->x.x[i])*(first->x.x[i] - second->x.x[i]); 726 minBond = sqrt(minBond); 727 DoLog(0) && (Log() << Verbose(0) << "Current Bond length between " << first->type->name << " Atom " << first->nr << " and " << second->type->name << " Atom " << second->nr << ": " << minBond << " a.u." << endl); 728 DoLog(0) && (Log() << Verbose(0) << "Enter new bond length [a.u.]: "); 729 cin >> bond; 730 for (int i=NDIM;i--;) { 731 second->x.x[i] -= (second->x.x[i]-first->x.x[i])/minBond*(minBond-bond); 732 } 733 //Log() << Verbose(0) << "New coordinates of Atom " << second->nr << " are: "; 734 //second->Output(second->type->No, 1); 735 } 736 break; 737 738 case 'c': // unit scaling of the metric 739 for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++) 740 if ((*ListRunner)->ActiveFlag) { 741 mol = *ListRunner; 742 DoLog(0) && (Log() << Verbose(0) << "Current molecule is: " << mol->IndexNr << "\t" << mol->name << endl); 743 DoLog(0) && (Log() << Verbose(0) << "Angstroem -> Bohrradius: 1.8897261\t\tBohrradius -> Angstroem: 0.52917721" << endl); 744 DoLog(0) && (Log() << Verbose(0) << "Enter three factors: "); 745 factor = new double[NDIM]; 746 cin >> factor[0]; 747 cin >> factor[1]; 748 cin >> factor[2]; 749 valid = true; 750 mol->Scale((const double ** const)&factor); 751 delete[](factor); 752 } 753 break; 754 755 case 'l': // measure distances or angles 756 for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++) 757 if ((*ListRunner)->ActiveFlag) { 758 mol = *ListRunner; 759 DoLog(0) && (Log() << Verbose(0) << "Current molecule is: " << mol->IndexNr << "\t" << mol->name << endl); 760 MeasureAtoms(periode, mol, configuration); 761 } 762 break; 763 764 case 'r': // remove atom 765 for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++) 766 if ((*ListRunner)->ActiveFlag) { 767 mol = *ListRunner; 768 DoLog(0) && (Log() << Verbose(0) << "Current molecule is: " << mol->IndexNr << "\t" << mol->name << endl); 769 RemoveAtoms(mol); 770 } 771 break; 772 773 case 't': // turn/rotate atom 774 for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++) 775 if ((*ListRunner)->ActiveFlag) { 776 mol = *ListRunner; 777 DoLog(0) && (Log() << Verbose(0) << "Turning atom around another bond - first is atom to turn, second (central) and third specify bond" << endl); 778 first = mol->AskAtom("Enter turning atom: "); 779 second = mol->AskAtom("Enter central atom: "); 780 third = mol->AskAtom("Enter bond atom: "); 781 cout << Verbose(0) << "Enter new angle in degrees: "; 782 double tmp = 0.; 783 cin >> tmp; 784 // calculate old angle 785 x.CopyVector((const Vector *)&first->x); 786 x.SubtractVector((const Vector *)&second->x); 787 y.CopyVector((const Vector *)&third->x); 788 y.SubtractVector((const Vector *)&second->x); 789 double alpha = (acos(x.ScalarProduct((const Vector *)&y)/(y.Norm()*x.Norm()))/M_PI*180.); 790 cout << Verbose(0) << "Bond angle between first atom Nr." << first->nr << ", central atom Nr." << second->nr << " and last atom Nr." << third->nr << ": "; 791 cout << Verbose(0) << alpha << " degrees" << endl; 792 // rotate 793 z.MakeNormalVector(&x,&y); 794 x.RotateVector(&z,(alpha-tmp)*M_PI/180.); 795 x.AddVector(&second->x); 796 first->x.CopyVector(&x); 797 // check new angle 798 x.CopyVector((const Vector *)&first->x); 799 x.SubtractVector((const Vector *)&second->x); 800 alpha = (acos(x.ScalarProduct((const Vector *)&y)/(y.Norm()*x.Norm()))/M_PI*180.); 801 cout << Verbose(0) << "new Bond angle between first atom Nr." << first->nr << ", central atom Nr." << second->nr << " and last atom Nr." << third->nr << ": "; 802 cout << Verbose(0) << alpha << " degrees" << endl; 803 } 804 break; 805 806 case 'u': // change an atom's element 807 for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++) 808 if ((*ListRunner)->ActiveFlag) { 809 int Z; 810 mol = *ListRunner; 811 DoLog(0) && (Log() << Verbose(0) << "Current molecule is: " << mol->IndexNr << "\t" << mol->name << endl); 812 first = NULL; 813 do { 814 DoLog(0) && (Log() << Verbose(0) << "Change the element of which atom: "); 815 cin >> Z; 816 } while ((first = mol->FindAtom(Z)) == NULL); 817 DoLog(0) && (Log() << Verbose(0) << "New element by atomic number Z: "); 818 cin >> Z; 819 first->type = periode->FindElement(Z); 820 DoLog(0) && (Log() << Verbose(0) << "Atom " << first->nr << "'s element is " << first->type->name << "." << endl); 821 } 822 break; 823 } 824 }; 825 826 /** Submenu for manipulating molecules. 827 * \param *periode periodentafel 828 * \param *molecules list of molecule to manipulate 829 */ 830 static void ManipulateMolecules(periodentafel *periode, MoleculeListClass *molecules, config *configuration) 831 { 832 atom *first = NULL; 833 Vector x,y,z,n; // coordinates for absolute point in cell volume 834 int j, axis, count, faktor; 835 char choice; // menu choice char 836 molecule *mol = NULL; 837 element **Elements; 838 Vector **vectors; 839 MoleculeLeafClass *Subgraphs = NULL; 840 841 DoLog(0) && (Log() << Verbose(0) << "=========MANIPULATE GLOBALLY===================" << endl); 842 DoLog(0) && (Log() << Verbose(0) << "c - scale by unit transformation" << endl); 843 DoLog(0) && (Log() << Verbose(0) << "d - duplicate molecule/periodic cell" << endl); 844 DoLog(0) && (Log() << Verbose(0) << "f - fragment molecule many-body bond order style" << endl); 845 DoLog(0) && (Log() << Verbose(0) << "g - center atoms in box" << endl); 846 DoLog(0) && (Log() << Verbose(0) << "i - realign molecule" << endl); 847 DoLog(0) && (Log() << Verbose(0) << "m - mirror all molecules" << endl); 848 DoLog(0) && (Log() << Verbose(0) << "o - create connection matrix" << endl); 849 DoLog(0) && (Log() << Verbose(0) << "t - translate molecule by vector" << endl); 850 DoLog(0) && (Log() << Verbose(0) << "all else - go back" << endl); 851 DoLog(0) && (Log() << Verbose(0) << "===============================================" << endl); 852 if (molecules->NumberOfActiveMolecules() > 1) 853 DoeLog(2) && (eLog()<< Verbose(2) << "There is more than one molecule active! Atoms will be added to each." << endl); 854 DoLog(0) && (Log() << Verbose(0) << "INPUT: "); 855 cin >> choice; 856 857 switch (choice) { 858 default: 859 DoLog(0) && (Log() << Verbose(0) << "Not a valid choice." << endl); 860 break; 861 862 case 'd': // duplicate the periodic cell along a given axis, given times 863 for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++) 864 if ((*ListRunner)->ActiveFlag) { 865 mol = *ListRunner; 866 DoLog(0) && (Log() << Verbose(0) << "Current molecule is: " << mol->IndexNr << "\t" << mol->name << endl); 867 DoLog(0) && (Log() << Verbose(0) << "State the axis [(+-)123]: "); 868 cin >> axis; 869 DoLog(0) && (Log() << Verbose(0) << "State the factor: "); 870 cin >> faktor; 871 872 mol->CountAtoms(); // recount atoms 873 if (mol->getAtomCount() != 0) { // if there is more than none 874 count = mol->getAtomCount(); // is changed becausing of adding, thus has to be stored away beforehand 875 Elements = new element *[count]; 876 vectors = new Vector *[count]; 877 j = 0; 878 first = mol->start; 879 while (first->next != mol->end) { // make a list of all atoms with coordinates and element 880 first = first->next; 881 Elements[j] = first->type; 882 vectors[j] = &first->x; 883 j++; 884 } 885 if (count != j) 886 DoeLog(1) && (eLog()<< Verbose(1) << "AtomCount " << count << " is not equal to number of atoms in molecule " << j << "!" << endl); 887 x.Zero(); 888 y.Zero(); 889 y.x[abs(axis)-1] = World::getInstance().getDomain()[(abs(axis) == 2) ? 2 : ((abs(axis) == 3) ? 5 : 0)] * abs(axis)/axis; // last term is for sign, first is for magnitude 890 for (int i=1;i<faktor;i++) { // then add this list with respective translation factor times 891 x.AddVector(&y); // per factor one cell width further 892 for (int k=count;k--;) { // go through every atom of the original cell 893 first = new atom(); // create a new body 894 first->x.CopyVector(vectors[k]); // use coordinate of original atom 895 first->x.AddVector(&x); // translate the coordinates 896 first->type = Elements[k]; // insert original element 897 mol->AddAtom(first); // and add to the molecule (which increments ElementsInMolecule, AtomCount, ...) 898 } 899 } 900 if (mol->first->next != mol->last) // if connect matrix is present already, redo it 901 mol->CreateAdjacencyList(mol->BondDistance, configuration->GetIsAngstroem(), &BondGraph::CovalentMinMaxDistance, NULL); 902 // free memory 903 delete[](Elements); 904 delete[](vectors); 905 // correct cell size 906 if (axis < 0) { // if sign was negative, we have to translate everything 907 x.Zero(); 908 x.AddVector(&y); 909 x.Scale(-(faktor-1)); 910 mol->Translate(&x); 911 } 912 World::getInstance().getDomain()[(abs(axis) == 2) ? 2 : ((abs(axis) == 3) ? 5 : 0)] *= faktor; 913 } 914 } 915 break; 916 917 case 'f': 918 FragmentAtoms(mol, configuration); 919 break; 920 921 case 'g': // center the atoms 922 for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++) 923 if ((*ListRunner)->ActiveFlag) { 924 mol = *ListRunner; 925 DoLog(0) && (Log() << Verbose(0) << "Current molecule is: " << mol->IndexNr << "\t" << mol->name << endl); 926 CenterAtoms(mol); 927 } 928 break; 929 930 case 'i': // align all atoms 931 for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++) 932 if ((*ListRunner)->ActiveFlag) { 933 mol = *ListRunner; 934 DoLog(0) && (Log() << Verbose(0) << "Current molecule is: " << mol->IndexNr << "\t" << mol->name << endl); 935 AlignAtoms(periode, mol); 936 } 937 break; 938 939 case 'm': // mirror atoms along a given axis 940 for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++) 941 if ((*ListRunner)->ActiveFlag) { 942 mol = *ListRunner; 943 DoLog(0) && (Log() << Verbose(0) << "Current molecule is: " << mol->IndexNr << "\t" << mol->name << endl); 944 MirrorAtoms(mol); 945 } 946 break; 947 948 case 'o': // create the connection matrix 949 for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++) 950 if ((*ListRunner)->ActiveFlag) { 951 mol = *ListRunner; 952 double bonddistance; 953 clock_t start,end; 954 DoLog(0) && (Log() << Verbose(0) << "What's the maximum bond distance: "); 955 cin >> bonddistance; 956 start = clock(); 957 mol->CreateAdjacencyList(bonddistance, configuration->GetIsAngstroem(), &BondGraph::CovalentMinMaxDistance, NULL); 958 end = clock(); 959 DoLog(0) && (Log() << Verbose(0) << "Clocks for this operation: " << (end-start) << ", time: " << ((double)(end-start)/CLOCKS_PER_SEC) << "s." << endl); 960 } 961 break; 962 963 case 't': // translate all atoms 964 for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++) 965 if ((*ListRunner)->ActiveFlag) { 966 mol = *ListRunner; 967 DoLog(0) && (Log() << Verbose(0) << "Current molecule is: " << mol->IndexNr << "\t" << mol->name << endl); 968 DoLog(0) && (Log() << Verbose(0) << "Enter translation vector." << endl); 969 x.AskPosition(World::getInstance().getDomain(),0); 970 mol->Center.AddVector((const Vector *)&x); 971 } 972 break; 973 } 974 // Free all 975 if (Subgraphs != NULL) { // free disconnected subgraph list of DFS analysis was performed 976 while (Subgraphs->next != NULL) { 977 Subgraphs = Subgraphs->next; 978 delete(Subgraphs->previous); 979 } 980 delete(Subgraphs); 981 } 982 }; 983 984 985 /** Submenu for creating new molecules. 986 * \param *periode periodentafel 987 * \param *molecules list of molecules to add to 988 */ 989 static void EditMolecules(periodentafel *periode, MoleculeListClass *molecules) 990 { 991 char choice; // menu choice char 992 Vector center; 993 int nr, count; 994 molecule *mol = NULL; 995 996 DoLog(0) && (Log() << Verbose(0) << "==========EDIT MOLECULES=====================" << endl); 997 DoLog(0) && (Log() << Verbose(0) << "c - create new molecule" << endl); 998 DoLog(0) && (Log() << Verbose(0) << "l - load molecule from xyz file" << endl); 999 DoLog(0) && (Log() << Verbose(0) << "n - change molecule's name" << endl); 1000 DoLog(0) && (Log() << Verbose(0) << "N - give molecules filename" << endl); 1001 DoLog(0) && (Log() << Verbose(0) << "p - parse atoms in xyz file into molecule" << endl); 1002 DoLog(0) && (Log() << Verbose(0) << "r - remove a molecule" << endl); 1003 DoLog(0) && (Log() << Verbose(0) << "all else - go back" << endl); 1004 DoLog(0) && (Log() << Verbose(0) << "===============================================" << endl); 1005 DoLog(0) && (Log() << Verbose(0) << "INPUT: "); 1006 cin >> choice; 1007 1008 switch (choice) { 1009 default: 1010 DoLog(0) && (Log() << Verbose(0) << "Not a valid choice." << endl); 1011 break; 1012 case 'c': 1013 mol = World::getInstance().createMolecule(); 1014 molecules->insert(mol); 1015 break; 1016 1017 case 'l': // load from XYZ file 1018 { 1019 char filename[MAXSTRINGSIZE]; 1020 DoLog(0) && (Log() << Verbose(0) << "Format should be XYZ with: ShorthandOfElement\tX\tY\tZ" << endl); 1021 mol = World::getInstance().createMolecule(); 1022 do { 1023 DoLog(0) && (Log() << Verbose(0) << "Enter file name: "); 1024 cin >> filename; 1025 } while (!mol->AddXYZFile(filename)); 1026 mol->SetNameFromFilename(filename); 1027 // center at set box dimensions 1028 mol->CenterEdge(¢er); 1029 double * const cell_size = World::getInstance().getDomain(); 1030 cell_size[0] = center.x[0]; 1031 cell_size[1] = 0; 1032 cell_size[2] = center.x[1]; 1033 cell_size[3] = 0; 1034 cell_size[4] = 0; 1035 cell_size[5] = center.x[2]; 1036 molecules->insert(mol); 1037 } 1038 break; 1039 1040 case 'n': 1041 { 1042 char filename[MAXSTRINGSIZE]; 1043 do { 1044 DoLog(0) && (Log() << Verbose(0) << "Enter index of molecule: "); 1045 cin >> nr; 1046 mol = molecules->ReturnIndex(nr); 1047 } while (mol == NULL); 1048 DoLog(0) && (Log() << Verbose(0) << "Enter name: "); 1049 cin >> filename; 1050 strcpy(mol->name, filename); 1051 } 1052 break; 1053 1054 case 'N': 1055 { 1056 char filename[MAXSTRINGSIZE]; 1057 do { 1058 DoLog(0) && (Log() << Verbose(0) << "Enter index of molecule: "); 1059 cin >> nr; 1060 mol = molecules->ReturnIndex(nr); 1061 } while (mol == NULL); 1062 DoLog(0) && (Log() << Verbose(0) << "Enter name: "); 1063 cin >> filename; 1064 mol->SetNameFromFilename(filename); 1065 } 1066 break; 1067 1068 case 'p': // parse XYZ file 1069 { 1070 char filename[MAXSTRINGSIZE]; 1071 mol = NULL; 1072 do { 1073 DoLog(0) && (Log() << Verbose(0) << "Enter index of molecule: "); 1074 cin >> nr; 1075 mol = molecules->ReturnIndex(nr); 1076 } while (mol == NULL); 1077 DoLog(0) && (Log() << Verbose(0) << "Format should be XYZ with: ShorthandOfElement\tX\tY\tZ" << endl); 1078 do { 1079 DoLog(0) && (Log() << Verbose(0) << "Enter file name: "); 1080 cin >> filename; 1081 } while (!mol->AddXYZFile(filename)); 1082 mol->SetNameFromFilename(filename); 1083 } 1084 break; 1085 1086 case 'r': 1087 DoLog(0) && (Log() << Verbose(0) << "Enter index of molecule: "); 1088 cin >> nr; 1089 count = 1; 1090 for(MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++) 1091 if (nr == (*ListRunner)->IndexNr) { 1092 mol = *ListRunner; 1093 molecules->ListOfMolecules.erase(ListRunner); 1094 delete(mol); 1095 break; 1096 } 1097 break; 1098 } 1099 }; 1100 1101 1102 /** Submenu for merging molecules. 1103 * \param *periode periodentafel 1104 * \param *molecules list of molecules to add to 1105 */ 1106 static void MergeMolecules(periodentafel *periode, MoleculeListClass *molecules) 1107 { 1108 char choice; // menu choice char 1109 1110 DoLog(0) && (Log() << Verbose(0) << "===========MERGE MOLECULES=====================" << endl); 1111 DoLog(0) && (Log() << Verbose(0) << "a - simple add of one molecule to another" << endl); 1112 DoLog(0) && (Log() << Verbose(0) << "b - count the number of bonds of two elements" << endl); 1113 DoLog(0) && (Log() << Verbose(0) << "B - count the number of bonds of three elements " << endl); 1114 DoLog(0) && (Log() << Verbose(0) << "e - embedding merge of two molecules" << endl); 1115 DoLog(0) && (Log() << Verbose(0) << "h - count the number of hydrogen bonds" << endl); 1116 DoLog(0) && (Log() << Verbose(0) << "b - count the number of hydrogen bonds" << endl); 1117 DoLog(0) && (Log() << Verbose(0) << "m - multi-merge of all molecules" << endl); 1118 DoLog(0) && (Log() << Verbose(0) << "s - scatter merge of two molecules" << endl); 1119 DoLog(0) && (Log() << Verbose(0) << "t - simple merge of two molecules" << endl); 1120 DoLog(0) && (Log() << Verbose(0) << "all else - go back" << endl); 1121 DoLog(0) && (Log() << Verbose(0) << "===============================================" << endl); 1122 DoLog(0) && (Log() << Verbose(0) << "INPUT: "); 1123 cin >> choice; 1124 1125 switch (choice) { 1126 default: 1127 DoLog(0) && (Log() << Verbose(0) << "Not a valid choice." << endl); 1128 break; 1129 1130 case 'a': 1131 { 1132 int src, dest; 1133 molecule *srcmol = NULL, *destmol = NULL; 1134 { 1135 do { 1136 DoLog(0) && (Log() << Verbose(0) << "Enter index of destination molecule: "); 1137 cin >> dest; 1138 destmol = molecules->ReturnIndex(dest); 1139 } while ((destmol == NULL) && (dest != -1)); 1140 do { 1141 DoLog(0) && (Log() << Verbose(0) << "Enter index of source molecule to add from: "); 1142 cin >> src; 1143 srcmol = molecules->ReturnIndex(src); 1144 } while ((srcmol == NULL) && (src != -1)); 1145 if ((src != -1) && (dest != -1)) 1146 molecules->SimpleAdd(srcmol, destmol); 1147 } 1148 } 1149 break; 1150 1151 case 'b': 1152 { 1153 const int nr = 2; 1154 char *names[nr] = {"first", "second"}; 1155 int Z[nr]; 1156 element *elements[nr]; 1157 for (int i=0;i<nr;i++) { 1158 Z[i] = 0; 1159 do { 1160 cout << "Enter " << names[i] << " element: "; 1161 cin >> Z[i]; 1162 } while ((Z[i] <= 0) && (Z[i] > MAX_ELEMENTS)); 1163 elements[i] = periode->FindElement(Z[i]); 1164 } 1165 const int count = CountBondsOfTwo(molecules, elements[0], elements[1]); 1166 cout << endl << "There are " << count << " "; 1167 for (int i=0;i<nr;i++) { 1168 if (i==0) 1169 cout << elements[i]->symbol; 1170 else 1171 cout << "-" << elements[i]->symbol; 1172 } 1173 cout << " bonds." << endl; 1174 } 1175 break; 1176 1177 case 'B': 1178 { 1179 const int nr = 3; 1180 char *names[nr] = {"first", "second", "third"}; 1181 int Z[nr]; 1182 element *elements[nr]; 1183 for (int i=0;i<nr;i++) { 1184 Z[i] = 0; 1185 do { 1186 cout << "Enter " << names[i] << " element: "; 1187 cin >> Z[i]; 1188 } while ((Z[i] <= 0) && (Z[i] > MAX_ELEMENTS)); 1189 elements[i] = periode->FindElement(Z[i]); 1190 } 1191 const int count = CountBondsOfThree(molecules, elements[0], elements[1], elements[2]); 1192 cout << endl << "There are " << count << " "; 1193 for (int i=0;i<nr;i++) { 1194 if (i==0) 1195 cout << elements[i]->symbol; 1196 else 1197 cout << "-" << elements[i]->symbol; 1198 } 1199 cout << " bonds." << endl; 1200 } 1201 break; 1202 1203 case 'e': 1204 { 1205 int src, dest; 1206 molecule *srcmol = NULL, *destmol = NULL; 1207 do { 1208 DoLog(0) && (Log() << Verbose(0) << "Enter index of matrix molecule (the variable one): "); 1209 cin >> src; 1210 srcmol = molecules->ReturnIndex(src); 1211 } while ((srcmol == NULL) && (src != -1)); 1212 do { 1213 DoLog(0) && (Log() << Verbose(0) << "Enter index of molecule to merge into (the fixed one): "); 1214 cin >> dest; 1215 destmol = molecules->ReturnIndex(dest); 1216 } while ((destmol == NULL) && (dest != -1)); 1217 if ((src != -1) && (dest != -1)) 1218 molecules->EmbedMerge(destmol, srcmol); 1219 } 1220 break; 1221 1222 case 'h': 1223 { 1224 int Z; 1225 cout << "Please enter interface element: "; 1226 cin >> Z; 1227 element * const InterfaceElement = periode->FindElement(Z); 1228 cout << endl << "There are " << CountHydrogenBridgeBonds(molecules, InterfaceElement) << " hydrogen bridges with connections to " << (InterfaceElement != 0 ? InterfaceElement->name : "None") << "." << endl; 1229 } 1230 break; 1231 1232 case 'm': 1233 { 1234 int nr; 1235 molecule *mol = NULL; 1236 do { 1237 DoLog(0) && (Log() << Verbose(0) << "Enter index of molecule to merge into: "); 1238 cin >> nr; 1239 mol = molecules->ReturnIndex(nr); 1240 } while ((mol == NULL) && (nr != -1)); 1241 if (nr != -1) { 1242 int N = molecules->ListOfMolecules.size()-1; 1243 int *src = new int(N); 1244 for(MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++) 1245 if ((*ListRunner)->IndexNr != nr) 1246 src[N++] = (*ListRunner)->IndexNr; 1247 molecules->SimpleMultiMerge(mol, src, N); 1248 delete[](src); 1249 } 1250 } 1251 break; 1252 1253 case 's': 1254 DoLog(0) && (Log() << Verbose(0) << "Not implemented yet." << endl); 1255 break; 1256 1257 case 't': 1258 { 1259 int src, dest; 1260 molecule *srcmol = NULL, *destmol = NULL; 1261 { 1262 do { 1263 DoLog(0) && (Log() << Verbose(0) << "Enter index of destination molecule: "); 1264 cin >> dest; 1265 destmol = molecules->ReturnIndex(dest); 1266 } while ((destmol == NULL) && (dest != -1)); 1267 do { 1268 DoLog(0) && (Log() << Verbose(0) << "Enter index of source molecule to merge into: "); 1269 cin >> src; 1270 srcmol = molecules->ReturnIndex(src); 1271 } while ((srcmol == NULL) && (src != -1)); 1272 if ((src != -1) && (dest != -1)) 1273 molecules->SimpleMerge(srcmol, destmol); 1274 } 1275 } 1276 break; 1277 } 1278 }; 1279 1280 /********************************************** Test routine **************************************/ 1281 1282 /** Is called always as option 'T' in the menu. 1283 * \param *molecules list of molecules 1284 */ 1285 static void testroutine(MoleculeListClass *molecules) 1286 { 1287 // the current test routine checks the functionality of the KeySet&Graph concept: 1288 // We want to have a multiindex (the KeySet) describing a unique subgraph 1289 int i, comp, counter=0; 1290 1291 // create a clone 1292 molecule *mol = NULL; 1293 if (molecules->ListOfMolecules.size() != 0) // clone 1294 mol = (molecules->ListOfMolecules.front())->CopyMolecule(); 1295 else { 1296 DoeLog(0) && (eLog()<< Verbose(0) << "I don't have anything to test on ... "); 1297 performCriticalExit(); 1298 return; 1299 } 1300 atom *Walker = mol->start; 1301 1302 // generate some KeySets 1303 DoLog(0) && (Log() << Verbose(0) << "Generating KeySets." << endl); 1304 KeySet TestSets[mol->getAtomCount()+1]; 1305 i=1; 1306 while (Walker->next != mol->end) { 1307 Walker = Walker->next; 1308 for (int j=0;j<i;j++) { 1309 TestSets[j].insert(Walker->nr); 1310 } 1311 i++; 1312 } 1313 DoLog(0) && (Log() << Verbose(0) << "Testing insertion of already present item in KeySets." << endl); 1314 KeySetTestPair test; 1315 test = TestSets[mol->getAtomCount()-1].insert(Walker->nr); 1316 if (test.second) { 1317 DoLog(1) && (Log() << Verbose(1) << "Insertion worked?!" << endl); 1318 } else { 1319 DoLog(1) && (Log() << Verbose(1) << "Insertion rejected: Present object is " << (*test.first) << "." << endl); 1320 } 1321 TestSets[mol->getAtomCount()].insert(mol->end->previous->nr); 1322 TestSets[mol->getAtomCount()].insert(mol->end->previous->previous->previous->nr); 1323 1324 // constructing Graph structure 1325 DoLog(0) && (Log() << Verbose(0) << "Generating Subgraph class." << endl); 1326 Graph Subgraphs; 1327 1328 // insert KeySets into Subgraphs 1329 DoLog(0) && (Log() << Verbose(0) << "Inserting KeySets into Subgraph class." << endl); 1330 for (int j=0;j<mol->getAtomCount();j++) { 1331 Subgraphs.insert(GraphPair (TestSets[j],pair<int, double>(counter++, 1.))); 1332 } 1333 DoLog(0) && (Log() << Verbose(0) << "Testing insertion of already present item in Subgraph." << endl); 1334 GraphTestPair test2; 1335 test2 = Subgraphs.insert(GraphPair (TestSets[mol->getAtomCount()],pair<int, double>(counter++, 1.))); 1336 if (test2.second) { 1337 DoLog(1) && (Log() << Verbose(1) << "Insertion worked?!" << endl); 1338 } else { 1339 DoLog(1) && (Log() << Verbose(1) << "Insertion rejected: Present object is " << (*(test2.first)).second.first << "." << endl); 1340 } 1341 1342 // show graphs 1343 DoLog(0) && (Log() << Verbose(0) << "Showing Subgraph's contents, checking that it's sorted." << endl); 1344 Graph::iterator A = Subgraphs.begin(); 1345 while (A != Subgraphs.end()) { 1346 DoLog(0) && (Log() << Verbose(0) << (*A).second.first << ": "); 1347 KeySet::iterator key = (*A).first.begin(); 1348 comp = -1; 1349 while (key != (*A).first.end()) { 1350 if ((*key) > comp) 1351 DoLog(0) && (Log() << Verbose(0) << (*key) << " "); 1352 else 1353 DoLog(0) && (Log() << Verbose(0) << (*key) << "! "); 1354 comp = (*key); 1355 key++; 1356 } 1357 DoLog(0) && (Log() << Verbose(0) << endl); 1358 A++; 1359 } 1360 delete(mol); 1361 }; 1362 1363 1364 /** Tries given filename or standard on saving the config file. 1365 * \param *ConfigFileName name of file 1366 * \param *configuration pointer to configuration structure with all the values 1367 * \param *periode pointer to periodentafel structure with all the elements 1368 * \param *molecules list of molecules structure with all the atoms and coordinates 1369 */ 1370 static void SaveConfig(char *ConfigFileName, config *configuration, periodentafel *periode, MoleculeListClass *molecules) 1371 { 1372 char filename[MAXSTRINGSIZE]; 1373 ofstream output; 1374 molecule *mol = World::getInstance().createMolecule(); 1375 mol->SetNameFromFilename(ConfigFileName); 1376 1377 if (!strcmp(configuration->configpath, configuration->GetDefaultPath())) { 1378 DoeLog(2) && (eLog()<< Verbose(2) << "config is found under different path then stated in config file::defaultpath!" << endl); 1379 } 1380 1381 1382 // first save as PDB data 1383 if (ConfigFileName != NULL) 1384 strcpy(filename, ConfigFileName); 1385 if (output == NULL) 1386 strcpy(filename,"main_pcp_linux"); 1387 DoLog(0) && (Log() << Verbose(0) << "Saving as pdb input "); 1388 if (configuration->SavePDB(filename, molecules)) 1389 DoLog(0) && (Log() << Verbose(0) << "done." << endl); 1390 else 1391 DoLog(0) && (Log() << Verbose(0) << "failed." << endl); 1392 1393 // then save as tremolo data file 1394 if (ConfigFileName != NULL) 1395 strcpy(filename, ConfigFileName); 1396 if (output == NULL) 1397 strcpy(filename,"main_pcp_linux"); 1398 DoLog(0) && (Log() << Verbose(0) << "Saving as tremolo data input "); 1399 if (configuration->SaveTREMOLO(filename, molecules)) 1400 DoLog(0) && (Log() << Verbose(0) << "done." << endl); 1401 else 1402 DoLog(0) && (Log() << Verbose(0) << "failed." << endl); 1403 1404 // translate each to its center and merge all molecules in MoleculeListClass into this molecule 1405 int N = molecules->ListOfMolecules.size(); 1406 int *src = new int[N]; 1407 N=0; 1408 for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++) { 1409 src[N++] = (*ListRunner)->IndexNr; 1410 (*ListRunner)->Translate(&(*ListRunner)->Center); 1411 } 1412 molecules->SimpleMultiAdd(mol, src, N); 1413 delete[](src); 1414 1415 // ... and translate back 1416 for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++) { 1417 (*ListRunner)->Center.Scale(-1.); 1418 (*ListRunner)->Translate(&(*ListRunner)->Center); 1419 (*ListRunner)->Center.Scale(-1.); 1420 } 1421 1422 DoLog(0) && (Log() << Verbose(0) << "Storing configuration ... " << endl); 1423 // get correct valence orbitals 1424 mol->CalculateOrbitals(*configuration); 1425 configuration->InitMaxMinStopStep = configuration->MaxMinStopStep = configuration->MaxPsiDouble; 1426 if (ConfigFileName != NULL) { // test the file name 1427 strcpy(filename, ConfigFileName); 1428 output.open(filename, ios::trunc); 1429 } else if (strlen(configuration->configname) != 0) { 1430 strcpy(filename, configuration->configname); 1431 output.open(configuration->configname, ios::trunc); 1432 } else { 1433 strcpy(filename, DEFAULTCONFIG); 1434 output.open(DEFAULTCONFIG, ios::trunc); 1435 } 1436 output.close(); 1437 output.clear(); 1438 DoLog(0) && (Log() << Verbose(0) << "Saving of config file "); 1439 if (configuration->Save(filename, periode, mol)) 1440 DoLog(0) && (Log() << Verbose(0) << "successful." << endl); 1441 else 1442 DoLog(0) && (Log() << Verbose(0) << "failed." << endl); 1443 1444 // and save to xyz file 1445 if (ConfigFileName != NULL) { 1446 strcpy(filename, ConfigFileName); 1447 strcat(filename, ".xyz"); 1448 output.open(filename, ios::trunc); 1449 } 1450 if (output == NULL) { 1451 strcpy(filename,"main_pcp_linux"); 1452 strcat(filename, ".xyz"); 1453 output.open(filename, ios::trunc); 1454 } 1455 DoLog(0) && (Log() << Verbose(0) << "Saving of XYZ file "); 1456 if (mol->MDSteps <= 1) { 1457 if (mol->OutputXYZ(&output)) 1458 DoLog(0) && (Log() << Verbose(0) << "successful." << endl); 1459 else 1460 DoLog(0) && (Log() << Verbose(0) << "failed." << endl); 1461 } else { 1462 if (mol->OutputTrajectoriesXYZ(&output)) 1463 DoLog(0) && (Log() << Verbose(0) << "successful." << endl); 1464 else 1465 DoLog(0) && (Log() << Verbose(0) << "failed." << endl); 1466 } 1467 output.close(); 1468 output.clear(); 1469 1470 // and save as MPQC configuration 1471 if (ConfigFileName != NULL) 1472 strcpy(filename, ConfigFileName); 1473 if (output == NULL) 1474 strcpy(filename,"main_pcp_linux"); 1475 DoLog(0) && (Log() << Verbose(0) << "Saving as mpqc input "); 1476 if (configuration->SaveMPQC(filename, mol)) 1477 DoLog(0) && (Log() << Verbose(0) << "done." << endl); 1478 else 1479 DoLog(0) && (Log() << Verbose(0) << "failed." << endl); 1480 1481 if (!strcmp(configuration->configpath, configuration->GetDefaultPath())) { 1482 DoeLog(2) && (eLog()<< Verbose(2) << "config is found under different path then stated in config file::defaultpath!" << endl); 1483 } 1484 1485 World::getInstance().destroyMolecule(mol); 1486 }; 1487 1488 #endif 1489 1490 /** Parses the command line options. 1491 * Note that this function is from now on transitional. All commands that are not passed 1492 * here are handled by CommandLineParser and the actions of CommandLineUIFactory. 1493 * \param argc argument count 1494 * \param **argv arguments array 1495 * \param *molecules list of molecules structure 1496 * \param *periode elements structure 1497 * \param configuration config file structure 1498 * \param *ConfigFileName pointer to config file name in **argv 1499 * \param *PathToDatabases pointer to db's path in **argv 1500 * \param &ArgcList list of arguments that we do not parse here 1501 * \return exit code (0 - successful, all else - something's wrong) 1502 */ 1503 static int ParseCommandLineOptions(int argc, char **argv, MoleculeListClass *&molecules, periodentafel *&periode, 1504 config& configuration, char **ConfigFileName, set<int> &ArgcList) 1505 { 1506 Vector x,y,z,n; // coordinates for absolute point in cell volume 1507 ifstream test; 1508 ofstream output; 1509 string line; 1510 bool SaveFlag = false; 1511 int ExitFlag = 0; 1512 int j; 1513 double volume = 0.; 1514 enum ConfigStatus configPresent = absent; 1515 int argptr; 1516 molecule *mol = NULL; 1517 string BondGraphFileName("\n"); 1518 1519 if (argc > 1) { // config file specified as option 1520 // 1. : Parse options that just set variables or print help 1521 argptr = 1; 1522 do { 1523 if (argv[argptr][0] == '-') { 1524 DoLog(0) && (Log() << Verbose(0) << "Recognized command line argument: " << argv[argptr][1] << ".\n"); 1525 argptr++; 1526 switch(argv[argptr-1][1]) { 1527 case 'h': 1528 case 'H': 1529 case '?': 1530 ArgcList.insert(argptr-1); 1531 return(1); 1532 break; 1533 case 'v': 1534 if ((argptr >= argc) || (argv[argptr][0] == '-')) { 1535 DoeLog(0) && (eLog()<< Verbose(0) << "Not enough or invalid arguments for specifying verbosity: -v <level>" << endl); 1536 performCriticalExit(); 1537 } else { 1538 setVerbosity(atoi(argv[argptr])); 1539 ArgcList.insert(argptr-1); 1540 ArgcList.insert(argptr); 1541 argptr++; 1542 } 1543 break; 1544 case 'V': 1545 ArgcList.insert(argptr-1); 1546 return(1); 1547 break; 1548 case 'B': 1549 if (ExitFlag == 0) ExitFlag = 1; 1550 if ((argptr+5 >= argc)) { 1551 DoeLog(0) && (eLog()<< Verbose(0) << "Not enough or invalid arguments for setting Box: -B <xx> <<xy> <<xz> <yy> <yz> <zz>" << endl); 1552 performCriticalExit(); 1553 } else { 1554 ArgcList.insert(argptr-1); 1555 ArgcList.insert(argptr); 1556 ArgcList.insert(argptr+1); 1557 ArgcList.insert(argptr+2); 1558 ArgcList.insert(argptr+3); 1559 ArgcList.insert(argptr+4); 1560 ArgcList.insert(argptr+5); 1561 argptr+=6; 1562 } 1563 break; 1564 case 'e': 1565 if ((argptr >= argc) || (argv[argptr][0] == '-')) { 1566 DoeLog(0) && (eLog()<< Verbose(0) << "Not enough or invalid arguments for specifying element db: -e <db file>" << endl); 1567 performCriticalExit(); 1568 } else { 1569 ArgcList.insert(argptr-1); 1570 ArgcList.insert(argptr); 1571 argptr+=1; 1572 } 1573 break; 1574 case 'g': 1575 if ((argptr >= argc) || (argv[argptr][0] == '-')) { 1576 DoeLog(0) && (eLog()<< Verbose(0) << "Not enough or invalid arguments for specifying bond length table: -g <table file>" << endl); 1577 performCriticalExit(); 1578 } else { 1579 ArgcList.insert(argptr-1); 1580 ArgcList.insert(argptr); 1581 argptr+=1; 1582 } 1583 break; 1584 case 'M': 1585 if ((argptr >= argc) || (argv[argptr][0] == '-')) { 1586 ExitFlag = 255; 1587 DoeLog(0) && (eLog()<< Verbose(0) << "Not enough or invalid arguments given for setting MPQC basis: -M <basis name>" << endl); 1588 performCriticalExit(); 1589 } else { 1590 ArgcList.insert(argptr-1); 1591 ArgcList.insert(argptr); 1592 argptr+=1; 1593 } 1594 break; 1595 case 'n': 1596 if ((argptr >= argc) || (argv[argptr][0] == '-')) { 1597 ExitFlag = 255; 1598 DoeLog(0) && (eLog()<< Verbose(0) << "Not enough or invalid arguments given for setting fast-parsing: -n <0/1>" << endl); 1599 performCriticalExit(); 1600 } else { 1601 ArgcList.insert(argptr-1); 1602 ArgcList.insert(argptr); 1603 argptr+=1; 1604 } 1605 break; 1606 case 'X': 1607 if ((argptr >= argc) || (argv[argptr][0] == '-')) { 1608 ExitFlag = 255; 1609 DoeLog(0) && (eLog()<< Verbose(0) << "Not enough or invalid arguments given for setting default molecule name: -X <name>" << endl); 1610 performCriticalExit(); 1611 } else { 1612 ArgcList.insert(argptr-1); 1613 ArgcList.insert(argptr); 1614 argptr+=1; 1615 } 1616 break; 1617 default: // no match? Step on 1618 argptr++; 1619 break; 1620 } 1621 } else 1622 argptr++; 1623 } while (argptr < argc); 1624 1625 // 3b. Find config file name and parse if possible, also BondGraphFileName 1626 if (argv[1][0] != '-') { 1627 // simply create a new molecule, wherein the config file is loaded and the manipulation takes place 1628 DoLog(0) && (Log() << Verbose(0) << "Config file given." << endl); 1629 test.open(argv[1], ios::in); 1630 if (test == NULL) { 1631 //return (1); 1632 output.open(argv[1], ios::out); 1633 if (output == NULL) { 1634 DoLog(1) && (Log() << Verbose(1) << "Specified config file " << argv[1] << " not found." << endl); 1635 configPresent = absent; 1636 } else { 1637 DoLog(0) && (Log() << Verbose(0) << "Empty configuration file." << endl); 1638 strcpy(*ConfigFileName, argv[1]); 1639 configPresent = empty; 1640 output.close(); 1641 } 1642 } else { 1643 test.close(); 1644 strcpy(*ConfigFileName, argv[1]); 1645 DoLog(1) && (Log() << Verbose(1) << "Specified config file found, parsing ... "); 1646 switch (configuration.TestSyntax(*ConfigFileName, periode)) { 1647 case 1: 1648 DoLog(0) && (Log() << Verbose(0) << "new syntax." << endl); 1649 configuration.Load(*ConfigFileName, BondGraphFileName, periode, molecules); 1650 configPresent = present; 1651 break; 1652 case 0: 1653 DoLog(0) && (Log() << Verbose(0) << "old syntax." << endl); 1654 configuration.LoadOld(*ConfigFileName, BondGraphFileName, periode, molecules); 1655 configPresent = present; 1656 break; 1657 default: 1658 DoLog(0) && (Log() << Verbose(0) << "Unknown syntax or empty, yet present file." << endl); 1659 configPresent = empty; 1660 } 1661 } 1662 } else 1663 configPresent = absent; 1664 // set mol to first active molecule 1665 if (molecules->ListOfMolecules.size() != 0) { 1666 for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++) 1667 if ((*ListRunner)->ActiveFlag) { 1668 mol = *ListRunner; 1669 break; 1670 } 1671 } 1672 if (mol == NULL) { 1673 mol = World::getInstance().createMolecule(); 1674 mol->ActiveFlag = true; 1675 if (*ConfigFileName != NULL) 1676 mol->SetNameFromFilename(*ConfigFileName); 1677 molecules->insert(mol); 1678 } 1679 1680 // 4. parse again through options, now for those depending on elements db and config presence 1681 argptr = 1; 1682 do { 1683 DoLog(0) && (Log() << Verbose(0) << "Current Command line argument: " << argv[argptr] << "." << endl); 1684 if (argv[argptr][0] == '-') { 1685 argptr++; 1686 if ((configPresent == present) || (configPresent == empty)) { 1687 switch(argv[argptr-1][1]) { 1688 case 'p': 1689 if (ExitFlag == 0) ExitFlag = 1; 1690 if ((argptr >= argc) || (argv[argptr][0] == '-')) { 1691 ExitFlag = 255; 1692 DoeLog(0) && (eLog()<< Verbose(0) << "Not enough arguments for parsing: -p <xyz file>" << endl); 1693 performCriticalExit(); 1694 } else { 1695 SaveFlag = true; 1696 DoLog(1) && (Log() << Verbose(1) << "Parsing xyz file for new atoms." << endl); 1697 if (!mol->AddXYZFile(argv[argptr])) 1698 DoLog(2) && (Log() << Verbose(2) << "File not found." << endl); 1699 else { 1700 DoLog(2) && (Log() << Verbose(2) << "File found and parsed." << endl); 1701 configPresent = present; 1702 } 1703 } 1704 break; 1705 case 'a': 1706 if (ExitFlag == 0) ExitFlag = 1; 1707 if ((argptr+4 >= argc) || (argv[argptr][0] == '-')) { 1708 ExitFlag = 255; 1709 DoeLog(0) && (eLog()<< Verbose(0) << "Not enough arguments for adding atom: -a <Z> --position <x> <y> <z>" << endl); 1710 performCriticalExit(); 1711 } else { 1712 ArgcList.insert(argptr-1); 1713 ArgcList.insert(argptr); 1714 ArgcList.insert(argptr+1); 1715 ArgcList.insert(argptr+2); 1716 ArgcList.insert(argptr+3); 1717 ArgcList.insert(argptr+4); 1718 argptr+=5; 1719 } 1720 break; 1721 default: // no match? Don't step on (this is done in next switch's default) 1722 break; 1723 } 1724 } 1725 if (configPresent == present) { 1726 switch(argv[argptr-1][1]) { 1727 case 'D': 1728 if (ExitFlag == 0) ExitFlag = 1; 1729 if ((argptr >= argc) || (argv[argptr][0] == '-')) { 1730 ExitFlag = 255; 1731 DoeLog(0) && (eLog()<< Verbose(0) << "Not enough or invalid arguments given for depth-first-search analysis: -D <max. bond distance>" << endl); 1732 performCriticalExit(); 1733 } else { 1734 ArgcList.insert(argptr-1); 1735 ArgcList.insert(argptr); 1736 argptr+=1; 1737 } 1738 break; 1739 case 'I': 1740 DoLog(1) && (Log() << Verbose(1) << "Dissecting molecular system into a set of disconnected subgraphs ... " << endl); 1741 ArgcList.insert(argptr-1); 1742 argptr+=0; 1743 break; 1744 case 'C': 1745 { 1746 if (ExitFlag == 0) ExitFlag = 1; 1747 if ((argptr+11 >= argc)) { 1748 ExitFlag = 255; 1749 DoeLog(0) && (eLog()<< Verbose(0) << "Not enough or invalid arguments given for pair correlation analysis: -C[p] <type: E/P/S> [more params] <output> <bin output> <BinStart> <BinEnd>" << endl); 1750 performCriticalExit(); 1751 } else { 1752 switch(argv[argptr][0]) { 1753 case 'E': 1754 ArgcList.insert(argptr-1); 1755 ArgcList.insert(argptr); 1756 ArgcList.insert(argptr+1); 1757 ArgcList.insert(argptr+2); 1758 ArgcList.insert(argptr+3); 1759 ArgcList.insert(argptr+4); 1760 ArgcList.insert(argptr+5); 1761 ArgcList.insert(argptr+6); 1762 ArgcList.insert(argptr+7); 1763 ArgcList.insert(argptr+8); 1764 ArgcList.insert(argptr+9); 1765 ArgcList.insert(argptr+10); 1766 ArgcList.insert(argptr+11); 1767 argptr+=12; 1768 break; 1769 1770 case 'P': 1771 ArgcList.insert(argptr-1); 1772 ArgcList.insert(argptr); 1773 ArgcList.insert(argptr+1); 1774 ArgcList.insert(argptr+2); 1775 ArgcList.insert(argptr+3); 1776 ArgcList.insert(argptr+4); 1777 ArgcList.insert(argptr+5); 1778 ArgcList.insert(argptr+6); 1779 ArgcList.insert(argptr+7); 1780 ArgcList.insert(argptr+8); 1781 ArgcList.insert(argptr+9); 1782 ArgcList.insert(argptr+10); 1783 ArgcList.insert(argptr+11); 1784 ArgcList.insert(argptr+12); 1785 ArgcList.insert(argptr+13); 1786 ArgcList.insert(argptr+14); 1787 argptr+=15; 1788 break; 1789 1790 case 'S': 1791 ArgcList.insert(argptr-1); 1792 ArgcList.insert(argptr); 1793 ArgcList.insert(argptr+1); 1794 ArgcList.insert(argptr+2); 1795 ArgcList.insert(argptr+3); 1796 ArgcList.insert(argptr+4); 1797 ArgcList.insert(argptr+5); 1798 ArgcList.insert(argptr+6); 1799 ArgcList.insert(argptr+7); 1800 ArgcList.insert(argptr+8); 1801 ArgcList.insert(argptr+9); 1802 ArgcList.insert(argptr+10); 1803 ArgcList.insert(argptr+11); 1804 ArgcList.insert(argptr+12); 1805 ArgcList.insert(argptr+13); 1806 ArgcList.insert(argptr+14); 1807 argptr+=15; 1808 break; 1809 1810 default: 1811 ExitFlag = 255; 1812 DoeLog(0) && (eLog()<< Verbose(0) << "Invalid type given for pair correlation analysis: -C <type: E/P/S> [more params] <output> <bin output>" << endl); 1813 performCriticalExit(); 1814 break; 1815 } 1816 } 1817 break; 1818 } 1819 case 'E': 1820 if (ExitFlag == 0) ExitFlag = 1; 1821 if ((argptr+2 >= argc) || (!IsValidNumber(argv[argptr]))) { 1822 ExitFlag = 255; 1823 DoeLog(0) && (eLog()<< Verbose(0) << "Not enough or invalid arguments given for changing element: -E <atom nr.> --element <Z>" << endl); 1824 performCriticalExit(); 1825 } else { 1826 ArgcList.insert(argptr-1); 1827 ArgcList.insert(argptr); 1828 ArgcList.insert(argptr+1); 1829 ArgcList.insert(argptr+2); 1830 argptr+=3; 1831 } 1832 break; 1833 case 'F': 1834 if (ExitFlag == 0) ExitFlag = 1; 1835 if ((argptr+12 >= argc) || (argv[argptr][0] == '-')) { 1836 ExitFlag = 255; 1837 DoeLog(0) && (eLog()<< Verbose(0) << "Not enough or invalid arguments given for filling with molecule: -F <filler xyz file> --MaxDistance <distance or -1> --distances <x> <y> <z> --lengths <surface> <randatm> <randmol> --DoRotate <0/1>" << endl); 1838 performCriticalExit(); 1839 } else { 1840 ArgcList.insert(argptr-1); 1841 ArgcList.insert(argptr); 1842 ArgcList.insert(argptr+1); 1843 ArgcList.insert(argptr+2); 1844 ArgcList.insert(argptr+3); 1845 ArgcList.insert(argptr+4); 1846 ArgcList.insert(argptr+5); 1847 ArgcList.insert(argptr+6); 1848 ArgcList.insert(argptr+7); 1849 ArgcList.insert(argptr+8); 1850 ArgcList.insert(argptr+9); 1851 ArgcList.insert(argptr+10); 1852 ArgcList.insert(argptr+11); 1853 ArgcList.insert(argptr+12); 1854 argptr+=13; 1855 } 1856 break; 1857 case 'A': 1858 if (ExitFlag == 0) ExitFlag = 1; 1859 if ((argptr+2 >= argc) || (argv[argptr][0] == '-')) { 1860 ExitFlag =255; 1861 DoeLog(0) && (eLog()<< Verbose(0) << "Missing source file for bonds in molecule: -A <bond sourcefile> --molecule-by-id <molecule_id>" << endl); 1862 performCriticalExit(); 1863 } else { 1864 ArgcList.insert(argptr-1); 1865 ArgcList.insert(argptr); 1866 ArgcList.insert(argptr+1); 1867 ArgcList.insert(argptr+2); 1868 argptr+=3; 1869 } 1870 break; 1871 1872 case 'J': 1873 if (ExitFlag == 0) ExitFlag = 1; 1874 if ((argptr+2 >= argc) || (argv[argptr][0] == '-')) { 1875 ExitFlag =255; 1876 DoeLog(0) && (eLog()<< Verbose(0) << "Missing path of adjacency file: -J <path> --molecule-by-id <molecule_id>" << endl); 1877 performCriticalExit(); 1878 } else { 1879 ArgcList.insert(argptr-1); 1880 ArgcList.insert(argptr); 1881 ArgcList.insert(argptr+1); 1882 ArgcList.insert(argptr+2); 1883 argptr+=3; 1884 } 1885 break; 1886 1887 case 'j': 1888 if (ExitFlag == 0) ExitFlag = 1; 1889 if ((argptr >= argc) || (argv[argptr][0] == '-')) { 1890 ExitFlag =255; 1891 DoeLog(0) && (eLog()<< Verbose(0) << "Missing path of bonds file: -j <path> --molecule-by-id <molecule_id>" << endl); 1892 performCriticalExit(); 1893 } else { 1894 ArgcList.insert(argptr-1); 1895 ArgcList.insert(argptr); 1896 ArgcList.insert(argptr+1); 1897 ArgcList.insert(argptr+2); 1898 argptr+=3; 1899 } 1900 break; 1901 1902 case 'N': 1903 if (ExitFlag == 0) ExitFlag = 1; 1904 if ((argptr+4 >= argc) || (argv[argptr][0] == '-')){ 1905 ExitFlag = 255; 1906 DoeLog(0) && (eLog()<< Verbose(0) << "Not enough or invalid arguments given for non-convex envelope: -N <molecule_id> --sphere-radius <radius> --nonconvex-file <output prefix>" << endl); 1907 performCriticalExit(); 1908 } else { 1909 ArgcList.insert(argptr-1); 1910 ArgcList.insert(argptr); 1911 ArgcList.insert(argptr+1); 1912 ArgcList.insert(argptr+2); 1913 ArgcList.insert(argptr+3); 1914 ArgcList.insert(argptr+4); 1915 argptr+=5; 1916 } 1917 break; 1918 case 'S': 1919 if (ExitFlag == 0) ExitFlag = 1; 1920 if ((argptr+2 >= argc) || (argv[argptr][0] == '-')) { 1921 ExitFlag = 255; 1922 DoeLog(0) && (eLog()<< Verbose(0) << "Not enough or invalid arguments given for storing tempature: -S <temperature file> --molecule-by-id 0" << endl); 1923 performCriticalExit(); 1924 } else { 1925 ArgcList.insert(argptr-1); 1926 ArgcList.insert(argptr); 1927 ArgcList.insert(argptr+1); 1928 ArgcList.insert(argptr+2); 1929 argptr+=3; 1930 } 1931 break; 1932 case 'L': 1933 if (ExitFlag == 0) ExitFlag = 1; 1934 if ((argptr+8 >= argc) || (argv[argptr][0] == '-')) { 1935 ExitFlag = 255; 1936 DoeLog(0) && (eLog()<< Verbose(0) << "Not enough or invalid arguments given for linear interpolation: -L <prefix> --start-step <step0> --end-step <step1> --molecule-by-id 0 --id-mapping <0/1>" << endl); 1937 performCriticalExit(); 1938 } else { 1939 ArgcList.insert(argptr-1); 1940 ArgcList.insert(argptr); 1941 ArgcList.insert(argptr+1); 1942 ArgcList.insert(argptr+2); 1943 ArgcList.insert(argptr+3); 1944 ArgcList.insert(argptr+4); 1945 ArgcList.insert(argptr+5); 1946 ArgcList.insert(argptr+6); 1947 ArgcList.insert(argptr+7); 1948 ArgcList.insert(argptr+8); 1949 argptr+=9; 1950 } 1951 break; 1952 case 'P': 1953 if (ExitFlag == 0) ExitFlag = 1; 1954 if ((argptr+2 >= argc) || (argv[argptr][0] == '-')) { 1955 ExitFlag = 255; 1956 DoeLog(0) && (eLog()<< Verbose(0) << "Not enough or invalid arguments given for parsing and integrating forces: -P <forces file> --molecule-by-id <molecule_id>" << endl); 1957 performCriticalExit(); 1958 } else { 1959 ArgcList.insert(argptr-1); 1960 ArgcList.insert(argptr); 1961 ArgcList.insert(argptr+1); 1962 ArgcList.insert(argptr+2); 1963 argptr+=3; 1964 } 1965 break; 1966 case 'R': 1967 if (ExitFlag == 0) ExitFlag = 1; 1968 if ((argptr+4 >= argc) || (argv[argptr][0] == '-')) { 1969 ExitFlag = 255; 1970 DoeLog(0) && (eLog()<< Verbose(0) << "Not enough or invalid arguments given for removing atoms: -R <distance> --position <x> <y> <z>" << endl); 1971 performCriticalExit(); 1972 } else { 1973 ArgcList.insert(argptr-1); 1974 ArgcList.insert(argptr); 1975 ArgcList.insert(argptr+1); 1976 ArgcList.insert(argptr+2); 1977 ArgcList.insert(argptr+3); 1978 ArgcList.insert(argptr+4); 1979 argptr+=5; 1980 } 1981 break; 1982 case 't': 1983 if (ExitFlag == 0) ExitFlag = 1; 1984 if ((argptr+4 >= argc) || (!IsValidNumber(argv[argptr])) || (!IsValidNumber(argv[argptr+1])) || (!IsValidNumber(argv[argptr+2])) ) { 1985 ExitFlag = 255; 1986 DoeLog(0) && (eLog()<< Verbose(0) << "Not enough or invalid arguments given for translation: -t <x> <y> <z> --molecule-by-id <molecule_id> --periodic <0/1>" << endl); 1987 performCriticalExit(); 1988 } else { 1989 ArgcList.insert(argptr-1); 1990 ArgcList.insert(argptr); 1991 ArgcList.insert(argptr+1); 1992 ArgcList.insert(argptr+2); 1993 ArgcList.insert(argptr+3); 1994 ArgcList.insert(argptr+4); 1995 ArgcList.insert(argptr+5); 1996 ArgcList.insert(argptr+6); 1997 argptr+=7; 1998 } 1999 break; 2000 case 's': 2001 if (ExitFlag == 0) ExitFlag = 1; 2002 if ((argptr+2 >= argc) || (!IsValidNumber(argv[argptr])) || (!IsValidNumber(argv[argptr+1])) || (!IsValidNumber(argv[argptr+2])) ) { 2003 ExitFlag = 255; 2004 DoeLog(0) && (eLog()<< Verbose(0) << "Not enough or invalid arguments given for scaling: -s <factor_x> [factor_y] [factor_z]" << endl); 2005 performCriticalExit(); 2006 } else { 2007 ArgcList.insert(argptr-1); 2008 ArgcList.insert(argptr); 2009 ArgcList.insert(argptr+1); 2010 ArgcList.insert(argptr+2); 2011 argptr+=3; 2012 } 2013 break; 2014 case 'b': 2015 if (ExitFlag == 0) ExitFlag = 1; 2016 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])) ) { 2017 ExitFlag = 255; 2018 DoeLog(0) && (eLog()<< Verbose(0) << "Not enough or invalid arguments given for centering in box: -b <xx> <xy> <xz> <yy> <yz> <zz>" << endl); 2019 performCriticalExit(); 2020 } else { 2021 ArgcList.insert(argptr-1); 2022 ArgcList.insert(argptr); 2023 ArgcList.insert(argptr+1); 2024 ArgcList.insert(argptr+2); 2025 ArgcList.insert(argptr+3); 2026 ArgcList.insert(argptr+4); 2027 ArgcList.insert(argptr+5); 2028 argptr+=6; 2029 } 2030 break; 2031 case 'B': 2032 if (ExitFlag == 0) ExitFlag = 1; 2033 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])) ) { 2034 ExitFlag = 255; 2035 DoeLog(0) && (eLog()<< Verbose(0) << "Not enough or invalid arguments given for bounding in box: -B <xx> <xy> <xz> <yy> <yz> <zz>" << endl); 2036 performCriticalExit(); 2037 } else { 2038 ArgcList.insert(argptr-1); 2039 ArgcList.insert(argptr); 2040 ArgcList.insert(argptr+1); 2041 ArgcList.insert(argptr+2); 2042 ArgcList.insert(argptr+3); 2043 ArgcList.insert(argptr+4); 2044 ArgcList.insert(argptr+5); 2045 argptr+=6; 2046 } 2047 break; 2048 case 'c': 2049 if (ExitFlag == 0) ExitFlag = 1; 2050 if ((argptr+2 >= argc) || (argv[argptr][0] == '-') || (!IsValidNumber(argv[argptr])) || (!IsValidNumber(argv[argptr+1])) || (!IsValidNumber(argv[argptr+2])) ) { 2051 ExitFlag = 255; 2052 DoeLog(0) && (eLog()<< Verbose(0) << "Not enough or invalid arguments given for centering with boundary: -c <boundary_x> <boundary_y> <boundary_z>" << endl); 2053 performCriticalExit(); 2054 } else { 2055 ArgcList.insert(argptr-1); 2056 ArgcList.insert(argptr); 2057 ArgcList.insert(argptr+1); 2058 ArgcList.insert(argptr+2); 2059 argptr+=3; 2060 } 2061 break; 2062 case 'O': 2063 if (ExitFlag == 0) ExitFlag = 1; 2064 ArgcList.insert(argptr-1); 2065 argptr+=0; 2066 break; 2067 case 'r': 2068 if (ExitFlag == 0) ExitFlag = 1; 2069 if ((argptr >= argc) || (argv[argptr][0] == '-') || (!IsValidNumber(argv[argptr]))) { 2070 ExitFlag = 255; 2071 DoeLog(0) && (eLog()<< Verbose(0) << "Not enough or invalid arguments given for removing atoms: -r <id>" << endl); 2072 performCriticalExit(); 2073 } else { 2074 ArgcList.insert(argptr-1); 2075 ArgcList.insert(argptr); 2076 argptr+=1; 2077 } 2078 break; 2079 case 'f': 2080 if (ExitFlag == 0) ExitFlag = 1; 2081 if ((argptr+1 >= argc) || (argv[argptr][0] == '-')) { 2082 ExitFlag = 255; 2083 DoeLog(0) && (eLog()<< Verbose(0) << "Not enough or invalid arguments for fragmentation: -f <max. bond distance> <bond order>" << endl); 2084 performCriticalExit(); 2085 } else { 2086 ArgcList.insert(argptr-1); 2087 ArgcList.insert(argptr); 2088 ArgcList.insert(argptr+1); 2089 ArgcList.insert(argptr+2); 2090 ArgcList.insert(argptr+3); 2091 ArgcList.insert(argptr+4); 2092 argptr+=5; 2093 } 2094 break; 2095 case 'm': 2096 if (ExitFlag == 0) ExitFlag = 1; 2097 j = atoi(argv[argptr++]); 2098 if ((j<0) || (j>1)) { 2099 DoeLog(1) && (eLog()<< Verbose(1) << "Argument of '-m' should be either 0 for no-rotate or 1 for rotate." << endl); 2100 j = 0; 2101 } 2102 if (j) { 2103 SaveFlag = true; 2104 DoLog(0) && (Log() << Verbose(0) << "Converting to prinicipal axis system." << endl); 2105 mol->PrincipalAxisSystem((bool)j); 2106 } else 2107 ArgcList.insert(argptr-1); 2108 argptr+=0; 2109 break; 2110 case 'o': 2111 if (ExitFlag == 0) ExitFlag = 1; 2112 if ((argptr+4 >= argc) || (argv[argptr][0] == '-')){ 2113 ExitFlag = 255; 2114 DoeLog(0) && (eLog()<< Verbose(0) << "Not enough or invalid arguments given for convex envelope: -o <molecule_id> --output-file <output file> --output-file <binned output file>" << endl); 2115 performCriticalExit(); 2116 } else { 2117 ArgcList.insert(argptr-1); 2118 ArgcList.insert(argptr); 2119 ArgcList.insert(argptr+1); 2120 ArgcList.insert(argptr+2); 2121 ArgcList.insert(argptr+3); 2122 ArgcList.insert(argptr+4); 2123 argptr+=5; 2124 } 2125 break; 2126 case 'U': 2127 if (ExitFlag == 0) ExitFlag = 1; 2128 if ((argptr+1 >= argc) || (argv[argptr][0] == '-') || (!IsValidNumber(argv[argptr])) || (!IsValidNumber(argv[argptr+1])) ) { 2129 ExitFlag = 255; 2130 DoeLog(0) && (eLog()<< Verbose(0) << "Not enough or invalid arguments given for suspension with specified volume: -U <volume> <density>" << endl); 2131 performCriticalExit(); 2132 } else { 2133 volume = atof(argv[argptr++]); 2134 DoLog(0) && (Log() << Verbose(0) << "Using " << volume << " angstrom^3 as the volume instead of convex envelope one's." << endl); 2135 } 2136 case 'u': 2137 if (ExitFlag == 0) ExitFlag = 1; 2138 if ((argptr >= argc) || (argv[argptr][0] == '-') || (!IsValidNumber(argv[argptr])) ) { 2139 if (volume != -1) 2140 ExitFlag = 255; 2141 DoeLog(0) && (eLog()<< Verbose(0) << "Not enough or invalid arguments given for suspension: -u <density>" << endl); 2142 performCriticalExit(); 2143 } else { 2144 ArgcList.insert(argptr-1); 2145 ArgcList.insert(argptr); 2146 argptr+=1; 2147 } 2148 break; 2149 case 'd': 2150 if (ExitFlag == 0) ExitFlag = 1; 2151 if ((argptr+2 >= argc) || (argv[argptr][0] == '-') || (!IsValidNumber(argv[argptr])) || (!IsValidNumber(argv[argptr+1])) || (!IsValidNumber(argv[argptr+2])) ) { 2152 ExitFlag = 255; 2153 DoeLog(0) && (eLog()<< Verbose(0) << "Not enough or invalid arguments given for repeating cells: -d <repeat_x> <repeat_y> <repeat_z>" << endl); 2154 performCriticalExit(); 2155 } else { 2156 ArgcList.insert(argptr-1); 2157 ArgcList.insert(argptr); 2158 ArgcList.insert(argptr+1); 2159 ArgcList.insert(argptr+2); 2160 argptr+=3; 2161 } 2162 break; 2163 default: // no match? Step on 2164 if ((argptr < argc) && (argv[argptr][0] != '-')) // if it started with a '-' we've already made a step! 2165 argptr++; 2166 break; 2167 } 2168 } 2169 } else argptr++; 2170 } while (argptr < argc); 2171 if (SaveFlag) 2172 configuration.SaveAll(*ConfigFileName, periode, molecules); 2173 } else { // no arguments, hence scan the elements db 2174 if (periode->LoadPeriodentafel(configuration.databasepath)) 2175 DoLog(0) && (Log() << Verbose(0) << "Element list loaded successfully." << endl); 2176 else 2177 DoLog(0) && (Log() << Verbose(0) << "Element list loading failed." << endl); 2178 configuration.RetrieveConfigPathAndName("main_pcp_linux"); 2179 } 2180 return(ExitFlag); 2181 }; 91 2182 92 2183 93 /********************************************** Main routine **************************************/ 2184 94 2185 95 void cleanUp(){ 96 FormatParserStorage::purgeInstance(); 97 ChangeTracker::purgeInstance(); 2186 98 World::purgeInstance(); 2187 99 logger::purgeInstance(); … … 2200 112 int main(int argc, char **argv) 2201 113 { 2202 // while we are non interactive, we want to abort from asserts 2203 //ASSERT_DO(Assert::Abort); 2204 Vector x, y, z, n; 2205 ifstream test; 2206 ofstream output; 2207 string line; 2208 char **Arguments = NULL; 2209 int ArgcSize = 0; 2210 int ExitFlag = 0; 2211 bool ArgumentsCopied = false; 2212 char *ConfigFileName = new char[MAXSTRINGSIZE]; 2213 2214 // print version check whether arguments are present at all 2215 cout << ESPACKVersion << endl; 2216 if (argc < 2) { 2217 cout << "Obtain help with " << argv[0] << " -h." << endl; 2218 cleanUp(); 2219 Memory::getState(); 2220 return(1); 2221 } 2222 2223 2224 setVerbosity(0); 2225 // need to init the history before any action is created 2226 ActionHistory::init(); 2227 2228 // In the interactive mode, we can leave the user the choice in case of error 2229 ASSERT_DO(Assert::Ask); 2230 2231 // from this moment on, we need to be sure to deeinitialize in the correct order 2232 // this is handled by the cleanup function 2233 atexit(cleanUp); 2234 2235 // Parse command line options and if present create respective UI 2236 { 2237 set<int> ArgcList; 2238 ArgcList.insert(0); // push back program! 2239 ArgcList.insert(1); // push back config file name 2240 // handle arguments by ParseCommandLineOptions() 2241 ExitFlag = ParseCommandLineOptions(argc,argv,World::getInstance().getMolecules(),World::getInstance().getPeriode(),*World::getInstance().getConfig(), &ConfigFileName, ArgcList); 2242 World::getInstance().setExitFlag(ExitFlag); 2243 // copy all remaining arguments to a new argv 2244 Arguments = new char *[ArgcList.size()]; 2245 cout << "The following arguments are handled by CommandLineParser: "; 2246 for (set<int>::iterator ArgcRunner = ArgcList.begin(); ArgcRunner != ArgcList.end(); ++ArgcRunner) { 2247 Arguments[ArgcSize] = new char[strlen(argv[*ArgcRunner])+2]; 2248 strcpy(Arguments[ArgcSize], argv[*ArgcRunner]); 2249 cout << " " << argv[*ArgcRunner]; 2250 ArgcSize++; 2251 } 2252 cout << endl; 2253 ArgumentsCopied = true; 2254 // handle remaining arguments by CommandLineParser 2255 MapOfActions::getInstance().AddOptionsToParser(); 2256 map <std::string, std::string> ShortFormToActionMap = MapOfActions::getInstance().getShortFormToActionMap(); 2257 CommandLineParser::getInstance().Run(ArgcSize,Arguments, ShortFormToActionMap); 2258 if (!CommandLineParser::getInstance().isEmpty()) { 2259 DoLog(0) && (Log() << Verbose(0) << "Setting UI to CommandLine." << endl); 2260 UIFactory::registerFactory(new CommandLineUIFactory::description()); 2261 UIFactory::makeUserInterface("CommandLine"); 114 // while we are non interactive, we want to abort from asserts 115 //ASSERT_DO(Assert::Abort); 116 string line; 117 char **Arguments = NULL; 118 int ArgcSize = 0; 119 int ExitFlag = 0; 120 bool ArgumentsCopied = false; 121 std::string BondGraphFileName("\n"); 122 FormatParserStorage::getInstance().addMpqc(); 123 FormatParserStorage::getInstance().addPcp(); 124 FormatParserStorage::getInstance().addXyz(); 125 126 // print version check whether arguments are present at all 127 cout << ESPACKVersion << endl; 128 if (argc < 2) { 129 cout << "Obtain help with " << argv[0] << " -h." << endl; 130 cleanUp(); 131 Memory::getState(); 132 return(1); 133 } 134 135 136 setVerbosity(0); 137 // need to init the history before any action is created 138 ActionHistory::init(); 139 140 // In the interactive mode, we can leave the user the choice in case of error 141 ASSERT_DO(Assert::Ask); 142 143 // from this moment on, we need to be sure to deeinitialize in the correct order 144 // this is handled by the cleanup function 145 atexit(cleanUp); 146 147 // Parse command line options and if present create respective UI 148 { 149 // construct bond graph 150 if (World::getInstance().getConfig()->BG == NULL) { 151 World::getInstance().getConfig()->BG = new BondGraph(World::getInstance().getConfig()->GetIsAngstroem()); 152 if (World::getInstance().getConfig()->BG->LoadBondLengthTable(BondGraphFileName)) { 153 DoLog(0) && (Log() << Verbose(0) << "Bond length table loaded successfully." << endl); 2262 154 } else { 2263 #ifdef USE_GUI_QT 2264 DoLog(0) && (Log() << Verbose(0) << "Setting UI to QT4." << endl); 2265 UIFactory::registerFactory(new QTUIFactory::description()); 2266 UIFactory::makeUserInterface("QT4"); 2267 #else 2268 DoLog(0) && (Log() << Verbose(0) << "Setting UI to Text." << endl); 2269 cout << ESPACKVersion << endl; 2270 UIFactory::registerFactory(new TextUIFactory::description()); 2271 UIFactory::makeUserInterface("Text"); 2272 #endif 155 DoeLog(1) && (eLog()<< Verbose(1) << "Bond length table loading failed." << endl); 2273 156 } 2274 157 } 2275 2276 { 2277 MainWindow *mainWindow = UIFactory::getInstance().makeMainWindow(); 2278 mainWindow->display(); 2279 delete mainWindow; 158 // handle remaining arguments by CommandLineParser 159 MapOfActions::getInstance().AddOptionsToParser(); 160 map <std::string, std::string> ShortFormToActionMap = MapOfActions::getInstance().getShortFormToActionMap(); 161 CommandLineParser::getInstance().Run(argc,argv, ShortFormToActionMap); 162 if (!CommandLineParser::getInstance().isEmpty()) { 163 DoLog(0) && (Log() << Verbose(0) << "Setting UI to CommandLine." << endl); 164 UIFactory::registerFactory(new CommandLineUIFactory::description()); 165 UIFactory::makeUserInterface("CommandLine"); 166 } else { 167 #ifdef USE_GUI_QT 168 DoLog(0) && (Log() << Verbose(0) << "Setting UI to QT4." << endl); 169 UIFactory::registerFactory(new QTUIFactory::description()); 170 UIFactory::makeUserInterface("QT4"); 171 #else 172 DoLog(0) && (Log() << Verbose(0) << "Setting UI to Text." << endl); 173 cout << ESPACKVersion << endl; 174 UIFactory::registerFactory(new TextUIFactory::description()); 175 UIFactory::makeUserInterface("Text"); 176 #endif 2280 177 } 2281 2282 Log() << Verbose(0) << "Saving to " << ConfigFileName << "." << endl; 2283 World::getInstance().getConfig()->SaveAll(ConfigFileName, World::getInstance().getPeriode(), World::getInstance().getMolecules()); 178 } 179 180 { 181 MainWindow *mainWindow = UIFactory::getInstance().makeMainWindow(); 182 mainWindow->display(); 183 delete mainWindow; 184 } 185 186 FormatParserStorage::getInstance().SaveAll(); 187 ChangeTracker::getInstance().saveStatus(); 2284 188 2285 189 // free the new argv … … 2289 193 delete[](Arguments); 2290 194 } 2291 delete[](ConfigFileName);195 //delete[](ConfigFileName); 2292 196 2293 197 ExitFlag = World::getInstance().getExitFlag();
Note:
See TracChangeset
for help on using the changeset viewer.