mirror of https://github.com/lammps/lammps.git
Change how a Python pair style is loaded
Implements a class loader which takes a fully qualified Python class name, loads the module and creates an object instance. To add flexibility, the current working directory and the directory specified by the LAMMPS_POTENTIALS environment variable are added to the module search path.
This commit is contained in:
parent
a6f0d700f1
commit
7caf6cf459
|
@ -12,7 +12,7 @@ mass * 1.0
|
|||
velocity all create 3.0 87287
|
||||
|
||||
pair_style hybrid lj/cut 2.5 python 2.5
|
||||
pair_coeff * * python lj-melt-potential.py lj NULL
|
||||
pair_coeff * * python potentials.LAMMPSLJCutPotential lj NULL
|
||||
pair_coeff * 2 lj/cut 1.0 1.0
|
||||
|
||||
neighbor 0.3 bin
|
||||
|
@ -31,7 +31,7 @@ clear
|
|||
read_restart hybrid.restart
|
||||
|
||||
pair_style hybrid lj/cut 2.5 python 2.5
|
||||
pair_coeff * * python lj-melt-potential.py lj NULL
|
||||
pair_coeff * * python potentials.LAMMPSLJCutPotential lj NULL
|
||||
pair_coeff * 2 lj/cut 1.0 1.0
|
||||
|
||||
fix 1 all nve
|
||||
|
@ -47,7 +47,7 @@ atom_style atomic
|
|||
read_data hybrid.data
|
||||
|
||||
pair_style hybrid lj/cut 2.5 python 2.5
|
||||
pair_coeff * * python lj-melt-potential.py lj NULL
|
||||
pair_coeff * * python potentials.LAMMPSLJCutPotential lj NULL
|
||||
pair_coeff * 2 lj/cut 1.0 1.0
|
||||
|
||||
neighbor 0.3 bin
|
||||
|
|
|
@ -12,7 +12,7 @@ mass * 1.0
|
|||
velocity all create 3.0 87287
|
||||
|
||||
pair_style python 2.5
|
||||
pair_coeff * * lj-melt-potential.py lj
|
||||
pair_coeff * * potentials.LAMMPSLJCutPotential lj
|
||||
|
||||
neighbor 0.3 bin
|
||||
neigh_modify every 20 delay 0 check no
|
||||
|
@ -30,7 +30,7 @@ clear
|
|||
read_restart melt.restart
|
||||
|
||||
pair_style python 2.5
|
||||
pair_coeff * * lj-melt-potential.py lj
|
||||
pair_coeff * * potentials.LAMMPSLJCutPotential lj
|
||||
|
||||
fix 1 all nve
|
||||
|
||||
|
@ -45,7 +45,7 @@ atom_style atomic
|
|||
read_data melt.data
|
||||
|
||||
pair_style python 2.5
|
||||
pair_coeff * * lj-melt-potential.py lj
|
||||
pair_coeff * * potentials.LAMMPSLJCutPotential lj
|
||||
|
||||
neighbor 0.3 bin
|
||||
neigh_modify every 20 delay 0 check no
|
||||
|
|
|
@ -32,6 +32,3 @@ class LAMMPSLJCutPotential(object):
|
|||
lj3 = coeff[4]
|
||||
lj4 = coeff[5]
|
||||
return (r6inv * (lj3*r6inv - lj4))
|
||||
|
||||
lammps_pair_style = LAMMPSLJCutPotential()
|
||||
|
|
@ -42,12 +42,26 @@ PairPython::PairPython(LAMMPS *lmp) : Pair(lmp) {
|
|||
reinitflag = 0;
|
||||
|
||||
python->init();
|
||||
|
||||
py_potential = NULL;
|
||||
|
||||
// add current directory to PYTHONPATH
|
||||
PyObject * py_path = PySys_GetObject("path");
|
||||
PyList_Append(py_path, PY_STRING_FROM_STRING("."));
|
||||
|
||||
// if LAMMPS_POTENTIALS environment variable is set, add it to PYTHONPATH as well
|
||||
const char * potentials_path = getenv("LAMMPS_POTENTIALS");
|
||||
if (potentials_path != NULL) {
|
||||
PyList_Append(py_path, PY_STRING_FROM_STRING(potentials_path));
|
||||
}
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
PairPython::~PairPython()
|
||||
{
|
||||
if(py_potential) Py_DECREF((PyObject*) py_potential);
|
||||
|
||||
if (allocated) {
|
||||
memory->destroy(setflag);
|
||||
memory->destroy(cutsq);
|
||||
|
@ -234,34 +248,56 @@ void PairPython::coeff(int narg, char **arg)
|
|||
error->all(FLERR,"Incorrect args for pair coefficients");
|
||||
|
||||
// check if python potential file exists and source it
|
||||
char * full_cls_name = arg[2];
|
||||
char * lastpos = strrchr(full_cls_name, '.');
|
||||
|
||||
FILE *fp = fopen(arg[2],"r");
|
||||
if (fp == NULL)
|
||||
error->all(FLERR,"Cannot open python pair potential class file");
|
||||
if (lastpos == NULL) {
|
||||
error->all(FLERR,"Python pair style requires fully qualified class name");
|
||||
}
|
||||
|
||||
size_t module_name_length = strlen(full_cls_name) - strlen(lastpos);
|
||||
size_t cls_name_length = strlen(lastpos)-1;
|
||||
|
||||
char * module_name = new char[module_name_length+1];
|
||||
char * cls_name = new char[cls_name_length+1];
|
||||
strncpy(module_name, full_cls_name, module_name_length);
|
||||
module_name[module_name_length] = 0;
|
||||
|
||||
strcpy(cls_name, lastpos+1);
|
||||
|
||||
PyGILState_STATE gstate = PyGILState_Ensure();
|
||||
|
||||
int err = PyRun_SimpleFile(fp,arg[2]);
|
||||
if (err) {
|
||||
PyObject * pModule = PyImport_ImportModule(module_name);
|
||||
if (!pModule) {
|
||||
PyErr_Print();
|
||||
PyErr_Clear();
|
||||
PyGILState_Release(gstate);
|
||||
error->all(FLERR,"Loading python pair style class failure");
|
||||
error->all(FLERR,"Loading python pair style module failure");
|
||||
}
|
||||
fclose(fp);
|
||||
|
||||
// create LAMMPS atom type to potential file type mapping in python class
|
||||
// by calling 'lammps_pair_style.map_coeff(name,type)'
|
||||
|
||||
PyObject *pModule = PyImport_AddModule("__main__");
|
||||
if (!pModule) error->all(FLERR,"Could not initialize embedded Python");
|
||||
PyObject *py_pair_type = PyObject_GetAttrString(pModule, cls_name);
|
||||
if (!py_pair_type) {
|
||||
PyErr_Print();
|
||||
PyErr_Clear();
|
||||
PyGILState_Release(gstate);
|
||||
error->all(FLERR,"Could not find pair style class in module'");
|
||||
}
|
||||
|
||||
PyObject *py_pair_instance = PyObject_GetAttrString(pModule,"lammps_pair_style");
|
||||
delete [] module_name;
|
||||
delete [] cls_name;
|
||||
|
||||
PyObject * py_pair_instance = PyObject_CallObject(py_pair_type, NULL);
|
||||
if (!py_pair_instance) {
|
||||
PyErr_Print();
|
||||
PyErr_Clear();
|
||||
PyGILState_Release(gstate);
|
||||
error->all(FLERR,"Could not find 'lammps_pair_style instance'");
|
||||
error->all(FLERR,"Could not instantiate instance of pair style class'");
|
||||
}
|
||||
py_potential = (void *) py_pair_instance; // XXX do we need to increment reference counter?
|
||||
|
||||
py_potential = (void *) py_pair_instance;
|
||||
|
||||
PyObject *py_map_coeff = PyObject_GetAttrString(py_pair_instance,"map_coeff");
|
||||
if (!py_map_coeff) {
|
||||
|
|
Loading…
Reference in New Issue