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()
|
:cpp:func:`ValueTokenizer::next_int()
|
||||||
<LAMMPS_NS::ValueTokenizer::next_int>` is called on the same string.
|
<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
|
Fix contributions to instantaneous energy, virial, and cumulative energy
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user