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