Merge pull request #2477 from yafshar/kim_improvement

Misc. KIM updates
This commit is contained in:
Richard Berger
2020-11-29 12:17:17 -05:00
committed by GitHub
9 changed files with 589 additions and 422 deletions

View File

@ -92,7 +92,12 @@ void KimInit::command(int narg, char **arg)
strcpy(user_units,arg[1]);
if (narg == 3) {
if (strcmp(arg[2],"unit_conversion_mode")==0) unit_conversion_mode = true;
else { error->all(FLERR,"Illegal kim_init command"); }
else {
error->all(FLERR,fmt::format("Illegal kim_init command.\nThe argument "
"followed by unit_style {} is an optional "
"argument and when is used must "
"be unit_conversion_mode", user_units));
}
} else unit_conversion_mode = false;
char *model_units;
@ -122,38 +127,41 @@ void get_kim_unit_names(
KIM_TimeUnit & timeUnit,
Error * error)
{
if ((strcmp(system,"real")==0)) {
if (strcmp(system,"real") == 0) {
lengthUnit = KIM_LENGTH_UNIT_A;
energyUnit = KIM_ENERGY_UNIT_kcal_mol;
chargeUnit = KIM_CHARGE_UNIT_e;
temperatureUnit = KIM_TEMPERATURE_UNIT_K;
timeUnit = KIM_TIME_UNIT_fs;
} else if ((strcmp(system,"metal")==0)) {
} else if (strcmp(system,"metal") == 0) {
lengthUnit = KIM_LENGTH_UNIT_A;
energyUnit = KIM_ENERGY_UNIT_eV;
chargeUnit = KIM_CHARGE_UNIT_e;
temperatureUnit = KIM_TEMPERATURE_UNIT_K;
timeUnit = KIM_TIME_UNIT_ps;
} else if ((strcmp(system,"si")==0)) {
} else if (strcmp(system,"si") == 0) {
lengthUnit = KIM_LENGTH_UNIT_m;
energyUnit = KIM_ENERGY_UNIT_J;
chargeUnit = KIM_CHARGE_UNIT_C;
temperatureUnit = KIM_TEMPERATURE_UNIT_K;
timeUnit = KIM_TIME_UNIT_s;
} else if ((strcmp(system,"cgs")==0)) {
} else if (strcmp(system,"cgs") == 0) {
lengthUnit = KIM_LENGTH_UNIT_cm;
energyUnit = KIM_ENERGY_UNIT_erg;
chargeUnit = KIM_CHARGE_UNIT_statC;
temperatureUnit = KIM_TEMPERATURE_UNIT_K;
timeUnit = KIM_TIME_UNIT_s;
} else if ((strcmp(system,"electron")==0)) {
} else if (strcmp(system,"electron") == 0) {
lengthUnit = KIM_LENGTH_UNIT_Bohr;
energyUnit = KIM_ENERGY_UNIT_Hartree;
chargeUnit = KIM_CHARGE_UNIT_e;
temperatureUnit = KIM_TEMPERATURE_UNIT_K;
timeUnit = KIM_TIME_UNIT_fs;
} else if ((strcmp(system,"lj")==0)) {
error->all(FLERR,"LAMMPS unit_style lj not supported by KIM models");
} else if (strcmp(system,"lj") == 0 ||
strcmp(system,"micro") ==0 ||
strcmp(system,"nano")==0) {
error->all(FLERR,fmt::format("LAMMPS unit_style {} not supported "
"by KIM models", system));
} else {
error->all(FLERR,"Unknown unit_style");
}
@ -171,19 +179,19 @@ void KimInit::determine_model_type_and_units(char * model_name,
KIM_TemperatureUnit temperatureUnit;
KIM_TimeUnit timeUnit;
int units_accepted;
KIM_Collections * kim_Coll;
KIM_Collections * collections;
KIM_CollectionItemType itemType;
int kim_error = KIM_Collections_Create(&kim_Coll);
if (kim_error) {
error->all(FLERR,"Unable to access KIM Collections to find Model.");
}
int kim_error = KIM_Collections_Create(&collections);
if (kim_error)
error->all(FLERR,"Unable to access KIM Collections to find Model");
kim_error = KIM_Collections_GetItemType(kim_Coll, model_name, &itemType);
if (kim_error) {
error->all(FLERR,"KIM Model name not found.");
}
KIM_Collections_Destroy(&kim_Coll);
auto logID = fmt::format("{}_Collections", comm->me);
KIM_Collections_SetLogID(collections, logID.c_str());
kim_error = KIM_Collections_GetItemType(collections, model_name, &itemType);
if (kim_error) error->all(FLERR,"KIM Model name not found");
KIM_Collections_Destroy(&collections);
if (KIM_CollectionItemType_Equal(itemType,
KIM_COLLECTION_ITEM_TYPE_portableModel)) {
@ -199,12 +207,13 @@ void KimInit::determine_model_type_and_units(char * model_name,
&units_accepted,
&pkim);
if (kim_error)
error->all(FLERR,"Unable to load KIM Simulator Model.");
if (kim_error) error->all(FLERR,"Unable to load KIM Simulator Model");
model_type = MO;
if (units_accepted) {
logID = fmt::format("{}_Model", comm->me);
KIM_Model_SetLogID(pkim, logID.c_str());
*model_units = new char[strlen(user_units)+1];
strcpy(*model_units,user_units);
return;
@ -226,6 +235,8 @@ void KimInit::determine_model_type_and_units(char * model_name,
&units_accepted,
&pkim);
if (units_accepted) {
logID = fmt::format("{}_Model", comm->me);
KIM_Model_SetLogID(pkim, logID.c_str());
*model_units = new char[strlen(systems[i])+1];
strcpy(*model_units,systems[i]);
return;
@ -238,37 +249,40 @@ void KimInit::determine_model_type_and_units(char * model_name,
error->all(FLERR,"KIM Model does not support the requested unit system");
}
} else if (KIM_CollectionItemType_Equal(
itemType, KIM_COLLECTION_ITEM_TYPE_simulatorModel)) {
KIM_SimulatorModel * kim_SM;
kim_error = KIM_SimulatorModel_Create(model_name, &kim_SM);
itemType, KIM_COLLECTION_ITEM_TYPE_simulatorModel)) {
KIM_SimulatorModel * simulatorModel;
kim_error = KIM_SimulatorModel_Create(model_name, &simulatorModel);
if (kim_error)
error->all(FLERR,"Unable to load KIM Simulator Model.");
error->all(FLERR,"Unable to load KIM Simulator Model");
model_type = SM;
logID = fmt::format("{}_SimulatorModel", comm->me);
KIM_SimulatorModel_SetLogID(simulatorModel, logID.c_str());
int sim_fields;
int sim_lines;
char const * sim_field;
char const * sim_value;
KIM_SimulatorModel_GetNumberOfSimulatorFields(kim_SM, &sim_fields);
KIM_SimulatorModel_CloseTemplateMap(kim_SM);
KIM_SimulatorModel_GetNumberOfSimulatorFields(simulatorModel, &sim_fields);
KIM_SimulatorModel_CloseTemplateMap(simulatorModel);
for (int i=0; i < sim_fields; ++i) {
KIM_SimulatorModel_GetSimulatorFieldMetadata(
kim_SM,i,&sim_lines,&sim_field);
simulatorModel, i, &sim_lines, &sim_field);
if (0 == strcmp(sim_field,"units")) {
KIM_SimulatorModel_GetSimulatorFieldLine(kim_SM,i,0,&sim_value);
KIM_SimulatorModel_GetSimulatorFieldLine(
simulatorModel, i, 0, &sim_value);
int len=strlen(sim_value)+1;
*model_units = new char[len]; strcpy(*model_units,sim_value);
*model_units = new char[len];
strcpy(*model_units,sim_value);
break;
}
}
KIM_SimulatorModel_Destroy(&kim_SM);
KIM_SimulatorModel_Destroy(&simulatorModel);
if ((! unit_conversion_mode) && (strcmp(*model_units, user_units)!=0)) {
std::string mesg("Incompatible units for KIM Simulator Model, "
"required units = ");
mesg += *model_units;
error->all(FLERR,mesg);
error->all(FLERR,fmt::format("Incompatible units for KIM Simulator Model"
", required units = {}", *model_units));
}
}
}
@ -295,13 +309,16 @@ void KimInit::do_init(char *model_name, char *user_units, char *model_units, KIM
KIM_SimulatorModel * simulatorModel;
if (model_type == SM) {
int kim_error =
KIM_SimulatorModel_Create(model_name,&simulatorModel);
KIM_SimulatorModel_Create(model_name, &simulatorModel);
if (kim_error)
error->all(FLERR,"Unable to load KIM Simulator Model.");
error->all(FLERR,"Unable to load KIM Simulator Model");
auto logID = fmt::format("{}_SimulatorModel", comm->me);
KIM_SimulatorModel_SetLogID(simulatorModel, logID.c_str());
char const *sim_name, *sim_version;
KIM_SimulatorModel_GetSimulatorNameAndVersion(
simulatorModel,&sim_name, &sim_version);
simulatorModel, &sim_name, &sim_version);
if (0 != strcmp(sim_name,"LAMMPS"))
error->all(FLERR,"Incompatible KIM Simulator Model");
@ -389,7 +406,7 @@ void KimInit::do_init(char *model_name, char *user_units, char *model_units, KIM
mesg += fmt::format(" {:<8} | {:<{}} | {:<10} | {}\n",i+1,str_name,
max_len,data_type,extent);
}
} else mesg += "No mutable parameters. \n";
} else mesg += "No mutable parameters.\n";
KIM_Model_Destroy(&pkim);
input->write_echo(mesg);
@ -447,7 +464,7 @@ void KimInit::do_variables(const std::string &from, const std::string &to)
conversion_factor);
if (ier != 0)
error->all(FLERR,fmt::format("Unable to obtain conversion factor: "
"unit = {}; from = {}; to = {}.",
"unit = {}; from = {}; to = {}",
units[i], from, to));
variable->internal_set(v_unit,conversion_factor);
@ -461,23 +478,28 @@ void KimInit::do_variables(const std::string &from, const std::string &to)
void KimInit::write_log_cite(char *model_name)
{
KIM_Collections * coll;
int err = KIM_Collections_Create(&coll);
KIM_Collections * collections;
int err = KIM_Collections_Create(&collections);
if (err) return;
auto logID = fmt::format("{}_Collections", comm->me);
KIM_Collections_SetLogID(collections, logID.c_str());
int extent;
if (model_type == MO) {
err = KIM_Collections_CacheListOfItemMetadataFiles(
coll,KIM_COLLECTION_ITEM_TYPE_portableModel,model_name,&extent);
collections, KIM_COLLECTION_ITEM_TYPE_portableModel,
model_name,&extent);
} else if (model_type == SM) {
err = KIM_Collections_CacheListOfItemMetadataFiles(
coll,KIM_COLLECTION_ITEM_TYPE_simulatorModel,model_name,&extent);
collections, KIM_COLLECTION_ITEM_TYPE_simulatorModel,
model_name, &extent);
} else {
error->all(FLERR,"Unknown model type.");
error->all(FLERR,"Unknown model type");
}
if (err) {
KIM_Collections_Destroy(&coll);
KIM_Collections_Destroy(&collections);
return;
}
@ -486,7 +508,8 @@ void KimInit::write_log_cite(char *model_name)
int availableAsString;
char const * fileString;
err = KIM_Collections_GetItemMetadataFile(
coll,i,&fileName,nullptr,nullptr,&availableAsString,&fileString);
collections, i, &fileName, nullptr, nullptr,
&availableAsString, &fileString);
if (err) continue;
if (0 == strncmp("kimcite",fileName,7)) {
@ -494,5 +517,5 @@ void KimInit::write_log_cite(char *model_name)
}
}
KIM_Collections_Destroy(&coll);
KIM_Collections_Destroy(&collections);
}

