~ubuntu-branches/ubuntu/oneiric/mpqc/oneiric

« back to all changes in this revision

Viewing changes to src/lib/chemistry/molecule/atominfo.cc

  • Committer: Bazaar Package Importer
  • Author(s): Michael Banck
  • Date: 2005-11-27 11:41:49 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20051127114149-zgz9r3gk50w8ww2q
Tags: 2.3.0-1
* New upstream release.
* debian/rules (SONAME): Activate awk snippet for automatic so-name
  detection again, resulting in a bump to `7' and making a `c2a' for
  the C++ allocator change unnecessary; closes: #339232.
* debian/patches/00list (08_gcc-4.0_fixes): Removed, no longer needed.
* debian/rules (test): Remove workarounds, do not abort build if tests
  fail.
* debian/ref: Removed.
* debian/control.in (libsc): Added Conflict against libsc6c2.

Show diffs side-by-side

added added

removed removed

Lines of Context:
25
25
// The U.S. Government is granted a limited license as per AL 91-7.
26
26
//
27
27
 
28
 
#include <stdio.h>
29
28
#include <stdlib.h>
30
 
#include <string.h>
 
29
#include <util/misc/string.h>
31
30
#include <ctype.h>
32
31
#include <sys/stat.h>
33
32
 
 
33
#include <sstream>
 
34
#include <stdexcept>
 
35
 
34
36
#include <util/misc/units.h>
 
37
#include <util/misc/autovec.h>
35
38
#include <util/misc/formio.h>
36
39
#include <util/state/stateio.h>
37
40
#include <util/group/message.h>
43
46
////////////////////////////////////////////////////////////////////////
44
47
// AtomInfo
45
48
 
46
 
struct AtomInfo::atomname
47
 
