diff --git a/python/README b/python/README index c5f7511260..3c7480b94b 100644 --- a/python/README +++ b/python/README @@ -8,14 +8,13 @@ doc/Section_python.html and in doc/Section_start.html#start_5. Basically you need to follow these steps in the src directory: -% make makeshlib # creates Makefile.shlib -% make -f Makefile.shlib g++ # build for whatever machine target you wish +% make g++ mode=shlib # build for whatever machine target you wish % make install-python # may need to do this via sudo -You can replace the last step with running the python/install.py -script directly to give you more control over where two relevant files -are installed, or by setting environment variables in your shell -script. See doc/Section_python.html for details. +You can replace the last step by a one-time setting of environment +variables in your shell script. Or you can run the python/install.py +script directly to give you more control over where the two relevant +files are installed. See doc/Section_python.html for details. You can then launch Python and instantiate an instance of LAMMPS: diff --git a/python/lammps.py b/python/lammps.py index 0f6e9dc76b..be55bcd979 100644 --- a/python/lammps.py +++ b/python/lammps.py @@ -17,11 +17,11 @@ import sys,traceback,types from ctypes import * class lammps: - def __init__(self,name="",cmdargs=None): + def __init__(self,name="",cmdargs=None,ptr=None): # load liblammps.so by default # if name = "g++", load liblammps_g++.so - + try: if not name: self.lib = CDLL("liblammps.so",RTLD_GLOBAL) else: self.lib = CDLL("liblammps_%s.so" % name,RTLD_GLOBAL) @@ -30,28 +30,39 @@ class lammps: traceback.print_exception(type,value,tb) raise OSError,"Could not load LAMMPS dynamic library" - # create an instance of LAMMPS - # don't know how to pass an MPI communicator from PyPar - # no_mpi call lets LAMMPS use MPI_COMM_WORLD - # cargs = array of C strings from args + # if no ptr provided, create an instance of LAMMPS + # don't know how to pass an MPI communicator from PyPar + # no_mpi call lets LAMMPS use MPI_COMM_WORLD + # cargs = array of C strings from args + # if ptr, then are embedding Python in LAMMPS input script + # ptr is the desired instance of LAMMPS + # just convert it to ctypes ptr and store in self.lmp - if cmdargs: - cmdargs.insert(0,"lammps.py") - narg = len(cmdargs) - cargs = (c_char_p*narg)(*cmdargs) - self.lmp = c_void_p() - self.lib.lammps_open_no_mpi(narg,cargs,byref(self.lmp)) + if not ptr: + self.opened = 1 + if cmdargs: + cmdargs.insert(0,"lammps.py") + narg = len(cmdargs) + cargs = (c_char_p*narg)(*cmdargs) + self.lmp = c_void_p() + self.lib.lammps_open_no_mpi(narg,cargs,byref(self.lmp)) + else: + self.lmp = c_void_p() + self.lib.lammps_open_no_mpi(0,None,byref(self.lmp)) + # could use just this if LAMMPS lib interface supported it + # self.lmp = self.lib.lammps_open_no_mpi(0,None) else: - self.lmp = c_void_p() - self.lib.lammps_open_no_mpi(0,None,byref(self.lmp)) - # could use just this if LAMMPS lib interface supported it - # self.lmp = self.lib.lammps_open_no_mpi(0,None) + self.opened = 0 + # magic to convert ptr to ctypes ptr + pythonapi.PyCObject_AsVoidPtr.restype = c_void_p + pythonapi.PyCObject_AsVoidPtr.argtypes = [py_object] + self.lmp = c_void_p(pythonapi.PyCObject_AsVoidPtr(ptr)) def __del__(self): - if self.lmp: self.lib.lammps_close(self.lmp) + if self.lmp and self.opened: self.lib.lammps_close(self.lmp) def close(self): - self.lib.lammps_close(self.lmp) + if self.opened: self.lib.lammps_close(self.lmp) self.lmp = None def file(self,file): @@ -142,6 +153,13 @@ class lammps: return result return None + # set variable value + # value is converted to string + # returns 0 for success, -1 if failed + + def set_variable(self,name,value): + return self.lib.lammps_set_variable(self.lmp,name,str(value)) + # return total number of atoms in system def get_natoms(self):