source: src/moleculelist.cpp@ f7fd17

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 f7fd17 was d3abb1, checked in by Frederik Heber <heber@…>, 14 years ago

Extracted MoleculeLeafClass into own module.

  • removed some unnecessary includes in moleculelist.cpp.
  • Property mode set to 100755
File size: 25.3 KB
Line 
1/*
2 * Project: MoleCuilder
3 * Description: creates and alters molecular systems
4 * Copyright (C) 2010 University of Bonn. All rights reserved.
5 * Please see the LICENSE file or "Copyright notice" in builder.cpp for details.
6 */
7
8/** \file MoleculeListClass.cpp
9 *
10 * Function implementations for the class MoleculeListClass.
11 *
12 */
13
14// include config.h
15#ifdef HAVE_CONFIG_H
16#include <config.h>
17#endif
18
19#include "CodePatterns/MemDebug.hpp"
20
21//#include <cstring>
22
23//#include <gsl/gsl_inline.h>
24#include <gsl/gsl_heapsort.h>
25
26#include "molecule.hpp"
27
28#include "CodePatterns/Log.hpp"
29
30#include "atom.hpp"
31#include "Bond/bond.hpp"
32#include "Box.hpp"
33#include "config.hpp"
34#include "Element/element.hpp"
35#include "Element/periodentafel.hpp"
36#include "Fragmentation/Graph.hpp"
37#include "Fragmentation/KeySet.hpp"
38#include "Graph/BondGraph.hpp"
39#include "Helpers/helpers.hpp"
40#include "LinearAlgebra/RealSpaceMatrix.hpp"
41#include "Parser/FormatParserStorage.hpp"
42#include "World.hpp"
43
44
45/** Constructor for MoleculeListClass.
46 */
47MoleculeListClass::MoleculeListClass(World *_world) :
48 Observable("MoleculeListClass"),
49 MaxIndex(1),
50 world(_world)
51{};
52
53/** Destructor for MoleculeListClass.
54 */
55MoleculeListClass::~MoleculeListClass()
56{
57 DoLog(4) && (Log() << Verbose(4) << "Clearing ListOfMolecules." << endl);
58 for(MoleculeList::iterator MolRunner = ListOfMolecules.begin(); MolRunner != ListOfMolecules.end(); ++MolRunner)
59 (*MolRunner)->signOff(this);
60 ListOfMolecules.clear(); // empty list
61};
62
63/** Insert a new molecule into the list and set its number.
64 * \param *mol molecule to add to list.
65 */
66void MoleculeListClass::insert(molecule *mol)
67{
68 OBSERVE;
69 mol->IndexNr = MaxIndex++;
70 ListOfMolecules.push_back(mol);
71 mol->signOn(this);
72};
73
74/** Erases a molecule from the list.
75 * \param *mol molecule to add to list.
76 */
77void MoleculeListClass::erase(molecule *mol)
78{
79 OBSERVE;
80 mol->signOff(this);
81 ListOfMolecules.remove(mol);
82};
83
84/** Comparison function for two values.
85 * \param *a
86 * \param *b
87 * \return <0, \a *a less than \a *b, ==0 if equal, >0 \a *a greater than \a *b
88 */
89int CompareDoubles (const void * a, const void * b)
90{
91 if (*(double *)a > *(double *)b)
92 return -1;
93 else if (*(double *)a < *(double *)b)
94 return 1;
95 else
96 return 0;
97};
98
99
100/** Compare whether two molecules are equal.
101 * \param *a molecule one
102 * \param *n molecule two
103 * \return lexical value (-1, 0, +1)
104 */
105int MolCompare(const void *a, const void *b)
106{
107 int *aList = NULL, *bList = NULL;
108 int Count, Counter, aCounter, bCounter;
109 int flag;
110
111 // sort each atom list and put the numbers into a list, then go through
112 //Log() << Verbose(0) << "Comparing fragment no. " << *(molecule **)a << " to " << *(molecule **)b << "." << endl;
113 // Yes those types are awkward... but check it for yourself it checks out this way
114 molecule *const *mol1_ptr= static_cast<molecule *const *>(a);
115 molecule *mol1 = *mol1_ptr;
116 molecule *const *mol2_ptr= static_cast<molecule *const *>(b);
117 molecule *mol2 = *mol2_ptr;
118 if (mol1->getAtomCount() < mol2->getAtomCount()) {
119 return -1;
120 } else {
121 if (mol1->getAtomCount() > mol2->getAtomCount())
122 return +1;
123 else {
124 Count = mol1->getAtomCount();
125 aList = new int[Count];
126 bList = new int[Count];
127
128 // fill the lists
129 Counter = 0;
130 aCounter = 0;
131 bCounter = 0;
132 molecule::const_iterator aiter = mol1->begin();
133 molecule::const_iterator biter = mol2->begin();
134 for (;(aiter != mol1->end()) && (biter != mol2->end());
135 ++aiter, ++biter) {
136 if ((*aiter)->GetTrueFather() == NULL)
137 aList[Counter] = Count + (aCounter++);
138 else
139 aList[Counter] = (*aiter)->GetTrueFather()->getNr();
140 if ((*biter)->GetTrueFather() == NULL)
141 bList[Counter] = Count + (bCounter++);
142 else
143 bList[Counter] = (*biter)->GetTrueFather()->getNr();
144 Counter++;
145 }
146 // check if AtomCount was for real
147 flag = 0;
148 if ((aiter == mol1->end()) && (biter != mol2->end())) {
149 flag = -1;
150 } else {
151 if ((aiter != mol1->end()) && (biter == mol2->end()))
152 flag = 1;
153 }
154 if (flag == 0) {
155 // sort the lists
156 gsl_heapsort(aList, Count, sizeof(int), CompareDoubles);
157 gsl_heapsort(bList, Count, sizeof(int), CompareDoubles);
158 // compare the lists
159
160 flag = 0;
161 for (int i = 0; i < Count; i++) {
162 if (aList[i] < bList[i]) {
163 flag = -1;
164 } else {
165 if (aList[i] > bList[i])
166 flag = 1;
167 }
168 if (flag != 0)
169 break;
170 }
171 }
172 delete[] (aList);
173 delete[] (bList);
174 return flag;
175 }
176 }
177 return -1;
178};
179
180/** Output of a list of all molecules.
181 * \param *out output stream
182 */
183void MoleculeListClass::Enumerate(ostream *out)
184{
185 periodentafel *periode = World::getInstance().getPeriode();
186 std::map<atomicNumber_t,unsigned int> counts;
187 double size=0;
188 Vector Origin;
189
190 // header
191 (*out) << "Index\tName\t\tAtoms\tFormula\tCenter\tSize" << endl;
192 (*out) << "-----------------------------------------------" << endl;
193 if (ListOfMolecules.size() == 0)
194 (*out) << "\tNone" << endl;
195 else {
196 Origin.Zero();
197 for (MoleculeList::iterator ListRunner = ListOfMolecules.begin(); ListRunner != ListOfMolecules.end(); ListRunner++) {
198 // count atoms per element and determine size of bounding sphere
199 size=0.;
200 for (molecule::const_iterator iter = (*ListRunner)->begin(); iter != (*ListRunner)->end(); ++iter) {
201 counts[(*iter)->getType()->getNumber()]++;
202 if ((*iter)->DistanceSquared(Origin) > size)
203 size = (*iter)->DistanceSquared(Origin);
204 }
205 // output Index, Name, number of atoms, chemical formula
206 (*out) << ((*ListRunner)->ActiveFlag ? "*" : " ") << (*ListRunner)->IndexNr << "\t" << (*ListRunner)->name << "\t\t" << (*ListRunner)->getAtomCount() << "\t";
207
208 std::map<atomicNumber_t,unsigned int>::reverse_iterator iter;
209 for(iter=counts.rbegin(); iter!=counts.rend();++iter){
210 atomicNumber_t Z =(*iter).first;
211 (*out) << periode->FindElement(Z)->getSymbol() << (*iter).second;
212 }
213 // Center and size
214 Vector *Center = (*ListRunner)->DetermineCenterOfAll();
215 (*out) << "\t" << *Center << "\t" << sqrt(size) << endl;
216 delete(Center);
217 }
218 }
219};
220
221/** Returns the molecule with the given index \a index.
222 * \param index index of the desired molecule
223 * \return pointer to molecule structure, NULL if not found
224 */
225molecule * MoleculeListClass::ReturnIndex(int index)
226{
227 for(MoleculeList::iterator ListRunner = ListOfMolecules.begin(); ListRunner != ListOfMolecules.end(); ListRunner++)
228 if ((*ListRunner)->IndexNr == index)
229 return (*ListRunner);
230 return NULL;
231};
232
233
234/** Simple output of the pointers in ListOfMolecules.
235 * \param *out output stream
236 */
237void MoleculeListClass::Output(ofstream *out)
238{
239 DoLog(1) && (Log() << Verbose(1) << "MoleculeList: ");
240 for (MoleculeList::iterator ListRunner = ListOfMolecules.begin(); ListRunner != ListOfMolecules.end(); ListRunner++)
241 DoLog(0) && (Log() << Verbose(0) << *ListRunner << "\t");
242 DoLog(0) && (Log() << Verbose(0) << endl);
243};
244
245/** Returns a string with \a i prefixed with 0s to match order of total number of molecules in digits.
246 * \param FragmentNumber total number of fragments to determine necessary number of digits
247 * \param digits number to create with 0 prefixed
248 * \return allocated(!) char array with number in digits, ten base.
249 */
250inline char *FixedDigitNumber(const int FragmentNumber, const int digits)
251{
252 char *returnstring;
253 int number = FragmentNumber;
254 int order = 0;
255 while (number != 0) { // determine number of digits needed
256 number = (int)floor(((double)number / 10.));
257 order++;
258 //Log() << Verbose(0) << "Number is " << number << ", order is " << order << "." << endl;
259 }
260 // allocate string
261 returnstring = new char[order + 2];
262 // terminate and fill string array from end backward
263 returnstring[order] = '\0';
264 number = digits;
265 for (int i=order;i--;) {
266 returnstring[i] = '0' + (char)(number % 10);
267 number = (int)floor(((double)number / 10.));
268 }
269 //Log() << Verbose(0) << returnstring << endl;
270 return returnstring;
271};
272
273/** Calculates necessary hydrogen correction due to unwanted interaction between saturated ones.
274 * If for a pair of two hydrogen atoms a and b, at least is a saturated one, and a and b are not
275 * bonded to the same atom, then we add for this pair a correction term constructed from a Morse
276 * potential function fit to QM calculations with respecting to the interatomic hydrogen distance.
277 * \param &path path to file
278 */
279bool MoleculeListClass::AddHydrogenCorrection(std::string &path)
280{
281 const bond *Binder = NULL;
282 double ***FitConstant = NULL, **correction = NULL;
283 int a, b;
284 ofstream output;
285 ifstream input;
286 string line;
287 stringstream zeile;
288 double distance;
289 char ParsedLine[1023];
290 double tmp;
291 char *FragmentNumber = NULL;
292
293 DoLog(1) && (Log() << Verbose(1) << "Saving hydrogen saturation correction ... ");
294 // 0. parse in fit constant files that should have the same dimension as the final energy files
295 // 0a. find dimension of matrices with constants
296 line = path;
297 line += "1";
298 line += FITCONSTANTSUFFIX;
299 input.open(line.c_str());
300 if (input.fail()) {
301 DoLog(1) && (Log() << Verbose(1) << endl << "Unable to open " << line << ", is the directory correct?" << endl);
302 return false;
303 }
304 a = 0;
305 b = -1; // we overcount by one
306 while (!input.eof()) {
307 input.getline(ParsedLine, 1023);
308 zeile.str(ParsedLine);
309 int i = 0;
310 while (!zeile.eof()) {
311 zeile >> distance;
312 i++;
313 }
314 if (i > a)
315 a = i;
316 b++;
317 }
318 DoLog(0) && (Log() << Verbose(0) << "I recognized " << a << " columns and " << b << " rows, ");
319 input.close();
320
321 // 0b. allocate memory for constants
322 FitConstant = new double**[3];
323 for (int k = 0; k < 3; k++) {
324 FitConstant[k] = new double*[a];
325 for (int i = a; i--;) {
326 FitConstant[k][i] = new double[b];
327 for (int j = b; j--;) {
328 FitConstant[k][i][j] = 0.;
329 }
330 }
331 }
332 // 0c. parse in constants
333 for (int i = 0; i < 3; i++) {
334 line = path;
335 line.append("/");
336 line += FRAGMENTPREFIX;
337 sprintf(ParsedLine, "%d", i + 1);
338 line += ParsedLine;
339 line += FITCONSTANTSUFFIX;
340 input.open(line.c_str());
341 if (input.fail()) {
342 DoeLog(0) && (eLog()<< Verbose(0) << endl << "Unable to open " << line << ", is the directory correct?" << endl);
343 performCriticalExit();
344 return false;
345 }
346 int k = 0, l;
347 while ((!input.eof()) && (k < b)) {
348 input.getline(ParsedLine, 1023);
349 //Log() << Verbose(0) << "Current Line: " << ParsedLine << endl;
350 zeile.str(ParsedLine);
351 zeile.clear();
352 l = 0;
353 while ((!zeile.eof()) && (l < a)) {
354 zeile >> FitConstant[i][l][k];
355 //Log() << Verbose(0) << FitConstant[i][l][k] << "\t";
356 l++;
357 }
358 //Log() << Verbose(0) << endl;
359 k++;
360 }
361 input.close();
362 }
363 for (int k = 0; k < 3; k++) {
364 DoLog(0) && (Log() << Verbose(0) << "Constants " << k << ":" << endl);
365 for (int j = 0; j < b; j++) {
366 for (int i = 0; i < a; i++) {
367 DoLog(0) && (Log() << Verbose(0) << FitConstant[k][i][j] << "\t");
368 }
369 DoLog(0) && (Log() << Verbose(0) << endl);
370 }
371 DoLog(0) && (Log() << Verbose(0) << endl);
372 }
373
374 // 0d. allocate final correction matrix
375 correction = new double*[a];
376 for (int i = a; i--;)
377 correction[i] = new double[b];
378
379 // 1a. go through every molecule in the list
380 for (MoleculeList::iterator ListRunner = ListOfMolecules.begin(); ListRunner != ListOfMolecules.end(); ListRunner++) {
381 // 1b. zero final correction matrix
382 for (int k = a; k--;)
383 for (int j = b; j--;)
384 correction[k][j] = 0.;
385 // 2. take every hydrogen that is a saturated one
386 for (molecule::const_iterator iter = (*ListRunner)->begin(); iter != (*ListRunner)->end(); ++iter) {
387 //Log() << Verbose(1) << "(*iter): " << *(*iter) << " with first bond " << *((*iter)->getListOfBonds().begin()) << "." << endl;
388 if (((*iter)->getType()->getAtomicNumber() == 1) && (((*iter)->father == NULL)
389 || ((*iter)->father->getType()->getAtomicNumber() != 1))) { // if it's a hydrogen
390 for (molecule::const_iterator runner = (*ListRunner)->begin(); runner != (*ListRunner)->end(); ++runner) {
391 //Log() << Verbose(2) << "Runner: " << *(*runner) << " with first bond " << *((*iter)->getListOfBonds().begin()) << "." << endl;
392 // 3. take every other hydrogen that is the not the first and not bound to same bonding partner
393 const BondList &bondlist = (*runner)->getListOfBonds();
394 Binder = *(bondlist.begin());
395 if (((*runner)->getType()->getAtomicNumber() == 1) && ((*runner)->getNr() > (*iter)->getNr()) && (Binder->GetOtherAtom((*runner)) != Binder->GetOtherAtom((*iter)))) { // (hydrogens have only one bonding partner!)
396 // 4. evaluate the morse potential for each matrix component and add up
397 distance = (*runner)->distance(*(*iter));
398 //Log() << Verbose(0) << "Fragment " << (*ListRunner)->name << ": " << *(*runner) << "<= " << distance << "=>" << *(*iter) << ":" << endl;
399 for (int k = 0; k < a; k++) {
400 for (int j = 0; j < b; j++) {
401 switch (k) {
402 case 1:
403 case 7:
404 case 11:
405 tmp = pow(FitConstant[0][k][j] * (1. - exp(-FitConstant[1][k][j] * (distance - FitConstant[2][k][j]))), 2);
406 break;
407 default:
408 tmp = FitConstant[0][k][j] * pow(distance, FitConstant[1][k][j]) + FitConstant[2][k][j];
409 };
410 correction[k][j] -= tmp; // ground state is actually lower (disturbed by additional interaction)
411 //Log() << Verbose(0) << tmp << "\t";
412 }
413 //Log() << Verbose(0) << endl;
414 }
415 //Log() << Verbose(0) << endl;
416 }
417 }
418 }
419 }
420 // 5. write final matrix to file
421 line = path;
422 line.append("/");
423 line += FRAGMENTPREFIX;
424 FragmentNumber = FixedDigitNumber(ListOfMolecules.size(), (*ListRunner)->IndexNr);
425 line += FragmentNumber;
426 delete[] (FragmentNumber);
427 line += HCORRECTIONSUFFIX;
428 output.open(line.c_str());
429 output << "Time\t\tTotal\t\tKinetic\t\tNonLocal\tCorrelation\tExchange\tPseudo\t\tHartree\t\t-Gauss\t\tEwald\t\tIonKin\t\tETotal" << endl;
430 for (int j = 0; j < b; j++) {
431 for (int i = 0; i < a; i++)
432 output << correction[i][j] << "\t";
433 output << endl;
434 }
435 output.close();
436 }
437 for (int i = a; i--;)
438 delete[](correction[i]);
439 delete[](correction);
440
441 line = path;
442 line.append("/");
443 line += HCORRECTIONSUFFIX;
444 output.open(line.c_str());
445 output << "Time\t\tTotal\t\tKinetic\t\tNonLocal\tCorrelation\tExchange\tPseudo\t\tHartree\t\t-Gauss\t\tEwald\t\tIonKin\t\tETotal" << endl;
446 for (int j = 0; j < b; j++) {
447 for (int i = 0; i < a; i++)
448 output << 0 << "\t";
449 output << endl;
450 }
451 output.close();
452 // 6. free memory of parsed matrices
453 for (int k = 0; k < 3; k++) {
454 for (int i = a; i--;) {
455 delete[](FitConstant[k][i]);
456 }
457 delete[](FitConstant[k]);
458 }
459 delete[](FitConstant);
460 DoLog(0) && (Log() << Verbose(0) << "done." << endl);
461 return true;
462};
463
464/** Store force indices, i.e. the connection between the nuclear index in the total molecule config and the respective atom in fragment config.
465 * \param &path path to file
466 * \param *SortIndex Index to map from the BFS labeling to the sequence how of Ion_Type in the config
467 * \return true - file written successfully, false - writing failed
468 */
469bool MoleculeListClass::StoreForcesFile(std::string &path, int *SortIndex)
470{
471 bool status = true;
472 string filename(path);
473 filename += FORCESFILE;
474 ofstream ForcesFile(filename.c_str());
475 periodentafel *periode=World::getInstance().getPeriode();
476
477 // open file for the force factors
478 DoLog(1) && (Log() << Verbose(1) << "Saving force factors ... ");
479 if (!ForcesFile.fail()) {
480 //Log() << Verbose(1) << "Final AtomicForcesList: ";
481 //output << prefix << "Forces" << endl;
482 for (MoleculeList::iterator ListRunner = ListOfMolecules.begin(); ListRunner != ListOfMolecules.end(); ListRunner++) {
483 periodentafel::const_iterator elemIter;
484 for(elemIter=periode->begin();elemIter!=periode->end();++elemIter){
485 if ((*ListRunner)->hasElement((*elemIter).first)) { // if this element got atoms
486 for(molecule::iterator atomIter = (*ListRunner)->begin(); atomIter !=(*ListRunner)->end();++atomIter){
487 if ((*atomIter)->getType()->getNumber() == (*elemIter).first) {
488 if (((*atomIter)->GetTrueFather() != NULL) && ((*atomIter)->GetTrueFather() != (*atomIter))) {// if there is a rea
489 //Log() << Verbose(0) << "Walker is " << *Walker << " with true father " << *( Walker->GetTrueFather()) << ", it
490 ForcesFile << SortIndex[(*atomIter)->GetTrueFather()->getNr()] << "\t";
491 } else
492 // otherwise a -1 to indicate an added saturation hydrogen
493 ForcesFile << "-1\t";
494 }
495 }
496 }
497 }
498 ForcesFile << endl;
499 }
500 ForcesFile.close();
501 DoLog(1) && (Log() << Verbose(1) << "done." << endl);
502 } else {
503 status = false;
504 DoLog(1) && (Log() << Verbose(1) << "failed to open file " << filename << "." << endl);
505 }
506 ForcesFile.close();
507
508 return status;
509};
510
511/** Writes a config file for each molecule in the given \a **FragmentList.
512 * \param *out output stream for debugging
513 * \param &prefix path and prefix to the fragment config files
514 * \param *SortIndex Index to map from the BFS labeling to the sequence how of Ion_Type in the config
515 * \return true - success (each file was written), false - something went wrong.
516 */
517bool MoleculeListClass::OutputConfigForListOfFragments(std::string &prefix, int *SortIndex)
518{
519 ofstream outputFragment;
520 std::string FragmentName;
521 char PathBackup[MAXSTRINGSIZE];
522 bool result = true;
523 bool intermediateResult = true;
524 Vector BoxDimension;
525 char *FragmentNumber = NULL;
526 char *path = NULL;
527 int FragmentCounter = 0;
528 ofstream output;
529 RealSpaceMatrix cell_size = World::getInstance().getDomain().getM();
530 RealSpaceMatrix cell_size_backup = cell_size;
531 int count=0;
532
533 // store the fragments as config and as xyz
534 for (MoleculeList::iterator ListRunner = ListOfMolecules.begin(); ListRunner != ListOfMolecules.end(); ListRunner++) {
535 // save default path as it is changed for each fragment
536 path = World::getInstance().getConfig()->GetDefaultPath();
537 if (path != NULL)
538 strcpy(PathBackup, path);
539 else {
540 ELOG(0, "OutputConfigForListOfFragments: NULL default path obtained from config!");
541 performCriticalExit();
542 }
543
544 // correct periodic
545 if ((*ListRunner)->ScanForPeriodicCorrection()) {
546 count++;
547 }
548
549 {
550 // list atoms in fragment for debugging
551 std::stringstream output;
552 output << "Contained atoms: ";
553 for (molecule::const_iterator iter = (*ListRunner)->begin(); iter != (*ListRunner)->end(); ++iter) {
554 output << (*iter)->getName() << " ";
555 }
556 LOG(2, output.str());
557 }
558
559 {
560 // output xyz file
561 FragmentNumber = FixedDigitNumber(ListOfMolecules.size(), FragmentCounter++);
562 FragmentName = prefix + FragmentNumber + ".conf.xyz";
563 outputFragment.open(FragmentName.c_str(), ios::out);
564 std::stringstream output;
565 output << "Saving bond fragment No. " << FragmentNumber << "/" << FragmentCounter - 1 << " as XYZ ... ";
566 if ((intermediateResult = (*ListRunner)->OutputXYZ(&outputFragment)))
567 output << " done.";
568 else
569 output << " failed.";
570 LOG(3, output.str());
571 result = result && intermediateResult;
572 outputFragment.close();
573 outputFragment.clear();
574 }
575
576 // center on edge
577 (*ListRunner)->CenterEdge(&BoxDimension);
578 for (int k = 0; k < NDIM; k++) // if one edge is to small, set at least to 1 angstroem
579 if (BoxDimension[k] < 1.)
580 BoxDimension[k] += 1.;
581 (*ListRunner)->SetBoxDimension(&BoxDimension); // update Box of atoms by boundary
582 for (int k = 0; k < NDIM; k++) {
583 BoxDimension[k] = 2.5 * (World::getInstance().getConfig()->GetIsAngstroem() ? 1. : 1. / AtomicLengthToAngstroem);
584 cell_size.at(k,k) = BoxDimension[k] * 2.;
585 }
586 World::getInstance().setDomain(cell_size);
587 (*ListRunner)->Translate(&BoxDimension);
588
589 // change path in config
590 FragmentName = PathBackup;
591 FragmentName += "/";
592 FragmentName += FRAGMENTPREFIX;
593 FragmentName += FragmentNumber;
594 FragmentName += "/";
595 World::getInstance().getConfig()->SetDefaultPath(FragmentName.c_str());
596
597 {
598 // and save as config
599 FragmentName = prefix + FragmentNumber + ".conf";
600 std::stringstream output;
601 output << "Saving bond fragment No. " << FragmentNumber << "/" << FragmentCounter - 1 << " as config ... ";
602 if ((intermediateResult = World::getInstance().getConfig()->Save(FragmentName.c_str(), (*ListRunner)->elemente, (*ListRunner))))
603 output << " done.";
604 else
605 output << " failed.";
606 LOG(3, output.str());
607 result = result && intermediateResult;
608 }
609
610 // restore old config
611 World::getInstance().getConfig()->SetDefaultPath(PathBackup);
612
613 {
614 // and save as mpqc input file
615 stringstream output;
616 FragmentName = prefix + FragmentNumber + ".conf.in";
617 output << "Saving bond fragment No. " << FragmentNumber << "/" << FragmentCounter - 1 << " as mpqc input ... ";
618 std::ofstream outfile(FragmentName.c_str());
619 std::vector<atom *> atoms;
620 for (molecule::const_iterator iter = (*ListRunner)->begin(); iter != (*ListRunner)->end(); ++iter)
621 atoms.push_back(*iter);
622// atoms.resize((*ListRunner)->getAtomCount());
623// std::copy((*ListRunner)->begin(), (*ListRunner)->end(), atoms.begin());
624 FormatParserStorage::getInstance().get(mpqc).save(&outfile, atoms);
625// if ((intermediateResult = World::getInstance().getConfig()->SaveMPQC(FragmentName.c_str(), (*ListRunner))))
626 output << " done.";
627// else
628// output << " failed.";
629 LOG(3, output.str());
630 }
631
632 result = result && intermediateResult;
633 //outputFragment.close();
634 //outputFragment.clear();
635 delete[](FragmentNumber);
636 }
637 LOG(0, "STATUS: done.");
638
639 // printing final number
640 LOG(2, "INFO: Final number of fragments: " << FragmentCounter << ".");
641
642 // printing final number
643 LOG(2, "INFO: For " << count << " fragments periodic correction would have been necessary.");
644
645 // restore cell_size
646 World::getInstance().setDomain(cell_size_backup);
647
648 return result;
649};
650
651/** Counts the number of molecules with the molecule::ActiveFlag set.
652 * \return number of molecules with ActiveFlag set to true.
653 */
654int MoleculeListClass::NumberOfActiveMolecules()
655{
656 int count = 0;
657 for (MoleculeList::iterator ListRunner = ListOfMolecules.begin(); ListRunner != ListOfMolecules.end(); ListRunner++)
658 count += ((*ListRunner)->ActiveFlag ? 1 : 0);
659 return count;
660};
661
662/** Count all atoms in each molecule.
663 * \return number of atoms in the MoleculeListClass.
664 * TODO: the inner loop should be done by some (double molecule::CountAtom()) function
665 */
666int MoleculeListClass::CountAllAtoms() const
667{
668 int AtomNo = 0;
669 for (MoleculeList::const_iterator MolWalker = ListOfMolecules.begin(); MolWalker != ListOfMolecules.end(); MolWalker++) {
670 AtomNo += (*MolWalker)->size();
671 }
672 return AtomNo;
673}
674
675/***********
676 * Methods Moved here from the menus
677 */
678
679void MoleculeListClass::createNewMolecule(periodentafel *periode) {
680 OBSERVE;
681 molecule *mol = NULL;
682 mol = World::getInstance().createMolecule();
683 insert(mol);
684};
685
686void MoleculeListClass::loadFromXYZ(periodentafel *periode){
687 molecule *mol = NULL;
688 Vector center;
689 char filename[MAXSTRINGSIZE];
690 Log() << Verbose(0) << "Format should be XYZ with: ShorthandOfElement\tX\tY\tZ" << endl;
691 mol = World::getInstance().createMolecule();
692 do {
693 Log() << Verbose(0) << "Enter file name: ";
694 cin >> filename;
695 } while (!mol->AddXYZFile(filename));
696 mol->SetNameFromFilename(filename);
697 // center at set box dimensions
698 mol->CenterEdge(&center);
699 RealSpaceMatrix domain;
700 for(int i =0;i<NDIM;++i)
701 domain.at(i,i) = center[i];
702 World::getInstance().setDomain(domain);
703 insert(mol);
704}
705
706void MoleculeListClass::setMoleculeFilename() {
707 char filename[MAXSTRINGSIZE];
708 int nr;
709 molecule *mol = NULL;
710 do {
711 Log() << Verbose(0) << "Enter index of molecule: ";
712 cin >> nr;
713 mol = ReturnIndex(nr);
714 } while (mol == NULL);
715 Log() << Verbose(0) << "Enter name: ";
716 cin >> filename;
717 mol->SetNameFromFilename(filename);
718}
719
720void MoleculeListClass::parseXYZIntoMolecule(){
721 char filename[MAXSTRINGSIZE];
722 int nr;
723 molecule *mol = NULL;
724 mol = NULL;
725 do {
726 Log() << Verbose(0) << "Enter index of molecule: ";
727 cin >> nr;
728 mol = ReturnIndex(nr);
729 } while (mol == NULL);
730 Log() << Verbose(0) << "Format should be XYZ with: ShorthandOfElement\tX\tY\tZ" << endl;
731 do {
732 Log() << Verbose(0) << "Enter file name: ";
733 cin >> filename;
734 } while (!mol->AddXYZFile(filename));
735 mol->SetNameFromFilename(filename);
736};
737
738void MoleculeListClass::eraseMolecule(){
739 int nr;
740 molecule *mol = NULL;
741 Log() << Verbose(0) << "Enter index of molecule: ";
742 cin >> nr;
743 for(MoleculeList::iterator ListRunner = ListOfMolecules.begin(); ListRunner != ListOfMolecules.end(); ListRunner++)
744 if (nr == (*ListRunner)->IndexNr) {
745 mol = *ListRunner;
746 ListOfMolecules.erase(ListRunner);
747 World::getInstance().destroyMolecule(mol);
748 break;
749 }
750};
Note: See TracBrowser for help on using the repository browser.