source: src/menu.cpp@ 1020f0

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

Extracted several methods from the EditMolecules Submenu.

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