source: src/periodentafel.cpp@ bbbad5

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

Added MemDebug.hpp to each and every .cpp file (were it was still missing).

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