describe new neighbor list request APIs
This commit is contained in:
@ -65,6 +65,139 @@ when converting "12.5", while the ValueTokenizer class will throw an
|
||||
:cpp:func:`ValueTokenizer::next_int()
|
||||
<LAMMPS_NS::ValueTokenizer::next_int>` is called on the same string.
|
||||
|
||||
Requesting and accessing neighbor lists
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
LAMMPS uses Verlet-style neighbor lists to avoid having to loop over
|
||||
*all* pairs of *all* atoms when computing pairwise properties with a
|
||||
cutoff (e.g. pairwise forces or radial distribution functions). There
|
||||
are three main algorithms that can be selected by the :doc:`neighbor
|
||||
command <neighbor>`: `bin` (the default, uses binning to achieve linear
|
||||
scaling with system size), `nsq` (without binning, quadratic scaling),
|
||||
`multi` (with binning, optimized for varying cutoffs or polydisperse
|
||||
granular particles). In addition how the neighbor lists are constructed
|
||||
a number of different variants of neighbor lists need to be created
|
||||
(e.g. "full" or "half") for different purposes and styles and those may
|
||||
be be required in every time step ("perpetual") or on some steps
|
||||
("occasional").
|
||||
|
||||
The neighbor list creation is managed by the ``Neighbor`` class.
|
||||
Individual classes can obtain a neighbor list by creating an instance of
|
||||
a ``NeighRequest`` class which is stored in a list inside the
|
||||
``Neighbor`` class. The ``Neighbor`` class will then analyze the
|
||||
various requests and apply optimizations where neighbor lists that have
|
||||
the same settings will be created only once and then copied, or a list
|
||||
may be constructed by processing a neighbor list from a different
|
||||
request that is a superset of the requested list. The neighbor list
|
||||
build is then :doc:`processed in parallel <Developer_par_neigh>`.
|
||||
|
||||
The most commonly required neighbor list is a so-called "half" neighbor
|
||||
list requested by a pair style, where each pair of atoms is listed only
|
||||
once (except when then :doc:`newton command setting <newton>` for pair
|
||||
is off; in that case pairs straddling sub-domains or periodic boundaries
|
||||
will be listed twice). Thus these are the default settings when a
|
||||
neighbor list request is created in:
|
||||
|
||||
.. code-block:: C++
|
||||
|
||||
void Pair::init_style()
|
||||
{
|
||||
neighbor->add_request(this, NeighConst::REQ_DEFAULT);
|
||||
}
|
||||
|
||||
void Pair::init_list(int /*id*/, NeighList *ptr)
|
||||
{
|
||||
list = ptr;
|
||||
}
|
||||
|
||||
The ``this`` pointer argument is required so the neighbor list code can
|
||||
access the requesting class instance to store the assembled neighbor
|
||||
list with that instance by calling its ``init_list()`` member function.
|
||||
The second argument contains a bitmask of flags that determines the kind
|
||||
of neighbor list, i.e. a perpetual "half" neighbor list here.
|
||||
|
||||
To adjust a neighbor list request to the specific needs of a style
|
||||
usually just a different additional request flag is needed. The :doc:`tersoff <pair_tersoff>` pair
|
||||
style, for example, needs a "full" neighbor list:
|
||||
|
||||
.. code-block:: C++
|
||||
|
||||
void PairTersoff::init_style()
|
||||
{
|
||||
// [...]
|
||||
neighbor->add_request(this, NeighConst::REQ_FULL);
|
||||
}
|
||||
|
||||
When a pair style supports r-RESPA time integration with different cutoff regions,
|
||||
the request flag may depend on the corresponding r-RESPA settings. Here an example
|
||||
from pair style lj/cut:
|
||||
|
||||
.. code-block:: C++
|
||||
|
||||
void PairLJCut::init_style()
|
||||
{
|
||||
int list_style = NeighConst::REQ_DEFAULT;
|
||||
|
||||
if (update->whichflag == 1 && utils::strmatch(update->integrate_style, "^respa")) {
|
||||
auto respa = (Respa *) update->integrate;
|
||||
if (respa->level_inner >= 0) list_style = NeighConst::REQ_RESPA_INOUT;
|
||||
if (respa->level_middle >= 0) list_style = NeighConst::REQ_RESPA_ALL;
|
||||
}
|
||||
neighbor->add_request(this, list_style);
|
||||
// [...]
|
||||
}
|
||||
|
||||
In case a class would need to make multiple neighbor list requests with different
|
||||
settings each request can set an id which is then used in the corresponding
|
||||
``init_list()`` function to assign it to the suitable pointer variable. This is
|
||||
done for example by the :doc:`pair style meam <pair_meam>`:
|
||||
|
||||
.. code-block:: C++
|
||||
|
||||
void PairMEAM::init_style()
|
||||
{
|
||||
// [...]
|
||||
neighbor->add_request(this, NeighConst::REQ_FULL)->set_id(1);
|
||||
neighbor->add_request(this, NeighConst::REQ_DEFAULT)->set_id(2);
|
||||
}
|
||||
void PairMEAM::init_list(int id, NeighList *ptr)
|
||||
{
|
||||
if (id == 1) listfull = ptr;
|
||||
else if (id == 2) listhalf = ptr;
|
||||
}
|
||||
|
||||
Fixes may require a neighbor list that is only build occasionally (or
|
||||
just once) and this can also be indicated by a flag. As an example here
|
||||
is the request from the ``FixPeriNeigh`` class which is created
|
||||
internally by :doc:`Peridynamics pair styles <pair_peri>`:
|
||||
|
||||
.. code-block:: C++
|
||||
|
||||
neighbor->add_request(this, NeighConst::REQ_FULL|NeighConst::REQ_OCCASIONAL);
|
||||
|
||||
It is also possible to request a neighbor list that uses a different cutoff
|
||||
than what is usually inferred from the pair style settings (largest cutoff of
|
||||
all pair styles plus neighbor list skin). The following is used in the
|
||||
:doc:`compute rdf <compute_rdf>` command implementation:
|
||||
|
||||
.. code-block:: C++
|
||||
|
||||
if (cutflag)
|
||||
neighbor->add_request(this,NeighConst::REQ_OCCASIONAL)->set_cutoff(mycutneigh);
|
||||
else
|
||||
neighbor->add_request(this,NeighConst::REQ_OCCASIONAL);
|
||||
|
||||
The neighbor list request function has a slightly different set of arguments
|
||||
when created by a command style. In this case the neighbor list is
|
||||
*always* an occasional neighbor list, so that flag is not needed. However
|
||||
for printing the neighbor list summary the name of the requesting command
|
||||
should be set. Below is the request from the :doc:`delete atoms <delete_atoms>`
|
||||
command:
|
||||
|
||||
.. code-block:: C++
|
||||
|
||||
neighbor->add_request(this, "delete_atoms", NeighConst::REQ_FULL);
|
||||
|
||||
Fix contributions to instantaneous energy, virial, and cumulative energy
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
|
||||
Reference in New Issue
Block a user