make computes rdf and adf error out multi cutoff neighbor lists if needed

This commit is contained in:
Axel Kohlmeyer
2024-03-03 12:27:39 -05:00
parent a776d8425f
commit 2809428fe2
6 changed files with 108 additions and 91 deletions

View File

@ -204,8 +204,23 @@ angles per atom satisfying the ADF criteria.
Restrictions Restrictions
"""""""""""" """"""""""""
This compute is part of the EXTRA-COMPUTE package. It is only enabled if This compute is part of the EXTRA-COMPUTE package. It is only enabled
LAMMPS was built with that package. See the :doc:`Build package <Build_package>` page for more info. if LAMMPS was built with that package. See the :doc:`Build package
<Build_package>` page for more info.
By default, the ADF is not computed for distances longer than the
largest force cutoff, since the neighbor list creation will only contain
pairs up to that distance (plus neighbor list skin). If you use outer
cutoffs larger than that, you must use :doc:`neighbor style 'bin' or
'nsq' <neighbor>`.
If you want an ADF for a larger outer cutoff, you can also use the
:doc:`rerun <rerun>` command to post-process a dump file, use :doc:`pair
style zero <pair_zero>` and set the force cutoff to be larger in the
rerun script. Note that in the rerun context, the force cutoff is
arbitrary and with pair style zero you are not computing any forces, and
since you are not running dynamics you are not changing the model that
generated the trajectory.
The ADF is not computed for neighbors outside the force cutoff, The ADF is not computed for neighbors outside the force cutoff,
since processors (in parallel) don't know about atom coordinates for since processors (in parallel) don't know about atom coordinates for

View File

@ -176,22 +176,29 @@ also numbers :math:`\ge 0.0`.
Restrictions Restrictions
"""""""""""" """"""""""""
The RDF is not computed for distances longer than the force cutoff, By default, the RDF is not computed for distances longer than the
since processors (in parallel) do not know about atom coordinates for largest force cutoff, since the neighbor list creation will only contain
atoms further away than that distance. If you want an RDF for larger pairs up to that distance (plus neighbor list skin). This distance can
distances, you can use the :doc:`rerun <rerun>` command to post-process be increased using the *cutoff* keyword but this keyword is only valid
a dump file and set the cutoff for the potential to be longer in the with :doc:`neighbor styles 'bin' and 'nsq' <neighbor>`.
If you want an RDF for larger distances, you can also use the
:doc:`rerun <rerun>` command to post-process a dump file, use :doc:`pair
style zero <pair_zero>` and set the force cutoff to be longer in the
rerun script. Note that in the rerun context, the force cutoff is rerun script. Note that in the rerun context, the force cutoff is
arbitrary, since you are not running dynamics and thus are not changing arbitrary and with pair style zero you are not computing any forces, and
your model. The definition of :math:`g(r)` used by LAMMPS is only appropriate you are not running dynamics you are not changing the model that
for characterizing atoms that are uniformly distributed throughout the generated the trajectory.
simulation cell. In such cases, the coordination number is still
correct and meaningful. As an example, if a large simulation cell The definition of :math:`g(r)` used by LAMMPS is only appropriate for
contains only one atom of type *itypeN* and one of *jtypeN*, then :math:`g(r)` characterizing atoms that are uniformly distributed throughout the
will register an arbitrarily large spike at whatever distance they simulation cell. In such cases, the coordination number is still correct
happen to be at, and zero everywhere else. and meaningful. As an example, if a large simulation cell contains only
The function :math:`\text{coord}(r)` will show a step one atom of type *itypeN* and one of *jtypeN*, then :math:`g(r)` will
change from zero to one at the location of the spike in :math:`g(r)`. register an arbitrarily large spike at whatever distance they happen to
be at, and zero everywhere else. The function :math:`\text{coord}(r)`
will show a step change from zero to one at the location of the spike in
:math:`g(r)`.
.. note:: .. note::

View File