AtomInfo::names_[MaxZ] = 
48
 
  {{"",           ""}, // 0
49
 
   {"hydrogen",   "H"}, // 1
50
 
   {"helium",     "He"}, // 2
51
 
   {"lithium",    "Li"}, // 3
52
 
   {"beryllium",  "Be"}, // 4
53
 
   {"boron",      "B"}, // 5
54
 
   {"carbon",     "C"}, // 6
55
 
   {"nitrogen",   "N"}, // 7
56
 
   {"oxygen",     "O"}, // 8
57
 
   {"fluorine",   "F"}, // 9
58
 
   {"neon",       "Ne"}, // 10
59
 
   {"sodium",     "Na"}, // 11
60
 
   {"magnesium",  "Mg"}, // 12
61
 
   {"aluminum",   "Al"}, // 13
62
 
   {"silicon",    "Si"}, // 14
63
 
   {"phosphorus" ,"P"}, // 15
64
 
   {"sulfur",     "S"}, // 16
65
 
   {"chlorine",   "Cl"}, // 17
66
 
   {"argon",      "Ar"}, // 18
67
 
   {"potassium",  "K"}, // 19
68
 
   {"calcium",    "Ca"}, // 20
69
 
   {"scandium",   "Sc"}, // 21
70
 
   {"titanium",   "Ti"}, // 22
71
 
   {"vanadium",   "V"}, // 23
72
 
   {"chromium",   "Cr"}, // 24
73
 
   {"manganese",  "Mn"}, // 25
74
 
   {"iron",       "Fe"}, // 26
75
 
   {"cobalt",     "Co"}, // 27
76
 
   {"nickel",     "Ni"}, // 28
77
 
   {"copper",     "Cu"}, // 29
78
 
   {"zinc",       "Zn"}, // 30
79
 
   {"gallium",    "Ga"}, // 31
80
 
   {"germanium",  "Ge"}, // 32
81
 
   {"arsenic",    "As"}, // 33
82
 
   {"selenium",   "Se"}, // 34
83
 
   {"bromine",    "Br"}, // 35
84
 
   {"krypton",    "Kr"}, // 36
85
 
   {"rubidium",     "Rb"}, // 37
86
 
   {"strontium",    "Sr"}, // 38
87
 
   {"yttrium",      "Y"}, // 39
88
 
   {"zirconium",    "Zr"}, // 40
89
 
   {"niobium",      "Nb"}, // 41
90
 
   {"molybdenum",   "Mo"}, // 42
91
 
   {"technetium",   "Tc"}, // 43
92
 
   {"ruthenium",    "Ru"}, // 44
93
 
   {"rhodium",      "Rh"}, // 45
94
 
   {"palladium",    "Pd"}, // 46
95
 
   {"silver",       "Ag"}, // 47
96
 
   {"cadminium",    "Cd"}, // 48
97
 
   {"indium",       "In"}, // 49
98
 
   {"tin",          "Sn"}, // 50
99
 
   {"antimony",     "Sb"}, // 51
100
 
   {"tellurium",    "Te"}, // 52
101
 
   {"iodine",       "I"}, // 53
102
 
   {"xenon",        "Xe"}, // 54
103
 
   {"cesium",       "Cs"}, // 55
104
 
   {"barium",       "Ba"}, // 56
105
 
   {"lanthanium",   "La"}, // 57
106
 
   {"cerium",       "Ce"}, // 58
107
 
   {"praseodymium", "Pr"}, // 59
108
 
   {"neodymium",    "Nd"}, // 60
109
 
   {"promethium",   "Pm"}, // 61
110
 
   {"samarium",     "Sm"}, // 62
111
 
   {"europium",     "Eu"}, // 63
112
 
   {"gadolinium",   "Gd"}, // 64
113
 
   {"terbium",      "Tb"}, // 65
114
 
   {"dysprosium",   "Dy"}, // 66
115
 
   {"holmium",      "Ho"}, // 67
116
 
   {"erbium",       "Er"}, // 68
117
 
   {"thulium",      "Tm"}, // 69
118
 
   {"ytterbium",    "Yb"}, // 70
119
 
   {"lutetium",     "Lu"}, // 71
120
 
   {"hafnium",      "Hf"}, // 72
121
 
   {"tantalum",     "Ta"}, // 73
122
 
   {"tungsten",     "W"}, // 74
123
 
   {"rhenium",      "Re"}, // 75
124
 
   {"osmium",       "Os"}, // 76
125
 
   {"iridium",      "Ir"}, // 77
126
 
   {"platinum",     "Pt"}, // 78
127
 
   {"gold",         "Au"}, // 79
128
 
   {"mercury",      "Hg"}, // 80
129
 
   {"thallium",     "Tl"}, // 81
130
 
   {"lead",         "Pb"}, // 82
131
 
   {"bismuth",      "Bi"}, // 83
132
 
   {"polonium",     "Po"}, // 84
133
 
   {"astatine",     "At"}, // 85
134
 
   {"radon",        "Rn"}, // 86
135
 
   {"francium",     "Fr"}, // 87
136
 
   {"radium",       "Ra"}, // 88
137
 
   {"actinium",     "Ac"}, // 89
138
 
   {"thorium",      "Th"}, // 90
139
 
   {"protactinium", "Pa"}, // 91
140
 
   {"uranium",      "U"}, // 92
141
 
   {"neptunium",    "Np"}, // 93
142
 
   {"plutonium",    "Pu"}, // 94
143
 
   {"americium",    "Am"}, // 95
144
 
   {"curium",       "Cm"}, // 96
145
 
   {"berkelium",    "Bk"}, // 97
146
 
   {"californium",  "Cf"}, // 98
147
 
   {"einsteinum",   "Es"}, // 99
148
 
   {"fermium",      "Fm"}, // 100
149
 
   {"mendelevium",  "Md"}, // 101
150
 
   {"nobelium",     "No"}, // 102
151
 
   {"lawrencium",   "Lr"}, // 103
152
 
   {"rutherfordium","Rf"}, // 104
153
 
   {"hahnium",      "Ha"}, // 105
154
 
   {"Unnamed",      "Un"}, // 106
155
 
   {"Unnamed",      "Un"} // 107
 
49
struct AtomInfo::atom
 
50
AtomInfo::elements_[Nelement] = 
 
51
  {{1, "hydrogen",   "H"},
 
52
   {2, "helium",     "He"},
 
53
   {3, "lithium",    "Li"},
 
54
   {4, "beryllium",  "Be"},
 
55
   {5, "boron",      "B"},
 
56
   {6, "carbon",     "C"},
 
57
   {7, "nitrogen",   "N"},
 
58
   {8, "oxygen",     "O"},
 
59
   {9, "fluorine",   "F"},
 
60
   {10, "neon",       "Ne"},
 
61
   {11, "sodium",     "Na"},
 
62
   {12, "magnesium",  "Mg"},
 
63
   {13, "aluminum",   "Al"},
 
64
   {14, "silicon",    "Si"},
 
65
   {15, "phosphorus" ,"P"},
 
66
   {16, "sulfur",     "S"},
 
67
   {17, "chlorine",   "Cl"},
 
68
   {18, "argon",      "Ar"},
 
69
   {19, "potassium",  "K"},
 
70
   {20, "calcium",    "Ca"},
 
71
   {21, "scandium",   "Sc"},
 
72
   {22, "titanium",   "Ti"},
 
73
   {23, "vanadium",   "V"},
 
74
   {24, "chromium",   "Cr"},
 
75
   {25, "manganese",  "Mn"},
 
76
   {26, "iron",       "Fe"},
 
77
   {27, "cobalt",     "Co"},
 
78
   {28, "nickel",     "Ni"},
 
79
   {29, "copper",     "Cu"},
 
80
   {30, "zinc",       "Zn"},
 
81
   {31, "gallium",    "Ga"},
 
82
   {32, "germanium",  "Ge"},
 
83
   {33, "arsenic",    "As"},
 
84
   {34, "selenium",   "Se"},
 
85
   {35, "bromine",    "Br"},
 
86
   {36, "krypton",    "Kr"},
 
87
   {37, "rubidium",     "Rb"},
 
88
   {38, "strontium",    "Sr"},
 
89
   {39, "yttrium",      "Y"},
 
90
   {40, "zirconium",    "Zr"},
 
91
   {41, "niobium",      "Nb"},
 
92
   {42, "molybdenum",   "Mo"},
 
93
   {43, "technetium",   "Tc"},
 
94
   {44, "ruthenium",    "Ru"},
 
95
   {45, "rhodium",      "Rh"},
 
96
   {46, "palladium",    "Pd"},
 
97
   {47, "silver",       "Ag"},
 
98
   {48, "cadminium",    "Cd"},
 
99
   {49, "indium",       "In"},
 
100
   {50, "tin",          "Sn"},
 
101
   {51, "antimony",     "Sb"},
 
102
   {52, "tellurium",    "Te"},
 
103
   {53, "iodine",       "I"},
 
104
   {54, "xenon",        "Xe"},
 
105
   {55, "cesium",       "Cs"},
 
106
   {56, "barium",       "Ba"},
 
107
   {57, "lanthanium",   "La"},
 
108
   {58, "cerium",       "Ce"},
 
109
   {59, "praseodymium", "Pr"},
 
110
   {60, "neodymium",    "Nd"},
 
111
   {61, "promethium",   "Pm"},
 
112
   {62, "samarium",     "Sm"},
 
113
   {63, "europium",     "Eu"},
 
114
   {64, "gadolinium",   "Gd"},
 
115
   {65, "terbium",      "Tb"},
 
116
   {66, "dysprosium",   "Dy"},
 
117
   {67, "holmium",      "Ho"},
 
118
   {68, "erbium",       "Er"},
 
119
   {69, "thulium",      "Tm"},
 
120
   {70, "ytterbium",    "Yb"},
 
121
   {71, "lutetium",     "Lu"},
 
122
   {72, "hafnium",      "Hf"},
 
123
   {73, "tantalum",     "Ta"},
 
124
   {74, "tungsten",     "W"},
 
125
   {75, "rhenium",      "Re"},
 
126
   {76, "osmium",       "Os"},
 
127
   {77, "iridium",      "Ir"},
 
128
   {78, "platinum",     "Pt"},
 
129
   {79, "gold",         "Au"},
 
130
   {80, "mercury",      "Hg"},
 
131
   {81, "thallium",     "Tl"},
 
132
   {82, "lead",         "Pb"},
 
133
   {83, "bismuth",      "Bi"},
 
134
   {84, "polonium",     "Po"},
 
135
   {85, "astatine",     "At"},
 
136
   {86, "radon",        "Rn"},
 
137
   {87, "francium",     "Fr"},
 
138
   {88, "radium",       "Ra"},
 
139
   {89, "actinium",     "Ac"},
 
140
   {90, "thorium",      "Th"},
 
141
   {91, "protactinium", "Pa"},
 
142
   {92, "uranium",      "U"},
 
143
   {93, "neptunium",    "Np"},
 
144
   {94, "plutonium",    "Pu"},
 
145
   {95, "americium",    "Am"},
 
146
   {96, "curium",       "Cm"},
 
147
   {97, "berkelium",    "Bk"},
 
148
   {98, "californium",  "Cf"},
 
149
   {99, "einsteinum",   "Es"},
 
150
   {100, "fermium",      "Fm"},
 
151
   {101, "mendelevium",  "Md"},
 
152
   {102, "nobelium",     "No"},
 
153
   {103, "lawrencium",   "Lr"},
 
154
   {104, "rutherfordium","Rf"},
 
155
   {105, "hahnium",      "Ha"},
 
156
   {106, "seaborgium",   "Sg"},
 
157
   {107, "bohrium",      "Bh"},
 
158
   {108, "hassium",      "Hs"},
 
159
   {109, "meitnerium",   "Mt"},
 
160
   {110, "darmstadtium", "Ds"},
 
161
   {111, "roentgenium",  "Rg"},
 
162
   {112, "ununbium",     "Uub"},
 
163
   {113, "ununtrium",    "Uut"},
 
164
   {114, "ununquadium",  "Uuq"},
 
165
   {115, "ununpentium",  "Uup"},
 
166
   {116, "ununhexium",   "Uuh"},
 
167
   {117, "ununseptium",  "Uus"},
 
168
   {118, "ununoctium",   "Uuo"}
156
169
  };
157
170
 
158
171
static ClassDesc AtomInfo_cd(
161
174
 
162
175
AtomInfo::AtomInfo()
163
176
{
 
177
  initialize_names();
164
178
  overridden_values_ = 0;
165
179
  load_library_values();
166
180
}
167
181
 
168
182
AtomInfo::AtomInfo(const Ref<KeyVal>& keyval)
169
183
{
 
184
  initialize_names();
170
185
  overridden_values_ = 0;
171
186
  load_library_values();
172
187
  override_library_values(keyval);
175
190
AtomInfo::AtomInfo(StateIn& s):
176
191
  SavableState(s)
177
192
{
178
 
  if (s.node_to_node()) {
179
 
      s.get_array_double(mass_,MaxZ);
180
 
      s.get_array_double(atomic_radius_,MaxZ);
181
 
      s.get_array_double(vdw_radius_,MaxZ);
182
 
      s.get_array_double(bragg_radius_,MaxZ);
183
 
      s.get_array_double(maxprob_radius_,MaxZ);
184
 
      for (int i=0; i<MaxZ; i++) s.get_array_double(rgb_[i],3);
185
 
      s.getstring(overridden_values_);
186
 
      if (s.version(::class_desc<AtomInfo>()) >= 3) {
187
 
          s.get_array_double(ip_,MaxZ);
188
 
        }
189
 
    }
190
 
  else {
191
 
      overridden_values_ = 0;
192
 
      load_library_values();
193
 
      char *overrides;
194
 
      s.getstring(overrides);
195
 
      if (overrides) {
196
 
          Ref<ParsedKeyVal> keyval = new ParsedKeyVal;
197
 
          keyval->parse_string(overrides);
198
 
          override_library_values(keyval.pointer());
199
 
          delete[] overrides;
200
 
        }
 
193
  initialize_names();
 
194
  overridden_values_ = 0;
 
195
  load_library_values();
 
196
  char *overrides;
 
197
  s.getstring(overrides);
 
198
  if (overrides) {
 
199
      Ref<ParsedKeyVal> keyval = new ParsedKeyVal;
 
200
      keyval->parse_string(overrides);
 
201
      override_library_values(keyval.pointer());
 
202
      delete[] overrides;
201
203
    }
202
204
  if (s.version(::class_desc<AtomInfo>()) < 2) {
203
205
      atomic_radius_scale_ = 1.0;
221
223
void
222
224
AtomInfo::save_data_state(StateOut& s)
223
225
{
224
 
  if (s.node_to_node()) {
225
 
      s.put_array_double(mass_,MaxZ);
226
 
      s.put_array_double(atomic_radius_,MaxZ);
227
 
      s.put_array_double(vdw_radius_,MaxZ);
228
 
      s.put_array_double(bragg_radius_,MaxZ);
229
 
      s.put_array_double(maxprob_radius_,MaxZ);
230
 
      for (int i=0; i<MaxZ; i++) s.put_array_double(rgb_[i],3);
231
 
      s.put_array_double(ip_,MaxZ);
232
 
      s.putstring(overridden_values_);
233
 
    }
234
 
  else {
235
 
      s.putstring(overridden_values_);
236
 
    }
 
226
  s.putstring(overridden_values_);
237
227
  s.put(atomic_radius_scale_);
238
228
  s.put(vdw_radius_scale_);
239
229
  s.put(bragg_radius_scale_);
241
231
}
242
232
 
243
233
void
 
234
AtomInfo::initialize_names()
 
235
{
 
236
  for (int i=0; i<Nelement; i++) {
 
237
      symbol_to_Z_[elements_[i].symbol] = elements_[i].Z;
 
238
      name_to_Z_[elements_[i].name] = elements_[i].Z;
 
239
    }
 
240
 
 
241
  // Z == DefaultZ is reserved for default values
 
242
  symbol_to_Z_["Def"] = DefaultZ;
 
243
  name_to_Z_["default"] = DefaultZ;
 
244
 
 
245
  // Z == 1000 is reserved for point charges
 
246
  name_to_Z_["charge"] = 1000;
 
247
  symbol_to_Z_["Q"] = 1000;
 
248
 
 
249
  for (std::map<std::string,int>::iterator i = symbol_to_Z_.begin();
 
250
       i != symbol_to_Z_.end(); i++) {
 
251
      Z_to_symbols_[i->second] = i->first;
 
252
    }
 
253
 
 
254
  for (std::map<std::string,int>::iterator i = name_to_Z_.begin();
 
255
       i != name_to_Z_.end(); i++) {
 
256
      Z_to_names_[i->second] = i->first;
 
257
    }
 
258
}
 
259
 
 
260
void
244
261
AtomInfo::load_library_values()
245
262
{
246
263
  Ref<MessageGrp> grp = MessageGrp::get_default_messagegrp();
 
264
  sc::auto_vec<char> in_char_array;
247
265
  if (grp->me() == 0) {
248
266
      const char* libdir;
249
 
      Ref<KeyVal> keyval;
 
267
      std::string filename;
250
268
      if ((libdir = getenv("SCLIBDIR")) != 0) {
251
269
          const char* atominfo = "/atominfo.kv";
252
270
          const char *eq = ::strchr(libdir,'=');
253
271
          if (eq) libdir = eq + 1;
254
 
          char *filename = new char[strlen(libdir) + strlen(atominfo) + 1];
255
 
          strcpy(filename, libdir);
256
 
          strcat(filename, atominfo);
257
 
          keyval = new ParsedKeyVal(filename);
258
 
          delete[] filename;
 
272
          filename = std::string(libdir) + atominfo;
259
273
        }
260
274
      else {
261
275
          struct stat sb;
265
279
              ainfo = SRC_SCLIBDIR "/atominfo.kv";
266
280
            }
267
281
#endif
268
 
          ExEnv::out0() << indent << "Reading file " << ainfo << "." << endl;
269
 
          keyval = new ParsedKeyVal(ainfo);
 
282
          filename = ainfo;
270
283
        }
271
 
      Ref<KeyVal> pkeyval = new PrefixKeyVal(keyval, "atominfo");
272
 
      load_values(pkeyval,0);
273
 
    }
274
 
  grp->bcast(mass_,MaxZ);
275
 
  grp->bcast(atomic_radius_,MaxZ);
276
 
  grp->bcast(vdw_radius_,MaxZ);
277
 
  grp->bcast(bragg_radius_,MaxZ);
278
 
  grp->bcast(maxprob_radius_,MaxZ);
279
 
  grp->bcast(atomic_radius_scale_);
280
 
  grp->bcast(vdw_radius_scale_);
281
 
  grp->bcast(bragg_radius_scale_);
282
 
  grp->bcast(maxprob_radius_scale_);
283
 
  for (int i=0; i<MaxZ; i++) grp->bcast(rgb_[i],3);
284
 
  grp->bcast(ip_,MaxZ);
 
284
      ExEnv::out0() << indent << "Reading file " << filename << "." << endl;
 
285
      ifstream is(filename.c_str());
 
286
      ostringstream ostrs;
 
287
      is >> ostrs.rdbuf();
 
288
      int n = 1 + strlen(ostrs.str().c_str());
 
289
      in_char_array.reset(strcpy(new char[n],ostrs.str().c_str()));
 
290
      grp->bcast(n);
 
291
      grp->bcast(in_char_array.get(), n);
 
292
    }
 
293
  else {
 
294
      int n;
 
295
      grp->bcast(n);
 
296
      in_char_array.reset(new char[n]);
 
297
      grp->bcast(in_char_array.get(), n);
 
298
    }
 
299
 
 
300
  Ref<ParsedKeyVal> keyval = new ParsedKeyVal();
 
301
  keyval->parse_string(in_char_array.get());
 
302
  Ref<KeyVal> pkeyval = new PrefixKeyVal(keyval.pointer(), "atominfo");
 
303
  load_values(pkeyval,0);
285
304
}
286
305
 
287
306
void
297
316
  Ref<Units> bohr = new Units("bohr");
298
317
  Ref<Units> hartree = new Units("hartree");
299
318
 
300
 
  load_values(mass_, 0, "mass", keyval, override, amu);
301
 
  load_values(atomic_radius_, &atomic_radius_scale_, "atomic_radius",
302
 
              keyval, override, bohr);
303
 
  load_values(vdw_radius_, &vdw_radius_scale_, "vdw_radius",
304
 
              keyval, override, bohr);
305
 
  load_values(bragg_radius_, &bragg_radius_scale_,
 
319
  load_values(Z_to_mass_, 0, "mass", keyval, override, amu);
 
320
  load_values(Z_to_atomic_radius_, &atomic_radius_scale_, "atomic_radius",
 
321
              keyval, override, bohr);
 
322
  load_values(Z_to_vdw_radius_, &vdw_radius_scale_, "vdw_radius",
 
323
              keyval, override, bohr);
 
324
  load_values(Z_to_bragg_radius_, &bragg_radius_scale_,
306
325
              "bragg_radius", keyval, override, bohr);
307
 
  load_values(maxprob_radius_, &maxprob_radius_scale_,
 
326
  load_values(Z_to_maxprob_radius_, &maxprob_radius_scale_,
308
327
              "maxprob_radius", keyval, override, bohr);
309
 
  load_values(rgb_, "rgb", keyval, override);
310
 
  load_values(ip_, 0, "ip", keyval, override, hartree);
 
328
  load_values(Z_to_rgb_, "rgb", keyval, override);
 
329
  load_values(Z_to_ip_, 0, "ip", keyval, override, hartree);
311
330
}
312
331
 
313
332
void
314
 
AtomInfo::load_values(double *array, double *scale, const char *keyword,
 
333
AtomInfo::load_values(std::map<int,double>&values,
 
334
                      double *scale, const char *keyword,
315
335
                      const Ref<KeyVal> &keyval, int override,
316
336
                      const Ref<Units> &units)
317
337
{
324
344
  double def = 0.0;
325
345
  if (!override) {
326
346
      def = pkeyval->doublevalue("default");
327
 
      array[0] = def;
 
347
      values[DefaultZ] = def;
328
348
    }
329
349
  int have_overridden = 0;
330
 
  int i;
331
 
  for (i=1; i<MaxZ; i++) {
332
 
      double val = f * pkeyval->doublevalue(names_[i].symbol);
 
350
  for (int elem=0; elem<Nelement; elem++) {
 
351
      int Z = elements_[elem].Z;
 
352
      double val = f * pkeyval->doublevalue(elements_[elem].symbol);
333
353
      if (pkeyval->error() != KeyVal::OK) {
334
 
          if (!override) array[i] = def;
 
354
          if (!override) values[Z] = def;
335
355
        }
336
356
      else {
337
 
          array[i] = val;
 
357
          values[Z] = val;
338
358
          if (override) {
339
359
              const char *prefix = " ";
340
360
              if (!have_overridden) {
350
370
                    }
351
371
                  have_overridden = 1;
352
372
                }
353
 
              char *strval = pkeyval->pcharvalue(names_[i].symbol);
 
373
              char *strval = pkeyval->pcharvalue(elements_[elem].symbol);
354
374
              char assignment[256];
355
 
              sprintf(assignment,"%s%s=%s", prefix, names_[i].symbol, strval);
 
375
              sprintf(assignment,"%s%s=%s", prefix,
 
376
                      elements_[elem].symbol, strval);
356
377
              delete[] strval;
357
378
              add_overridden_value(assignment);
358
379
            }
384
405
}
385
406
 
386
407
void
387
 
AtomInfo::load_values(double array[][3], const char *keyword,
 
408
AtomInfo::load_values(std::map<int,std::vector<double> >&values,
 
409
                      const char *keyword,
388
410
                      const Ref<KeyVal> &keyval, int override)
389
411
{
390
 
  int i,j;
391
412
  Ref<KeyVal> pkeyval = new PrefixKeyVal(keyval,keyword);
392
413
  double def[3];
393
414
  if (!override) {
394
 
      for (i=0; i<3; i++) {
 
415
      values[DefaultZ].resize(3);
 
416
      for (int i=0; i<3; i++) {
395
417
          def[i] = pkeyval->doublevalue("default",i);
396
 
          array[0][i] = def[i];
 
418
          values[DefaultZ][i] = def[i];
397
419
        }
398
420
    }
399
421
  int have_overridden = 0;
400
 
  for (i=1; i<MaxZ; i++) {
 
422
  for (int elem=0; elem<Nelement; elem++) {
401
423
      double val;
402
 
      for (j=0; j<3; j++) {
403
 
          val = pkeyval->doublevalue(names_[i].symbol,j);
 
424
      int Z = elements_[elem].Z;
 
425
      values[Z].resize(3);
 
426
      for (int j=0; j<3; j++) {
 
427
          val = pkeyval->doublevalue(elements_[elem].symbol,j);
404
428
          if (pkeyval->error() != KeyVal::OK) {
405
 
              if (!override) array[i][j] = def[j];
 
429
              if (!override) values[Z][j] = def[j];
406
430
            }
407
431
          else {
408
 
              array[i][j] = val;
 
432
              values[Z][j] = val;
409
433
              if (override) {
410
434
                  const char *prefix = " ";
411
435
                  if (!have_overridden) {
414
438
                      prefix = "";
415
439
                      have_overridden = 1;
416
440
                    }
417
 
                  char *strval = pkeyval->pcharvalue(names_[i].symbol,j);
 
441
                  char *strval = pkeyval->pcharvalue(elements_[elem].symbol,j);
418
442
                  char assignment[256];
419
443
                  sprintf(assignment,"%s%s:%d=%s",
420
 
                          prefix, names_[i].symbol, j, strval);
 
444
                          prefix, elements_[elem].symbol, j, strval);
421
445
                  delete[] strval;
422
446
                  add_overridden_value(assignment);
423
447
                }
443
467
}
444
468
 
445
469
int
446
 
AtomInfo::string_to_Z(const char *name, int allow_exceptions)
 
470
AtomInfo::string_to_Z(const std::string &name, int allow_exceptions)
447
471
{
448
 
  unsigned int i,j;
449
472
  int Z;
450
473
 
451
474
  // see if the name is a atomic number
452
 
  Z = atoi(name);
453
 
 
454
 
  // name is not an atomic number--must be a symbol or atom name
455
 
  if (!Z) {
456
 
 
457
 
      // convert the name to lower case
458
 
      char* tmpname = strdup(name);
459
 
      for (j=0; j<strlen(tmpname); j++) {
460
 
          if (isupper(tmpname[j])) tmpname[j] = tolower(tmpname[j]);
461
 
        }
462
 
 
463
 
      // loop thru the elements, looking for a match
464
 
      for (i=0; i<MaxZ; i++) {
465
 
 
466
 
          // see if an atom name matches
467
 
          // if we find a match we are done looping
468
 
          if (!strcmp(names_[i].name,tmpname)) {
469
 
              Z = i;
470
 
              break;
471
 
            }
472
 
 
473
 
          // see if an atomic symbol (converted to lower case) matches
474
 
          char* tmpsymbol = strdup(names_[i].symbol);
475
 
          for (j=0; j<strlen(tmpsymbol); j++) {
476
 
              if (isupper(tmpsymbol[j])) tmpsymbol[j] = tolower(tmpsymbol[j]);
477
 
            }
478
 
          // if we find a match we are done looping
479
 
          if (!strcmp(tmpsymbol,tmpname)) {
480
 
              Z = i;
481
 
              free(tmpsymbol);
482
 
              break;
483
 
            }
484
 
          free(tmpsymbol);
485
 
        }
486
 
 
487
 
      // free the lowercase version of the name
488
 
      free(tmpname);
489
 
    }  
490
 
 
491
 
  // check to see if z value is OK, if not then the name must have been
492
 
  // invalid
493
 
  if (Z < 1 || Z > MaxZ) {
494
 
      if (allow_exceptions) {
495
 
          ExEnv::err0()
496
 
                       << sprintf("AtomInfo: invalid name: %s\n",name);
497
 
          abort();
498
 
        }
499
 
      else return 0;
500
 
    }
501
 
 
502
 
  return Z;
 
475
  Z = atoi(name.c_str());
 
476
  if (Z) return Z;
 
477
 
 
478
  // convert the name to lower case
 
479
  std::string tmpname(name);
 
480
  for (int j=0; j<tmpname.size(); j++) {
 
481
      if (isupper(tmpname[j])) tmpname[j] = tolower(tmpname[j]);
 
482
    }
 
483
 
 
484
  std::map<std::string,int>::const_iterator iname
 
485
      = name_to_Z_.find(tmpname);
 
486
  if (iname != name_to_Z_.end()) return iname->second;
 
487
 
 
488
  if (tmpname.size() > 0) {
 
489
      if (islower(tmpname[0])) tmpname[0] = toupper(tmpname[0]);
 
490
    }
 
491
 
 
492
  iname = symbol_to_Z_.find(tmpname);
 
493
  if (iname != symbol_to_Z_.end()) return iname->second;
 
494
 
 
495
  if (allow_exceptions) {
 
496
      ExEnv::err0() << sprintf("AtomInfo: invalid name: %s\n",name.c_str());
 
497
      throw std::runtime_error("invalid atom name");
 
498
    }
 
499
 
 
500
  return 0;
 
501
}
 
502
 
 
503
double
 
504
AtomInfo::lookup_value(const std::map<int,double>& values, int Z) const
 
505
{
 
506
  std::map<int,double>::const_iterator found = values.find(Z);
 
507
  if (found == values.end()) {
 
508
      found = values.find(DefaultZ);
 
509
    }
 
510
  return found->second;
 
511
}
 
512
 
 
513
double
 
514
AtomInfo::lookup_array_value(const std::map<int,std::vector<double> >& values,
 
515
                             int Z, int i) const
 
516
{
 
517
  std::map<int,std::vector<double> >::const_iterator found = values.find(Z);
 
518
  if (found == values.end()) {
 
519
      found = values.find(DefaultZ);
 
520
    }
 
521
  return found->second[i];
 
522
}
 
523
 
 
524
double
 
525
AtomInfo::vdw_radius(int Z) const
 
526
{
 
527
  return lookup_value(Z_to_vdw_radius_,Z)*vdw_radius_scale_;
 
528
}
 
529
 
 
530
double
 
531
AtomInfo::bragg_radius(int Z) const
 
532
{
 
533
  return lookup_value(Z_to_bragg_radius_,Z)*bragg_radius_scale_;
 
534
}
 
535
 
 
536
double
 
537
AtomInfo::atomic_radius(int Z) const
 
538
{
 
539
  return lookup_value(Z_to_atomic_radius_,Z)*atomic_radius_scale_;
 
540
}
 
541
 
 
542
double
 
543
AtomInfo::maxprob_radius(int Z) const
 
544
{
 
545
  return lookup_value(Z_to_maxprob_radius_,Z)*maxprob_radius_scale_;
 
546
}
 
547
 
 
548
double
 
549
AtomInfo::ip(int Z) const
 
550
{
 
551
  return lookup_value(Z_to_ip_,Z);
 
552
}
 
553
 
 
554
double
 
555
AtomInfo::rgb(int Z, int color) const
 
556
{
 
557
  return lookup_array_value(Z_to_rgb_,Z,color);
 
558
}
 
559
 
 
560
double
 
561
AtomInfo::red(int Z) const
 
562
{
 
563
  return lookup_array_value(Z_to_rgb_,Z,0);
 
564
}
 
565
 
 
566
double
 
567
AtomInfo::green(int Z) const
 
568
{
 
569
  return lookup_array_value(Z_to_rgb_,Z,1);
 
570
}
 
571
 
 
572
double
 
573
AtomInfo::blue(int Z) const
 
574
{
 
575
  return lookup_array_value(Z_to_rgb_,Z,2);
 
576
}
 
577
 
 
578
double
 
579
AtomInfo::mass(int Z) const
 
580
{
 
581
  return lookup_value(Z_to_mass_,Z);
 
582
}
 
583
 
 
584
std::string
 
585
AtomInfo::name(int Z)
 
586
{
 
587
  std::map<int,std::string>::const_iterator found = Z_to_names_.find(Z);
 
588
  if (found == Z_to_names_.end()) {
 
589
      ExEnv::err0() << scprintf("AtomInfo: invalid Z: %d\n",Z);
 
590
      throw std::runtime_error("invalid Z");
 
591
    }
 
592
  return found->second;
 
593
}
 
594
 
 
595
std::string
 
596
AtomInfo::symbol(int Z)
 
597
{
 
598
  std::map<int,std::string>::const_iterator found = Z_to_symbols_.find(Z);
 
599
  if (found == Z_to_symbols_.end()) {
 
600
      ExEnv::err0() << scprintf("AtomInfo: invalid Z: %d\n",Z);
 
601
      throw std::runtime_error("invalid Z");
 
602
    }
 
603
  return found->second;
503
604
}
504
605
 
505
606
/////////////////////////////////////////////////////////////////////////////