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