source: src/periodentafel.cpp@ bf3817

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

Added ifdef HAVE_CONFIG and config.h include to each and every cpp file.

  • is now topmost in front of MemDebug.hpp (and any other).
  • Property mode set to 100755
File size: 15.1 KB
Line 
1/** \file periodentafel.cpp
2 *
3 * Function implementations for the class periodentafel.
4 *
5 */
6
7// include config.h
8#ifdef HAVE_CONFIG_H
9#include <config.h>
10#endif
11
12#include "Helpers/MemDebug.hpp"
13
14#include <iomanip>
15#include <iostream>
16#include <fstream>
17#include <cstring>
18
19#include "Helpers/Assert.hpp"
20#include "element.hpp"
21#include "elements_db.hpp"
22#include "Helpers/helpers.hpp"
23#include "lists.hpp"
24#include "Helpers/Log.hpp"
25#include "periodentafel.hpp"
26#include "Helpers/Verbose.hpp"
27
28using namespace std;
29
30/************************************* Functions for class periodentafel ***************************/
31
32/** constructor for class periodentafel
33 * Initialises start and end of list and resets periodentafel::checkliste to false.
34 */
35periodentafel::periodentafel()
36{
37 {
38 stringstream input(elementsDB,ios_base::in);
39 bool status = LoadElementsDatabase(input);
40 ASSERT(status, "General element initialization failed");
41 }
42 {
43 stringstream input(valenceDB,ios_base::in);
44 bool status = LoadValenceDatabase(&input);
45 ASSERT(status, "Valence entry of element initialization failed");
46 }
47 {
48 stringstream input(orbitalsDB,ios_base::in);
49 bool status = LoadOrbitalsDatabase(&input);
50 ASSERT(status, "Orbitals entry of element initialization failed");
51 }
52 {
53 stringstream input(HbondangleDB,ios_base::in);
54 bool status = LoadHBondAngleDatabase(&input);
55 ASSERT(status, "HBond angle entry of element initialization failed");
56 }
57 {
58 stringstream input(HbonddistanceDB,ios_base::in);
59 bool status = LoadHBondLengthsDatabase(&input);
60 ASSERT(status, "HBond distance entry of element initialization failed");
61 }
62};
63
64/** destructor for class periodentafel
65 * Removes every element and afterwards deletes start and end of list.
66 * TODO: Handle when elements have changed and store databases then
67 */
68periodentafel::~periodentafel()
69{
70 CleanupPeriodtable();
71};
72
73/** Adds element to period table list
74 * \param *pointer element to be added
75 * \return iterator to added element
76 */
77periodentafel::iterator periodentafel::AddElement(element * pointer)
78{
79 atomicNumber_t Z = pointer->getNumber();
80 ASSERT(!elements.count(Z), "Element is already present.");
81 if (pointer->getNumber() < 1 && pointer->getNumber() >= MAX_ELEMENTS)
82 DoeLog(0) && (eLog() << Verbose(0) << "Invalid Z number!\n");
83 pair<iterator,bool> res = elements.insert(pair<atomicNumber_t,element*>(Z,pointer));
84 return res.first;
85};
86
87/** Removes element from list.
88 * \param *pointer element to be removed
89 */
90size_t periodentafel::RemoveElement(const element * pointer)
91{
92 return RemoveElement(pointer->getNumber());
93};
94
95/** Removes element from list.
96 * \param Z element to be removed
97 */
98size_t periodentafel::RemoveElement(atomicNumber_t Z)
99{
100 return elements.erase(Z);
101};
102
103/** Removes every element from the period table.
104 */
105void periodentafel::CleanupPeriodtable()
106{
107 for(iterator iter=elements.begin();iter!=elements.end();++iter){
108 delete(*iter).second;
109 }
110 elements.clear();
111};
112
113/** Finds an element by its atomic number.
114 * If element is not yet in list, returns NULL.
115 * \param Z atomic number
116 * \return pointer to element or NULL if not found
117 */
118const element * periodentafel::FindElement(atomicNumber_t Z) const
119{
120 const_iterator res = elements.find(Z);
121 return res!=elements.end()?((*res).second):0;
122};
123
124/** Finds an element by its atomic number.
125 * If element is not yet in list, datas are asked and stored in database.
126 * \param shorthand chemical symbol of the element, e.g. H for hydrogene
127 * \return pointer to element
128 */
129const element * periodentafel::FindElement(const string &shorthand) const
130{
131 element *res = 0;
132 for(const_iterator iter=elements.begin();iter!=elements.end();++iter) {
133 if((*iter).second->getSymbol() == shorthand){
134 res = (*iter).second;
135 break;
136 }
137 }
138 return res;
139};
140
141/** Asks for element number and returns pointer to element
142 * \return desired element or NULL
143 */
144const element * periodentafel::AskElement() const
145{
146 const element * walker = NULL;
147 int Z;
148 do {
149 DoLog(0) && (Log() << Verbose(0) << "Atomic number Z: ");
150 cin >> Z;
151 walker = this->FindElement(Z); // give type
152 } while (walker == NULL);
153 return walker;
154};
155
156/** Asks for element and if not found, presents mask to enter info.
157 * \return pointer to either present or newly created element
158 */
159const element * periodentafel::EnterElement()
160{
161 atomicNumber_t Z = 0;
162 DoLog(0) && (Log() << Verbose(0) << "Atomic number: " << Z << endl);
163 cin >> Z;
164 const element *res = FindElement(Z);
165 if (!res) {
166 // TODO: make this using the constructor
167 DoLog(0) && (Log() << Verbose(0) << "Element not found in database, please enter." << endl);
168 element *tmp = new element;
169 tmp->Z = Z;
170 DoLog(0) && (Log() << Verbose(0) << "Mass: " << endl);
171 cin >> tmp->mass;
172 DoLog(0) && (Log() << Verbose(0) << "Name [max 64 chars]: " << endl);
173 cin >> tmp->getName();
174 DoLog(0) && (Log() << Verbose(0) << "Short form [max 3 chars]: " << endl);
175 cin >> tmp->getSymbol();
176 AddElement(tmp);
177 return tmp;
178 }
179 return res;
180};
181
182
183/******************** Access to iterators ****************************/
184periodentafel::const_iterator periodentafel::begin() const{
185 return elements.begin();
186}
187
188periodentafel::const_iterator periodentafel::end() const{
189 return elements.end();
190}
191
192periodentafel::reverse_iterator periodentafel::rbegin() const{
193 return reverse_iterator(elements.end());
194}
195
196periodentafel::reverse_iterator periodentafel::rend() const{
197 return reverse_iterator(elements.begin());
198}
199
200/** Prints period table to given stream.
201 * \param output stream
202 */
203bool periodentafel::Output(ostream * const output) const
204{
205 bool result = true;
206 if (output != NULL) {
207 for(const_iterator iter=elements.begin(); iter !=elements.end();++iter){
208 result = result && (*iter).second->Output(output);
209 }
210 return result;
211 } else
212 return false;
213};
214
215/** Loads element list from file.
216 * \param *path to to standard file names
217 */
218bool periodentafel::LoadPeriodentafel(const char *path)
219{
220 ifstream input;
221 bool status = true;
222 bool otherstatus = true;
223 char filename[255];
224
225 // fill elements DB
226 strncpy(filename, path, MAXSTRINGSIZE);
227 strncat(filename, "/", MAXSTRINGSIZE-strlen(filename));
228 strncat(filename, STANDARDELEMENTSDB, MAXSTRINGSIZE-strlen(filename));
229 input.open(filename);
230 if (!input.fail())
231 DoLog(0) && (Log() << Verbose(0) << "Using " << filename << " as elements database." << endl);
232 status = status && LoadElementsDatabase(input);
233 input.close();
234 input.clear();
235
236 // fill valence DB per element
237 strncpy(filename, path, MAXSTRINGSIZE);
238 strncat(filename, "/", MAXSTRINGSIZE-strlen(filename));
239 strncat(filename, STANDARDVALENCEDB, MAXSTRINGSIZE-strlen(filename));
240 input.open(filename);
241 if (!input.fail())
242 DoLog(0) && (Log() << Verbose(0) << "Using " << filename << " as valence database." << endl);
243 otherstatus = otherstatus && LoadValenceDatabase(&input);
244 input.close();
245 input.clear();
246
247 // fill orbitals DB per element
248 strncpy(filename, path, MAXSTRINGSIZE);
249 strncat(filename, "/", MAXSTRINGSIZE-strlen(filename));
250 strncat(filename, STANDARDORBITALDB, MAXSTRINGSIZE-strlen(filename));
251 input.open(filename);
252 if (!input.fail())
253 DoLog(0) && (Log() << Verbose(0) << "Using " << filename << " as orbitals database." << endl);
254 otherstatus = otherstatus && LoadOrbitalsDatabase(&input);
255 input.close();
256 input.clear();
257
258 // fill H-BondAngle DB per element
259 strncpy(filename, path, MAXSTRINGSIZE);
260 strncat(filename, "/", MAXSTRINGSIZE-strlen(filename));
261 strncat(filename, STANDARDHBONDANGLEDB, MAXSTRINGSIZE-strlen(filename));
262 input.open(filename);
263 if (!input.fail())
264 DoLog(0) && (Log() << Verbose(0) << "Using " << filename << " as H bond angle database." << endl);
265 otherstatus = otherstatus && LoadHBondAngleDatabase(&input);
266 input.close();
267 input.clear();
268
269 // fill H-BondDistance DB per element
270 strncpy(filename, path, MAXSTRINGSIZE);
271 strncat(filename, "/", MAXSTRINGSIZE-strlen(filename));
272 strncat(filename, STANDARDHBONDDISTANCEDB, MAXSTRINGSIZE-strlen(filename));
273 input.open(filename);
274 if (!input.fail())
275 DoLog(0) && (Log() << Verbose(0) << "Using " << filename << " as H bond length database." << endl);
276 otherstatus = otherstatus && LoadHBondLengthsDatabase(&input);
277 input.close();
278 input.clear();
279
280 if (!otherstatus){
281 DoeLog(2) && (eLog()<< Verbose(2) << "Something went wrong while parsing the other databases!" << endl);
282 }
283
284 return status;
285};
286
287/** load the element info.
288 * \param *input stream to parse from
289 * \return true - parsing successful, false - something went wrong
290 */
291bool periodentafel::LoadElementsDatabase(istream &input)
292{
293 bool status = true;
294 string header1tmp,header2tmp;
295 // first parse into a map, so we can revert to old status in case something goes wront
296 map<atomicNumber_t,element*> parsedElements;
297 if (!input.fail()) {
298 getline(input,header1tmp);
299 getline(input,header2tmp); // skip first two header lines
300 //cout << "First header: " << header1tmp << endl;
301 //cout << "Second header: " << header2tmp << endl;
302 DoLog(0) && (Log() << Verbose(0) << "Parsed elements:");
303 while (!input.eof()) {
304 element *neues = new element;
305 input >> neues->getName();;
306 //(*input) >> ws;
307 input >> neues->getSymbol();
308 //(*input) >> ws;
309 input >> neues->period;
310 //(*input) >> ws;
311 input >> neues->group;
312 //(*input) >> ws;
313 input >> neues->block;
314 //(*input) >> ws;
315 input >> neues->Z;
316 //(*input) >> ws;
317 input >> neues->mass;
318 //(*input) >> ws;
319 input >> neues->CovalentRadius;
320 //(*input) >> ws;
321 input >> neues->VanDerWaalsRadius;
322 //(*input) >> ws;
323 input >> ws;
324 //neues->Output((ofstream *)&cout);
325 if ((neues->getNumber() > 0) && (neues->getNumber() < MAX_ELEMENTS)) {
326 parsedElements[neues->Z] = neues;
327 DoLog(0) && (Log() << Verbose(0) << " " << *neues);
328 } else {
329 DoeLog(2) && (eLog() << Verbose(2) << "Detected empty line or invalid element in elements db, discarding." << endl);
330 DoLog(0) && (Log() << Verbose(0) << " <?>");
331 delete(neues);
332 }
333 // when the input is in failed state, we most likely just read garbage
334 if(input.fail()) {
335 DoeLog(2) && (eLog() << Verbose(2) << "Error parsing elements db." << endl);
336 status = false;
337 break;
338 }
339 }
340 DoLog(0) && (Log() << Verbose(0) << endl);
341 } else {
342 DoeLog(1) && (eLog() << Verbose(1) << "Could not open the database." << endl);
343 status = false;
344 }
345
346 if (!parsedElements.size())
347 status = false;
348
349 if(status){
350 for(map<atomicNumber_t,element*>::iterator iter=parsedElements.begin();
351 iter!=parsedElements.end();
352 ++iter){
353 if (elements.count(iter->first)) {
354 // if element already present, replace the old one
355 // pointer to old element might still be in use, so we have to replace into the old element
356 *(elements[iter->first])=*iter->second;
357 }
358 else {
359 // no such element in periodentafel... we can just insert
360 elements[iter->first] = iter->second;
361 }
362 }
363 // all went well.. we now copy the header
364 strncpy(header1,header1tmp.c_str(),MAXSTRINGSIZE);
365 header1[MAXSTRINGSIZE-1]=0;
366 strncpy(header2,header2tmp.c_str(),MAXSTRINGSIZE);
367 header2[MAXSTRINGSIZE-1]=0;
368 }
369
370 return status;
371}
372
373/** load the valence info.
374 * \param *input stream to parse from
375 * \return true - parsing successful, false - something went wrong
376 */
377bool periodentafel::LoadValenceDatabase(istream *input)
378{
379 char dummy[MAXSTRINGSIZE];
380 if (!(*input).fail()) {
381 (*input).getline(dummy, MAXSTRINGSIZE);
382 while (!(*input).eof()) {
383 atomicNumber_t Z;
384 (*input) >> Z;
385 ASSERT(elements.count(Z), "Element not present");
386 (*input) >> ws;
387 (*input) >> elements[Z]->Valence;
388 (*input) >> ws;
389 //Log() << Verbose(3) << "Element " << Z << " has " << FindElement(Z)->Valence << " valence electrons." << endl;
390 }
391 return true;
392 } else
393 return false;
394}
395
396/** load the orbitals info.
397 * \param *input stream to parse from
398 * \return true - parsing successful, false - something went wrong
399 */
400bool periodentafel::LoadOrbitalsDatabase(istream *input)
401{
402 char dummy[MAXSTRINGSIZE];
403 if (!(*input).fail()) {
404 (*input).getline(dummy, MAXSTRINGSIZE);
405 while (!(*input).eof()) {
406 atomicNumber_t Z;
407 (*input) >> Z;
408 ASSERT(elements.count(Z), "Element not present");
409 (*input) >> ws;
410 (*input) >> elements[Z]->NoValenceOrbitals;
411 (*input) >> ws;
412 //Log() << Verbose(3) << "Element " << Z << " has " << FindElement(Z)->NoValenceOrbitals << " number of singly occupied valence orbitals." << endl;
413 }
414 return true;
415 } else
416 return false;
417}
418
419/** load the hbond angles info.
420 * \param *input stream to parse from
421 * \return true - parsing successful, false - something went wrong
422 */
423bool periodentafel::LoadHBondAngleDatabase(istream *input)
424{
425 char dummy[MAXSTRINGSIZE];
426 if (!(*input).fail()) {
427 (*input).getline(dummy, MAXSTRINGSIZE);
428 while (!(*input).eof()) {
429 atomicNumber_t Z;
430 (*input) >> Z;
431 ASSERT(elements.count(Z), "Element not present");
432 (*input) >> ws;
433 (*input) >> elements[Z]->HBondAngle[0];
434 (*input) >> elements[Z]->HBondAngle[1];
435 (*input) >> elements[Z]->HBondAngle[2];
436 (*input) >> ws;
437 //Log() << Verbose(3) << "Element " << (int)tmp << " has " << FindElement((int)tmp)->HBondAngle[0] << ", " << FindElement((int)tmp)->HBondAngle[1] << ", " << FindElement((int)tmp)->HBondAngle[2] << " degrees bond angle for one, two, three connected hydrogens." << endl;
438 }
439 return true;
440 } else
441 return false;
442}
443
444/** load the hbond lengths info.
445 * \param *input stream to parse from
446 * \return true - parsing successful, false - something went wrong
447 */
448bool periodentafel::LoadHBondLengthsDatabase(istream *input)
449{
450 char dummy[MAXSTRINGSIZE];
451 if (!(*input).fail()) {
452 (*input).getline(dummy, MAXSTRINGSIZE);
453 while (!(*input).eof()) {
454 atomicNumber_t Z;
455 (*input) >> Z;
456 ASSERT(elements.count(Z), "Element not present");
457 (*input) >> ws;
458 (*input) >> elements[Z]->HBondDistance[0];
459 (*input) >> elements[Z]->HBondDistance[1];
460 (*input) >> elements[Z]->HBondDistance[2];
461 (*input) >> ws;
462 //Log() << Verbose(3) << "Element " << (int)tmp << " has " << FindElement((int)tmp)->HBondDistance[0] << " Angstrom typical distance to hydrogen." << endl;
463 }
464 return true;
465 } else
466 return false;
467}
468
469/** Stores element list to file.
470 */
471bool periodentafel::StorePeriodentafel(const char *path) const
472{
473 bool result = true;
474 ofstream f;
475 char filename[MAXSTRINGSIZE];
476
477 strncpy(filename, path, MAXSTRINGSIZE);
478 strncat(filename, "/", MAXSTRINGSIZE-strlen(filename));
479 strncat(filename, STANDARDELEMENTSDB, MAXSTRINGSIZE-strlen(filename));
480 f.open(filename);
481 if (f != NULL) {
482 f << header1 << endl;
483 f << header2 << endl;
484 for(const_iterator iter=elements.begin();iter!=elements.end();++iter){
485 result = result && (*iter).second->Output(&f);
486 }
487 f.close();
488 return true;
489 } else
490 return result;
491};
Note: See TracBrowser for help on using the repository browser.