Merge pull request #2694 from akohlmey/neighlist-interface-updates

Neighbor list library/python interface improvements
This commit is contained in:
Axel Kohlmeyer
2021-04-07 16:25:38 -04:00
committed by GitHub
18 changed files with 760 additions and 161 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -2681,6 +2681,7 @@ representable
Reproducibility
reproducibility
repuls
reqid
rescale
rescaled
rescales

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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,28 +3921,33 @@ 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) {
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);
@ -3946,11 +3955,9 @@ int lammps_find_pair_neighlist(void* handle, char * style, int exact, int nsub,
// 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;
}
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) {
int lammps_find_fix_neighlist(void *handle, const char *id, int reqid) {
LAMMPS *lmp = (LAMMPS *) handle;
Fix* fix = nullptr;
const int nfix = lmp->modify->nfix;
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) {
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) continue;
if (list->index == request) {
return 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) {
int lammps_find_compute_neighlist(void* handle, const char *id, int reqid) {
LAMMPS *lmp = (LAMMPS *) handle;
Compute* compute = nullptr;
const int ncompute = lmp->modify->ncompute;
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) {
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) continue;
if (list->index == request) {
return i;
}
}
if ( (list->requestor_type == NeighList::COMPUTE)
&& (compute == list->requestor)
&& (list->id == reqid) ) return i;
}
return -1;
}

View File

@ -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);

View File

@ -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];

View File

@ -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

View File

@ -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)

View File

@ -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;

View File

@ -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()

View File

@ -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")

View File

@ -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")