| 1 | //
 | 
|---|
| 2 | // molinfo.cc
 | 
|---|
| 3 | //
 | 
|---|
| 4 | // Copyright (C) 1996 Limit Point Systems, Inc.
 | 
|---|
| 5 | //
 | 
|---|
| 6 | // Author: Curtis Janssen <cljanss@limitpt.com>
 | 
|---|
| 7 | // Maintainer: LPS
 | 
|---|
| 8 | //
 | 
|---|
| 9 | // This file is part of the SC Toolkit.
 | 
|---|
| 10 | //
 | 
|---|
| 11 | // The SC Toolkit is free software; you can redistribute it and/or modify
 | 
|---|
| 12 | // it under the terms of the GNU Library General Public License as published by
 | 
|---|
| 13 | // the Free Software Foundation; either version 2, or (at your option)
 | 
|---|
| 14 | // any later version.
 | 
|---|
| 15 | //
 | 
|---|
| 16 | // The SC Toolkit is distributed in the hope that it will be useful,
 | 
|---|
| 17 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
|---|
| 18 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
|---|
| 19 | // GNU Library General Public License for more details.
 | 
|---|
| 20 | //
 | 
|---|
| 21 | // You should have received a copy of the GNU Library General Public License
 | 
|---|
| 22 | // along with the SC Toolkit; see the file COPYING.LIB.  If not, write to
 | 
|---|
| 23 | // the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
 | 
|---|
| 24 | //
 | 
|---|
| 25 | // The U.S. Government is granted a limited license as per AL 91-7.
 | 
|---|
| 26 | //
 | 
|---|
| 27 | 
 | 
|---|
| 28 | #include <stdlib.h>
 | 
|---|
| 29 | #include <util/misc/string.h>
 | 
|---|
| 30 | #include <ctype.h>
 | 
|---|
| 31 | #include <sys/stat.h>
 | 
|---|
| 32 | 
 | 
|---|
| 33 | #include <sstream>
 | 
|---|
| 34 | #include <stdexcept>
 | 
|---|
| 35 | 
 | 
|---|
| 36 | #include <util/misc/units.h>
 | 
|---|
| 37 | #include <util/misc/autovec.h>
 | 
|---|
| 38 | #include <util/misc/formio.h>
 | 
|---|
| 39 | #include <util/state/stateio.h>
 | 
|---|
| 40 | #include <util/group/message.h>
 | 
|---|
| 41 | #include <chemistry/molecule/atominfo.h>
 | 
|---|
| 42 | 
 | 
|---|
| 43 | using namespace std;
 | 
|---|
| 44 | using namespace sc;
 | 
|---|
| 45 | 
 | 
|---|
| 46 | ////////////////////////////////////////////////////////////////////////
 | 
|---|
| 47 | // AtomInfo
 | 
|---|
| 48 | 
 | 
|---|
| 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"}
 | 
|---|
| 169 |   };
 | 
|---|
| 170 | 
 | 
|---|
| 171 | static ClassDesc AtomInfo_cd(
 | 
|---|
| 172 |   typeid(AtomInfo),"AtomInfo",3,"public SavableState",
 | 
|---|
| 173 |   0, create<AtomInfo>, create<AtomInfo>);
 | 
|---|
| 174 | 
 | 
|---|
| 175 | AtomInfo::AtomInfo()
 | 
|---|
| 176 | {
 | 
|---|
| 177 |   initialize_names();
 | 
|---|
| 178 |   overridden_values_ = 0;
 | 
|---|
| 179 |   load_library_values();
 | 
|---|
| 180 | }
 | 
|---|
| 181 | 
 | 
|---|
| 182 | AtomInfo::AtomInfo(const Ref<KeyVal>& keyval)
 | 
|---|
| 183 | {
 | 
|---|
| 184 |   initialize_names();
 | 
|---|
| 185 |   overridden_values_ = 0;
 | 
|---|
| 186 |   load_library_values();
 | 
|---|
| 187 |   override_library_values(keyval);
 | 
|---|
| 188 | }
 | 
|---|
| 189 | 
 | 
|---|
| 190 | AtomInfo::AtomInfo(StateIn& s):
 | 
|---|
| 191 |   SavableState(s)
 | 
|---|
| 192 | {
 | 
|---|
| 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;
 | 
|---|
| 203 |     }
 | 
|---|
| 204 |   if (s.version(::class_desc<AtomInfo>()) < 2) {
 | 
|---|
| 205 |       atomic_radius_scale_ = 1.0;
 | 
|---|
| 206 |       vdw_radius_scale_ = 1.0;
 | 
|---|
| 207 |       bragg_radius_scale_ = 1.0;
 | 
|---|
| 208 |       maxprob_radius_scale_ = 1.0;
 | 
|---|
| 209 |     }
 | 