View File

@ -16,6 +16,7 @@
Ryan S. Elliott (UMN)
Ellad B. Tadmor (UMN)
Ronald Miller (Carleton U)
Yaser Afshar (UMN)
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
@ -87,6 +88,7 @@ void KimInteractions::command(int narg, char **arg)
if (!domain->box_exist)
error->all(FLERR,"Must use 'kim_interactions' command after "
"simulation box is defined");
do_setup(narg,arg);
}
@ -98,7 +100,11 @@ void KimInteractions::do_setup(int narg, char **arg)
if ((narg == 1) && (0 == strcmp("fixed_types",arg[0]))) {
fixed_types = true;
} else if (narg != atom->ntypes) {
error->all(FLERR,"Illegal kim_interactions command");
error->all(FLERR,fmt::format("Illegal kim_interactions command.\nThe "
"LAMMPS simulation has {} atom type(s), but "
"{} chemical species passed to the "
"kim_interactions command",
atom->ntypes, narg));
} else {
fixed_types = false;
}
@ -121,22 +127,20 @@ void KimInteractions::do_setup(int narg, char **arg)
input->write_echo("#=== BEGIN kim_interactions ==================================\n");
if (simulatorModel) {
if (!fixed_types) {
std::string delimiter("");
std::string atom_type_sym_list;
std::string atom_type_num_list;
std::string atom_type_sym_list =
fmt::format("{}", fmt::join(arg, arg + narg, " "));
std::string atom_type_num_list =
fmt::format("{}", species_to_atomic_no(arg[0]));
for (int i = 0; i < narg; i++) {
atom_type_sym_list += delimiter + arg[i];
atom_type_num_list += delimiter + std::to_string(species_to_atomic_no(arg[i]));
delimiter = " ";
}
for (int i = 1; i < narg; ++i)
atom_type_num_list += fmt::format(" {}", species_to_atomic_no(arg[i]));
KIM_SimulatorModel_AddTemplateMap(
simulatorModel,"atom-type-sym-list",atom_type_sym_list.c_str());
simulatorModel, "atom-type-sym-list", atom_type_sym_list.c_str());
KIM_SimulatorModel_AddTemplateMap(
simulatorModel,"atom-type-num-list",atom_type_num_list.c_str());
simulatorModel, "atom-type-num-list", atom_type_num_list.c_str());
KIM_SimulatorModel_CloseTemplateMap(simulatorModel);
// validate species selection
@ -150,14 +154,14 @@ void KimInteractions::do_setup(int narg, char **arg)
for (auto atom_type_sym : utils::split_words(atom_type_sym_list)) {
species_is_supported = false;
if (atom_type_sym == "NULL") continue;
for (int i=0; i < sim_num_species; ++i) {
KIM_SimulatorModel_GetSupportedSpecies(simulatorModel,i,&sim_species);
for (int i = 0; i < sim_num_species; ++i) {
KIM_SimulatorModel_GetSupportedSpecies(
simulatorModel, i, &sim_species);
if (atom_type_sym == sim_species) species_is_supported = true;
}
if (!species_is_supported) {
std::string msg = "Species '";
msg += atom_type_sym + "' is not supported by this KIM Simulator Model";
error->all(FLERR,msg);
error->all(FLERR,fmt::format("Species '{}' is not supported by this "
"KIM Simulator Model", atom_type_sym));
}
}
} else {
@ -169,29 +173,39 @@ void KimInteractions::do_setup(int narg, char **arg)
int sim_fields, sim_lines;
const char *sim_field, *sim_value;
KIM_SimulatorModel_GetNumberOfSimulatorFields(simulatorModel, &sim_fields);
for (int i=0; i < sim_fields; ++i) {
for (int i = 0; i < sim_fields; ++i) {
KIM_SimulatorModel_GetSimulatorFieldMetadata(
simulatorModel,i,&sim_lines,&sim_field);
simulatorModel, i, &sim_lines, &sim_field);
if (0 == strcmp(sim_field,"units")) {
KIM_SimulatorModel_GetSimulatorFieldLine(simulatorModel,i,0,&sim_value);
if (0 != strcmp(sim_value,update->unit_style))
if (strcmp(sim_field,"units") == 0) {
KIM_SimulatorModel_GetSimulatorFieldLine(
simulatorModel, i, 0, &sim_value);
if (strcmp(sim_value,update->unit_style) != 0)
error->all(FLERR,"Incompatible units for KIM Simulator Model");
}
}
int sim_model_idx=-1;
for (int i=0; i < sim_fields; ++i) {
bool no_model_definition = true;
for (int i = 0; i < sim_fields; ++i) {
KIM_SimulatorModel_GetSimulatorFieldMetadata(
simulatorModel,i,&sim_lines,&sim_field);
if (0 == strcmp(sim_field,"model-defn")) {
if (domain->periodicity[0]&&domain->periodicity[1]&&domain->periodicity[2]) input->one("variable kim_periodic equal 1");
else if (domain->periodicity[0]&&domain->periodicity[1]&&!domain->periodicity[2]) input->one("variable kim_periodic equal 2");
else input->one("variable kim_periodic equal 0");
sim_model_idx = i;
for (int j=0; j < sim_lines; ++j) {
simulatorModel, i, &sim_lines, &sim_field);
if (strcmp(sim_field,"model-defn") == 0) {
if (domain->periodicity[0]&&
domain->periodicity[1]&&
domain->periodicity[2])
input->one("variable kim_periodic equal 1");
else if (domain->periodicity[0]&&
domain->periodicity[1]&&
!domain->periodicity[2])
input->one("variable kim_periodic equal 2");
else input->one("variable kim_periodic equal 0");
// KIM Simulator Model has a Model definition
no_model_definition = false;
for (int j = 0; j < sim_lines; ++j) {
KIM_SimulatorModel_GetSimulatorFieldLine(
simulatorModel,sim_model_idx,j,&sim_value);
simulatorModel, i, j, &sim_value);
if (utils::strmatch(sim_value,"^KIM_SET_TYPE_PARAMETERS")) {
// Notes regarding the KIM_SET_TYPE_PARAMETERS command
// * This is an INTERNAL command.
@ -212,7 +226,7 @@ void KimInteractions::do_setup(int narg, char **arg)
}
}
if (sim_model_idx < 0)
if (no_model_definition)
error->all(FLERR,"KIM Simulator Model has no Model definition");
KIM_SimulatorModel_OpenAndInitializeTemplateMap(simulatorModel);
@ -227,14 +241,9 @@ void KimInteractions::do_setup(int narg, char **arg)
// NOTE: all references to arg must appear before calls to input->one()
// as that will reset the argument vector.
std::string cmd1("pair_style kim ");
cmd1 += model_name;
std::string cmd2("pair_coeff * * ");
for (int i=0; i < narg; ++i) {
cmd2 += arg[i];
cmd2 += " ";
}
auto cmd1 = fmt::format("pair_style kim {}", model_name);
auto cmd2 =
fmt::format("pair_coeff * * {}", fmt::join(arg, arg + narg, " "));
input->one(cmd1);
input->one(cmd2);
@ -248,22 +257,25 @@ void KimInteractions::do_setup(int narg, char **arg)
void KimInteractions::KIM_SET_TYPE_PARAMETERS(const std::string &input_line) const
{
int nocomment;
auto words = utils::split_words(input_line);
std::string key = words[1];
const std::string key = words[1];
if (key != "pair" && key != "charge")
error->one(FLERR,fmt::format("Unrecognized KEY {} for "
"KIM_SET_TYPE_PARAMETERS command", key));
std::string filename = words[2];
std::vector<std::string> species(words.begin()+3,words.end());
if ((int)species.size() != atom->ntypes)
error->one(FLERR,"Incorrect args for KIM_SET_TYPE_PARAMETERS command");
FILE *fp;
fp = fopen(filename.c_str(),"r");
if (fp == nullptr) {
error->one(FLERR,"Parameter file not found");
FILE *fp = nullptr;
if (comm->me == 0) {
fp = fopen(filename.c_str(),"r");
if (fp == nullptr) error->one(FLERR,"Parameter file not found");
}
char line[MAXLINE],*ptr;
char line[MAXLINE], *ptr;
int n, eof = 0;
while (1) {
@ -279,27 +291,24 @@ void KimInteractions::KIM_SET_TYPE_PARAMETERS(const std::string &input_line) con
MPI_Bcast(&n,1,MPI_INT,0,world);
MPI_Bcast(line,n,MPI_CHAR,0,world);
nocomment = line[0] != '#';
if (ptr = strchr(line,'#')) *ptr = '\0';
if (strspn(line," \t\n\r") == strlen(line)) continue;
if(nocomment) {
words = utils::split_words(line);
if (key == "pair") {
for (int ia = 0; ia < atom->ntypes; ++ia) {
for (int ib = ia; ib < atom->ntypes; ++ib)
if (((species[ia] == words[0]) && (species[ib] == words[1]))
|| ((species[ib] == words[0]) && (species[ia] == words[1])))
input->one(fmt::format("pair_coeff {} {} {}",ia+1,ib+1,fmt::join(words.begin()+2,words.end()," ")));
}
} else if (key == "charge") {
for (int ia = 0; ia < atom->ntypes; ++ia)
if (species[ia] == words[0])
input->one(fmt::format("set type {} charge {}",ia+1,words[1]));
} else {
error->one(FLERR,"Unrecognized KEY for KIM_SET_TYPE_PARAMETERS command");
words = utils::split_words(line);
if (key == "pair") {
for (int ia = 0; ia < atom->ntypes; ++ia) {
for (int ib = ia; ib < atom->ntypes; ++ib)
if (((species[ia] == words[0]) && (species[ib] == words[1]))
|| ((species[ib] == words[0]) && (species[ia] == words[1])))
input->one(fmt::format("pair_coeff {} {} {}",ia+1,ib+1,
fmt::join(words.begin()+2,words.end()," ")));
}
} else {
for (int ia = 0; ia < atom->ntypes; ++ia)
if (species[ia] == words[0])
input->one(fmt::format("set type {} charge {}",ia+1,words[1]));
}
}
fclose(fp);
}
/* ---------------------------------------------------------------------- */

View File

@ -57,6 +57,7 @@
#include "kim_param.h"
#include "comm.h"
#include "error.h"
#include "fix_store_kim.h"
#include "force.h"
@ -65,8 +66,9 @@
#include "pair_kim.h"
#include "variable.h"
#include <cstdlib>
#include <cstring>
#include <sstream>
#include <vector>
extern "C"
{
@ -118,8 +120,11 @@ void get_kim_unit_names(
chargeUnit = KIM_CHARGE_UNIT_e;
temperatureUnit = KIM_TEMPERATURE_UNIT_K;
timeUnit = KIM_TIME_UNIT_fs;
} else if ((strcmp(system, "lj") == 0)) {
error->all(FLERR, "LAMMPS unit_style lj not supported by KIM models");
} else if (strcmp(system,"lj") == 0 ||
strcmp(system,"micro") ==0 ||
strcmp(system,"nano")==0) {
error->all(FLERR,fmt::format("LAMMPS unit_style {} not supported "
"by KIM models", system));
} else
error->all(FLERR, "Unknown unit_style");
}
@ -240,6 +245,9 @@ void KimParam::command(int narg, char **arg)
&pkim);
if (kim_error)
error->all(FLERR, "Unable to create KIM Portable Model");
auto logID = fmt::format("{}_Model", comm->me);
KIM_Model_SetLogID(pkim, logID.c_str());
}
}
@ -253,7 +261,7 @@ void KimParam::command(int narg, char **arg)
// Parameter name
char *paramname = nullptr;
// Variable name
char *varname = nullptr;
std::string varname;
// Loop over all the arguments
for (int i = 1; i < narg;) {
@ -277,15 +285,13 @@ void KimParam::command(int narg, char **arg)
if (kim_error)
error->all(FLERR, "KIM GetParameterMetadata returned error");
if (strcmp(paramname, str_name) == 0)
break;
if (strcmp(paramname, str_name) == 0) break;
}
if (param_index >= numberOfParameters) {
std::string msg("Wrong argument in kim_param get command.\n");
msg += "This Model does not have the requested '";
msg += paramname;
msg += "' parameter";
auto msg = fmt::format("Wrong argument in kim_param get command.\n"
"This Model does not have the requested '{}' "
"parameter", paramname);
error->all(FLERR, msg);
}
@ -299,60 +305,53 @@ void KimParam::command(int narg, char **arg)
// Check to see if the indices range contains
// only integer numbers and/or range :
if (argtostr.find_first_not_of("0123456789:") != std::string::npos) {
std::string msg("Illegal index_range.\n");
msg += "Expected integer parameter(s) instead of '";
msg += argtostr;
msg += "' in index_range";
auto msg = fmt::format("Illegal index_range.\nExpected integer "
"parameter(s) instead of '{}' in "
"index_range", argtostr);
error->all(FLERR, msg);
}
std::string::size_type npos = argtostr.find(':');
if (npos != std::string::npos) {
argtostr[npos] = ' ';
std::stringstream str(argtostr);
str >> nlbound >> nubound;
auto words = utils::split_words(argtostr);
nlbound = atoi(words[0].c_str());
nubound = atoi(words[1].c_str());
if (nubound < 1 || nubound > extent ||
nlbound < 1 || nlbound > nubound) {
std::string msg("Illegal index_range '");
msg += std::to_string(nlbound) + "-";
msg += std::to_string(nubound) + "' for '";
msg += paramname;
msg += "' parameter with the extent of '";
msg += std::to_string(extent);
msg += "'";
auto msg = fmt::format("Illegal index_range '{}-{}' for '{}' "
"parameter with the extent of '{}'",
nlbound, nubound, paramname, extent);
error->all(FLERR, msg);
}
} else {
std::stringstream str(argtostr);
str >> nlbound;
nlbound = atoi(argtostr.c_str());
if (nlbound < 1 || nlbound > extent) {
std::string msg("Illegal index '");
msg += std::to_string(nlbound) + "' for '";
msg += paramname;
msg += "' parameter with the extent of '";
msg += std::to_string(extent);
msg += "'";
auto msg = fmt::format("Illegal index '{}' for '{}' parameter "
"with the extent of '{}'", nlbound,
paramname, extent);
error->all(FLERR, msg);
}
nubound = nlbound;
}
} else {
std::string msg("Wrong number of arguments in ");
msg += "'kim_param get' command.\n";
msg += "Index range after parameter name is mandatory";
std::string msg("Wrong number of arguments in 'kim_param get' ");
msg += "command.\nIndex range after parameter name is mandatory";
error->all(FLERR, msg);
}
int const nvars = nubound - nlbound + 1;
char **varsname = nullptr;
std::vector<std::string> varsname;
if (i < narg) {
// Get the variable/variable_base name
varname = arg[i++];
} else {
std::string msg("Wrong number of arguments in ");
msg += "'kim_param get' command.\n";
msg += "The LAMMPS variable name is mandatory";
std::string msg("Wrong number of arguments in 'kim_param get' ");
msg += "command.\nThe LAMMPS variable name is mandatory";
error->all(FLERR, msg);
}
@ -362,56 +361,47 @@ void KimParam::command(int narg, char **arg)
if (nvars > 1) {
if (i < narg) {
if (strcmp(arg[i], "split") == 0) {
varsname = new char *[nvars];
varsname.resize(nvars);
for (int j = 0, k = nlbound; j < nvars; ++j, ++k) {
std::stringstream str;
str << varname << "_" << k;
varsname[j] = const_cast<char *>(str.str().c_str());
varsname[j] = fmt::format("{}_{}", varname, k);
}
} else if (strcmp(arg[i], "list") == 0) {
list_requested = true;
varsname = new char *[1];
varsname.resize(1);
varsname[0] = varname;
// Default explicit (optional) formatarg
} else if (i - 1 + nvars < narg) {
varsname = new char *[nvars];
varsname.resize(nvars);
--i;
for (int j = 0; j < nvars; ++j, ++i)
varsname[j] = arg[i];
for (int j = 0; j < nvars; ++j, ++i) varsname[j] = arg[i];
if (i < narg) {
if (strcmp(arg[i], "explicit") == 0)
++i;
if (strcmp(arg[i], "explicit") == 0) ++i;
}
} else {
std::string msg("Wrong number of arguments in ");
msg += "'kim_param get' command.\nThe LAMMPS '";
msg += std::to_string(nvars);
msg += "' variable names or '";
msg += varname;
msg += " split' is mandatory";
auto msg =
fmt::format("Wrong number of arguments in 'kim_param get' "
"command.\nThe LAMMPS '{}' variable names or "
"'{} split' is mandatory", nvars, varname);
error->all(FLERR, msg);
}
} else {
std::string msg("Wrong number of arguments in ");
msg += "'kim_param get' command.\nThe LAMMPS '";
msg += std::to_string(nvars);
msg += "' variable names or '";
msg += varname;
msg += " split/list' is mandatory";
auto msg =
fmt::format("Wrong number of arguments in 'kim_param get' "
"command.\nThe LAMMPS '{}' variable names or "
"'{} split/list' is mandatory", nvars, varname);
error->all(FLERR, msg);
}
} else {
varsname = new char *[1];
varsname.resize(1);
if (i < narg) {
if (strcmp(arg[i], "split") == 0) {
std::stringstream str;
str << varname << "_" << nlbound;
varsname[0] = const_cast<char *>(str.str().c_str());
varsname[0] = fmt::format("{}_{}", varname, nlbound);
++i;
} else {
if ((strcmp(arg[i], "list") == 0) ||
(strcmp(arg[i], "explicit") == 0))
(strcmp(arg[i], "explicit") == 0))
++i;
varsname[0] = varname;
}
} else {
@ -419,98 +409,90 @@ void KimParam::command(int narg, char **arg)
}
}
char **varcmd = new char *[3];
varcmd[1] = const_cast<char *>("string");
if (KIM_DataType_Equal(kim_DataType, KIM_DATA_TYPE_Double)) {
if (list_requested) {
std::stringstream str;
std::string str;
double V;
{
kim_error = KIM_Model_GetParameterDouble(pkim, param_index,
nlbound - 1, &V);
if (kim_error)
error->all(FLERR, "KIM GetParameterDouble returned error");
str << V;
str = fmt::format("{}", V);
}
for (int j = 1; j < nvars; ++j) {
kim_error = KIM_Model_GetParameterDouble(pkim, param_index,
nlbound - 1 + j, &V);
if (kim_error)
error->all(FLERR, "KIM GetParameterDouble returned error");
str << " " << V;
str += fmt::format(" {}", V);
}
varcmd[0] = varsname[0];
varcmd[2] = const_cast<char *>(str.str().c_str());
input->variable->set(3, varcmd);
echo_var_assign(varcmd[0], varcmd[2]);
auto setcmd = fmt::format("{} string {}", varsname[0], str);
input->variable->set(setcmd);
input->write_echo(fmt::format("variable {}\n", setcmd));
} else {
double V;
for (int j = 0; j < nvars; ++j) {
varcmd[0] = varsname[j];
double V;
kim_error = KIM_Model_GetParameterDouble(pkim, param_index,
nlbound - 1 + j, &V);
if (kim_error)
error->all(FLERR, "KIM GetParameterDouble returned error");
std::stringstream str;
str << V;
varcmd[2] = const_cast<char *>(str.str().c_str());
input->variable->set(3, varcmd);
echo_var_assign(varcmd[0], varcmd[2]);
auto setcmd = fmt::format("{} string {}", varsname[j], V);
input->variable->set(setcmd);
input->write_echo(fmt::format("variable {}\n", setcmd));
}
}
} else if (KIM_DataType_Equal(kim_DataType, KIM_DATA_TYPE_Integer)) {
if (list_requested) {
std::stringstream str;
std::string str;
int V;
{
kim_error = KIM_Model_GetParameterInteger(pkim, param_index,
nlbound - 1, &V);
if (kim_error)
error->all(FLERR, "KIM GetParameterInteger returned error");
str << V;
str = fmt::format("{}", V);
}
for (int j = 1; j < nvars; ++j) {
kim_error = KIM_Model_GetParameterInteger(pkim, param_index,
nlbound - 1 + j, &V);
if (kim_error)
error->all(FLERR, "KIM GetParameterInteger returned error");
str << " " << V;
str += fmt::format(" {}", V);
}
varcmd[0] = varsname[0];
varcmd[2] = const_cast<char *>(str.str().c_str());
input->variable->set(3, varcmd);
echo_var_assign(varcmd[0], varcmd[2]);
auto setcmd = fmt::format("{} string {}", varsname[0], str);
input->variable->set(setcmd);
input->write_echo(fmt::format("variable {}\n", setcmd));
} else {
int V;
for (int j = 0; j < nvars; ++j) {
varcmd[0] = varsname[j];
int V;
kim_error = KIM_Model_GetParameterInteger(pkim, param_index,
nlbound - 1 + j, &V);
if (kim_error)
error->all(FLERR, "KIM GetParameterInteger returned error");
std::stringstream str;
str << V;
varcmd[2] = const_cast<char *>(str.str().c_str());
input->variable->set(3, varcmd);
echo_var_assign(varcmd[0], varcmd[2]);
auto setcmd = fmt::format("{} string {}", varsname[j], V);
input->variable->set(setcmd);
input->write_echo(fmt::format("variable {}\n", setcmd));
}
}
} else
error->all(FLERR, "Wrong parameter type");
delete[] varcmd;
delete[] varsname;
} // End of loop over all the arguments
// Set the parameters
} else {
std::string set_cmd("pair_coeff * * ");
set_cmd += atom_type_list;
for (int i = 1; i < narg; ++i) {
set_cmd += " ";
set_cmd += arg[i];
}
input->one(set_cmd);
auto setcmd = fmt::format("pair_coeff * * {} {}", atom_type_list,
fmt::join(arg + 1, arg + narg, " "));
input->one(setcmd);
}
} else
error->all(FLERR, "This model has No mutable parameters");
@ -521,12 +503,3 @@ void KimParam::command(int narg, char **arg)
input->write_echo(fmt::format("#=== END kim-param {} ====================="
"==================\n",kim_param_get_set));
}
/* ---------------------------------------------------------------------- */
void KimParam::echo_var_assign(const std::string &name,
const std::string &value) const
{
input->write_echo(fmt::format("variable {} string {}\n",
name, value));
}

