OpenMD 3.0
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 init_ = false;
60 dir_ = std::string("TO_STRING(FRC_PATH)");
61 envvar_ = "FORCE_PARAM_PATH";
62 filename_ = "element.txt";
63 }
64
66 std::vector<Element*>::iterator i;
67 for (i = elements_.begin(); i != elements_.end(); ++i)
68 delete *i;
69 }
70
71 void ElementsTable::ParseLine(const char* buffer) {
72 int num, maxbonds;
73 char symbol[4];
74 char name[256];
75 RealType Rcov, Rvdw, mass, elNeg, ARENeg, ionize, elAffin;
76 RealType red, green, blue;
77
78 // skip comment line (at the top)
79 if (buffer[0] != '#') {
80 sscanf(buffer,
81 "%d %3s %lf %lf %*f %lf %d %lf %lf %lf %lf %lf %lf %lf %255s",
82 &num, symbol, &ARENeg, &Rcov, &Rvdw, &maxbonds, &mass, &elNeg,
83 &ionize, &elAffin, &red, &green, &blue, name);
84
85 Element* ele =
86 new Element(num, symbol, ARENeg, Rcov, Rvdw, maxbonds, mass, elNeg,
87 ionize, elAffin, red, green, blue, name);
88 elements_.push_back(ele);
89 }
90 }
91
93 if (!init_) Init();
94
95 return elements_.size();
96 }
97
98 const char* ElementsTable::GetSymbol(int atomicnum) {
99 if (!init_) Init();
100
101 if (atomicnum < 0 || atomicnum >= static_cast<int>(elements_.size()))
102 return ("\0");
103
104 return (elements_[atomicnum]->GetSymbol());
105 }
106
107 int ElementsTable::GetMaxBonds(int atomicnum) {
108 if (!init_) Init();
109
110 if (atomicnum < 0 || atomicnum >= static_cast<int>(elements_.size()))
111 return (0);
112
113 return (elements_[atomicnum]->GetMaxBonds());
114 }
115
116 RealType ElementsTable::GetElectroNeg(int atomicnum) {
117 if (!init_) Init();
118
119 if (atomicnum < 0 || atomicnum >= static_cast<int>(elements_.size()))
120 return (0.0);
121
122 return (elements_[atomicnum]->GetElectroNeg());
123 }
124
126 if (!init_) Init();
127
128 if (atomicnum < 0 || atomicnum >= static_cast<int>(elements_.size()))
129 return (0.0);
130
131 return (elements_[atomicnum]->GetAllredRochowElectroNeg());
132 }
133
134 RealType ElementsTable::GetIonization(int atomicnum) {
135 if (!init_) Init();
136
137 if (atomicnum < 0 || atomicnum >= static_cast<int>(elements_.size()))
138 return (0.0);
139
140 return (elements_[atomicnum]->GetIonization());
141 }
142
143 RealType ElementsTable::GetElectronAffinity(int atomicnum) {
144 if (!init_) Init();
145
146 if (atomicnum < 0 || atomicnum >= static_cast<int>(elements_.size()))
147 return (0.0);
148
149 return (elements_[atomicnum]->GetElectronAffinity());
150 }
151
152 std::vector<RealType> ElementsTable::GetRGB(int atomicnum) {
153 if (!init_) Init();
154
155 std::vector<RealType> colors;
156 colors.reserve(3);
157
158 if (atomicnum < 0 || atomicnum >= static_cast<int>(elements_.size())) {
159 colors.push_back(0.0);
160 colors.push_back(0.0);
161 colors.push_back(0.0);
162 return (colors);
163 }
164
165 colors.push_back(elements_[atomicnum]->GetRed());
166 colors.push_back(elements_[atomicnum]->GetGreen());
167 colors.push_back(elements_[atomicnum]->GetBlue());
168
169 return (colors);
170 }
171
172 std::string ElementsTable::GetName(int atomicnum) {
173 if (!init_) Init();
174
175 if (atomicnum < 0 || atomicnum >= static_cast<int>(elements_.size()))
176 return ("Unknown");
177
178 return (elements_[atomicnum]->GetName());
179 }
180
181 RealType ElementsTable::GetVdwRad(int atomicnum) {
182 if (!init_) Init();
183
184 if (atomicnum < 0 || atomicnum >= static_cast<int>(elements_.size()))
185 return (0.0);
186
187 return (elements_[atomicnum]->GetVdwRad());
188 }
189
190 RealType ElementsTable::CorrectedBondRad(int atomicnum, int hyb) {
191 RealType rad;
192 if (!init_) Init();
193
194 if (atomicnum < 0 || atomicnum >= static_cast<int>(elements_.size()))
195 return (1.0);
196
197 rad = elements_[atomicnum]->GetCovalentRad();
198
199 if (hyb == 2)
200 rad *= 0.95;
201 else if (hyb == 1)
202 rad *= 0.90;
203
204 return (rad);
205 }
206
207 RealType ElementsTable::CorrectedVdwRad(int atomicnum, int hyb) {
208 RealType rad;
209 if (!init_) Init();
210
211 if (atomicnum < 0 || atomicnum >= static_cast<int>(elements_.size()))
212 return (1.95);
213
214 rad = elements_[atomicnum]->GetVdwRad();
215
216 if (hyb == 2)
217 rad *= 0.95;
218 else if (hyb == 1)
219 rad *= 0.90;
220
221 return (rad);
222 }
223
224 RealType ElementsTable::GetCovalentRad(int atomicnum) {
225 if (!init_) Init();
226
227 if (atomicnum < 0 || atomicnum >= static_cast<int>(elements_.size()))
228 return (0.0);
229
230 return (elements_[atomicnum]->GetCovalentRad());
231 }
232
233 RealType ElementsTable::GetMass(int atomicnum) {
234 if (!init_) Init();
235
236 if (atomicnum < 0 || atomicnum >= static_cast<int>(elements_.size()))
237 return (0.0);
238
239 return (elements_[atomicnum]->GetMass());
240 }
241
242 int ElementsTable::GetAtomicNum(const char* sym) {
243 int temp;
244 return GetAtomicNum(sym, temp);
245 }
246
247 int ElementsTable::GetAtomicNum(const char* identifier, int& iso) {
248 if (!init_) Init();
249
250 // Compare to symbol
251 std::vector<Element*>::iterator i;
252 for (i = elements_.begin(); i != elements_.end(); ++i)
253 if (!strncasecmp(identifier, (*i)->GetSymbol(), 3))
254 return ((*i)->GetAtomicNum());
255
256 // Compare to IUPAC name (an abbreviated name will also work if 5
257 // letters or more)
258 int numCharsToTest = std::max<int>(strlen(identifier), 5);
259 for (i = elements_.begin(); i != elements_.end(); ++i)
260 if (strncasecmp(identifier, (*i)->GetName().c_str(), numCharsToTest) == 0)
261 return ((*i)->GetAtomicNum());
262
263 if (strcasecmp(identifier, "D") == 0 ||
264 (strcasecmp(identifier, "Deuterium") == 0)) {
265 iso = 2;
266 return (1);
267 } else if (strcasecmp(identifier, "T") == 0 ||
268 (strcasecmp(identifier, "Tritium") == 0)) {
269 iso = 3;
270 return (1);
271 } else if (strcasecmp(identifier, "Hl") == 0) {
272 // ligand hydrogen -- found in some CIF PR#3048959.
273 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
274 "ElementsTable warning.\n"
275 "\tCannot understand the element label %s\n"
276 "\tGuessing it's hydrogen\n",
277 identifier);
278 painCave.isFatal = 0;
279 painCave.severity = OPENMD_WARNING;
280 simError();
281 return (1);
282 } else
283 iso = 0;
284
285 if (identifier[0] != '*') {
286 // Quiet down the error messages for now:
287 // snprintf( painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
288 // "ElementsTable warning.\n"
289 // "\tCannot understand the element label %s\n", identifier);
290 // painCave.isFatal = 0;
291 // painCave.severity = OPENMD_WARNING;
292 // simError();
293 }
294 return (0);
295 }
296
297 int ElementsTable::GetAtomicNum(std::string name, int& iso) {
298 return GetAtomicNum(name.c_str(), iso);
299 }
300
302 if (init_) return;
303 init_ = true;
304
305 std::string buffer, subbuffer;
306 ifstrstream ifs;
307 char charBuffer[BUFF_SIZE];
308
309 // First, look for an environment variable
310 if (getenv(envvar_.c_str()) != NULL) {
311 buffer = getenv(envvar_.c_str());
312 buffer += FILE_SEP_CHAR;
313
314 if (!subdir_.empty()) {
315 subbuffer = buffer;
316 subbuffer += subdir_;
317 subbuffer += FILE_SEP_CHAR;
318 }
319
320 buffer += filename_;
321 subbuffer += filename_;
322 }
323
324 ifs.clear();
325 ifs.open(subbuffer.c_str());
326
327 if (!(&ifs)->is_open()) {
328 ifs.clear();
329 ifs.open(buffer.c_str());
330
331 if (!(&ifs)->is_open()) {
332 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
333 "ElementsTable error.\n"
334 "\tunable to open datafile %s \n",
335 filename_.c_str());
336 painCave.isFatal = 0;
337 simError();
338 }
339 }
340
341 if (ifs) {
342 while (ifs.getline(charBuffer, BUFF_SIZE))
343 ParseLine(charBuffer);
344 }
345
346 if (ifs) ifs.close();
347
348 if (GetSize() == 0) {
349 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
350 "ElementsTable error.\n"
351 "\tCannot initialize database %s \n",
352 filename_.c_str());
353 painCave.isFatal = 0;
354 simError();
355 }
356 }
357} // 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)
std::string envvar_
environment variable to check first
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)
std::string subdir_
subdirectory (if using environment variable)
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...
void close()
In single mode, closes a file.
This basic Periodic Table class was originally taken from the data.cpp file in OpenBabel.