OpenMD 3.1
Molecular Dynamics in the Open
Loading...
Searching...
No Matches
ElementsTable.cpp
Go to the documentation of this file.
1/**********************************************************************
2
3This basic Periodic Table class was originally taken from the data.cpp
4file in OpenBabel. The code has been modified to match the OpenMD coding style.
5
6We have retained the OpenBabel copyright and GPL license on this class:
7
8Copyright (C) 1998-2001 by OpenEye Scientific Software, Inc.
9Some portions Copyright (C) 2001-2005 by Geoffrey R. Hutchison
10
11This file is part of the Open Babel project.
12For more information, see <http://openbabel.sourceforge.net/>
13
14This program is free software; you can redistribute it and/or modify
15it under the terms of the GNU General Public License as published by
16the Free Software Foundation version 2 of the License.
17
18This program is distributed in the hope that it will be useful,
19but WITHOUT ANY WARRANTY; without even the implied warranty of
20MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21GNU General Public License for more details.
22***********************************************************************/
23
24/**
25 * @file ElementsTable.cpp
26 * @author gezelter
27 * @date 12/21/2007
28 * @version 1.0
29 */
30
32
33#include <config.h>
34
35#include <algorithm>
36#include <cstdlib>
37#include <fstream>
38#include <iostream>
39#include <string>
40
41#include "io/ifstrstream.hpp"
42#include "utils/simError.h"
43
44#ifdef WIN32
45#define FILE_SEP_CHAR "\\"
46#else
47#define FILE_SEP_CHAR "/"
48#endif
49
50#ifndef BUFF_SIZE
51#define BUFF_SIZE 32768
52#endif
53
54namespace OpenMD {
55
56 ElementsTable etab;
57
59
61 std::vector<Element*>::iterator i;
62 for (i = elements_.begin(); i != elements_.end(); ++i)
63 delete *i;
64 }
65
66 void ElementsTable::ParseLine(const char* buffer) {
67 int num, maxbonds;
68 char symbol[4];
69 char name[256];
70 RealType Rcov, Rvdw, mass, elNeg, ARENeg, ionize, elAffin;
71 RealType red, green, blue;
72
73 // skip comment line (at the top)
74 if (buffer[0] != '#') {
75 sscanf(buffer,
76 "%d %3s %lf %lf %*f %lf %d %lf %lf %lf %lf %lf %lf %lf %255s",
77 &num, symbol, &ARENeg, &Rcov, &Rvdw, &maxbonds, &mass, &elNeg,
78 &ionize, &elAffin, &red, &green, &blue, name);
79
80 Element* ele =
81 new Element(num, symbol, ARENeg, Rcov, Rvdw, maxbonds, mass, elNeg,
82 ionize, elAffin, red, green, blue, name);
83 elements_.push_back(ele);
84 }
85 }
86
88 if (!init_) Init();
89
90 return elements_.size();
91 }
92
93 const char* ElementsTable::GetSymbol(int atomicnum) {
94 if (!init_) Init();
95
96 if (atomicnum < 0 || atomicnum >= static_cast<int>(elements_.size()))
97 return ("\0");
98
99 return (elements_[atomicnum]->GetSymbol());
100 }
101
102 int ElementsTable::GetMaxBonds(int atomicnum) {
103 if (!init_) Init();
104
105 if (atomicnum < 0 || atomicnum >= static_cast<int>(elements_.size()))
106 return (0);
107
108 return (elements_[atomicnum]->GetMaxBonds());
109 }
110
111 RealType ElementsTable::GetElectroNeg(int atomicnum) {
112 if (!init_) Init();
113
114 if (atomicnum < 0 || atomicnum >= static_cast<int>(elements_.size()))
115 return (0.0);
116
117 return (elements_[atomicnum]->GetElectroNeg());
118 }
119
121 if (!init_) Init();
122
123 if (atomicnum < 0 || atomicnum >= static_cast<int>(elements_.size()))
124 return (0.0);
125
126 return (elements_[atomicnum]->GetAllredRochowElectroNeg());
127 }
128
129 RealType ElementsTable::GetIonization(int atomicnum) {
130 if (!init_) Init();
131
132 if (atomicnum < 0 || atomicnum >= static_cast<int>(elements_.size()))
133 return (0.0);
134
135 return (elements_[atomicnum]->GetIonization());
136 }
137
138 RealType ElementsTable::GetElectronAffinity(int atomicnum) {
139 if (!init_) Init();
140
141 if (atomicnum < 0 || atomicnum >= static_cast<int>(elements_.size()))
142 return (0.0);
143
144 return (elements_[atomicnum]->GetElectronAffinity());
145 }
146
147 std::vector<RealType> ElementsTable::GetRGB(int atomicnum) {
148 if (!init_) Init();
149
150 std::vector<RealType> colors;
151 colors.reserve(3);
152
153 if (atomicnum < 0 || atomicnum >= static_cast<int>(elements_.size())) {
154 colors.push_back(0.0);
155 colors.push_back(0.0);
156 colors.push_back(0.0);
157 return (colors);
158 }
159
160 colors.push_back(elements_[atomicnum]->GetRed());
161 colors.push_back(elements_[atomicnum]->GetGreen());
162 colors.push_back(elements_[atomicnum]->GetBlue());
163
164 return (colors);
165 }
166
167 std::string ElementsTable::GetName(int atomicnum) {
168 if (!init_) Init();
169
170 if (atomicnum < 0 || atomicnum >= static_cast<int>(elements_.size()))
171 return ("Unknown");
172
173 return (elements_[atomicnum]->GetName());
174 }
175
176 RealType ElementsTable::GetVdwRad(int atomicnum) {
177 if (!init_) Init();
178
179 if (atomicnum < 0 || atomicnum >= static_cast<int>(elements_.size()))
180 return (0.0);
181
182 return (elements_[atomicnum]->GetVdwRad());
183 }
184
185 RealType ElementsTable::CorrectedBondRad(int atomicnum, int hyb) {
186 RealType rad;
187 if (!init_) Init();
188
189 if (atomicnum < 0 || atomicnum >= static_cast<int>(elements_.size()))
190 return (1.0);
191
192 rad = elements_[atomicnum]->GetCovalentRad();
193
194 if (hyb == 2)
195 rad *= 0.95;
196 else if (hyb == 1)
197 rad *= 0.90;
198
199 return (rad);
200 }
201
202 RealType ElementsTable::CorrectedVdwRad(int atomicnum, int hyb) {
203 RealType rad;
204 if (!init_) Init();
205
206 if (atomicnum < 0 || atomicnum >= static_cast<int>(elements_.size()))
207 return (1.95);
208
209 rad = elements_[atomicnum]->GetVdwRad();
210
211 if (hyb == 2)
212 rad *= 0.95;
213 else if (hyb == 1)
214 rad *= 0.90;
215
216 return (rad);
217 }
218
219 RealType ElementsTable::GetCovalentRad(int atomicnum) {
220 if (!init_) Init();
221
222 if (atomicnum < 0 || atomicnum >= static_cast<int>(elements_.size()))
223 return (0.0);
224
225 return (elements_[atomicnum]->GetCovalentRad());
226 }
227
228 RealType ElementsTable::GetMass(int atomicnum) {
229 if (!init_) Init();
230
231 if (atomicnum < 0 || atomicnum >= static_cast<int>(elements_.size()))
232 return (0.0);
233
234 return (elements_[atomicnum]->GetMass());
235 }
236
237 int ElementsTable::GetAtomicNum(const char* sym) {
238 int temp;
239 return GetAtomicNum(sym, temp);
240 }
241
242 int ElementsTable::GetAtomicNum(const char* identifier, int& iso) {
243 if (!init_) Init();
244
245 // Compare to symbol
246 std::vector<Element*>::iterator i;
247 for (i = elements_.begin(); i != elements_.end(); ++i)
248 if (!strncasecmp(identifier, (*i)->GetSymbol(), 3))
249 return ((*i)->GetAtomicNum());
250
251 // Compare to IUPAC name (an abbreviated name will also work if 5
252 // letters or more)
253 int numCharsToTest = std::max<int>(strlen(identifier), 5);
254 for (i = elements_.begin(); i != elements_.end(); ++i)
255 if (strncasecmp(identifier, (*i)->GetName().c_str(), numCharsToTest) == 0)
256 return ((*i)->GetAtomicNum());
257
258 if (strcasecmp(identifier, "D") == 0 ||
259 (strcasecmp(identifier, "Deuterium") == 0)) {
260 iso = 2;
261 return (1);
262 } else if (strcasecmp(identifier, "T") == 0 ||
263 (strcasecmp(identifier, "Tritium") == 0)) {
264 iso = 3;
265 return (1);
266 } else if (strcasecmp(identifier, "Hl") == 0) {
267 // ligand hydrogen -- found in some CIF PR#3048959.
268 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
269 "ElementsTable warning.\n"
270 "\tCannot understand the element label %s\n"
271 "\tGuessing it's hydrogen\n",
272 identifier);
273 painCave.isFatal = 0;
274 painCave.severity = OPENMD_WARNING;
275 simError();
276 return (1);
277 } else
278 iso = 0;
279
280 if (identifier[0] != '*') {
281 // Quiet down the error messages for now:
282 // snprintf( painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
283 // "ElementsTable warning.\n"
284 // "\tCannot understand the element label %s\n", identifier);
285 // painCave.isFatal = 0;
286 // painCave.severity = OPENMD_WARNING;
287 // simError();
288 }
289 return (0);
290 }
291
292 int ElementsTable::GetAtomicNum(std::string name, int& iso) {
293 return GetAtomicNum(name.c_str(), iso);
294 }
295
297 if (init_) return;
298 init_ = true;
299
300 char* tempPath;
301 char charBuffer[BUFF_SIZE];
302 tempPath = getenv("FORCE_PARAM_PATH");
303
304 if (tempPath == NULL) {
305 // convert a macro from compiler to a string in c++
306 STR_DEFINE(dir_, FRC_PATH);
307 } else {
308 dir_ = tempPath;
309 }
310
311 std::string filename_("element.txt");
312
313 ifstrstream* efStream = new ifstrstream();
314
315 // Try to open the elements file in current directory first
316 efStream->open(filename_.c_str());
317
318 if (!efStream->is_open()) {
319 // If current directory does not contain the elements file,
320 // try to open it in ffPath_:
321 filename_ = dir_ + FILE_SEP_CHAR + filename_;
322 efStream->open(filename_.c_str());
323
324 if (!efStream->is_open()) {
325 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
326 "Error opening the ElementsTable file:\n"
327 "\t%s\n"
328 "\tHave you tried setting the FORCE_PARAM_PATH environment "
329 "variable?\n",
330 filename_.c_str());
331 painCave.severity = OPENMD_ERROR;
332 painCave.isFatal = 1;
333 simError();
334 }
335 }
336
337 if (efStream->is_open()) {
338 while (efStream->getline(charBuffer, BUFF_SIZE))
339 ParseLine(charBuffer);
340 }
341
342 if (efStream->is_open()) efStream->close();
343
344 if (GetSize() == 0) {
345 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
346 "ElementsTable error.\n"
347 "\tCannot initialize database %s \n",
348 filename_.c_str());
349 painCave.isFatal = 0;
350 simError();
351 }
352 }
353} // namespace OpenMD
This basic Periodic Table class was originally taken from the data.h file in OpenBabel.
std::string dir_
data directory for file if _envvar fails
bool init_
whether the data been read already
RealType CorrectedVdwRad(int atomicnum, int hyb=3)
RealType CorrectedBondRad(int atomicnum, int hyb=3)
RealType GetCovalentRad(int atomicnum)
~ElementsTable()
Destructor.
const char * GetSymbol(int atomicnum)
unsigned int GetNumberOfElements()
RealType GetAllredRochowElectroNeg(int atomicnum)
ElementsTable()
Constructor.
std::vector< RealType > GetRGB(int atomicnum)
std::string filename_
file to search for
int GetMaxBonds(int atomicnum)
RealType GetElectronAffinity(int atomicnum)
RealType GetIonization(int atomicnum)
RealType GetMass(int atomicnum)
std::string GetName(int atomicnum)
void Init()
Read in the data file.
void ParseLine(const char *line)
Specified by particular table classes (parses an individual data line)
RealType GetVdwRad(int atomicnum)
RealType GetElectroNeg(int atomicnum)
int GetAtomicNum(const char *str)
ifstrstream class provides a stream interface to read data from files.
void open(const char *filename, std::ios_base::openmode mode=std::ios_base::in, bool checkFilename=false)
Opens a file and associates a buffer with the specified file to perform the i/o operations (single mo...
bool is_open()
Tests if the stream is currently associated with a valid buffer.
void close()
In single mode, closes a file.
This basic Periodic Table class was originally taken from the data.cpp file in OpenBabel.