clarify doc for fix ave/histo command

This commit is contained in:
Steve Plimpton
2023-08-21 10:54:42 -06:00
parent c6233547a5
commit ab2b83f654
4 changed files with 86 additions and 129 deletions

View File

@ -63,9 +63,11 @@ Description
""""""""""" """""""""""
Define a calculation that "reduces" one or more vector inputs into Define a calculation that "reduces" one or more vector inputs into
scalar values, one per listed input. The inputs can be per-atom or scalar values, one per listed input. For the compute reduce command,
local quantities and must all be the same kind (per-atom or local); the inputs can be either per-atom or local quantities and must all be
see discussion of the optional *inputs* keyword below. of the same kind (per-atom or local); see discussion of the optional
*inputs* keyword below. The compute reduce/region command can only be
used with per-atom inputs.
Atom attributes are per-atom quantities, :doc:`computes <compute>` and Atom attributes are per-atom quantities, :doc:`computes <compute>` and
:doc:`fixes <fix>` can generate either per-atom or local quantities, :doc:`fixes <fix>` can generate either per-atom or local quantities,
@ -92,13 +94,13 @@ values.
Each listed input is operated on independently. For per-atom inputs, Each listed input is operated on independently. For per-atom inputs,
the group specified with this command means only atoms within the the group specified with this command means only atoms within the
group contribute to the result. For per-atom inputs, if the compute group contribute to the result. Likewise for per-atom inputs, if the
reduce/region command is used, the atoms must also currently be within compute reduce/region command is used, the atoms must also currently
the region. Note that an input that produces per-atom quantities may be within the region. Note that an input that produces per-atom
define its own group which affects the quantities it returns. For quantities may define its own group which affects the quantities it
example, if a compute is used as an input which generates a per-atom returns. For example, if a compute is used as an input which
vector, it will generate values of 0.0 for atoms that are not in the generates a per-atom vector, it will generate values of 0.0 for atoms
group specified for that compute. that are not in the group specified for that compute.
Each listed input can be an atom attribute (position, velocity, force Each listed input can be an atom attribute (position, velocity, force
component) or can be the result of a :doc:`compute <compute>` or component) or can be the result of a :doc:`compute <compute>` or
@ -246,7 +248,9 @@ the quantities being reduced are in.
Restrictions Restrictions
"""""""""""" """"""""""""
none
As noted above, the compute reduce/region command can only be used
with per-atom inputs.
Related commands Related commands
"""""""""""""""" """"""""""""""""

View File

@ -79,9 +79,10 @@ Description
Use one or more values as inputs every few timesteps to create a Use one or more values as inputs every few timesteps to create a
single histogram. The histogram can then be averaged over longer single histogram. The histogram can then be averaged over longer
timescales. The resulting histogram can be used by other :doc:`output commands <Howto_output>`, and can also be written to a file. The timescales. The resulting histogram can be used by other :doc:`output
fix ave/histo/weight command has identical syntax to fix ave/histo, commands <Howto_output>`, and can also be written to a file. The fix
except that exactly two values must be specified. See details below. ave/histo/weight command has identical syntax to fix ave/histo, except
that exactly two values must be specified. See details below.
The group specified with this command is ignored for global and local The group specified with this command is ignored for global and local
input values. For per-atom input values, only atoms in the group input values. For per-atom input values, only atoms in the group
@ -96,14 +97,18 @@ different ways; see the discussion of the *beyond* keyword below.
Each input value can be an atom attribute (position, velocity, force Each input value can be an atom attribute (position, velocity, force
component) or can be the result of a :doc:`compute <compute>` or component) or can be the result of a :doc:`compute <compute>` or
:doc:`fix <fix>` or the evaluation of an equal-style or vector-style or :doc:`fix <fix>` or the evaluation of an equal-style or vector-style
atom-style :doc:`variable <variable>`. The set of input values can be or atom-style :doc:`variable <variable>`. The set of input values can
either all global, all per-atom, or all local quantities. Inputs of be either all global, all per-atom, or all local quantities. Inputs
different kinds (e.g. global and per-atom) cannot be mixed. Atom of different kinds (e.g. global and per-atom) cannot be mixed. Atom
attributes are per-atom vector values. See the page for attributes are per-atom vector values. See the page for individual
individual "compute" and "fix" commands to see what kinds of "compute" and "fix" commands to see what kinds of quantities they
quantities they generate. See the optional *kind* keyword below for generate.
how to force the fix ave/histo command to disambiguate if necessary.
Note that a compute or fix can produce multiple kinds of data (global,
per-atom, local). If LAMMPS cannot unambiguosly determine which kind
of data to use, the optional *kind* keyword discussed below can force
the desired disambiguation.
Note that the output of this command is a single histogram for all Note that the output of this command is a single histogram for all
input values combined together, not one histogram per input value. input values combined together, not one histogram per input value.
@ -258,13 +263,14 @@ keyword is set to *vector*, then all input values must be global or
per-atom or local vectors, or columns of global or per-atom or local per-atom or local vectors, or columns of global or per-atom or local
arrays. arrays.
The *kind* keyword only needs to be set if a compute or fix produces The *kind* keyword only needs to be used if any of the specfied input
more than one kind of output (global, per-atom, local). If this is computes or fixes produce more than one kind of output (global,
not the case, then LAMMPS will determine what kind of input is per-atom, local). If not, LAMMPS will determine the kind of data all
provided and whether all the input arguments are consistent. If a the inputs produce and verify it is all the same kind. If not, an
compute or fix produces more than one kind of output, the *kind* error will be triggered. If a compute or fix produces more than one
keyword should be used to specify which output will be used. The kind of output, the *kind* keyword should be used to specify which
remaining input arguments must still be consistent. output will be used. The other input arguments must still be
consistent.
The *beyond* keyword determines how input values that fall outside the The *beyond* keyword determines how input values that fall outside the
*lo* to *hi* bounds are treated. Values such that *lo* :math:`\le` value *lo* to *hi* bounds are treated. Values such that *lo* :math:`\le` value