|---|
| 210 |   else {
 | 
|---|
| 211 |       s.get(atomic_radius_scale_);
 | 
|---|
| 212 |       s.get(vdw_radius_scale_);
 | 
|---|
| 213 |       s.get(bragg_radius_scale_);
 | 
|---|
| 214 |       s.get(maxprob_radius_scale_);
 | 
|---|
| 215 |     }
 | 
|---|
| 216 | }
 | 
|---|
| 217 | 
 | 
|---|
| 218 | AtomInfo::~AtomInfo()
 | 
|---|
| 219 | {
 | 
|---|
| 220 |   delete[] overridden_values_;
 | 
|---|
| 221 | }
 | 
|---|
| 222 | 
 | 
|---|
| 223 | void
 | 
|---|
| 224 | AtomInfo::save_data_state(StateOut& s)
 | 
|---|
| 225 | {
 | 
|---|
| 226 |   s.putstring(overridden_values_);
 | 
|---|
| 227 |   s.put(atomic_radius_scale_);
 | 
|---|
| 228 |   s.put(vdw_radius_scale_);
 | 
|---|
| 229 |   s.put(bragg_radius_scale_);
 | 
|---|
| 230 |   s.put(maxprob_radius_scale_);
 | 
|---|
| 231 | }
 | 
|---|
| 232 | 
 | 
|---|
| 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
 | 
|---|
| 261 | AtomInfo::load_library_values()
 | 
|---|
| 262 | {
 | 
|---|
| 263 |   Ref<MessageGrp> grp = MessageGrp::get_default_messagegrp();
 | 
|---|
| 264 |   sc::auto_vec<char> in_char_array;
 | 
|---|
| 265 |   if (grp->me() == 0) {
 | 
|---|
| 266 |       const char* libdir;
 | 
|---|
| 267 |       std::string filename;
 | 
|---|
| 268 |       if ((libdir = getenv("SCLIBDIR")) != 0) {
 | 
|---|
| 269 |           const char* atominfo = "/atominfo.kv";
 | 
|---|
| 270 |           const char *eq = ::strchr(libdir,'=');
 | 
|---|
| 271 |           if (eq) libdir = eq + 1;
 | 
|---|
| 272 |           filename = std::string(libdir) + atominfo;
 | 
|---|
| 273 |         }
 | 
|---|
| 274 |       else {
 | 
|---|
| 275 |           struct stat sb;
 | 
|---|
| 276 |           const char *ainfo = SCDATADIR "/atominfo.kv";
 | 
|---|
| 277 | #ifdef SRC_SCLIBDIR
 | 
|---|
| 278 |           if (stat(ainfo, &sb) != 0) {
 | 
|---|
| 279 |               ainfo = SRC_SCLIBDIR "/atominfo.kv";
 | 
|---|
| 280 |             }
 | 
|---|
| 281 | #endif
 | 
|---|
| 282 |           filename = ainfo;
 | 
|---|
| 283 |         }
 | 
|---|
| 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);
 | 
|---|
| 304 | }
 | 
|---|
| 305 | 
 | 
|---|
| 306 | void
 | 
|---|
| 307 | AtomInfo::override_library_values(const Ref<KeyVal> &keyval)
 | 
|---|
| 308 | {
 | 
|---|
| 309 |   load_values(keyval, 1);
 | 
|---|
| 310 | }
 | 
|---|
| 311 | 
 | 
|---|
| 312 | void
 | 
|---|
| 313 | AtomInfo::load_values(const Ref<KeyVal>& keyval, int override)
 | 
|---|
| 314 | {
 | 
|---|
| 315 |   Ref<Units> amu = new Units("amu");
 | 
|---|
| 316 |   Ref<Units> bohr = new Units("bohr");
 | 
|---|
| 317 |   Ref<Units> hartree = new Units("hartree");
 | 
|---|
| 318 | 
 | 
|---|
| 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_,
 | 
|---|
| 325 |               "bragg_radius", keyval, override, bohr);
 | 
|---|
| 326 |   load_values(Z_to_maxprob_radius_, &maxprob_radius_scale_,
 | 
|---|
| 327 |               "maxprob_radius", keyval, override, bohr);
 | 
|---|
| 328 |   load_values(Z_to_rgb_, "rgb", keyval, override);
 | 
|---|
| 329 |   load_values(Z_to_ip_, 0, "ip", keyval, override, hartree);
 | 
|---|
| 330 | }
 | 
|---|
| 331 | 
 | 
|---|
| 332 | void
 | 
