Changeset 85bc8e
- Timestamp:
- Dec 16, 2009, 12:30:16 PM (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:
- 992a54
- Parents:
- c5f836
- git-author:
- Tillmann Crueger <crueger@…> (12/02/09 16:26:24)
- git-committer:
- Frederik Heber <heber@…> (12/16/09 12:30:16)
- Files:
-
- 2 added
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
doc/Doxyfile
rc5f836 r85bc8e 125 125 # configuration options related to source browsing 126 126 #--------------------------------------------------------------------------- 127 SOURCE_BROWSER = NO127 SOURCE_BROWSER = YES 128 128 INLINE_SOURCES = NO 129 129 STRIP_CODE_COMMENTS = YES -
src/Makefile.am
rc5f836 r85bc8e 5 5 ANALYSISHEADER = analysis_bonds.hpp analysis_correlation.hpp 6 6 7 SOURCE = ${ANALYSISSOURCE} ${ATOMSOURCE} bond.cpp bondgraph.cpp boundary.cpp config.cpp element.cpp ellipsoid.cpp errorlogger.cpp graph.cpp helpers.cpp leastsquaremin.cpp linkedcell.cpp log.cpp logger.cpp memoryusageobserver.cpp moleculelist.cpp molecule.cpp molecule_dynamics.cpp molecule_fragmentation.cpp molecule_geometry.cpp molecule_graph.cpp molecule_pointcloud.cpp parser.cpp periodentafel.cpp tesselation.cpp tesselationhelpers.cpp vector.cpp verbose.cpp 8 HEADER = ${ANALYSISHEADER} ${ATOMHEADER} bond.hpp bondgraph.hpp boundary.hpp config.hpp defs.hpp element.hpp ellipsoid.hpp errorlogger.hpp graph.hpp helpers.hpp leastsquaremin.hpp linkedcell.hpp lists.hpp log.hpp logger.hpp memoryallocator.hpp memoryusageobserver.hpp molecule.hpp molecule_template.hpp parser.hpp periodentafel.hpp stackclass.hpp tesselation.hpp tesselationhelpers.hpp vector.hpp verbose.hpp 7 SOURCE = ${ANALYSISSOURCE} ${ATOMSOURCE} bond.cpp bondgraph.cpp boundary.cpp config.cpp element.cpp ellipsoid.cpp errorlogger.cpp graph.cpp helpers.cpp leastsquaremin.cpp linkedcell.cpp log.cpp logger.cpp memoryusageobserver.cpp moleculelist.cpp molecule.cpp molecule_dynamics.cpp molecule_fragmentation.cpp molecule_geometry.cpp molecule_graph.cpp molecule_pointcloud.cpp parser.cpp periodentafel.cpp tesselation.cpp tesselationhelpers.cpp vector.cpp verbose.cpp menu.cpp 8 HEADER = ${ANALYSISHEADER} ${ATOMHEADER} bond.hpp bondgraph.hpp boundary.hpp config.hpp defs.hpp element.hpp ellipsoid.hpp errorlogger.hpp graph.hpp helpers.hpp leastsquaremin.hpp linkedcell.hpp lists.hpp log.hpp logger.hpp memoryallocator.hpp memoryusageobserver.hpp molecule.hpp molecule_template.hpp parser.hpp periodentafel.hpp stackclass.hpp tesselation.hpp tesselationhelpers.hpp vector.hpp verbose.hpp menu.hpp 9 9 10 10 BOOST_LIB = $(BOOST_LDFLAGS) $(BOOST_MPL_LIB) -
src/builder.cpp
rc5f836 r85bc8e 65 65 #include "molecule.hpp" 66 66 #include "periodentafel.hpp" 67 68 /********************************************* Subsubmenu routine ************************************/ 69 70 /** Submenu for adding atoms to the molecule. 71 * \param *periode periodentafel 72 * \param *molecule molecules with atoms 73 */ 74 static void AddAtoms(periodentafel *periode, molecule *mol) 75 { 76 atom *first, *second, *third, *fourth; 77 Vector **atoms; 78 Vector x,y,z,n; // coordinates for absolute point in cell volume 79 double a,b,c; 80 char choice; // menu choice char 81 bool valid; 82 83 Log() << Verbose(0) << "===========ADD ATOM============================" << endl; 84 Log() << Verbose(0) << " a - state absolute coordinates of atom" << endl; 85 Log() << Verbose(0) << " b - state relative coordinates of atom wrt to reference point" << endl; 86 Log() << Verbose(0) << " c - state relative coordinates of atom wrt to already placed atom" << endl; 87 Log() << Verbose(0) << " d - state two atoms, two angles and a distance" << endl; 88 Log() << Verbose(0) << " e - least square distance position to a set of atoms" << endl; 89 Log() << Verbose(0) << "all else - go back" << endl; 90 Log() << Verbose(0) << "===============================================" << endl; 91 Log() << Verbose(0) << "Note: Specifiy angles in degrees not multiples of Pi!" << endl; 92 Log() << Verbose(0) << "INPUT: "; 93 cin >> choice; 94 95 switch (choice) { 96 default: 97 eLog() << Verbose(2) << "Not a valid choice." << endl; 98 break; 99 case 'a': // absolute coordinates of atom 100 Log() << Verbose(0) << "Enter absolute coordinates." << endl; 101 first = new atom; 102 first->x.AskPosition(mol->cell_size, false); 103 first->type = periode->AskElement(); // give type 104 mol->AddAtom(first); // add to molecule 105 break; 106 107 case 'b': // relative coordinates of atom wrt to reference point 108 first = new atom; 109 valid = true; 110 do { 111 if (!valid) eLog() << Verbose(2) << "Resulting position out of cell." << endl; 112 Log() << Verbose(0) << "Enter reference coordinates." << endl; 113 x.AskPosition(mol->cell_size, true); 114 Log() << Verbose(0) << "Enter relative coordinates." << endl; 115 first->x.AskPosition(mol->cell_size, false); 116 first->x.AddVector((const Vector *)&x); 117 Log() << Verbose(0) << "\n"; 118 } while (!(valid = mol->CheckBounds((const Vector *)&first->x))); 119 first->type = periode->AskElement(); // give type 120 mol->AddAtom(first); // add to molecule 121 break; 122 123 case 'c': // relative coordinates of atom wrt to already placed atom 124 first = new atom; 125 valid = true; 126 do { 127 if (!valid) eLog() << Verbose(2) << "Resulting position out of cell." << endl; 128 second = mol->AskAtom("Enter atom number: "); 129 Log() << Verbose(0) << "Enter relative coordinates." << endl; 130 first->x.AskPosition(mol->cell_size, false); 131 for (int i=NDIM;i--;) { 132 first->x.x[i] += second->x.x[i]; 133 } 134 } while (!(valid = mol->CheckBounds((const Vector *)&first->x))); 135 first->type = periode->AskElement(); // give type 136 mol->AddAtom(first); // add to molecule 137 break; 138 139 case 'd': // two atoms, two angles and a distance 140 first = new atom; 141 valid = true; 142 do { 143 if (!valid) { 144 eLog() << Verbose(2) << "Resulting coordinates out of cell - " << first->x << endl; 145 } 146 Log() << Verbose(0) << "First, we need two atoms, the first atom is the central, while the second is the outer one." << endl; 147 second = mol->AskAtom("Enter central atom: "); 148 third = mol->AskAtom("Enter second atom (specifying the axis for first angle): "); 149 fourth = mol->AskAtom("Enter third atom (specifying a plane for second angle): "); 150 a = ask_value("Enter distance between central (first) and new atom: "); 151 b = ask_value("Enter angle between new, first and second atom (degrees): "); 152 b *= M_PI/180.; 153 bound(&b, 0., 2.*M_PI); 154 c = ask_value("Enter second angle between new and normal vector of plane defined by first, second and third atom (degrees): "); 155 c *= M_PI/180.; 156 bound(&c, -M_PI, M_PI); 157 Log() << Verbose(0) << "radius: " << a << "\t phi: " << b*180./M_PI << "\t theta: " << c*180./M_PI << endl; 158 /* 159 second->Output(1,1,(ofstream *)&cout); 160 third->Output(1,2,(ofstream *)&cout); 161 fourth->Output(1,3,(ofstream *)&cout); 162 n.MakeNormalvector((const vector *)&second->x, (const vector *)&third->x, (const vector *)&fourth->x); 163 x.Copyvector(&second->x); 164 x.SubtractVector(&third->x); 165 x.Copyvector(&fourth->x); 166 x.SubtractVector(&third->x); 167 168 if (!z.SolveSystem(&x,&y,&n, b, c, a)) { 169 Log() << Verbose(0) << "Failure solving self-dependent linear system!" << endl; 170 continue; 171 } 172 Log() << Verbose(0) << "resulting relative coordinates: "; 173 z.Output(); 174 Log() << Verbose(0) << endl; 175 */ 176 // calc axis vector 177 x.CopyVector(&second->x); 178 x.SubtractVector(&third->x); 179 x.Normalize(); 180 Log() << Verbose(0) << "x: ", 181 x.Output(); 182 Log() << Verbose(0) << endl; 183 z.MakeNormalVector(&second->x,&third->x,&fourth->x); 184 Log() << Verbose(0) << "z: ", 185 z.Output(); 186 Log() << Verbose(0) << endl; 187 y.MakeNormalVector(&x,&z); 188 Log() << Verbose(0) << "y: ", 189 y.Output(); 190 Log() << Verbose(0) << endl; 191 192 // rotate vector around first angle 193 first->x.CopyVector(&x); 194 first->x.RotateVector(&z,b - M_PI); 195 Log() << Verbose(0) << "Rotated vector: ", 196 first->x.Output(); 197 Log() << Verbose(0) << endl; 198 // remove the projection onto the rotation plane of the second angle 199 n.CopyVector(&y); 200 n.Scale(first->x.ScalarProduct(&y)); 201 Log() << Verbose(0) << "N1: ", 202 n.Output(); 203 Log() << Verbose(0) << endl; 204 first->x.SubtractVector(&n); 205 Log() << Verbose(0) << "Subtracted vector: ", 206 first->x.Output(); 207 Log() << Verbose(0) << endl; 208 n.CopyVector(&z); 209 n.Scale(first->x.ScalarProduct(&z)); 210 Log() << Verbose(0) << "N2: ", 211 n.Output(); 212 Log() << Verbose(0) << endl; 213 first->x.SubtractVector(&n); 214 Log() << Verbose(0) << "2nd subtracted vector: ", 215 first->x.Output(); 216 Log() << Verbose(0) << endl; 217 218 // rotate another vector around second angle 219 n.CopyVector(&y); 220 n.RotateVector(&x,c - M_PI); 221 Log() << Verbose(0) << "2nd Rotated vector: ", 222 n.Output(); 223 Log() << Verbose(0) << endl; 224 225 // add the two linear independent vectors 226 first->x.AddVector(&n); 227 first->x.Normalize(); 228 first->x.Scale(a); 229 first->x.AddVector(&second->x); 230 231 Log() << Verbose(0) << "resulting coordinates: "; 232 first->x.Output(); 233 Log() << Verbose(0) << endl; 234 } while (!(valid = mol->CheckBounds((const Vector *)&first->x))); 235 first->type = periode->AskElement(); // give type 236 mol->AddAtom(first); // add to molecule 237 break; 238 239 case 'e': // least square distance position to a set of atoms 240 first = new atom; 241 atoms = new (Vector*[128]); 242 valid = true; 243 for(int i=128;i--;) 244 atoms[i] = NULL; 245 int i=0, j=0; 246 Log() << Verbose(0) << "Now we need at least three molecules.\n"; 247 do { 248 Log() << Verbose(0) << "Enter " << i+1 << "th atom: "; 249 cin >> j; 250 if (j != -1) { 251 second = mol->FindAtom(j); 252 atoms[i++] = &(second->x); 253 } 254 } while ((j != -1) && (i<128)); 255 if (i >= 2) { 256 first->x.LSQdistance((const Vector **)atoms, i); 257 258 first->x.Output(); 259 first->type = periode->AskElement(); // give type 260 mol->AddAtom(first); // add to molecule 261 } else { 262 delete first; 263 Log() << Verbose(0) << "Please enter at least two vectors!\n"; 264 } 265 break; 266 }; 267 }; 268 269 /** Submenu for centering the atoms in the molecule. 270 * \param *mol molecule with all the atoms 271 */ 272 static void CenterAtoms(molecule *mol) 273 { 274 Vector x, y, helper; 275 char choice; // menu choice char 276 277 Log() << Verbose(0) << "===========CENTER ATOMS=========================" << endl; 278 Log() << Verbose(0) << " a - on origin" << endl; 279 Log() << Verbose(0) << " b - on center of gravity" << endl; 280 Log() << Verbose(0) << " c - within box with additional boundary" << endl; 281 Log() << Verbose(0) << " d - within given simulation box" << endl; 282 Log() << Verbose(0) << "all else - go back" << endl; 283 Log() << Verbose(0) << "===============================================" << endl; 284 Log() << Verbose(0) << "INPUT: "; 285 cin >> choice; 286 287 switch (choice) { 288 default: 289 Log() << Verbose(0) << "Not a valid choice." << endl; 290 break; 291 case 'a': 292 Log() << Verbose(0) << "Centering atoms in config file on origin." << endl; 293 mol->CenterOrigin(); 294 break; 295 case 'b': 296 Log() << Verbose(0) << "Centering atoms in config file on center of gravity." << endl; 297 mol->CenterPeriodic(); 298 break; 299 case 'c': 300 Log() << Verbose(0) << "Centering atoms in config file within given additional boundary." << endl; 301 for (int i=0;i<NDIM;i++) { 302 Log() << Verbose(0) << "Enter axis " << i << " boundary: "; 303 cin >> y.x[i]; 304 } 305 mol->CenterEdge(&x); // make every coordinate positive 306 mol->Center.AddVector(&y); // translate by boundary 307 helper.CopyVector(&y); 308 helper.Scale(2.); 309 helper.AddVector(&x); 310 mol->SetBoxDimension(&helper); // update Box of atoms by boundary 311 break; 312 case 'd': 313 Log() << Verbose(1) << "Centering atoms in config file within given simulation box." << endl; 314 for (int i=0;i<NDIM;i++) { 315 Log() << Verbose(0) << "Enter axis " << i << " boundary: "; 316 cin >> x.x[i]; 317 } 318 // update Box of atoms by boundary 319 mol->SetBoxDimension(&x); 320 // center 321 mol->CenterInBox(); 322 break; 323 } 324 }; 325 326 /** Submenu for aligning the atoms in the molecule. 327 * \param *periode periodentafel 328 * \param *mol molecule with all the atoms 329 */ 330 static void AlignAtoms(periodentafel *periode, molecule *mol) 331 { 332 atom *first, *second, *third; 333 Vector x,n; 334 char choice; // menu choice char 335 336 Log() << Verbose(0) << "===========ALIGN ATOMS=========================" << endl; 337 Log() << Verbose(0) << " a - state three atoms defining align plane" << endl; 338 Log() << Verbose(0) << " b - state alignment vector" << endl; 339 Log() << Verbose(0) << " c - state two atoms in alignment direction" << endl; 340 Log() << Verbose(0) << " d - align automatically by least square fit" << endl; 341 Log() << Verbose(0) << "all else - go back" << endl; 342 Log() << Verbose(0) << "===============================================" << endl; 343 Log() << Verbose(0) << "INPUT: "; 344 cin >> choice; 345 346 switch (choice) { 347 default: 348 case 'a': // three atoms defining mirror plane 349 first = mol->AskAtom("Enter first atom: "); 350 second = mol->AskAtom("Enter second atom: "); 351 third = mol->AskAtom("Enter third atom: "); 352 353 n.MakeNormalVector((const Vector *)&first->x,(const Vector *)&second->x,(const Vector *)&third->x); 354 break; 355 case 'b': // normal vector of mirror plane 356 Log() << Verbose(0) << "Enter normal vector of mirror plane." << endl; 357 n.AskPosition(mol->cell_size,0); 358 n.Normalize(); 359 break; 360 case 'c': // three atoms defining mirror plane 361 first = mol->AskAtom("Enter first atom: "); 362 second = mol->AskAtom("Enter second atom: "); 363 364 n.CopyVector((const Vector *)&first->x); 365 n.SubtractVector((const Vector *)&second->x); 366 n.Normalize(); 367 break; 368 case 'd': 369 char shorthand[4]; 370 Vector a; 371 struct lsq_params param; 372 do { 373 fprintf(stdout, "Enter the element of atoms to be chosen: "); 374 fscanf(stdin, "%3s", shorthand); 375 } while ((param.type = periode->FindElement(shorthand)) == NULL); 376 Log() << Verbose(0) << "Element is " << param.type->name << endl; 377 mol->GetAlignvector(¶m); 378 for (int i=NDIM;i--;) { 379 x.x[i] = gsl_vector_get(param.x,i); 380 n.x[i] = gsl_vector_get(param.x,i+NDIM); 381 } 382 gsl_vector_free(param.x); 383 Log() << Verbose(0) << "Offset vector: "; 384 x.Output(); 385 Log() << Verbose(0) << endl; 386 n.Normalize(); 387 break; 388 }; 389 Log() << Verbose(0) << "Alignment vector: "; 390 n.Output(); 391 Log() << Verbose(0) << endl; 392 mol->Align(&n); 393 }; 394 395 /** Submenu for mirroring the atoms in the molecule. 396 * \param *mol molecule with all the atoms 397 */ 398 static void MirrorAtoms(molecule *mol) 399 { 400 atom *first, *second, *third; 401 Vector n; 402 char choice; // menu choice char 403 404 Log() << Verbose(0) << "===========MIRROR ATOMS=========================" << endl; 405 Log() << Verbose(0) << " a - state three atoms defining mirror plane" << endl; 406 Log() << Verbose(0) << " b - state normal vector of mirror plane" << endl; 407 Log() << Verbose(0) << " c - state two atoms in normal direction" << endl; 408 Log() << Verbose(0) << "all else - go back" << endl; 409 Log() << Verbose(0) << "===============================================" << endl; 410 Log() << Verbose(0) << "INPUT: "; 411 cin >> choice; 412 413 switch (choice) { 414 default: 415 case 'a': // three atoms defining mirror plane 416 first = mol->AskAtom("Enter first atom: "); 417 second = mol->AskAtom("Enter second atom: "); 418 third = mol->AskAtom("Enter third atom: "); 419 420 n.MakeNormalVector((const Vector *)&first->x,(const Vector *)&second->x,(const Vector *)&third->x); 421 break; 422 case 'b': // normal vector of mirror plane 423 Log() << Verbose(0) << "Enter normal vector of mirror plane." << endl; 424 n.AskPosition(mol->cell_size,0); 425 n.Normalize(); 426 break; 427 case 'c': // three atoms defining mirror plane 428 first = mol->AskAtom("Enter first atom: "); 429 second = mol->AskAtom("Enter second atom: "); 430 431 n.CopyVector((const Vector *)&first->x); 432 n.SubtractVector((const Vector *)&second->x); 433 n.Normalize(); 434 break; 435 }; 436 Log() << Verbose(0) << "Normal vector: "; 437 n.Output(); 438 Log() << Verbose(0) << endl; 439 mol->Mirror((const Vector *)&n); 440 }; 441 442 /** Submenu for removing the atoms from the molecule. 443 * \param *mol molecule with all the atoms 444 */ 445 static void RemoveAtoms(molecule *mol) 446 { 447 atom *first, *second; 448 int axis; 449 double tmp1, tmp2; 450 char choice; // menu choice char 451 452 Log() << Verbose(0) << "===========REMOVE ATOMS=========================" << endl; 453 Log() << Verbose(0) << " a - state atom for removal by number" << endl; 454 Log() << Verbose(0) << " b - keep only in radius around atom" << endl; 455 Log() << Verbose(0) << " c - remove this with one axis greater value" << endl; 456 Log() << Verbose(0) << "all else - go back" << endl; 457 Log() << Verbose(0) << "===============================================" << endl; 458 Log() << Verbose(0) << "INPUT: "; 459 cin >> choice; 460 461 switch (choice) { 462 default: 463 case 'a': 464 if (mol->RemoveAtom(mol->AskAtom("Enter number of atom within molecule: "))) 465 Log() << Verbose(1) << "Atom removed." << endl; 466 else 467 Log() << Verbose(1) << "Atom not found." << endl; 468 break; 469 case 'b': 470 second = mol->AskAtom("Enter number of atom as reference point: "); 471 Log() << Verbose(0) << "Enter radius: "; 472 cin >> tmp1; 473 first = mol->start; 474 second = first->next; 475 while(second != mol->end) { 476 first = second; 477 second = first->next; 478 if (first->x.DistanceSquared((const Vector *)&second->x) > tmp1*tmp1) // distance to first above radius ... 479 mol->RemoveAtom(first); 480 } 481 break; 482 case 'c': 483 Log() << Verbose(0) << "Which axis is it: "; 484 cin >> axis; 485 Log() << Verbose(0) << "Lower boundary: "; 486 cin >> tmp1; 487 Log() << Verbose(0) << "Upper boundary: "; 488 cin >> tmp2; 489 first = mol->start; 490 second = first->next; 491 while(second != mol->end) { 492 first = second; 493 second = first->next; 494 if ((first->x.x[axis] < tmp1) || (first->x.x[axis] > tmp2)) {// out of boundary ... 495 //Log() << Verbose(0) << "Atom " << *first << " with " << first->x.x[axis] << " on axis " << axis << " is out of bounds [" << tmp1 << "," << tmp2 << "]." << endl; 496 mol->RemoveAtom(first); 497 } 498 } 499 break; 500 }; 501 //mol->Output(); 502 choice = 'r'; 503 }; 504 505 /** Submenu for measuring out the atoms in the molecule. 506 * \param *periode periodentafel 507 * \param *mol molecule with all the atoms 508 */ 509 static void MeasureAtoms(periodentafel *periode, molecule *mol, config *configuration) 510 { 511 atom *first, *second, *third; 512 Vector x,y; 513 double min[256], tmp1, tmp2, tmp3; 514 int Z; 515 char choice; // menu choice char 516 517 Log() << Verbose(0) << "===========MEASURE ATOMS=========================" << endl; 518 Log() << Verbose(0) << " a - calculate bond length between one atom and all others" << endl; 519 Log() << Verbose(0) << " b - calculate bond length between two atoms" << endl; 520 Log() << Verbose(0) << " c - calculate bond angle" << endl; 521 Log() << Verbose(0) << " d - calculate principal axis of the system" << endl; 522 Log() << Verbose(0) << " e - calculate volume of the convex envelope" << endl; 523 Log() << Verbose(0) << " f - calculate temperature from current velocity" << endl; 524 Log() << Verbose(0) << " g - output all temperatures per step from velocities" << endl; 525 Log() << Verbose(0) << "all else - go back" << endl; 526 Log() << Verbose(0) << "===============================================" << endl; 527 Log() << Verbose(0) << "INPUT: "; 528 cin >> choice; 529 530 switch(choice) { 531 default: 532 Log() << Verbose(1) << "Not a valid choice." << endl; 533 break; 534 case 'a': 535 first = mol->AskAtom("Enter first atom: "); 536 for (int i=MAX_ELEMENTS;i--;) 537 min[i] = 0.; 538 539 second = mol->start; 540 while ((second->next != mol->end)) { 541 second = second->next; // advance 542 Z = second->type->Z; 543 tmp1 = 0.; 544 if (first != second) { 545 x.CopyVector((const Vector *)&first->x); 546 x.SubtractVector((const Vector *)&second->x); 547 tmp1 = x.Norm(); 548 } 549 if ((tmp1 != 0.) && ((min[Z] == 0.) || (tmp1 < min[Z]))) min[Z] = tmp1; 550 //Log() << Verbose(0) << "Bond length between Atom " << first->nr << " and " << second->nr << ": " << tmp1 << " a.u." << endl; 551 } 552 for (int i=MAX_ELEMENTS;i--;) 553 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; 554 break; 555 556 case 'b': 557 first = mol->AskAtom("Enter first atom: "); 558 second = mol->AskAtom("Enter second atom: "); 559 for (int i=NDIM;i--;) 560 min[i] = 0.; 561 x.CopyVector((const Vector *)&first->x); 562 x.SubtractVector((const Vector *)&second->x); 563 tmp1 = x.Norm(); 564 Log() << Verbose(1) << "Distance vector is "; 565 x.Output(); 566 Log() << Verbose(0) << "." << endl << "Norm of distance is " << tmp1 << "." << endl; 567 break; 568 569 case 'c': 570 Log() << Verbose(0) << "Evaluating bond angle between three - first, central, last - atoms." << endl; 571 first = mol->AskAtom("Enter first atom: "); 572 second = mol->AskAtom("Enter central atom: "); 573 third = mol->AskAtom("Enter last atom: "); 574 tmp1 = tmp2 = tmp3 = 0.; 575 x.CopyVector((const Vector *)&first->x); 576 x.SubtractVector((const Vector *)&second->x); 577 y.CopyVector((const Vector *)&third->x); 578 y.SubtractVector((const Vector *)&second->x); 579 Log() << Verbose(0) << "Bond angle between first atom Nr." << first->nr << ", central atom Nr." << second->nr << " and last atom Nr." << third->nr << ": "; 580 Log() << Verbose(0) << (acos(x.ScalarProduct((const Vector *)&y)/(y.Norm()*x.Norm()))/M_PI*180.) << " degrees" << endl; 581 break; 582 case 'd': 583 Log() << Verbose(0) << "Evaluating prinicipal axis." << endl; 584 Log() << Verbose(0) << "Shall we rotate? [0/1]: "; 585 cin >> Z; 586 if ((Z >=0) && (Z <=1)) 587 mol->PrincipalAxisSystem((bool)Z); 588 else 589 mol->PrincipalAxisSystem(false); 590 break; 591 case 'e': 592 { 593 Log() << Verbose(0) << "Evaluating volume of the convex envelope."; 594 class Tesselation *TesselStruct = NULL; 595 const LinkedCell *LCList = NULL; 596 LCList = new LinkedCell(mol, 10.); 597 FindConvexBorder(mol, TesselStruct, LCList, NULL); 598 double clustervolume = VolumeOfConvexEnvelope(TesselStruct, configuration); 599 Log() << Verbose(0) << "The tesselated surface area is " << clustervolume << "." << endl;\ 600 delete(LCList); 601 delete(TesselStruct); 602 } 603 break; 604 case 'f': 605 mol->OutputTemperatureFromTrajectories((ofstream *)&cout, mol->MDSteps-1, mol->MDSteps); 606 break; 607 case 'g': 608 { 609 char filename[255]; 610 Log() << Verbose(0) << "Please enter filename: " << endl; 611 cin >> filename; 612 Log() << Verbose(1) << "Storing temperatures in " << filename << "." << endl; 613 ofstream *output = new ofstream(filename, ios::trunc); 614 if (!mol->OutputTemperatureFromTrajectories(output, 0, mol->MDSteps)) 615 Log() << Verbose(2) << "File could not be written." << endl; 616 else 617 Log() << Verbose(2) << "File stored." << endl; 618 output->close(); 619 delete(output); 620 } 621 break; 622 } 623 }; 624 625 /** Submenu for measuring out the atoms in the molecule. 626 * \param *mol molecule with all the atoms 627 * \param *configuration configuration structure for the to be written config files of all fragments 628 */ 629 static void FragmentAtoms(molecule *mol, config *configuration) 630 { 631 int Order1; 632 clock_t start, end; 633 634 Log() << Verbose(0) << "Fragmenting molecule with current connection matrix ..." << endl; 635 Log() << Verbose(0) << "What's the desired bond order: "; 636 cin >> Order1; 637 if (mol->first->next != mol->last) { // there are bonds 638 start = clock(); 639 mol->FragmentMolecule(Order1, configuration); 640 end = clock(); 641 Log() << Verbose(0) << "Clocks for this operation: " << (end-start) << ", time: " << ((double)(end-start)/CLOCKS_PER_SEC) << "s." << endl; 642 } else 643 Log() << Verbose(0) << "Connection matrix has not yet been generated!" << endl; 644 }; 645 646 /********************************************** Submenu routine **************************************/ 647 648 /** Submenu for manipulating atoms. 649 * \param *periode periodentafel 650 * \param *molecules list of molecules whose atoms are to be manipulated 651 */ 652 static void ManipulateAtoms(periodentafel *periode, MoleculeListClass *molecules, config *configuration) 653 { 654 atom *first, *second; 655 molecule *mol = NULL; 656 Vector x,y,z,n; // coordinates for absolute point in cell volume 657 double *factor; // unit factor if desired 658 double bond, minBond; 659 char choice; // menu choice char 660 bool valid; 661 662 Log() << Verbose(0) << "=========MANIPULATE ATOMS======================" << endl; 663 Log() << Verbose(0) << "a - add an atom" << endl; 664 Log() << Verbose(0) << "r - remove an atom" << endl; 665 Log() << Verbose(0) << "b - scale a bond between atoms" << endl; 666 Log() << Verbose(0) << "u - change an atoms element" << endl; 667 Log() << Verbose(0) << "l - measure lengths, angles, ... for an atom" << endl; 668 Log() << Verbose(0) << "all else - go back" << endl; 669 Log() << Verbose(0) << "===============================================" << endl; 670 if (molecules->NumberOfActiveMolecules() > 1) 671 eLog() << Verbose(2) << "There is more than one molecule active! Atoms will be added to each." << endl; 672 Log() << Verbose(0) << "INPUT: "; 673 cin >> choice; 674 675 switch (choice) { 676 default: 677 Log() << Verbose(0) << "Not a valid choice." << endl; 678 break; 679 680 case 'a': // add atom 681 for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++) 682 if ((*ListRunner)->ActiveFlag) { 683 mol = *ListRunner; 684 Log() << Verbose(0) << "Current molecule is: " << mol->IndexNr << "\t" << mol->name << endl; 685 AddAtoms(periode, mol); 686 } 687 break; 688 689 case 'b': // scale a bond 690 for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++) 691 if ((*ListRunner)->ActiveFlag) { 692 mol = *ListRunner; 693 Log() << Verbose(0) << "Current molecule is: " << mol->IndexNr << "\t" << mol->name << endl; 694 Log() << Verbose(0) << "Scaling bond length between two atoms." << endl; 695 first = mol->AskAtom("Enter first (fixed) atom: "); 696 second = mol->AskAtom("Enter second (shifting) atom: "); 697 minBond = 0.; 698 for (int i=NDIM;i--;) 699 minBond += (first->x.x[i]-second->x.x[i])*(first->x.x[i] - second->x.x[i]); 700 minBond = sqrt(minBond); 701 Log() << Verbose(0) << "Current Bond length between " << first->type->name << " Atom " << first->nr << " and " << second->type->name << " Atom " << second->nr << ": " << minBond << " a.u." << endl; 702 Log() << Verbose(0) << "Enter new bond length [a.u.]: "; 703 cin >> bond; 704 for (int i=NDIM;i--;) { 705 second->x.x[i] -= (second->x.x[i]-first->x.x[i])/minBond*(minBond-bond); 706 } 707 //Log() << Verbose(0) << "New coordinates of Atom " << second->nr << " are: "; 708 //second->Output(second->type->No, 1); 709 } 710 break; 711 712 case 'c': // unit scaling of the metric 713 for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++) 714 if ((*ListRunner)->ActiveFlag) { 715 mol = *ListRunner; 716 Log() << Verbose(0) << "Current molecule is: " << mol->IndexNr << "\t" << mol->name << endl; 717 Log() << Verbose(0) << "Angstroem -> Bohrradius: 1.8897261\t\tBohrradius -> Angstroem: 0.52917721" << endl; 718 Log() << Verbose(0) << "Enter three factors: "; 719 factor = new double[NDIM]; 720 cin >> factor[0]; 721 cin >> factor[1]; 722 cin >> factor[2]; 723 valid = true; 724 mol->Scale((const double ** const)&factor); 725 delete[](factor); 726 } 727 break; 728 729 case 'l': // measure distances or angles 730 for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++) 731 if ((*ListRunner)->ActiveFlag) { 732 mol = *ListRunner; 733 Log() << Verbose(0) << "Current molecule is: " << mol->IndexNr << "\t" << mol->name << endl; 734 MeasureAtoms(periode, mol, configuration); 735 } 736 break; 737 738 case 'r': // remove atom 739 for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++) 740 if ((*ListRunner)->ActiveFlag) { 741 mol = *ListRunner; 742 Log() << Verbose(0) << "Current molecule is: " << mol->IndexNr << "\t" << mol->name << endl; 743 RemoveAtoms(mol); 744 } 745 break; 746 747 case 'u': // change an atom's element 748 for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++) 749 if ((*ListRunner)->ActiveFlag) { 750 int Z; 751 mol = *ListRunner; 752 Log() << Verbose(0) << "Current molecule is: " << mol->IndexNr << "\t" << mol->name << endl; 753 first = NULL; 754 do { 755 Log() << Verbose(0) << "Change the element of which atom: "; 756 cin >> Z; 757 } while ((first = mol->FindAtom(Z)) == NULL); 758 Log() << Verbose(0) << "New element by atomic number Z: "; 759 cin >> Z; 760 first->type = periode->FindElement(Z); 761 Log() << Verbose(0) << "Atom " << first->nr << "'s element is " << first->type->name << "." << endl; 762 } 763 break; 764 } 765 }; 766 767 /** Submenu for manipulating molecules. 768 * \param *periode periodentafel 769 * \param *molecules list of molecule to manipulate 770 */ 771 static void ManipulateMolecules(periodentafel *periode, MoleculeListClass *molecules, config *configuration) 772 { 773 atom *first = NULL; 774 Vector x,y,z,n; // coordinates for absolute point in cell volume 775 int j, axis, count, faktor; 776 char choice; // menu choice char 777 molecule *mol = NULL; 778 element **Elements; 779 Vector **vectors; 780 MoleculeLeafClass *Subgraphs = NULL; 781 782 Log() << Verbose(0) << "=========MANIPULATE GLOBALLY===================" << endl; 783 Log() << Verbose(0) << "c - scale by unit transformation" << endl; 784 Log() << Verbose(0) << "d - duplicate molecule/periodic cell" << endl; 785 Log() << Verbose(0) << "f - fragment molecule many-body bond order style" << endl; 786 Log() << Verbose(0) << "g - center atoms in box" << endl; 787 Log() << Verbose(0) << "i - realign molecule" << endl; 788 Log() << Verbose(0) << "m - mirror all molecules" << endl; 789 Log() << Verbose(0) << "o - create connection matrix" << endl; 790 Log() << Verbose(0) << "t - translate molecule by vector" << endl; 791 Log() << Verbose(0) << "all else - go back" << endl; 792 Log() << Verbose(0) << "===============================================" << endl; 793 if (molecules->NumberOfActiveMolecules() > 1) 794 eLog() << Verbose(2) << "There is more than one molecule active! Atoms will be added to each." << endl; 795 Log() << Verbose(0) << "INPUT: "; 796 cin >> choice; 797 798 switch (choice) { 799 default: 800 Log() << Verbose(0) << "Not a valid choice." << endl; 801 break; 802 803 case 'd': // duplicate the periodic cell along a given axis, given times 804 for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++) 805 if ((*ListRunner)->ActiveFlag) { 806 mol = *ListRunner; 807 Log() << Verbose(0) << "Current molecule is: " << mol->IndexNr << "\t" << mol->name << endl; 808 Log() << Verbose(0) << "State the axis [(+-)123]: "; 809 cin >> axis; 810 Log() << Verbose(0) << "State the factor: "; 811 cin >> faktor; 812 813 mol->CountAtoms(); // recount atoms 814 if (mol->AtomCount != 0) { // if there is more than none 815 count = mol->AtomCount; // is changed becausing of adding, thus has to be stored away beforehand 816 Elements = new element *[count]; 817 vectors = new Vector *[count]; 818 j = 0; 819 first = mol->start; 820 while (first->next != mol->end) { // make a list of all atoms with coordinates and element 821 first = first->next; 822 Elements[j] = first->type; 823 vectors[j] = &first->x; 824 j++; 825 } 826 if (count != j) 827 eLog() << Verbose(1) << "AtomCount " << count << " is not equal to number of atoms in molecule " << j << "!" << endl; 828 x.Zero(); 829 y.Zero(); 830 y.x[abs(axis)-1] = mol->cell_size[(abs(axis) == 2) ? 2 : ((abs(axis) == 3) ? 5 : 0)] * abs(axis)/axis; // last term is for sign, first is for magnitude 831 for (int i=1;i<faktor;i++) { // then add this list with respective translation factor times 832 x.AddVector(&y); // per factor one cell width further 833 for (int k=count;k--;) { // go through every atom of the original cell 834 first = new atom(); // create a new body 835 first->x.CopyVector(vectors[k]); // use coordinate of original atom 836 first->x.AddVector(&x); // translate the coordinates 837 first->type = Elements[k]; // insert original element 838 mol->AddAtom(first); // and add to the molecule (which increments ElementsInMolecule, AtomCount, ...) 839 } 840 } 841 if (mol->first->next != mol->last) // if connect matrix is present already, redo it 842 mol->CreateAdjacencyList(mol->BondDistance, configuration->GetIsAngstroem(), &BondGraph::CovalentMinMaxDistance, NULL); 843 // free memory 844 delete[](Elements); 845 delete[](vectors); 846 // correct cell size 847 if (axis < 0) { // if sign was negative, we have to translate everything 848 x.Zero(); 849 x.AddVector(&y); 850 x.Scale(-(faktor-1)); 851 mol->Translate(&x); 852 } 853 mol->cell_size[(abs(axis) == 2) ? 2 : ((abs(axis) == 3) ? 5 : 0)] *= faktor; 854 } 855 } 856 break; 857 858 case 'f': 859 FragmentAtoms(mol, configuration); 860 break; 861 862 case 'g': // center the atoms 863 for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++) 864 if ((*ListRunner)->ActiveFlag) { 865 mol = *ListRunner; 866 Log() << Verbose(0) << "Current molecule is: " << mol->IndexNr << "\t" << mol->name << endl; 867 CenterAtoms(mol); 868 } 869 break; 870 871 case 'i': // align all atoms 872 for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++) 873 if ((*ListRunner)->ActiveFlag) { 874 mol = *ListRunner; 875 Log() << Verbose(0) << "Current molecule is: " << mol->IndexNr << "\t" << mol->name << endl; 876 AlignAtoms(periode, mol); 877 } 878 break; 879 880 case 'm': // mirror atoms along a given axis 881 for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++) 882 if ((*ListRunner)->ActiveFlag) { 883 mol = *ListRunner; 884 Log() << Verbose(0) << "Current molecule is: " << mol->IndexNr << "\t" << mol->name << endl; 885 MirrorAtoms(mol); 886 } 887 break; 888 889 case 'o': // create the connection matrix 890 for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++) 891 if ((*ListRunner)->ActiveFlag) { 892 mol = *ListRunner; 893 double bonddistance; 894 clock_t start,end; 895 Log() << Verbose(0) << "What's the maximum bond distance: "; 896 cin >> bonddistance; 897 start = clock(); 898 mol->CreateAdjacencyList(bonddistance, configuration->GetIsAngstroem(), &BondGraph::CovalentMinMaxDistance, NULL); 899 end = clock(); 900 Log() << Verbose(0) << "Clocks for this operation: " << (end-start) << ", time: " << ((double)(end-start)/CLOCKS_PER_SEC) << "s." << endl; 901 } 902 break; 903 904 case 't': // translate all atoms 905 for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++) 906 if ((*ListRunner)->ActiveFlag) { 907 mol = *ListRunner; 908 Log() << Verbose(0) << "Current molecule is: " << mol->IndexNr << "\t" << mol->name << endl; 909 Log() << Verbose(0) << "Enter translation vector." << endl; 910 x.AskPosition(mol->cell_size,0); 911 mol->Center.AddVector((const Vector *)&x); 912 } 913 break; 914 } 915 // Free all 916 if (Subgraphs != NULL) { // free disconnected subgraph list of DFS analysis was performed 917 while (Subgraphs->next != NULL) { 918 Subgraphs = Subgraphs->next; 919 delete(Subgraphs->previous); 920 } 921 delete(Subgraphs); 922 } 923 }; 924 925 926 /** Submenu for creating new molecules. 927 * \param *periode periodentafel 928 * \param *molecules list of molecules to add to 929 */ 930 static void EditMolecules(periodentafel *periode, MoleculeListClass *molecules) 931 { 932 char choice; // menu choice char 933 Vector center; 934 int nr, count; 935 molecule *mol = NULL; 936 937 Log() << Verbose(0) << "==========EDIT MOLECULES=====================" << endl; 938 Log() << Verbose(0) << "c - create new molecule" << endl; 939 Log() << Verbose(0) << "l - load molecule from xyz file" << endl; 940 Log() << Verbose(0) << "n - change molecule's name" << endl; 941 Log() << Verbose(0) << "N - give molecules filename" << endl; 942 Log() << Verbose(0) << "p - parse atoms in xyz file into molecule" << endl; 943 Log() << Verbose(0) << "r - remove a molecule" << endl; 944 Log() << Verbose(0) << "all else - go back" << endl; 945 Log() << Verbose(0) << "===============================================" << endl; 946 Log() << Verbose(0) << "INPUT: "; 947 cin >> choice; 948 949 switch (choice) { 950 default: 951 Log() << Verbose(0) << "Not a valid choice." << endl; 952 break; 953 case 'c': 954 mol = new molecule(periode); 955 molecules->insert(mol); 956 break; 957 958 case 'l': // load from XYZ file 959 { 960 char filename[MAXSTRINGSIZE]; 961 Log() << Verbose(0) << "Format should be XYZ with: ShorthandOfElement\tX\tY\tZ" << endl; 962 mol = new molecule(periode); 963 do { 964 Log() << Verbose(0) << "Enter file name: "; 965 cin >> filename; 966 } while (!mol->AddXYZFile(filename)); 967 mol->SetNameFromFilename(filename); 968 // center at set box dimensions 969 mol->CenterEdge(¢er); 970 mol->cell_size[0] = center.x[0]; 971 mol->cell_size[1] = 0; 972 mol->cell_size[2] = center.x[1]; 973 mol->cell_size[3] = 0; 974 mol->cell_size[4] = 0; 975 mol->cell_size[5] = center.x[2]; 976 molecules->insert(mol); 977 } 978 break; 979 980 case 'n': 981 { 982 char filename[MAXSTRINGSIZE]; 983 do { 984 Log() << Verbose(0) << "Enter index of molecule: "; 985 cin >> nr; 986 mol = molecules->ReturnIndex(nr); 987 } while (mol == NULL); 988 Log() << Verbose(0) << "Enter name: "; 989 cin >> filename; 990 strcpy(mol->name, filename); 991 } 992 break; 993 994 case 'N': 995 { 996 char filename[MAXSTRINGSIZE]; 997 do { 998 Log() << Verbose(0) << "Enter index of molecule: "; 999 cin >> nr; 1000 mol = molecules->ReturnIndex(nr); 1001 } while (mol == NULL); 1002 Log() << Verbose(0) << "Enter name: "; 1003 cin >> filename; 1004 mol->SetNameFromFilename(filename); 1005 } 1006 break; 1007 1008 case 'p': // parse XYZ file 1009 { 1010 char filename[MAXSTRINGSIZE]; 1011 mol = NULL; 1012 do { 1013 Log() << Verbose(0) << "Enter index of molecule: "; 1014 cin >> nr; 1015 mol = molecules->ReturnIndex(nr); 1016 } while (mol == NULL); 1017 Log() << Verbose(0) << "Format should be XYZ with: ShorthandOfElement\tX\tY\tZ" << endl; 1018 do { 1019 Log() << Verbose(0) << "Enter file name: "; 1020 cin >> filename; 1021 } while (!mol->AddXYZFile(filename)); 1022 mol->SetNameFromFilename(filename); 1023 } 1024 break; 1025 1026 case 'r': 1027 Log() << Verbose(0) << "Enter index of molecule: "; 1028 cin >> nr; 1029 count = 1; 1030 for(MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++) 1031 if (nr == (*ListRunner)->IndexNr) { 1032 mol = *ListRunner; 1033 molecules->ListOfMolecules.erase(ListRunner); 1034 delete(mol); 1035 break; 1036 } 1037 break; 1038 } 1039 }; 1040 1041 1042 /** Submenu for merging molecules. 1043 * \param *periode periodentafel 1044 * \param *molecules list of molecules to add to 1045 */ 1046 static void MergeMolecules(periodentafel *periode, MoleculeListClass *molecules) 1047 { 1048 char choice; // menu choice char 1049 1050 Log() << Verbose(0) << "===========MERGE MOLECULES=====================" << endl; 1051 Log() << Verbose(0) << "a - simple add of one molecule to another" << endl; 1052 Log() << Verbose(0) << "e - embedding merge of two molecules" << endl; 1053 Log() << Verbose(0) << "m - multi-merge of all molecules" << endl; 1054 Log() << Verbose(0) << "s - scatter merge of two molecules" << endl; 1055 Log() << Verbose(0) << "t - simple merge of two molecules" << endl; 1056 Log() << Verbose(0) << "all else - go back" << endl; 1057 Log() << Verbose(0) << "===============================================" << endl; 1058 Log() << Verbose(0) << "INPUT: "; 1059 cin >> choice; 1060 1061 switch (choice) { 1062 default: 1063 Log() << Verbose(0) << "Not a valid choice." << endl; 1064 break; 1065 1066 case 'a': 1067 { 1068 int src, dest; 1069 molecule *srcmol = NULL, *destmol = NULL; 1070 { 1071 do { 1072 Log() << Verbose(0) << "Enter index of destination molecule: "; 1073 cin >> dest; 1074 destmol = molecules->ReturnIndex(dest); 1075 } while ((destmol == NULL) && (dest != -1)); 1076 do { 1077 Log() << Verbose(0) << "Enter index of source molecule to add from: "; 1078 cin >> src; 1079 srcmol = molecules->ReturnIndex(src); 1080 } while ((srcmol == NULL) && (src != -1)); 1081 if ((src != -1) && (dest != -1)) 1082 molecules->SimpleAdd(srcmol, destmol); 1083 } 1084 } 1085 break; 1086 1087 case 'e': 1088 { 1089 int src, dest; 1090 molecule *srcmol = NULL, *destmol = NULL; 1091 do { 1092 Log() << Verbose(0) << "Enter index of matrix molecule (the variable one): "; 1093 cin >> src; 1094 srcmol = molecules->ReturnIndex(src); 1095 } while ((srcmol == NULL) && (src != -1)); 1096 do { 1097 Log() << Verbose(0) << "Enter index of molecule to merge into (the fixed one): "; 1098 cin >> dest; 1099 destmol = molecules->ReturnIndex(dest); 1100 } while ((destmol == NULL) && (dest != -1)); 1101 if ((src != -1) && (dest != -1)) 1102 molecules->EmbedMerge(destmol, srcmol); 1103 } 1104 break; 1105 1106 case 'm': 1107 { 1108 int nr; 1109 molecule *mol = NULL; 1110 do { 1111 Log() << Verbose(0) << "Enter index of molecule to merge into: "; 1112 cin >> nr; 1113 mol = molecules->ReturnIndex(nr); 1114 } while ((mol == NULL) && (nr != -1)); 1115 if (nr != -1) { 1116 int N = molecules->ListOfMolecules.size()-1; 1117 int *src = new int(N); 1118 for(MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++) 1119 if ((*ListRunner)->IndexNr != nr) 1120 src[N++] = (*ListRunner)->IndexNr; 1121 molecules->SimpleMultiMerge(mol, src, N); 1122 delete[](src); 1123 } 1124 } 1125 break; 1126 1127 case 's': 1128 Log() << Verbose(0) << "Not implemented yet." << endl; 1129 break; 1130 1131 case 't': 1132 { 1133 int src, dest; 1134 molecule *srcmol = NULL, *destmol = NULL; 1135 { 1136 do { 1137 Log() << Verbose(0) << "Enter index of destination molecule: "; 1138 cin >> dest; 1139 destmol = molecules->ReturnIndex(dest); 1140 } while ((destmol == NULL) && (dest != -1)); 1141 do { 1142 Log() << Verbose(0) << "Enter index of source molecule to merge into: "; 1143 cin >> src; 1144 srcmol = molecules->ReturnIndex(src); 1145 } while ((srcmol == NULL) && (src != -1)); 1146 if ((src != -1) && (dest != -1)) 1147 molecules->SimpleMerge(srcmol, destmol); 1148 } 1149 } 1150 break; 1151 } 1152 }; 1153 1154 1155 /********************************************** Test routine **************************************/ 1156 1157 /** Is called always as option 'T' in the menu. 1158 * \param *molecules list of molecules 1159 */ 1160 static void testroutine(MoleculeListClass *molecules) 1161 { 1162 // the current test routine checks the functionality of the KeySet&Graph concept: 1163 // We want to have a multiindex (the KeySet) describing a unique subgraph 1164 int i, comp, counter=0; 1165 1166 // create a clone 1167 molecule *mol = NULL; 1168 if (molecules->ListOfMolecules.size() != 0) // clone 1169 mol = (molecules->ListOfMolecules.front())->CopyMolecule(); 1170 else { 1171 eLog() << Verbose(0) << "I don't have anything to test on ... "; 1172 performCriticalExit(); 1173 return; 1174 } 1175 atom *Walker = mol->start; 1176 1177 // generate some KeySets 1178 Log() << Verbose(0) << "Generating KeySets." << endl; 1179 KeySet TestSets[mol->AtomCount+1]; 1180 i=1; 1181 while (Walker->next != mol->end) { 1182 Walker = Walker->next; 1183 for (int j=0;j<i;j++) { 1184 TestSets[j].insert(Walker->nr); 1185 } 1186 i++; 1187 } 1188 Log() << Verbose(0) << "Testing insertion of already present item in KeySets." << endl; 1189 KeySetTestPair test; 1190 test = TestSets[mol->AtomCount-1].insert(Walker->nr); 1191 if (test.second) { 1192 Log() << Verbose(1) << "Insertion worked?!" << endl; 1193 } else { 1194 Log() << Verbose(1) << "Insertion rejected: Present object is " << (*test.first) << "." << endl; 1195 } 1196 TestSets[mol->AtomCount].insert(mol->end->previous->nr); 1197 TestSets[mol->AtomCount].insert(mol->end->previous->previous->previous->nr); 1198 1199 // constructing Graph structure 1200 Log() << Verbose(0) << "Generating Subgraph class." << endl; 1201 Graph Subgraphs; 1202 1203 // insert KeySets into Subgraphs 1204 Log() << Verbose(0) << "Inserting KeySets into Subgraph class." << endl; 1205 for (int j=0;j<mol->AtomCount;j++) { 1206 Subgraphs.insert(GraphPair (TestSets[j],pair<int, double>(counter++, 1.))); 1207 } 1208 Log() << Verbose(0) << "Testing insertion of already present item in Subgraph." << endl; 1209 GraphTestPair test2; 1210 test2 = Subgraphs.insert(GraphPair (TestSets[mol->AtomCount],pair<int, double>(counter++, 1.))); 1211 if (test2.second) { 1212 Log() << Verbose(1) << "Insertion worked?!" << endl; 1213 } else { 1214 Log() << Verbose(1) << "Insertion rejected: Present object is " << (*(test2.first)).second.first << "." << endl; 1215 } 1216 1217 // show graphs 1218 Log() << Verbose(0) << "Showing Subgraph's contents, checking that it's sorted." << endl; 1219 Graph::iterator A = Subgraphs.begin(); 1220 while (A != Subgraphs.end()) { 1221 Log() << Verbose(0) << (*A).second.first << ": "; 1222 KeySet::iterator key = (*A).first.begin(); 1223 comp = -1; 1224 while (key != (*A).first.end()) { 1225 if ((*key) > comp) 1226 Log() << Verbose(0) << (*key) << " "; 1227 else 1228 Log() << Verbose(0) << (*key) << "! "; 1229 comp = (*key); 1230 key++; 1231 } 1232 Log() << Verbose(0) << endl; 1233 A++; 1234 } 1235 delete(mol); 1236 }; 1237 1238 /** Tries given filename or standard on saving the config file. 1239 * \param *ConfigFileName name of file 1240 * \param *configuration pointer to configuration structure with all the values 1241 * \param *periode pointer to periodentafel structure with all the elements 1242 * \param *molecules list of molecules structure with all the atoms and coordinates 1243 */ 1244 static void SaveConfig(char *ConfigFileName, config *configuration, periodentafel *periode, MoleculeListClass *molecules) 1245 { 1246 char filename[MAXSTRINGSIZE]; 1247 ofstream output; 1248 molecule *mol = new molecule(periode); 1249 1250 if (!strcmp(configuration->configpath, configuration->GetDefaultPath())) { 1251 eLog() << Verbose(2) << "config is found under different path then stated in config file::defaultpath!" << endl; 1252 } 1253 1254 1255 // first save as PDB data 1256 if (ConfigFileName != NULL) 1257 strcpy(filename, ConfigFileName); 1258 if (output == NULL) 1259 strcpy(filename,"main_pcp_linux"); 1260 Log() << Verbose(0) << "Saving as pdb input "; 1261 if (configuration->SavePDB(filename, molecules)) 1262 Log() << Verbose(0) << "done." << endl; 1263 else 1264 Log() << Verbose(0) << "failed." << endl; 1265 1266 // then save as tremolo data file 1267 if (ConfigFileName != NULL) 1268 strcpy(filename, ConfigFileName); 1269 if (output == NULL) 1270 strcpy(filename,"main_pcp_linux"); 1271 Log() << Verbose(0) << "Saving as tremolo data input "; 1272 if (configuration->SaveTREMOLO(filename, molecules)) 1273 Log() << Verbose(0) << "done." << endl; 1274 else 1275 Log() << Verbose(0) << "failed." << endl; 1276 1277 // translate each to its center and merge all molecules in MoleculeListClass into this molecule 1278 int N = molecules->ListOfMolecules.size(); 1279 int *src = new int[N]; 1280 N=0; 1281 for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++) { 1282 src[N++] = (*ListRunner)->IndexNr; 1283 (*ListRunner)->Translate(&(*ListRunner)->Center); 1284 } 1285 molecules->SimpleMultiAdd(mol, src, N); 1286 delete[](src); 1287 1288 // ... and translate back 1289 for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++) { 1290 (*ListRunner)->Center.Scale(-1.); 1291 (*ListRunner)->Translate(&(*ListRunner)->Center); 1292 (*ListRunner)->Center.Scale(-1.); 1293 } 1294 1295 Log() << Verbose(0) << "Storing configuration ... " << endl; 1296 // get correct valence orbitals 1297 mol->CalculateOrbitals(*configuration); 1298 configuration->InitMaxMinStopStep = configuration->MaxMinStopStep = configuration->MaxPsiDouble; 1299 if (ConfigFileName != NULL) { // test the file name 1300 strcpy(filename, ConfigFileName); 1301 output.open(filename, ios::trunc); 1302 } else if (strlen(configuration->configname) != 0) { 1303 strcpy(filename, configuration->configname); 1304 output.open(configuration->configname, ios::trunc); 1305 } else { 1306 strcpy(filename, DEFAULTCONFIG); 1307 output.open(DEFAULTCONFIG, ios::trunc); 1308 } 1309 output.close(); 1310 output.clear(); 1311 Log() << Verbose(0) << "Saving of config file "; 1312 if (configuration->Save(filename, periode, mol)) 1313 Log() << Verbose(0) << "successful." << endl; 1314 else 1315 Log() << Verbose(0) << "failed." << endl; 1316 1317 // and save to xyz file 1318 if (ConfigFileName != NULL) { 1319 strcpy(filename, ConfigFileName); 1320 strcat(filename, ".xyz"); 1321 output.open(filename, ios::trunc); 1322 } 1323 if (output == NULL) { 1324 strcpy(filename,"main_pcp_linux"); 1325 strcat(filename, ".xyz"); 1326 output.open(filename, ios::trunc); 1327 } 1328 Log() << Verbose(0) << "Saving of XYZ file "; 1329 if (mol->MDSteps <= 1) { 1330 if (mol->OutputXYZ(&output)) 1331 Log() << Verbose(0) << "successful." << endl; 1332 else 1333 Log() << Verbose(0) << "failed." << endl; 1334 } else { 1335 if (mol->OutputTrajectoriesXYZ(&output)) 1336 Log() << Verbose(0) << "successful." << endl; 1337 else 1338 Log() << Verbose(0) << "failed." << endl; 1339 } 1340 output.close(); 1341 output.clear(); 1342 1343 // and save as MPQC configuration 1344 if (ConfigFileName != NULL) 1345 strcpy(filename, ConfigFileName); 1346 if (output == NULL) 1347 strcpy(filename,"main_pcp_linux"); 1348 Log() << Verbose(0) << "Saving as mpqc input "; 1349 if (configuration->SaveMPQC(filename, mol)) 1350 Log() << Verbose(0) << "done." << endl; 1351 else 1352 Log() << Verbose(0) << "failed." << endl; 1353 1354 if (!strcmp(configuration->configpath, configuration->GetDefaultPath())) { 1355 eLog() << Verbose(2) << "config is found under different path then stated in config file::defaultpath!" << endl; 1356 } 1357 1358 delete(mol); 1359 }; 67 #include "menu.hpp" 1360 68 1361 69 /** Parses the command line options. … … 1369 77 * \return exit code (0 - successful, all else - something's wrong) 1370 78 */ 1371 static int ParseCommandLineOptions(int argc, char **argv, MoleculeListClass *&molecules, periodentafel *&periode, config& configuration, char *&ConfigFileName) 79 static int ParseCommandLineOptions(int argc, char **argv, MoleculeListClass *&molecules, periodentafel *&periode,\ 80 config& configuration, char *&ConfigFileName, menu *main_menu) 1372 81 { 1373 82 Vector x,y,z,n; // coordinates for absolute point in cell volume … … 2170 879 } while (argptr < argc); 2171 880 if (SaveFlag) 2172 SaveConfig(ConfigFileName, &configuration, periode, molecules);881 main_menu->SaveConfig(ConfigFileName, &configuration, periode, molecules); 2173 882 } else { // no arguments, hence scan the elements db 2174 883 if (periode->LoadPeriodentafel(configuration.databasepath)) … … 2185 894 int main(int argc, char **argv) 2186 895 { 2187 periodentafel *periode = new periodentafel; // and a period table of all elements 2188 MoleculeListClass *molecules = new MoleculeListClass; // list of all molecules 2189 molecule *mol = NULL; 2190 config *configuration = new config; 2191 char choice; // menu choice char 2192 Vector x,y,z,n; // coordinates for absolute point in cell volume 2193 ifstream test; 2194 ofstream output; 2195 string line; 2196 char *ConfigFileName = NULL; 2197 int j; 2198 2199 setVerbosity(0); 2200 2201 // =========================== PARSE COMMAND LINE OPTIONS ==================================== 2202 j = ParseCommandLineOptions(argc, argv, molecules, periode, *configuration, ConfigFileName); 2203 switch(j) { 2204 case 255: // something went wrong 2205 case 2: // just for -f option 2206 case 1: // just for -v and -h options 2207 delete(molecules); // also free's all molecules contained 2208 delete(periode); 2209 delete(configuration); 2210 Log() << Verbose(0) << "Maximum of allocated memory: " 2211 << MemoryUsageObserver::getInstance()->getMaximumUsedMemory() << endl; 2212 Log() << Verbose(0) << "Remaining non-freed memory: " 2213 << MemoryUsageObserver::getInstance()->getUsedMemorySize() << endl; 2214 MemoryUsageObserver::getInstance()->purgeInstance(); 2215 logger::purgeInstance(); 2216 errorLogger::purgeInstance(); 2217 return (j == 1 ? 0 : j); 2218 default: 2219 break; 2220 } 2221 2222 // General stuff 2223 if (molecules->ListOfMolecules.size() == 0) { 2224 mol = new molecule(periode); 2225 if (mol->cell_size[0] == 0.) { 2226 Log() << Verbose(0) << "enter lower tridiagonal form of basis matrix" << endl << endl; 2227 for (int i=0;i<6;i++) { 2228 Log() << Verbose(1) << "Cell size" << i << ": "; 2229 cin >> mol->cell_size[i]; 2230 } 896 periodentafel *periode = new periodentafel; 897 MoleculeListClass *molecules = new MoleculeListClass; 898 molecule *mol = NULL; 899 config *configuration = new config; 900 Vector x, y, z, n; 901 ifstream test; 902 ofstream output; 903 string line; 904 char *ConfigFileName = NULL; 905 int j; 906 menu *main_menu; 907 main_menu = new menu; 908 setVerbosity(0); 909 /* main menu is needed to call actions inside the menu */ 910 /* structure of ParseCommandLineOptions will be refactored later */ 911 j = ParseCommandLineOptions(argc, argv, molecules, periode, *configuration, ConfigFileName,main_menu); 912 switch (j){ 913 case 255: 914 case 2: 915 case 1: 916 delete (molecules); 917 delete (periode); 918 delete (configuration); 919 Log() << Verbose(0) << "Maximum of allocated memory: " << MemoryUsageObserver::getInstance()->getMaximumUsedMemory() << endl; 920 Log() << Verbose(0) << "Remaining non-freed memory: " << MemoryUsageObserver::getInstance()->getUsedMemorySize() << endl; 921 MemoryUsageObserver::getInstance()->purgeInstance(); 922 logger::purgeInstance(); 923 errorLogger::purgeInstance(); 924 return (j == 1 ? 0 : j); 925 default: 926 break; 2231 927 } 2232 mol->ActiveFlag = true; 2233 molecules->insert(mol); 2234 } 2235 2236 // =========================== START INTERACTIVE SESSION ==================================== 2237 2238 // now the main construction loop 2239 Log() << Verbose(0) << endl << "Now comes the real construction..." << endl; 2240 do { 2241 Log() << Verbose(0) << endl << endl; 2242 Log() << Verbose(0) << "============Molecule list=======================" << endl; 2243 molecules->Enumerate((ofstream *)&cout); 2244 Log() << Verbose(0) << "============Menu===============================" << endl; 2245 Log() << Verbose(0) << "a - set molecule (in)active" << endl; 2246 Log() << Verbose(0) << "e - edit molecules (load, parse, save)" << endl; 2247 Log() << Verbose(0) << "g - globally manipulate atoms in molecule" << endl; 2248 Log() << Verbose(0) << "M - Merge molecules" << endl; 2249 Log() << Verbose(0) << "m - manipulate atoms" << endl; 2250 Log() << Verbose(0) << "-----------------------------------------------" << endl; 2251 Log() << Verbose(0) << "c - edit the current configuration" << endl; 2252 Log() << Verbose(0) << "-----------------------------------------------" << endl; 2253 Log() << Verbose(0) << "s - save current setup to config file" << endl; 2254 Log() << Verbose(0) << "T - call the current test routine" << endl; 2255 Log() << Verbose(0) << "q - quit" << endl; 2256 Log() << Verbose(0) << "===============================================" << endl; 2257 Log() << Verbose(0) << "Input: "; 2258 cin >> choice; 2259 2260 switch (choice) { 2261 case 'a': // (in)activate molecule 2262 { 2263 Log() << Verbose(0) << "Enter index of molecule: "; 2264 cin >> j; 2265 for(MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++) 2266 if ((*ListRunner)->IndexNr == j) 2267 (*ListRunner)->ActiveFlag = !(*ListRunner)->ActiveFlag; 928 if(molecules->ListOfMolecules.size() == 0){ 929 mol = new molecule(periode); 930 if(mol->cell_size[0] == 0.){ 931 Log() << Verbose(0) << "enter lower tridiagonal form of basis matrix" << endl << endl; 932 for(int i = 0;i < 6;i++){ 933 Log() << Verbose(1) << "Cell size" << i << ": "; 934 cin >> mol->cell_size[i]; 935 } 2268 936 } 2269 break; 2270 2271 case 'c': // edit each field of the configuration 2272 configuration->Edit(); 2273 break; 2274 2275 case 'e': // create molecule 2276 EditMolecules(periode, molecules); 2277 break; 2278 2279 case 'g': // manipulate molecules 2280 ManipulateMolecules(periode, molecules, configuration); 2281 break; 2282 2283 case 'M': // merge molecules 2284 MergeMolecules(periode, molecules); 2285 break; 2286 2287 case 'm': // manipulate atoms 2288 ManipulateAtoms(periode, molecules, configuration); 2289 break; 2290 2291 case 'q': // quit 2292 break; 2293 2294 case 's': // save to config file 2295 SaveConfig(ConfigFileName, configuration, periode, molecules); 2296 break; 2297 2298 case 'T': 2299 testroutine(molecules); 2300 break; 2301 2302 default: 2303 break; 2304 }; 2305 } while (choice != 'q'); 2306 2307 // save element data base 2308 if (periode->StorePeriodentafel(configuration->databasepath)) //ElementsFileName 2309 Log() << Verbose(0) << "Saving of elements.db successful." << endl; 2310 else 2311 Log() << Verbose(0) << "Saving of elements.db failed." << endl; 2312 2313 delete(molecules); // also free's all molecules contained 2314 delete(periode); 937 938 mol->ActiveFlag = true; 939 molecules->insert(mol); 940 } 941 942 943 944 main_menu->perform(molecules, configuration, periode, ConfigFileName); 945 946 if(periode->StorePeriodentafel(configuration->databasepath)) 947 Log() << Verbose(0) << "Saving of elements.db successful." << endl; 948 949 else 950 Log() << Verbose(0) << "Saving of elements.db failed." << endl; 951 952 delete (molecules); 953 delete(periode); 2315 954 delete(configuration); 2316 955
Note:
See TracChangeset
for help on using the changeset viewer.