A symmetric neighbor map given in a dense format like:
| 1 | 2 | 3 | 4 | 5 | 6 | |
|---|---|---|---|---|---|---|
| 1 | x | x | x | |||
| 2 | x | x | x | x | ||
| 3 | x | x | x | |||
| 4 | x | x | x | x | ||
| 5 | x | x | x | |||
| 6 | x | x | x |
is stored in two compressed arrays: nlat identifying the neighboring atom
and nltr tracking its cell index. The index array inl maps the atomic
index to the offset of its row.
inl = 1, 4, 8, 11, 15, 18, 21
nlat = 2, 4, 5, 1, 3, 5, 6, 2, 4, 6, 1, 3, 5, 6, 1, 2, 4, 2, 3, 4
nltr = 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
The first element of a row (nlat(inl(i)), nltr(inl(i))) is the diagonal
entry of the atom itself, which is always present. Either the full matrix
(complete mode) or only its upper triangular part is stored.
The slice nlat(inl(i):inl(i+1)-1) can be handed to standard CSR libraries
(MKL, cuSPARSE) directly.
Construction proceeds in three stages:
1. sort_atoms sorts the atoms into a linked cell grid,
2. build_stencil fixes which cells are scanned around each cell,
3. neighbor_pass walks the grid twice, once to size the CSR arrays and
once to fill them.
References:
Verlet neighbor list:
L. Verlet, Phys. Rev., 1967, 159, 98. DOI: 10.1103/PhysRev.159.98
Linked-cell algorithm:
R. W. Hockney, S. P. Goel, and J. W. Eastwood, J. Comput. Phys., 1974, 14, 148. DOI: 10.1016/0021-9991(74)90010-2
Hybrid approach combining Verlet and linked-cell algorithms:
D. Yao, J. Wang, and Q. Cheng, Comput. Phys. Commun., 2004, 161, 27. DOI: 10.1016/j.cpc.2004.04.004
Neighborlist in CSR format
| Type | Visibility | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|---|
| logical, | public | :: | complete |
Complete asymmetric neighbor list flag |
|||
| real(kind=wp), | public, | allocatable | :: | cutoff |
Realspace cutoff for neighborlist generation |
||
| integer(kind=i8), | public, | allocatable | :: | inl(:) |
Offset index in the neighbor map |
||
| integer, | public, | allocatable | :: | nlat(:) |
Index of the neighboring atom |
||
| integer, | public, | allocatable | :: | nltr(:) |
Cell index of the neighboring atom |
||
| real(kind=wp), | public, | allocatable | :: | trans(:,:) |
Lattice translation vector |
Cell-sorted linked cell grid used during the neighbor search
| Type | Visibility | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|---|
| integer, | public, | allocatable | :: | cellatidx(:) |
Atom index of each entry of the cell-ordered atom list |
||
| integer, | public | :: | n_xyz(3) | = | 1 |
Number of linked cells along the x, y and z direction |
|
| integer, | public | :: | ncell | = | 0 |
Total number of linked cells |
|
| integer, | public, | allocatable | :: | off(:,:) |
Stencil offsets of the cells scanned for each cell |
||
| logical, | public | :: | periodic | = | .false. |
Periodic boundaries flag of the grid |
|
| logical, | public | :: | single | = | .false. |
If true, every neighboring linked cell is a periodic unit cell, i.e., its lattice translation follows directly from the PBCs |
|
| integer, | public, | allocatable | :: | start(:) |
Offset of each cell into the cell-ordered atom list, size ncell + 1 |
||
| integer, | public | :: | trmap(-1:1,-1:1,-1:1) | = | 0 |
Index of the lattice translation for each pbc shift in {-1,0,1}^3, zero if no translation vector matches that image |
|
| real(kind=wp), | public, | allocatable | :: | x(:) |
Cell-ordered coordinates, kept as separate streams for vectorisation |
||
| real(kind=wp), | public, | allocatable | :: | y(:) |
Cell-ordered coordinates, kept as separate streams for vectorisation |
||
| real(kind=wp), | public, | allocatable | :: | z(:) |
Cell-ordered coordinates, kept as separate streams for vectorisation |
Computes linked cell grid
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(structure_type), | intent(in) | :: | mol |
Stucture type |
||
| real(kind=wp), | intent(in) | :: | cutoff |
Interaction cutoff radius |
||
| type(grid_type), | intent(out) | :: | grid |
Linked cell grid type |
||
| real(kind=wp), | intent(out) | :: | det |
Determinant (Volume) of the lattice |
||
| real(kind=wp), | intent(out), | optional | :: | lat_inv(3,3) |
Inverse of the lattice matrix, zero for a molecular system |
|
| real(kind=wp), | intent(out), | optional | :: | cell_w(3) |
Perpendicular width of each grid cell |
Build a linked cell list. Returns the chain-ordered lists ‘head’ and ‘nxt’.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(structure_type), | intent(in) | :: | mol |
Stucture type |
||
| integer, | intent(in) | :: | n_xyz(3) |
Number of linked cells along the x, y, and z directions |
||
| integer, | intent(out) | :: | head(:) |
Flattened cell-to-atom chain heads list |
||
| integer, | intent(out) | :: | nxt(:) |
Next atom in each linked-cell chain, indexed by atom |
||
| real(kind=wp), | intent(in), | optional | :: | lat_inv(3,3) |
Inverse of the lattice matrix |
|
| real(kind=wp), | intent(in), | optional | :: | cell_w(3) |
Width of each grid cell |
Create a neighbor list for a geometry and cutoff
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(csr_list), | intent(out) | :: | self |
Instance of the neighborlist |
||
| type(structure_type), | intent(in) | :: | mol |
Structure type |
||
| type(error_type), | intent(out), | optional, | allocatable | :: | error |
Error status, zero on success |
| type(wignerseitz_cell), | intent(inout), | optional | :: | wsc |
Wigner-Seitz cell type, enables the Wigner-Seitz image search |
|
| real(kind=wp), | intent(in), | optional | :: | cutoff |
Realspace cutoff for neighborlist generation |
|
| real(kind=wp), | intent(in), | optional | :: | trans(:,:) |
Lattice translation vectors for periodic systems |
|
| logical, | intent(in), | optional | :: | complete |
Flag for complete neighborlist generation |