// -*- 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 #include #include #include #include KimParameterProvider::KimParameterProvider(KIM::ModelDriverCreate *const modelDriverCreate, std::vector ¶meter_filenames, KIM::LengthUnit const requestedLengthUnit, KIM::EnergyUnit const requestedEnergyUnit, KIM::ChargeUnit const requestedChargeUnit, KIM::TemperatureUnit const requestedTemperatureUnit, KIM::TimeUnit const requestedTimeUnit) { DEBUGPRINT; int error; // Register units error = modelDriverCreate->SetUnits(requestedLengthUnit, requestedEnergyUnit, KIM::CHARGE_UNIT::unused, KIM::TEMPERATURE_UNIT::unused, KIM::TIME_UNIT::unused); if (error) throw AsapError("Unable to set units to requested values"); // define default base units KIM::LengthUnit fromLength = KIM::LENGTH_UNIT::A; KIM::EnergyUnit fromEnergy = KIM::ENERGY_UNIT::eV; KIM::ChargeUnit fromCharge = KIM::CHARGE_UNIT::e; KIM::TemperatureUnit fromTemperature = KIM::TEMPERATURE_UNIT::K; KIM::TimeUnit fromTime = KIM::TIME_UNIT::ps; // Prepare to convert all parameters to other units. double energy_conv = 1.0; error = modelDriverCreate->ConvertUnit(fromLength, fromEnergy, fromCharge, fromTemperature, fromTime, requestedLengthUnit, requestedEnergyUnit, requestedChargeUnit, requestedTemperatureUnit, requestedTimeUnit, 0.0, 1.0, 0.0, 0.0, 0.0, &energy_conv); if (error) throw AsapError("Unable to convert energy unit"); double len_conv = 1.0; error = modelDriverCreate->ConvertUnit(fromLength, fromEnergy, fromCharge, fromTemperature, fromTime, requestedLengthUnit, requestedEnergyUnit, requestedChargeUnit, requestedTemperatureUnit, requestedTimeUnit, 1.0, 0.0, 0.0, 0.0, 0.0, &len_conv); if (error) throw AsapError("Unable to convert length unit"); double inv_len_conv = 1.0; error = modelDriverCreate->ConvertUnit(fromLength, fromEnergy, fromCharge, fromTemperature, fromTime, requestedLengthUnit, requestedEnergyUnit, requestedChargeUnit, requestedTemperatureUnit, requestedTimeUnit, -1.0, 0.0, 0.0, 0.0, 0.0, &inv_len_conv); if (error) throw AsapError("Unable to convert inverse length unit"); double inv_vol_conv = 1.0; error = modelDriverCreate->ConvertUnit(fromLength, fromEnergy, fromCharge, fromTemperature, fromTime, requestedLengthUnit, requestedEnergyUnit, requestedChargeUnit, requestedTemperatureUnit, requestedTimeUnit, -3.0, 0.0, 0.0, 0.0, 0.0, &inv_vol_conv); if (error) throw AsapError("Unable to convert inverse length unit"); // Read the parameter file. if (parameter_filenames.size() != 1) throw AsapError("Expected a single parameter file, got ") << parameter_filenames.size(); std::ifstream pstr(parameter_filenames[0].c_str()); int numread = -1; emt_parameters *p = NULL; while(true) { std::string word; double value; pstr >> word >> value; //std::cerr << "read(" << word << ")(" << value << ")" << std::endl; numread++; if (word == "NEWELEMENT") { std::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; KIM::SpeciesName const specName(name); error = modelDriverCreate->SetSpeciesCode(name, value); if (error) throw AsapError("Cannot set species code ") << name << " to " << value; } 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"); } p->index = params.size(); // Count the elements, starting at zero. params.push_back(p); 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 not supported (missing from parameter file): number = ") << element; }