source: src/moleculelist.cpp@ 9ec4b8

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 9ec4b8 was fac58f, checked in by Frederik Heber <heber@…>, 9 years ago

Converted FormatParser::save() to using vector of const atom ptrs.

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