source: src/periodentafel.cpp@ 776b64

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 776b64 was db6bf74, checked in by Frederik Heber <heber@…>, 16 years ago

Fixed two memory leaks.

  • FIX: if the element database could not be parsed, in LoadPeriodentafel() still one element would be allocated, Loading failure admonished and then not free'd. Fixed
  • FIX: the config was allocated in main not by a new, but fixed. In its constructor Malloc calls were present. Hence, the memory was not free'd. As fixed types are free'd first at the very end of the code. Hence before any MemoryUsageObserver::getUsedMemorySize() calls ... that's why 1614 bytes were always claimed as still allocated. Fixed.
  • valgrind does not admonish any leaks (however, some errors) anymore when molecuilder is started and immediately quitted.

Signed-off-by: Frederik Heber <heber@…>

  • Property mode set to 100755
File size: 9.5 KB
Line 
1/** \file periodentafel.cpp
2 *
3 * Function implementations for the class periodentafel.
4 *
5 */
6
7using namespace std;
8
9#include <iomanip>
10#include <fstream>
11
12#include "element.hpp"
13#include "helpers.hpp"
14#include "lists.hpp"
15#include "periodentafel.hpp"
16#include "verbose.hpp"
17
18/************************************* Functions for class periodentafel ***************************/
19
20/** constructor for class periodentafel
21 * Initialises start and end of list and resets periodentafel::checkliste to false.
22 */
23periodentafel::periodentafel()
24{
25 start = new element;
26 end = new element;
27 start->previous = NULL;
28 start->next = end;
29 end->previous = start;
30 end->next = NULL;
31};
32
33/** destructor for class periodentafel
34 * Removes every element and afterwards deletes start and end of list.
35 */
36periodentafel::~periodentafel()
37{
38 CleanupPeriodtable();
39 delete(end);
40 delete(start);
41};
42
43/** Adds element to period table list
44 * \param *pointer element to be added
45 * \return true - succeeded, false - does not occur
46 */
47bool periodentafel::AddElement(element *pointer)
48{
49 pointer->sort = &pointer->Z;
50 if (pointer->Z < 1 && pointer->Z >= MAX_ELEMENTS)
51 cout << Verbose(0) << "Invalid Z number!\n";
52 return add(pointer, end);
53};
54
55/** Removes element from list.
56 * \param *pointer element to be removed
57 * \return true - succeeded, false - element not found
58 */
59bool periodentafel::RemoveElement(element *pointer)
60{
61 return remove(pointer, start, end);
62};
63
64/** Removes every element from the period table.
65 * \return true - succeeded, false - does not occur
66 */
67bool periodentafel::CleanupPeriodtable()
68{
69 return cleanup(start,end);
70};
71
72/** Finds an element by its atomic number.
73 * If element is not yet in list, datas are asked and stored in database.
74 * \param Z atomic number
75 * \return pointer to element
76 */
77element * periodentafel::FindElement(int Z)
78{
79 element *walker = find(&Z, start,end);
80 if (walker == NULL) { // not found: enter and put into db
81 cout << Verbose(0) << "Element not found in database, please enter." << endl;
82 walker = new element;
83 cout << Verbose(0) << "Mass: " << endl;
84 cin >> walker->mass;
85 walker->Z = Z;
86 cout << Verbose(0) << "Atomic number: " << walker->Z << endl;
87 cout << Verbose(0) << "Name [max 64 chars]: " << endl;
88 cin >> walker->name;
89 cout << Verbose(0) << "Short form [max 3 chars]: " << endl;
90 cin >> walker->symbol;
91 periodentafel::AddElement(walker);
92 }
93 return(walker);
94};
95
96/** Finds an element by its atomic number.
97 * If element is not yet in list, datas are asked and stored in database.
98 * \param shorthand chemical symbol of the element, e.g. H for hydrogene
99 * \return pointer to element
100 */
101element * periodentafel::FindElement(const char *shorthand) const
102{
103 element *walker = periodentafel::start;
104 while (walker->next != periodentafel::end) {
105 walker = walker->next;
106 if (strncmp(walker->symbol, shorthand, 3) == 0)
107 return(walker);
108 }
109 return (NULL);
110};
111
112/** Asks for element number and returns pointer to element
113 */
114element * periodentafel::AskElement()
115{
116 element *walker = NULL;
117 int Z;
118 do {
119 cout << Verbose(0) << "Atomic number Z: ";
120 cin >> Z;
121 walker = this->FindElement(Z); // give type
122 } while (walker == NULL);
123 return walker;
124};
125
126/** Prints period table to given stream.
127 * \param output stream
128 */
129bool periodentafel::Output(ofstream *output) const
130{
131 bool result = true;
132 element *walker = start;
133 if (output != NULL) {
134 while (walker->next != end) {
135 walker = walker->next;
136 result = result && walker->Output(output);
137 }
138 return result;
139 } else
140 return false;
141};
142
143/** Prints period table to given stream.
144 * \param *output output stream
145 * \param *checkliste elements table for this molecule
146 */
147bool periodentafel::Checkout(ofstream *output, const int *checkliste) const
148{
149 element *walker = start;
150 bool result = true;
151 int No = 1;
152
153 if (output != NULL) {
154 *output << "# Ion type data (PP = PseudoPotential, Z = atomic number)" << endl;
155 *output << "#Ion_TypeNr.\tAmount\tZ\tRGauss\tL_Max(PP)L_Loc(PP)IonMass\t# chemical name, symbol" << endl;
156 while (walker->next != end) {
157 walker = walker->next;
158 if ((walker != NULL) && (walker->Z > 0) && (walker->Z < MAX_ELEMENTS) && (checkliste[walker->Z])) {
159 walker->No = No;
160 result = result && walker->Checkout(output, No++, checkliste[walker->Z]);
161 }
162 }
163 return result;
164 } else
165 return false;
166};
167
168/** Loads element list from file.
169 * \param *path to to standard file names
170 */
171bool periodentafel::LoadPeriodentafel(const char *path)
172{
173 ifstream infile;
174 double tmp;
175 element *ptr;
176 bool status = true;
177 bool otherstatus = true;
178 char filename[255];
179
180 // fill elements DB
181 strncpy(filename, path, MAXSTRINGSIZE);
182 strncat(filename, "/", MAXSTRINGSIZE-strlen(filename));
183 strncat(filename, STANDARDELEMENTSDB, MAXSTRINGSIZE-strlen(filename));
184 infile.open(filename);
185 if (infile != NULL) {
186 infile.getline(header1, MAXSTRINGSIZE);
187 infile.getline(header2, MAXSTRINGSIZE); // skip first two header lines
188 cout << "Parsed elements:";
189 while (!infile.eof()) {
190 element *neues = new element;
191 infile >> neues->name;
192 //infile >> ws;
193 infile >> neues->symbol;
194 //infile >> ws;
195 infile >> neues->period;
196 //infile >> ws;
197 infile >> neues->group;
198 //infile >> ws;
199 infile >> neues->block;
200 //infile >> ws;
201 infile >> neues->Z;
202 //infile >> ws;
203 infile >> neues->mass;
204 //infile >> ws;
205 infile >> neues->CovalentRadius;
206 //infile >> ws;
207 infile >> neues->VanDerWaalsRadius;
208 //infile >> ws;
209 infile >> ws;
210 cout << " " << neues->symbol;
211 //neues->Output((ofstream *)&cout);
212 if ((neues->Z > 0) && (neues->Z < MAX_ELEMENTS))
213 periodentafel::AddElement(neues);
214 else {
215 cout << "Could not parse element: ";
216 neues->Output((ofstream *)&cout);
217 delete(neues);
218 }
219 }
220 cout << endl;
221 infile.close();
222 infile.clear();
223 } else
224 status = false;
225
226 // fill valence DB per element
227 strncpy(filename, path, MAXSTRINGSIZE);
228 strncat(filename, "/", MAXSTRINGSIZE-strlen(filename));
229 strncat(filename, STANDARDVALENCEDB, MAXSTRINGSIZE-strlen(filename));
230 infile.open(filename);
231 if (infile != NULL) {
232 while (!infile.eof()) {
233 infile >> tmp;
234 infile >> ws;
235 infile >> FindElement((int)tmp)->Valence;
236 infile >> ws;
237 //cout << Verbose(3) << "Element " << (int)tmp << " has " << FindElement((int)tmp)->Valence << " valence electrons." << endl;
238 }
239 infile.close();
240 infile.clear();
241 } else
242 otherstatus = false;
243
244 // fill valence DB per element
245 strncpy(filename, path, MAXSTRINGSIZE);
246 strncat(filename, "/", MAXSTRINGSIZE-strlen(filename));
247 strncat(filename, STANDARDORBITALDB, MAXSTRINGSIZE-strlen(filename));
248 infile.open(filename);
249 if (infile != NULL) {
250 while (!infile.eof()) {
251 infile >> tmp;
252 infile >> ws;
253 infile >> FindElement((int)tmp)->NoValenceOrbitals;
254 infile >> ws;
255 //cout << Verbose(3) << "Element " << (int)tmp << " has " << FindElement((int)tmp)->NoValenceOrbitals << " number of singly occupied valence orbitals." << endl;
256 }
257 infile.close();
258 infile.clear();
259 } else
260 otherstatus = false;
261
262 // fill H-BondDistance DB per element
263 strncpy(filename, path, MAXSTRINGSIZE);
264 strncat(filename, "/", MAXSTRINGSIZE-strlen(filename));
265 strncat(filename, STANDARDHBONDDISTANCEDB, MAXSTRINGSIZE-strlen(filename));
266 infile.open(filename);
267 if (infile != NULL) {
268 while (!infile.eof()) {
269 infile >> tmp;
270 ptr = FindElement((int)tmp);
271 infile >> ws;
272 infile >> ptr->HBondDistance[0];
273 infile >> ptr->HBondDistance[1];
274 infile >> ptr->HBondDistance[2];
275 infile >> ws;
276 //cout << Verbose(3) << "Element " << (int)tmp << " has " << FindElement((int)tmp)->HBondDistance[0] << " Angstrom typical distance to hydrogen." << endl;
277 }
278 infile.close();
279 infile.clear();
280 } else
281 otherstatus = false;
282
283 // fill H-BondAngle DB per element
284 strncpy(filename, path, MAXSTRINGSIZE);
285 strncat(filename, "/", MAXSTRINGSIZE-strlen(filename));
286 strncat(filename, STANDARDHBONDANGLEDB, MAXSTRINGSIZE-strlen(filename));
287 infile.open(filename);
288 if (infile != NULL) {
289 while (!infile.eof()) {
290 infile >> tmp;
291 ptr = FindElement((int)tmp);
292 infile >> ws;
293 infile >> ptr->HBondAngle[0];
294 infile >> ptr->HBondAngle[1];
295 infile >> ptr->HBondAngle[2];
296 infile >> ws;
297 //cout << 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;
298 }
299 infile.close();
300 } else
301 otherstatus = false;
302
303 if (!otherstatus)
304 cerr << "WARNING: Something went wrong while parsing the other databases!" << endl;
305
306 return status;
307};
308
309/** Stores element list to file.
310 */
311bool periodentafel::StorePeriodentafel(const char *path) const
312{
313 bool result = true;
314 ofstream f;
315 char filename[MAXSTRINGSIZE];
316
317 strncpy(filename, path, MAXSTRINGSIZE);
318 strncat(filename, "/", MAXSTRINGSIZE-strlen(filename));
319 strncat(filename, STANDARDELEMENTSDB, MAXSTRINGSIZE-strlen(filename));
320 f.open(filename);
321 if (f != NULL) {
322 f << header1 << endl;
323 f << header2 << endl;
324 element *walker = periodentafel::start;
325 while (walker->next != periodentafel::end) {
326 walker = walker->next;
327 result = result && walker->Output(&f);
328 }
329 f.close();
330 } else
331 result = false;
332 return result;
333};
Note: See TracBrowser for help on using the repository browser.