Merge pull request #2694 from akohlmey/neighlist-interface-updates
Neighbor list library/python interface improvements
This commit is contained in:
@ -76,7 +76,7 @@ It documents the following functions:
|
||||
|
||||
-----------------------
|
||||
|
||||
.. doxygenfunction:: lammps_create_atoms(void *handle, int n, int *id, int *type, double *x, double *v, int *image, int bexpand)
|
||||
.. doxygenfunction:: lammps_create_atoms(void *handle, int n, const int *id, const int *type, const double *x, const double *v, const int *image, int bexpand)
|
||||
:project: progguide
|
||||
|
||||
|
||||
|
||||
@ -142,7 +142,7 @@ Style Constants
|
||||
Type Constants
|
||||
--------------
|
||||
|
||||
.. py:data:: LMP_TYPE_SCALAR, LMP_TYLE_VECTOR, LMP_TYPE_ARRAY, LMP_SIZE_VECTOR, LMP_SIZE_ROWS, LMP_SIZE_COLS
|
||||
.. py:data:: LMP_TYPE_SCALAR, LMP_TYPE_VECTOR, LMP_TYPE_ARRAY, LMP_SIZE_VECTOR, LMP_SIZE_ROWS, LMP_SIZE_COLS
|
||||
:type: int
|
||||
|
||||
Constants in the :py:mod:`lammps` module to select what type of data
|
||||
|
||||
@ -1,6 +1,43 @@
|
||||
Neighbor list access
|
||||
====================
|
||||
|
||||
Access to neighbor lists is handled through a couple of wrapper classes
|
||||
that allows to treat it like either a python list or a NumPy array. The
|
||||
access procedure is similar to that of the C-library interface: use one
|
||||
of the "find" functions to look up the index of the neighbor list in the
|
||||
global table of neighbor lists and then get access to the neighbor list
|
||||
data. The code sample below demonstrates reading the neighbor list data
|
||||
using the NumPy access method.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from lammps import lammps
|
||||
import numpy as np
|
||||
|
||||
lmp = lammps()
|
||||
lmp.commands_string("""
|
||||
region box block -2 2 -2 2 -2 2
|
||||
lattice fcc 1.0
|
||||
create_box 1 box
|
||||
create_atoms 1 box
|
||||
mass 1 1.0
|
||||
pair_style lj/cut 2.5
|
||||
pair_coeff 1 1 1.0 1.0
|
||||
run 0 post no""")
|
||||
|
||||
# look up the neighbor list
|
||||
nlidx = lmp.find_pair_neighlist('lj/cut')
|
||||
nl = lmp.numpy.get_neighlist(nlidx)
|
||||
tags = lmp.extract_atom('id')
|
||||
print("half neighbor list with {} entries".format(nl.size))
|
||||
# print neighbor list contents
|
||||
for i in range(0,nl.size):
|
||||
idx, nlist = nl.get(i)
|
||||
print("\natom {} with ID {} has {} neighbors:".format(idx,tags[idx],nlist.size))
|
||||
if nlist.size > 0:
|
||||
for n in np.nditer(nlist):
|
||||
print(" atom {} with ID {}".format(n,tags[n]))
|
||||
|
||||
**Methods:**
|
||||
|
||||
* :py:meth:`lammps.get_neighlist() <lammps.lammps.get_neighlist()>`: Get neighbor list for given index
|
||||
|
||||
@ -138,8 +138,8 @@ vector or columns of the array had been listed one by one. E.g. these
|
||||
.. code-block:: LAMMPS
|
||||
|
||||
compute myCOM all com/chunk
|
||||
fix 1 all ave/histo 100 1 100 c_myCOM[*] file tmp1.com mode vector
|
||||
fix 2 all ave/histo 100 1 100 c_myCOM[1] c_myCOM[2] c_myCOM[3] file tmp2.com mode vector
|
||||
fix 1 all ave/histo 100 1 100 -10.0 10.0 100 c_myCOM[*] file tmp1.com mode vector
|
||||
fix 2 all ave/histo 100 1 100 -10.0 10.0 100 c_myCOM[1] c_myCOM[2] c_myCOM[3] file tmp2.com mode vector
|
||||
|
||||
If the fix ave/histo/weight command is used, exactly two values must
|
||||
be specified. If the values are vectors, they must be the same
|
||||
|
||||
@ -2681,6 +2681,7 @@ representable
|
||||
Reproducibility
|
||||
reproducibility
|
||||
repuls
|
||||
reqid
|
||||
rescale
|
||||
rescaled
|
||||
rescales
|
||||
|
||||
@ -1747,17 +1747,23 @@ class lammps(object):
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
def find_pair_neighlist(self, style, exact=True, nsub=0, request=0):
|
||||
def find_pair_neighlist(self, style, exact=True, nsub=0, reqid=0):
|
||||
"""Find neighbor list index of pair style neighbor list
|
||||
|
||||
Try finding pair instance that matches style. If exact is set, the pair must
|
||||
match style exactly. If exact is 0, style must only be contained. If pair is
|
||||
of style pair/hybrid, style is instead matched the nsub-th hybrid sub-style.
|
||||
Search for a neighbor list requested by a pair style instance that
|
||||
matches "style". If exact is True, the pair style name must match
|
||||
exactly. If exact is False, the pair style name is matched against
|
||||
"style" as regular expression or sub-string. If the pair style is a
|
||||
hybrid pair style, the style is instead matched against the hybrid
|
||||
sub-styles. If the same pair style is used as sub-style multiple
|
||||
types, you must set nsub to a value n > 0 which indicates the nth
|
||||
instance of that sub-style to be used (same as for the pair_coeff
|
||||
command). The default value of 0 will fail to match in that case.
|
||||
|
||||
Once the pair instance has been identified, multiple neighbor list requests
|
||||
may be found. Every neighbor list is uniquely identified by its request
|
||||
index. Thus, providing this request index ensures that the correct neighbor
|
||||
list index is returned.
|
||||
Once the pair style instance has been identified, it may have
|
||||
requested multiple neighbor lists. Those are uniquely identified by
|
||||
a request ID > 0 as set by the pair style. Otherwise the request
|
||||
ID is 0.
|
||||
|
||||
:param style: name of pair style that should be searched for
|
||||
:type style: string
|
||||
@ -1765,44 +1771,58 @@ class lammps(object):
|
||||
:type exact: bool, optional
|
||||
:param nsub: match nsub-th hybrid sub-style, defaults to 0
|
||||
:type nsub: int, optional
|
||||
:param request: index of neighbor list request, in case there are more than one, defaults to 0
|
||||
:type request: int, optional
|
||||
:param reqid: list request id, > 0 in case there are more than one, defaults to 0
|
||||
:type reqid: int, optional
|
||||
:return: neighbor list index if found, otherwise -1
|
||||
:rtype: int
|
||||
"""
|
||||
|
||||
"""
|
||||
style = style.encode()
|
||||
exact = int(exact)
|
||||
idx = self.lib.lammps_find_pair_neighlist(self.lmp, style, exact, nsub, request)
|
||||
idx = self.lib.lammps_find_pair_neighlist(self.lmp, style, exact, nsub, reqid)
|
||||
return idx
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
def find_fix_neighlist(self, fixid, request=0):
|
||||
def find_fix_neighlist(self, fixid, reqid=0):
|
||||
"""Find neighbor list index of fix neighbor list
|
||||
|
||||
The fix instance requesting the neighbor list is uniquely identified
|
||||
by the fix ID. In case the fix has requested multiple neighbor
|
||||
lists, those are uniquely identified by a request ID > 0 as set by
|
||||
the fix. Otherwise the request ID is 0 (the default).
|
||||
|
||||
:param fixid: name of fix
|
||||
:type fixid: string
|
||||
:param request: index of neighbor list request, in case there are more than one, defaults to 0
|
||||
:type request: int, optional
|
||||
:param reqid: id of neighbor list request, in case there are more than one request, defaults to 0
|
||||
:type reqid: int, optional
|
||||
:return: neighbor list index if found, otherwise -1
|
||||
:rtype: int
|
||||
"""
|
||||
|
||||
"""
|
||||
fixid = fixid.encode()
|
||||
idx = self.lib.lammps_find_fix_neighlist(self.lmp, fixid, request)
|
||||
idx = self.lib.lammps_find_fix_neighlist(self.lmp, fixid, reqid)
|
||||
return idx
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
def find_compute_neighlist(self, computeid, request=0):
|
||||
def find_compute_neighlist(self, computeid, reqid=0):
|
||||
"""Find neighbor list index of compute neighbor list
|
||||
|
||||
The compute instance requesting the neighbor list is uniquely
|
||||
identified by the compute ID. In case the compute has requested
|
||||
multiple neighbor lists, those are uniquely identified by a request
|
||||
ID > 0 as set by the compute. Otherwise the request ID is 0 (the
|
||||
default).
|
||||
|
||||
:param computeid: name of compute
|
||||
:type computeid: string
|
||||
:param request: index of neighbor list request, in case there are more than one, defaults to 0
|
||||
:type request: int, optional
|
||||
:param reqid: index of neighbor list request, in case there are more than one request, defaults to 0
|
||||
:type reqid: int, optional
|
||||
:return: neighbor list index if found, otherwise -1
|
||||
:rtype: int
|
||||
"""
|
||||
|
||||
"""
|
||||
computeid = computeid.encode()
|
||||
idx = self.lib.lammps_find_compute_neighlist(self.lmp, computeid, request)
|
||||
idx = self.lib.lammps_find_compute_neighlist(self.lmp, computeid, reqid)
|
||||
return idx
|
||||
|
||||
@ -52,7 +52,9 @@ class NeighList:
|
||||
|
||||
def get(self, element):
|
||||
"""
|
||||
:return: tuple with atom local index, numpy array of neighbor local atom indices
|
||||
Access a specific neighbor list entry. "element" must be a number from 0 to the size-1 of the list
|
||||
|
||||
:return: tuple with atom local index, number of neighbors and ctypes pointer to neighbor's local atom indices
|
||||
:rtype: (int, int, ctypes.POINTER(c_int))
|
||||
"""
|
||||
iatom, numneigh, neighbors = self.lmp.get_neighlist_element_neighbors(self.idx, element)
|
||||
@ -71,3 +73,20 @@ class NeighList:
|
||||
|
||||
for ii in range(inum):
|
||||
yield self.get(ii)
|
||||
|
||||
def find(self, iatom):
|
||||
"""
|
||||
Find the neighbor list for a specific (local) atom iatom.
|
||||
If there is no list for iatom, (-1, None) is returned.
|
||||
|
||||
:return: tuple with number of neighbors and ctypes pointer to neighbor's local atom indices
|
||||
:rtype: (int, ctypes.POINTER(c_int))
|
||||
"""
|
||||
|
||||
inum = self.size
|
||||
for ii in range(inum):
|
||||
idx, numneigh, neighbors = self.get(ii)
|
||||
if idx == iatom:
|
||||
return numneigh, neighbors
|
||||
|
||||
return -1, None
|
||||
|
||||
@ -331,8 +331,25 @@ class NumPyNeighList(NeighList):
|
||||
|
||||
def get(self, element):
|
||||
"""
|
||||
Access a specific neighbor list entry. "element" must be a number from 0 to the size-1 of the list
|
||||
|
||||
:return: tuple with atom local index, numpy array of neighbor local atom indices
|
||||
:rtype: (int, numpy.array)
|
||||
"""
|
||||
iatom, neighbors = self.lmp.numpy.get_neighlist_element_neighbors(self.idx, element)
|
||||
return iatom, neighbors
|
||||
|
||||
def find(self, iatom):
|
||||
"""
|
||||
Find the neighbor list for a specific (local) atom iatom.
|
||||
If there is no list for iatom, None is returned.
|
||||
|
||||
:return: numpy array of neighbor local atom indices
|
||||
:rtype: numpy.array or None
|
||||
"""
|
||||
inum = self.size
|
||||
for ii in range(inum):
|
||||
idx, neighbors = self.get(ii)
|
||||
if idx == iatom:
|
||||
return neighbors
|
||||
return None
|
||||
|
||||
@ -318,7 +318,6 @@ void PairQUIP::init_style()
|
||||
|
||||
// Initialise neighbor list
|
||||
int irequest_full = neighbor->request(this);
|
||||
neighbor->requests[irequest_full]->id = 1;
|
||||
neighbor->requests[irequest_full]->half = 0;
|
||||
neighbor->requests[irequest_full]->full = 1;
|
||||
}
|
||||
|
||||
151
src/library.cpp
151
src/library.cpp
@ -1615,7 +1615,7 @@ lists the available options.
|
||||
* \return pointer (cast to ``void *``) to the location of the
|
||||
* requested data or ``NULL`` if not found. */
|
||||
|
||||
void *lammps_extract_compute(void *handle, char *id, int style, int type)
|
||||
void *lammps_extract_compute(void *handle, const char *id, int style, int type)
|
||||
{
|
||||
LAMMPS *lmp = (LAMMPS *) handle;
|
||||
|
||||
@ -1801,7 +1801,7 @@ The following table lists the available options.
|
||||
* \return pointer (cast to ``void *``) to the location of the
|
||||
* requested data or ``NULL`` if not found. */
|
||||
|
||||
void *lammps_extract_fix(void *handle, char *id, int style, int type,
|
||||
void *lammps_extract_fix(void *handle, const char *id, int style, int type,
|
||||
int nrow, int ncol)
|
||||
{
|
||||
LAMMPS *lmp = (LAMMPS *) handle;
|
||||
@ -3822,8 +3822,8 @@ X(1),Y(1),Z(1),X(2),Y(2),Z(2),...,X(N),Y(N),Z(N).
|
||||
* \return number of atoms created on success;
|
||||
-1 on failure (no box, no atom IDs, etc.) */
|
||||
|
||||
int lammps_create_atoms(void *handle, int n, tagint *id, int *type,
|
||||
double *x, double *v, imageint *image,
|
||||
int lammps_create_atoms(void *handle, int n, const tagint *id, const int *type,
|
||||
const double *x, const double *v, const imageint *image,
|
||||
int bexpand)
|
||||
{
|
||||
LAMMPS *lmp = (LAMMPS *) handle;
|
||||
@ -3859,13 +3859,17 @@ int lammps_create_atoms(void *handle, int n, tagint *id, int *type,
|
||||
|
||||
int nlocal_prev = nlocal;
|
||||
double xdata[3];
|
||||
imageint idata, *img;
|
||||
|
||||
for (int i = 0; i < n; i++) {
|
||||
xdata[0] = x[3*i];
|
||||
xdata[1] = x[3*i+1];
|
||||
xdata[2] = x[3*i+2];
|
||||
imageint * img = image ? image + i : nullptr;
|
||||
tagint tag = id ? id[i] : 0;
|
||||
if (image) {
|
||||
idata = image[i];
|
||||
img = &idata;
|
||||
} else img = nullptr;
|
||||
const tagint tag = id ? id[i] : 0;
|
||||
|
||||
// create atom only on MPI rank that would own it
|
||||
|
||||
@ -3917,40 +3921,43 @@ int lammps_create_atoms(void *handle, int n, tagint *id, int *type,
|
||||
// Library functions for accessing neighbor lists
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
/** Find neighbor list index of pair style neighbor list
|
||||
/** Find index of a neighbor list requested by a pair style
|
||||
*
|
||||
* Try finding pair instance that matches style. If exact is set, the pair must
|
||||
* match style exactly. If exact is 0, style must only be contained. If pair is
|
||||
* of style pair/hybrid, style is instead matched the nsub-th hybrid sub-style.
|
||||
* This function determines which of the available neighbor lists for
|
||||
* pair styles matches the given conditions. It first matches the style
|
||||
* name. If exact is 1 the name must match exactly, if exact is 0, a
|
||||
* regular expression or sub-string match is done. If the pair style is
|
||||
* hybrid or hybrid/overlay the style is matched against the sub styles
|
||||
* instead.
|
||||
* If a the same pair style is used multiple times as a sub-style, the
|
||||
* nsub argument must be > 0 and represents the nth instance of the sub-style
|
||||
* (same as for the pair_coeff command, for example). In that case
|
||||
* nsub=0 will not produce a match and this function will return -1.
|
||||
*
|
||||
* Once the pair instance has been identified, multiple neighbor list requests
|
||||
* may be found. Every neighbor list is uniquely identified by its request
|
||||
* index. Thus, providing this request index ensures that the correct neighbor
|
||||
* list index is returned.
|
||||
* The final condition to be checked is the request ID (reqid). This
|
||||
* will normally be 0, but some pair styles request multiple neighbor
|
||||
* lists and set the request ID to a value > 0.
|
||||
*
|
||||
* \param handle pointer to a previously created LAMMPS instance cast to ``void *``.
|
||||
* \param style String used to search for pair style instance
|
||||
* \param exact Flag to control whether style should match exactly or only
|
||||
* must be contained in pair style name
|
||||
* \param nsub match nsub-th hybrid sub-style
|
||||
* \param request request index that specifies which neighbor list should be
|
||||
* returned, in case there are multiple neighbor lists requests
|
||||
* for the found pair style
|
||||
* a regular expression / sub-string match is applied.
|
||||
* \param nsub match nsub-th hybrid sub-style instance of the same style
|
||||
* \param reqid request id to identify neighbor list in case there are
|
||||
* multiple requests from the same pair style instance
|
||||
* \return return neighbor list index if found, otherwise -1 */
|
||||
|
||||
int lammps_find_pair_neighlist(void* handle, char * style, int exact, int nsub, int request) {
|
||||
LAMMPS * lmp = (LAMMPS *) handle;
|
||||
Pair* pair = lmp->force->pair_match(style, exact, nsub);
|
||||
int lammps_find_pair_neighlist(void *handle, const char *style, int exact, int nsub, int reqid) {
|
||||
LAMMPS *lmp = (LAMMPS *) handle;
|
||||
Pair *pair = lmp->force->pair_match(style, exact, nsub);
|
||||
|
||||
if (pair != nullptr) {
|
||||
// find neigh list
|
||||
for (int i = 0; i < lmp->neighbor->nlist; i++) {
|
||||
NeighList * list = lmp->neighbor->lists[i];
|
||||
if (list->requestor_type != NeighList::PAIR || pair != list->requestor) continue;
|
||||
|
||||
if (list->index == request) {
|
||||
return i;
|
||||
}
|
||||
NeighList *list = lmp->neighbor->lists[i];
|
||||
if ( (list->requestor_type == NeighList::PAIR)
|
||||
&& (pair == list->requestor)
|
||||
&& (list->id == reqid) ) return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
@ -3958,74 +3965,60 @@ int lammps_find_pair_neighlist(void* handle, char * style, int exact, int nsub,
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
/** Find neighbor list index of fix neighbor list
|
||||
/** Find index of a neighbor list requested by a fix
|
||||
*
|
||||
* The neighbor list request from a fix is identified by the fix ID and
|
||||
* the request ID. The request ID is typically 0, but will be > 0 in
|
||||
* case a fix has multiple neighbor list requests.
|
||||
*
|
||||
* \param handle pointer to a previously created LAMMPS instance cast to ``void *``.
|
||||
* \param id Identifier of fix instance
|
||||
* \param request request index that specifies which request should be returned,
|
||||
* in case there are multiple neighbor lists for this fix
|
||||
* \param reqid request id to identify neighbor list in case there are
|
||||
* multiple requests from the same fix
|
||||
* \return return neighbor list index if found, otherwise -1 */
|
||||
|
||||
int lammps_find_fix_neighlist(void* handle, char *id, int request) {
|
||||
LAMMPS * lmp = (LAMMPS *) handle;
|
||||
Fix* fix = nullptr;
|
||||
const int nfix = lmp->modify->nfix;
|
||||
int lammps_find_fix_neighlist(void *handle, const char *id, int reqid) {
|
||||
LAMMPS *lmp = (LAMMPS *) handle;
|
||||
const int ifix = lmp->modify->find_fix(id);
|
||||
if (ifix < 0) return -1;
|
||||
|
||||
// find fix with name
|
||||
for (int ifix = 0; ifix < nfix; ifix++) {
|
||||
if (strcmp(lmp->modify->fix[ifix]->id, id) == 0) {
|
||||
fix = lmp->modify->fix[ifix];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (fix != nullptr) {
|
||||
// find neigh list
|
||||
for (int i = 0; i < lmp->neighbor->nlist; i++) {
|
||||
NeighList * list = lmp->neighbor->lists[i];
|
||||
if (list->requestor_type != NeighList::FIX || fix != list->requestor) continue;
|
||||
|
||||
if (list->index == request) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
Fix *fix = lmp->modify->fix[ifix];
|
||||
// find neigh list
|
||||
for (int i = 0; i < lmp->neighbor->nlist; i++) {
|
||||
NeighList *list = lmp->neighbor->lists[i];
|
||||
if ( (list->requestor_type == NeighList::FIX)
|
||||
&& (fix == list->requestor)
|
||||
&& (list->id == reqid) ) return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
/** Find neighbor list index of compute neighbor list
|
||||
/** Find index of a neighbor list requested by a compute
|
||||
*
|
||||
* The neighbor list request from a compute is identified by the compute
|
||||
* ID and the request ID. The request ID is typically 0, but will be
|
||||
* > 0 in case a compute has multiple neighbor list requests.
|
||||
*
|
||||
* \param handle pointer to a previously created LAMMPS instance cast to ``void *``.
|
||||
* \param id Identifier of fix instance
|
||||
* \param request request index that specifies which request should be returned,
|
||||
* in case there are multiple neighbor lists for this fix
|
||||
* \param id Identifier of compute instance
|
||||
* \param reqid request id to identify neighbor list in case there are
|
||||
* multiple requests from the same compute
|
||||
* \return return neighbor list index if found, otherwise -1 */
|
||||
|
||||
int lammps_find_compute_neighlist(void* handle, char *id, int request) {
|
||||
LAMMPS * lmp = (LAMMPS *) handle;
|
||||
Compute* compute = nullptr;
|
||||
const int ncompute = lmp->modify->ncompute;
|
||||
int lammps_find_compute_neighlist(void* handle, const char *id, int reqid) {
|
||||
LAMMPS *lmp = (LAMMPS *) handle;
|
||||
const int icompute = lmp->modify->find_compute(id);
|
||||
if (icompute < 0) return -1;
|
||||
|
||||
// find compute with name
|
||||
for (int icompute = 0; icompute < ncompute; icompute++) {
|
||||
if (strcmp(lmp->modify->compute[icompute]->id, id) == 0) {
|
||||
compute = lmp->modify->compute[icompute];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (compute != nullptr) {
|
||||
// find neigh list
|
||||
for (int i = 0; i < lmp->neighbor->nlist; i++) {
|
||||
NeighList * list = lmp->neighbor->lists[i];
|
||||
if (list->requestor_type != NeighList::COMPUTE || compute != list->requestor) continue;
|
||||
|
||||
if (list->index == request) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
Compute *compute = lmp->modify->compute[icompute];
|
||||
// find neigh list
|
||||
for (int i = 0; i < lmp->neighbor->nlist; i++) {
|
||||
NeighList * list = lmp->neighbor->lists[i];
|
||||
if ( (list->requestor_type == NeighList::COMPUTE)
|
||||
&& (compute == list->requestor)
|
||||
&& (list->id == reqid) ) return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -138,8 +138,8 @@ void *lammps_extract_atom(void *handle, const char *name);
|
||||
* Library functions to access data from computes, fixes, variables in LAMMPS
|
||||
* ---------------------------------------------------------------------- */
|
||||
|
||||
void *lammps_extract_compute(void *handle, char *id, int, int);
|
||||
void *lammps_extract_fix(void *handle, char *, int, int, int, int);
|
||||
void *lammps_extract_compute(void *handle, const char *, int, int);
|
||||
void *lammps_extract_fix(void *handle, const char *, int, int, int, int);
|
||||
void *lammps_extract_variable(void *handle, const char *, const char *);
|
||||
int lammps_set_variable(void *, char *, char *);
|
||||
|
||||
@ -160,20 +160,20 @@ void lammps_scatter(void *handle, char *name, int type, int count, void *data);
|
||||
void lammps_scatter_subset(void *handle, char *name, int type, int count, int ndata, int *ids, void *data);
|
||||
|
||||
#if !defined(LAMMPS_BIGBIG)
|
||||
int lammps_create_atoms(void *handle, int n, int *id, int *type,
|
||||
double *x, double *v, int *image, int bexpand);
|
||||
int lammps_create_atoms(void *handle, int n, const int *id, const int *type,
|
||||
const double *x, const double *v, const int *image, int bexpand);
|
||||
#else
|
||||
int lammps_create_atoms(void *handle, int n, int64_t *id, int *type,
|
||||
double *x, double *v, int64_t* image, int bexpand);
|
||||
int lammps_create_atoms(void *handle, int n, const int64_t *id, const int *type,
|
||||
const double *x, const double *v, const int64_t* image, int bexpand);
|
||||
#endif
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
* Library functions for accessing neighbor lists
|
||||
* ---------------------------------------------------------------------- */
|
||||
|
||||
int lammps_find_pair_neighlist(void *handle, char *style, int exact, int nsub, int request);
|
||||
int lammps_find_fix_neighlist(void *handle, char *id, int request);
|
||||
int lammps_find_compute_neighlist(void *handle, char *id, int request);
|
||||
int lammps_find_pair_neighlist(void *handle, const char *style, int exact, int nsub, int request);
|
||||
int lammps_find_fix_neighlist(void *handle, const char *id, int request);
|
||||
int lammps_find_compute_neighlist(void *handle, const char *id, int request);
|
||||
int lammps_neighlist_num_elements(void *handle, int idx);
|
||||
void lammps_neighlist_element_neighbors(void *handle, int idx, int element, int *iatom, int *numneigh, int **neighbors);
|
||||
|
||||
|
||||
@ -143,6 +143,7 @@ void NeighList::post_constructor(NeighRequest *nq)
|
||||
respamiddle = nq->respamiddle;
|
||||
respainner = nq->respainner;
|
||||
copy = nq->copy;
|
||||
id = nq->id;
|
||||
|
||||
if (nq->copy) {
|
||||
listcopy = neighbor->lists[nq->copylist];
|
||||
|
||||
@ -44,6 +44,7 @@ class NeighList : protected Pointers {
|
||||
int copy; // 1 if this list is copied from another list
|
||||
int kk2cpu; // 1 if this list is copied from Kokkos to CPU
|
||||
int copymode; // 1 if this is a Kokkos on-device copy
|
||||
int id; // copied from neighbor list request
|
||||
|
||||
// data structs to store neighbor pairs I,J and associated values
|
||||
|
||||
|
||||
@ -11,6 +11,7 @@ add_executable(test_library_properties test_library_properties.cpp test_main.cpp
|
||||
target_link_libraries(test_library_properties PRIVATE lammps GTest::GTest GTest::GMock)
|
||||
target_compile_definitions(test_library_properties PRIVATE -DTEST_INPUT_FOLDER=${CMAKE_CURRENT_SOURCE_DIR})
|
||||
add_test(LibraryProperties test_library_properties)
|
||||
set_tests_properties(LibraryProperties PROPERTIES ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR}")
|
||||
|
||||
set(TEST_CONFIG_DEFS "-DTEST_INPUT_FOLDER=${CMAKE_CURRENT_SOURCE_DIR};-DLAMMPS_${LAMMPS_SIZES}")
|
||||
set(PKG_COUNT 0)
|
||||
|
||||
@ -160,7 +160,9 @@ TEST_F(LibraryProperties, box)
|
||||
boxlo[0] = -6.1;
|
||||
boxhi[1] = 7.3;
|
||||
xy = 0.1;
|
||||
if (!verbose) ::testing::internal::CaptureStdout();
|
||||
lammps_reset_box(lmp, boxlo, boxhi, xy, yz, xz);
|
||||
if (!verbose) ::testing::internal::GetCapturedStdout();
|
||||
lammps_extract_box(lmp, boxlo, boxhi, &xy, &yz, &xz, pflags, &boxflag);
|
||||
EXPECT_DOUBLE_EQ(boxlo[0], -6.1);
|
||||
EXPECT_DOUBLE_EQ(boxlo[1], -7.692866);
|
||||
@ -313,6 +315,121 @@ TEST_F(LibraryProperties, global)
|
||||
EXPECT_DOUBLE_EQ((*d_ptr), 0.1);
|
||||
};
|
||||
|
||||
TEST_F(LibraryProperties, neighlist)
|
||||
{
|
||||
if (!lammps_has_style(lmp, "pair", "sw")) GTEST_SKIP();
|
||||
const char sysinit[] = "boundary f f f\n"
|
||||
"units real\n"
|
||||
"region box block -5 5 -5 5 -5 5\n"
|
||||
"create_box 2 box\n"
|
||||
"mass 1 1.0\n"
|
||||
"mass 2 1.0\n"
|
||||
"pair_style hybrid/overlay lj/cut 4.0 lj/cut 4.0 morse 4.0 sw\n"
|
||||
"pair_coeff * * sw Si.sw Si NULL\n"
|
||||
"pair_coeff 1 2 morse 0.2 2.0 2.0\n"
|
||||
"pair_coeff 2 2 lj/cut 1 0.1 2.0\n"
|
||||
"pair_coeff * * lj/cut 2 0.01 2.0\n"
|
||||
"compute dist all pair/local dist\n"
|
||||
"fix dist all ave/histo 1 1 1 0.0 3.0 4 c_dist mode vector\n"
|
||||
"thermo_style custom f_dist[*]";
|
||||
|
||||
const double pos[] = {0.0, 0.0, 0.0, -1.1, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.1,
|
||||
0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.1, 0.0, 0.0, 1.0};
|
||||
const tagint ids[] = {1, 2, 3, 4, 5, 6, 7};
|
||||
const int types[] = {1, 1, 1, 1, 2, 2, 2};
|
||||
|
||||
const int numatoms = sizeof(ids) / sizeof(tagint);
|
||||
|
||||
if (!verbose) ::testing::internal::CaptureStdout();
|
||||
lammps_commands_string(lmp, sysinit);
|
||||
lammps_create_atoms(lmp, numatoms, ids, types, pos, nullptr, nullptr, 0);
|
||||
lammps_command(lmp, "run 0 post no");
|
||||
if (!verbose) ::testing::internal::GetCapturedStdout();
|
||||
|
||||
int nhisto =
|
||||
*(double *)lammps_extract_fix(lmp, "dist", LMP_STYLE_GLOBAL, LMP_TYPE_VECTOR, 0, 0);
|
||||
int nskip = *(double *)lammps_extract_fix(lmp, "dist", LMP_STYLE_GLOBAL, LMP_TYPE_VECTOR, 1, 0);
|
||||
double minval =
|
||||
*(double *)lammps_extract_fix(lmp, "dist", LMP_STYLE_GLOBAL, LMP_TYPE_VECTOR, 2, 0);
|
||||
double maxval =
|
||||
*(double *)lammps_extract_fix(lmp, "dist", LMP_STYLE_GLOBAL, LMP_TYPE_VECTOR, 3, 0);
|
||||
// 21 pair distances counted, none skipped, smallest 1.0, largest 2.1
|
||||
EXPECT_EQ(nhisto, 21);
|
||||
EXPECT_EQ(nskip, 0);
|
||||
EXPECT_DOUBLE_EQ(minval, 1.0);
|
||||
EXPECT_DOUBLE_EQ(maxval, 2.1);
|
||||
|
||||
const int nlocal = lammps_extract_setting(lmp, "nlocal");
|
||||
EXPECT_EQ(nlocal, numatoms);
|
||||
EXPECT_NE(lammps_find_pair_neighlist(lmp, "sw", 1, 0, 0), -1);
|
||||
EXPECT_NE(lammps_find_pair_neighlist(lmp, "morse", 1, 0, 0), -1);
|
||||
EXPECT_NE(lammps_find_pair_neighlist(lmp, "lj/cut", 1, 1, 0), -1);
|
||||
EXPECT_NE(lammps_find_pair_neighlist(lmp, "lj/cut", 1, 2, 0), -1);
|
||||
EXPECT_EQ(lammps_find_pair_neighlist(lmp, "lj/cut", 1, 0, 0), -1);
|
||||
EXPECT_EQ(lammps_find_pair_neighlist(lmp, "hybrid/overlay", 1, 0, 0), -1);
|
||||
EXPECT_NE(lammps_find_compute_neighlist(lmp, "dist", 0), -1);
|
||||
EXPECT_EQ(lammps_find_fix_neighlist(lmp, "dist", 0), -1);
|
||||
EXPECT_EQ(lammps_find_compute_neighlist(lmp, "xxx", 0), -1);
|
||||
|
||||
// full neighbor list for 4 type 1 atoms
|
||||
// all have 3 type 1 atom neighbors
|
||||
int idx = lammps_find_pair_neighlist(lmp, "sw", 1, 0, 0);
|
||||
int num = lammps_neighlist_num_elements(lmp, idx);
|
||||
EXPECT_EQ(num, 4);
|
||||
int iatom, inum, *neighbors;
|
||||
for (int i = 0; i < num; ++i) {
|
||||
lammps_neighlist_element_neighbors(lmp, idx, i, &iatom, &inum, &neighbors);
|
||||
EXPECT_EQ(iatom, i);
|
||||
EXPECT_EQ(inum, 3);
|
||||
EXPECT_NE(neighbors, nullptr);
|
||||
}
|
||||
|
||||
// half neighbor list for all pairs between type 1 and type 2
|
||||
// 4 type 1 atoms with 3 type 2 neighbors and 3 type 2 atoms without neighbors
|
||||
idx = lammps_find_pair_neighlist(lmp, "morse", 0, 0, 0);
|
||||
num = lammps_neighlist_num_elements(lmp, idx);
|
||||
EXPECT_EQ(num, nlocal);
|
||||
for (int i = 0; i < num; ++i) {
|
||||
lammps_neighlist_element_neighbors(lmp, idx, i, &iatom, &inum, &neighbors);
|
||||
if (i < 4)
|
||||
EXPECT_EQ(inum, 3);
|
||||
else
|
||||
EXPECT_EQ(inum, 0);
|
||||
EXPECT_NE(neighbors, nullptr);
|
||||
}
|
||||
|
||||
// half neighbor list between type 2 atoms only
|
||||
// 3 pairs with 2, 1, 0 neighbors
|
||||
idx = lammps_find_pair_neighlist(lmp, "lj/cut", 1, 1, 0);
|
||||
num = lammps_neighlist_num_elements(lmp, idx);
|
||||
EXPECT_EQ(num, 3);
|
||||
for (int i = 0; i < num; ++i) {
|
||||
lammps_neighlist_element_neighbors(lmp, idx, i, &iatom, &inum, &neighbors);
|
||||
EXPECT_EQ(inum, 2 - i);
|
||||
EXPECT_NE(neighbors, nullptr);
|
||||
}
|
||||
|
||||
// half neighbor list between all pairs. same as simple lj/cut case
|
||||
idx = lammps_find_pair_neighlist(lmp, "lj/cut", 1, 2, 0);
|
||||
num = lammps_neighlist_num_elements(lmp, idx);
|
||||
EXPECT_EQ(num, nlocal);
|
||||
for (int i = 0; i < num; ++i) {
|
||||
lammps_neighlist_element_neighbors(lmp, idx, i, &iatom, &inum, &neighbors);
|
||||
EXPECT_EQ(inum, nlocal - 1 - i);
|
||||
EXPECT_NE(neighbors, nullptr);
|
||||
}
|
||||
|
||||
// the compute has a half neighbor list
|
||||
idx = lammps_find_compute_neighlist(lmp, "dist", 0);
|
||||
num = lammps_neighlist_num_elements(lmp, idx);
|
||||
EXPECT_EQ(num, nlocal);
|
||||
for (int i = 0; i < num; ++i) {
|
||||
lammps_neighlist_element_neighbors(lmp, idx, i, &iatom, &inum, &neighbors);
|
||||
EXPECT_EQ(inum, nlocal - 1 - i);
|
||||
EXPECT_NE(neighbors, nullptr);
|
||||
}
|
||||
};
|
||||
|
||||
class AtomProperties : public ::testing::Test {
|
||||
protected:
|
||||
void *lmp;
|
||||
|
||||
@ -28,6 +28,7 @@ endif()
|
||||
if(Python_EXECUTABLE)
|
||||
# prepare to augment the environment so that the LAMMPS python module and the shared library is found.
|
||||
set(PYTHON_TEST_ENVIRONMENT PYTHONPATH=${LAMMPS_PYTHON_DIR}:$ENV{PYTHONPATH})
|
||||
list(APPEND PYTHON_TEST_ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR}")
|
||||
if(APPLE)
|
||||
list(APPEND PYTHON_TEST_ENVIRONMENT "DYLD_LIBRARY_PATH=${CMAKE_BINARY_DIR}:$ENV{DYLD_LIBRARY_PATH};LAMMPS_CMAKE_CACHE=${CMAKE_BINARY_DIR}/CMakeCache.txt")
|
||||
else()
|
||||
|
||||
@ -1,6 +1,17 @@
|
||||
|
||||
import sys,os,unittest
|
||||
from lammps import lammps, LMP_VAR_ATOM
|
||||
from lammps import lammps, LMP_VAR_ATOM, LMP_STYLE_GLOBAL, LMP_TYPE_VECTOR
|
||||
|
||||
has_manybody=False
|
||||
try:
|
||||
machine=None
|
||||
if 'LAMMPS_MACHINE_NAME' in os.environ:
|
||||
machine=os.environ['LAMMPS_MACHINE_NAME']
|
||||
lmp=lammps(name=machine)
|
||||
has_manybody = lmp.has_style("pair","sw")
|
||||
lmp.close()
|
||||
except:
|
||||
pass
|
||||
|
||||
class PythonCommand(unittest.TestCase):
|
||||
|
||||
@ -85,36 +96,35 @@ create_atoms 1 single &
|
||||
natoms = self.lmp.get_natoms()
|
||||
self.assertEqual(natoms,2)
|
||||
|
||||
def testNeighborList(self):
|
||||
self.lmp.command("units lj")
|
||||
self.lmp.command("atom_style atomic")
|
||||
self.lmp.command("atom_modify map array")
|
||||
self.lmp.command("boundary f f f")
|
||||
self.lmp.command("region box block 0 2 0 2 0 2")
|
||||
self.lmp.command("create_box 1 box")
|
||||
|
||||
x = [
|
||||
1.0, 1.0, 1.0,
|
||||
1.0, 1.0, 1.5
|
||||
]
|
||||
def testNeighborListSimple(self):
|
||||
self.lmp.commands_string("""
|
||||
units lj
|
||||
atom_style atomic
|
||||
atom_modify map array
|
||||
boundary f f f
|
||||
region box block 0 2 0 2 0 2
|
||||
create_box 1 box""")
|
||||
|
||||
x = [ 1.0, 1.0, 1.0, 1.0, 1.0, 1.5 ]
|
||||
types = [1, 1]
|
||||
|
||||
self.assertEqual(self.lmp.create_atoms(2, id=None, type=types, x=x), 2)
|
||||
nlocal = self.lmp.extract_global("nlocal")
|
||||
self.assertEqual(nlocal, 2)
|
||||
|
||||
self.lmp.command("mass 1 1.0")
|
||||
self.lmp.command("velocity all create 3.0 87287")
|
||||
self.lmp.command("pair_style lj/cut 2.5")
|
||||
self.lmp.command("pair_coeff 1 1 1.0 1.0 2.5")
|
||||
self.lmp.command("neighbor 0.1 bin")
|
||||
self.lmp.command("neigh_modify every 20 delay 0 check no")
|
||||
self.lmp.commands_string("""
|
||||
mass 1 1.0
|
||||
velocity all create 3.0 87287
|
||||
pair_style lj/cut 2.5
|
||||
pair_coeff 1 1 1.0 1.0 2.5
|
||||
neighbor 0.1 bin
|
||||
neigh_modify every 20 delay 0 check no
|
||||
run 0 post no""")
|
||||
|
||||
self.lmp.command("run 0")
|
||||
|
||||
self.assertEqual(self.lmp.find_pair_neighlist("lj/cut"), 0)
|
||||
nlist = self.lmp.get_neighlist(0)
|
||||
idx = self.lmp.find_pair_neighlist("lj/cut")
|
||||
self.assertNotEqual(idx, -1)
|
||||
self.assertEqual(self.lmp.find_pair_neighlist("morse"), -1)
|
||||
nlist = self.lmp.get_neighlist(idx)
|
||||
self.assertEqual(len(nlist), 2)
|
||||
atom_i, numneigh_i, neighbors_i = nlist[0]
|
||||
atom_j, numneigh_j, _ = nlist[1]
|
||||
@ -127,6 +137,193 @@ create_atoms 1 single &
|
||||
|
||||
self.assertEqual(1, neighbors_i[0])
|
||||
|
||||
def testNeighborListHalf(self):
|
||||
self.lmp.commands_string("""
|
||||
boundary f f f
|
||||
units real
|
||||
region box block -5 5 -5 5 -5 5
|
||||
create_box 1 box
|
||||
mass 1 1.0
|
||||
pair_style lj/cut 4.0
|
||||
pair_coeff 1 1 0.2 2.0
|
||||
""")
|
||||
x = [ 0.0, 0.0, 0.0, -1.1, 0.0, 0.0, 1.0, 0.0, 0.0,
|
||||
0.0, -1.1, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.1,
|
||||
0.0, 0.0, 1.0 ]
|
||||
tags = [1, 2, 3, 4, 5, 6, 7]
|
||||
types = [1, 1, 1, 1, 1, 1, 1]
|
||||
|
||||
self.assertEqual(self.lmp.create_atoms(7, id=tags, type=types, x=x), 7)
|
||||
nlocal = self.lmp.extract_global("nlocal")
|
||||
self.assertEqual(nlocal, 7)
|
||||
|
||||
self.lmp.command("run 0 post no")
|
||||
|
||||
self.assertEqual(self.lmp.find_pair_neighlist("lj/cut"),0)
|
||||
nlist = self.lmp.get_neighlist(0)
|
||||
self.assertEqual(nlist.size, 7)
|
||||
for i in range(0,nlist.size):
|
||||
idx, num, neighs = nlist.get(i)
|
||||
self.assertEqual(idx,i)
|
||||
self.assertEqual(num,nlocal-1-i)
|
||||
|
||||
# look up neighbor list by atom index
|
||||
num, neighs = nlist.find(2)
|
||||
self.assertEqual(num,4)
|
||||
self.assertIsNotNone(neighs,None)
|
||||
# this one will fail
|
||||
num, neighs = nlist.find(10)
|
||||
self.assertEqual(num,-1)
|
||||
self.assertIsNone(neighs,None)
|
||||
|
||||
@unittest.skipIf(not has_manybody,"Full neighbor list test for manybody potential")
|
||||
def testNeighborListFull(self):
|
||||
self.lmp.commands_string("""
|
||||
boundary f f f
|
||||
units metal
|
||||
region box block -5 5 -5 5 -5 5
|
||||
create_box 1 box
|
||||
mass 1 1.0
|
||||
pair_style sw
|
||||
pair_coeff * * Si.sw Si
|
||||
""")
|
||||
x = [ 0.0, 0.0, 0.0, -1.1, 0.0, 0.0, 1.0, 0.0, 0.0,
|
||||
0.0, -1.1, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.1,
|
||||
0.0, 0.0, 1.0 ]
|
||||
tags = [1, 2, 3, 4, 5, 6, 7]
|
||||
types = [1, 1, 1, 1, 1, 1, 1]
|
||||
|
||||
self.assertEqual(self.lmp.create_atoms(7, id=tags, type=types, x=x), 7)
|
||||
nlocal = self.lmp.extract_global("nlocal")
|
||||
self.assertEqual(nlocal, 7)
|
||||
|
||||
self.lmp.command("run 0 post no")
|
||||
|
||||
self.assertEqual(self.lmp.find_pair_neighlist("sw"),0)
|
||||
nlist = self.lmp.get_neighlist(0)
|
||||
self.assertEqual(nlist.size, 7)
|
||||
for i in range(0,nlist.size):
|
||||
idx, num, neighs = nlist.get(i)
|
||||
self.assertEqual(idx,i)
|
||||
self.assertEqual(num,nlocal-1)
|
||||
|
||||
@unittest.skipIf(not has_manybody,"Hybrid neighbor list test for manybody potential")
|
||||
def testNeighborListHybrid(self):
|
||||
self.lmp.commands_string("""
|
||||
boundary f f f
|
||||
units metal
|
||||
region box block -5 5 -5 5 -5 5
|
||||
create_box 2 box
|
||||
mass * 1.0
|
||||
pair_style hybrid/overlay morse 4.0 lj/cut 4.0 lj/cut 4.0 sw
|
||||
pair_coeff * * sw Si.sw Si NULL
|
||||
pair_coeff 1 2 morse 0.2 2.0 2.0
|
||||
pair_coeff 2 2 lj/cut 1 0.1 2.0
|
||||
pair_coeff * * lj/cut 2 0.01 2.0
|
||||
""")
|
||||
x = [ 0.0, 0.0, 0.0, -1.1, 0.0, 0.0, 1.0, 0.0, 0.0,
|
||||
0.0, -1.1, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.1,
|
||||
0.0, 0.0, 1.0 ]
|
||||
tags = [1, 2, 3, 4, 5, 6, 7]
|
||||
types = [1, 1, 1, 1, 2, 2, 2]
|
||||
|
||||
self.assertEqual(self.lmp.create_atoms(7, id=tags, type=types, x=x), 7)
|
||||
nlocal = self.lmp.extract_global("nlocal")
|
||||
self.assertEqual(nlocal, 7)
|
||||
|
||||
self.lmp.command("run 0 post no")
|
||||
|
||||
# valid and invalid lookups
|
||||
self.assertNotEqual(self.lmp.find_pair_neighlist("sw"),-1)
|
||||
self.assertNotEqual(self.lmp.find_pair_neighlist("morse"),-1)
|
||||
self.assertNotEqual(self.lmp.find_pair_neighlist("lj/cut",nsub=1),-1)
|
||||
self.assertNotEqual(self.lmp.find_pair_neighlist("lj/cut",nsub=2),-1)
|
||||
self.assertEqual(self.lmp.find_pair_neighlist("lj/cut"),-1)
|
||||
self.assertEqual(self.lmp.find_pair_neighlist("hybrid/overlay"),-1)
|
||||
self.assertNotEqual(self.lmp.get_neighlist(4).size,0)
|
||||
self.assertEqual(self.lmp.get_neighlist(5).size,-1)
|
||||
|
||||
# full neighbor list for 4 type 1 atoms
|
||||
# all have 3 type 1 atom neighbors
|
||||
nlist = self.lmp.get_neighlist(self.lmp.find_pair_neighlist("sw"))
|
||||
self.assertEqual(nlist.size, 4)
|
||||
for i in range(0,nlist.size):
|
||||
idx, num, neighs = nlist.get(i)
|
||||
self.assertEqual(idx,i)
|
||||
self.assertEqual(num,3)
|
||||
|
||||
# half neighbor list for all pairs between type 1 and type 2
|
||||
# 4 type 1 atoms with 3 type 2 neighbors and 3 type 2 atoms without neighbors
|
||||
nlist = self.lmp.get_neighlist(self.lmp.find_pair_neighlist("morse"))
|
||||
self.assertEqual(nlist.size, 7)
|
||||
for i in range(0,nlist.size):
|
||||
idx, num, neighs = nlist.get(i)
|
||||
if (i < 4): self.assertEqual(num,3)
|
||||
else: self.assertEqual(num,0)
|
||||
|
||||
# half neighbor list between type 2 atoms only
|
||||
# 3 pairs with 2, 1, 0 neighbors
|
||||
nlist = self.lmp.get_neighlist(self.lmp.find_pair_neighlist("lj/cut",nsub=1))
|
||||
self.assertEqual(nlist.size, 3)
|
||||
for i in range(0,nlist.size):
|
||||
idx, num, neighs = nlist.get(i)
|
||||
self.assertEqual(num,2-i)
|
||||
|
||||
# half neighbor list between all pairs. same as simple lj/cut case
|
||||
nlist = self.lmp.get_neighlist(self.lmp.find_pair_neighlist("lj/cut",nsub=2))
|
||||
self.assertEqual(nlist.size, 7)
|
||||
for i in range(0,nlist.size):
|
||||
idx, num, neighs = nlist.get(i)
|
||||
self.assertEqual(num,nlocal-1-i)
|
||||
|
||||
def testNeighborListCompute(self):
|
||||
self.lmp.commands_string("""
|
||||
boundary f f f
|
||||
units real
|
||||
region box block -5 5 -5 5 -5 5
|
||||
create_box 1 box
|
||||
mass 1 1.0
|
||||
pair_style lj/cut 4.0
|
||||
pair_coeff 1 1 0.2 2.0
|
||||
compute dist all pair/local dist
|
||||
fix dist all ave/histo 1 1 1 0.0 3.0 4 c_dist mode vector
|
||||
thermo_style custom f_dist[*]
|
||||
""")
|
||||
x = [ 0.0, 0.0, 0.0, -1.1, 0.0, 0.0, 1.0, 0.0, 0.0,
|
||||
0.0, -1.1, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.1,
|
||||
0.0, 0.0, 1.0 ]
|
||||
tags = [1, 2, 3, 4, 5, 6, 7]
|
||||
types = [1, 1, 1, 1, 1, 1, 1]
|
||||
|
||||
self.assertEqual(self.lmp.create_atoms(7, id=tags, type=types, x=x), 7)
|
||||
nlocal = self.lmp.extract_global("nlocal")
|
||||
self.assertEqual(nlocal, 7)
|
||||
|
||||
self.lmp.command("run 0 post no")
|
||||
# check compute data from histogram summary
|
||||
nhisto = self.lmp.extract_fix("dist",LMP_STYLE_GLOBAL,LMP_TYPE_VECTOR,nrow=0)
|
||||
nskip = self.lmp.extract_fix("dist",LMP_STYLE_GLOBAL,LMP_TYPE_VECTOR,nrow=1)
|
||||
minval = self.lmp.extract_fix("dist",LMP_STYLE_GLOBAL,LMP_TYPE_VECTOR,nrow=2)
|
||||
maxval = self.lmp.extract_fix("dist",LMP_STYLE_GLOBAL,LMP_TYPE_VECTOR,nrow=3)
|
||||
# 21 pair distances counted, none skipped, smallest 1.0, largest 2.1
|
||||
self.assertEqual(nhisto,21)
|
||||
self.assertEqual(nskip,0)
|
||||
self.assertEqual(minval,1.0)
|
||||
self.assertEqual(maxval,2.1)
|
||||
|
||||
self.assertNotEqual(self.lmp.find_pair_neighlist("lj/cut"),-1)
|
||||
self.assertNotEqual(self.lmp.find_compute_neighlist("dist"),-1)
|
||||
self.assertEqual(self.lmp.find_compute_neighlist("xxx"),-1)
|
||||
self.assertEqual(self.lmp.find_fix_neighlist("dist"),-1)
|
||||
|
||||
# the compute has a half neighbor list
|
||||
nlist = self.lmp.get_neighlist(self.lmp.find_compute_neighlist("dist"))
|
||||
self.assertEqual(nlist.size, 7)
|
||||
for i in range(0,nlist.size):
|
||||
idx, num, neighs = nlist.get(i)
|
||||
self.assertEqual(idx,i)
|
||||
self.assertEqual(num,nlocal-1-i)
|
||||
|
||||
def test_extract_box_non_periodic(self):
|
||||
self.lmp.command("boundary f f f")
|
||||
self.lmp.command("region box block 0 2 0 2 0 2")
|
||||
|
||||
@ -4,6 +4,17 @@ from lammps import lammps, LAMMPS_INT, LMP_STYLE_GLOBAL, LMP_STYLE_LOCAL, \
|
||||
LMP_VAR_ATOM
|
||||
from ctypes import c_void_p
|
||||
|
||||
has_manybody=False
|
||||
try:
|
||||
machine=None
|
||||
if 'LAMMPS_MACHINE_NAME' in os.environ:
|
||||
machine=os.environ['LAMMPS_MACHINE_NAME']
|
||||
lmp=lammps(name=machine)
|
||||
has_manybody = lmp.has_style("pair","sw")
|
||||
lmp.close()
|
||||
except:
|
||||
pass
|
||||
|
||||
try:
|
||||
import numpy
|
||||
NUMPY_INSTALLED = True
|
||||
@ -137,36 +148,34 @@ class PythonNumpy(unittest.TestCase):
|
||||
self.assertTrue((x[1] == (1.0, 1.0, 1.5)).all())
|
||||
self.assertEqual(len(v), 2)
|
||||
|
||||
def testNeighborList(self):
|
||||
self.lmp.command("units lj")
|
||||
self.lmp.command("atom_style atomic")
|
||||
self.lmp.command("atom_modify map array")
|
||||
self.lmp.command("boundary f f f")
|
||||
self.lmp.command("region box block 0 2 0 2 0 2")
|
||||
self.lmp.command("create_box 1 box")
|
||||
|
||||
x = [
|
||||
1.0, 1.0, 1.0,
|
||||
1.0, 1.0, 1.5
|
||||
]
|
||||
def testNeighborListSimple(self):
|
||||
self.lmp.commands_string("""
|
||||
units lj
|
||||
atom_style atomic
|
||||
atom_modify map array
|
||||
boundary f f f
|
||||
region box block 0 2 0 2 0 2
|
||||
create_box 1 box""")
|
||||
|
||||
x = [ 1.0, 1.0, 1.0, 1.0, 1.0, 1.5 ]
|
||||
types = [1, 1]
|
||||
|
||||
self.assertEqual(self.lmp.create_atoms(2, id=None, type=types, x=x), 2)
|
||||
nlocal = self.lmp.extract_global("nlocal")
|
||||
self.assertEqual(nlocal, 2)
|
||||
|
||||
self.lmp.command("mass 1 1.0")
|
||||
self.lmp.command("velocity all create 3.0 87287")
|
||||
self.lmp.command("pair_style lj/cut 2.5")
|
||||
self.lmp.command("pair_coeff 1 1 1.0 1.0 2.5")
|
||||
self.lmp.command("neighbor 0.1 bin")
|
||||
self.lmp.command("neigh_modify every 20 delay 0 check no")
|
||||
self.lmp.commands_string("""
|
||||
mass 1 1.0
|
||||
velocity all create 3.0 87287
|
||||
pair_style lj/cut 2.5
|
||||
pair_coeff 1 1 1.0 1.0 2.5
|
||||
neighbor 0.1 bin
|
||||
neigh_modify every 20 delay 0 check no
|
||||
run 0 post no""")
|
||||
|
||||
self.lmp.command("run 0")
|
||||
|
||||
self.assertEqual(self.lmp.find_pair_neighlist("lj/cut"), 0)
|
||||
nlist = self.lmp.numpy.get_neighlist(0)
|
||||
idx = self.lmp.find_pair_neighlist("lj/cut")
|
||||
self.assertNotEqual(idx, -1)
|
||||
nlist = self.lmp.numpy.get_neighlist(idx)
|
||||
self.assertEqual(len(nlist), 2)
|
||||
atom_i, neighbors_i = nlist[0]
|
||||
atom_j, neighbors_j = nlist[1]
|
||||
@ -180,6 +189,192 @@ class PythonNumpy(unittest.TestCase):
|
||||
self.assertIn(1, neighbors_i)
|
||||
self.assertNotIn(0, neighbors_j)
|
||||
|
||||
def testNeighborListHalf(self):
|
||||
self.lmp.commands_string("""
|
||||
boundary f f f
|
||||
units real
|
||||
region box block -5 5 -5 5 -5 5
|
||||
create_box 1 box
|
||||
mass 1 1.0
|
||||
pair_style lj/cut 4.0
|
||||
pair_coeff 1 1 0.2 2.0
|
||||
""")
|
||||
x = [ 0.0, 0.0, 0.0, -1.1, 0.0, 0.0, 1.0, 0.0, 0.0,
|
||||
0.0, -1.1, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.1,
|
||||
0.0, 0.0, 1.0 ]
|
||||
tags = [1, 2, 3, 4, 5, 6, 7]
|
||||
types = [1, 1, 1, 1, 1, 1, 1]
|
||||
|
||||
self.assertEqual(self.lmp.create_atoms(7, id=tags, type=types, x=x), 7)
|
||||
nlocal = self.lmp.extract_global("nlocal")
|
||||
self.assertEqual(nlocal, 7)
|
||||
|
||||
self.lmp.command("run 0 post no")
|
||||
|
||||
self.assertEqual(self.lmp.find_pair_neighlist("lj/cut"),0)
|
||||
nlist = self.lmp.numpy.get_neighlist(0)
|
||||
self.assertEqual(nlist.size, 7)
|
||||
for i in range(0,nlist.size):
|
||||
idx, neighs = nlist.get(i)
|
||||
self.assertEqual(idx,i)
|
||||
self.assertEqual(neighs.size,nlocal-1-i)
|
||||
|
||||
# look up neighbor list by atom index
|
||||
neighs = nlist.find(2)
|
||||
self.assertEqual(neighs.size,4)
|
||||
self.assertIsNotNone(neighs,None)
|
||||
# this one will fail
|
||||
neighs = nlist.find(10)
|
||||
self.assertIsNone(neighs,None)
|
||||
|
||||
@unittest.skipIf(not has_manybody,"Full neighbor list test for manybody potential")
|
||||
def testNeighborListFull(self):
|
||||
self.lmp.commands_string("""
|
||||
boundary f f f
|
||||
units metal
|
||||
region box block -5 5 -5 5 -5 5
|
||||
create_box 1 box
|
||||
mass 1 1.0
|
||||
pair_style sw
|
||||
pair_coeff * * Si.sw Si
|
||||
""")
|
||||
x = [ 0.0, 0.0, 0.0, -1.1, 0.0, 0.0, 1.0, 0.0, 0.0,
|
||||
0.0, -1.1, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.1,
|
||||
0.0, 0.0, 1.0 ]
|
||||
tags = [1, 2, 3, 4, 5, 6, 7]
|
||||
types = [1, 1, 1, 1, 1, 1, 1]
|
||||
|
||||
self.assertEqual(self.lmp.create_atoms(7, id=tags, type=types, x=x), 7)
|
||||
nlocal = self.lmp.extract_global("nlocal")
|
||||
self.assertEqual(nlocal, 7)
|
||||
|
||||
self.lmp.command("run 0 post no")
|
||||
|
||||
self.assertEqual(self.lmp.find_pair_neighlist("sw"),0)
|
||||
nlist = self.lmp.numpy.get_neighlist(0)
|
||||
self.assertEqual(nlist.size, 7)
|
||||
for i in range(0,nlist.size):
|
||||
idx, neighs = nlist.get(i)
|
||||
self.assertEqual(idx,i)
|
||||
self.assertEqual(neighs.size,nlocal-1)
|
||||
|
||||
@unittest.skipIf(not has_manybody,"Hybrid neighbor list test for manybody potential")
|
||||
def testNeighborListHybrid(self):
|
||||
self.lmp.commands_string("""
|
||||
boundary f f f
|
||||
units metal
|
||||
region box block -5 5 -5 5 -5 5
|
||||
create_box 2 box
|
||||
mass * 1.0
|
||||
pair_style hybrid/overlay morse 4.0 lj/cut 4.0 lj/cut 4.0 sw
|
||||
pair_coeff * * sw Si.sw Si NULL
|
||||
pair_coeff 1 2 morse 0.2 2.0 2.0
|
||||
pair_coeff 2 2 lj/cut 1 0.1 2.0
|
||||
pair_coeff * * lj/cut 2 0.01 2.0
|
||||
""")
|
||||
x = [ 0.0, 0.0, 0.0, -1.1, 0.0, 0.0, 1.0, 0.0, 0.0,
|
||||
0.0, -1.1, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.1,
|
||||
0.0, 0.0, 1.0 ]
|
||||
tags = [1, 2, 3, 4, 5, 6, 7]
|
||||
types = [1, 1, 1, 1, 2, 2, 2]
|
||||
|
||||
self.assertEqual(self.lmp.create_atoms(7, id=tags, type=types, x=x), 7)
|
||||
nlocal = self.lmp.extract_global("nlocal")
|
||||
self.assertEqual(nlocal, 7)
|
||||
|
||||
self.lmp.command("run 0 post no")
|
||||
|
||||
# valid and invalid lookups
|
||||
self.assertNotEqual(self.lmp.find_pair_neighlist("sw"),-1)
|
||||
self.assertNotEqual(self.lmp.find_pair_neighlist("morse"),-1)
|
||||
self.assertNotEqual(self.lmp.find_pair_neighlist("lj/cut",nsub=1),-1)
|
||||
self.assertNotEqual(self.lmp.find_pair_neighlist("lj/cut",nsub=2),-1)
|
||||
self.assertEqual(self.lmp.find_pair_neighlist("lj/cut"),-1)
|
||||
self.assertEqual(self.lmp.find_pair_neighlist("hybrid/overlay"),-1)
|
||||
self.assertNotEqual(self.lmp.numpy.get_neighlist(4).size,0)
|
||||
self.assertEqual(self.lmp.numpy.get_neighlist(5).size,-1)
|
||||
|
||||
# full neighbor list for 4 type 1 atoms
|
||||
# all have 3 type 1 atom neighbors
|
||||
nlist = self.lmp.numpy.get_neighlist(self.lmp.find_pair_neighlist("sw"))
|
||||
self.assertEqual(nlist.size, 4)
|
||||
for i in range(0,nlist.size):
|
||||
idx, neighs = nlist.get(i)
|
||||
self.assertEqual(idx,i)
|
||||
self.assertEqual(neighs.size,3)
|
||||
|
||||
# half neighbor list for all pairs between type 1 and type 2
|
||||
# 4 type 1 atoms with 3 type 2 neighbors and 3 type 2 atoms without neighbors
|
||||
nlist = self.lmp.numpy.get_neighlist(self.lmp.find_pair_neighlist("morse"))
|
||||
self.assertEqual(nlist.size, 7)
|
||||
for i in range(0,nlist.size):
|
||||
idx, neighs = nlist.get(i)
|
||||
if (i < 4): self.assertEqual(neighs.size,3)
|
||||
else: self.assertEqual(neighs.size,0)
|
||||
|
||||
# half neighbor list between type 2 atoms only
|
||||
# 3 pairs with 2, 1, 0 neighbors
|
||||
nlist = self.lmp.numpy.get_neighlist(self.lmp.find_pair_neighlist("lj/cut",nsub=1))
|
||||
self.assertEqual(nlist.size, 3)
|
||||
for i in range(0,nlist.size):
|
||||
idx, neighs = nlist.get(i)
|
||||
self.assertEqual(neighs.size,2-i)
|
||||
|
||||
# half neighbor list between all pairs. same as simple lj/cut case
|
||||
nlist = self.lmp.numpy.get_neighlist(self.lmp.find_pair_neighlist("lj/cut",nsub=2))
|
||||
self.assertEqual(nlist.size, 7)
|
||||
for i in range(0,nlist.size):
|
||||
idx, neighs = nlist.get(i)
|
||||
self.assertEqual(neighs.size,nlocal-1-i)
|
||||
|
||||
def testNeighborListCompute(self):
|
||||
self.lmp.commands_string("""
|
||||
boundary f f f
|
||||
units real
|
||||
region box block -5 5 -5 5 -5 5
|
||||
create_box 1 box
|
||||
mass 1 1.0
|
||||
pair_style lj/cut 4.0
|
||||
pair_coeff 1 1 0.2 2.0
|
||||
compute dist all pair/local dist
|
||||
fix dist all ave/histo 1 1 1 0.0 3.0 4 c_dist mode vector
|
||||
thermo_style custom f_dist[*]
|
||||
""")
|
||||
x = [ 0.0, 0.0, 0.0, -1.1, 0.0, 0.0, 1.0, 0.0, 0.0,
|
||||
0.0, -1.1, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.1,
|
||||
0.0, 0.0, 1.0 ]
|
||||
tags = [1, 2, 3, 4, 5, 6, 7]
|
||||
types = [1, 1, 1, 1, 1, 1, 1]
|
||||
|
||||
self.assertEqual(self.lmp.create_atoms(7, id=tags, type=types, x=x), 7)
|
||||
nlocal = self.lmp.extract_global("nlocal")
|
||||
self.assertEqual(nlocal, 7)
|
||||
|
||||
self.lmp.command("run 0 post no")
|
||||
# check compute data from histogram summary
|
||||
nhisto = self.lmp.extract_fix("dist",LMP_STYLE_GLOBAL,LMP_TYPE_VECTOR,nrow=0)
|
||||
nskip = self.lmp.extract_fix("dist",LMP_STYLE_GLOBAL,LMP_TYPE_VECTOR,nrow=1)
|
||||
minval = self.lmp.extract_fix("dist",LMP_STYLE_GLOBAL,LMP_TYPE_VECTOR,nrow=2)
|
||||
maxval = self.lmp.extract_fix("dist",LMP_STYLE_GLOBAL,LMP_TYPE_VECTOR,nrow=3)
|
||||
# 21 pair distances counted, none skipped, smallest 1.0, largest 2.1
|
||||
self.assertEqual(nhisto,21)
|
||||
self.assertEqual(nskip,0)
|
||||
self.assertEqual(minval,1.0)
|
||||
self.assertEqual(maxval,2.1)
|
||||
|
||||
self.assertNotEqual(self.lmp.find_pair_neighlist("lj/cut"),-1)
|
||||
self.assertNotEqual(self.lmp.find_compute_neighlist("dist"),-1)
|
||||
self.assertEqual(self.lmp.find_compute_neighlist("xxx"),-1)
|
||||
self.assertEqual(self.lmp.find_fix_neighlist("dist"),-1)
|
||||
|
||||
# the compute has a half neighbor list
|
||||
nlist = self.lmp.numpy.get_neighlist(self.lmp.find_compute_neighlist("dist"))
|
||||
self.assertEqual(nlist.size, 7)
|
||||
for i in range(0,nlist.size):
|
||||
idx, neighs = nlist.get(i)
|
||||
self.assertEqual(idx,i)
|
||||
self.assertEqual(neighs.size,nlocal-1-i)
|
||||
|
||||
def test_extract_variable_equalstyle(self):
|
||||
self.lmp.command("variable a equal 100")
|
||||
a = self.lmp.numpy.extract_variable("a")
|
||||
|
||||
Reference in New Issue
Block a user