// -*- C++ -*- // KimParameterProvider.cpp: Get parameters from a string (for OpenKIM). // // Copyright (C) 2012-2013 Jakob Schiotz and the Department of Physics, // Technical University of Denmark. Email: schiotz@fysik.dtu.dk // // This file is part of Asap version 3. // Asap is released under the GNU Lesser Public License (LGPL) version 3. // However, the parts of Asap distributed within the OpenKIM project // (including this file) are also released under the Common Development // and Distribution License (CDDL) version 1.0. // // This program is free software: you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public License // version 3 as published by the Free Software Foundation. Permission // to use other versions of the GNU Lesser General Public License may // granted by Jakob Schiotz or the head of department of the // Department of Physics, Technical University of Denmark, as // described in section 14 of the GNU General Public License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // and the GNU Lesser Public License along with this program. If not, // see . #include "KimParameterProvider.h" #include "Asap.h" #include "Exception.h" // #define ASAPDEBUG #include "Debug.h" #include "KIM_API_C.h" #include "KIM_API_status.h" #include #include #include #include #include KimParameterProvider::KimParameterProvider(const char *parameter_filename, intptr_t *pkim) { DEBUGPRINT; // Get a list of elements in the simulation. int nelements; int ier; char *elementlist = KIM_API_get_test_partcl_typs(pkim, &nelements, &ier); if (ier != KIM_STATUS_OK || nelements < 1 || elementlist == NULL) { std::cerr << "KIM_API_get_test_partcl_typs failed. " << ier << " " << nelements << " " << elementlist << std::endl; KIM_API_report_error(__LINE__, __FILE__, "KIM_API_get_test_partcl_typs failed.", ier); throw AsapError("Failed to get element list from OpenKIM."); } std::set elements; for (int i = 0; i < nelements; i++) { string el = string(elementlist + i * KIM_KEY_STRING_LENGTH); elements.insert(el); // std::cerr << "Simulation needs element *" << el << "*" << std::endl; } free(elementlist); // Prepare to convert all parameters to other units. double energy_conv = KIM_API_convert_to_act_unit(pkim, "A", "eV", "e", "K", "ps", 0.0, 1.0, 0.0, 0.0, 0.0, &ier); assert(ier == KIM_STATUS_OK); // Should not be able to fail. double len_conv = KIM_API_convert_to_act_unit(pkim, "A", "eV", "e", "K", "ps", 1.0, 0.0, 0.0, 0.0, 0.0, &ier); assert(ier == KIM_STATUS_OK); // Should not be able to fail. double inv_len_conv = KIM_API_convert_to_act_unit(pkim, "A", "eV", "e", "K", "ps", -1.0, 0.0, 0.0, 0.0, 0.0, &ier); assert(ier == KIM_STATUS_OK); // Should not be able to fail. double inv_vol_conv = KIM_API_convert_to_act_unit(pkim, "A", "eV", "e", "K", "ps", -3.0, 0.0, 0.0, 0.0, 0.0, &ier); assert(ier == KIM_STATUS_OK); // Should not be able to fail. // Read the parameter file. std::fstream pstr(parameter_filename, std::fstream::in); int numread = -1; emt_parameters *p = NULL; while(true) { string word; double value; pstr >> word >> value; //std::cerr << "read(" << word << ")(" << value << ")" << std::endl; numread++; if (word == "NEWELEMENT") { string name; pstr >> name; numread = 0; p = new emt_parameters; p->Z = (int) value; p->gamma1 = 0.0; // These are calculated later! p->gamma2 = 0.0; p->name = name; } else if (word == "V0") p->V0 = value * energy_conv; else if (word == "kappa") p->kappa = value * inv_len_conv; else if (word == "eta2") p->eta2 = value * inv_len_conv; else if (word == "n0") p->neq = value * inv_vol_conv; else if (word == "S0") p->seq = value * len_conv; else if (word == "E0") p->e0 = value * energy_conv; else if (word == "lambda") p->lambda = value * inv_len_conv; else if (word == "mass") { p->mass = value; // Never really used. p->invmass = 1.0/value; } else if (word == "ENDELEMENT") { if (numread != 9) { std::cerr << "Wrong number of parameters for element " << p->name << std::endl; throw AsapError("Error in parameterfile"); } if (elements.count(p->name)) { // We need this element p->index = params.size(); // Count the elements, starting at zero. params.push_back(p); } else delete p; // We don't need it. p = NULL; } else if (word == "STOP") break; else { std::cerr << "Unknown keyword in parameter file: " << word << std::endl; throw AsapError("Error in parameterfile"); } } } emt_parameters *KimParameterProvider::GetNewParameters(int element) { throw AsapError("Element missing from parameter file or unannounced by simulation: number = ") << element; }