View File

@ -77,9 +77,6 @@ public:
~KimParam();
void command(int, char **);
private:
void echo_var_assign(const std::string &name, const std::string &value) const;
};
} // namespace LAMMPS_NS

View File

@ -100,11 +100,7 @@ void kimProperty::command(int narg, char **arg)
error->all(FLERR, msg);
}
if (comm->me == 0) {
std::string msg;
msg = "#=== kim-property ===========================================\n";
input->write_echo(msg);
}
input->write_echo("#=== kim-property ===========================================\n");
// Get the kim_str ptr to the data associated with a kim_property_str
// variable

View File

@ -63,11 +63,15 @@
#include "info.h"
#include "input.h"
#include "modify.h"
#include "utils.h"
#include "variable.h"
#include "version.h"
#include "tokenizer.h"
#include "fmt/format.h"
#include <cstdlib>
#include <cstring>
#include <sstream>
#include <string>
#if defined(LMP_KIM_CURL)
#include <sys/types.h>
@ -92,26 +96,28 @@ static size_t write_callback(void *, size_t, size_t, void *);
void KimQuery::command(int narg, char **arg)
{
char *varname, *function, *value;
if (narg < 2) error->all(FLERR,"Illegal kim_query command");
// check if we had a kim_init command by finding fix STORE/KIM
// retrieve model name.
char * model_name;
char *model_name;
int ifix = modify->find_fix("KIM_MODEL_STORE");
const int ifix = modify->find_fix("KIM_MODEL_STORE");
if (ifix >= 0) {
FixStoreKIM *fix_store = (FixStoreKIM *) modify->fix[ifix];
model_name = (char *)fix_store->getptr("model_name");
} else error->all(FLERR,"Must use 'kim_init' before 'kim_query'");
varname = arg[0];
char *varname = arg[0];
bool split = false;
if (0 == strcmp("split",arg[1])) {
if (narg == 2) error->all(FLERR,"Illegal kim_query command");
if (0 == strcmp("list",arg[2]))
error->all(FLERR,"Illegal kim_query command");
if (strcmp("split",arg[1]) == 0) {
if (narg == 2) error->all(FLERR,"Illegal kim_query command.\nThe keyword "
"'split' must be followed by the name of "
"the query function");
if (strcmp("list",arg[2]) == 0)
error->all(FLERR,"Illegal kim_query command.\nThe 'list' keyword "
"can not be used after 'split'");
split = true;
arg++;
narg--;
@ -119,78 +125,69 @@ void KimQuery::command(int narg, char **arg)
// The “list” is the default setting
// the result is returned as a space-separated list of values in variable
if (0 == strcmp("list",arg[1])) {
if (narg == 2) error->all(FLERR,"Illegal kim_query command");
if (split) error->all(FLERR,"Illegal kim_query command");
if (strcmp("list",arg[1]) == 0) {
if (narg == 2) error->all(FLERR,"Illegal kim_query command.\nThe 'list' "
"keyword must be followed by ('split' "
"and) the name of the query function");
arg++;
narg--;
}
function = arg[1];
for (int i = 2; i < narg; ++i) {
if (0 == strncmp("model=",arg[i], 6)) {
error->all(FLERR,"Illegal 'model' key in kim_query command");
}
}
char *function = arg[1];
for (int i = 2; i < narg; ++i) {
if (strncmp("model=",arg[i],6) == 0)
error->all(FLERR,"Illegal 'model' key in kim_query command");
if (!strchr(arg[i], '=') || !strchr(arg[i], '[') || !strchr(arg[i], ']'))
error->all(FLERR,fmt::format("Illegal query format.\nInput argument of "
"`{}` to kim_query is wrong. The query "
"format is the keyword=[value], where value "
"is always an array of one or more "
"comma-separated items", arg[i]));
}
#if defined(LMP_KIM_CURL)
value = do_query(function, model_name, narg-2, arg+2, comm->me, world);
char *value = do_query(function, model_name, narg-2, arg+2, comm->me, world);
// check for valid result
// on error the content of "value" is a '\0' byte
// as the first element, and then the error message
// that was returned by the web server
char errmsg[1024];
if (0 == strlen(value)) {
sprintf(errmsg,"OpenKIM query failed: %s",value+1);
error->all(FLERR,errmsg);
} else if (0 == strcmp(value,"EMPTY")) {
sprintf(errmsg,"OpenKIM query returned no results");
error->all(FLERR,errmsg);
if (strlen(value) == 0) {
error->all(FLERR,fmt::format("OpenKIM query failed: {}", value+1));
} else if (strcmp(value,"EMPTY") == 0) {
error->all(FLERR,fmt::format("OpenKIM query returned no results"));
}
input->write_echo("#=== BEGIN kim-query =========================================\n");
char **varcmd = new char*[3];
varcmd[1] = (char *) "string";
std::stringstream ss(value);
std::string token;
ValueTokenizer values(value, ",");
if (split) {
int counter = 1;
while(std::getline(ss, token, ',')) {
token.erase(0,token.find_first_not_of(" \n\r\t")); // ltrim
token.erase(token.find_last_not_of(" \n\r\t") + 1); // rtrim
std::stringstream splitname;
splitname << varname << "_" << counter++;
varcmd[0] = const_cast<char *>(splitname.str().c_str());
varcmd[2] = const_cast<char *>(token.c_str());
input->variable->set(3,varcmd);
echo_var_assign(splitname.str(), varcmd[2]);
while (values.has_next()) {
auto svalue = values.next_string();
auto setcmd = fmt::format("{}_{} string {}", varname, counter++, svalue);
input->variable->set(setcmd);
input->write_echo(fmt::format("variable {}\n", setcmd));
}
} else {
varcmd[0] = varname;
std::string value_string;
while(std::getline(ss, token, ',')) {
token.erase(0,token.find_first_not_of(" \n\r\t")); // ltrim
token.erase(token.find_last_not_of(" \n\r\t") + 1); // rtrim
if (value_string.size() && token.size())
value_string += " ";
value_string += token;
auto svalue = values.next_string();
std::string setcmd = fmt::format("{} string \"{}", varname, svalue);
while (values.has_next()) {
svalue = values.next_string();
setcmd += fmt::format(" {}", svalue);
}
varcmd[2] = const_cast<char *>(value_string.c_str());;
input->variable->set(3,varcmd);
echo_var_assign(varname, value_string);
setcmd += "\"";
input->variable->set(setcmd);
input->write_echo(fmt::format("variable {}\n", setcmd));
}
input->write_echo("#=== END kim-query ===========================================\n\n");
delete[] varcmd;
delete[] value;
#else
error->all(FLERR,"Cannot use 'kim_query' command when KIM package "
"is compiled without support for libcurl");
"is compiled without support for libcurl");
#endif
}
@ -201,17 +198,18 @@ void KimQuery::command(int narg, char **arg)
size_t write_callback(void *data, size_t size, size_t nmemb, void *userp)
{
struct WriteBuf *buf = (struct WriteBuf *)userp;
size_t buffer_size = size*nmemb;
// copy chunks into the buffer for as long as there is space left
if (buf->sizeleft) {
size_t copy_this_much = buf->sizeleft;
if (copy_this_much > buffer_size)
copy_this_much = buffer_size;
const size_t buffer_size = size * nmemb;
const size_t copy_this_much =
buf->sizeleft > buffer_size ? buffer_size : buf->sizeleft;
memcpy(buf->dataptr, data, copy_this_much);
buf->dataptr += copy_this_much;
buf->sizeleft -= copy_this_much;
return copy_this_much;
}
return 0; // done
@ -220,16 +218,12 @@ size_t write_callback(void *data, size_t size, size_t nmemb, void *userp)
char *do_query(char *qfunction, char * model_name, int narg, char **arg,
int rank, MPI_Comm comm)
{
char value[512], *retval;
char value[512];
// run the web query from rank 0 only
if (rank == 0) {
CURL *handle;
CURLcode res;
// set up and clear receive buffer
struct WriteBuf buf;
buf.dataptr = value;
buf.sizeleft = 511;
@ -237,19 +231,43 @@ char *do_query(char *qfunction, char * model_name, int narg, char **arg,
// create curl web query instance
curl_global_init(CURL_GLOBAL_DEFAULT);
handle = curl_easy_init();
CURL *handle = curl_easy_init();
if (handle) {
std::string url("https://query.openkim.org/api/");
url += qfunction;
std::string query(arg[0]);
query += "&model=[\"";
query += model_name;
query += "\"]";
for (int i=1; i < narg; ++i) {
query += '&';
query += arg[i];
auto url = fmt::format("https://query.openkim.org/api/{}", qfunction);
auto query = fmt::format("model=[\"{}\"]", model_name);
for (int i = 0; i < narg; ++i) {
ValueTokenizer values(arg[i], "=[]");
std::string key = values.next_string();
std::string val = values.next_string();
std::string::size_type n = val.find(",");
if (n == std::string::npos) {
if (utils::is_integer(val) ||
utils::is_double(val) ||
(val.front() == '"' &&
val.back() == '"')) {
query += fmt::format("&{}", arg[i]);
} else {
query += fmt::format("&{}=[\"{}\"]", key, val);
}
} else {
query += fmt::format("&{}=[", key);
while (n != std::string::npos){
std::string sval = val.substr(0, n);
if (utils::is_integer(sval) ||
utils::is_double(sval) ||
(val.front() == '"' &&
val.back() == '"')) {
query += fmt::format("{},", sval);
} else {
query += fmt::format("\"{}\",", sval);
}
val = val.substr(n + 1);
n = val.find(",");
}
if (val.size()) query += fmt::format("\"{}\"]", val);
else query[query.size() - 1]=']';
}
}
#if LMP_DEBUG_CURL
@ -274,23 +292,21 @@ char *do_query(char *qfunction, char * model_name, int narg, char **arg,
}
}
std::string user_agent = std::string("kim_query--LAMMPS/")
+ LAMMPS_VERSION
+ " (" + Info::get_os_info() + ")";
std::string user_agent = fmt::format("kim_query--LAMMPS/{} ({})",
LAMMPS_VERSION, Info::get_os_info());
curl_easy_setopt(handle, CURLOPT_USERAGENT, user_agent.c_str());
curl_easy_setopt(handle, CURLOPT_URL, url.c_str());
curl_easy_setopt(handle, CURLOPT_FOLLOWLOCATION, 1L);
curl_easy_setopt(handle, CURLOPT_POSTFIELDS, query.c_str());
curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION,write_callback);
curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, write_callback);
curl_easy_setopt(handle, CURLOPT_WRITEDATA,&buf);
// perform OpenKIM query and check for errors
res = curl_easy_perform(handle);
CURLcode res = curl_easy_perform(handle);
if (res != CURLE_OK) {
// on error we return an "empty" string but add error message after it
value[0]= '\0';
value[0] = '\0';
strcpy(value+1,curl_easy_strerror(res));
}
curl_easy_cleanup(handle);
@ -302,30 +318,31 @@ char *do_query(char *qfunction, char * model_name, int narg, char **arg,
// we must make a proper copy of the query, as the stack allocation
// for "value" will go out of scope. a valid query has a '[' as
// the first character. skip over it (and the last character ']', too)
// an error messages starts with a '\0' character. copy that and
// an error message starts with a '\0' character. copy that and
// the remaining string, as that is the error message.
char *retval;
// a valid query has a '[' as the first character
if (value[0] == '[') {
int len = strlen(value)-1;
int len = strlen(value) - 1;
if (value[len] == ']') {
retval = new char[len];
value[len] = '\0';
if (0 == strcmp(value+1, "")) {
strcpy(retval,"EMPTY");
} else
strcpy(retval,value+1);
retval = new char[len];
if (strcmp(value+1, "") == 0) strcpy(retval,"EMPTY");
else strcpy(retval,value+1);
} else {
retval = new char[len+2];
retval[0] = '\0';
strcpy(retval+1,value);
}
// an error message starts with a '\0' character
} else if (value[0] == '\0') {
int len = strlen(value+1)+2;
retval = new char[len];
retval[0] = '\0';
strcpy(retval+1,value+1);
// unknown response type. we should not get here.
} else {
// unknown response type. we should not get here.
// we return an "empty" string but add error message after it
int len = strlen(value)+2;
retval = new char[len];
@ -335,11 +352,3 @@ char *do_query(char *qfunction, char * model_name, int narg, char **arg,
return retval;
}
#endif
/* ---------------------------------------------------------------------- */
void KimQuery::echo_var_assign(const std::string &name,
const std::string &value) const
{
input->write_echo(fmt::format("variable {} string {}\n",name,value));
}

View File

@ -13,7 +13,8 @@
/* ----------------------------------------------------------------------
Contributing authors: Axel Kohlmeyer (Temple U),
Ryan S. Elliott (UMN)
Ryan S. Elliott (UMN),
Yaser Afshar (UMN)
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
@ -71,9 +72,6 @@ class KimQuery : protected Pointers {
public:
KimQuery(class LAMMPS *lmp) : Pointers(lmp) {};
void command(int, char **);
private:
void echo_var_assign(const std::string &name, const std::string &value)
const;
};
}

View File

@ -67,8 +67,9 @@
#include "neighbor.h"
#include "update.h"
#include <cstdlib>
#include <cstring>
#include <sstream>
#include <vector>
using namespace LAMMPS_NS;
@ -204,8 +205,8 @@ void PairKIM::compute(int eflag, int vflag)
KIM_COMPUTE_ARGUMENT_NAME_particleContributing,
kim_particleContributing);
if (kimerror)
error->all(FLERR,
"Unable to set KIM particle species codes and/or contributing");
error->all(FLERR,"Unable to set KIM particle species "
"codes and/or contributing");
}
// kim_particleSpecies = KIM atom species for each LAMMPS atom
@ -339,7 +340,9 @@ void PairKIM::coeff(int narg, char **arg)
// insure I,J args are * *
if (strcmp(arg[0],"*") != 0 || strcmp(arg[1],"*") != 0)
error->all(FLERR,"Incorrect args for pair coefficients");
error->all(FLERR,"Incorrect args for pair coefficients.\nThe first two "
"arguments of pair_coeff command must be * * to span "
"all LAMMPS atom types");
int ilo,ihi,jlo,jhi;
utils::bounds(FLERR,arg[0],1,atom->ntypes,ilo,ihi,error);
@ -410,9 +413,8 @@ void PairKIM::coeff(int narg, char **arg)
if (supported) {
kim_particle_codes[i] = code;
} else {
std::string msg("create_kim_particle_codes: symbol not found: ");
msg += lmps_unique_elements[i];
error->all(FLERR, msg);
error->all(FLERR,fmt::format("GetSpeciesSupportAndCode: symbol not "
"found: {}",lmps_unique_elements[i]));
}
}
// Set the new values for PM parameters
@ -421,11 +423,9 @@ void PairKIM::coeff(int narg, char **arg)
int numberOfParameters(0);
KIM_Model_GetNumberOfParameters(pkim, &numberOfParameters);
if (!numberOfParameters) {
std::string msg("Incorrect args for pair coefficients \n");
msg += "This model has No mutable parameters";
error->all(FLERR, msg);
}
if (!numberOfParameters)
error->all(FLERR,"Incorrect args for pair coefficients\n"
"This model has No mutable parameters");
int kimerror;
@ -456,11 +456,10 @@ void PairKIM::coeff(int narg, char **arg)
}
if (param_index >= numberOfParameters) {
std::string msg("Wrong argument for pair coefficients.\n");
msg += "This Model does not have the requested '";
msg += paramname;
msg += "' parameter";
error->all(FLERR, msg);
auto msg = fmt::format("Wrong argument for pair coefficients.\n"
"This Model does not have the requested "
"'{}' parameter", paramname);
error->all(FLERR,msg);
}
// Get the index_range for the requested parameter
@ -472,48 +471,41 @@ void PairKIM::coeff(int narg, char **arg)
// Check to see if the indices range contains only integer numbers & :
if (argtostr.find_first_not_of("0123456789:") != std::string::npos) {
std::string msg("Illegal index_range.\n");
msg += "Expected integer parameter(s) instead of '";
msg += argtostr;
msg += "' in index_range";
error->all(FLERR, msg);
auto msg = fmt::format("Illegal index_range.\nExpected integer "
"parameter(s) instead of '{}' in "
"index_range", argtostr);
error->all(FLERR,msg);
}
std::string::size_type npos = argtostr.find(':');
if (npos != std::string::npos) {
argtostr[npos] = ' ';
std::stringstream str(argtostr);
str >> nlbound >> nubound;
auto words = utils::split_words(argtostr);
nlbound = atoi(words[0].c_str());
nubound = atoi(words[1].c_str());
if (nubound < 1 || nubound > extent ||
nlbound < 1 || nlbound > nubound) {
std::string msg("Illegal index_range '");
msg += std::to_string(nlbound) + "-" ;
msg += std::to_string(nubound) + "' for '";
msg += paramname;
msg += "' parameter with the extent of '";
msg += std::to_string(extent);
msg += "'";
error->all(FLERR, msg);
auto msg = fmt::format("Illegal index_range '{}-{}' for '{}' "
"parameter with the extent of '{}'",
nlbound, nubound, paramname, extent);
error->all(FLERR,msg);
}
} else {
std::stringstream str(argtostr);
str >> nlbound;
nlbound = atoi(argtostr.c_str());
if (nlbound < 1 || nlbound > extent) {
std::string msg("Illegal index '");
msg += std::to_string(nlbound) + "' for '";
msg += paramname;
msg += "' parameter with the extent of '";
msg += std::to_string(extent);
msg += "'";
error->all(FLERR, msg);
auto msg = fmt::format("Illegal index '{}' for '{}' parameter "
"with the extent of '{}'", nlbound,
paramname, extent);
error->all(FLERR,msg);
}
nubound = nlbound;
}
} else {
std::string msg =
"Wrong number of arguments for pair coefficients.\n";
msg += "Index range after parameter name is mandatory";
error->all(FLERR, msg);
error->all(FLERR,"Wrong number of arguments for pair coefficients.\n"
"Index range after parameter name is mandatory");
}
// Parameter values
@ -524,7 +516,7 @@ void PairKIM::coeff(int narg, char **arg)
kimerror = KIM_Model_SetParameterDouble(pkim, param_index,
nlbound - 1 + j, V);
if (kimerror)
error->all(FLERR, "KIM SetParameterDouble returned error");
error->all(FLERR,"KIM SetParameterDouble returned error");
}
} else if (KIM_DataType_Equal(kim_DataType, KIM_DATA_TYPE_Integer)) {
for (int j = 0; j < nubound - nlbound + 1; ++j) {
@ -532,25 +524,22 @@ void PairKIM::coeff(int narg, char **arg)
kimerror = KIM_Model_SetParameterInteger(pkim, param_index,
nlbound - 1 + j, V);
if (kimerror)
error->all(FLERR, "KIM SetParameterInteger returned error");
error->all(FLERR,"KIM SetParameterInteger returned error");
}
} else
error->all(FLERR, "Wrong parameter type to update");
error->all(FLERR,"Wrong parameter type to update");
} else {
std::string msg =
"Wrong number of variable values for pair coefficients.\n";
msg += "'";
msg += std::to_string(nubound - nlbound + 1);
msg += "' values are requested for '";
msg += paramname;
msg += "' parameter.";
error->all(FLERR, msg);
auto msg = fmt::format("Wrong number of variable values for pair "
"coefficients.\n'{}' values are requested "
"for '{}' parameter", nubound - nlbound + 1,
paramname);
error->all(FLERR,msg);
}
}
kimerror = KIM_Model_ClearThenRefresh(pkim);
if (kimerror)
error->all(FLERR, "KIM KIM_Model_ClearThenRefresh returned error");
error->all(FLERR,"KIM KIM_Model_ClearThenRefresh returned error");
}
}
@ -842,11 +831,13 @@ void PairKIM::kim_init()
else if (!requestedUnitsAccepted)
error->all(FLERR,"KIM Model did not accept the requested unit system");
auto logID = fmt::format("{}_Model", comm->me);
KIM_Model_SetLogID(pkim, logID.c_str());
// check that the model does not require unknown capabilities
kimerror = check_for_routine_compatibility();
if (kimerror)
error->all(FLERR,
"KIM Model requires unknown Routines. Unable to proceed");
error->all(FLERR,"KIM Model requires unknown Routines. Unable to proceed");
kimerror = KIM_Model_ComputeArgumentsCreate(pkim, &pargs);
if (kimerror) {
@ -854,6 +845,9 @@ void PairKIM::kim_init()
error->all(FLERR,"KIM ComputeArgumentsCreate failed");
} else kim_init_ok = true;
logID = fmt::format("{}_ComputeArguments", comm->me);
KIM_ComputeArguments_SetLogID(pargs, logID.c_str());
// determine KIM Model capabilities (used in this function below)
set_kim_model_has_flags();
@ -985,43 +979,46 @@ void PairKIM::set_lmps_flags()
error->all(FLERR,"pair_kim does not support hybrid");
// determine unit system and set lmps_units flag
if ((strcmp(update->unit_style,"real")==0)) {
if (strcmp(update->unit_style,"real") == 0) {
lmps_units = REAL;
lengthUnit = KIM_LENGTH_UNIT_A;
energyUnit = KIM_ENERGY_UNIT_kcal_mol;
chargeUnit = KIM_CHARGE_UNIT_e;
temperatureUnit = KIM_TEMPERATURE_UNIT_K;
timeUnit = KIM_TIME_UNIT_fs;
} else if ((strcmp(update->unit_style,"metal")==0)) {
} else if (strcmp(update->unit_style,"metal") == 0) {
lmps_units = METAL;
lengthUnit = KIM_LENGTH_UNIT_A;
energyUnit = KIM_ENERGY_UNIT_eV;
chargeUnit = KIM_CHARGE_UNIT_e;
temperatureUnit = KIM_TEMPERATURE_UNIT_K;
timeUnit = KIM_TIME_UNIT_ps;
} else if ((strcmp(update->unit_style,"si")==0)) {
} else if (strcmp(update->unit_style,"si") == 0) {
lmps_units = SI;
lengthUnit = KIM_LENGTH_UNIT_m;
energyUnit = KIM_ENERGY_UNIT_J;
chargeUnit = KIM_CHARGE_UNIT_C;
temperatureUnit = KIM_TEMPERATURE_UNIT_K;
timeUnit = KIM_TIME_UNIT_s;
} else if ((strcmp(update->unit_style,"cgs")==0)) {
} else if (strcmp(update->unit_style,"cgs") == 0) {
lmps_units = CGS;
lengthUnit = KIM_LENGTH_UNIT_cm;
energyUnit = KIM_ENERGY_UNIT_erg;
chargeUnit = KIM_CHARGE_UNIT_statC;
temperatureUnit = KIM_TEMPERATURE_UNIT_K;
timeUnit = KIM_TIME_UNIT_s;
} else if ((strcmp(update->unit_style,"electron")==0)) {
} else if (strcmp(update->unit_style,"electron") == 0) {
lmps_units = ELECTRON;
lengthUnit = KIM_LENGTH_UNIT_Bohr;
energyUnit = KIM_ENERGY_UNIT_Hartree;
chargeUnit = KIM_CHARGE_UNIT_e;
temperatureUnit = KIM_TEMPERATURE_UNIT_K;
timeUnit = KIM_TIME_UNIT_fs;
} else if ((strcmp(update->unit_style,"lj")==0)) {
error->all(FLERR,"LAMMPS unit_style lj not supported by KIM models");
} else if (strcmp(update->unit_style,"lj") == 0 ||
strcmp(update->unit_style,"micro") == 0 ||
strcmp(update->unit_style,"nano") == 0) {
error->all(FLERR,fmt::format("LAMMPS unit_style {} not supported "
"by KIM models", update->unit_style));
} else {
error->all(FLERR,"Unknown unit_style");
}
@ -1102,29 +1099,33 @@ void PairKIM::set_kim_model_has_flags()
KIM_SUPPORT_STATUS_required)) {
std::string msg("KIM Model requires unsupported compute argument: ");
msg += KIM_ComputeArgumentName_ToString(computeArgumentName);
error->all(FLERR, msg);
error->all(FLERR,msg);
}
}
if (KIM_SupportStatus_Equal(kim_model_support_for_energy,
KIM_SUPPORT_STATUS_notSupported))
error->warning(FLERR,"KIM Model does not provide `partialEnergy'; "
"Potential energy will be zero");
if (comm->me == 0) {
if (KIM_SupportStatus_Equal(kim_model_support_for_energy,
KIM_SUPPORT_STATUS_notSupported))
error->warning(FLERR,"KIM Model does not provide 'partialEnergy'; "
"Potential energy will be zero");
if (KIM_SupportStatus_Equal(kim_model_support_for_forces,
KIM_SUPPORT_STATUS_notSupported))
error->warning(FLERR,"KIM Model does not provide `partialForce'; "
"Forces will be zero");
if (KIM_SupportStatus_Equal(kim_model_support_for_forces,
KIM_SUPPORT_STATUS_notSupported))
error->warning(FLERR,"KIM Model does not provide 'partialForce'; "
"Forces will be zero");
if (KIM_SupportStatus_Equal(kim_model_support_for_particleEnergy,
KIM_SUPPORT_STATUS_notSupported))
error->warning(FLERR,"KIM Model does not provide `partialParticleEnergy'; "
"energy per atom will be zero");
if (KIM_SupportStatus_Equal(kim_model_support_for_particleEnergy,
KIM_SUPPORT_STATUS_notSupported))
error->warning(FLERR,"KIM Model does not provide "
"'partialParticleEnergy'; "
"energy per atom will be zero");
if (KIM_SupportStatus_Equal(kim_model_support_for_particleVirial,
KIM_SUPPORT_STATUS_notSupported))
error->warning(FLERR,"KIM Model does not provide `partialParticleVirial'; "
"virial per atom will be zero");
if (KIM_SupportStatus_Equal(kim_model_support_for_particleVirial,
KIM_SUPPORT_STATUS_notSupported))
error->warning(FLERR,"KIM Model does not provide "
"'partialParticleVirial'; "
"virial per atom will be zero");
}
int numberOfComputeCallbackNames;
KIM_COMPUTE_CALLBACK_NAME_GetNumberOfComputeCallbackNames(

View File

@ -17,6 +17,7 @@
#include "lammps.h"
#include "lmppython.h"
#include "modify.h"
#include "output.h"
#include "utils.h"
#include "variable.h"
#include "gmock/gmock.h"
@ -82,17 +83,24 @@ TEST_F(KimCommandsTest, kim_init)
{
if (!LAMMPS::is_installed_pkg("KIM")) GTEST_SKIP();
TEST_FAILURE(".*ERROR: Illegal kim_init command.*", lmp->input->one("kim_init"););
TEST_FAILURE(".*ERROR: Illegal kim_init command.*",
lmp->input->one("kim_init"););
TEST_FAILURE(".*ERROR: Illegal kim_init command.*",
lmp->input->one("kim_init LennardJones_Ar real si"););
TEST_FAILURE(".*ERROR: LAMMPS unit_style lj not supported by KIM models.*",
lmp->input->one("kim_init LennardJones_Ar lj"););
TEST_FAILURE(".*ERROR: LAMMPS unit_style micro not supported by KIM models.*",
lmp->input->one("kim_init LennardJones_Ar micro"););
TEST_FAILURE(".*ERROR: LAMMPS unit_style nano not supported by KIM models.*",
lmp->input->one("kim_init LennardJones_Ar nano"););
TEST_FAILURE(".*ERROR: Unknown unit_style.*",
lmp->input->one("kim_init LennardJones_Ar new_style"););
TEST_FAILURE(".*ERROR: KIM Model name not found.*",
lmp->input->one("kim_init Unknown_Model real"););
TEST_FAILURE(".*ERROR: Incompatible units for KIM Simulator Model, required units = metal.*",
lmp->input->one("kim_init Sim_LAMMPS_LJcut_AkersonElliott_Alchemy_PbAu real"););
// TEST_FAILURE(".*ERROR: KIM Model does not support the requested unit system.*",
// lmp->input->one("kim_init ex_model_Ar_P_Morse real"););
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("kim_init LennardJones_Ar real");
@ -125,6 +133,17 @@ TEST_F(KimCommandsTest, kim_interactions)
lmp->input->one("create_atoms 1 box");
if (!verbose) ::testing::internal::GetCapturedStdout();
TEST_FAILURE(".*ERROR: Illegal kim_interactions command.*",
lmp->input->one("kim_interactions Ar Ar"););
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("clear");
lmp->input->one("lattice fcc 4.4300");
lmp->input->one("region box block 0 20 0 20 0 20");
lmp->input->one("create_box 4 box");
lmp->input->one("create_atoms 4 box");
if (!verbose) ::testing::internal::GetCapturedStdout();
TEST_FAILURE(".*ERROR: Illegal kim_interactions command.*",
lmp->input->one("kim_interactions Ar Ar"););
@ -172,6 +191,21 @@ TEST_F(KimCommandsTest, kim_interactions)
TEST_FAILURE(".*ERROR: Species 'Ar' is not supported by this KIM Simulator Model.*",
lmp->input->one("kim_interactions Ar"););
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("clear");
lmp->input->one("kim_init Sim_LAMMPS_LJcut_AkersonElliott_Alchemy_PbAu metal");
lmp->input->one("lattice fcc 4.08");
lmp->input->one("region box block 0 10 0 10 0 10");
lmp->input->one("create_box 1 box");
lmp->input->one("create_atoms 1 box");
lmp->input->one("kim_interactions Au");
if (!verbose) ::testing::internal::GetCapturedStdout();
// ASSERT_EQ(lmp->output->var_kim_periodic, 1);
// TEST_FAILURE(".*ERROR: Incompatible units for KIM Simulator Model.*",
// lmp->input->one("kim_interactions Au"););
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("clear");
lmp->input->one("kim_init LennardJones_Ar real");
@ -302,6 +336,133 @@ TEST_F(KimCommandsTest, kim_property)
}
}
TEST_F(KimCommandsTest, kim_query)
{
if (!LAMMPS::is_installed_pkg("KIM")) GTEST_SKIP();
TEST_FAILURE(".*ERROR: Illegal kim_query command.*",
lmp->input->one("kim_query"););
TEST_FAILURE(".*ERROR: Must use 'kim_init' before 'kim_query'.*",
lmp->input->one("kim_query a0 get_lattice_constant_cubic"););
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("clear");
lmp->input->one("kim_init LennardJones612_UniversalShifted__MO_959249795837_003 real");
if (!verbose) ::testing::internal::GetCapturedStdout();
TEST_FAILURE(".*ERROR: Illegal kim_query command.\nThe keyword 'split' "
"must be followed by the name of the query function.*",
lmp->input->one("kim_query a0 split"););
TEST_FAILURE(".*ERROR: Illegal kim_query command.\nThe 'list' keyword "
"can not be used after 'split'.*",
lmp->input->one("kim_query a0 split list"););
TEST_FAILURE(".*ERROR: Illegal kim_query command.\nThe 'list' keyword "
"must be followed by \\('split' and\\) the name of the query "
"function.*", lmp->input->one("kim_query a0 list"););
TEST_FAILURE(".*ERROR: Illegal 'model' key in kim_query command.*",
lmp->input->one("kim_query a0 get_lattice_constant_cubic "
"model=[MO_959249795837_003]"););
TEST_FAILURE(".*ERROR: Illegal query format.\nInput argument of `crystal` "
"to kim_query is wrong. The query format is the "
"keyword=\\[value\\], where value is always an array of one "
"or more comma-separated items.*",
lmp->input->one("kim_query a0 get_lattice_constant_cubic "
"crystal"););
TEST_FAILURE(".*ERROR: Illegal query format.\nInput argument of `"
"crystal=fcc` to kim_query is wrong. The query format is the "
"keyword=\\[value\\], where value is always an array of one "
"or more comma-separated items.*",
lmp->input->one("kim_query a0 get_lattice_constant_cubic "
"crystal=fcc"););
TEST_FAILURE(".*ERROR: Illegal query format.\nInput argument of `"
"crystal=\\[fcc` to kim_query is wrong. The query format is "
"the keyword=\\[value\\], where value is always an array of "
"one or more comma-separated items.*",
lmp->input->one("kim_query a0 get_lattice_constant_cubic "
"crystal=[fcc"););
TEST_FAILURE(".*ERROR: Illegal query format.\nInput argument of `"
"crystal=fcc\\]` to kim_query is wrong. The query format is "
"the keyword=\\[value\\], where value is always an array of "
"one or more comma-separated items.*",
lmp->input->one("kim_query a0 get_lattice_constant_cubic "
"crystal=fcc]"););
std::string squery("kim_query a0 get_lattice_constant_cubic ");
squery += "crystal=[\"fcc\"] species=\"Al\",\"Ni\" units=[\"angstrom\"]";
TEST_FAILURE(".*ERROR: Illegal query format.\nInput argument of `species="
"\"Al\",\"Ni\"` to kim_query is wrong. The query format is "
"the keyword=\\[value\\], where value is always an array of "
"one or more comma-separated items.*",
lmp->input->one(squery););
squery = "kim_query a0 get_lattice_constant_cubic ";
squery += "crystal=[\"fcc\"] species=\"Al\",\"Ni\", units=[\"angstrom\"]";
TEST_FAILURE(".*ERROR: Illegal query format.\nInput argument of `species="
"\"Al\",\"Ni\",` to kim_query is wrong. The query format is "
"the keyword=\\[value\\], where value is always an array of "
"one or more comma-separated items.*",
lmp->input->one(squery););
squery = "kim_query a0 get_lattice_constant_cubic crystal=[fcc] "
"species=[Al]";
TEST_FAILURE(".*ERROR: OpenKIM query failed:.*", lmp->input->one(squery););
squery = "kim_query a0 get_lattice_constant_cubic crystal=[fcc] "
"units=[\"angstrom\"]";
TEST_FAILURE(".*ERROR: OpenKIM query failed:.*", lmp->input->one(squery););
// if (!verbose) ::testing::internal::CaptureStdout();
// lmp->input->one("clear");
// lmp->input->one("kim_init EAM_Dynamo_Mendelev_2007_Zr__MO_848899341753_000 metal");
// squery = "kim_query latconst split get_lattice_constant_hexagonal ";
// squery += "crystal=[\"hcp\"] species=[\"Zr\"] units=[\"angstrom\"]";
// lmp->input->one(squery);
// if (!verbose) ::testing::internal::GetCapturedStdout();
// ASSERT_TRUE((std::string(lmp->input->variable->retrieve("latconst_1")) ==
// std::string("3.234055244384789")));
// ASSERT_TRUE((std::string(lmp->input->variable->retrieve("latconst_2")) ==
// std::string("5.167650199630013")));
// if (!verbose) ::testing::internal::CaptureStdout();
// lmp->input->one("clear");
// lmp->input->one("kim_init EAM_Dynamo_Mendelev_2007_Zr__MO_848899341753_000 metal");
// squery = "kim_query latconst list get_lattice_constant_hexagonal ";
// squery += "crystal=[hcp] species=[Zr] units=[angstrom]";
// lmp->input->one(squery);
// if (!verbose) ::testing::internal::GetCapturedStdout();
// ASSERT_TRUE((std::string(lmp->input->variable->retrieve("latconst")) ==
// std::string("3.234055244384789 5.167650199630013")));
// squery = "kim_query latconst list get_lattice_constant_hexagonal ";
// squery += "crystal=[bcc] species=[Zr] units=[angstrom]";
// TEST_FAILURE(".*ERROR: OpenKIM query failed:.*", lmp->input->one(squery););
// if (!verbose) ::testing::internal::CaptureStdout();
// lmp->input->one("clear");
// lmp->input->one("kim_init EAM_Dynamo_ErcolessiAdams_1994_Al__MO_123629422045_005 metal");
// squery = "kim_query alpha get_linear_thermal_expansion_coefficient_cubic ";
// squery += "crystal=[fcc] species=[Al] units=[1/K] temperature=[293.15] ";
// squery += "temperature_units=[K]";
// lmp->input->one(squery);
// if (!verbose) ::testing::internal::GetCapturedStdout();
// ASSERT_TRUE((std::string(lmp->input->variable->retrieve("alpha")) ==
// std::string("1.654960564704273e-05")));
}
} // namespace LAMMPS_NS
int main(int argc, char **argv)