diff --git a/examples/COUPLE/plugin/liblammpsplugin.c b/examples/COUPLE/plugin/liblammpsplugin.c index 81dcf2cd50..7df23c5b67 100644 --- a/examples/COUPLE/plugin/liblammpsplugin.c +++ b/examples/COUPLE/plugin/liblammpsplugin.c @@ -101,6 +101,8 @@ liblammpsplugin_t *liblammpsplugin_load(const char *lib) ADDSYM(extract_setting); ADDSYM(extract_global_datatype); ADDSYM(extract_global); + ADDSYM(extract_pair_dimension); + ADDSYM(extract_pair); ADDSYM(map_atom); ADDSYM(extract_atom_datatype); diff --git a/examples/COUPLE/plugin/liblammpsplugin.h b/examples/COUPLE/plugin/liblammpsplugin.h index ea00277083..9f53e4749b 100644 --- a/examples/COUPLE/plugin/liblammpsplugin.h +++ b/examples/COUPLE/plugin/liblammpsplugin.h @@ -144,11 +144,13 @@ struct _liblammpsplugin { int (*get_mpi_comm)(void *); int (*extract_setting)(void *, const char *); - int *(*extract_global_datatype)(void *, const char *); + int (*extract_global_datatype)(void *, const char *); void *(*extract_global)(void *, const char *); - void *(*map_atom)(void *, const void *); + int (*extract_pair_dimension)(void *, const char *); + void *(*extract_pair)(void *, const char *); + int (*map_atom)(void *, const void *); - int *(*extract_atom_datatype)(void *, const char *); + int (*extract_atom_datatype)(void *, const char *); void *(*extract_atom)(void *, const char *); void *(*extract_compute)(void *, const char *, int, int); diff --git a/python/lammps/core.py b/python/lammps/core.py index 8966a77440..ccf5f19d27 100644 --- a/python/lammps/core.py +++ b/python/lammps/core.py @@ -267,6 +267,9 @@ class lammps(object): self.lib.lammps_extract_global.argtypes = [c_void_p, c_char_p] self.lib.lammps_extract_global_datatype.argtypes = [c_void_p, c_char_p] self.lib.lammps_extract_global_datatype.restype = c_int + self.lib.lammps_extract_pair.argtypes = [c_void_p, c_char_p] + self.lib.lammps_extract_pair_dimension.argtypes = [c_void_p, c_char_p] + self.lib.lammps_extract_pair_dimension.restype = c_int self.lib.lammps_extract_compute.argtypes = [c_void_p, c_char_p, c_int, c_int] self.lib.lammps_map_atom.argtypes = [c_void_p, c_void_p] @@ -848,7 +851,7 @@ class lammps(object): This function returns ``None`` if the keyword is not recognized. Otherwise it will return a positive integer value that corresponds to one of the :ref:`data type ` - constants define in the :py:mod:`lammps` module. + constants defined in the :py:mod:`lammps` module. :param name: name of the property :type name: string @@ -931,6 +934,96 @@ class lammps(object): else: return target_type(ptr[0]) return None + # ------------------------------------------------------------------------- + # extract pair property dimensionality + + def extract_pair_dimension(self, name): + """Retrieve pair style property dimensionality from LAMMPS + + This is a wrapper around the :cpp:func:`lammps_extract_pair_dimension` + function of the C-library interface. The list of supported keywords + depends on the pair style. This function returns ``None`` if the keyword + is not recognized. + + :param name: name of the property + :type name: string + :return: dimensionality of the extractable data (typically 0, 1, or 2) + :rtype: int + """ + if name: + name = name.encode() + else: + return None + dim = self.lib.lammps_extract_pair_dimension(self.lmp, name) + + if dim < 0: + return None + else: + return dim; + + # ------------------------------------------------------------------------- + # get access to pair style extractable data + + def extract_pair(self, name): + """Extract pair style data from LAMMPS. + + This is a wrapper around the :cpp:func:`lammps_extract_pair` function + of the C-library interface. Since there are no pointers in Python, this + method will - unlike the C function - return the value or a list of + values. + Since Python needs to know the dimensionality to be able to interpret + the result, this function will detect the dimensionality by asking the library. + This function returns ``None`` if the keyword is not recognized. + + :param name: name of the property + :type name: string + :return: value of the property or list of values or None + :rtype: float, list of float, list of list of floats, or NoneType + """ + + if name: + name = name.encode() + else: + return None + + dim = self.extract_pair_dimension(name) + if dim == None: + return None + elif dim == 0: + self.lib.lammps_extract_pair.restype = POINTER(c_double) + elif dim == 1: + self.lib.lammps_extract_pair.restype = POINTER(c_double) + elif dim == 2: + self.lib.lammps_extract_pair.restype = POINTER(POINTER(c_double)) + else: + return None + + ntypes = self.extract_setting('ntypes') + ptr = self.lib.lammps_extract_pair(self.lmp, name) + if ptr: + if dim == 0: + return float(ptr[0]) + elif dim == 1: + result = [0.0] + for i in range(1,ntypes+1): + result.append(float(ptr[i])) + return result + elif dim == 2: + result = [] + inner = [] + for i in range(0,ntypes+1): + inner.append(float(0.0)) + result.append(inner) + for i in range(1,ntypes+1): + inner = [0.0] + for j in range(1,ntypes+1): + inner.append(float(ptr[i][j])) + result.append(inner) + return result + else: + return None + return None + # ------------------------------------------------------------------------- # map global atom ID to local atom index diff --git a/src/library.cpp b/src/library.cpp index bb58762563..13563abc02 100644 --- a/src/library.cpp +++ b/src/library.cpp @@ -42,6 +42,7 @@ #include "neigh_list.h" #include "neighbor.h" #include "output.h" +#include "pair.h" #if defined(LMP_PLUGIN) #include "plugin.h" #endif @@ -1938,6 +1939,69 @@ void *lammps_extract_global(void *handle, const char *name) /* ---------------------------------------------------------------------- */ +/** Get data dimension of pair style data accesible via Pair::extract(). + * +\verbatim embed:rst + +.. versionadded:: TBD + +This function returns an integer that specified the dimensionality of +the data that can be extracted from the current pair style with ``Pair::extract()``. +Callers of :cpp:func:`lammps_extract_pair` can use this information +to then decide how to cast the ``void *`` pointer and access the data. + +\endverbatim + * + * \param handle pointer to a previously created LAMMPS instance + * \param name string with the name of the extracted property + * \return integer constant encoding the dimensionality of the + extractable pair style property or -1 if not found. */ + +int lammps_extract_pair_dimension(void * handle, const char *name) +{ + auto lmp = (LAMMPS *) handle; + if (!lmp) return -1; + auto pair = lmp->force->pair; + if (!pair) return -1; + + int dim = -1; + if (lmp->force->pair->extract(name, dim)) return dim; + + return -1; +} + +/* ---------------------------------------------------------------------- */ + +/** Get extract pair style data accesible via Pair::extract(). + * +\verbatim embed:rst + +.. versionadded:: TBD + +This function returns a pointer to data available from the current pair +style with ``Pair::extract()``. The dimensionality of the returned +pointer can be determined with :cpp:func:`lammps_extract_pair_dimension`. + +\endverbatim + * + * \param handle pointer to a previously created LAMMPS instance + * \param name string with the name of the extracted property + * \return pointer (cast to ``void *``) to the location of the + requested property. NULL if name is not known. */ + +void *lammps_extract_pair(void * handle, const char *name) +{ + auto lmp = (LAMMPS *) handle; + if (!lmp) return nullptr; + auto pair = lmp->force->pair; + if (!pair) return nullptr; + + int dim = -1; + return lmp->force->pair->extract(name, dim); +} + +/* ---------------------------------------------------------------------- */ + /** Map global atom ID to local atom index * \verbatim embed:rst diff --git a/src/library.h b/src/library.h index fa4a3bd0a5..38ecffb772 100644 --- a/src/library.h +++ b/src/library.h @@ -162,6 +162,9 @@ int lammps_extract_setting(void *handle, const char *keyword); int lammps_extract_global_datatype(void *handle, const char *name); void *lammps_extract_global(void *handle, const char *name); +int lammps_extract_pair_dimension(void *handle, const char *name); +void *lammps_extract_pair(void *handle, const char *name); + int lammps_map_atom(void *handle, const void *id); /* ---------------------------------------------------------------------- diff --git a/tools/swig/lammps.i b/tools/swig/lammps.i index d350966c2a..2207a72e36 100644 --- a/tools/swig/lammps.i +++ b/tools/swig/lammps.i @@ -125,6 +125,8 @@ extern int lammps_get_mpi_comm(void *handle); extern int lammps_extract_setting(void *handle, const char *keyword); extern int lammps_extract_global_datatype(void *handle, const char *name); extern void *lammps_extract_global(void *handle, const char *name); +extern int lammps_extract_pair_dimension(void *handle, const char *name); +extern void *lammps_extract_pair(void *handle, const char *name); extern int lammps_map_atom(void *handle, const void *id); extern int lammps_extract_atom_datatype(void *handle, const char *name); @@ -311,6 +313,8 @@ extern int lammps_get_mpi_comm(void *handle); extern int lammps_extract_setting(void *handle, const char *keyword); extern int lammps_extract_global_datatype(void *handle, const char *name); extern void *lammps_extract_global(void *handle, const char *name); +extern int lammps_extract_pair_dimension(void *handle, const char *name); +extern void *lammps_extract_pair(void *handle, const char *name); extern int lammps_map_atom(void *handle, const void *id); extern int lammps_extract_atom_datatype(void *handle, const char *name);