@ -34,7 +34,8 @@
#include <cstring> #include <cstring>
using namespace LAMMPS_NS; using namespace LAMMPS_NS;
using namespace MathConst; using MathConst::MY_PI;
using MathConst::RAD2DEG;
enum { DEGREE, RADIAN, COSINE }; enum { DEGREE, RADIAN, COSINE };
@ -43,23 +44,17 @@ enum{DEGREE, RADIAN, COSINE};
---------------------------------------------------------------------- */ ---------------------------------------------------------------------- */
ComputeADF::ComputeADF(LAMMPS *lmp, int narg, char **arg) : ComputeADF::ComputeADF(LAMMPS *lmp, int narg, char **arg) :
Compute(lmp, narg, arg), Compute(lmp, narg, arg), ilo(nullptr), ihi(nullptr), jlo(nullptr), jhi(nullptr), klo(nullptr),
ilo(nullptr), ihi(nullptr), jlo(nullptr), jhi(nullptr), klo(nullptr), khi(nullptr), khi(nullptr), hist(nullptr), histall(nullptr), rcutinnerj(nullptr), rcutinnerk(nullptr),
hist(nullptr), histall(nullptr), rcutouterj(nullptr), rcutouterk(nullptr), list(nullptr), iatomcount(nullptr),
rcutinnerj(nullptr), rcutinnerk(nullptr), iatomcountall(nullptr), iatomflag(nullptr), maxjatom(nullptr), maxkatom(nullptr),
rcutouterj(nullptr), rcutouterk(nullptr), numjatom(nullptr), numkatom(nullptr), neighjatom(nullptr), neighkatom(nullptr),
list(nullptr), jatomflag(nullptr), katomflag(nullptr), maxjkatom(nullptr), numjkatom(nullptr),
iatomcount(nullptr), iatomcountall(nullptr), iatomflag(nullptr),
maxjatom(nullptr), maxkatom(nullptr),
numjatom(nullptr), numkatom(nullptr),
neighjatom(nullptr),neighkatom(nullptr),
jatomflag(nullptr), katomflag(nullptr),
maxjkatom(nullptr), numjkatom(nullptr),
neighjkatom(nullptr), bothjkatom(nullptr), delrjkatom(nullptr) neighjkatom(nullptr), bothjkatom(nullptr), delrjkatom(nullptr)
{ {
int nargsperadf = 7; int nargsperadf = 7;
if (narg < 4 ) error->all(FLERR,"Illegal compute adf command"); if (narg < 4) utils::missing_cmd_args(FLERR, "compute adf", error);
array_flag = 1; array_flag = 1;
extarray = 0; extarray = 0;
@ -89,17 +84,16 @@ ComputeADF::ComputeADF(LAMMPS *lmp, int narg, char **arg) :
if (strcmp(arg[iarg+1],"degree") == 0) ordinate_style = DEGREE; if (strcmp(arg[iarg+1],"degree") == 0) ordinate_style = DEGREE;
else if (strcmp(arg[iarg+1],"radian") == 0) ordinate_style = RADIAN; else if (strcmp(arg[iarg+1],"radian") == 0) ordinate_style = RADIAN;
else if (strcmp(arg[iarg+1],"cosine") == 0) ordinate_style = COSINE; else if (strcmp(arg[iarg+1],"cosine") == 0) ordinate_style = COSINE;
else error->all(FLERR,"Illegal compute adf command"); else error->all(FLERR,"Unknown compute adf ordinate flag {}",arg[iarg+1]);
iarg += 2; iarg += 2;
} else error->all(FLERR,"Illegal compute adf command"); } else error->all(FLERR,"Unknown compute adf keyword {}", arg[iarg]);
} }
// triplewise args // triplewise args
if (!nargtriple) ntriples = 1; if (!nargtriple) ntriples = 1;
else { else {
if (nargtriple % nargsperadf) if (nargtriple % nargsperadf) error->all(FLERR,"Illegal compute adf command");
error->all(FLERR,"Illegal compute adf command");
ntriples = nargtriple/nargsperadf; ntriples = nargtriple/nargsperadf;
} }
@ -107,12 +101,9 @@ ComputeADF::ComputeADF(LAMMPS *lmp, int narg, char **arg) :
size_array_cols = 1 + 2*ntriples; size_array_cols = 1 + 2*ntriples;
int ntypes = atom->ntypes; int ntypes = atom->ntypes;
memory->create(iatomflag,ntriples,ntypes+1, memory->create(iatomflag,ntriples,ntypes+1,"adf:iatomflag");
"adf:iatomflag"); memory->create(jatomflag,ntriples,ntypes+1,"adf:jatomflag");
memory->create(jatomflag,ntriples,ntypes+1, memory->create(katomflag,ntriples,ntypes+1,"adf:katomflag");
"adf:jatomflag");
memory->create(katomflag,ntriples,ntypes+1,
"adf:katomflag");
ilo = new int[ntriples]; ilo = new int[ntriples];
ihi = new int[ntriples]; ihi = new int[ntriples];
@ -134,14 +125,14 @@ ComputeADF::ComputeADF(LAMMPS *lmp, int narg, char **arg) :
klo[0] = 1; khi[0] = ntypes; klo[0] = 1; khi[0] = ntypes;
} else { } else {
cutflag = 1; cutflag = 1;
if ((neighbor->style == Neighbor::MULTI) || (neighbor->style == Neighbor::MULTI_OLD))
error->all(FLERR, "Compute adf with custom cutoffs requires neighbor style 'bin' or 'nsq'");
iarg = 4; iarg = 4;
for (int m = 0; m < ntriples; m++) { for (int m = 0; m < ntriples; m++) {
utils::bounds(FLERR,arg[iarg],1,atom->ntypes,ilo[m],ihi[m],error); utils::bounds(FLERR,arg[iarg],1,atom->ntypes,ilo[m],ihi[m],error);
utils::bounds(FLERR,arg[iarg+1],1,atom->ntypes,jlo[m],jhi[m],error); utils::bounds(FLERR,arg[iarg+1],1,atom->ntypes,jlo[m],jhi[m],error);
utils::bounds(FLERR,arg[iarg+2],1,atom->ntypes,klo[m],khi[m],error); utils::bounds(FLERR,arg[iarg+2],1,atom->ntypes,klo[m],khi[m],error);
if (ilo[m] > ihi[m] || if ((ilo[m] > ihi[m]) || (jlo[m] > jhi[m]) || (klo[m] > khi[m]))
jlo[m] > jhi[m] ||
klo[m] > khi[m])
error->all(FLERR,"Illegal compute adf command"); error->all(FLERR,"Illegal compute adf command");
rcutinnerj[m] = utils::numeric(FLERR,arg[iarg+3],false,lmp); rcutinnerj[m] = utils::numeric(FLERR,arg[iarg+3],false,lmp);
rcutouterj[m] = utils::numeric(FLERR,arg[iarg+4],false,lmp); rcutouterj[m] = utils::numeric(FLERR,arg[iarg+4],false,lmp);
@ -221,8 +212,6 @@ ComputeADF::ComputeADF(LAMMPS *lmp, int narg, char **arg) :
memory->create(bothjkatom[m],maxjkatom[m],"adf:bothjkatom"); memory->create(bothjkatom[m],maxjkatom[m],"adf:bothjkatom");
memory->create(delrjkatom[m],maxjkatom[m],4,"adf:delrjkatom"); memory->create(delrjkatom[m],maxjkatom[m],4,"adf:delrjkatom");
} }
rad2deg = 180.0 / MY_PI;
} }
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
@ -282,8 +271,7 @@ void ComputeADF::init()
if (!cutflag) { if (!cutflag) {
if (!force->pair) if (!force->pair)
error->all(FLERR,"Compute adf requires a pair style be defined " error->all(FLERR,"Compute adf requires a pair style be defined or an outer cutoff specified");
"or an outer cutoff specified");
rcutinnerj[0] = 0.0; rcutinnerj[0] = 0.0;
rcutinnerk[0] = 0.0; rcutinnerk[0] = 0.0;
rcutouterj[0] = force->pair->cutforce; rcutouterj[0] = force->pair->cutforce;
@ -298,7 +286,7 @@ void ComputeADF::init()
// specify mycutneigh if force cutoff too small or non-existent // specify mycutneigh if force cutoff too small or non-existent
if (!(force->pair) || maxouter > force->pair->cutforce) { if (!(force->pair) || (maxouter > force->pair->cutforce)) {
double skin = neighbor->skin; double skin = neighbor->skin;
mycutneigh = maxouter + skin; mycutneigh = maxouter + skin;
if (mycutneigh > comm->cutghostuser) if (mycutneigh > comm->cutghostuser)
@ -310,7 +298,7 @@ void ComputeADF::init()
int x0; int x0;
if (ordinate_style == DEGREE) { if (ordinate_style == DEGREE) {
deltax = MY_PI / nbin * rad2deg; deltax = MY_PI / nbin * RAD2DEG;
deltaxinv = nbin / MY_PI; deltaxinv = nbin / MY_PI;
x0 = 0.0; x0 = 0.0;
@ -337,7 +325,11 @@ void ComputeADF::init()
// than maxouter apart, just like a normal neighbor list does // than maxouter apart, just like a normal neighbor list does
auto req = neighbor->add_request(this, NeighConst::REQ_FULL | NeighConst::REQ_OCCASIONAL); auto req = neighbor->add_request(this, NeighConst::REQ_FULL | NeighConst::REQ_OCCASIONAL);
if (mycutneigh > 0.0) req->set_cutoff(mycutneigh); if (mycutneigh > 0.0) {
if ((neighbor->style == Neighbor::MULTI) || (neighbor->style == Neighbor::MULTI_OLD))
error->all(FLERR, "Compute adf with custom cutoffs requires neighbor style 'bin' or 'nsq'");
req->set_cutoff(mycutneigh);
}
} }
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */

View File

@ -59,7 +59,6 @@ class ComputeADF : public Compute {
int **bothjkatom; // 1 if atom is in both jatom and katom lists int **bothjkatom; // 1 if atom is in both jatom and katom lists
double ***delrjkatom; // list of 4-vectors: delx, dely, delx, and 1/r double ***delrjkatom; // list of 4-vectors: delx, dely, delx, and 1/r
double rad2deg; // conversion factor from radians to degrees
int ordinate_style; // DEGREE, RADIAN, or COSINE int ordinate_style; // DEGREE, RADIAN, or COSINE
int cutflag; // 1 if at least one outer cutoff specified int cutflag; // 1 if at least one outer cutoff specified
}; };

View File

@ -96,7 +96,7 @@ ComputeRDF::ComputeRDF(LAMMPS *lmp, int narg, char **arg) :
jlo = new int[npairs]; jlo = new int[npairs];
jhi = new int[npairs]; jhi = new int[npairs];
if (nargpair == 0) { if (!nargpair) {
ilo[0] = 1; ihi[0] = ntypes; ilo[0] = 1; ihi[0] = ntypes;
jlo[0] = 1; jhi[0] = ntypes; jlo[0] = 1; jhi[0] = ntypes;
} else { } else {
@ -206,7 +206,11 @@ void ComputeRDF::init()
// than cutoff_user apart, just like a normal neighbor list does // than cutoff_user apart, just like a normal neighbor list does
auto req = neighbor->add_request(this, NeighConst::REQ_OCCASIONAL); auto req = neighbor->add_request(this, NeighConst::REQ_OCCASIONAL);
if (cutflag) req->set_cutoff(mycutneigh); if (cutflag) {
if ((neighbor->style == Neighbor::MULTI) || (neighbor->style == Neighbor::MULTI_OLD))
error->all(FLERR, "Compute rdf with custom cutoff requires neighbor style 'bin' or 'nsq'");
req->set_cutoff(mycutneigh);
}
} }
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */