// -*- 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;
}