Compare commits
7 Commits
develop
...
rigid-shea
| Author | SHA1 | Date | |
|---|---|---|---|
| a83489e511 | |||
| 79ccd302c2 | |||
| 64b23c90a6 | |||
| d00f376453 | |||
| d556bfe0c4 | |||
| 83e5146ec9 | |||
| f7a2833829 |
@ -783,109 +783,134 @@ x-component of velocity if the atom-attribute "vx" was specified.
|
|||||||
The basic idea of a color map is that the atom-attribute will be
|
The basic idea of a color map is that the atom-attribute will be
|
||||||
within a range of values, and that range is associated with a series
|
within a range of values, and that range is associated with a series
|
||||||
of colors (e.g. red, blue, green). An atom's specific value (vx =
|
of colors (e.g. red, blue, green). An atom's specific value (vx =
|
||||||
-3.2) can then mapped to the series of colors (e.g. halfway between
|
-3.2) can then be mapped to a specific color. The details of the
|
||||||
red and blue), and a specific color is determined via an interpolation
|
mapping procedure depend on the *style* of the color map, as explained
|
||||||
procedure.
|
below.
|
||||||
|
|
||||||
There are many possible options for the color map, enabled by the
|
There are many possible options for defining a color map, enabled by
|
||||||
*amap* keyword. Here are the details.
|
the *amap* keyword. Here are the details.
|
||||||
|
|
||||||
The *lo* and *hi* settings determine the range of values allowed for
|
The *lo* and *hi* settings determine the range of values allowed for
|
||||||
the atom attribute. If numeric values are used for *lo* and/or *hi*,
|
the atom attribute. If numeric values are used for *lo* and/or *hi*,
|
||||||
then values that are lower/higher than that value are set to the
|
then individual atom values which are lower/higher than lo/hi are set
|
||||||
value. I.e. the range is static. If *lo* is specified as *min* or
|
to lo/hi for purposes of determining the atom's color. I.e. the range
|
||||||
*hi* as *max* then the range is dynamic, and the lower and/or
|
is static. If *lo* is specified as *min* or *hi* as *max* then the
|
||||||
upper bound will be calculated each time an image is drawn, based
|
range is dynamic. The lower and/or upper bound will be calculated
|
||||||
on the set of atoms being visualized.
|
each time an image is drawn, based on the current atom values of all
|
||||||
|
the atoms being visualized.
|
||||||
|
|
||||||
The *style* setting is two letters, such as "ca". The first letter is
|
The *style* setting is two letters, such as "ca". The first letter is
|
||||||
either "c" for continuous, "d" for discrete, or "s" for sequential.
|
either "c" for continuous, "d" for discrete, or "s" for sequential.
|
||||||
The second letter is either "a" for absolute, or "f" for fractional.
|
The second letter is either "a" for absolute, or "f" for fractional.
|
||||||
|
|
||||||
A continuous color map is one in which the color changes continuously
|
A *continuous* color map is one in which the color of an atom changes
|
||||||
from value to value within the range. A discrete color map is one in
|
continuously as its attribute value increases within the range.
|
||||||
which discrete colors are assigned to sub-ranges of values within the
|
Colors are assigned to specific values within the range; an atom with
|
||||||
range. A sequential color map is one in which discrete colors are
|
an attribue value between two adjacent specific values is assigned a
|
||||||
assigned to a sequence of sub-ranges of values covering the entire
|
color interpolated between the two adjacent colors.
|
||||||
range.
|
|
||||||
|
|
||||||
An absolute color map is one in which the values to which colors are
|
A *discrete* color map is one in which discrete colors are assigned to
|
||||||
assigned are specified explicitly as values within the range. A
|
sub-ranges of values within the overall range. Each sub-range can be
|
||||||
fractional color map is one in which the values to which colors are
|
of variable width and overlap with other sub-ranges. An atom with an
|
||||||
assigned are specified as a fractional portion of the range. For
|
attribute value is mapped to one of the sub-ranges and assigned that
|
||||||
example if the range is from -10.0 to 10.0, and the color red is to be
|
color.
|
||||||
assigned to atoms with a value of 5.0, then for an absolute color map
|
|
||||||
the number 5.0 would be used. But for a fractional map, the number
|
A *sequential* color map is similar to a discrete color map except that
|
||||||
0.75 would be used since 5.0 is 3/4 of the way from -10.0 to 10.0.
|
all sub-ranges are of equal width and discrete colors are assigned to
|
||||||
|
each sub-range in a round-robin fashion until the overall range is
|
||||||
|
covered from *lo* to *hi*.
|
||||||
|
|
||||||
|
An *absolute* color map is one in which the numeric settings
|
||||||
|
associated with assigned colors are specified explicitly as values
|
||||||
|
within the range.
|
||||||
|
|
||||||
|
A *fractional* color map is one in which the numeric settings
|
||||||
|
associated with assigned colors are specified as a fractional position
|
||||||
|
within the range.
|
||||||
|
|
||||||
|
For a continuous color map, the numeric settings are the specific
|
||||||
|
values each color is assigned to. For a discrete color map, the
|
||||||
|
numeric settings are the bounds of each sub-range. For a sequential
|
||||||
|
color map, the numeric settings is the width of all the sub-ranges.
|
||||||
|
For example if the overall range is from -10.0 to 10.0, and the color
|
||||||
|
red is to be assigned to atoms with an attribute value of 5.0, then
|
||||||
|
for an absolute color map the numeric value of 5.0 should map to red.
|
||||||
|
But for a fractional map, the numeric value of 0.75 should map to red,
|
||||||
|
since 5.0 is 3/4 of the way from -10.0 to 10.0.
|
||||||
|
|
||||||
The *delta* setting must be specified for all styles, but is only used
|
The *delta* setting must be specified for all styles, but is only used
|
||||||
for the sequential style; otherwise the value is ignored. It
|
for the *sequential* style; otherwise the setting is ignored. It
|
||||||
specifies the bin size to use within the range for assigning
|
specifies the bin size of the sub-ranges of values described above,
|
||||||
consecutive colors to. For example, if the range is from :math:`-10.0` to
|
For example, if the overall range is from :math:`-10.0` to
|
||||||
:math:`10.0` and a *delta* of :math:`1.0` is used, then 20 colors will be
|
:math:`10.0` and a *delta* of :math:`1.0` is used, then 20 colors will
|
||||||
assigned to the range. The first will be from
|
be assigned to a series of sub-ranges. The first sub-range will be
|
||||||
:math:`-10.0 \le \text{color1} < -9.0`, then second from
|
from :math:`-10.0 \le \text{color1} < -9.0`, the second from
|
||||||
:math:`-9.0 \le color2 < -8.0`, etc.
|
:math:`-9.0 \le color2 < -8.0`, etc.
|
||||||
|
|
||||||
The *N* setting is how many entries follow. The format of the entries
|
The *N* setting is how many color entries follow. The format of each
|
||||||
depends on whether the color map style is continuous, discrete or
|
color entry depends on whether the color map style is continuous,
|
||||||
sequential. In all cases the *color* setting can be any of the 140
|
discrete, or sequential. For each entry, the specified *color* can be
|
||||||
pre-defined colors (see below) or a color name defined by the
|
any of the 140 pre-defined colors (see below) or a color name defined
|
||||||
dump_modify color option.
|
by the dump_modify color option.
|
||||||
|
|
||||||
For continuous color maps, each entry has a *value* and a *color*\ .
|
For *continuous* color maps, each entry has a *value* and a *color*\ .
|
||||||
The *value* is either a number within the range of values or *min* or
|
The *value* is either a number within the *lo/hi* range of values or
|
||||||
*max*\ . The *value* of the first entry must be *min* and the *value*
|
*min* or *max*\ . The *value* for the first entry must be *min* and
|
||||||
of the last entry must be *max*\ . Any entries in between must have
|
the *value* for the last entry must be *max*\ . In-between entries
|
||||||
increasing values. Note that numeric values can be specified either
|
must have increasing numeric values. There must be 2 or more entries.
|
||||||
as absolute numbers or as fractions (0.0 to 1.0) of the range,
|
Note that numeric values are specified either as absolute numbers or
|
||||||
depending on the "a" or "f" in the style setting for the color map.
|
as fractions (0.0 to 1.0) of the range, depending on the "a" or "f" in
|
||||||
|
the style setting for the color map.
|
||||||
|
|
||||||
Here is how the entries are used to determine the color of an individual
|
Here is how the *N* entries are used to determine the color of an
|
||||||
atom, given the value :math:`X` of its atom attribute. :math:`X` will
|
individual atom, based on the value :math:`X` of its atom attribute.
|
||||||
fall between 2 of the entry values. The color of the atom is linearly
|
:math:`X` will fall between 2 of the entry values. The color of the
|
||||||
interpolated (in each of the RGB values) between the 2 colors associated
|
atom is linearly interpolated (in each of the RGB values) between the
|
||||||
with those entries. For example, if :math:`X = -5.0` and the two
|
2 colors associated with those entries. For example, if :math:`X =
|
||||||
surrounding entries are "red" at :math:`-10.0` and "blue" at
|
-5.0` and the two surrounding entries are "red" at :math:`-10.0` and
|
||||||
:math:`0.0`, then the atom's color will be halfway between "red" and
|
"blue" at :math:`0.0`, then the atom's color will be halfway between
|
||||||
"blue", which happens to be "purple".
|
"red" and "blue", which in this case is "purple".
|
||||||
|
|
||||||
For discrete color maps, each entry has a *lo* and *hi* value and a
|
For *discrete* color maps, each entry has a *lo* and *hi* value and a
|
||||||
*color*\ . The *lo* and *hi* settings are either numbers within the
|
*color*\ . The *lo* and *hi* settings are either numbers within the
|
||||||
range of values or *lo* can be *min* or *hi* can be *max*\ . The *lo*
|
range of values or *min* (for *lo) or *max* (for *hi*). The *lo* and
|
||||||
and *hi* settings of the last entry must be *min* and *max*\ . Other
|
*hi* settings of the last entry must be *min* and *max*\ . Other
|
||||||
entries can have any *lo* and *hi* values and the sub-ranges of
|
entries can have any *lo* and *hi* values and the sub-ranges of
|
||||||
different values can overlap. Note that numeric *lo* and *hi* values
|
different entries can overlap. There must be one or more entries.
|
||||||
can be specified either as absolute numbers or as fractions (0.0 to 1.0)
|
Note that numeric *lo* and *hi* values are specified either as
|
||||||
of the range, depending on the "a" or "f" in the style setting for the
|
absolute numbers or as fractions (0.0 to 1.0) of the range, depending
|
||||||
color map.
|
on the "a" or "f" in the style setting for the color map. The lo/hi
|
||||||
|
values in each sub-range must satisfy lo < hi.
|
||||||
|
|
||||||
Here is how the entries are used to determine the color of an individual
|
Here is how the *N* entries are used to determine the color of an
|
||||||
atom, given the value X of its atom attribute. The entries are scanned
|
individual atom, based on the value :math:`X` of its atom attribute.
|
||||||
from first to last. The first time that *lo* <= X <= *hi*, X is
|
The entries are scanned from first to last. The first time that *lo*
|
||||||
assigned the color associated with that entry. You can think of the
|
<= X <= *hi*, X is assigned the color associated with that entry.
|
||||||
last entry as assigning a default color (since it will always be matched
|
This means can the last entry can be thought of as a default color
|
||||||
by X), and the earlier entries as colors that override the default.
|
(since it will always be matched by X); the earlier entries override
|
||||||
Also note that no interpolation of a color RGB is done. All atoms will
|
the default. Note that for a *discrete* map, no interpolation of a
|
||||||
be drawn with one of the colors in the list of entries.
|
color RGB values is done. All atoms will be drawn with one of the
|
||||||
|
colors in the list of entries.
|
||||||
|
|
||||||
For sequential color maps, each entry has only a *color*\ . Here is how
|
For *sequential* color maps, each entry has only a *color*\ . There
|
||||||
the entries are used to determine the color of an individual atom,
|
must be 1 or more entries. Here is how the *N* entries are used to
|
||||||
given the value X of its atom attribute. The range is partitioned
|
determine the color of an individual atom, given the value X of its
|
||||||
into N bins of width *binsize*\ . Thus X will fall in a specific bin
|
atom attribute. The range is overlaid with M bins of width *delta*\ ,
|
||||||
from 1 to N, say the Mth bin. If it falls on a boundary between 2
|
the last of which may extend beyond the *hi* boundary of the range.
|
||||||
bins, it is considered to be in the higher of the 2 bins. Each bin is
|
Thus X will fall in a specific bin from 1 to M. If it falls on a
|
||||||
assigned a color from the E entries. If E < N, then the colors are
|
boundary between 2 bins, it is considered to be in the higher of the 2
|
||||||
repeated. For example if 2 entries with colors red and green are
|
bins (except in the case of 2 bins whose boundary is the *hi*
|
||||||
specified, then the odd numbered bins will be red and the even bins
|
boundary, it is considered to be in the lower of the 2 bins). Each of
|
||||||
green. The color of the atom is the color of its bin. Note that the
|
the M bins is assigned a color from the *N* entries. If M < *N*, then
|
||||||
sequential color map is really a shorthand way of defining a discrete
|
the colors are repeated in a round-robin fashion. For example if 2
|
||||||
color map without having to specify where all the bin boundaries are.
|
entries with colors red and green are specified, then the odd numbered
|
||||||
|
bins will be red and the even bins green. An atom's color is the
|
||||||
|
color of its bin.
|
||||||
|
|
||||||
Here is an example of using a sequential color map to color all the
|
Here is an example of using a sequential color map to color all the
|
||||||
atoms in individual molecules with a different color. See the
|
atoms in individual molecules with a different color based on its
|
||||||
examples/pour/in.pour.2d.molecule input script for an example of how
|
molecule ID. See the examples/pour/in.pour.2d.molecule input script
|
||||||
this is used.
|
for an example of how this is used.
|
||||||
|
|
||||||
.. code-block:: LAMMPS
|
.. code-block:: LAMMPS
|
||||||
|
|
||||||
@ -897,8 +922,9 @@ this is used.
|
|||||||
zoom 1.6 adiam 1.5
|
zoom 1.6 adiam 1.5
|
||||||
dump_modify 1 pad 5 amap 0 10 sa 1 10 ${colors}
|
dump_modify 1 pad 5 amap 0 10 sa 1 10 ${colors}
|
||||||
|
|
||||||
In this case, 10 colors are defined, and molecule IDs are
|
In this case, the sequential color map has 10 color entries, and
|
||||||
mapped to one of the colors, even if there are 1000s of molecules.
|
molecule IDs are mapped to one of the colors, even if there are 1000s
|
||||||
|
of molecules.
|
||||||
|
|
||||||
----------
|
----------
|
||||||
|
|
||||||
|
|||||||
2
src/.gitignore
vendored
2
src/.gitignore
vendored
@ -677,6 +677,8 @@
|
|||||||
/compute_rattlers_atom.h
|
/compute_rattlers_atom.h
|
||||||
/compute_reaxff_atom.cpp
|
/compute_reaxff_atom.cpp
|
||||||
/compute_reaxff_atom.h
|
/compute_reaxff_atom.h
|
||||||
|
/compute_rigid_atom.cpp
|
||||||
|
/compute_rigid_atom.h
|
||||||
/compute_rigid_local.cpp
|
/compute_rigid_local.cpp
|
||||||
/compute_rigid_local.h
|
/compute_rigid_local.h
|
||||||
/compute_slcsa_atom.cpp
|
/compute_slcsa_atom.cpp
|
||||||
|
|||||||
@ -1141,13 +1141,12 @@ struct AtomVecSphereKokkos_PackBorderVel {
|
|||||||
_buf(i,6) = _radius(j);
|
_buf(i,6) = _radius(j);
|
||||||
_buf(i,7) = _rmass(j);
|
_buf(i,7) = _rmass(j);
|
||||||
if (DEFORM_VREMAP) {
|
if (DEFORM_VREMAP) {
|
||||||
if (_mask(i) & _deform_groupbit) {
|
if (_mask(j) & _deform_groupbit) {
|
||||||
_buf(i,8) = _v(j,0) + _dvx;
|
_buf(i,8) = _v(j,0) + _dvx;
|
||||||
_buf(i,9) = _v(j,1) + _dvy;
|
_buf(i,9) = _v(j,1) + _dvy;
|
||||||
_buf(i,10) = _v(j,2) + _dvz;
|
_buf(i,10) = _v(j,2) + _dvz;
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
_buf(i,8) = _v(j,0);
|
_buf(i,8) = _v(j,0);
|
||||||
_buf(i,9) = _v(j,1);
|
_buf(i,9) = _v(j,1);
|
||||||
_buf(i,10) = _v(j,2);
|
_buf(i,10) = _v(j,2);
|
||||||
|
|||||||
305
src/RIGID/compute_rigid_atom.cpp
Normal file
305
src/RIGID/compute_rigid_atom.cpp
Normal file
@ -0,0 +1,305 @@
|
|||||||
|
// clang-format off
|
||||||
|
/* ----------------------------------------------------------------------
|
||||||
|
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
|
||||||
|
https://www.lammps.org/, Sandia National Laboratories
|
||||||
|
LAMMPS development team: developers@lammps.org
|
||||||
|
|
||||||
|
Copyright (2003) Sandia Corporation. Under the terms of Contract
|
||||||
|
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
|
||||||
|
certain rights in this software. This software is distributed under
|
||||||
|
the GNU General Public License.
|
||||||
|
|
||||||
|
See the README file in the top-level LAMMPS directory.
|
||||||
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
#include "compute_rigid_atom.h"
|
||||||
|
|
||||||
|
#include "atom.h"
|
||||||
|
#include "domain.h"
|
||||||
|
#include "error.h"
|
||||||
|
#include "modify.h"
|
||||||
|
#include "fix_rigid_small.h"
|
||||||
|
#include "memory.h"
|
||||||
|
#include "update.h"
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
using namespace LAMMPS_NS;
|
||||||
|
|
||||||
|
static constexpr int DELTA = 10000;
|
||||||
|
|
||||||
|
enum{ID,MOL,MASS,X,Y,Z,XU,YU,ZU,VX,VY,VZ,FX,FY,FZ,IX,IY,IZ,
|
||||||
|
TQX,TQY,TQZ,OMEGAX,OMEGAY,OMEGAZ,ANGMOMX,ANGMOMY,ANGMOMZ,
|
||||||
|
QUATW,QUATI,QUATJ,QUATK,INERTIAX,INERTIAY,INERTIAZ};
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
ComputeRigidAtom::ComputeRigidAtom(LAMMPS *lmp, int narg, char **arg) :
|
||||||
|
Compute(lmp, narg, arg),
|
||||||
|
rstyle(nullptr), idrigid(nullptr), fixrigid(nullptr)
|
||||||
|
{
|
||||||
|
if (narg < 5) error->all(FLERR,"Illegal compute rigid/local command");
|
||||||
|
|
||||||
|
peratom_flag = 1;
|
||||||
|
|
||||||
|
idrigid = utils::strdup(arg[3]);
|
||||||
|
|
||||||
|
nvalues = narg - 4;
|
||||||
|
rstyle = new int[nvalues];
|
||||||
|
|
||||||
|
nvalues = 0;
|
||||||
|
for (int iarg = 4; iarg < narg; iarg++) {
|
||||||
|
if (strcmp(arg[iarg],"id") == 0) rstyle[nvalues++] = ID;
|
||||||
|
else if (strcmp(arg[iarg],"mol") == 0) rstyle[nvalues++] = MOL;
|
||||||
|
else if (strcmp(arg[iarg],"mass") == 0) rstyle[nvalues++] = MASS;
|
||||||
|
else if (strcmp(arg[iarg],"x") == 0) rstyle[nvalues++] = X;
|
||||||
|
else if (strcmp(arg[iarg],"y") == 0) rstyle[nvalues++] = Y;
|
||||||
|
else if (strcmp(arg[iarg],"z") == 0) rstyle[nvalues++] = Z;
|
||||||
|
else if (strcmp(arg[iarg],"xu") == 0) rstyle[nvalues++] = XU;
|
||||||
|
else if (strcmp(arg[iarg],"yu") == 0) rstyle[nvalues++] = YU;
|
||||||
|
else if (strcmp(arg[iarg],"zu") == 0) rstyle[nvalues++] = ZU;
|
||||||
|
else if (strcmp(arg[iarg],"vx") == 0) rstyle[nvalues++] = VX;
|
||||||
|
else if (strcmp(arg[iarg],"vy") == 0) rstyle[nvalues++] = VY;
|
||||||
|
else if (strcmp(arg[iarg],"vz") == 0) rstyle[nvalues++] = VZ;
|
||||||
|
else if (strcmp(arg[iarg],"fx") == 0) rstyle[nvalues++] = FX;
|
||||||
|
else if (strcmp(arg[iarg],"fy") == 0) rstyle[nvalues++] = FY;
|
||||||
|
else if (strcmp(arg[iarg],"fz") == 0) rstyle[nvalues++] = FZ;
|
||||||
|
else if (strcmp(arg[iarg],"ix") == 0) rstyle[nvalues++] = IX;
|
||||||
|
else if (strcmp(arg[iarg],"iy") == 0) rstyle[nvalues++] = IY;
|
||||||
|
else if (strcmp(arg[iarg],"iz") == 0) rstyle[nvalues++] = IZ;
|
||||||
|
else if (strcmp(arg[iarg],"tqx") == 0) rstyle[nvalues++] = TQX;
|
||||||
|
else if (strcmp(arg[iarg],"tqy") == 0) rstyle[nvalues++] = TQY;
|
||||||
|
else if (strcmp(arg[iarg],"tqz") == 0) rstyle[nvalues++] = TQZ;
|
||||||
|
else if (strcmp(arg[iarg],"omegax") == 0) rstyle[nvalues++] = OMEGAX;
|
||||||
|
else if (strcmp(arg[iarg],"omegay") == 0) rstyle[nvalues++] = OMEGAY;
|
||||||
|
else if (strcmp(arg[iarg],"omegaz") == 0) rstyle[nvalues++] = OMEGAZ;
|
||||||
|
else if (strcmp(arg[iarg],"angmomx") == 0) rstyle[nvalues++] = ANGMOMX;
|
||||||
|
else if (strcmp(arg[iarg],"angmomy") == 0) rstyle[nvalues++] = ANGMOMY;
|
||||||
|
else if (strcmp(arg[iarg],"angmomz") == 0) rstyle[nvalues++] = ANGMOMZ;
|
||||||
|
else if (strcmp(arg[iarg],"quatw") == 0) rstyle[nvalues++] = QUATW;
|
||||||
|
else if (strcmp(arg[iarg],"quati") == 0) rstyle[nvalues++] = QUATI;
|
||||||
|
else if (strcmp(arg[iarg],"quatj") == 0) rstyle[nvalues++] = QUATJ;
|
||||||
|
else if (strcmp(arg[iarg],"quatk") == 0) rstyle[nvalues++] = QUATK;
|
||||||
|
else if (strcmp(arg[iarg],"inertiax") == 0) rstyle[nvalues++] = INERTIAX;
|
||||||
|
else if (strcmp(arg[iarg],"inertiay") == 0) rstyle[nvalues++] = INERTIAY;
|
||||||
|
else if (strcmp(arg[iarg],"inertiaz") == 0) rstyle[nvalues++] = INERTIAZ;
|
||||||
|
else error->all(FLERR,"Invalid keyword in compute rigid/local command");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nvalues == 1) size_peratom_cols = 0;
|
||||||
|
else size_peratom_cols = nvalues;
|
||||||
|
|
||||||
|
maxatom = 0;
|
||||||
|
vector_atom = nullptr;
|
||||||
|
array_atom = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
ComputeRigidAtom::~ComputeRigidAtom()
|
||||||
|
{
|
||||||
|
memory->destroy(vector_atom);
|
||||||
|
memory->destroy(array_atom);
|
||||||
|
delete[] idrigid;
|
||||||
|
delete[] rstyle;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
void ComputeRigidAtom::init()
|
||||||
|
{
|
||||||
|
// set fixrigid
|
||||||
|
|
||||||
|
auto ifix = modify->get_fix_by_id(idrigid);
|
||||||
|
if (!ifix) error->all(FLERR,"FixRigidSmall ID {} for compute rigid/atom does not exist", idrigid);
|
||||||
|
fixrigid = dynamic_cast<FixRigidSmall *>(ifix);
|
||||||
|
if (!fixrigid)
|
||||||
|
error->all(FLERR,"Fix ID {} for compute rigid/atom does not point to fix rigid/small", idrigid);
|
||||||
|
|
||||||
|
// do initial memory allocation so that memory_usage() is correct
|
||||||
|
|
||||||
|
if (atom->nmax > maxatom) {
|
||||||
|
maxatom = atom->nmax;
|
||||||
|
if (nvalues == 1) {
|
||||||
|
memory->destroy(vector_atom);
|
||||||
|
memory->create(vector_atom, maxatom, "rigid/atom:vector_atom");
|
||||||
|
} else {
|
||||||
|
memory->destroy(array_atom);
|
||||||
|
memory->create(array_atom, maxatom, nvalues, "rigid/atom:array_atom");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------------
|
||||||
|
loop over atoms, store rigid body info for the body it is in
|
||||||
|
set output to zero if atom not in group or not in a body
|
||||||
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
void ComputeRigidAtom::compute_peratom()
|
||||||
|
{
|
||||||
|
invoked_peratom = update->ntimestep;
|
||||||
|
|
||||||
|
int i,m,n,ibody;
|
||||||
|
double *ptr;
|
||||||
|
FixRigidSmall::Body *body;
|
||||||
|
|
||||||
|
double xprd = domain->xprd;
|
||||||
|
double yprd = domain->yprd;
|
||||||
|
double zprd = domain->zprd;
|
||||||
|
|
||||||
|
tagint *tag = atom->tag;
|
||||||
|
tagint *molecule = atom->molecule;
|
||||||
|
int *mask = atom->mask;
|
||||||
|
int nlocal = atom->nlocal;
|
||||||
|
|
||||||
|
m = 0;
|
||||||
|
for (i = 0; i < nlocal; i++) {
|
||||||
|
if (!(mask[i] & groupbit)) {
|
||||||
|
zero(i);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
ibody = fixrigid->atom2body[i];
|
||||||
|
if (ibody < 0) {
|
||||||
|
zero(i);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
body = &fixrigid->body[ibody];
|
||||||
|
|
||||||
|
if (nvalues == 1) ptr = &vector_atom[i];
|
||||||
|
else ptr = array_atom[i];
|
||||||
|
|
||||||
|
for (n = 0; n < nvalues; n++) {
|
||||||
|
switch (rstyle[n]) {
|
||||||
|
case ID:
|
||||||
|
ptr[n] = tag[body->ilocal];
|
||||||
|
break;
|
||||||
|
case MOL:
|
||||||
|
ptr[n] = molecule[body->ilocal];
|
||||||
|
break;
|
||||||
|
case MASS:
|
||||||
|
ptr[n] = body->mass;
|
||||||
|
break;
|
||||||
|
case X:
|
||||||
|
ptr[n] = body->xcm[0];
|
||||||
|
break;
|
||||||
|
case Y:
|
||||||
|
ptr[n] = body->xcm[1];
|
||||||
|
break;
|
||||||
|
case Z:
|
||||||
|
ptr[n] = body->xcm[2];
|
||||||
|
break;
|
||||||
|
case XU:
|
||||||
|
ptr[n] = body->xcm[0] +
|
||||||
|
((body->image & IMGMASK) - IMGMAX) * xprd;
|
||||||
|
break;
|
||||||
|
case YU:
|
||||||
|
ptr[n] = body->xcm[1] +
|
||||||
|
((body->image >> IMGBITS & IMGMASK) - IMGMAX) * yprd;
|
||||||
|
break;
|
||||||
|
case ZU:
|
||||||
|
ptr[n] = body->xcm[2] +
|
||||||
|
((body->image >> IMG2BITS) - IMGMAX) * zprd;
|
||||||
|
break;
|
||||||
|
case VX:
|
||||||
|
ptr[n] = body->vcm[0];
|
||||||
|
break;
|
||||||
|
case VY:
|
||||||
|
ptr[n] = body->vcm[1];
|
||||||
|
break;
|
||||||
|
case VZ:
|
||||||
|
ptr[n] = body->vcm[2];
|
||||||
|
break;
|
||||||
|
case FX:
|
||||||
|
ptr[n] = body->fcm[0];
|
||||||
|
break;
|
||||||
|
case FY:
|
||||||
|
ptr[n] = body->fcm[1];
|
||||||
|
break;
|
||||||
|
case FZ:
|
||||||
|
ptr[n] = body->fcm[2];
|
||||||
|
break;
|
||||||
|
case IX:
|
||||||
|
ptr[n] = (body->image & IMGMASK) - IMGMAX;
|
||||||
|
break;
|
||||||
|
case IY:
|
||||||
|
ptr[n] = (body->image >> IMGBITS & IMGMASK) - IMGMAX;
|
||||||
|
break;
|
||||||
|
case IZ:
|
||||||
|
ptr[n] = (body->image >> IMG2BITS) - IMGMAX;
|
||||||
|
break;
|
||||||
|
case TQX:
|
||||||
|
ptr[n] = body->torque[0];
|
||||||
|
break;
|
||||||
|
case TQY:
|
||||||
|
ptr[n] = body->torque[1];
|
||||||
|
break;
|
||||||
|
case TQZ:
|
||||||
|
ptr[n] = body->torque[2];
|
||||||
|
break;
|
||||||
|
case OMEGAX:
|
||||||
|
ptr[n] = body->omega[0];
|
||||||
|
break;
|
||||||
|
case OMEGAY:
|
||||||
|
ptr[n] = body->omega[1];
|
||||||
|
break;
|
||||||
|
case OMEGAZ:
|
||||||
|
ptr[n] = body->omega[2];
|
||||||
|
break;
|
||||||
|
case ANGMOMX:
|
||||||
|
ptr[n] = body->angmom[0];
|
||||||
|
break;
|
||||||
|
case ANGMOMY:
|
||||||
|
ptr[n] = body->angmom[1];
|
||||||
|
break;
|
||||||
|
case ANGMOMZ:
|
||||||
|
ptr[n] = body->angmom[2];
|
||||||
|
break;
|
||||||
|
case QUATW:
|
||||||
|
ptr[n] = body->quat[0];
|
||||||
|
break;
|
||||||
|
case QUATI:
|
||||||
|
ptr[n] = body->quat[1];
|
||||||
|
break;
|
||||||
|
case QUATJ:
|
||||||
|
ptr[n] = body->quat[2];
|
||||||
|
break;
|
||||||
|
case QUATK:
|
||||||
|
ptr[n] = body->quat[3];
|
||||||
|
break;
|
||||||
|
case INERTIAX:
|
||||||
|
ptr[n] = body->inertia[0];
|
||||||
|
break;
|
||||||
|
case INERTIAY:
|
||||||
|
ptr[n] = body->inertia[1];
|
||||||
|
break;
|
||||||
|
case INERTIAZ:
|
||||||
|
ptr[n] = body->inertia[2];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------------
|
||||||
|
zero the peratom output for atom I
|
||||||
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
void ComputeRigidAtom::zero(int i)
|
||||||
|
{
|
||||||
|
if (nvalues == 1) vector_atom[i] = 0.0;
|
||||||
|
else {
|
||||||
|
for (int n = 0; n < nvalues; n++) array_atom[i][n] = 0.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------------
|
||||||
|
memory usage of peratom data
|
||||||
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
double ComputeRigidAtom::memory_usage()
|
||||||
|
{
|
||||||
|
double bytes = (double)maxatom*nvalues * sizeof(double);
|
||||||
|
return bytes;
|
||||||
|
}
|
||||||
49
src/RIGID/compute_rigid_atom.h
Normal file
49
src/RIGID/compute_rigid_atom.h
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
/* -*- c++ -*- ----------------------------------------------------------
|
||||||
|
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
|
||||||
|
https://www.lammps.org/, Sandia National Laboratories
|
||||||
|
LAMMPS development team: developers@lammps.org
|
||||||
|
|
||||||
|
Copyright (2003) Sandia Corporation. Under the terms of Contract
|
||||||
|
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
|
||||||
|
certain rights in this software. This software is distributed under
|
||||||
|
the GNU General Public License.
|
||||||
|
|
||||||
|
See the README file in the top-level LAMMPS directory.
|
||||||
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
#ifdef COMPUTE_CLASS
|
||||||
|
// clang-format off
|
||||||
|
ComputeStyle(rigid/atom,ComputeRigidAtom);
|
||||||
|
// clang-format on
|
||||||
|
#else
|
||||||
|
|
||||||
|
#ifndef LMP_COMPUTE_RIGID_ATOM_H
|
||||||
|
#define LMP_COMPUTE_RIGID_ATOM_H
|
||||||
|
|
||||||
|
#include "compute.h"
|
||||||
|
|
||||||
|
namespace LAMMPS_NS {
|
||||||
|
|
||||||
|
class ComputeRigidAtom : public Compute {
|
||||||
|
public:
|
||||||
|
ComputeRigidAtom(class LAMMPS *, int, char **);
|
||||||
|
~ComputeRigidAtom() override;
|
||||||
|
void init() override;
|
||||||
|
void compute_peratom() override;
|
||||||
|
double memory_usage() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
int nvalues;
|
||||||
|
int *rstyle;
|
||||||
|
|
||||||
|
int maxatom;
|
||||||
|
char *idrigid;
|
||||||
|
class FixRigidSmall *fixrigid;
|
||||||
|
|
||||||
|
void zero(int);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace LAMMPS_NS
|
||||||
|
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
@ -969,20 +969,24 @@ void FixRigid::initial_integrate(int vflag)
|
|||||||
use domain->remap() in case xcm is far away from box
|
use domain->remap() in case xcm is far away from box
|
||||||
due to first-time definition of rigid body in setup_bodies_static()
|
due to first-time definition of rigid body in setup_bodies_static()
|
||||||
or due to box flip
|
or due to box flip
|
||||||
|
also remap vcm if xcm crosses periodic shearing boundary
|
||||||
also adjust imagebody = rigid body image flags, due to xcm remap
|
also adjust imagebody = rigid body image flags, due to xcm remap
|
||||||
also reset body xcmimage flags of all atoms in bodies
|
also reset body xcmimage flags of all atoms in bodies
|
||||||
xcmimage flags are relative to xcm so that body can be unwrapped
|
xcmimage flags are relative to xcm so that body can be unwrapped
|
||||||
if don't do this, would need xcm to move with true image flags
|
if don't do this, would need xcm to move with true image flags
|
||||||
then a body could end up very far away from box
|
then a body could end up very far away from box
|
||||||
set_xv() will then compute huge displacements every step to
|
set_xv() would then compute huge displacements every step to
|
||||||
reset coords of all body atoms to be back inside the box,
|
reset coords of all body atoms to be back inside the box,
|
||||||
ditto for triclinic box flip, which causes numeric problems
|
ditto for triclinic box flip which could cause numeric problems
|
||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
void FixRigid::pre_neighbor()
|
void FixRigid::pre_neighbor()
|
||||||
{
|
{
|
||||||
for (int ibody = 0; ibody < nbody; ibody++)
|
for (int ibody = 0; ibody < nbody; ibody++) {
|
||||||
domain->remap(xcm[ibody],imagebody[ibody]);
|
//domain->remap(xcm[ibody],imagebody[ibody]);
|
||||||
|
domain->remap(xcm[ibody],imagebody[ibody],vcm[ibody]);
|
||||||
|
}
|
||||||
|
|
||||||
image_shift();
|
image_shift();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -21,6 +21,8 @@
|
|||||||
#include "comm.h"
|
#include "comm.h"
|
||||||
#include "domain.h"
|
#include "domain.h"
|
||||||
#include "error.h"
|
#include "error.h"
|
||||||
|
#include "fix.h"
|
||||||
|
#include "fix_deform.h"
|
||||||
#include "force.h"
|
#include "force.h"
|
||||||
#include "group.h"
|
#include "group.h"
|
||||||
#include "hashlittle.h"
|
#include "hashlittle.h"
|
||||||
@ -559,6 +561,16 @@ void FixRigidSmall::init()
|
|||||||
if (ifix->box_change) boxflag = true;
|
if (ifix->box_change) boxflag = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check for fix deform with V_REMAP set
|
||||||
|
|
||||||
|
deform_vremap = 0;
|
||||||
|
const auto &fixes = modify->get_fix_list();
|
||||||
|
for (const auto &fix : fixes)
|
||||||
|
if (utils::strmatch(fix->style,"^deform")) {
|
||||||
|
if ((dynamic_cast<FixDeform *>(fix))->remapflag == Domain::V_REMAP)
|
||||||
|
deform_vremap = 1;
|
||||||
|
}
|
||||||
|
|
||||||
// add gravity forces based on gravity vector from fix
|
// add gravity forces based on gravity vector from fix
|
||||||
|
|
||||||
if (id_gravity) {
|
if (id_gravity) {
|
||||||
@ -787,7 +799,8 @@ void FixRigidSmall::initial_integrate(int vflag)
|
|||||||
due to first-time definition of rigid body in setup_bodies_static()
|
due to first-time definition of rigid body in setup_bodies_static()
|
||||||
or due to box flip
|
or due to box flip
|
||||||
also adjust imagebody = rigid body image flags, due to xcm remap
|
also adjust imagebody = rigid body image flags, due to xcm remap
|
||||||
then communicate bodies so other procs will know of changes to body xcm
|
also remap vcm if xcm crosses periodic shearing boundary
|
||||||
|
then communicate bodies so other procs will know of changes to body xcm/vcm
|
||||||
then adjust xcmimage flags of all atoms in bodies via image_shift()
|
then adjust xcmimage flags of all atoms in bodies via image_shift()
|
||||||
for two effects
|
for two effects
|
||||||
(1) change in true image flags due to pbc() call during exchange
|
(1) change in true image flags due to pbc() call during exchange
|
||||||
@ -795,18 +808,17 @@ void FixRigidSmall::initial_integrate(int vflag)
|
|||||||
xcmimage flags are always -1,0,-1 so that body can be unwrapped
|
xcmimage flags are always -1,0,-1 so that body can be unwrapped
|
||||||
around in-box xcm and stay close to simulation box
|
around in-box xcm and stay close to simulation box
|
||||||
if just inferred unwrapped from atom image flags,
|
if just inferred unwrapped from atom image flags,
|
||||||
then a body could end up very far away
|
then an unwrapped body could end up very far away from box
|
||||||
when unwrapped by true image flags
|
set_xv() would then compute huge displacements every step to
|
||||||
then set_xv() will compute huge displacements every step to reset coords of
|
reset coords of all body atoms to be back inside the box,
|
||||||
all the body atoms to be back inside the box, ditto for triclinic box flip
|
ditto for triclinic box flip which could cause numeric problems
|
||||||
note: so just want to avoid that numeric problem?
|
|
||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
void FixRigidSmall::pre_neighbor()
|
void FixRigidSmall::pre_neighbor()
|
||||||
{
|
{
|
||||||
for (int ibody = 0; ibody < nlocal_body; ibody++) {
|
for (int ibody = 0; ibody < nlocal_body; ibody++) {
|
||||||
Body *b = &body[ibody];
|
Body *b = &body[ibody];
|
||||||
domain->remap(b->xcm,b->image);
|
domain->remap(b->xcm,b->image,b->vcm);
|
||||||
}
|
}
|
||||||
|
|
||||||
nghost_body = 0;
|
nghost_body = 0;
|
||||||
@ -966,9 +978,11 @@ void FixRigidSmall::apply_langevin_thermostat()
|
|||||||
gamma1 = -body[ibody].mass / t_period / ftm2v;
|
gamma1 = -body[ibody].mass / t_period / ftm2v;
|
||||||
gamma2 = sqrt(body[ibody].mass) * tsqrt *
|
gamma2 = sqrt(body[ibody].mass) * tsqrt *
|
||||||
sqrt(24.0*boltz/t_period/dt/mvv2e) / ftm2v;
|
sqrt(24.0*boltz/t_period/dt/mvv2e) / ftm2v;
|
||||||
|
if (deform_vremap) remove_bias(ibody,vcm);
|
||||||
langextra[ibody][0] = gamma1*vcm[0] + gamma2*(random->uniform()-0.5);
|
langextra[ibody][0] = gamma1*vcm[0] + gamma2*(random->uniform()-0.5);
|
||||||
langextra[ibody][1] = gamma1*vcm[1] + gamma2*(random->uniform()-0.5);
|
langextra[ibody][1] = gamma1*vcm[1] + gamma2*(random->uniform()-0.5);
|
||||||
langextra[ibody][2] = gamma1*vcm[2] + gamma2*(random->uniform()-0.5);
|
langextra[ibody][2] = gamma1*vcm[2] + gamma2*(random->uniform()-0.5);
|
||||||
|
if (deform_vremap) restore_bias(ibody,vcm);
|
||||||
|
|
||||||
gamma1 = -1.0 / t_period / ftm2v;
|
gamma1 = -1.0 / t_period / ftm2v;
|
||||||
gamma2 = tsqrt * sqrt(24.0*boltz/t_period/dt/mvv2e) / ftm2v;
|
gamma2 = tsqrt * sqrt(24.0*boltz/t_period/dt/mvv2e) / ftm2v;
|
||||||
@ -992,6 +1006,37 @@ void FixRigidSmall::apply_langevin_thermostat()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------------
|
||||||
|
remove velocity bias from VCM of Body ibody to leave thermal VCM
|
||||||
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
void FixRigidSmall::remove_bias(int ibody, double *vcm)
|
||||||
|
{
|
||||||
|
double lamda[3];
|
||||||
|
double *h_rate = domain->h_rate;
|
||||||
|
double *h_ratelo = domain->h_ratelo;
|
||||||
|
|
||||||
|
domain->x2lamda(body[ibody].xcm, lamda);
|
||||||
|
vbias[0] = h_rate[0] * lamda[0] + h_rate[5] * lamda[1] + h_rate[4] * lamda[2] + h_ratelo[0];
|
||||||
|
vbias[1] = h_rate[1] * lamda[1] + h_rate[3] * lamda[2] + h_ratelo[1];
|
||||||
|
vbias[2] = h_rate[2] * lamda[2] + h_ratelo[2];
|
||||||
|
vcm[0] -= vbias[0];
|
||||||
|
vcm[1] -= vbias[1];
|
||||||
|
vcm[2] -= vbias[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------------
|
||||||
|
add back velocity bias to VCM of Body ibody removed by remove_bias()
|
||||||
|
assume remove_bias() was previously called
|
||||||
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
void FixRigidSmall::restore_bias(int /*i*/, double *vcm)
|
||||||
|
{
|
||||||
|
vcm[0] += vbias[0];
|
||||||
|
vcm[1] += vbias[1];
|
||||||
|
vcm[2] += vbias[2];
|
||||||
|
}
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------- */
|
||||||
|
|
||||||
void FixRigidSmall::compute_forces_and_torques()
|
void FixRigidSmall::compute_forces_and_torques()
|
||||||
|
|||||||
@ -26,6 +26,7 @@ namespace LAMMPS_NS {
|
|||||||
|
|
||||||
class FixRigidSmall : public Fix {
|
class FixRigidSmall : public Fix {
|
||||||
friend class ComputeRigidLocal;
|
friend class ComputeRigidLocal;
|
||||||
|
friend class ComputeRigidAtom;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
FixRigidSmall(class LAMMPS *, int, char **);
|
FixRigidSmall(class LAMMPS *, int, char **);
|
||||||
@ -151,6 +152,9 @@ class FixRigidSmall : public Fix {
|
|||||||
double **langextra; // Langevin thermostat forces and torques
|
double **langextra; // Langevin thermostat forces and torques
|
||||||
int maxlang; // max size of langextra
|
int maxlang; // max size of langextra
|
||||||
class RanMars *random; // RNG
|
class RanMars *random; // RNG
|
||||||
|
int deform_vremap; // 1 if fix deform with V_REMAP exists
|
||||||
|
// if so, add/sub bias around Langevin
|
||||||
|
double vbias[3]; // store deformation bias for one body
|
||||||
|
|
||||||
int tstat_flag, pstat_flag; // 0/1 = no/yes thermostat/barostat
|
int tstat_flag, pstat_flag; // 0/1 = no/yes thermostat/barostat
|
||||||
|
|
||||||
@ -200,6 +204,8 @@ class FixRigidSmall : public Fix {
|
|||||||
void setup_bodies_static();
|
void setup_bodies_static();
|
||||||
void setup_bodies_dynamic();
|
void setup_bodies_dynamic();
|
||||||
void apply_langevin_thermostat();
|
void apply_langevin_thermostat();
|
||||||
|
void remove_bias(int, double *);
|
||||||
|
void restore_bias(int, double *);
|
||||||
virtual void compute_forces_and_torques();
|
virtual void compute_forces_and_torques();
|
||||||
void enforce2d();
|
void enforce2d();
|
||||||
void readfile(int, double **, int *);
|
void readfile(int, double **, int *);
|
||||||
|
|||||||
@ -485,7 +485,7 @@ int AtomVec::pack_comm_vel(int n, int *list, double *buf, int pbc_flag, int *pbc
|
|||||||
buf[m++] = x[j][0] + dx;
|
buf[m++] = x[j][0] + dx;
|
||||||
buf[m++] = x[j][1] + dy;
|
buf[m++] = x[j][1] + dy;
|
||||||
buf[m++] = x[j][2] + dz;
|
buf[m++] = x[j][2] + dz;
|
||||||
if (mask[i] & deform_groupbit) {
|
if (mask[j] & deform_groupbit) {
|
||||||
buf[m++] = v[j][0] + dvx;
|
buf[m++] = v[j][0] + dvx;
|
||||||
buf[m++] = v[j][1] + dvy;
|
buf[m++] = v[j][1] + dvy;
|
||||||
buf[m++] = v[j][2] + dvz;
|
buf[m++] = v[j][2] + dvz;
|
||||||
@ -946,7 +946,7 @@ int AtomVec::pack_border_vel(int n, int *list, double *buf, int pbc_flag, int *p
|
|||||||
buf[m++] = ubuf(tag[j]).d;
|
buf[m++] = ubuf(tag[j]).d;
|
||||||
buf[m++] = ubuf(type[j]).d;
|
buf[m++] = ubuf(type[j]).d;
|
||||||
buf[m++] = ubuf(mask[j]).d;
|
buf[m++] = ubuf(mask[j]).d;
|
||||||
if (mask[i] & deform_groupbit) {
|
if (mask[j] & deform_groupbit) {
|
||||||
buf[m++] = v[j][0] + dvx;
|
buf[m++] = v[j][0] + dvx;
|
||||||
buf[m++] = v[j][1] + dvy;
|
buf[m++] = v[j][1] + dvy;
|
||||||
buf[m++] = v[j][2] + dvz;
|
buf[m++] = v[j][2] + dvz;
|
||||||
|
|||||||
@ -1527,16 +1527,19 @@ void Domain::closest_image(const double * const xi, const double * const xj, dou
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------
|
/* ----------------------------------------------------------------------
|
||||||
remap the point into the periodic box no matter how far away
|
remap the point X into the periodic box no matter how far away
|
||||||
adjust 3 image flags encoded in image accordingly
|
adjust 3 image flags encoded in image accordingly
|
||||||
resulting coord must satisfy lo <= coord < hi
|
resulting coord must satisfy lo <= coord < hi
|
||||||
MAX is important since coord - prd < lo can happen when coord = hi
|
MAX is important since coord - prd < lo can happen when coord = hi
|
||||||
for triclinic, point is converted to lamda coords (0-1) before doing remap
|
for triclinic, point is converted to lamda coords (0-1) before doing remap
|
||||||
image = 10 bits for each dimension
|
image = 10 or 20 bits for each dimension
|
||||||
increment/decrement in wrap-around fashion
|
increment/decrement in wrap-around fashion
|
||||||
|
if V is specified (default = NULL) and deform_vremap set by fix deform:
|
||||||
|
also remap v via h_rate calclated by fix deform
|
||||||
|
currently only used by fix rigid commands to remap body VCM
|
||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
void Domain::remap(double *x, imageint &image)
|
void Domain::remap(double *x, imageint &image, double *v)
|
||||||
{
|
{
|
||||||
double *lo,*hi,*period,*coord;
|
double *lo,*hi,*period,*coord;
|
||||||
double lamda[3];
|
double lamda[3];
|
||||||
@ -1558,6 +1561,7 @@ void Domain::remap(double *x, imageint &image)
|
|||||||
if (xperiodic) {
|
if (xperiodic) {
|
||||||
while (coord[0] < lo[0]) {
|
while (coord[0] < lo[0]) {
|
||||||
coord[0] += period[0];
|
coord[0] += period[0];
|
||||||
|
if (deform_vremap && v) v[0] += h_rate[0];
|
||||||
idim = image & IMGMASK;
|
idim = image & IMGMASK;
|
||||||
otherdims = image ^ idim;
|
otherdims = image ^ idim;
|
||||||
idim--;
|
idim--;
|
||||||
@ -1566,6 +1570,7 @@ void Domain::remap(double *x, imageint &image)
|
|||||||
}
|
}
|
||||||
while (coord[0] >= hi[0]) {
|
while (coord[0] >= hi[0]) {
|
||||||
coord[0] -= period[0];
|
coord[0] -= period[0];
|
||||||
|
if (deform_vremap && v) v[0] -= h_rate[0];
|
||||||
idim = image & IMGMASK;
|
idim = image & IMGMASK;
|
||||||
otherdims = image ^ idim;
|
otherdims = image ^ idim;
|
||||||
idim++;
|
idim++;
|
||||||
@ -1578,6 +1583,10 @@ void Domain::remap(double *x, imageint &image)
|
|||||||
if (yperiodic) {
|
if (yperiodic) {
|
||||||
while (coord[1] < lo[1]) {
|
while (coord[1] < lo[1]) {
|
||||||
coord[1] += period[1];
|
coord[1] += period[1];
|
||||||
|
if (deform_vremap && v) {
|
||||||
|
v[0] += h_rate[5];
|
||||||
|
v[1] += h_rate[1];
|
||||||
|
}
|
||||||
idim = (image >> IMGBITS) & IMGMASK;
|
idim = (image >> IMGBITS) & IMGMASK;
|
||||||
otherdims = image ^ (idim << IMGBITS);
|
otherdims = image ^ (idim << IMGBITS);
|
||||||
idim--;
|
idim--;
|
||||||
@ -1586,6 +1595,10 @@ void Domain::remap(double *x, imageint &image)
|
|||||||
}
|
}
|
||||||
while (coord[1] >= hi[1]) {
|
while (coord[1] >= hi[1]) {
|
||||||
coord[1] -= period[1];
|
coord[1] -= period[1];
|
||||||
|
if (deform_vremap && v) {
|
||||||
|
v[0] -= h_rate[5];
|
||||||
|
v[1] -= h_rate[1];
|
||||||
|
}
|
||||||
idim = (image >> IMGBITS) & IMGMASK;
|
idim = (image >> IMGBITS) & IMGMASK;
|
||||||
otherdims = image ^ (idim << IMGBITS);
|
otherdims = image ^ (idim << IMGBITS);
|
||||||
idim++;
|
idim++;
|
||||||
@ -1598,6 +1611,11 @@ void Domain::remap(double *x, imageint &image)
|
|||||||
if (zperiodic) {
|
if (zperiodic) {
|
||||||
while (coord[2] < lo[2]) {
|
while (coord[2] < lo[2]) {
|
||||||
coord[2] += period[2];
|
coord[2] += period[2];
|
||||||
|
if (deform_vremap && v) {
|
||||||
|
v[0] += h_rate[4];
|
||||||
|
v[1] += h_rate[3];
|
||||||
|
v[2] += h_rate[2];
|
||||||
|
}
|
||||||
idim = image >> IMG2BITS;
|
idim = image >> IMG2BITS;
|
||||||
otherdims = image ^ (idim << IMG2BITS);
|
otherdims = image ^ (idim << IMG2BITS);
|
||||||
idim--;
|
idim--;
|
||||||
@ -1606,6 +1624,11 @@ void Domain::remap(double *x, imageint &image)
|
|||||||
}
|
}
|
||||||
while (coord[2] >= hi[2]) {
|
while (coord[2] >= hi[2]) {
|
||||||
coord[2] -= period[2];
|
coord[2] -= period[2];
|
||||||
|
if (deform_vremap && v) {
|
||||||
|
v[0] -= h_rate[4];
|
||||||
|
v[1] -= h_rate[3];
|
||||||
|
v[2] -= h_rate[2];
|
||||||
|
}
|
||||||
idim = image >> IMG2BITS;
|
idim = image >> IMG2BITS;
|
||||||
otherdims = image ^ (idim << IMG2BITS);
|
otherdims = image ^ (idim << IMG2BITS);
|
||||||
idim++;
|
idim++;
|
||||||
@ -1619,7 +1642,7 @@ void Domain::remap(double *x, imageint &image)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------
|
/* ----------------------------------------------------------------------
|
||||||
remap the point into the periodic box no matter how far away
|
remap the point X into the periodic box no matter how far away
|
||||||
no image flag calculation
|
no image flag calculation
|
||||||
resulting coord must satisfy lo <= coord < hi
|
resulting coord must satisfy lo <= coord < hi
|
||||||
MAX is important since coord - prd < lo can happen when coord = hi
|
MAX is important since coord - prd < lo can happen when coord = hi
|
||||||
@ -1666,7 +1689,7 @@ void Domain::remap(double *x)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------
|
/* ----------------------------------------------------------------------
|
||||||
remap all points into the periodic box no matter how far away
|
remap all atom coords into the periodic box no matter how far away
|
||||||
adjust 3 image flags encoded in image accordingly
|
adjust 3 image flags encoded in image accordingly
|
||||||
resulting coord must satisfy lo <= coord < hi
|
resulting coord must satisfy lo <= coord < hi
|
||||||
MAX is important since coord - prd < lo can happen when coord = hi
|
MAX is important since coord - prd < lo can happen when coord = hi
|
||||||
|
|||||||
@ -134,7 +134,7 @@ class Domain : protected Pointers {
|
|||||||
int closest_image(int, int);
|
int closest_image(int, int);
|
||||||
int closest_image(const double *const, int);
|
int closest_image(const double *const, int);
|
||||||
void closest_image(const double *const, const double *const, double *const);
|
void closest_image(const double *const, const double *const, double *const);
|
||||||
void remap(double *, imageint &);
|
void remap(double *, imageint &, double *v = nullptr);
|
||||||
void remap(double *);
|
void remap(double *);
|
||||||
void remap_all();
|
void remap_all();
|
||||||
void remap_near(double *, double *);
|
void remap_near(double *, double *);
|
||||||
|
|||||||
@ -271,7 +271,7 @@ FixAveChunk::FixAveChunk(LAMMPS *lmp, int narg, char **arg) :
|
|||||||
error->all(FLERR, val.iarg, "Fix ave/chunk compute {} does not calculate a per-atom array",
|
error->all(FLERR, val.iarg, "Fix ave/chunk compute {} does not calculate a per-atom array",
|
||||||
val.id);
|
val.id);
|
||||||
if (val.argindex && (val.argindex > val.val.c->size_peratom_cols))
|
if (val.argindex && (val.argindex > val.val.c->size_peratom_cols))
|
||||||
error->all(FLERR, val.iarg, "Fix ave/chunk compute {} vector is accessed out-of-range{}",
|
error->all(FLERR, val.iarg, "Fix ave/chunk compute {} array is accessed out-of-range{}",
|
||||||
val.id, utils::errorurl(20));
|
val.id, utils::errorurl(20));
|
||||||
|
|
||||||
} else if (val.which == ArgInfo::FIX) {
|
} else if (val.which == ArgInfo::FIX) {
|
||||||
@ -288,7 +288,7 @@ FixAveChunk::FixAveChunk(LAMMPS *lmp, int narg, char **arg) :
|
|||||||
error->all(FLERR, val.iarg, "Fix ave/chunk fix {} does not calculate a per-atom array",
|
error->all(FLERR, val.iarg, "Fix ave/chunk fix {} does not calculate a per-atom array",
|
||||||
val.id);
|
val.id);
|
||||||
if (val.argindex && val.argindex > val.val.f->size_peratom_cols)
|
if (val.argindex && val.argindex > val.val.f->size_peratom_cols)
|
||||||
error->all(FLERR, val.iarg, "Fix ave/chunk fix {} vector is accessed out-of-range{}",
|
error->all(FLERR, val.iarg, "Fix ave/chunk fix {} array is accessed out-of-range{}",
|
||||||
val.id, utils::errorurl(20));
|
val.id, utils::errorurl(20));
|
||||||
} else if (val.which == ArgInfo::VARIABLE) {
|
} else if (val.which == ArgInfo::VARIABLE) {
|
||||||
val.val.v = input->variable->find(val.id.c_str());
|
val.val.v = input->variable->find(val.id.c_str());
|
||||||
|
|||||||
@ -1785,7 +1785,7 @@ ColorMap::~ColorMap()
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------
|
/* ----------------------------------------------------------------------
|
||||||
redefine color map
|
redefine a color map
|
||||||
args = lo hi style delta N entry1 entry2 ... entryN as defined by caller
|
args = lo hi style delta N entry1 entry2 ... entryN as defined by caller
|
||||||
return 1 if any error in args, else return 0
|
return 1 if any error in args, else return 0
|
||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
@ -1849,13 +1849,11 @@ int ColorMap::reset(int narg, char **arg)
|
|||||||
mentry[i].lo = NUMERIC;
|
mentry[i].lo = NUMERIC;
|
||||||
mentry[i].lvalue = utils::numeric(FLERR,arg[n],false,lmp);
|
mentry[i].lvalue = utils::numeric(FLERR,arg[n],false,lmp);
|
||||||
} else if (strcmp(arg[n],"min") == 0) mentry[i].lo = MINVALUE;
|
} else if (strcmp(arg[n],"min") == 0) mentry[i].lo = MINVALUE;
|
||||||
else if (strcmp(arg[n],"max") == 0) mentry[i].lo = MAXVALUE;
|
|
||||||
else return 1;
|
else return 1;
|
||||||
if (!islower(arg[n+1][0])) {
|
if (!islower(arg[n+1][0])) {
|
||||||
mentry[i].hi = NUMERIC;
|
mentry[i].hi = NUMERIC;
|
||||||
mentry[i].hvalue = utils::numeric(FLERR,arg[n+1],false,lmp);
|
mentry[i].hvalue = utils::numeric(FLERR,arg[n+1],false,lmp);
|
||||||
} else if (strcmp(arg[n+1],"min") == 0) mentry[i].hi = MINVALUE;
|
} else if (strcmp(arg[n+1],"max") == 0) mentry[i].hi = MAXVALUE;
|
||||||
else if (strcmp(arg[n+1],"max") == 0) mentry[i].hi = MAXVALUE;
|
|
||||||
else return 1;
|
else return 1;
|
||||||
mentry[i].color = image->color2rgb(arg[n+2]);
|
mentry[i].color = image->color2rgb(arg[n+2]);
|
||||||
n += 3;
|
n += 3;
|
||||||
@ -1867,7 +1865,7 @@ int ColorMap::reset(int narg, char **arg)
|
|||||||
// current code is just 1st nentry values of ALL or USER
|
// current code is just 1st nentry values of ALL or USER
|
||||||
// need to comment out error check in DumpImage::modify_param()
|
// need to comment out error check in DumpImage::modify_param()
|
||||||
// for amap check on (narg < n) to get it to work
|
// for amap check on (narg < n) to get it to work
|
||||||
// need to add extra logic here to check not accessing undefined colors
|
// need to add extra logic here to ensure not accessinging undefined colors
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
if (n+1 > narg) return 1;
|
if (n+1 > narg) return 1;
|
||||||
if (strcmp(arg[n],"ALL") == 0) expandflag = 1;
|
if (strcmp(arg[n],"ALL") == 0) expandflag = 1;
|
||||||
@ -1883,6 +1881,9 @@ int ColorMap::reset(int narg, char **arg)
|
|||||||
}
|
}
|
||||||
n += 1;
|
n += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// error return if color string was not recognized
|
||||||
|
|
||||||
if (mentry[i].color == nullptr) return 1;
|
if (mentry[i].color == nullptr) return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1890,8 +1891,11 @@ int ColorMap::reset(int narg, char **arg)
|
|||||||
if (nentry < 2) return 1;
|
if (nentry < 2) return 1;
|
||||||
if (mentry[0].single != MINVALUE || mentry[nentry-1].single != MAXVALUE)
|
if (mentry[0].single != MINVALUE || mentry[nentry-1].single != MAXVALUE)
|
||||||
return 1;
|
return 1;
|
||||||
for (int i = 2; i < nentry-1; i++)
|
for (int i = 1; i < nentry-1; i++)
|
||||||
|
if (mentry[i].single != NUMERIC) return 1;
|
||||||
|
for (int i = 2; i < nentry-1; i++) {
|
||||||
if (mentry[i].svalue <= mentry[i-1].svalue) return 1;
|
if (mentry[i].svalue <= mentry[i-1].svalue) return 1;
|
||||||
|
}
|
||||||
} else if (mstyle == DISCRETE) {
|
} else if (mstyle == DISCRETE) {
|
||||||
if (nentry < 1) return 1;
|
if (nentry < 1) return 1;
|
||||||
if (mentry[nentry-1].lo != MINVALUE || mentry[nentry-1].hi != MAXVALUE)
|
if (mentry[nentry-1].lo != MINVALUE || mentry[nentry-1].hi != MAXVALUE)
|
||||||
@ -1930,7 +1934,7 @@ int ColorMap::minmax(double mindynamic, double maxdynamic)
|
|||||||
if (mrange == ABSOLUTE) mentry[nentry-1].svalue = hicurrent;
|
if (mrange == ABSOLUTE) mentry[nentry-1].svalue = hicurrent;
|
||||||
else mentry[nentry-1].svalue = 1.0;
|
else mentry[nentry-1].svalue = 1.0;
|
||||||
|
|
||||||
// error in ABSOLUTE mode if new lo/hi current cause
|
// error in ABSOLUTE mode if current lo/hi values cause
|
||||||
// first/last entry to become lo > hi with adjacent entry
|
// first/last entry to become lo > hi with adjacent entry
|
||||||
|
|
||||||
if (mrange == ABSOLUTE) {
|
if (mrange == ABSOLUTE) {
|
||||||
@ -1952,6 +1956,23 @@ int ColorMap::minmax(double mindynamic, double maxdynamic)
|
|||||||
else mentry[i].hvalue = 1.0;
|
else mentry[i].hvalue = 1.0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// set rounddown_flag if bin boundary is essentially at hicurrent
|
||||||
|
// this is to prevent all atoms with values >= hicurrent being assigned
|
||||||
|
// the color for a bin starting at highcurrent,
|
||||||
|
// more sensible to assign them color for bin ending at hicurrent
|
||||||
|
// rounddown_flag is used in value2color()
|
||||||
|
|
||||||
|
} else if (mstyle == SEQUENTIAL) {
|
||||||
|
// NOTE: need to formalize and pre-set these 2 epsilon constants
|
||||||
|
double epsbin;
|
||||||
|
if (mrange == ABSOLUTE) epsbin = (hicurrent-locurrent) * 1.0e-12;
|
||||||
|
else epsbin = 1.0e-9;
|
||||||
|
|
||||||
|
int ibin = static_cast<int> ((hicurrent-locurrent) * mbinsizeinv);
|
||||||
|
int jbin = static_cast<int> ((hicurrent-locurrent-epsbin) * mbinsizeinv);
|
||||||
|
if (jbin < ibin) rounddown_flag = 1;
|
||||||
|
else rounddown_flag = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -1964,7 +1985,7 @@ int ColorMap::minmax(double mindynamic, double maxdynamic)
|
|||||||
|
|
||||||
double *ColorMap::value2color(double value)
|
double *ColorMap::value2color(double value)
|
||||||
{
|
{
|
||||||
double lo;//,hi;
|
double lo,hi;
|
||||||
|
|
||||||
value = MAX(value,locurrent);
|
value = MAX(value,locurrent);
|
||||||
value = MIN(value,hicurrent);
|
value = MIN(value,hicurrent);
|
||||||
@ -1973,10 +1994,10 @@ double *ColorMap::value2color(double value)
|
|||||||
if (locurrent == hicurrent) value = 0.0;
|
if (locurrent == hicurrent) value = 0.0;
|
||||||
else value = (value-locurrent) / (hicurrent-locurrent);
|
else value = (value-locurrent) / (hicurrent-locurrent);
|
||||||
lo = 0.0;
|
lo = 0.0;
|
||||||
//hi = 1.0;
|
hi = 1.0;
|
||||||
} else {
|
} else {
|
||||||
lo = locurrent;
|
lo = locurrent;
|
||||||
//hi = hicurrent;
|
hi = hicurrent;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mstyle == CONTINUOUS) {
|
if (mstyle == CONTINUOUS) {
|
||||||
@ -1998,6 +2019,7 @@ double *ColorMap::value2color(double value)
|
|||||||
return mentry[i].color;
|
return mentry[i].color;
|
||||||
} else {
|
} else {
|
||||||
int ibin = static_cast<int> ((value-lo) * mbinsizeinv);
|
int ibin = static_cast<int> ((value-lo) * mbinsizeinv);
|
||||||
|
if (value == hi && rounddown_flag) ibin--;
|
||||||
return mentry[ibin%nentry].color;
|
return mentry[ibin%nentry].color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -165,8 +165,13 @@ class ColorMap : protected Pointers {
|
|||||||
class Image *image; // caller with color2rgb() method
|
class Image *image; // caller with color2rgb() method
|
||||||
int mstyle, mrange; // 2-letter style/range of color map
|
int mstyle, mrange; // 2-letter style/range of color map
|
||||||
int mlo, mhi; // bounds = NUMERIC or MINVALUE or MAXVALUE
|
int mlo, mhi; // bounds = NUMERIC or MINVALUE or MAXVALUE
|
||||||
|
int rounddown_flag; // for sequential color map,
|
||||||
|
// ensure value at hi end of range is not
|
||||||
|
// assigned color of bin starting at hi,
|
||||||
|
// but rather the color of bin ending at hi
|
||||||
double mlovalue, mhivalue; // user bounds if NUMERIC
|
double mlovalue, mhivalue; // user bounds if NUMERIC
|
||||||
double locurrent, hicurrent; // current bounds for this snapshot
|
double locurrent, hicurrent; // current bounds for this snapshot
|
||||||
|
// from user bounds or dynamic bounds
|
||||||
double mbinsize, mbinsizeinv; // bin size for sequential color map
|
double mbinsize, mbinsizeinv; // bin size for sequential color map
|
||||||
double interpolate[3]; // local storage for returned RGB color
|
double interpolate[3]; // local storage for returned RGB color
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user