Merge pull request #3034 from akohlmey/mixing-info
Provide information about pair_coeff mixing and improve hybrid docs
This commit is contained in:
@ -65,7 +65,7 @@ of some larger molecule.
|
||||
|
||||
The value *dist* is the current length of the bond.
|
||||
The values *dx*, *dy*, and *dz* are the xyz components of the
|
||||
*distance* between the pair of atoms. This value is always the
|
||||
*distance* between the pair of atoms. This value is always the
|
||||
distance from the atom of lower to the one with the higher id.
|
||||
|
||||
The value *engpot* is the potential energy for the bond,
|
||||
|
||||
@ -58,7 +58,7 @@ commands.
|
||||
|
||||
The value *dist* is the distance between the pair of atoms.
|
||||
The values *dx*, *dy*, and *dz* are the xyz components of the
|
||||
*distance* between the pair of atoms. This value is always the
|
||||
*distance* between the pair of atoms. This value is always the
|
||||
distance from the atom of lower to the one with the higher id.
|
||||
|
||||
The value *eng* is the interaction energy for the pair of atoms.
|
||||
@ -93,9 +93,9 @@ from the second of the two sub-styles. If the referenced *pN*
|
||||
is not computed for the specific pairwise interaction (based on
|
||||
atom types), then the output will be 0.0.
|
||||
|
||||
The value *dist*, *dx*, *dy* and *dz* will be in distance :doc:`units <units>`.
|
||||
The value *eng* will be in energy :doc:`units <units>`.
|
||||
The values *force*, *fx*, *fy*, and *fz* will be in force :doc:`units <units>`.
|
||||
The value *dist*, *dx*, *dy* and *dz* will be in distance :doc:`units <units>`.
|
||||
The value *eng* will be in energy :doc:`units <units>`.
|
||||
The values *force*, *fx*, *fy*, and *fz* will be in force :doc:`units <units>`.
|
||||
The values *pN* will be in whatever units the pair style defines.
|
||||
|
||||
The optional *cutoff* keyword determines how the force cutoff distance
|
||||
|
||||
@ -74,14 +74,17 @@ atoms interact with each other via an *eam* potential, the surface atoms
|
||||
interact with each other via a *lj/cut* potential, and the metal/surface
|
||||
interaction is also computed via a *lj/cut* potential. The
|
||||
*hybrid/overlay* style could be used as in the second example above,
|
||||
where multiple potentials are superposed in an additive fashion to
|
||||
where multiple potentials are superimposed in an additive fashion to
|
||||
compute the interaction between atoms. In this example, using *lj/cut*
|
||||
and *coul/long* together gives the same result as if the
|
||||
*lj/cut/coul/long* potential were used by itself. In this case, it
|
||||
would be more efficient to use the single combined potential, but in
|
||||
general any combination of pair potentials can be used together in to
|
||||
produce an interaction that is not encoded in any single pair_style
|
||||
file, e.g. adding Coulombic forces between granular particles.
|
||||
file, e.g. adding Coulombic forces between granular particles. Another
|
||||
limitation of using the *hybrid/overlay* variant, that it does not generate
|
||||
*lj/cut* parameters for mixed atom types from a mixing rule due to
|
||||
restrictions discussed below.
|
||||
|
||||
If the *hybrid/scaled* style is used instead of *hybrid/overlay*,
|
||||
contributions from sub-styles are weighted by their scale factors, which
|
||||
@ -150,10 +153,14 @@ with Tersoff, and the cross-interactions with Lennard-Jones:
|
||||
pair_coeff * * tersoff 2 C.tersoff NULL C
|
||||
pair_coeff 1 2 lj/cut 1.0 1.5
|
||||
|
||||
If pair coefficients are specified in the data file read via the
|
||||
:doc:`read_data <read_data>` command, then the same rule applies.
|
||||
E.g. "eam/alloy" or "lj/cut" must be added after the atom type, for
|
||||
each line in the "Pair Coeffs" section, e.g.
|
||||
|
||||
It is not recommended to read pair coefficients for a hybrid style from a "Pair Coeffs"
|
||||
or "PairIJ Coeffs" section of a data file via the :doc:`read_data <read_data>` command,
|
||||
since those sections expect a fixed number of lines, either one line per atom type or
|
||||
one line pair pair of atom types, respectively. When reading from a data file, the
|
||||
lines of the "Pair Coeffs" and "PairIJ Coeffs" are changed in the same way as the *pair_coeff*
|
||||
command, i.e. the name of the pair style to which the parameters apply must follow the
|
||||
atom type (or atom types), e.g.
|
||||
|
||||
.. parsed-literal::
|
||||
|
||||
@ -162,6 +169,11 @@ each line in the "Pair Coeffs" section, e.g.
|
||||
1 lj/cut/coul/cut 1.0 1.0
|
||||
...
|
||||
|
||||
PairIJ Coeffs
|
||||
|
||||
1 1 lj/cut/coul/cut 1.0 1.0
|
||||
...
|
||||
|
||||
Note that the pair_coeff command for some potentials such as
|
||||
:doc:`pair_style eam/alloy <pair_eam>` includes a mapping specification
|
||||
of elements to all atom types, which in the hybrid case, can include
|
||||
@ -208,12 +220,22 @@ examples above, or in the data file read by the :doc:`read_data
|
||||
<read_data>`, or by mixing as described below. Also all sub-styles
|
||||
must be used at least once in a :doc:`pair_coeff <pair_coeff>` command.
|
||||
|
||||
.. note::
|
||||
.. warning::
|
||||
|
||||
LAMMPS never performs mixing of parameters from different sub-styles,
|
||||
**even** if they use the same type of coefficients, e.g. contain
|
||||
a Lennard-Jones potential variant. Those parameters must be provided
|
||||
explicitly.
|
||||
With hybrid pair styles the use of mixing to generate pair
|
||||
coefficients is significantly limited compared to the individual pair
|
||||
styles. LAMMPS **never** performs mixing of parameters from
|
||||
different sub-styles, **even** if they use the same type of
|
||||
coefficients, e.g. contain a Lennard-Jones potential variant. Those
|
||||
parameters must be provided explicitly. Also for *hybrid/overlay*
|
||||
and *hybrid/scaled* mixing is **only** performed for pairs of atom
|
||||
types for which only a single pair style is assigned.
|
||||
|
||||
Thus it is strongly recommended to provide all mixed terms
|
||||
explicitly. For non-hybrid styles those could be generated and
|
||||
written out using the :doc:`write_coeff command <write_coeff>` and
|
||||
then edited as needed to comply with the requirements for hybrid
|
||||
styles as explained above.
|
||||
|
||||
If you want there to be no interactions between a particular pair of
|
||||
atom types, you have 3 choices. You can assign the pair of atom types
|
||||
|
||||
@ -71,21 +71,23 @@ The *mix* keyword affects pair coefficients for interactions between
|
||||
atoms of type I and J, when I != J and the coefficients are not
|
||||
explicitly set in the input script. Note that coefficients for I = J
|
||||
must be set explicitly, either in the input script via the
|
||||
:doc:`pair_coeff <pair_coeff>` command or in the "Pair Coeffs" section of the
|
||||
:doc:`data file <read_data>`. For some pair styles it is not
|
||||
:doc:`pair_coeff <pair_coeff>` command or in the "Pair Coeffs" or "PairIJ Coeffs"
|
||||
sections of the :doc:`data file <read_data>`. For some pair styles it is not
|
||||
necessary to specify coefficients when I != J, since a "mixing" rule
|
||||
will create them from the I,I and J,J settings. The pair_modify
|
||||
*mix* value determines what formulas are used to compute the mixed
|
||||
coefficients. In each case, the cutoff distance is mixed the same way
|
||||
as sigma.
|
||||
|
||||
Note that not all pair styles support mixing and some mix options
|
||||
are not available for certain pair styles. Also, there are additional
|
||||
restrictions when using :doc:`pair style hybrid or hybrid/overlay <pair_hybrid>`.
|
||||
See the page for individual pair styles for those restrictions. Note also that the
|
||||
:doc:`pair_coeff <pair_coeff>` command also can be used to directly set
|
||||
coefficients for a specific I != J pairing, in which case no mixing is
|
||||
performed.
|
||||
Note that not all pair styles support mixing and some mix options are
|
||||
not available for certain pair styles. Also, there are additional
|
||||
restrictions when using :doc:`pair style hybrid or hybrid/overlay
|
||||
<pair_hybrid>`. See the page for individual pair styles for those
|
||||
restrictions. Note also that the :doc:`pair_coeff <pair_coeff>` command
|
||||
also can be used to directly set coefficients for a specific I != J
|
||||
pairing, in which case no mixing is performed. If possible, LAMMPS will
|
||||
print an informational message about how many of the mixed pair
|
||||
coefficients were generated and which mixing rule was applied.
|
||||
|
||||
- mix *geometric*
|
||||
|
||||
|
||||
24
src/pair.cpp
24
src/pair.cpp
@ -41,6 +41,7 @@ using namespace LAMMPS_NS;
|
||||
using namespace MathConst;
|
||||
|
||||
enum{NONE,RLINEAR,RSQ,BMP};
|
||||
static const std::string mixing_rule_names[Pair::SIXTHPOWER+1] = {"geometric", "arithmetic", "sixthpower" };
|
||||
|
||||
// allocate space for static class instance variable and initialize it
|
||||
|
||||
@ -217,11 +218,9 @@ void Pair::init()
|
||||
if (tail_flag && domain->nonperiodic && comm->me == 0)
|
||||
error->warning(FLERR,"Using pair tail corrections with non-periodic system");
|
||||
if (!compute_flag && tail_flag && comm->me == 0)
|
||||
error->warning(FLERR,"Using pair tail corrections with "
|
||||
"pair_modify compute no");
|
||||
error->warning(FLERR,"Using pair tail corrections with pair_modify compute no");
|
||||
if (!compute_flag && offset_flag && comm->me == 0)
|
||||
error->warning(FLERR,"Using pair potential shift with "
|
||||
"pair_modify compute no");
|
||||
error->warning(FLERR,"Using pair potential shift with pair_modify compute no");
|
||||
|
||||
// for manybody potentials
|
||||
// check if bonded exclusions could invalidate the neighbor list
|
||||
@ -259,13 +258,18 @@ void Pair::init()
|
||||
etail = ptail = 0.0;
|
||||
mixed_flag = 1;
|
||||
double cut;
|
||||
int mixed_count = 0;
|
||||
|
||||
for (i = 1; i <= atom->ntypes; i++)
|
||||
for (j = i; j <= atom->ntypes; j++) {
|
||||
if ((i != j) && setflag[i][j]) mixed_flag = 0;
|
||||
did_mix = false;
|
||||
cut = init_one(i,j);
|
||||
cutsq[i][j] = cutsq[j][i] = cut*cut;
|
||||
cutforce = MAX(cutforce,cut);
|
||||
if (i != j) {
|
||||
if (setflag[i][j]) mixed_flag = 0;
|
||||
if (did_mix) ++mixed_count;
|
||||
}
|
||||
if (tail_flag) {
|
||||
etail += etail_ij;
|
||||
ptail += ptail_ij;
|
||||
@ -275,6 +279,12 @@ void Pair::init()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!manybody_flag && (comm->me == 0)) {
|
||||
const int num_mixed_pairs = atom->ntypes * (atom->ntypes - 1) / 2;
|
||||
utils::logmesg(lmp," generated {} of {} mixed pair_coeff terms from {} mixing rule\n",
|
||||
mixed_count, num_mixed_pairs, mixing_rule_names[mix_flag]);
|
||||
}
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
@ -681,6 +691,7 @@ void Pair::free_disp_tables()
|
||||
|
||||
double Pair::mix_energy(double eps1, double eps2, double sig1, double sig2)
|
||||
{
|
||||
did_mix = true;
|
||||
if (mix_flag == GEOMETRIC)
|
||||
return sqrt(eps1*eps2);
|
||||
else if (mix_flag == ARITHMETIC)
|
||||
@ -688,7 +699,8 @@ double Pair::mix_energy(double eps1, double eps2, double sig1, double sig2)
|
||||
else if (mix_flag == SIXTHPOWER)
|
||||
return (2.0 * sqrt(eps1*eps2) *
|
||||
pow(sig1,3.0) * pow(sig2,3.0) / (pow(sig1,6.0) + pow(sig2,6.0)));
|
||||
else return 0.0;
|
||||
else did_mix = false;
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
|
||||
@ -110,6 +110,7 @@ class Pair : protected Pointers {
|
||||
// public so external driver can check
|
||||
int compute_flag; // 0 if skip compute()
|
||||
int mixed_flag; // 1 if all itype != jtype coeffs are from mixing
|
||||
bool did_mix; // set to true by mix_energy() to indicate that mixing was performed
|
||||
|
||||
enum { GEOMETRIC, ARITHMETIC, SIXTHPOWER }; // mixing options
|
||||
|
||||
|
||||
@ -706,11 +706,10 @@ double PairHybrid::init_one(int i, int j)
|
||||
for (int k = 0; k < nmap[i][j]; k++) {
|
||||
map[j][i][k] = map[i][j][k];
|
||||
double cut = styles[map[i][j][k]]->init_one(i,j);
|
||||
styles[map[i][j][k]]->cutsq[i][j] =
|
||||
styles[map[i][j][k]]->cutsq[j][i] = cut*cut;
|
||||
if (styles[map[i][j][k]]->did_mix) did_mix = true;
|
||||
styles[map[i][j][k]]->cutsq[i][j] = styles[map[i][j][k]]->cutsq[j][i] = cut*cut;
|
||||
if (styles[map[i][j][k]]->ghostneigh)
|
||||
cutghost[i][j] = cutghost[j][i] =
|
||||
MAX(cutghost[i][j],styles[map[i][j][k]]->cutghost[i][j]);
|
||||
cutghost[i][j] = cutghost[j][i] = MAX(cutghost[i][j],styles[map[i][j][k]]->cutghost[i][j]);
|
||||
if (tail_flag) {
|
||||
etail_ij += styles[map[i][j][k]]->etail_ij;
|
||||
ptail_ij += styles[map[i][j][k]]->ptail_ij;
|
||||
|
||||
Reference in New Issue
Block a user