Merge branch 'develop' into python-lint
This commit is contained in:
@ -275,8 +275,14 @@ 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]
|
||||
self.lib.lammps_map_atom.restype = c_int
|
||||
|
||||
self.lib.lammps_get_thermo.argtypes = [c_void_p, c_char_p]
|
||||
self.lib.lammps_get_thermo.restype = c_double
|
||||
|
||||
@ -320,6 +326,8 @@ class lammps(object):
|
||||
self.lib.lammps_extract_atom.argtypes = [c_void_p, c_char_p]
|
||||
self.lib.lammps_extract_atom_datatype.argtypes = [c_void_p, c_char_p]
|
||||
self.lib.lammps_extract_atom_datatype.restype = c_int
|
||||
self.lib.lammps_extract_atom_size.argtypes = [c_void_p, c_char_p, c_int]
|
||||
self.lib.lammps_extract_atom_size.restype = c_int
|
||||
|
||||
self.lib.lammps_extract_fix.argtypes = [c_void_p, c_char_p, c_int, c_int, c_int, c_int]
|
||||
|
||||
@ -344,8 +352,8 @@ class lammps(object):
|
||||
if self.has_mpi_support:
|
||||
try:
|
||||
from mpi4py import __version__ as mpi4py_version
|
||||
# tested to work with mpi4py versions 2 and 3
|
||||
self.has_mpi4py = mpi4py_version.split('.')[0] in ['2','3']
|
||||
# tested to work with mpi4py versions 2, 3, and 4
|
||||
self.has_mpi4py = mpi4py_version.split('.')[0] in ['2','3','4']
|
||||
except ImportError:
|
||||
# ignore failing import
|
||||
pass
|
||||
@ -371,7 +379,7 @@ class lammps(object):
|
||||
if not self.has_mpi_support:
|
||||
raise Exception('LAMMPS not compiled with real MPI library')
|
||||
if not self.has_mpi4py:
|
||||
raise Exception('Python mpi4py version is not 2 or 3')
|
||||
raise Exception('Python mpi4py version is not 2, 3, or 4')
|
||||
if self.MPI._sizeof(self.MPI.Comm) == sizeof(c_int):
|
||||
MPI_Comm = c_int
|
||||
else:
|
||||
@ -384,12 +392,16 @@ class lammps(object):
|
||||
narg = 0
|
||||
cargs = None
|
||||
if cmdargs is not None:
|
||||
cmdargs.insert(0,"lammps")
|
||||
narg = len(cmdargs)
|
||||
for i in range(narg):
|
||||
if type(cmdargs[i]) is str:
|
||||
cmdargs[i] = cmdargs[i].encode()
|
||||
cargs = (c_char_p*(narg+1))(*cmdargs)
|
||||
myargs = ["lammps".encode()]
|
||||
narg = len(cmdargs) + 1
|
||||
for arg in cmdargs:
|
||||
if type(arg) is str:
|
||||
myargs.append(arg.encode())
|
||||
elif type(arg) is bytes:
|
||||
myargs.append(arg)
|
||||
else:
|
||||
raise TypeError('Unsupported cmdargs type ', type(arg))
|
||||
cargs = (c_char_p*(narg+1))(*myargs)
|
||||
cargs[narg] = None
|
||||
self.lib.lammps_open.argtypes = [c_int, c_char_p*(narg+1), MPI_Comm, c_void_p]
|
||||
else:
|
||||
@ -405,12 +417,16 @@ class lammps(object):
|
||||
self.comm = self.MPI.COMM_WORLD
|
||||
self.opened = 1
|
||||
if cmdargs is not None:
|
||||
cmdargs.insert(0,"lammps")
|
||||
narg = len(cmdargs)
|
||||
for i in range(narg):
|
||||
if type(cmdargs[i]) is str:
|
||||
cmdargs[i] = cmdargs[i].encode()
|
||||
cargs = (c_char_p*(narg+1))(*cmdargs)
|
||||
myargs = ["lammps".encode()]
|
||||
narg = len(cmdargs) + 1
|
||||
for arg in cmdargs:
|
||||
if type(arg) is str:
|
||||
myargs.append(arg.encode())
|
||||
elif type(arg) is bytes:
|
||||
myargs.append(arg)
|
||||
else:
|
||||
raise TypeError('Unsupported cmdargs type ', type(arg))
|
||||
cargs = (c_char_p*(narg+1))(*myargs)
|
||||
cargs[narg] = None
|
||||
self.lib.lammps_open_no_mpi.argtypes = [c_int, c_char_p*(narg+1), c_void_p]
|
||||
self.lmp = c_void_p(self.lib.lammps_open_no_mpi(narg,cargs,None))
|
||||
@ -527,11 +543,11 @@ class lammps(object):
|
||||
:param error_text:
|
||||
:type error_text: string
|
||||
"""
|
||||
if error_text: error_text = error_text.encode()
|
||||
else: error_text = "(unknown error)".encode()
|
||||
if error_text: new_error_text = error_text.encode()
|
||||
else: new_error_text = "(unknown error)".encode()
|
||||
|
||||
with ExceptionCheck(self):
|
||||
self.lib.lammps_error(self.lmp, error_type, error_text)
|
||||
self.lib.lammps_error(self.lmp, error_type, new_error_text)
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
@ -606,11 +622,11 @@ class lammps(object):
|
||||
:param path: Name of the file/path with LAMMPS commands
|
||||
:type path: string
|
||||
"""
|
||||
if path: path = path.encode()
|
||||
if path: newpath = path.encode()
|
||||
else: return
|
||||
|
||||
with ExceptionCheck(self):
|
||||
self.lib.lammps_file(self.lmp, path)
|
||||
self.lib.lammps_file(self.lmp, newpath)
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
@ -623,11 +639,11 @@ class lammps(object):
|
||||
:param cmd: a single lammps command
|
||||
:type cmd: string
|
||||
"""
|
||||
if cmd: cmd = cmd.encode()
|
||||
if cmd: newcmd = cmd.encode()
|
||||
else: return
|
||||
|
||||
with ExceptionCheck(self):
|
||||
self.lib.lammps_command(self.lmp,cmd)
|
||||
self.lib.lammps_command(self.lmp, newcmd)
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
@ -661,10 +677,11 @@ class lammps(object):
|
||||
:param multicmd: text block of lammps commands
|
||||
:type multicmd: string
|
||||
"""
|
||||
if type(multicmd) is str: multicmd = multicmd.encode()
|
||||
if type(multicmd) is str: newmulticmd = multicmd.encode()
|
||||
else: newmulticmd = multicmd
|
||||
|
||||
with ExceptionCheck(self):
|
||||
self.lib.lammps_commands_string(self.lmp,c_char_p(multicmd))
|
||||
self.lib.lammps_commands_string(self.lmp,c_char_p(newmulticmd))
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
@ -751,11 +768,11 @@ class lammps(object):
|
||||
:return: value of thermo keyword
|
||||
:rtype: double or None
|
||||
"""
|
||||
if name: name = name.encode()
|
||||
if name: newname = name.encode()
|
||||
else: return None
|
||||
|
||||
with ExceptionCheck(self):
|
||||
return self.lib.lammps_get_thermo(self.lmp,name)
|
||||
return self.lib.lammps_get_thermo(self.lmp, newname)
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
@property
|
||||
@ -829,9 +846,9 @@ class lammps(object):
|
||||
:return: value of the setting
|
||||
:rtype: int
|
||||
"""
|
||||
if name: name = name.encode()
|
||||
if name: newname = name.encode()
|
||||
else: return None
|
||||
return int(self.lib.lammps_extract_setting(self.lmp,name))
|
||||
return int(self.lib.lammps_extract_setting(self.lmp, newname))
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# extract global info datatype
|
||||
@ -845,16 +862,16 @@ 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 <py_datatype_constants>`
|
||||
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
|
||||
:return: data type of global property, see :ref:`py_datatype_constants`
|
||||
:rtype: int
|
||||
"""
|
||||
if name: name = name.encode()
|
||||
if name: newname = name.encode()
|
||||
else: return None
|
||||
return self.lib.lammps_extract_global_datatype(self.lmp, name)
|
||||
return self.lib.lammps_extract_global_datatype(self.lmp, newname)
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# extract global info
|
||||
@ -888,15 +905,17 @@ class lammps(object):
|
||||
# set length of vector for items that are not a scalar
|
||||
vec_dict = { 'boxlo':3, 'boxhi':3, 'sublo':3, 'subhi':3,
|
||||
'sublo_lambda':3, 'subhi_lambda':3, 'periodicity':3,
|
||||
'special_lj':4, 'special_coul':4 }
|
||||
'special_lj':4, 'special_coul':4, 'procgrid':3 }
|
||||
if name in vec_dict:
|
||||
veclen = vec_dict[name]
|
||||
elif name == 'respa_dt':
|
||||
veclen = self.extract_global('respa_levels',LAMMPS_INT)
|
||||
elif name == 'sametag':
|
||||
veclen = self.extract_setting('nall')
|
||||
else:
|
||||
veclen = 1
|
||||
|
||||
if name: name = name.encode()
|
||||
if name: newname = name.encode()
|
||||
else: return None
|
||||
|
||||
if dtype == LAMMPS_INT:
|
||||
@ -914,7 +933,7 @@ class lammps(object):
|
||||
else:
|
||||
target_type = None
|
||||
|
||||
ptr = self.lib.lammps_extract_global(self.lmp, name)
|
||||
ptr = self.lib.lammps_extract_global(self.lmp, newname)
|
||||
if ptr:
|
||||
if dtype == LAMMPS_STRING:
|
||||
return ptr.decode('utf-8')
|
||||
@ -926,6 +945,118 @@ 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
|
||||
|
||||
.. versionadded:: 29Aug2024
|
||||
|
||||
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:
|
||||
newname = name.encode()
|
||||
else:
|
||||
return None
|
||||
dim = self.lib.lammps_extract_pair_dimension(self.lmp, newname)
|
||||
|
||||
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.
|
||||
|
||||
.. versionadded:: 29Aug2024
|
||||
|
||||
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:
|
||||
newname = name.encode()
|
||||
else:
|
||||
return None
|
||||
|
||||
dim = self.extract_pair_dimension(name)
|
||||
if dim is 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, newname)
|
||||
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
|
||||
|
||||
def map_atom(self, id):
|
||||
"""Map a global atom ID (aka tag) to the local atom index
|
||||
|
||||
This is a wrapper around the :cpp:func:`lammps_map_atom`
|
||||
function of the C-library interface.
|
||||
|
||||
:param id: atom ID
|
||||
:type id: int
|
||||
:return: local index
|
||||
:rtype: int
|
||||
"""
|
||||
|
||||
tag = self.c_tagint(id)
|
||||
return self.lib.lammps_map_atom(self.lmp, pointer(tag))
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# extract per-atom info datatype
|
||||
|
||||
@ -945,9 +1076,37 @@ class lammps(object):
|
||||
:return: data type of per-atom property (see :ref:`py_datatype_constants`)
|
||||
:rtype: int
|
||||
"""
|
||||
if name: name = name.encode()
|
||||
if name: newname = name.encode()
|
||||
else: return None
|
||||
return self.lib.lammps_extract_atom_datatype(self.lmp, name)
|
||||
return self.lib.lammps_extract_atom_datatype(self.lmp, newname)
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# extract per-atom info datatype
|
||||
|
||||
def extract_atom_size(self, name, dtype):
|
||||
"""Retrieve per-atom property dimensions from LAMMPS
|
||||
|
||||
This is a wrapper around the :cpp:func:`lammps_extract_atom_size`
|
||||
function of the C-library interface. Its documentation includes a
|
||||
list of the supported keywords.
|
||||
This function returns ``None`` if the keyword is not
|
||||
recognized. Otherwise it will return an integer value with the size
|
||||
of the per-atom vector or array. If *name* corresponds to a per-atom
|
||||
array, the *dtype* keyword must be either LMP_SIZE_ROWS or LMP_SIZE_COLS
|
||||
from the :ref:`type <py_type_constants>` constants defined in the
|
||||
:py:mod:`lammps` module. The return value is the requested size.
|
||||
If *name* corresponds to a per-atom vector the *dtype* keyword is ignored.
|
||||
|
||||
:param name: name of the property
|
||||
:type name: string
|
||||
:param type: either LMP_SIZE_ROWS or LMP_SIZE_COLS for arrays, otherwise ignored
|
||||
:type type: int
|
||||
:return: data type of per-atom property (see :ref:`py_datatype_constants`)
|
||||
:rtype: int
|
||||
"""
|
||||
if name: newname = name.encode()
|
||||
else: return None
|
||||
return self.lib.lammps_extract_atom_size(self.lmp, newname, dtype)
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# extract per-atom info
|
||||
@ -955,25 +1114,25 @@ class lammps(object):
|
||||
def extract_atom(self, name, dtype=LAMMPS_AUTODETECT):
|
||||
"""Retrieve per-atom properties from LAMMPS
|
||||
|
||||
This is a wrapper around the :cpp:func:`lammps_extract_atom`
|
||||
function of the C-library interface. Its documentation includes a
|
||||
list of the supported keywords and their data types.
|
||||
Since Python needs to know the data type to be able to interpret
|
||||
the result, by default, this function will try to auto-detect the data type
|
||||
by asking the library. You can also force a specific data type by setting ``dtype``
|
||||
to one of the :ref:`data type <py_datatype_constants>` constants defined in the
|
||||
:py:mod:`lammps` module.
|
||||
This function returns ``None`` if either the keyword is not
|
||||
recognized, or an invalid data type constant is used.
|
||||
This is a wrapper around the :cpp:func:`lammps_extract_atom` function of the
|
||||
C-library interface. Its documentation includes a list of the supported
|
||||
keywords and their data types. Since Python needs to know the data type to
|
||||
be able to interpret the result, by default, this function will try to
|
||||
auto-detect the data type by asking the library. You can also force a
|
||||
specific data type by setting ``dtype`` to one of the :ref:`data type
|
||||
<py_datatype_constants>` constants defined in the :py:mod:`lammps` module.
|
||||
This function returns ``None`` if either the keyword is not recognized, or
|
||||
an invalid data type constant is used.
|
||||
|
||||
.. note::
|
||||
|
||||
While the returned arrays of per-atom data are dimensioned
|
||||
for the range [0:nmax] - as is the underlying storage -
|
||||
the data is usually only valid for the range of [0:nlocal],
|
||||
unless the property of interest is also updated for ghost
|
||||
atoms. In some cases, this depends on a LAMMPS setting, see
|
||||
for example :doc:`comm_modify vel yes <comm_modify>`.
|
||||
While the returned vectors or arrays of per-atom data are dimensioned for
|
||||
the range [0:nmax] - as is the underlying storage - the data is usually
|
||||
only valid for the range of [0:nlocal], unless the property of interest
|
||||
is also updated for ghost atoms. In some cases, this depends on a LAMMPS
|
||||
setting, see for example :doc:`comm_modify vel yes <comm_modify>`.
|
||||
The actual size can be determined by calling
|
||||
py:meth:`extract_atom_size() <lammps.lammps.extract_atom_size>`.
|
||||
|
||||
:param name: name of the property
|
||||
:type name: string
|
||||
@ -984,11 +1143,12 @@ class lammps(object):
|
||||
ctypes.POINTER(ctypes.c_int64), ctypes.POINTER(ctypes.POINTER(ctypes.c_int64)),
|
||||
ctypes.POINTER(ctypes.c_double), ctypes.POINTER(ctypes.POINTER(ctypes.c_double)),
|
||||
or NoneType
|
||||
|
||||
"""
|
||||
if dtype == LAMMPS_AUTODETECT:
|
||||
dtype = self.extract_atom_datatype(name)
|
||||
|
||||
if name: name = name.encode()
|
||||
if name: newname = name.encode()
|
||||
else: return None
|
||||
|
||||
if dtype == LAMMPS_INT:
|
||||
@ -1005,7 +1165,7 @@ class lammps(object):
|
||||
self.lib.lammps_extract_atom.restype = POINTER(POINTER(c_int64))
|
||||
else: return None
|
||||
|
||||
ptr = self.lib.lammps_extract_atom(self.lmp, name)
|
||||
ptr = self.lib.lammps_extract_atom(self.lmp, newname)
|
||||
if ptr: return ptr
|
||||
else: return None
|
||||
|
||||
@ -1033,47 +1193,47 @@ class lammps(object):
|
||||
:return: requested data as scalar, pointer to 1d or 2d double array, or None
|
||||
:rtype: c_double, ctypes.POINTER(c_double), ctypes.POINTER(ctypes.POINTER(c_double)), or NoneType
|
||||
"""
|
||||
if cid: cid = cid.encode()
|
||||
if cid: newcid = cid.encode()
|
||||
else: return None
|
||||
|
||||
if ctype == LMP_TYPE_SCALAR:
|
||||
if cstyle == LMP_STYLE_GLOBAL:
|
||||
self.lib.lammps_extract_compute.restype = POINTER(c_double)
|
||||
with ExceptionCheck(self):
|
||||
ptr = self.lib.lammps_extract_compute(self.lmp,cid,cstyle,ctype)
|
||||
ptr = self.lib.lammps_extract_compute(self.lmp,newcid,cstyle,ctype)
|
||||
return ptr[0]
|
||||
elif cstyle == LMP_STYLE_ATOM:
|
||||
return None
|
||||
elif cstyle == LMP_STYLE_LOCAL:
|
||||
self.lib.lammps_extract_compute.restype = POINTER(c_int)
|
||||
with ExceptionCheck(self):
|
||||
ptr = self.lib.lammps_extract_compute(self.lmp,cid,cstyle,ctype)
|
||||
ptr = self.lib.lammps_extract_compute(self.lmp,newcid,cstyle,ctype)
|
||||
return ptr[0]
|
||||
|
||||
elif ctype == LMP_TYPE_VECTOR:
|
||||
self.lib.lammps_extract_compute.restype = POINTER(c_double)
|
||||
with ExceptionCheck(self):
|
||||
ptr = self.lib.lammps_extract_compute(self.lmp,cid,cstyle,ctype)
|
||||
ptr = self.lib.lammps_extract_compute(self.lmp,newcid,cstyle,ctype)
|
||||
return ptr
|
||||
|
||||
elif ctype == LMP_TYPE_ARRAY:
|
||||
self.lib.lammps_extract_compute.restype = POINTER(POINTER(c_double))
|
||||
with ExceptionCheck(self):
|
||||
ptr = self.lib.lammps_extract_compute(self.lmp,cid,cstyle,ctype)
|
||||
ptr = self.lib.lammps_extract_compute(self.lmp,newcid,cstyle,ctype)
|
||||
return ptr
|
||||
|
||||
elif ctype == LMP_SIZE_COLS:
|
||||
if cstyle == LMP_STYLE_GLOBAL or cstyle == LMP_STYLE_ATOM or cstyle == LMP_STYLE_LOCAL:
|
||||
self.lib.lammps_extract_compute.restype = POINTER(c_int)
|
||||
with ExceptionCheck(self):
|
||||
ptr = self.lib.lammps_extract_compute(self.lmp,cid,cstyle,ctype)
|
||||
ptr = self.lib.lammps_extract_compute(self.lmp,newcid,cstyle,ctype)
|
||||
return ptr[0]
|
||||
|
||||
elif ctype == LMP_SIZE_VECTOR or ctype == LMP_SIZE_ROWS:
|
||||
if cstyle == LMP_STYLE_GLOBAL or cstyle == LMP_STYLE_LOCAL:
|
||||
self.lib.lammps_extract_compute.restype = POINTER(c_int)
|
||||
with ExceptionCheck(self):
|
||||
ptr = self.lib.lammps_extract_compute(self.lmp,cid,cstyle,ctype)
|
||||
ptr = self.lib.lammps_extract_compute(self.lmp,newcid,cstyle,ctype)
|
||||
return ptr[0]
|
||||
|
||||
return None
|
||||
@ -1118,21 +1278,21 @@ class lammps(object):
|
||||
:rtype: c_double, ctypes.POINTER(c_double), ctypes.POINTER(ctypes.POINTER(c_double)), or NoneType
|
||||
|
||||
"""
|
||||
if fid: fid = fid.encode()
|
||||
if fid: newfid = fid.encode()
|
||||
else: return None
|
||||
|
||||
if fstyle == LMP_STYLE_GLOBAL:
|
||||
if ftype in (LMP_TYPE_SCALAR, LMP_TYPE_VECTOR, LMP_TYPE_ARRAY):
|
||||
self.lib.lammps_extract_fix.restype = POINTER(c_double)
|
||||
with ExceptionCheck(self):
|
||||
ptr = self.lib.lammps_extract_fix(self.lmp,fid,fstyle,ftype,nrow,ncol)
|
||||
ptr = self.lib.lammps_extract_fix(self.lmp,newfid,fstyle,ftype,nrow,ncol)
|
||||
result = ptr[0]
|
||||
self.lib.lammps_free(ptr)
|
||||
return result
|
||||
elif ftype in (LMP_SIZE_VECTOR, LMP_SIZE_ROWS, LMP_SIZE_COLS):
|
||||
self.lib.lammps_extract_fix.restype = POINTER(c_int)
|
||||
with ExceptionCheck(self):
|
||||
ptr = self.lib.lammps_extract_fix(self.lmp,fid,fstyle,ftype,nrow,ncol)
|
||||
ptr = self.lib.lammps_extract_fix(self.lmp,newfid,fstyle,ftype,nrow,ncol)
|
||||
return ptr[0]
|
||||
else:
|
||||
return None
|
||||
@ -1147,7 +1307,7 @@ class lammps(object):
|
||||
else:
|
||||
return None
|
||||
with ExceptionCheck(self):
|
||||
ptr = self.lib.lammps_extract_fix(self.lmp,fid,fstyle,ftype,nrow,ncol)
|
||||
ptr = self.lib.lammps_extract_fix(self.lmp,newfid,fstyle,ftype,nrow,ncol)
|
||||
if ftype == LMP_SIZE_COLS:
|
||||
return ptr[0]
|
||||
else:
|
||||
@ -1163,7 +1323,7 @@ class lammps(object):
|
||||
else:
|
||||
return None
|
||||
with ExceptionCheck(self):
|
||||
ptr = self.lib.lammps_extract_fix(self.lmp,fid,fstyle,ftype,nrow,ncol)
|
||||
ptr = self.lib.lammps_extract_fix(self.lmp,newfid,fstyle,ftype,nrow,ncol)
|
||||
if ftype in (LMP_TYPE_VECTOR, LMP_TYPE_ARRAY):
|
||||
return ptr
|
||||
else:
|
||||
@ -1204,15 +1364,16 @@ class lammps(object):
|
||||
:return: the requested data
|
||||
:rtype: c_double, (c_double), or NoneType
|
||||
"""
|
||||
if name: name = name.encode()
|
||||
if name: newname = name.encode()
|
||||
else: return None
|
||||
if group: group = group.encode()
|
||||
if group: newgroup = group.encode()
|
||||
else: newgroup = None
|
||||
if vartype is None :
|
||||
vartype = self.lib.lammps_extract_variable_datatype(self.lmp, name)
|
||||
vartype = self.lib.lammps_extract_variable_datatype(self.lmp, newname)
|
||||
if vartype == LMP_VAR_EQUAL:
|
||||
self.lib.lammps_extract_variable.restype = POINTER(c_double)
|
||||
with ExceptionCheck(self):
|
||||
ptr = self.lib.lammps_extract_variable(self.lmp,name,group)
|
||||
ptr = self.lib.lammps_extract_variable(self.lmp, newname, newgroup)
|
||||
if ptr: result = ptr[0]
|
||||
else: return None
|
||||
self.lib.lammps_free(ptr)
|
||||
@ -1222,7 +1383,7 @@ class lammps(object):
|
||||
result = (c_double*nlocal)()
|
||||
self.lib.lammps_extract_variable.restype = POINTER(c_double)
|
||||
with ExceptionCheck(self):
|
||||
ptr = self.lib.lammps_extract_variable(self.lmp,name,group)
|
||||
ptr = self.lib.lammps_extract_variable(self.lmp, newname, newgroup)
|
||||
if ptr:
|
||||
for i in range(nlocal): result[i] = ptr[i]
|
||||
self.lib.lammps_free(ptr)
|
||||
@ -1231,27 +1392,27 @@ class lammps(object):
|
||||
elif vartype == LMP_VAR_VECTOR :
|
||||
nvector = 0
|
||||
self.lib.lammps_extract_variable.restype = POINTER(c_int)
|
||||
ptr = self.lib.lammps_extract_variable(self.lmp,name,
|
||||
ptr = self.lib.lammps_extract_variable(self.lmp, newname,
|
||||
'LMP_SIZE_VECTOR'.encode())
|
||||
if ptr :
|
||||
nvector = ptr[0]
|
||||
self.lib.lammps_free(ptr)
|
||||
else :
|
||||
else:
|
||||
return None
|
||||
self.lib.lammps_extract_variable.restype = POINTER(c_double)
|
||||
result = (c_double*nvector)()
|
||||
values = self.lib.lammps_extract_variable(self.lmp,name,group)
|
||||
values = self.lib.lammps_extract_variable(self.lmp, newname, newgroup)
|
||||
if values :
|
||||
for i in range(nvector) :
|
||||
result[i] = values[i]
|
||||
# do NOT free the values pointer (points to internal vector data)
|
||||
return result
|
||||
else :
|
||||
else:
|
||||
return None
|
||||
elif vartype == LMP_VAR_STRING :
|
||||
self.lib.lammps_extract_variable.restype = c_char_p
|
||||
with ExceptionCheck(self) :
|
||||
ptr = self.lib.lammps_extract_variable(self.lmp, name, group)
|
||||
ptr = self.lib.lammps_extract_variable(self.lmp, newname, newgroup)
|
||||
return ptr.decode('utf-8')
|
||||
return None
|
||||
|
||||
@ -1282,12 +1443,12 @@ class lammps(object):
|
||||
:return: either 0 on success or -1 on failure
|
||||
:rtype: int
|
||||
"""
|
||||
if name: name = name.encode()
|
||||
if name: newname = name.encode()
|
||||
else: return -1
|
||||
if value: value = str(value).encode()
|
||||
if value: newvalue = str(value).encode()
|
||||
else: return -1
|
||||
with ExceptionCheck(self):
|
||||
return self.lib.lammps_set_variable(self.lmp,name,value)
|
||||
return self.lib.lammps_set_variable(self.lmp, newname, newvalue)
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
@ -1306,12 +1467,12 @@ class lammps(object):
|
||||
:return: either 0 on success or -1 on failure
|
||||
:rtype: int
|
||||
"""
|
||||
if name: name = name.encode()
|
||||
if name: newname = name.encode()
|
||||
else: return -1
|
||||
if value: value = str(value).encode()
|
||||
if value: newvalue = str(value).encode()
|
||||
else: return -1
|
||||
with ExceptionCheck(self):
|
||||
return self.lib.lammps_set_string_variable(self.lmp,name,value)
|
||||
return self.lib.lammps_set_string_variable(self.lmp,newname,newvalue)
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
@ -1330,10 +1491,10 @@ class lammps(object):
|
||||
:return: either 0 on success or -1 on failure
|
||||
:rtype: int
|
||||
"""
|
||||
if name: name = name.encode()
|
||||
if name: newname = name.encode()
|
||||
else: return -1
|
||||
with ExceptionCheck(self):
|
||||
return self.lib.lammps_set_internal_variable(self.lmp,name,value)
|
||||
return self.lib.lammps_set_internal_variable(self.lmp,newname,value)
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
@ -1347,15 +1508,16 @@ class lammps(object):
|
||||
# e.g. for Python list or NumPy or ctypes
|
||||
|
||||
def gather_atoms(self,name,dtype,count):
|
||||
if name: name = name.encode()
|
||||
if name: newname = name.encode()
|
||||
else: newname = None
|
||||
natoms = self.get_natoms()
|
||||
with ExceptionCheck(self):
|
||||
if dtype == 0:
|
||||
data = ((count*natoms)*c_int)()
|
||||
self.lib.lammps_gather_atoms(self.lmp,name,dtype,count,data)
|
||||
self.lib.lammps_gather_atoms(self.lmp,newname,dtype,count,data)
|
||||
elif dtype == 1:
|
||||
data = ((count*natoms)*c_double)()
|
||||
self.lib.lammps_gather_atoms(self.lmp,name,dtype,count,data)
|
||||
self.lib.lammps_gather_atoms(self.lmp,newname,dtype,count,data)
|
||||
else:
|
||||
return None
|
||||
return data
|
||||
@ -1363,28 +1525,30 @@ class lammps(object):
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
def gather_atoms_concat(self,name,dtype,count):
|
||||
if name: name = name.encode()
|
||||
if name: newname = name.encode()
|
||||
else: newname = None
|
||||
natoms = self.get_natoms()
|
||||
with ExceptionCheck(self):
|
||||
if dtype == 0:
|
||||
data = ((count*natoms)*c_int)()
|
||||
self.lib.lammps_gather_atoms_concat(self.lmp,name,dtype,count,data)
|
||||
self.lib.lammps_gather_atoms_concat(self.lmp,newname,dtype,count,data)
|
||||
elif dtype == 1:
|
||||
data = ((count*natoms)*c_double)()
|
||||
self.lib.lammps_gather_atoms_concat(self.lmp,name,dtype,count,data)
|
||||
self.lib.lammps_gather_atoms_concat(self.lmp,newname,dtype,count,data)
|
||||
else:
|
||||
return None
|
||||
return data
|
||||
|
||||
def gather_atoms_subset(self,name,dtype,count,ndata,ids):
|
||||
if name: name = name.encode()
|
||||
if name: newname = name.encode()
|
||||
else: newname = None
|
||||
with ExceptionCheck(self):
|
||||
if dtype == 0:
|
||||
data = ((count*ndata)*c_int)()
|
||||
self.lib.lammps_gather_atoms_subset(self.lmp,name,dtype,count,ndata,ids,data)
|
||||
self.lib.lammps_gather_atoms_subset(self.lmp,newname,dtype,count,ndata,ids,data)
|
||||
elif dtype == 1:
|
||||
data = ((count*ndata)*c_double)()
|
||||
self.lib.lammps_gather_atoms_subset(self.lmp,name,dtype,count,ndata,ids,data)
|
||||
self.lib.lammps_gather_atoms_subset(self.lmp,newname,dtype,count,ndata,ids,data)
|
||||
else:
|
||||
return None
|
||||
return data
|
||||
@ -1401,16 +1565,18 @@ class lammps(object):
|
||||
# e.g. for Python list or NumPy or ctypes
|
||||
|
||||
def scatter_atoms(self,name,dtype,count,data):
|
||||
if name: name = name.encode()
|
||||
if name: newname = name.encode()
|
||||
else: newname = None
|
||||
with ExceptionCheck(self):
|
||||
self.lib.lammps_scatter_atoms(self.lmp,name,dtype,count,data)
|
||||
self.lib.lammps_scatter_atoms(self.lmp,newname,dtype,count,data)
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
def scatter_atoms_subset(self,name,dtype,count,ndata,ids,data):
|
||||
if name: name = name.encode()
|
||||
if name: newname = name.encode()
|
||||
else: newname = None
|
||||
with ExceptionCheck(self):
|
||||
self.lib.lammps_scatter_atoms_subset(self.lmp,name,dtype,count,ndata,ids,data)
|
||||
self.lib.lammps_scatter_atoms_subset(self.lmp,newname,dtype,count,ndata,ids,data)
|
||||
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
@ -1516,42 +1682,45 @@ class lammps(object):
|
||||
# NOTE: need to ensure are converting to/from correct Python type
|
||||
# e.g. for Python list or NumPy or ctypes
|
||||
def gather(self,name,dtype,count):
|
||||
if name: name = name.encode()
|
||||
if name: newname = name.encode()
|
||||
else: newname = None
|
||||
natoms = self.get_natoms()
|
||||
with ExceptionCheck(self):
|
||||
if dtype == 0:
|
||||
data = ((count*natoms)*c_int)()
|
||||
self.lib.lammps_gather(self.lmp,name,dtype,count,data)
|
||||
self.lib.lammps_gather(self.lmp,newname,dtype,count,data)
|
||||
elif dtype == 1:
|
||||
data = ((count*natoms)*c_double)()
|
||||
self.lib.lammps_gather(self.lmp,name,dtype,count,data)
|
||||
self.lib.lammps_gather(self.lmp,newname,dtype,count,data)
|
||||
else:
|
||||
return None
|
||||
return data
|
||||
|
||||
def gather_concat(self,name,dtype,count):
|
||||
if name: name = name.encode()
|
||||
if name: newname = name.encode()
|
||||
else: newname = None
|
||||
natoms = self.get_natoms()
|
||||
with ExceptionCheck(self):
|
||||
if dtype == 0:
|
||||
data = ((count*natoms)*c_int)()
|
||||
self.lib.lammps_gather_concat(self.lmp,name,dtype,count,data)
|
||||
self.lib.lammps_gather_concat(self.lmp,newname,dtype,count,data)
|
||||
elif dtype == 1:
|
||||
data = ((count*natoms)*c_double)()
|
||||
self.lib.lammps_gather_concat(self.lmp,name,dtype,count,data)
|
||||
self.lib.lammps_gather_concat(self.lmp,newname,dtype,count,data)
|
||||
else:
|
||||
return None
|
||||
return data
|
||||
|
||||
def gather_subset(self,name,dtype,count,ndata,ids):
|
||||
if name: name = name.encode()
|
||||
if name: newname = name.encode()
|
||||
else: newname = None
|
||||
with ExceptionCheck(self):
|
||||
if dtype == 0:
|
||||
data = ((count*ndata)*c_int)()
|
||||
self.lib.lammps_gather_subset(self.lmp,name,dtype,count,ndata,ids,data)
|
||||
self.lib.lammps_gather_subset(self.lmp,newname,dtype,count,ndata,ids,data)
|
||||
elif dtype == 1:
|
||||
data = ((count*ndata)*c_double)()
|
||||
self.lib.lammps_gather_subset(self.lmp,name,dtype,count,ndata,ids,data)
|
||||
self.lib.lammps_gather_subset(self.lmp,newname,dtype,count,ndata,ids,data)
|
||||
else:
|
||||
return None
|
||||
return data
|
||||
@ -1566,14 +1735,16 @@ class lammps(object):
|
||||
# e.g. for Python list or NumPy or ctypes
|
||||
|
||||
def scatter(self,name,dtype,count,data):
|
||||
if name: name = name.encode()
|
||||
if name: newname = name.encode()
|
||||
else: newname = None
|
||||
with ExceptionCheck(self):
|
||||
self.lib.lammps_scatter(self.lmp,name,dtype,count,data)
|
||||
self.lib.lammps_scatter(self.lmp,newname,dtype,count,data)
|
||||
|
||||
def scatter_subset(self,name,dtype,count,ndata,ids,data):
|
||||
if name: name = name.encode()
|
||||
if name: newname = name.encode()
|
||||
else: newname = None
|
||||
with ExceptionCheck(self):
|
||||
self.lib.lammps_scatter_subset(self.lmp,name,dtype,count,ndata,ids,data)
|
||||
self.lib.lammps_scatter_subset(self.lmp,newname,dtype,count,ndata,ids,data)
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
@ -1837,6 +2008,21 @@ class lammps(object):
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
@property
|
||||
def has_curl_support(self):
|
||||
""" Report whether the LAMMPS shared library was compiled with support
|
||||
for downloading files through libcurl.
|
||||
|
||||
This is a wrapper around the :cpp:func:`lammps_config_has_curl_support`
|
||||
function of the library interface.
|
||||
|
||||
:return: state of CURL support
|
||||
:rtype: bool
|
||||
"""
|
||||
return self.lib.lammps_config_has_curl_support() != 0
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
def has_package(self, name):
|
||||
""" Report if the named package has been enabled in the LAMMPS shared library.
|
||||
|
||||
@ -1920,7 +2106,7 @@ class lammps(object):
|
||||
""" List of the names of enabled packages in the LAMMPS shared library
|
||||
|
||||
This is a wrapper around the functions :cpp:func:`lammps_config_package_count`
|
||||
and :cpp:func`lammps_config_package_name` of the library interface.
|
||||
and :cpp:func:`lammps_config_package_name` of the library interface.
|
||||
|
||||
:return
|
||||
"""
|
||||
@ -2325,9 +2511,9 @@ class lammps(object):
|
||||
:rtype: int
|
||||
|
||||
"""
|
||||
style = style.encode()
|
||||
newstyle = style.encode()
|
||||
exact = int(exact)
|
||||
idx = self.lib.lammps_find_pair_neighlist(self.lmp, style, exact, nsub, reqid)
|
||||
idx = self.lib.lammps_find_pair_neighlist(self.lmp, newstyle, exact, nsub, reqid)
|
||||
return idx
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
@ -2348,8 +2534,8 @@ class lammps(object):
|
||||
:rtype: int
|
||||
|
||||
"""
|
||||
fixid = fixid.encode()
|
||||
idx = self.lib.lammps_find_fix_neighlist(self.lmp, fixid, reqid)
|
||||
newfixid = fixid.encode()
|
||||
idx = self.lib.lammps_find_fix_neighlist(self.lmp, newfixid, reqid)
|
||||
return idx
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
@ -2371,6 +2557,10 @@ class lammps(object):
|
||||
:rtype: int
|
||||
|
||||
"""
|
||||
computeid = computeid.encode()
|
||||
idx = self.lib.lammps_find_compute_neighlist(self.lmp, computeid, reqid)
|
||||
newcomputeid = computeid.encode()
|
||||
idx = self.lib.lammps_find_compute_neighlist(self.lmp, newcomputeid, reqid)
|
||||
return idx
|
||||
|
||||
# Local Variables:
|
||||
# fill-column: 80
|
||||
# End:
|
||||
|
||||
@ -58,7 +58,8 @@ class numpy_wrapper:
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
def extract_atom(self, name, dtype=LAMMPS_AUTODETECT, nelem=LAMMPS_AUTODETECT, dim=LAMMPS_AUTODETECT):
|
||||
def extract_atom(self, name, dtype=LAMMPS_AUTODETECT, nelem=LAMMPS_AUTODETECT,
|
||||
dim=LAMMPS_AUTODETECT):
|
||||
"""Retrieve per-atom properties from LAMMPS as NumPy arrays
|
||||
|
||||
This is a wrapper around the :py:meth:`lammps.extract_atom()` method.
|
||||
@ -67,16 +68,16 @@ class numpy_wrapper:
|
||||
|
||||
.. note::
|
||||
|
||||
The returned arrays of per-atom data are by default dimensioned
|
||||
for the range [0:nlocal] since that data is *always* valid. The
|
||||
underlying storage for the data, however, is typically allocated
|
||||
for the range of [0:nmax]. Whether there is valid data in the range
|
||||
[nlocal:nlocal+nghost] depends on whether the property of interest
|
||||
is also updated for ghost atoms. This is not often the case. In
|
||||
some cases, it depends on a LAMMPS setting, see for example
|
||||
:doc:`comm_modify vel yes <comm_modify>`. By using the optional
|
||||
*nelem* parameter the size of the returned NumPy can be overridden.
|
||||
There is no check whether the number of elements chosen is valid.
|
||||
The returned vectors or arrays of per-atom data are dimensioned
|
||||
according to the return value of :py:meth:`lammps.extract_atom_size()`.
|
||||
Except for the "mass" property, the underlying storage will always be
|
||||
dimensioned for the range [0:nmax]. The actual usable data may be
|
||||
only in the range [0:nlocal] or [0:nlocal][0:dim]. Whether there is
|
||||
valid data in the range [nlocal:nlocal+nghost] or [nlocal:local+nghost][0:dim]
|
||||
depends on whether the property of interest is also updated for ghost atoms.
|
||||
Also the value of *dim* depends on the value of *name*. By using the optional
|
||||
*nelem* and *dim* parameters the dimensions of the returned NumPy array can
|
||||
be overridden. There is no check whether the number of elements chosen is valid.
|
||||
|
||||
:param name: name of the property
|
||||
:type name: string
|
||||
@ -93,21 +94,10 @@ class numpy_wrapper:
|
||||
dtype = self.lmp.extract_atom_datatype(name)
|
||||
|
||||
if nelem == LAMMPS_AUTODETECT:
|
||||
if name == "mass":
|
||||
nelem = self.lmp.extract_global("ntypes") + 1
|
||||
else:
|
||||
nelem = self.lmp.extract_global("nlocal")
|
||||
nelem = self.lmp.extract_atom_size(name, LMP_SIZE_ROWS)
|
||||
if dim == LAMMPS_AUTODETECT:
|
||||
if dtype in (LAMMPS_INT_2D, LAMMPS_DOUBLE_2D, LAMMPS_INT64_2D):
|
||||
# TODO add other fields
|
||||
if name in ("x", "v", "f", "x0","omega", "angmom", "torque", "csforce", "vforce", "vest"):
|
||||
dim = 3
|
||||
elif name == "smd_data_9":
|
||||
dim = 9
|
||||
elif name == "smd_stress":
|
||||
dim = 6
|
||||
else:
|
||||
dim = 2
|
||||
dim = self.lmp.extract_atom_size(name, LMP_SIZE_COLS)
|
||||
else:
|
||||
dim = 1
|
||||
|
||||
@ -123,37 +113,6 @@ class numpy_wrapper:
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
def extract_atom_iarray(self, name, nelem, dim=1):
|
||||
warnings.warn("deprecated, use extract_atom instead", DeprecationWarning)
|
||||
|
||||
if name in ['id', 'molecule']:
|
||||
c_int_type = self.lmp.c_tagint
|
||||
elif name in ['image']:
|
||||
c_int_type = self.lmp.c_imageint
|
||||
else:
|
||||
c_int_type = c_int
|
||||
|
||||
if dim == 1:
|
||||
raw_ptr = self.lmp.extract_atom(name, LAMMPS_INT)
|
||||
else:
|
||||
raw_ptr = self.lmp.extract_atom(name, LAMMPS_INT_2D)
|
||||
|
||||
return self.iarray(c_int_type, raw_ptr, nelem, dim)
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
def extract_atom_darray(self, name, nelem, dim=1):
|
||||
warnings.warn("deprecated, use extract_atom instead", DeprecationWarning)
|
||||
|
||||
if dim == 1:
|
||||
raw_ptr = self.lmp.extract_atom(name, LAMMPS_DOUBLE)
|
||||
else:
|
||||
raw_ptr = self.lmp.extract_atom(name, LAMMPS_DOUBLE_2D)
|
||||
|
||||
return self.darray(raw_ptr, nelem, dim)
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
def extract_compute(self, cid, cstyle, ctype):
|
||||
"""Retrieve data from a LAMMPS compute
|
||||
|
||||
@ -275,11 +234,11 @@ class numpy_wrapper:
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
def gather_bonds(self):
|
||||
"""Retrieve global list of bonds as NumPy array
|
||||
"""Retrieve global list of bonds as a NumPy array
|
||||
|
||||
.. versionadded:: 28Jul2021
|
||||
|
||||
This is a wrapper around :py:meth:`lammps.gather_bonds() <lammps.lammps.gather_bonds()>`
|
||||
This is a wrapper around :py:meth:`lammps.gather_bonds() <lammps.lammps.gather_bonds()>`.
|
||||
It behaves the same as the original method, but returns a NumPy array instead
|
||||
of a ``ctypes`` list.
|
||||
|
||||
@ -293,11 +252,11 @@ class numpy_wrapper:
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
def gather_angles(self):
|
||||
""" Retrieve global list of angles as NumPy array
|
||||
""" Retrieve global list of angles as a NumPy array
|
||||
|
||||
.. versionadded:: 8Feb2023
|
||||
|
||||
This is a wrapper around :py:meth:`lammps.gather_angles() <lammps.lammps.gather_angles()>`
|
||||
This is a wrapper around :py:meth:`lammps.gather_angles() <lammps.lammps.gather_angles()>`.
|
||||
It behaves the same as the original method, but returns a NumPy array instead
|
||||
of a ``ctypes`` list.
|
||||
|
||||
@ -311,11 +270,11 @@ class numpy_wrapper:
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
def gather_dihedrals(self):
|
||||
""" Retrieve global list of dihedrals as NumPy array
|
||||
""" Retrieve global list of dihedrals as a NumPy array
|
||||
|
||||
.. versionadded:: 8Feb2023
|
||||
|
||||
This is a wrapper around :py:meth:`lammps.gather_dihedrals() <lammps.lammps.gather_dihedrals()>`
|
||||
This is a wrapper around :py:meth:`lammps.gather_dihedrals() <lammps.lammps.gather_dihedrals()>`.
|
||||
It behaves the same as the original method, but returns a NumPy array instead
|
||||
of a ``ctypes`` list.
|
||||
|
||||
@ -329,11 +288,11 @@ class numpy_wrapper:
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
def gather_impropers(self):
|
||||
""" Retrieve global list of impropers as NumPy array
|
||||
""" Retrieve global list of impropers as a NumPy array
|
||||
|
||||
.. versionadded:: 8Feb2023
|
||||
|
||||
This is a wrapper around :py:meth:`lammps.gather_impropers() <lammps.lammps.gather_impropers()>`
|
||||
This is a wrapper around :py:meth:`lammps.gather_impropers() <lammps.lammps.gather_impropers()>`.
|
||||
It behaves the same as the original method, but returns a NumPy array instead
|
||||
of a ``ctypes`` list.
|
||||
|
||||
|
||||
@ -358,6 +358,7 @@ class Atom2D(Atom):
|
||||
@property
|
||||
def velocity(self):
|
||||
"""Access to velocity of an atom
|
||||
|
||||
:getter: Return velocity of atom
|
||||
:setter: Set velocity of atom
|
||||
:type: numpy.array (float, float)
|
||||
@ -372,6 +373,7 @@ class Atom2D(Atom):
|
||||
@property
|
||||
def force(self):
|
||||
"""Access to force of an atom
|
||||
|
||||
:getter: Return force of atom
|
||||
:setter: Set force of atom
|
||||
:type: numpy.array (float, float)
|
||||
@ -418,7 +420,7 @@ class PyLammps(object):
|
||||
"""
|
||||
This is a Python wrapper class around the lower-level
|
||||
:py:class:`lammps` class, exposing a more Python-like,
|
||||
object-oriented interface for prototyping system inside of IPython and
|
||||
object-oriented interface for prototyping systems inside of IPython and
|
||||
Jupyter notebooks.
|
||||
|
||||
It either creates its own instance of :py:class:`lammps` or can be
|
||||
@ -463,13 +465,19 @@ class PyLammps(object):
|
||||
self.lmp = lammps(name=name,cmdargs=cmdargs,ptr=ptr,comm=comm)
|
||||
else:
|
||||
self.lmp = lammps(name=name,cmdargs=cmdargs,ptr=None,comm=comm)
|
||||
print("LAMMPS output is captured by PyLammps wrapper")
|
||||
self.comm_nprocs = self.lmp.extract_setting("world_size")
|
||||
self.comm_me = self.lmp.extract_setting("world_rank")
|
||||
if self.comm_me == 0:
|
||||
print("LAMMPS output is captured by PyLammps wrapper")
|
||||
if self.comm_nprocs > 1:
|
||||
print("WARNING: Using PyLammps with multiple MPI ranks is experimental. Not all functionality is supported.")
|
||||
self._cmd_history = []
|
||||
self._enable_cmd_history = False
|
||||
self.runs = []
|
||||
|
||||
if not self.lmp.has_package("PYTHON"):
|
||||
print("WARNING: run thermo data not captured since PYTHON LAMMPS package is not enabled")
|
||||
if self.comm_me == 0:
|
||||
print("WARNING: run thermo data not captured since PYTHON LAMMPS package is not enabled")
|
||||
|
||||
def __enter__(self):
|
||||
return self
|
||||
@ -550,7 +558,7 @@ class PyLammps(object):
|
||||
Commands will be added to the command history but not executed.
|
||||
|
||||
Add `commands` only to the command history, but do not execute them, so that you can
|
||||
conveniently create Lammps input files, using
|
||||
conveniently create LAMMPS input files, using
|
||||
:py:meth:`PyLammps.write_script()`.
|
||||
"""
|
||||
self._cmd_history.append(cmd)
|
||||
@ -727,7 +735,15 @@ class PyLammps(object):
|
||||
|
||||
def eval(self, expr):
|
||||
"""
|
||||
Evaluate expression
|
||||
Evaluate LAMMPS input file expression.
|
||||
|
||||
This is equivalent to using immediate variable expressions in the format "$(...)"
|
||||
in the LAMMPS input and will return the result of that expression.
|
||||
|
||||
.. warning::
|
||||
|
||||
This function is only supported on MPI rank 0. Calling it from a different
|
||||
MPI rank will raise an exception.
|
||||
|
||||
:param expr: the expression string that should be evaluated inside of LAMMPS
|
||||
:type expr: string
|
||||
@ -735,6 +751,9 @@ class PyLammps(object):
|
||||
:return: the value of the evaluated expression
|
||||
:rtype: float if numeric, string otherwise
|
||||
"""
|
||||
if self.comm_me > 0:
|
||||
raise Exception("PyLammps.eval() may only be used on MPI rank 0")
|
||||
|
||||
value = self.lmp_print('"$(%s)"' % expr).strip()
|
||||
try:
|
||||
return float(value)
|
||||
@ -796,18 +815,16 @@ class PyLammps(object):
|
||||
comm = {}
|
||||
comm['nprocs'] = self.lmp.extract_setting("world_size")
|
||||
comm['nthreads'] = self.lmp.extract_setting("nthreads")
|
||||
comm['proc_grid'] = comm['procgrid'] = self.lmp.extract_global("procgrid")
|
||||
idx = self.lmp.extract_setting("comm_style")
|
||||
comm['comm_style'] = ('brick', 'tiled')[idx]
|
||||
idx = self.lmp.extract_setting("comm_style")
|
||||
comm['comm_layout'] = ('uniform', 'nonuniform', 'irregular')[idx]
|
||||
comm['ghost_velocity'] = self.lmp.extract_setting("ghost_velocity") == 1
|
||||
|
||||
for line in output:
|
||||
if line.startswith("MPI library"):
|
||||
comm['mpi_version'] = line.split(':')[1].strip()
|
||||
elif line.startswith("Comm style"):
|
||||
parts = self._split_values(line)
|
||||
comm['comm_style'] = self._get_pair(parts[0])[1]
|
||||
comm['comm_layout'] = self._get_pair(parts[1])[1]
|
||||
elif line.startswith("Processor grid"):
|
||||
comm['proc_grid'] = [int(x) for x in self._get_pair(line)[1].split('x')]
|
||||
elif line.startswith("Communicate velocities for ghost atoms"):
|
||||
comm['ghost_velocity'] = (self._get_pair(line)[1] == "yes")
|
||||
return comm
|
||||
|
||||
def _parse_element_list(self, output):
|
||||
@ -893,7 +910,7 @@ class PyLammps(object):
|
||||
|
||||
class IPyLammps(PyLammps):
|
||||
"""
|
||||
IPython wrapper for LAMMPS which adds embedded graphics capabilities to PyLammmps interface
|
||||
IPython wrapper for LAMMPS which adds embedded graphics capabilities to PyLammps interface
|
||||
|
||||
It either creates its own instance of :py:class:`lammps` or can be
|
||||
initialized with an existing instance. The arguments are the same of the
|
||||
|
||||
Reference in New Issue
Block a user