source: src/moleculelist.cpp@ ca8bea

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 ca8bea was e554d0, checked in by Frederik Heber <heber@…>, 12 years ago

Removed SortIndex as (unused) parameter in OutputConfigForListOfFragments().

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