Implement maxabs and minabs atom reduction operations
This commit is contained in:
@ -23,7 +23,7 @@ Syntax
|
|||||||
*reduce/region* arg = region-ID
|
*reduce/region* arg = region-ID
|
||||||
region-ID = ID of region to use for choosing atoms
|
region-ID = ID of region to use for choosing atoms
|
||||||
|
|
||||||
* mode = *sum* or *min* or *max* or *ave* or *sumsq* or *avesq* or *sumabs* or *aveabs*
|
* mode = *sum* or *min* or *minabs* or *max* or *maxabs* or *ave* or *sumsq* or *avesq* or *sumabs* or *aveabs*
|
||||||
* one or more inputs can be listed
|
* one or more inputs can be listed
|
||||||
* input = *x* or *y* or *z* or *vx* or *vy* or *vz* or *fx* or *fy* or *fz* or c_ID or c_ID[N] or f_ID or f_ID[N] or v_name
|
* input = *x* or *y* or *z* or *vx* or *vy* or *vz* or *fx* or *fy* or *fz* or c_ID or c_ID[N] or f_ID or f_ID[N] or v_name
|
||||||
|
|
||||||
@ -71,12 +71,13 @@ vectors.
|
|||||||
The reduction operation is specified by the *mode* setting. The *sum*
|
The reduction operation is specified by the *mode* setting. The *sum*
|
||||||
option adds the values in the vector into a global total. The *min*
|
option adds the values in the vector into a global total. The *min*
|
||||||
or *max* options find the minimum or maximum value across all vector
|
or *max* options find the minimum or maximum value across all vector
|
||||||
values. The *ave* setting adds the vector values into a global total,
|
values. The *minabs* or *maxabs* options find the minimum or maximum
|
||||||
then divides by the number of values in the vector. The *sumsq*
|
value across all absolute vector values. The *ave* setting adds the
|
||||||
option sums the square of the values in the vector into a global
|
vector values into a global total, then divides by the number of values
|
||||||
total. The *avesq* setting does the same as *sumsq*, then divides the
|
in the vector. The *sumsq* option sums the square of the values in the
|
||||||
sum of squares by the number of values. The last two options can be
|
vector into a global total. The *avesq* setting does the same as *sumsq*,
|
||||||
useful for calculating the variance of some quantity (e.g., variance =
|
then divides the sum of squares by the number of values. The last two options
|
||||||
|
can be useful for calculating the variance of some quantity (e.g., variance =
|
||||||
sumsq :math:`-` ave\ :math:`^2`). The *sumabs* option sums the absolute
|
sumsq :math:`-` ave\ :math:`^2`). The *sumabs* option sums the absolute
|
||||||
values in the vector into a global total. The *aveabs* setting does the same
|
values in the vector into a global total. The *aveabs* setting does the same
|
||||||
as *sumabs*, then divides the sum of absolute values by the number of
|
as *sumabs*, then divides the sum of absolute values by the number of
|
||||||
|
|||||||
@ -33,6 +33,34 @@ using namespace LAMMPS_NS;
|
|||||||
|
|
||||||
#define BIG 1.0e20
|
#define BIG 1.0e20
|
||||||
|
|
||||||
|
//----------------------------------------------------------------
|
||||||
|
void abs_max(void *in, void *inout, int *len, MPI_Datatype *type)
|
||||||
|
{
|
||||||
|
// r is the already reduced value, n is the new value
|
||||||
|
double n = std::fabs(*(double *) in), r = *(double *) inout;
|
||||||
|
double m;
|
||||||
|
|
||||||
|
if (n > r) {
|
||||||
|
m = n;
|
||||||
|
} else {
|
||||||
|
m = r;
|
||||||
|
}
|
||||||
|
*(double *) inout = m;
|
||||||
|
}
|
||||||
|
void abs_min(void *in, void *inout, int *len, MPI_Datatype *type)
|
||||||
|
{
|
||||||
|
// r is the already reduced value, n is the new value
|
||||||
|
double n = std::fabs(*(double *) in), r = *(double *) inout;
|
||||||
|
double m;
|
||||||
|
|
||||||
|
if (n < r) {
|
||||||
|
m = n;
|
||||||
|
} else {
|
||||||
|
m = r;
|
||||||
|
}
|
||||||
|
*(double *) inout = m;
|
||||||
|
}
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------- */
|
||||||
|
|
||||||
ComputeReduce::ComputeReduce(LAMMPS *lmp, int narg, char **arg) :
|
ComputeReduce::ComputeReduce(LAMMPS *lmp, int narg, char **arg) :
|
||||||
@ -67,10 +95,28 @@ ComputeReduce::ComputeReduce(LAMMPS *lmp, int narg, char **arg) :
|
|||||||
mode = AVESQ;
|
mode = AVESQ;
|
||||||
else if (strcmp(arg[iarg], "aveabs") == 0)
|
else if (strcmp(arg[iarg], "aveabs") == 0)
|
||||||
mode = AVEABS;
|
mode = AVEABS;
|
||||||
|
else if (strcmp(arg[iarg], "maxabs") == 0)
|
||||||
|
mode = MAXABS;
|
||||||
|
else if (strcmp(arg[iarg], "minabs") == 0)
|
||||||
|
mode = MINABS;
|
||||||
else
|
else
|
||||||
error->all(FLERR, "Unknown compute {} mode: {}", style, arg[iarg]);
|
error->all(FLERR, "Unknown compute {} mode: {}", style, arg[iarg]);
|
||||||
iarg++;
|
iarg++;
|
||||||
|
|
||||||
|
if (mode == SUM || mode == SUMSQ || mode == SUMABS) {
|
||||||
|
this->scalar_reduction_operation = MPI_SUM;
|
||||||
|
} else if (mode == AVE || mode == AVESQ || mode == AVEABS) {
|
||||||
|
this->scalar_reduction_operation = MPI_SUM;
|
||||||
|
} else if (mode == MINN) {
|
||||||
|
this->scalar_reduction_operation = MPI_MIN;
|
||||||
|
} else if (mode == MAXX) {
|
||||||
|
this->scalar_reduction_operation = MPI_MAX;
|
||||||
|
} else if (mode == MAXABS) {
|
||||||
|
MPI_Op_create(&abs_max, 1, &this->scalar_reduction_operation);
|
||||||
|
} else if (mode == MINABS) {
|
||||||
|
MPI_Op_create(&abs_min, 1, &this->scalar_reduction_operation);
|
||||||
|
}
|
||||||
|
|
||||||
// expand args if any have wildcard character "*"
|
// expand args if any have wildcard character "*"
|
||||||
|
|
||||||
int expand = 0;
|
int expand = 0;
|
||||||
@ -329,14 +375,9 @@ double ComputeReduce::compute_scalar()
|
|||||||
|
|
||||||
double one = compute_one(0, -1);
|
double one = compute_one(0, -1);
|
||||||
|
|
||||||
if (mode == SUM || mode == SUMSQ || mode == SUMABS) {
|
MPI_Allreduce(&one, &scalar, 1, MPI_DOUBLE, this->scalar_reduction_operation, world);
|
||||||
MPI_Allreduce(&one, &scalar, 1, MPI_DOUBLE, MPI_SUM, world);
|
|
||||||
} else if (mode == MINN) {
|
if (mode == AVE || mode == AVESQ || mode == AVEABS) {
|
||||||
MPI_Allreduce(&one, &scalar, 1, MPI_DOUBLE, MPI_MIN, world);
|
|
||||||
} else if (mode == MAXX) {
|
|
||||||
MPI_Allreduce(&one, &scalar, 1, MPI_DOUBLE, MPI_MAX, world);
|
|
||||||
} else if (mode == AVE || mode == AVESQ || mode == AVEABS) {
|
|
||||||
MPI_Allreduce(&one, &scalar, 1, MPI_DOUBLE, MPI_SUM, world);
|
|
||||||
bigint n = count(0);
|
bigint n = count(0);
|
||||||
if (n) scalar /= n;
|
if (n) scalar /= n;
|
||||||
}
|
}
|
||||||
@ -441,7 +482,7 @@ double ComputeReduce::compute_one(int m, int flag)
|
|||||||
int nlocal = atom->nlocal;
|
int nlocal = atom->nlocal;
|
||||||
|
|
||||||
double one = 0.0;
|
double one = 0.0;
|
||||||
if (mode == MINN) one = BIG;
|
if (mode == MINN || mode == MINABS) one = BIG;
|
||||||
if (mode == MAXX) one = -BIG;
|
if (mode == MAXX) one = -BIG;
|
||||||
|
|
||||||
if (val.which == ArgInfo::X) {
|
if (val.which == ArgInfo::X) {
|
||||||
@ -637,6 +678,11 @@ void ComputeReduce::combine(double &one, double two, int i)
|
|||||||
one = two;
|
one = two;
|
||||||
index = i;
|
index = i;
|
||||||
}
|
}
|
||||||
|
} else if (mode == MAXABS) {
|
||||||
|
if (std::fabs(two) > one) {
|
||||||
|
one = std::fabs(two);
|
||||||
|
index = i;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -26,7 +26,7 @@ namespace LAMMPS_NS {
|
|||||||
|
|
||||||
class ComputeReduce : public Compute {
|
class ComputeReduce : public Compute {
|
||||||
public:
|
public:
|
||||||
enum { SUM, SUMSQ, SUMABS, MINN, MAXX, AVE, AVESQ, AVEABS };
|
enum { SUM, SUMSQ, SUMABS, MINN, MAXX, AVE, AVESQ, AVEABS, MINABS, MAXABS };
|
||||||
enum { PERATOM, LOCAL };
|
enum { PERATOM, LOCAL };
|
||||||
|
|
||||||
ComputeReduce(class LAMMPS *, int, char **);
|
ComputeReduce(class LAMMPS *, int, char **);
|
||||||
@ -52,6 +52,7 @@ class ComputeReduce : public Compute {
|
|||||||
std::vector<value_t> values;
|
std::vector<value_t> values;
|
||||||
double *onevec;
|
double *onevec;
|
||||||
int *replace, *indices, *owner;
|
int *replace, *indices, *owner;
|
||||||
|
MPI_Op scalar_reduction_operation;
|
||||||
|
|
||||||
int index;
|
int index;
|
||||||
char *idregion;
|
char *idregion;
|
||||||
|
|||||||
Reference in New Issue
Block a user