Changeset b8d1aeb for src/builder.cpp
- Timestamp:
- Feb 2, 2010, 11:38:06 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:
- 7ba324
- Parents:
- 9fe36b (diff), 2ededc2 (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
r9fe36b rb8d1aeb 52 52 using namespace std; 53 53 54 #include <cstring> 55 54 56 #include "analysis_correlation.hpp" 55 57 #include "atom.hpp" … … 74 76 #include "Actions/MethodAction.hpp" 75 77 #include "Actions/small_actions.hpp" 76 78 #include "version.h" 79 80 /********************************************* Subsubmenu routine ************************************/ 81 #if 0 82 /** Submenu for adding atoms to the molecule. 83 * \param *periode periodentafel 84 * \param *molecule molecules with atoms 85 */ 86 static void AddAtoms(periodentafel *periode, molecule *mol) 87 { 88 atom *first, *second, *third, *fourth; 89 Vector **atoms; 90 Vector x,y,z,n; // coordinates for absolute point in cell volume 91 double a,b,c; 92 char choice; // menu choice char 93 bool valid; 94 95 Log() << Verbose(0) << "===========ADD ATOM============================" << endl; 96 Log() << Verbose(0) << " a - state absolute coordinates of atom" << endl; 97 Log() << Verbose(0) << " b - state relative coordinates of atom wrt to reference point" << endl; 98 Log() << Verbose(0) << " c - state relative coordinates of atom wrt to already placed atom" << endl; 99 Log() << Verbose(0) << " d - state two atoms, two angles and a distance" << endl; 100 Log() << Verbose(0) << " e - least square distance position to a set of atoms" << endl; 101 Log() << Verbose(0) << "all else - go back" << endl; 102 Log() << Verbose(0) << "===============================================" << endl; 103 Log() << Verbose(0) << "Note: Specifiy angles in degrees not multiples of Pi!" << endl; 104 Log() << Verbose(0) << "INPUT: "; 105 cin >> choice; 106 107 switch (choice) { 108 default: 109 eLog() << Verbose(2) << "Not a valid choice." << endl; 110 break; 111 case 'a': // absolute coordinates of atom 112 Log() << Verbose(0) << "Enter absolute coordinates." << endl; 113 first = new atom; 114 first->x.AskPosition(mol->cell_size, false); 115 first->type = periode->AskElement(); // give type 116 mol->AddAtom(first); // add to molecule 117 break; 118 119 case 'b': // relative coordinates of atom wrt to reference point 120 first = new atom; 121 valid = true; 122 do { 123 if (!valid) eLog() << Verbose(2) << "Resulting position out of cell." << endl; 124 Log() << Verbose(0) << "Enter reference coordinates." << endl; 125 x.AskPosition(mol->cell_size, true); 126 Log() << Verbose(0) << "Enter relative coordinates." << endl; 127 first->x.AskPosition(mol->cell_size, false); 128 first->x.AddVector((const Vector *)&x); 129 Log() << Verbose(0) << "\n"; 130 } while (!(valid = mol->CheckBounds((const Vector *)&first->x))); 131 first->type = periode->AskElement(); // give type 132 mol->AddAtom(first); // add to molecule 133 break; 134 135 case 'c': // relative coordinates of atom wrt to already placed atom 136 first = new atom; 137 valid = true; 138 do { 139 if (!valid) eLog() << Verbose(2) << "Resulting position out of cell." << endl; 140 second = mol->AskAtom("Enter atom number: "); 141 Log() << Verbose(0) << "Enter relative coordinates." << endl; 142 first->x.AskPosition(mol->cell_size, false); 143 for (int i=NDIM;i--;) { 144 first->x.x[i] += second->x.x[i]; 145 } 146 } while (!(valid = mol->CheckBounds((const Vector *)&first->x))); 147 first->type = periode->AskElement(); // give type 148 mol->AddAtom(first); // add to molecule 149 break; 150 151 case 'd': // two atoms, two angles and a distance 152 first = new atom; 153 valid = true; 154 do { 155 if (!valid) { 156 eLog() << Verbose(2) << "Resulting coordinates out of cell - " << first->x << endl; 157 } 158 Log() << Verbose(0) << "First, we need two atoms, the first atom is the central, while the second is the outer one." << endl; 159 second = mol->AskAtom("Enter central atom: "); 160 third = mol->AskAtom("Enter second atom (specifying the axis for first angle): "); 161 fourth = mol->AskAtom("Enter third atom (specifying a plane for second angle): "); 162 a = ask_value("Enter distance between central (first) and new atom: "); 163 b = ask_value("Enter angle between new, first and second atom (degrees): "); 164 b *= M_PI/180.; 165 bound(&b, 0., 2.*M_PI); 166 c = ask_value("Enter second angle between new and normal vector of plane defined by first, second and third atom (degrees): "); 167 c *= M_PI/180.; 168 bound(&c, -M_PI, M_PI); 169 Log() << Verbose(0) << "radius: " << a << "\t phi: " << b*180./M_PI << "\t theta: " << c*180./M_PI << endl; 170 /* 171 second->Output(1,1,(ofstream *)&cout); 172 third->Output(1,2,(ofstream *)&cout); 173 fourth->Output(1,3,(ofstream *)&cout); 174 n.MakeNormalvector((const vector *)&second->x, (const vector *)&third->x, (const vector *)&fourth->x); 175 x.Copyvector(&second->x); 176 x.SubtractVector(&third->x); 177 x.Copyvector(&fourth->x); 178 x.SubtractVector(&third->x); 179 180 if (!z.SolveSystem(&x,&y,&n, b, c, a)) { 181 Log() << Verbose(0) << "Failure solving self-dependent linear system!" << endl; 182 continue; 183 } 184 Log() << Verbose(0) << "resulting relative coordinates: "; 185 z.Output(); 186 Log() << Verbose(0) << endl; 187 */ 188 // calc axis vector 189 x.CopyVector(&second->x); 190 x.SubtractVector(&third->x); 191 x.Normalize(); 192 Log() << Verbose(0) << "x: ", 193 x.Output(); 194 Log() << Verbose(0) << endl; 195 z.MakeNormalVector(&second->x,&third->x,&fourth->x); 196 Log() << Verbose(0) << "z: ", 197 z.Output(); 198 Log() << Verbose(0) << endl; 199 y.MakeNormalVector(&x,&z); 200 Log() << Verbose(0) << "y: ", 201 y.Output(); 202 Log() << Verbose(0) << endl; 203 204 // rotate vector around first angle 205 first->x.CopyVector(&x); 206 first->x.RotateVector(&z,b - M_PI); 207 Log() << Verbose(0) << "Rotated vector: ", 208 first->x.Output(); 209 Log() << Verbose(0) << endl; 210 // remove the projection onto the rotation plane of the second angle 211 n.CopyVector(&y); 212 n.Scale(first->x.ScalarProduct(&y)); 213 Log() << Verbose(0) << "N1: ", 214 n.Output(); 215 Log() << Verbose(0) << endl; 216 first->x.SubtractVector(&n); 217 Log() << Verbose(0) << "Subtracted vector: ", 218 first->x.Output(); 219 Log() << Verbose(0) << endl; 220 n.CopyVector(&z); 221 n.Scale(first->x.ScalarProduct(&z)); 222 Log() << Verbose(0) << "N2: ", 223 n.Output(); 224 Log() << Verbose(0) << endl; 225 first->x.SubtractVector(&n); 226 Log() << Verbose(0) << "2nd subtracted vector: ", 227 first->x.Output(); 228 Log() << Verbose(0) << endl; 229 230 // rotate another vector around second angle 231 n.CopyVector(&y); 232 n.RotateVector(&x,c - M_PI); 233 Log() << Verbose(0) << "2nd Rotated vector: ", 234 n.Output(); 235 Log() << Verbose(0) << endl; 236 237 // add the two linear independent vectors 238 first->x.AddVector(&n); 239 first->x.Normalize(); 240 first->x.Scale(a); 241 first->x.AddVector(&second->x); 242 243 Log() << Verbose(0) << "resulting coordinates: "; 244 first->x.Output(); 245 Log() << Verbose(0) << endl; 246 } while (!(valid = mol->CheckBounds((const Vector *)&first->x))); 247 first->type = periode->AskElement(); // give type 248 mol->AddAtom(first); // add to molecule 249 break; 250 251 case 'e': // least square distance position to a set of atoms 252 first = new atom; 253 atoms = new (Vector*[128]); 254 valid = true; 255 for(int i=128;i--;) 256 atoms[i] = NULL; 257 int i=0, j=0; 258 Log() << Verbose(0) << "Now we need at least three molecules.\n"; 259 do { 260 Log() << Verbose(0) << "Enter " << i+1 << "th atom: "; 261 cin >> j; 262 if (j != -1) { 263 second = mol->FindAtom(j); 264 atoms[i++] = &(second->x); 265 } 266 } while ((j != -1) && (i<128)); 267 if (i >= 2) { 268 first->x.LSQdistance((const Vector **)atoms, i); 269 270 first->x.Output(); 271 first->type = periode->AskElement(); // give type 272 mol->AddAtom(first); // add to molecule 273 } else { 274 delete first; 275 Log() << Verbose(0) << "Please enter at least two vectors!\n"; 276 } 277 break; 278 }; 279 }; 280 281 /** Submenu for centering the atoms in the molecule. 282 * \param *mol molecule with all the atoms 283 */ 284 static void CenterAtoms(molecule *mol) 285 { 286 Vector x, y, helper; 287 char choice; // menu choice char 288 289 Log() << Verbose(0) << "===========CENTER ATOMS=========================" << endl; 290 Log() << Verbose(0) << " a - on origin" << endl; 291 Log() << Verbose(0) << " b - on center of gravity" << endl; 292 Log() << Verbose(0) << " c - within box with additional boundary" << endl; 293 Log() << Verbose(0) << " d - within given simulation box" << endl; 294 Log() << Verbose(0) << "all else - go back" << endl; 295 Log() << Verbose(0) << "===============================================" << endl; 296 Log() << Verbose(0) << "INPUT: "; 297 cin >> choice; 298 299 switch (choice) { 300 default: 301 Log() << Verbose(0) << "Not a valid choice." << endl; 302 break; 303 case 'a': 304 Log() << Verbose(0) << "Centering atoms in config file on origin." << endl; 305 mol->CenterOrigin(); 306 break; 307 case 'b': 308 Log() << Verbose(0) << "Centering atoms in config file on center of gravity." << endl; 309 mol->CenterPeriodic(); 310 break; 311 case 'c': 312 Log() << Verbose(0) << "Centering atoms in config file within given additional boundary." << endl; 313 for (int i=0;i<NDIM;i++) { 314 Log() << Verbose(0) << "Enter axis " << i << " boundary: "; 315 cin >> y.x[i]; 316 } 317 mol->CenterEdge(&x); // make every coordinate positive 318 mol->Center.AddVector(&y); // translate by boundary 319 helper.CopyVector(&y); 320 helper.Scale(2.); 321 helper.AddVector(&x); 322 mol->SetBoxDimension(&helper); // update Box of atoms by boundary 323 break; 324 case 'd': 325 Log() << Verbose(1) << "Centering atoms in config file within given simulation box." << endl; 326 for (int i=0;i<NDIM;i++) { 327 Log() << Verbose(0) << "Enter axis " << i << " boundary: "; 328 cin >> x.x[i]; 329 } 330 // update Box of atoms by boundary 331 mol->SetBoxDimension(&x); 332 // center 333 mol->CenterInBox(); 334 break; 335 } 336 }; 337 338 /** Submenu for aligning the atoms in the molecule. 339 * \param *periode periodentafel 340 * \param *mol molecule with all the atoms 341 */ 342 static void AlignAtoms(periodentafel *periode, molecule *mol) 343 { 344 atom *first, *second, *third; 345 Vector x,n; 346 char choice; // menu choice char 347 348 Log() << Verbose(0) << "===========ALIGN ATOMS=========================" << endl; 349 Log() << Verbose(0) << " a - state three atoms defining align plane" << endl; 350 Log() << Verbose(0) << " b - state alignment vector" << endl; 351 Log() << Verbose(0) << " c - state two atoms in alignment direction" << endl; 352 Log() << Verbose(0) << " d - align automatically by least square fit" << endl; 353 Log() << Verbose(0) << "all else - go back" << endl; 354 Log() << Verbose(0) << "===============================================" << endl; 355 Log() << Verbose(0) << "INPUT: "; 356 cin >> choice; 357 358 switch (choice) { 359 default: 360 case 'a': // three atoms defining mirror plane 361 first = mol->AskAtom("Enter first atom: "); 362 second = mol->AskAtom("Enter second atom: "); 363 third = mol->AskAtom("Enter third atom: "); 364 365 n.MakeNormalVector((const Vector *)&first->x,(const Vector *)&second->x,(const Vector *)&third->x); 366 break; 367 case 'b': // normal vector of mirror plane 368 Log() << Verbose(0) << "Enter normal vector of mirror plane." << endl; 369 n.AskPosition(mol->cell_size,0); 370 n.Normalize(); 371 break; 372 case 'c': // three atoms defining mirror plane 373 first = mol->AskAtom("Enter first atom: "); 374 second = mol->AskAtom("Enter second atom: "); 375 376 n.CopyVector((const Vector *)&first->x); 377 n.SubtractVector((const Vector *)&second->x); 378 n.Normalize(); 379 break; 380 case 'd': 381 char shorthand[4]; 382 Vector a; 383 struct lsq_params param; 384 do { 385 fprintf(stdout, "Enter the element of atoms to be chosen: "); 386 fscanf(stdin, "%3s", shorthand); 387 } while ((param.type = periode->FindElement(shorthand)) == NULL); 388 Log() << Verbose(0) << "Element is " << param.type->name << endl; 389 mol->GetAlignvector(¶m); 390 for (int i=NDIM;i--;) { 391 x.x[i] = gsl_vector_get(param.x,i); 392 n.x[i] = gsl_vector_get(param.x,i+NDIM); 393 } 394 gsl_vector_free(param.x); 395 Log() << Verbose(0) << "Offset vector: "; 396 x.Output(); 397 Log() << Verbose(0) << endl; 398 n.Normalize(); 399 break; 400 }; 401 Log() << Verbose(0) << "Alignment vector: "; 402 n.Output(); 403 Log() << Verbose(0) << endl; 404 mol->Align(&n); 405 }; 406 407 /** Submenu for mirroring the atoms in the molecule. 408 * \param *mol molecule with all the atoms 409 */ 410 static void MirrorAtoms(molecule *mol) 411 { 412 atom *first, *second, *third; 413 Vector n; 414 char choice; // menu choice char 415 416 Log() << Verbose(0) << "===========MIRROR ATOMS=========================" << endl; 417 Log() << Verbose(0) << " a - state three atoms defining mirror plane" << endl; 418 Log() << Verbose(0) << " b - state normal vector of mirror plane" << endl; 419 Log() << Verbose(0) << " c - state two atoms in normal direction" << endl; 420 Log() << Verbose(0) << "all else - go back" << endl; 421 Log() << Verbose(0) << "===============================================" << endl; 422 Log() << Verbose(0) << "INPUT: "; 423 cin >> choice; 424 425 switch (choice) { 426 default: 427 case 'a': // three atoms defining mirror plane 428 first = mol->AskAtom("Enter first atom: "); 429 second = mol->AskAtom("Enter second atom: "); 430 third = mol->AskAtom("Enter third atom: "); 431 432 n.MakeNormalVector((const Vector *)&first->x,(const Vector *)&second->x,(const Vector *)&third->x); 433 break; 434 case 'b': // normal vector of mirror plane 435 Log() << Verbose(0) << "Enter normal vector of mirror plane." << endl; 436 n.AskPosition(mol->cell_size,0); 437 n.Normalize(); 438 break; 439 case 'c': // three atoms defining mirror plane 440 first = mol->AskAtom("Enter first atom: "); 441 second = mol->AskAtom("Enter second atom: "); 442 443 n.CopyVector((const Vector *)&first->x); 444 n.SubtractVector((const Vector *)&second->x); 445 n.Normalize(); 446 break; 447 }; 448 Log() << Verbose(0) << "Normal vector: "; 449 n.Output(); 450 Log() << Verbose(0) << endl; 451 mol->Mirror((const Vector *)&n); 452 }; 453 >>>>>>> MenuRefactoring:molecuilder/src/builder.cpp 454 455 /** Submenu for removing the atoms from the molecule. 456 * \param *mol molecule with all the atoms 457 */ 458 static void RemoveAtoms(molecule *mol) 459 { 460 atom *first, *second; 461 int axis; 462 double tmp1, tmp2; 463 char choice; // menu choice char 464 465 Log() << Verbose(0) << "===========REMOVE ATOMS=========================" << endl; 466 Log() << Verbose(0) << " a - state atom for removal by number" << endl; 467 Log() << Verbose(0) << " b - keep only in radius around atom" << endl; 468 Log() << Verbose(0) << " c - remove this with one axis greater value" << endl; 469 Log() << Verbose(0) << "all else - go back" << endl; 470 Log() << Verbose(0) << "===============================================" << endl; 471 Log() << Verbose(0) << "INPUT: "; 472 cin >> choice; 473 474 switch (choice) { 475 default: 476 case 'a': 477 if (mol->RemoveAtom(mol->AskAtom("Enter number of atom within molecule: "))) 478 Log() << Verbose(1) << "Atom removed." << endl; 479 else 480 Log() << Verbose(1) << "Atom not found." << endl; 481 break; 482 case 'b': 483 second = mol->AskAtom("Enter number of atom as reference point: "); 484 Log() << Verbose(0) << "Enter radius: "; 485 cin >> tmp1; 486 first = mol->start; 487 second = first->next; 488 while(second != mol->end) { 489 first = second; 490 second = first->next; 491 if (first->x.DistanceSquared((const Vector *)&second->x) > tmp1*tmp1) // distance to first above radius ... 492 mol->RemoveAtom(first); 493 } 494 break; 495 case 'c': 496 Log() << Verbose(0) << "Which axis is it: "; 497 cin >> axis; 498 Log() << Verbose(0) << "Lower boundary: "; 499 cin >> tmp1; 500 Log() << Verbose(0) << "Upper boundary: "; 501 cin >> tmp2; 502 first = mol->start; 503 second = first->next; 504 while(second != mol->end) { 505 first = second; 506 second = first->next; 507 if ((first->x.x[axis] < tmp1) || (first->x.x[axis] > tmp2)) {// out of boundary ... 508 //Log() << Verbose(0) << "Atom " << *first << " with " << first->x.x[axis] << " on axis " << axis << " is out of bounds [" << tmp1 << "," << tmp2 << "]." << endl; 509 mol->RemoveAtom(first); 510 } 511 } 512 break; 513 }; 514 //mol->Output(); 515 choice = 'r'; 516 }; 517 518 /** Submenu for measuring out the atoms in the molecule. 519 * \param *periode periodentafel 520 * \param *mol molecule with all the atoms 521 */ 522 static void MeasureAtoms(periodentafel *periode, molecule *mol, config *configuration) 523 { 524 atom *first, *second, *third; 525 Vector x,y; 526 double min[256], tmp1, tmp2, tmp3; 527 int Z; 528 char choice; // menu choice char 529 530 Log() << Verbose(0) << "===========MEASURE ATOMS=========================" << endl; 531 Log() << Verbose(0) << " a - calculate bond length between one atom and all others" << endl; 532 Log() << Verbose(0) << " b - calculate bond length between two atoms" << endl; 533 Log() << Verbose(0) << " c - calculate bond angle" << endl; 534 Log() << Verbose(0) << " d - calculate principal axis of the system" << endl; 535 Log() << Verbose(0) << " e - calculate volume of the convex envelope" << endl; 536 Log() << Verbose(0) << " f - calculate temperature from current velocity" << endl; 537 Log() << Verbose(0) << " g - output all temperatures per step from velocities" << endl; 538 Log() << Verbose(0) << "all else - go back" << endl; 539 Log() << Verbose(0) << "===============================================" << endl; 540 Log() << Verbose(0) << "INPUT: "; 541 cin >> choice; 542 543 switch(choice) { 544 default: 545 Log() << Verbose(1) << "Not a valid choice." << endl; 546 break; 547 case 'a': 548 first = mol->AskAtom("Enter first atom: "); 549 for (int i=MAX_ELEMENTS;i--;) 550 min[i] = 0.; 551 552 second = mol->start; 553 while ((second->next != mol->end)) { 554 second = second->next; // advance 555 Z = second->type->Z; 556 tmp1 = 0.; 557 if (first != second) { 558 x.CopyVector((const Vector *)&first->x); 559 x.SubtractVector((const Vector *)&second->x); 560 tmp1 = x.Norm(); 561 } 562 if ((tmp1 != 0.) && ((min[Z] == 0.) || (tmp1 < min[Z]))) min[Z] = tmp1; 563 //Log() << Verbose(0) << "Bond length between Atom " << first->nr << " and " << second->nr << ": " << tmp1 << " a.u." << endl; 564 } 565 for (int i=MAX_ELEMENTS;i--;) 566 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; 567 break; 568 569 case 'b': 570 first = mol->AskAtom("Enter first atom: "); 571 second = mol->AskAtom("Enter second atom: "); 572 for (int i=NDIM;i--;) 573 min[i] = 0.; 574 x.CopyVector((const Vector *)&first->x); 575 x.SubtractVector((const Vector *)&second->x); 576 tmp1 = x.Norm(); 577 Log() << Verbose(1) << "Distance vector is "; 578 x.Output(); 579 Log() << Verbose(0) << "." << endl << "Norm of distance is " << tmp1 << "." << endl; 580 break; 581 582 case 'c': 583 Log() << Verbose(0) << "Evaluating bond angle between three - first, central, last - atoms." << endl; 584 first = mol->AskAtom("Enter first atom: "); 585 second = mol->AskAtom("Enter central atom: "); 586 third = mol->AskAtom("Enter last atom: "); 587 tmp1 = tmp2 = tmp3 = 0.; 588 x.CopyVector((const Vector *)&first->x); 589 x.SubtractVector((const Vector *)&second->x); 590 y.CopyVector((const Vector *)&third->x); 591 y.SubtractVector((const Vector *)&second->x); 592 Log() << Verbose(0) << "Bond angle between first atom Nr." << first->nr << ", central atom Nr." << second->nr << " and last atom Nr." << third->nr << ": "; 593 Log() << Verbose(0) << (acos(x.ScalarProduct((const Vector *)&y)/(y.Norm()*x.Norm()))/M_PI*180.) << " degrees" << endl; 594 break; 595 case 'd': 596 Log() << Verbose(0) << "Evaluating prinicipal axis." << endl; 597 Log() << Verbose(0) << "Shall we rotate? [0/1]: "; 598 cin >> Z; 599 if ((Z >=0) && (Z <=1)) 600 mol->PrincipalAxisSystem((bool)Z); 601 else 602 mol->PrincipalAxisSystem(false); 603 break; 604 case 'e': 605 { 606 Log() << Verbose(0) << "Evaluating volume of the convex envelope."; 607 class Tesselation *TesselStruct = NULL; 608 const LinkedCell *LCList = NULL; 609 LCList = new LinkedCell(mol, 10.); 610 FindConvexBorder(mol, TesselStruct, LCList, NULL); 611 double clustervolume = VolumeOfConvexEnvelope(TesselStruct, configuration); 612 Log() << Verbose(0) << "The tesselated surface area is " << clustervolume << "." << endl;\ 613 delete(LCList); 614 delete(TesselStruct); 615 } 616 break; 617 case 'f': 618 mol->OutputTemperatureFromTrajectories((ofstream *)&cout, mol->MDSteps-1, mol->MDSteps); 619 break; 620 case 'g': 621 { 622 char filename[255]; 623 Log() << Verbose(0) << "Please enter filename: " << endl; 624 cin >> filename; 625 Log() << Verbose(1) << "Storing temperatures in " << filename << "." << endl; 626 ofstream *output = new ofstream(filename, ios::trunc); 627 if (!mol->OutputTemperatureFromTrajectories(output, 0, mol->MDSteps)) 628 Log() << Verbose(2) << "File could not be written." << endl; 629 else 630 Log() << Verbose(2) << "File stored." << endl; 631 output->close(); 632 delete(output); 633 } 634 break; 635 } 636 }; 637 638 /** Submenu for measuring out the atoms in the molecule. 639 * \param *mol molecule with all the atoms 640 * \param *configuration configuration structure for the to be written config files of all fragments 641 */ 642 static void FragmentAtoms(molecule *mol, config *configuration) 643 { 644 int Order1; 645 clock_t start, end; 646 647 Log() << Verbose(0) << "Fragmenting molecule with current connection matrix ..." << endl; 648 Log() << Verbose(0) << "What's the desired bond order: "; 649 cin >> Order1; 650 if (mol->first->next != mol->last) { // there are bonds 651 start = clock(); 652 mol->FragmentMolecule(Order1, configuration); 653 end = clock(); 654 Log() << Verbose(0) << "Clocks for this operation: " << (end-start) << ", time: " << ((double)(end-start)/CLOCKS_PER_SEC) << "s." << endl; 655 } else 656 Log() << Verbose(0) << "Connection matrix has not yet been generated!" << endl; 657 }; 658 659 /********************************************** Submenu routine **************************************/ 660 661 /** Submenu for manipulating atoms. 662 * \param *periode periodentafel 663 * \param *molecules list of molecules whose atoms are to be manipulated 664 */ 665 static void ManipulateAtoms(periodentafel *periode, MoleculeListClass *molecules, config *configuration) 666 { 667 atom *first, *second; 668 molecule *mol = NULL; 669 Vector x,y,z,n; // coordinates for absolute point in cell volume 670 double *factor; // unit factor if desired 671 double bond, minBond; 672 char choice; // menu choice char 673 bool valid; 674 675 Log() << Verbose(0) << "=========MANIPULATE ATOMS======================" << endl; 676 Log() << Verbose(0) << "a - add an atom" << endl; 677 Log() << Verbose(0) << "r - remove an atom" << endl; 678 Log() << Verbose(0) << "b - scale a bond between atoms" << endl; 679 Log() << Verbose(0) << "u - change an atoms element" << endl; 680 Log() << Verbose(0) << "l - measure lengths, angles, ... for an atom" << endl; 681 Log() << Verbose(0) << "all else - go back" << endl; 682 Log() << Verbose(0) << "===============================================" << endl; 683 if (molecules->NumberOfActiveMolecules() > 1) 684 eLog() << Verbose(2) << "There is more than one molecule active! Atoms will be added to each." << endl; 685 Log() << Verbose(0) << "INPUT: "; 686 cin >> choice; 687 688 switch (choice) { 689 default: 690 Log() << Verbose(0) << "Not a valid choice." << endl; 691 break; 692 693 case 'a': // add atom 694 for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++) 695 if ((*ListRunner)->ActiveFlag) { 696 mol = *ListRunner; 697 Log() << Verbose(0) << "Current molecule is: " << mol->IndexNr << "\t" << mol->name << endl; 698 AddAtoms(periode, mol); 699 } 700 break; 701 702 case 'b': // scale a bond 703 for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++) 704 if ((*ListRunner)->ActiveFlag) { 705 mol = *ListRunner; 706 Log() << Verbose(0) << "Current molecule is: " << mol->IndexNr << "\t" << mol->name << endl; 707 Log() << Verbose(0) << "Scaling bond length between two atoms." << endl; 708 first = mol->AskAtom("Enter first (fixed) atom: "); 709 second = mol->AskAtom("Enter second (shifting) atom: "); 710 minBond = 0.; 711 for (int i=NDIM;i--;) 712 minBond += (first->x.x[i]-second->x.x[i])*(first->x.x[i] - second->x.x[i]); 713 minBond = sqrt(minBond); 714 Log() << Verbose(0) << "Current Bond length between " << first->type->name << " Atom " << first->nr << " and " << second->type->name << " Atom " << second->nr << ": " << minBond << " a.u." << endl; 715 Log() << Verbose(0) << "Enter new bond length [a.u.]: "; 716 cin >> bond; 717 for (int i=NDIM;i--;) { 718 second->x.x[i] -= (second->x.x[i]-first->x.x[i])/minBond*(minBond-bond); 719 } 720 //Log() << Verbose(0) << "New coordinates of Atom " << second->nr << " are: "; 721 //second->Output(second->type->No, 1); 722 } 723 break; 724 725 case 'c': // unit scaling of the metric 726 for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++) 727 if ((*ListRunner)->ActiveFlag) { 728 mol = *ListRunner; 729 Log() << Verbose(0) << "Current molecule is: " << mol->IndexNr << "\t" << mol->name << endl; 730 Log() << Verbose(0) << "Angstroem -> Bohrradius: 1.8897261\t\tBohrradius -> Angstroem: 0.52917721" << endl; 731 Log() << Verbose(0) << "Enter three factors: "; 732 factor = new double[NDIM]; 733 cin >> factor[0]; 734 cin >> factor[1]; 735 cin >> factor[2]; 736 valid = true; 737 mol->Scale((const double ** const)&factor); 738 delete[](factor); 739 } 740 break; 741 742 case 'l': // measure distances or angles 743 for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++) 744 if ((*ListRunner)->ActiveFlag) { 745 mol = *ListRunner; 746 Log() << Verbose(0) << "Current molecule is: " << mol->IndexNr << "\t" << mol->name << endl; 747 MeasureAtoms(periode, mol, configuration); 748 } 749 break; 750 751 case 'r': // remove atom 752 for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++) 753 if ((*ListRunner)->ActiveFlag) { 754 mol = *ListRunner; 755 Log() << Verbose(0) << "Current molecule is: " << mol->IndexNr << "\t" << mol->name << endl; 756 RemoveAtoms(mol); 757 } 758 break; 759 760 case 'u': // change an atom's element 761 for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++) 762 if ((*ListRunner)->ActiveFlag) { 763 int Z; 764 mol = *ListRunner; 765 Log() << Verbose(0) << "Current molecule is: " << mol->IndexNr << "\t" << mol->name << endl; 766 first = NULL; 767 do { 768 Log() << Verbose(0) << "Change the element of which atom: "; 769 cin >> Z; 770 } while ((first = mol->FindAtom(Z)) == NULL); 771 Log() << Verbose(0) << "New element by atomic number Z: "; 772 cin >> Z; 773 first->type = periode->FindElement(Z); 774 Log() << Verbose(0) << "Atom " << first->nr << "'s element is " << first->type->name << "." << endl; 775 } 776 break; 777 } 778 }; 779 780 /** Submenu for manipulating molecules. 781 * \param *periode periodentafel 782 * \param *molecules list of molecule to manipulate 783 */ 784 static void ManipulateMolecules(periodentafel *periode, MoleculeListClass *molecules, config *configuration) 785 { 786 atom *first = NULL; 787 Vector x,y,z,n; // coordinates for absolute point in cell volume 788 int j, axis, count, faktor; 789 char choice; // menu choice char 790 molecule *mol = NULL; 791 element **Elements; 792 Vector **vectors; 793 MoleculeLeafClass *Subgraphs = NULL; 794 795 Log() << Verbose(0) << "=========MANIPULATE GLOBALLY===================" << endl; 796 Log() << Verbose(0) << "c - scale by unit transformation" << endl; 797 Log() << Verbose(0) << "d - duplicate molecule/periodic cell" << endl; 798 Log() << Verbose(0) << "f - fragment molecule many-body bond order style" << endl; 799 Log() << Verbose(0) << "g - center atoms in box" << endl; 800 Log() << Verbose(0) << "i - realign molecule" << endl; 801 Log() << Verbose(0) << "m - mirror all molecules" << endl; 802 Log() << Verbose(0) << "o - create connection matrix" << endl; 803 Log() << Verbose(0) << "t - translate molecule by vector" << endl; 804 Log() << Verbose(0) << "all else - go back" << endl; 805 Log() << Verbose(0) << "===============================================" << endl; 806 if (molecules->NumberOfActiveMolecules() > 1) 807 eLog() << Verbose(2) << "There is more than one molecule active! Atoms will be added to each." << endl; 808 Log() << Verbose(0) << "INPUT: "; 809 cin >> choice; 810 811 switch (choice) { 812 default: 813 Log() << Verbose(0) << "Not a valid choice." << endl; 814 break; 815 816 case 'd': // duplicate the periodic cell along a given axis, given times 817 for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++) 818 if ((*ListRunner)->ActiveFlag) { 819 mol = *ListRunner; 820 Log() << Verbose(0) << "Current molecule is: " << mol->IndexNr << "\t" << mol->name << endl; 821 Log() << Verbose(0) << "State the axis [(+-)123]: "; 822 cin >> axis; 823 Log() << Verbose(0) << "State the factor: "; 824 cin >> faktor; 825 826 mol->CountAtoms(); // recount atoms 827 if (mol->AtomCount != 0) { // if there is more than none 828 count = mol->AtomCount; // is changed becausing of adding, thus has to be stored away beforehand 829 Elements = new element *[count]; 830 vectors = new Vector *[count]; 831 j = 0; 832 first = mol->start; 833 while (first->next != mol->end) { // make a list of all atoms with coordinates and element 834 first = first->next; 835 Elements[j] = first->type; 836 vectors[j] = &first->x; 837 j++; 838 } 839 if (count != j) 840 eLog() << Verbose(1) << "AtomCount " << count << " is not equal to number of atoms in molecule " << j << "!" << endl; 841 x.Zero(); 842 y.Zero(); 843 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 844 for (int i=1;i<faktor;i++) { // then add this list with respective translation factor times 845 x.AddVector(&y); // per factor one cell width further 846 for (int k=count;k--;) { // go through every atom of the original cell 847 first = new atom(); // create a new body 848 first->x.CopyVector(vectors[k]); // use coordinate of original atom 849 first->x.AddVector(&x); // translate the coordinates 850 first->type = Elements[k]; // insert original element 851 mol->AddAtom(first); // and add to the molecule (which increments ElementsInMolecule, AtomCount, ...) 852 } 853 } 854 if (mol->first->next != mol->last) // if connect matrix is present already, redo it 855 mol->CreateAdjacencyList(mol->BondDistance, configuration->GetIsAngstroem(), &BondGraph::CovalentMinMaxDistance, NULL); 856 // free memory 857 delete[](Elements); 858 delete[](vectors); 859 // correct cell size 860 if (axis < 0) { // if sign was negative, we have to translate everything 861 x.Zero(); 862 x.AddVector(&y); 863 x.Scale(-(faktor-1)); 864 mol->Translate(&x); 865 } 866 mol->cell_size[(abs(axis) == 2) ? 2 : ((abs(axis) == 3) ? 5 : 0)] *= faktor; 867 } 868 } 869 break; 870 871 case 'f': 872 FragmentAtoms(mol, configuration); 873 break; 874 875 case 'g': // center the atoms 876 for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++) 877 if ((*ListRunner)->ActiveFlag) { 878 mol = *ListRunner; 879 Log() << Verbose(0) << "Current molecule is: " << mol->IndexNr << "\t" << mol->name << endl; 880 CenterAtoms(mol); 881 } 882 break; 883 884 case 'i': // align all atoms 885 for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++) 886 if ((*ListRunner)->ActiveFlag) { 887 mol = *ListRunner; 888 Log() << Verbose(0) << "Current molecule is: " << mol->IndexNr << "\t" << mol->name << endl; 889 AlignAtoms(periode, mol); 890 } 891 break; 892 893 case 'm': // mirror atoms along a given axis 894 for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++) 895 if ((*ListRunner)->ActiveFlag) { 896 mol = *ListRunner; 897 Log() << Verbose(0) << "Current molecule is: " << mol->IndexNr << "\t" << mol->name << endl; 898 MirrorAtoms(mol); 899 } 900 break; 901 902 case 'o': // create the connection matrix 903 for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++) 904 if ((*ListRunner)->ActiveFlag) { 905 mol = *ListRunner; 906 double bonddistance; 907 clock_t start,end; 908 Log() << Verbose(0) << "What's the maximum bond distance: "; 909 cin >> bonddistance; 910 start = clock(); 911 mol->CreateAdjacencyList(bonddistance, configuration->GetIsAngstroem(), &BondGraph::CovalentMinMaxDistance, NULL); 912 end = clock(); 913 Log() << Verbose(0) << "Clocks for this operation: " << (end-start) << ", time: " << ((double)(end-start)/CLOCKS_PER_SEC) << "s." << endl; 914 } 915 break; 916 917 case 't': // translate all atoms 918 for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++) 919 if ((*ListRunner)->ActiveFlag) { 920 mol = *ListRunner; 921 Log() << Verbose(0) << "Current molecule is: " << mol->IndexNr << "\t" << mol->name << endl; 922 Log() << Verbose(0) << "Enter translation vector." << endl; 923 x.AskPosition(mol->cell_size,0); 924 mol->Center.AddVector((const Vector *)&x); 925 } 926 break; 927 } 928 // Free all 929 if (Subgraphs != NULL) { // free disconnected subgraph list of DFS analysis was performed 930 while (Subgraphs->next != NULL) { 931 Subgraphs = Subgraphs->next; 932 delete(Subgraphs->previous); 933 } 934 delete(Subgraphs); 935 } 936 }; 937 938 939 /** Submenu for creating new molecules. 940 * \param *periode periodentafel 941 * \param *molecules list of molecules to add to 942 */ 943 static void EditMolecules(periodentafel *periode, MoleculeListClass *molecules) 944 { 945 char choice; // menu choice char 946 Vector center; 947 int nr, count; 948 molecule *mol = NULL; 949 950 Log() << Verbose(0) << "==========EDIT MOLECULES=====================" << endl; 951 Log() << Verbose(0) << "c - create new molecule" << endl; 952 Log() << Verbose(0) << "l - load molecule from xyz file" << endl; 953 Log() << Verbose(0) << "n - change molecule's name" << endl; 954 Log() << Verbose(0) << "N - give molecules filename" << endl; 955 Log() << Verbose(0) << "p - parse atoms in xyz file into molecule" << endl; 956 Log() << Verbose(0) << "r - remove a molecule" << endl; 957 Log() << Verbose(0) << "all else - go back" << endl; 958 Log() << Verbose(0) << "===============================================" << endl; 959 Log() << Verbose(0) << "INPUT: "; 960 cin >> choice; 961 962 switch (choice) { 963 default: 964 Log() << Verbose(0) << "Not a valid choice." << endl; 965 break; 966 case 'c': 967 mol = new molecule(periode); 968 molecules->insert(mol); 969 break; 970 971 case 'l': // load from XYZ file 972 { 973 char filename[MAXSTRINGSIZE]; 974 Log() << Verbose(0) << "Format should be XYZ with: ShorthandOfElement\tX\tY\tZ" << endl; 975 mol = new molecule(periode); 976 do { 977 Log() << Verbose(0) << "Enter file name: "; 978 cin >> filename; 979 } while (!mol->AddXYZFile(filename)); 980 mol->SetNameFromFilename(filename); 981 // center at set box dimensions 982 mol->CenterEdge(¢er); 983 mol->cell_size[0] = center.x[0]; 984 mol->cell_size[1] = 0; 985 mol->cell_size[2] = center.x[1]; 986 mol->cell_size[3] = 0; 987 mol->cell_size[4] = 0; 988 mol->cell_size[5] = center.x[2]; 989 molecules->insert(mol); 990 } 991 break; 992 993 case 'n': 994 { 995 char filename[MAXSTRINGSIZE]; 996 do { 997 Log() << Verbose(0) << "Enter index of molecule: "; 998 cin >> nr; 999 mol = molecules->ReturnIndex(nr); 1000 } while (mol == NULL); 1001 Log() << Verbose(0) << "Enter name: "; 1002 cin >> filename; 1003 strcpy(mol->name, filename); 1004 } 1005 break; 1006 1007 case 'N': 1008 { 1009 char filename[MAXSTRINGSIZE]; 1010 do { 1011 Log() << Verbose(0) << "Enter index of molecule: "; 1012 cin >> nr; 1013 mol = molecules->ReturnIndex(nr); 1014 } while (mol == NULL); 1015 Log() << Verbose(0) << "Enter name: "; 1016 cin >> filename; 1017 mol->SetNameFromFilename(filename); 1018 } 1019 break; 1020 1021 case 'p': // parse XYZ file 1022 { 1023 char filename[MAXSTRINGSIZE]; 1024 mol = NULL; 1025 do { 1026 Log() << Verbose(0) << "Enter index of molecule: "; 1027 cin >> nr; 1028 mol = molecules->ReturnIndex(nr); 1029 } while (mol == NULL); 1030 Log() << Verbose(0) << "Format should be XYZ with: ShorthandOfElement\tX\tY\tZ" << endl; 1031 do { 1032 Log() << Verbose(0) << "Enter file name: "; 1033 cin >> filename; 1034 } while (!mol->AddXYZFile(filename)); 1035 mol->SetNameFromFilename(filename); 1036 } 1037 break; 1038 1039 case 'r': 1040 Log() << Verbose(0) << "Enter index of molecule: "; 1041 cin >> nr; 1042 count = 1; 1043 for(MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++) 1044 if (nr == (*ListRunner)->IndexNr) { 1045 mol = *ListRunner; 1046 molecules->ListOfMolecules.erase(ListRunner); 1047 delete(mol); 1048 break; 1049 } 1050 break; 1051 } 1052 }; 1053 1054 1055 /** Submenu for merging molecules. 1056 * \param *periode periodentafel 1057 * \param *molecules list of molecules to add to 1058 */ 1059 static void MergeMolecules(periodentafel *periode, MoleculeListClass *molecules) 1060 { 1061 char choice; // menu choice char 1062 1063 Log() << Verbose(0) << "===========MERGE MOLECULES=====================" << endl; 1064 Log() << Verbose(0) << "a - simple add of one molecule to another" << endl; 1065 Log() << Verbose(0) << "e - embedding merge of two molecules" << endl; 1066 Log() << Verbose(0) << "m - multi-merge of all molecules" << endl; 1067 Log() << Verbose(0) << "s - scatter merge of two molecules" << endl; 1068 Log() << Verbose(0) << "t - simple merge of two molecules" << endl; 1069 Log() << Verbose(0) << "all else - go back" << endl; 1070 Log() << Verbose(0) << "===============================================" << endl; 1071 Log() << Verbose(0) << "INPUT: "; 1072 cin >> choice; 1073 1074 switch (choice) { 1075 default: 1076 Log() << Verbose(0) << "Not a valid choice." << endl; 1077 break; 1078 1079 case 'a': 1080 { 1081 int src, dest; 1082 molecule *srcmol = NULL, *destmol = NULL; 1083 { 1084 do { 1085 Log() << Verbose(0) << "Enter index of destination molecule: "; 1086 cin >> dest; 1087 destmol = molecules->ReturnIndex(dest); 1088 } while ((destmol == NULL) && (dest != -1)); 1089 do { 1090 Log() << Verbose(0) << "Enter index of source molecule to add from: "; 1091 cin >> src; 1092 srcmol = molecules->ReturnIndex(src); 1093 } while ((srcmol == NULL) && (src != -1)); 1094 if ((src != -1) && (dest != -1)) 1095 molecules->SimpleAdd(srcmol, destmol); 1096 } 1097 } 1098 break; 1099 1100 case 'e': 1101 { 1102 int src, dest; 1103 molecule *srcmol = NULL, *destmol = NULL; 1104 do { 1105 Log() << Verbose(0) << "Enter index of matrix molecule (the variable one): "; 1106 cin >> src; 1107 srcmol = molecules->ReturnIndex(src); 1108 } while ((srcmol == NULL) && (src != -1)); 1109 do { 1110 Log() << Verbose(0) << "Enter index of molecule to merge into (the fixed one): "; 1111 cin >> dest; 1112 destmol = molecules->ReturnIndex(dest); 1113 } while ((destmol == NULL) && (dest != -1)); 1114 if ((src != -1) && (dest != -1)) 1115 molecules->EmbedMerge(destmol, srcmol); 1116 } 1117 break; 1118 1119 case 'm': 1120 { 1121 int nr; 1122 molecule *mol = NULL; 1123 do { 1124 Log() << Verbose(0) << "Enter index of molecule to merge into: "; 1125 cin >> nr; 1126 mol = molecules->ReturnIndex(nr); 1127 } while ((mol == NULL) && (nr != -1)); 1128 if (nr != -1) { 1129 int N = molecules->ListOfMolecules.size()-1; 1130 int *src = new int(N); 1131 for(MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++) 1132 if ((*ListRunner)->IndexNr != nr) 1133 src[N++] = (*ListRunner)->IndexNr; 1134 molecules->SimpleMultiMerge(mol, src, N); 1135 delete[](src); 1136 } 1137 } 1138 break; 1139 1140 case 's': 1141 Log() << Verbose(0) << "Not implemented yet." << endl; 1142 break; 1143 1144 case 't': 1145 { 1146 int src, dest; 1147 molecule *srcmol = NULL, *destmol = NULL; 1148 { 1149 do { 1150 Log() << Verbose(0) << "Enter index of destination molecule: "; 1151 cin >> dest; 1152 destmol = molecules->ReturnIndex(dest); 1153 } while ((destmol == NULL) && (dest != -1)); 1154 do { 1155 Log() << Verbose(0) << "Enter index of source molecule to merge into: "; 1156 cin >> src; 1157 srcmol = molecules->ReturnIndex(src); 1158 } while ((srcmol == NULL) && (src != -1)); 1159 if ((src != -1) && (dest != -1)) 1160 molecules->SimpleMerge(srcmol, destmol); 1161 } 1162 } 1163 break; 1164 } 1165 }; 1166 1167 /********************************************** Test routine **************************************/ 1168 1169 /** Is called always as option 'T' in the menu. 1170 * \param *molecules list of molecules 1171 */ 1172 static void testroutine(MoleculeListClass *molecules) 1173 { 1174 // the current test routine checks the functionality of the KeySet&Graph concept: 1175 // We want to have a multiindex (the KeySet) describing a unique subgraph 1176 int i, comp, counter=0; 1177 1178 // create a clone 1179 molecule *mol = NULL; 1180 if (molecules->ListOfMolecules.size() != 0) // clone 1181 mol = (molecules->ListOfMolecules.front())->CopyMolecule(); 1182 else { 1183 eLog() << Verbose(0) << "I don't have anything to test on ... "; 1184 performCriticalExit(); 1185 return; 1186 } 1187 atom *Walker = mol->start; 1188 1189 // generate some KeySets 1190 Log() << Verbose(0) << "Generating KeySets." << endl; 1191 KeySet TestSets[mol->AtomCount+1]; 1192 i=1; 1193 while (Walker->next != mol->end) { 1194 Walker = Walker->next; 1195 for (int j=0;j<i;j++) { 1196 TestSets[j].insert(Walker->nr); 1197 } 1198 i++; 1199 } 1200 Log() << Verbose(0) << "Testing insertion of already present item in KeySets." << endl; 1201 KeySetTestPair test; 1202 test = TestSets[mol->AtomCount-1].insert(Walker->nr); 1203 if (test.second) { 1204 Log() << Verbose(1) << "Insertion worked?!" << endl; 1205 } else { 1206 Log() << Verbose(1) << "Insertion rejected: Present object is " << (*test.first) << "." << endl; 1207 } 1208 TestSets[mol->AtomCount].insert(mol->end->previous->nr); 1209 TestSets[mol->AtomCount].insert(mol->end->previous->previous->previous->nr); 1210 1211 // constructing Graph structure 1212 Log() << Verbose(0) << "Generating Subgraph class." << endl; 1213 Graph Subgraphs; 1214 1215 // insert KeySets into Subgraphs 1216 Log() << Verbose(0) << "Inserting KeySets into Subgraph class." << endl; 1217 for (int j=0;j<mol->AtomCount;j++) { 1218 Subgraphs.insert(GraphPair (TestSets[j],pair<int, double>(counter++, 1.))); 1219 } 1220 Log() << Verbose(0) << "Testing insertion of already present item in Subgraph." << endl; 1221 GraphTestPair test2; 1222 test2 = Subgraphs.insert(GraphPair (TestSets[mol->AtomCount],pair<int, double>(counter++, 1.))); 1223 if (test2.second) { 1224 Log() << Verbose(1) << "Insertion worked?!" << endl; 1225 } else { 1226 Log() << Verbose(1) << "Insertion rejected: Present object is " << (*(test2.first)).second.first << "." << endl; 1227 } 1228 1229 // show graphs 1230 Log() << Verbose(0) << "Showing Subgraph's contents, checking that it's sorted." << endl; 1231 Graph::iterator A = Subgraphs.begin(); 1232 while (A != Subgraphs.end()) { 1233 Log() << Verbose(0) << (*A).second.first << ": "; 1234 KeySet::iterator key = (*A).first.begin(); 1235 comp = -1; 1236 while (key != (*A).first.end()) { 1237 if ((*key) > comp) 1238 Log() << Verbose(0) << (*key) << " "; 1239 else 1240 Log() << Verbose(0) << (*key) << "! "; 1241 comp = (*key); 1242 key++; 1243 } 1244 Log() << Verbose(0) << endl; 1245 A++; 1246 } 1247 delete(mol); 1248 }; 1249 1250 #endif 77 1251 78 1252 /** Parses the command line options. … … 103 1277 int argptr; 104 1278 molecule *mol = NULL; 105 string BondGraphFileName(" ");1279 string BondGraphFileName("\n"); 106 1280 int verbosity = 0; 107 1281 strncpy(configuration.databasepath, LocalPath, MAXSTRINGSIZE-1); … … 126 1300 Log() << Verbose(0) << "\t-B xx xy xz yy yz zz\tBound atoms by domain with given symmetric matrix of (xx,xy,xz,yy,yz,zz)." << endl; 127 1301 Log() << Verbose(0) << "\t-c x1 x2 x3\tCenter atoms in domain with a minimum distance to boundary of (x1,x2,x3)." << endl; 128 Log() << Verbose(0) << "\t-C \tPair Correlation analysis." << endl;1302 Log() << Verbose(0) << "\t-C <Z> <output> <bin output>\tPair Correlation analysis." << endl; 129 1303 Log() << Verbose(0) << "\t-d x1 x2 x3\tDuplicate cell along each axis by given factor." << endl; 130 1304 Log() << Verbose(0) << "\t-D <bond distance>\tDepth-First-Search Analysis of the molecule, giving cycles and tree/back edges." << endl; 131 1305 Log() << Verbose(0) << "\t-e <file>\tSets the databases path to be parsed (default: ./)." << endl; 132 1306 Log() << Verbose(0) << "\t-E <id> <Z>\tChange atom <id>'s element to <Z>, <id> begins at 0." << endl; 133 Log() << Verbose(0) << "\t-f/F <dist> <order>\tFragments the molecule in BOSSANOVA manner (with/out rings compressed) and stores config files in same dir as config (return code 0 - fragmented, 2 - no fragmentation necessary)." << endl; 1307 Log() << Verbose(0) << "\t-f <dist> <order>\tFragments the molecule in BOSSANOVA manner (with/out rings compressed) and stores config files in same dir as config (return code 0 - fragmented, 2 - no fragmentation necessary)." << endl; 1308 Log() << Verbose(0) << "\t-F <dist_x> <dist_y> <dist_z> <epsilon> <randatom> <randmol> <DoRotate>\tFilling Box with water molecules." << endl; 134 1309 Log() << Verbose(0) << "\t-g <file>\tParses a bond length table from the given file." << endl; 135 1310 Log() << Verbose(0) << "\t-h/-H/-?\tGive this help screen." << endl; 1311 Log() << Verbose(0) << "\t-I\t Dissect current system of molecules into a set of disconnected (subgraphs of) molecules." << endl; 136 1312 Log() << Verbose(0) << "\t-L <step0> <step1> <prefix>\tStore a linear interpolation between two configurations <step0> and <step1> into single config files with prefix <prefix> and as Trajectories into the current config file." << endl; 137 1313 Log() << Verbose(0) << "\t-m <0/1>\tCalculate (0)/ Align in(1) PAS with greatest EV along z axis." << endl; … … 257 1433 mol = new molecule(periode); 258 1434 mol->ActiveFlag = true; 1435 if (ConfigFileName != NULL) 1436 mol->SetNameFromFilename(ConfigFileName); 259 1437 molecules->insert(mol); 1438 } 1439 if (configuration.BG == NULL) { 1440 configuration.BG = new BondGraph(configuration.GetIsAngstroem()); 1441 if ((!BondGraphFileName.empty()) && (configuration.BG->LoadBondLengthTable(BondGraphFileName))) { 1442 Log() << Verbose(0) << "Bond length table loaded successfully." << endl; 1443 } else { 1444 eLog() << Verbose(1) << "Bond length table loading failed." << endl; 1445 } 260 1446 } 261 1447 … … 359 1545 //argptr+=1; 360 1546 break; 1547 case 'I': 1548 Log() << Verbose(1) << "Dissecting molecular system into a set of disconnected subgraphs ... " << endl; 1549 // @TODO rather do the dissection afterwards 1550 molecules->DissectMoleculeIntoConnectedSubgraphs(periode, &configuration); 1551 mol = NULL; 1552 if (molecules->ListOfMolecules.size() != 0) { 1553 for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++) 1554 if ((*ListRunner)->ActiveFlag) { 1555 mol = *ListRunner; 1556 break; 1557 } 1558 } 1559 if (mol == NULL) { 1560 mol = *(molecules->ListOfMolecules.begin()); 1561 mol->ActiveFlag = true; 1562 } 1563 break; 361 1564 case 'C': 362 1565 if (ExitFlag == 0) ExitFlag = 1; … … 366 1569 performCriticalExit(); 367 1570 } else { 368 SaveFlag = false;369 1571 ofstream output(argv[argptr+1]); 370 1572 ofstream binoutput(argv[argptr+2]); … … 386 1588 counter = 0; 387 1589 for (MoleculeList::iterator BigFinder = molecules->ListOfMolecules.begin(); BigFinder != molecules->ListOfMolecules.end(); BigFinder++) { 388 Actives[counter ] = (*BigFinder)->ActiveFlag;1590 Actives[counter++] = (*BigFinder)->ActiveFlag; 389 1591 (*BigFinder)->ActiveFlag = (*BigFinder == Boundary) ? false : true; 390 1592 } … … 394 1596 int ranges[NDIM] = {1,1,1}; 395 1597 CorrelationToSurfaceMap *surfacemap = PeriodicCorrelationToSurface( molecules, elemental, TesselStruct, LCList, ranges ); 1598 //OutputCorrelationToSurface(&output, surfacemap); 396 1599 BinPairMap *binmap = BinData( surfacemap, 0.5, 0., 0. ); 397 1600 OutputCorrelation ( &binoutput, binmap ); … … 399 1602 binoutput.close(); 400 1603 for (MoleculeList::iterator BigFinder = molecules->ListOfMolecules.begin(); BigFinder != molecules->ListOfMolecules.end(); BigFinder++) 401 (*BigFinder)->ActiveFlag = Actives[counter ];1604 (*BigFinder)->ActiveFlag = Actives[counter++]; 402 1605 Free(&Actives); 403 1606 delete(LCList); … … 422 1625 case 'F': 423 1626 if (ExitFlag == 0) ExitFlag = 1; 424 if (argptr+ 5>=argc) {1627 if (argptr+6 >=argc) { 425 1628 ExitFlag = 255; 426 eLog() << Verbose(0) << "Not enough or invalid arguments given for filling box with water: -F <dist_x> <dist_y> <dist_z> < randatom> <randmol> <DoRotate>" << endl;1629 eLog() << Verbose(0) << "Not enough or invalid arguments given for filling box with water: -F <dist_x> <dist_y> <dist_z> <boundary> <randatom> <randmol> <DoRotate>" << endl; 427 1630 performCriticalExit(); 428 1631 } else { … … 430 1633 Log() << Verbose(1) << "Filling Box with water molecules." << endl; 431 1634 // construct water molecule 432 molecule *filler = new molecule(periode); ;1635 molecule *filler = new molecule(periode); 433 1636 molecule *Filling = NULL; 434 1637 atom *second = NULL, *third = NULL; 1638 // first = new atom(); 1639 // first->type = periode->FindElement(5); 1640 // first->x.Zero(); 1641 // filler->AddAtom(first); 435 1642 first = new atom(); 436 1643 first->type = periode->FindElement(1); … … 451 1658 for (int i=0;i<NDIM;i++) 452 1659 distance[i] = atof(argv[argptr+i]); 453 Filling = FillBoxWithMolecule(molecules, filler, configuration, distance, atof(argv[argptr+3]), atof(argv[argptr+4]), ato i(argv[argptr+5]));1660 Filling = FillBoxWithMolecule(molecules, filler, configuration, distance, atof(argv[argptr+3]), atof(argv[argptr+4]), atof(argv[argptr+5]), atoi(argv[argptr+6])); 454 1661 if (Filling != NULL) { 1662 Filling->ActiveFlag = false; 455 1663 molecules->insert(Filling); 456 1664 } … … 499 1707 start = clock(); 500 1708 LCList = new LinkedCell(Boundary, atof(argv[argptr])*2.); 501 FindNonConvexBorder(Boundary, T, LCList, atof(argv[argptr]), argv[argptr+1]); 1709 if (!FindNonConvexBorder(Boundary, T, LCList, atof(argv[argptr]), argv[argptr+1])) 1710 ExitFlag = 255; 502 1711 //FindDistributionOfEllipsoids(T, &LCList, N, number, filename.c_str()); 503 1712 end = clock(); 504 1713 Log() << Verbose(0) << "Clocks for this operation: " << (end-start) << ", time: " << ((double)(end-start)/CLOCKS_PER_SEC) << "s." << endl; 505 1714 delete(LCList); 1715 delete(T); 506 1716 argptr+=2; 507 1717 } … … 799 2009 if (volume != -1) 800 2010 ExitFlag = 255; 801 eLog() << Verbose(0) << "Not enough arguments given for suspension: -u <density>" << endl;2011 eLog() << Verbose(0) << "Not enough or invalid arguments given for suspension: -u <density>" << endl; 802 2012 performCriticalExit(); 803 2013 } else { … … 920 2130 Action *eraseMoleculeAction = new MethodAction("eraseMoleculeAction",boost::bind(&MoleculeListClass::eraseMolecule,molecules)); 921 2131 new ActionMenuItem('r',"remove a molecule",editMoleculesMenu,eraseMoleculeAction); 2132 922 2133 } 923 2134 … … 971 2182 972 2183 { 2184 cout << ESPACKVersion << endl; 2185 2186 setVerbosity(0); 2187 973 2188 menuPopulaters populaters; 974 2189 populaters.MakeEditMoleculesMenu = populateEditMoleculesMenu; … … 981 2196 MainWindow *mainWindow = UIFactory::get()->makeMainWindow(populaters,molecules, configuration, periode, ConfigFileName); 982 2197 mainWindow->display(); 2198 983 2199 delete mainWindow; 984 2200 }
Note:
See TracChangeset
for help on using the changeset viewer.