Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/periodentafel.cpp

    r4eb4fe ra67d19  
    88
    99#include <iomanip>
    10 #include <iostream>
    1110#include <fstream>
    1211#include <cstring>
    1312
    14 #include "Helpers/Assert.hpp"
    1513#include "element.hpp"
    16 #include "elements_db.hpp"
    1714#include "helpers.hpp"
    1815#include "lists.hpp"
     
    2118#include "verbose.hpp"
    2219
    23 using namespace std;
    24 
    2520/************************************* Functions for class periodentafel ***************************/
    2621
     
    2823 * Initialises start and end of list and resets periodentafel::checkliste to false.
    2924 */
    30 periodentafel::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");
     25periodentafel::periodentafel() : start(new element), end(new element)
     26{
     27  start->previous = NULL;
     28  start->next = end;
     29  end->previous = start;
     30  end->next = NULL;
    3731};
    3832
     
    4337{
    4438  CleanupPeriodtable();
     39  delete(end);
     40  delete(start);
    4541};
    4642
    4743/** Adds element to period table list
    4844 * \param *pointer element to be added
    49  * \return iterator to added element
    50  */
    51 periodentafel::iterator periodentafel::AddElement(element * const pointer)
    52 {
    53   atomicNumber_t Z = pointer->getNumber();
    54   ASSERT(!elements.count(Z), "Element is already present.");
     45 * \return true - succeeded, false - does not occur
     46 */
     47bool periodentafel::AddElement(element * const pointer)
     48{
    5549  pointer->sort = &pointer->Z;
    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;
     50  if (pointer->Z < 1 && pointer->Z >= MAX_ELEMENTS)
     51    DoLog(0) && (Log() << Verbose(0) << "Invalid Z number!\n");
     52  return add(pointer, end);
    6053};
    6154
    6255/** Removes element from list.
    6356 * \param *pointer element to be removed
    64  */
    65 void 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  */
    73 void periodentafel::RemoveElement(atomicNumber_t Z)
    74 {
    75   elements.erase(Z);
     57 * \return true - succeeded, false - element not found
     58 */
     59bool periodentafel::RemoveElement(element * const pointer)
     60{
     61  return remove(pointer, start, end);
    7662};
    7763
    7864/** Removes every element from the period table.
    79  */
    80 void periodentafel::CleanupPeriodtable()
    81 {
    82   for(iterator iter=elements.begin();iter!=elements.end();++iter){
    83     delete(*iter).second;
    84   }
    85   elements.clear();
     65 * \return true - succeeded, false - does not occur
     66 */
     67bool periodentafel::CleanupPeriodtable()
     68{
     69  return cleanup(start,end);
    8670};
    8771
     
    9175 * \return pointer to element or NULL if not found
    9276 */
    93 element * const periodentafel::FindElement(atomicNumber_t Z) const
    94 {
    95   const_iterator res = elements.find(Z);
    96   return res!=elements.end()?((*res).second):0;
     77element * const periodentafel::FindElement(const int Z) const
     78{
     79  element *walker = find(&Z, start,end);
     80  return(walker);
    9781};
    9882
     
    10488element * const periodentafel::FindElement(const char * const shorthand) const
    10589{
    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     }
     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);
    11295  }
    113   return res;
     96  return (NULL);
    11497};
    11598
    11699/** Asks for element number and returns pointer to element
    117  * \return desired element or NULL
    118100 */
    119101element * const periodentafel::AskElement() const
    120102{
    121   element * walker = NULL;
     103  element *walker = NULL;
    122104  int Z;
    123105  do {
     
    134116element * const periodentafel::EnterElement()
    135117{
    136   atomicNumber_t Z = 0;
     118  element *walker = NULL;
     119  int Z = -1;
    137120  DoLog(0) && (Log() << Verbose(0) << "Atomic number: " << Z << endl);
    138121  cin >> Z;
    139   element * const res = FindElement(Z);
    140   if (!res) {
    141     // TODO: make this using the constructor
     122  walker = FindElement(Z);
     123  if (walker == NULL) {
    142124    DoLog(0) && (Log() << Verbose(0) << "Element not found in database, please enter." << endl);
    143     element *tmp = new element;
    144     tmp->Z = Z;
     125    walker = new element;
     126    walker->Z = Z;
    145127    DoLog(0) && (Log() << Verbose(0) << "Mass: " << endl);
    146     cin >> tmp->mass;
     128    cin >> walker->mass;
    147129    DoLog(0) && (Log() << Verbose(0) << "Name [max 64 chars]: " << endl);
    148     cin >> tmp->name;
     130    cin >> walker->name;
    149131    DoLog(0) && (Log() << Verbose(0) << "Short form [max 3 chars]: " << endl);
    150     cin >> tmp->symbol;
    151     AddElement(tmp);
    152     return tmp;
     132    cin >> walker->symbol;
     133    periodentafel::AddElement(walker);
    153134  }
    154   return res;
    155 };
    156 
    157 
    158 /******************** Access to iterators ****************************/
    159 periodentafel::const_iterator periodentafel::begin(){
    160   return elements.begin();
    161 }
    162 
    163 periodentafel::const_iterator periodentafel::end(){
    164   return elements.end();
    165 }
    166 
    167 periodentafel::reverse_iterator periodentafel::rbegin(){
    168   return reverse_iterator(elements.end());
    169 }
    170 
    171 periodentafel::reverse_iterator periodentafel::rend(){
    172   return reverse_iterator(elements.begin());
    173 }
     135  return(walker);
     136};
    174137
    175138/** Prints period table to given stream.
    176139 * \param output stream
    177140 */
    178 bool periodentafel::Output(ostream * const output) const
     141bool periodentafel::Output(ofstream * const output) const
    179142{
    180143  bool result = true;
     144  element *walker = start;
    181145  if (output != NULL) {
    182     for(const_iterator iter=elements.begin(); iter !=elements.end();++iter){
    183       result = result && (*iter).second->Output(output);
     146    while (walker->next != end) {
     147      walker = walker->next;
     148      result = result && walker->Output(output);
    184149    }
    185150    return result;
     
    192157 * \param *checkliste elements table for this molecule
    193158 */
    194 bool periodentafel::Checkout(ostream * const output, const int * const checkliste) const
    195 {
     159bool periodentafel::Checkout(ofstream * const output, const int * const checkliste) const
     160{
     161  element *walker = start;
    196162  bool result = true;
    197163  int No = 1;
     
    200166    *output << "# Ion type data (PP = PseudoPotential, Z = atomic number)" << endl;
    201167    *output << "#Ion_TypeNr.\tAmount\tZ\tRGauss\tL_Max(PP)L_Loc(PP)IonMass\t# chemical name, symbol" << endl;
    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]);
     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]);
    206173      }
    207174    }
     
    216183bool periodentafel::LoadPeriodentafel(const char *path)
    217184{
    218   ifstream input;
     185  ifstream infile;
     186  double tmp;
     187  element *ptr;
    219188  bool status = true;
    220189  bool otherstatus = true;
     
    225194  strncat(filename, "/", MAXSTRINGSIZE-strlen(filename));
    226195  strncat(filename, STANDARDELEMENTSDB, MAXSTRINGSIZE-strlen(filename));
    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  */
    269 bool periodentafel::LoadElementsDatabase(istream *input)
    270 {
    271   if ((*input) != NULL) {
    272     (*input).getline(header1, MAXSTRINGSIZE);
    273     (*input).getline(header2, MAXSTRINGSIZE); // skip first two header lines
     196  infile.open(filename);
     197  if (infile != NULL) {
     198    infile.getline(header1, MAXSTRINGSIZE);
     199    infile.getline(header2, MAXSTRINGSIZE); // skip first two header lines
    274200    DoLog(0) && (Log() << Verbose(0) <<  "Parsed elements:");
    275     while (!(*input).eof()) {
     201    while (!infile.eof()) {
    276202      element *neues = new element;
    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;
     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;
    296222      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       }
    303223      //neues->Output((ofstream *)&cout);
    304224      if ((neues->Z > 0) && (neues->Z < MAX_ELEMENTS))
    305         elements[neues->getNumber()] = neues;
     225        periodentafel::AddElement(neues);
    306226      else {
    307227        DoLog(0) && (Log() << Verbose(0) << "Could not parse element: ");
     
    311231    }
    312232    DoLog(0) && (Log() << Verbose(0) << endl);
    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  */
    322 bool 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;
     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;
    334249      //Log() << Verbose(3) << "Element " << (int)tmp << " has " << FindElement((int)tmp)->Valence << " valence electrons." << endl;
    335250    }
    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  */
    345 bool 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;
     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;
    357267      //Log() << Verbose(3) << "Element " << (int)tmp << " has " << FindElement((int)tmp)->NoValenceOrbitals << " number of singly occupied valence orbitals." << endl;
    358268    }
    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  */
    368 bool 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;
     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;
     288      //Log() << Verbose(3) << "Element " << (int)tmp << " has " << FindElement((int)tmp)->HBondDistance[0] << " Angstrom typical distance to hydrogen." << endl;
     289    }
     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;
    382309      //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;
    383310    }
    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  */
    393 bool 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;
    407       //Log() << Verbose(3) << "Element " << (int)tmp << " has " << FindElement((int)tmp)->HBondDistance[0] << " Angstrom typical distance to hydrogen." << endl;
    408     }
    409     return true;
    410   } else
    411                 return false;
    412 }
     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};
    413320
    414321/** Stores element list to file.
     
    427334    f << header1 << endl;
    428335    f << header2 << endl;
    429     for(const_iterator iter=elements.begin();iter!=elements.end();++iter){
    430          result = result && (*iter).second->Output(&f);
     336    element *walker = periodentafel::start;
     337    while (walker->next != periodentafel::end) {
     338      walker = walker->next;
     339      result = result && walker->Output(&f);
    431340    }
    432341    f.close();
    433     return true;
    434   } else
    435     return result;
    436 };
     342  } else
     343    result = false;
     344  return result;
     345};
Note: See TracChangeset for help on using the changeset viewer.