|---|
| 333 | AtomInfo::load_values(std::map<int,double>&values,
 | 
|---|
| 334 |                       double *scale, const char *keyword,
 | 
|---|
| 335 |                       const Ref<KeyVal> &keyval, int override,
 | 
|---|
| 336 |                       const Ref<Units> &units)
 | 
|---|
| 337 | {
 | 
|---|
| 338 |   Ref<KeyVal> pkeyval = new PrefixKeyVal(keyval,keyword);
 | 
|---|
| 339 |   Ref<Units> fileunits = new Units(pkeyval->pcharvalue("unit"), Units::Steal);
 | 
|---|
| 340 |   double f = 1.0;
 | 
|---|
| 341 |   if (fileunits.nonnull() && units.nonnull()) {
 | 
|---|
| 342 |       f = fileunits->to(units);
 | 
|---|
| 343 |     }
 | 
|---|
| 344 |   double def = 0.0;
 | 
|---|
| 345 |   if (!override) {
 | 
|---|
| 346 |       def = pkeyval->doublevalue("default");
 | 
|---|
| 347 |       values[DefaultZ] = def;
 | 
|---|
| 348 |     }
 | 
|---|
| 349 |   int have_overridden = 0;
 | 
|---|
| 350 |   for (int elem=0; elem<Nelement; elem++) {
 | 
|---|
| 351 |       int Z = elements_[elem].Z;
 | 
|---|
| 352 |       double val = f * pkeyval->doublevalue(elements_[elem].symbol);
 | 
|---|
| 353 |       if (pkeyval->error() != KeyVal::OK) {
 | 
|---|
| 354 |           if (!override) values[Z] = def;
 | 
|---|
| 355 |         }
 | 
|---|
| 356 |       else {
 | 
|---|
| 357 |           values[Z] = val;
 | 
|---|
| 358 |           if (override) {
 | 
|---|
| 359 |               const char *prefix = " ";
 | 
|---|
| 360 |               if (!have_overridden) {
 | 
|---|
| 361 |                   add_overridden_value(keyword);
 | 
|---|
| 362 |                   add_overridden_value(":(");
 | 
|---|
| 363 |                   if (fileunits.nonnull() && fileunits->string_rep()) {
 | 
|---|
| 364 |                       char ustring[256];
 | 
|---|
| 365 |                       sprintf(ustring,"unit=\"%s\"",fileunits->string_rep());
 | 
|---|
| 366 |                       add_overridden_value(ustring);
 | 
|---|
| 367 |                     }
 | 
|---|
| 368 |                   else {
 | 
|---|
| 369 |                       prefix = "";
 | 
|---|
| 370 |                     }
 | 
|---|
| 371 |                   have_overridden = 1;
 | 
|---|
| 372 |                 }
 | 
|---|
| 373 |               char *strval = pkeyval->pcharvalue(elements_[elem].symbol);
 | 
|---|
| 374 |               char assignment[256];
 | 
|---|
| 375 |               sprintf(assignment,"%s%s=%s", prefix,
 | 
|---|
| 376 |                       elements_[elem].symbol, strval);
 | 
|---|
| 377 |               delete[] strval;
 | 
|---|
| 378 |               add_overridden_value(assignment);
 | 
|---|
| 379 |             }
 | 
|---|
| 380 |         }
 | 
|---|
| 381 |     }
 | 
|---|
| 382 |   if (scale) {
 | 
|---|
| 383 |       KeyValValuedouble kvvscale(1.0);
 | 
|---|
| 384 |       *scale = pkeyval->doublevalue("scale_factor", kvvscale);
 | 
|---|
| 385 |       if (pkeyval->error() == KeyVal::OK) {
 | 
|---|
| 386 |           if (override) {
 | 
|---|
| 387 |               const char *prefix = " ";
 | 
|---|
| 388 |               if (!have_overridden) {
 | 
|---|
| 389 |                   add_overridden_value(keyword);
 | 
|---|
| 390 |                   add_overridden_value(":(");
 | 
|---|
| 391 |                   have_overridden = 1;
 | 
|---|
| 392 |                   prefix = "";
 | 
|---|
| 393 |                 }
 | 
|---|
| 394 |               char *strval = pkeyval->pcharvalue("scale_factor");
 | 
|---|
| 395 |               char assignment[256];
 | 
|---|
| 396 |               sprintf(assignment,"%sscale_factor=%s", prefix, strval);
 | 
|---|
| 397 |               delete[] strval;
 | 
|---|
| 398 |               add_overridden_value(assignment);
 | 
|---|
| 399 |             }
 | 
|---|
| 400 |         }
 | 
|---|
| 401 |     }
 | 
|---|
| 402 |   if (have_overridden) {
 | 
|---|
| 403 |       add_overridden_value(")");
 | 
|---|
| 404 |     }
 | 
|---|
| 405 | }
 | 
