source: src/moleculelist.cpp@ 30c753

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 30c753 was d103d3, checked in by Frederik Heber <heber@…>, 13 years ago

Added additional check in CodeCheck's project disclaimer for current year in copyright.

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