View File

@ -35,13 +35,15 @@ static constexpr double BIG = 1.0e20;
ComputeReduceRegion::ComputeReduceRegion(LAMMPS *lmp, int narg, char **arg) : ComputeReduceRegion::ComputeReduceRegion(LAMMPS *lmp, int narg, char **arg) :
ComputeReduce(lmp, narg, arg) ComputeReduce(lmp, narg, arg)
{ {
if (input_mode == LOCAL)
error->all(FLERR,"Compute reduce/region cannot use local data as input");
} }
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------
calculate reduced value for one input M and return it calculate reduced value for one input M and return it
if flag = -1: if flag = -1:
sum/min/max/ave all values in vector sum/min/max/ave all values in vector
for per-atom quantities, limit to atoms in group and region limit to atoms in group and region
if mode = MIN or MAX, also set index to which vector value wins if mode = MIN or MAX, also set index to which vector value wins
if flag >= 0: simply return vector[flag] if flag >= 0: simply return vector[flag]
------------------------------------------------------------------------- */ ------------------------------------------------------------------------- */
@ -59,6 +61,7 @@ double ComputeReduceRegion::compute_one(int m, int flag)
// initialization in case it has not yet been run, e.g. when // initialization in case it has not yet been run, e.g. when
// the compute was invoked right after it has been created // the compute was invoked right after it has been created
if ((val.which == ArgInfo::COMPUTE) || (val.which == ArgInfo::FIX)) { if ((val.which == ArgInfo::COMPUTE) || (val.which == ArgInfo::FIX)) {
if (val.val.c == nullptr) init(); if (val.val.c == nullptr) init();
} }
@ -99,7 +102,7 @@ double ComputeReduceRegion::compute_one(int m, int flag)
// invoke compute if not previously invoked // invoke compute if not previously invoked
} else if (val.which == ArgInfo::COMPUTE) { } else if (val.which == ArgInfo::COMPUTE) {
if (input_mode == PERATOM) {
if (!(val.val.c->invoked_flag & Compute::INVOKED_PERATOM)) { if (!(val.val.c->invoked_flag & Compute::INVOKED_PERATOM)) {
val.val.c->compute_peratom(); val.val.c->compute_peratom();
val.val.c->invoked_flag |= Compute::INVOKED_PERATOM; val.val.c->invoked_flag |= Compute::INVOKED_PERATOM;
@ -124,36 +127,12 @@ double ComputeReduceRegion::compute_one(int m, int flag)
one = compute_array[flag][aidxm1]; one = compute_array[flag][aidxm1];
} }
} else if (input_mode == LOCAL) {
if (!(val.val.c->invoked_flag & Compute::INVOKED_LOCAL)) {
val.val.c->compute_local();
val.val.c->invoked_flag |= Compute::INVOKED_LOCAL;
}
if (aidx == 0) {
double *compute_vector = val.val.c->vector_local;
if (flag < 0)
for (int i = 0; i < val.val.c->size_local_rows; i++) combine(one, compute_vector[i], i);
else
one = compute_vector[flag];
} else {
double **compute_array = val.val.c->array_local;
int aidxm1 = aidx - 1;
if (flag < 0)
for (int i = 0; i < val.val.c->size_local_rows; i++)
combine(one, compute_array[i][aidxm1], i);
else
one = compute_array[flag][aidxm1];
}
}
// check if fix frequency is a match // check if fix frequency is a match
} else if (val.which == ArgInfo::FIX) { } else if (val.which == ArgInfo::FIX) {
if (update->ntimestep % val.val.f->peratom_freq) if (update->ntimestep % val.val.f->peratom_freq)
error->all(FLERR, "Fix {} used in compute {} not computed at compatible time", val.id, style); error->all(FLERR, "Fix {} used in compute {} not computed at compatible time", val.id, style);
if (input_mode == PERATOM) {
if (aidx == 0) { if (aidx == 0) {
double *fix_vector = val.val.f->vector_atom; double *fix_vector = val.val.f->vector_atom;
if (flag < 0) { if (flag < 0) {
@ -173,24 +152,6 @@ double ComputeReduceRegion::compute_one(int m, int flag)
one = fix_array[flag][aidxm1]; one = fix_array[flag][aidxm1];
} }
} else if (input_mode == LOCAL) {
if (aidx == 0) {
double *fix_vector = val.val.f->vector_local;
if (flag < 0)
for (int i = 0; i < val.val.f->size_local_rows; i++) combine(one, fix_vector[i], i);
else
one = fix_vector[flag];
} else {
double **fix_array = val.val.f->array_local;
int aidxm1 = aidx - 1;
if (flag < 0)
for (int i = 0; i < val.val.f->size_local_rows; i++)
combine(one, fix_array[i][aidxm1], i);
else
one = fix_array[flag][aidxm1];
}
}
// evaluate atom-style variable // evaluate atom-style variable
} else if (val.which == ArgInfo::VARIABLE) { } else if (val.which == ArgInfo::VARIABLE) {
@ -220,25 +181,11 @@ bigint ComputeReduceRegion::count(int m)
if (val.which == ArgInfo::X || val.which == ArgInfo::V || val.which == ArgInfo::F) if (val.which == ArgInfo::X || val.which == ArgInfo::V || val.which == ArgInfo::F)
return group->count(igroup, region); return group->count(igroup, region);
else if (val.which == ArgInfo::COMPUTE) { else if (val.which == ArgInfo::COMPUTE)
if (input_mode == PERATOM) {
return group->count(igroup, region); return group->count(igroup, region);
} else if (input_mode == LOCAL) { else if (val.which == ArgInfo::FIX)
bigint ncount = val.val.c->size_local_rows;
bigint ncountall;
MPI_Allreduce(&ncount, &ncountall, 1, MPI_DOUBLE, MPI_SUM, world);
return ncountall;
}
} else if (val.which == ArgInfo::FIX) {
if (input_mode == PERATOM) {
return group->count(igroup, region); return group->count(igroup, region);
} else if (input_mode == LOCAL) { else if (val.which == ArgInfo::VARIABLE)
bigint ncount = val.val.f->size_local_rows;
bigint ncountall;
MPI_Allreduce(&ncount, &ncountall, 1, MPI_DOUBLE, MPI_SUM, world);
return ncountall;
}
} else if (val.which == ArgInfo::VARIABLE)
return group->count(igroup, region); return group->count(igroup, region);
bigint dummy = 0; bigint dummy = 0;

View File

@ -164,7 +164,7 @@ FixAveHisto::FixAveHisto(LAMMPS *lmp, int narg, char **arg) :
} }
// check input args for kind consistency // check input args for kind consistency
// all inputs must all be global, per-atom, or local // inputs must all be all either global, per-atom, or local
if (nevery <= 0) if (nevery <= 0)
error->all(FLERR,"Illegal {} nevery value: {}", mycmd, nevery); error->all(FLERR,"Illegal {} nevery value: {}", mycmd, nevery);