Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/periodentafel.cpp

    ra67d19 r4eb4fe  
    88
    99#include <iomanip>
     10#include <iostream>
    1011#include <fstream>
    1112#include <cstring>
    1213
     14#include "Helpers/Assert.hpp"
    1315#include "element.hpp"
     16#include "elements_db.hpp"
    1417#include "helpers.hpp"
    1518#include "lists.hpp"
     
    1821#include "verbose.hpp"
    1922
     23using namespace std;
     24
    2025/************************************* Functions for class periodentafel ***************************/
    2126
     
    2328 * Initialises start and end of list and resets periodentafel::checkliste to false.
    2429 */
    25 periodentafel::periodentafel() : start(new element), end(new element)
    26 {
    27   start->previous = NULL;
    28   start->next = end;
    29   end->previous = start;
    30   end->next = NULL;
     30periodentafel::periodentafel()
     31{
     32  ASSERT(LoadElementsDatabase(new stringstream(elementsDB,ios_base::in)), "General element initialization failed");
     33  ASSERT(LoadValenceDatabase(new stringstream(valenceDB,ios_base::in)), "Valence entry of element initialization failed");
     34  ASSERT(LoadOrbitalsDatabase(new stringstream(orbitalsDB,ios_base::in)), "Orbitals entry of element initialization failed");
     35  ASSERT(LoadHBondAngleDatabase(new stringstream(HbondangleDB,ios_base::in)), "HBond angle entry of element initialization failed");
     36  ASSERT(LoadHBondLengthsDatabase(new stringstream(HbonddistanceDB,ios_base::in)), "HBond distance entry of element initialization failed");
    3137};
    3238
     
    3743{
    3844  CleanupPeriodtable();
    39   delete(end);
    40   delete(start);
    4145};
    4246
    4347/** Adds element to period table list
    4448 * \param *pointer element to be added
    45  * \return true - succeeded, false - does not occur
    46  */
    47 bool periodentafel::AddElement(element * const pointer)
    48 {
     49 * \return iterator to added element
     50 */
     51periodentafel::iterator periodentafel::AddElement(element * const pointer)
     52{
     53  atomicNumber_t Z = pointer->getNumber();
     54  ASSERT(!elements.count(Z), "Element is already present.");
    4955  pointer->sort = &pointer->Z;
    50   if (pointer->Z < 1 && pointer->Z >= MAX_ELEMENTS)
    51     DoLog(0) && (Log() << Verbose(0) << "Invalid Z number!\n");
    52   return add(pointer, end);
     56  if (pointer->getNumber() < 1 && pointer->getNumber() >= MAX_ELEMENTS)
     57    DoeLog(0) && (eLog() << Verbose(0) << "Invalid Z number!\n");
     58  pair<iterator,bool> res = elements.insert(pair<atomicNumber_t,element*>(Z,pointer));
     59  return res.first;
    5360};
    5461
    5562/** Removes element from list.
    5663 * \param *pointer element to be removed
    57  * \return true - succeeded, false - element not found
    58  */
    59 bool periodentafel::RemoveElement(element * const pointer)
    60 {
    61   return remove(pointer, start, end);
     64 */
     65void periodentafel::RemoveElement(element * const pointer)
     66{
     67  RemoveElement(pointer->getNumber());
     68};
     69
     70/** Removes element from list.
     71 * \param Z element to be removed
     72 */
     73void periodentafel::RemoveElement(atomicNumber_t Z)
     74{
     75  elements.erase(Z);
    6276};
    6377
    6478/** Removes every element from the period table.
    65  * \return true - succeeded, false - does not occur
    66  */
    67 bool periodentafel::CleanupPeriodtable()
    68 {
    69   return cleanup(start,end);
     79 */
     80void periodentafel::CleanupPeriodtable()
     81{
     82  for(iterator iter=elements.begin();iter!=elements.end();++iter){
     83    delete(*iter).second;
     84  }
     85  elements.clear();
    7086};
    7187
     
    7591 * \return pointer to element or NULL if not found
    7692 */
    77 element * const periodentafel::FindElement(const int Z) const
    78 {
    79   element *walker = find(&Z, start,end);
    80   return(walker);
     93element * const periodentafel::FindElement(atomicNumber_t Z) const
     94{
     95  const_iterator res = elements.find(Z);
     96  return res!=elements.end()?((*res).second):0;
    8197};
    8298
     
    88104element * const periodentafel::FindElement(const char * const shorthand) const
    89105{
    90   element *walker =  periodentafel::start;
    91   while (walker->next != periodentafel::end) {
    92     walker = walker->next;
    93     if (strncmp(walker->symbol, shorthand, 3) == 0)
    94       return(walker);
     106  element *res = 0;
     107  for(const_iterator iter=elements.begin();iter!=elements.end();++iter) {
     108    if((*iter).second->getSymbol() == shorthand){
     109      res = (*iter).second;
     110      break;
     111    }
    95112  }
    96   return (NULL);
     113  return res;
    97114};
    98115
    99116/** Asks for element number and returns pointer to element
     117 * \return desired element or NULL
    100118 */
    101119element * const periodentafel::AskElement() const
    102120{
    103   element *walker = NULL;
     121  element * walker = NULL;
    104122  int Z;
    105123  do {
     
    116134element * const periodentafel::EnterElement()
    117135{
    118   element *walker = NULL;
    119   int Z = -1;
     136  atomicNumber_t Z = 0;
    120137  DoLog(0) && (Log() << Verbose(0) << "Atomic number: " << Z << endl);
    121138  cin >> Z;
    122   walker = FindElement(Z);
    123   if (walker == NULL) {
     139  element * const res = FindElement(Z);
     140  if (!res) {
     141    // TODO: make this using the constructor
    124142    DoLog(0) && (Log() << Verbose(0) << "Element not found in database, please enter." << endl);
    125     walker = new element;
    126     walker->Z = Z;
     143    element *tmp = new element;
     144    tmp->Z = Z;
    127145    DoLog(0) && (Log() << Verbose(0) << "Mass: " << endl);
    128     cin >> walker->mass;
     146    cin >> tmp->mass;
    129147    DoLog(0) && (Log() << Verbose(0) << "Name [max 64 chars]: " << endl);
    130     cin >> walker->name;
     148    cin >> tmp->name;
    131149    DoLog(0) && (Log() << Verbose(0) << "Short form [max 3 chars]: " << endl);
    132     cin >> walker->symbol;
    133     periodentafel::AddElement(walker);
     150    cin >> tmp->symbol;
     151    AddElement(tmp);
     152    return tmp;
    134153  }
    135   return(walker);
    136 };
     154  return res;
     155};
     156
     157
     158/******************** Access to iterators ****************************/
     159periodentafel::const_iterator periodentafel::begin(){
     160  return elements.begin();
     161}
     162
     163periodentafel::const_iterator periodentafel::end(){
     164  return elements.end();
     165}
     166
     167periodentafel::reverse_iterator periodentafel::rbegin(){
     168  return reverse_iterator(elements.end());
     169}
     170
     171periodentafel::reverse_iterator periodentafel::rend(){
     172  return reverse_iterator(elements.begin());
     173}
    137174
    138175/** Prints period table to given stream.
    139176 * \param output stream
    140177 */
    141 bool periodentafel::Output(ofstream * const output) const
     178bool periodentafel::Output(ostream * const output) const
    142179{
    143180  bool result = true;
    144   element *walker = start;
    145181  if (output != NULL) {
    146     while (walker->next != end) {
    147       walker = walker->next;
    148       result = result && walker->Output(output);
     182    for(const_iterator iter=elements.begin(); iter !=elements.end();++iter){
     183      result = result && (*iter).second->Output(output);
    149184    }
    150185    return result;
     
    157192 * \param *checkliste elements table for this molecule
    158193 */
    159 bool periodentafel::Checkout(ofstream * const output, const int * const checkliste) const
    160 {
    161   element *walker = start;
     194bool periodentafel::Checkout(ostream * const output, const int * const checkliste) const
     195{
    162196  bool result = true;
    163197  int No = 1;
     
    166200    *output << "# Ion type data (PP = PseudoPotential, Z = atomic number)" << endl;
    167201    *output << "#Ion_TypeNr.\tAmount\tZ\tRGauss\tL_Max(PP)L_Loc(PP)IonMass\t# chemical name, symbol" << endl;
    168     while (walker->next != end) {
    169       walker = walker->next;
    170       if ((walker != NULL) && (walker->Z > 0) && (walker->Z < MAX_ELEMENTS) && (checkliste[walker->Z])) {
    171         walker->No = No;
    172         result = result && walker->Checkout(output, No++, checkliste[walker->Z]);
     202    for(const_iterator iter=elements.begin(); iter!=elements.end();++iter){
     203      if (((*iter).first < MAX_ELEMENTS) && (checkliste[(*iter).first])) {
     204        (*iter).second->No = No;
     205        result = result && (*iter).second->Checkout(output, No++, checkliste[(*iter).first]);
    173206      }
    174207    }
     
    183216bool periodentafel::LoadPeriodentafel(const char *path)
    184217{
    185   ifstream infile;
    186   double tmp;
    187   element *ptr;
     218  ifstream input;
    188219  bool status = true;
    189220  bool otherstatus = true;
     
    194225  strncat(filename, "/", MAXSTRINGSIZE-strlen(filename));
    195226  strncat(filename, STANDARDELEMENTSDB, MAXSTRINGSIZE-strlen(filename));
    196   infile.open(filename);
    197   if (infile != NULL) {
    198     infile.getline(header1, MAXSTRINGSIZE);
    199     infile.getline(header2, MAXSTRINGSIZE); // skip first two header lines
     227  input.open(filename);
     228  status = status && LoadElementsDatabase(&input);
     229
     230  // fill valence DB per element
     231  strncpy(filename, path, MAXSTRINGSIZE);
     232  strncat(filename, "/", MAXSTRINGSIZE-strlen(filename));
     233  strncat(filename, STANDARDVALENCEDB, MAXSTRINGSIZE-strlen(filename));
     234  input.open(filename);
     235  otherstatus = otherstatus && LoadValenceDatabase(&input);
     236
     237  // fill orbitals DB per element
     238  strncpy(filename, path, MAXSTRINGSIZE);
     239  strncat(filename, "/", MAXSTRINGSIZE-strlen(filename));
     240  strncat(filename, STANDARDORBITALDB, MAXSTRINGSIZE-strlen(filename));
     241  input.open(filename);
     242  otherstatus = otherstatus && LoadOrbitalsDatabase(&input);
     243
     244  // fill H-BondAngle DB per element
     245  strncpy(filename, path, MAXSTRINGSIZE);
     246  strncat(filename, "/", MAXSTRINGSIZE-strlen(filename));
     247  strncat(filename, STANDARDHBONDANGLEDB, MAXSTRINGSIZE-strlen(filename));
     248  input.open(filename);
     249  otherstatus = otherstatus && LoadHBondAngleDatabase(&input);
     250
     251  // fill H-BondDistance DB per element
     252  strncpy(filename, path, MAXSTRINGSIZE);
     253  strncat(filename, "/", MAXSTRINGSIZE-strlen(filename));
     254  strncat(filename, STANDARDHBONDDISTANCEDB, MAXSTRINGSIZE-strlen(filename));
     255  input.open(filename);
     256  otherstatus = otherstatus && LoadHBondLengthsDatabase(&input);
     257
     258  if (!otherstatus){
     259    DoeLog(2) && (eLog()<< Verbose(2) << "Something went wrong while parsing the other databases!" << endl);
     260  }
     261
     262  return status;
     263};
     264
     265/** load the element info.
     266 * \param *input stream to parse from
     267 * \return true - parsing successful, false - something went wrong
     268 */
     269bool periodentafel::LoadElementsDatabase(istream *input)
     270{
     271  if ((*input) != NULL) {
     272    (*input).getline(header1, MAXSTRINGSIZE);
     273    (*input).getline(header2, MAXSTRINGSIZE); // skip first two header lines
    200274    DoLog(0) && (Log() << Verbose(0) <<  "Parsed elements:");
    201     while (!infile.eof()) {
     275    while (!(*input).eof()) {
    202276      element *neues = new element;
    203       infile >> neues->name;
    204       //infile >> ws;
    205       infile >> neues->symbol;
    206       //infile >> ws;
    207       infile >> neues->period;
    208       //infile >> ws;
    209       infile >> neues->group;
    210       //infile >> ws;
    211       infile >> neues->block;
    212       //infile >> ws;
    213       infile >> neues->Z;
    214       //infile >> ws;
    215       infile >> neues->mass;
    216       //infile >> ws;
    217       infile >> neues->CovalentRadius;
    218       //infile >> ws;
    219       infile >> neues->VanDerWaalsRadius;
    220       //infile >> ws;
    221       infile >> ws;
     277      (*input) >> neues->name;
     278      //(*input) >> ws;
     279      (*input) >> neues->symbol;
     280      //(*input) >> ws;
     281      (*input) >> neues->period;
     282      //(*input) >> ws;
     283      (*input) >> neues->group;
     284      //(*input) >> ws;
     285      (*input) >> neues->block;
     286      //(*input) >> ws;
     287      (*input) >> neues->Z;
     288      //(*input) >> ws;
     289      (*input) >> neues->mass;
     290      //(*input) >> ws;
     291      (*input) >> neues->CovalentRadius;
     292      //(*input) >> ws;
     293      (*input) >> neues->VanDerWaalsRadius;
     294      //(*input) >> ws;
     295      (*input) >> ws;
    222296      DoLog(0) && (Log() << Verbose(0) << " " << neues->symbol);
     297      if (elements.count(neues->Z)) {// if element already present, remove and delete it
     298        element * const Elemental = FindElement(neues->Z);
     299        ASSERT(Elemental != NULL, "element should be present but is not??");
     300        RemoveElement(Elemental);
     301        delete(Elemental);
     302      }
    223303      //neues->Output((ofstream *)&cout);
    224304      if ((neues->Z > 0) && (neues->Z < MAX_ELEMENTS))
    225         periodentafel::AddElement(neues);
     305        elements[neues->getNumber()] = neues;
    226306      else {
    227307        DoLog(0) && (Log() << Verbose(0) << "Could not parse element: ");
     
    231311    }
    232312    DoLog(0) && (Log() << Verbose(0) << endl);
    233     infile.close();
    234     infile.clear();
    235   } else
    236     status = false;
    237 
    238   // fill valence DB per element
    239   strncpy(filename, path, MAXSTRINGSIZE);
    240   strncat(filename, "/", MAXSTRINGSIZE-strlen(filename));
    241   strncat(filename, STANDARDVALENCEDB, MAXSTRINGSIZE-strlen(filename));
    242   infile.open(filename);
    243   if (infile != NULL) {
    244     while (!infile.eof()) {
    245       infile >> tmp;
    246       infile >> ws;
    247       infile >> FindElement((int)tmp)->Valence;
    248       infile >> ws;
     313    return true;
     314  } else
     315    return false;
     316}
     317
     318/** load the valence info.
     319 * \param *input stream to parse from
     320 * \return true - parsing successful, false - something went wrong
     321 */
     322bool periodentafel::LoadValenceDatabase(istream *input)
     323{
     324  char dummy[MAXSTRINGSIZE];
     325  if ((*input) != NULL) {
     326    (*input).getline(dummy, MAXSTRINGSIZE);
     327    while (!(*input).eof()) {
     328      atomicNumber_t Z;
     329      (*input) >> Z;
     330      ASSERT(elements.count(Z), "Element not present");
     331      (*input) >> ws;
     332      (*input) >> elements[Z]->Valence;
     333      (*input) >> ws;
    249334      //Log() << Verbose(3) << "Element " << (int)tmp << " has " << FindElement((int)tmp)->Valence << " valence electrons." << endl;
    250335    }
    251     infile.close();
    252     infile.clear();
    253   } else
    254     otherstatus = false;
    255 
    256   // fill valence DB per element
    257   strncpy(filename, path, MAXSTRINGSIZE);
    258   strncat(filename, "/", MAXSTRINGSIZE-strlen(filename));
    259   strncat(filename, STANDARDORBITALDB, MAXSTRINGSIZE-strlen(filename));
    260   infile.open(filename);
    261   if (infile != NULL) {
    262     while (!infile.eof()) {
    263       infile >> tmp;
    264       infile >> ws;
    265       infile >> FindElement((int)tmp)->NoValenceOrbitals;
    266       infile >> ws;
     336    return true;
     337  } else
     338                return false;
     339}
     340
     341/** load the orbitals info.
     342 * \param *input stream to parse from
     343 * \return true - parsing successful, false - something went wrong
     344 */
     345bool periodentafel::LoadOrbitalsDatabase(istream *input)
     346{
     347  char dummy[MAXSTRINGSIZE];
     348  if ((*input) != NULL) {
     349    (*input).getline(dummy, MAXSTRINGSIZE);
     350    while (!(*input).eof()) {
     351      atomicNumber_t Z;
     352      (*input) >> Z;
     353      ASSERT(elements.count(Z), "Element not present");
     354      (*input) >> ws;
     355      (*input) >> elements[Z]->NoValenceOrbitals;
     356      (*input) >> ws;
    267357      //Log() << Verbose(3) << "Element " << (int)tmp << " has " << FindElement((int)tmp)->NoValenceOrbitals << " number of singly occupied valence orbitals." << endl;
    268358    }
    269     infile.close();
    270     infile.clear();
    271   } else
    272     otherstatus = false;
    273 
    274   // fill H-BondDistance DB per element
    275   strncpy(filename, path, MAXSTRINGSIZE);
    276   strncat(filename, "/", MAXSTRINGSIZE-strlen(filename));
    277   strncat(filename, STANDARDHBONDDISTANCEDB, MAXSTRINGSIZE-strlen(filename));
    278   infile.open(filename);
    279   if (infile != NULL) {
    280     while (!infile.eof()) {
    281       infile >> tmp;
    282       ptr = FindElement((int)tmp);
    283       infile >> ws;
    284       infile >> ptr->HBondDistance[0];
    285       infile >> ptr->HBondDistance[1];
    286       infile >> ptr->HBondDistance[2];
    287       infile >> ws;
     359    return true;
     360  } else
     361    return false;
     362}
     363
     364/** load the hbond angles info.
     365 * \param *input stream to parse from
     366 * \return true - parsing successful, false - something went wrong
     367 */
     368bool periodentafel::LoadHBondAngleDatabase(istream *input)
     369{
     370  char dummy[MAXSTRINGSIZE];
     371  if ((*input) != NULL) {
     372    (*input).getline(dummy, MAXSTRINGSIZE);
     373    while (!(*input).eof()) {
     374      atomicNumber_t Z;
     375      (*input) >> Z;
     376      ASSERT(elements.count(Z), "Element not present");
     377      (*input) >> ws;
     378      (*input) >> elements[Z]->HBondAngle[0];
     379      (*input) >> elements[Z]->HBondAngle[1];
     380      (*input) >> elements[Z]->HBondAngle[2];
     381      (*input) >> ws;
     382      //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;
     383    }
     384    return true;
     385  } else
     386                return false;
     387}
     388
     389/** load the hbond lengths info.
     390 * \param *input stream to parse from
     391 * \return true - parsing successful, false - something went wrong
     392 */
     393bool periodentafel::LoadHBondLengthsDatabase(istream *input)
     394{
     395  char dummy[MAXSTRINGSIZE];
     396  if ((*input) != NULL) {
     397    (*input).getline(dummy, MAXSTRINGSIZE);
     398    while (!(*input).eof()) {
     399      atomicNumber_t Z;
     400      (*input) >> Z;
     401      ASSERT(elements.count(Z), "Element not present");
     402      (*input) >> ws;
     403      (*input) >> elements[Z]->HBondDistance[0];
     404      (*input) >> elements[Z]->HBondDistance[1];
     405      (*input) >> elements[Z]->HBondDistance[2];
     406      (*input) >> ws;
    288407      //Log() << Verbose(3) << "Element " << (int)tmp << " has " << FindElement((int)tmp)->HBondDistance[0] << " Angstrom typical distance to hydrogen." << endl;
    289408    }
    290     infile.close();
    291     infile.clear();
    292   } else
    293     otherstatus = false;
    294 
    295   // fill H-BondAngle DB per element
    296   strncpy(filename, path, MAXSTRINGSIZE);
    297   strncat(filename, "/", MAXSTRINGSIZE-strlen(filename));
    298   strncat(filename, STANDARDHBONDANGLEDB, MAXSTRINGSIZE-strlen(filename));
    299   infile.open(filename);
    300   if (infile != NULL) {
    301     while (!infile.eof()) {
    302       infile >> tmp;
    303       ptr = FindElement((int)tmp);
    304       infile >> ws;
    305       infile >> ptr->HBondAngle[0];
    306       infile >> ptr->HBondAngle[1];
    307       infile >> ptr->HBondAngle[2];
    308       infile >> ws;
    309       //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;
    310     }
    311     infile.close();
    312   } else
    313     otherstatus = false;
    314 
    315   if (!otherstatus)
    316     DoeLog(2) && (eLog()<< Verbose(2) << "Something went wrong while parsing the other databases!" << endl);
    317 
    318   return status;
    319 };
     409    return true;
     410  } else
     411                return false;
     412}
    320413
    321414/** Stores element list to file.
     
    334427    f << header1 << endl;
    335428    f << header2 << endl;
    336     element *walker = periodentafel::start;
    337     while (walker->next != periodentafel::end) {
    338       walker = walker->next;
    339       result = result && walker->Output(&f);
     429    for(const_iterator iter=elements.begin();iter!=elements.end();++iter){
     430         result = result && (*iter).second->Output(&f);
    340431    }
    341432    f.close();
    342   } else
    343     result = false;
    344   return result;
    345 };
     433    return true;
     434  } else
     435    return result;
     436};
Note: See TracChangeset for help on using the changeset viewer.