|---|
| 406 | 
 | 
|---|
| 407 | void
 | 
|---|
| 408 | AtomInfo::load_values(std::map<int,std::vector<double> >&values,
 | 
|---|
| 409 |                       const char *keyword,
 | 
|---|
| 410 |                       const Ref<KeyVal> &keyval, int override)
 | 
|---|
| 411 | {
 | 
|---|
| 412 |   Ref<KeyVal> pkeyval = new PrefixKeyVal(keyval,keyword);
 | 
|---|
| 413 |   double def[3];
 | 
|---|
| 414 |   if (!override) {
 | 
|---|
| 415 |       values[DefaultZ].resize(3);
 | 
|---|
| 416 |       for (int i=0; i<3; i++) {
 | 
|---|
| 417 |           def[i] = pkeyval->doublevalue("default",i);
 | 
|---|
| 418 |           values[DefaultZ][i] = def[i];
 | 
|---|
| 419 |         }
 | 
|---|
| 420 |     }
 | 
|---|
| 421 |   int have_overridden = 0;
 | 
|---|
| 422 |   for (int elem=0; elem<Nelement; elem++) {
 | 
|---|
| 423 |       double val;
 | 
|---|
| 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);
 | 
|---|
| 428 |           if (pkeyval->error() != KeyVal::OK) {
 | 
|---|
| 429 |               if (!override) values[Z][j] = def[j];
 | 
|---|
| 430 |             }
 | 
|---|
| 431 |           else {
 | 
|---|
| 432 |               values[Z][j] = val;
 | 
|---|
| 433 |               if (override) {
 | 
|---|
| 434 |                   const char *prefix = " ";
 | 
|---|
| 435 |                   if (!have_overridden) {
 | 
|---|
| 436 |                       add_overridden_value(keyword);
 | 
|---|
| 437 |                       add_overridden_value(":(");
 | 
|---|
| 438 |                       prefix = "";
 | 
|---|
| 439 |                       have_overridden = 1;
 | 
|---|
| 440 |                     }
 | 
|---|
| 441 |                   char *strval = pkeyval->pcharvalue(elements_[elem].symbol,j);
 | 
|---|
| 442 |                   char assignment[256];
 | 
|---|
| 443 |                   sprintf(assignment,"%s%s:%d=%s",
 | 
|---|
| 444 |                           prefix, elements_[elem].symbol, j, strval);
 | 
|---|
| 445 |                   delete[] strval;
 | 
|---|
| 446 |                   add_overridden_value(assignment);
 | 
|---|
| 447 |                 }
 | 
|---|
| 448 |             }
 | 
|---|
| 449 |         }
 | 
|---|
| 450 |     }
 | 
|---|
| 451 |   if (have_overridden) {
 | 
|---|
| 452 |       add_overridden_value(")");
 | 
|---|
| 453 |     }
 | 
|---|
| 454 | }
 | 
|---|
| 455 | 
 | 
|---|
| 456 | void
 | 
|---|
| 457 | AtomInfo::add_overridden_value(const char *assignment)
 | 
|---|
| 458 | {
 | 
|---|
| 459 |   int length = strlen(assignment)+1;
 | 
|---|
| 460 |   if (overridden_values_) length += strlen(overridden_values_);
 | 
|---|
| 461 |   char *new_overridden_values = new char[length];
 | 
|---|
| 462 |   new_overridden_values[0] = '\0';
 | 
|---|
| 463 |   if (overridden_values_) strcat(new_overridden_values, overridden_values_);
 | 
|---|
| 464 |   strcat(new_overridden_values, assignment);
 | 
|---|
| 465 |   delete[] overridden_values_;
 | 
|---|
| 466 |   overridden_values_ = new_overridden_values;
 | 
|---|
| 467 | }
 | 
|---|
| 468 | 
 | 
|---|
| 469 | int
 | 
|---|
| 470 | AtomInfo::string_to_Z(const std::string &name, int allow_exceptions)
 | 
|---|
| 471 | {
 | 
|---|
| 472 |   int Z;
 | 
|---|
| 473 | 
 | 
|---|
| 474 |   // see if the name is a atomic number
 | 
|---|
| 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;
 | 
|---|
| 604 | }
 | 
|---|
| 605 | 
 | 
|---|
| 606 | /////////////////////////////////////////////////////////////////////////////
 | 
|---|
| 607 | 
 | 
|---|
| 608 | // Local Variables:
 | 
|---|
| 609 | // mode: c++
 | 
|---|
| 610 | // c-file-style: "CLJ"
 | 
|---|
| 611 | // End:
 | 
|---|