Merge pull request #3671 from akohlmey/bond-harmonic-restrain

Add new bond style harmonic/restrain
This commit is contained in:
Axel Kohlmeyer
2023-03-14 16:40:28 -04:00
committed by GitHub
48 changed files with 789 additions and 172 deletions

View File

@ -42,6 +42,7 @@ OPT.
* :doc:`gaussian <bond_gaussian>` * :doc:`gaussian <bond_gaussian>`
* :doc:`gromos (o) <bond_gromos>` * :doc:`gromos (o) <bond_gromos>`
* :doc:`harmonic (iko) <bond_harmonic>` * :doc:`harmonic (iko) <bond_harmonic>`
* :doc:`harmonic/restrain <bond_harmonic_restrain>`
* :doc:`harmonic/shift (o) <bond_harmonic_shift>` * :doc:`harmonic/shift (o) <bond_harmonic_shift>`
* :doc:`harmonic/shift/cut (o) <bond_harmonic_shift_cut>` * :doc:`harmonic/shift/cut (o) <bond_harmonic_shift_cut>`
* :doc:`lepton (o) <bond_lepton>` * :doc:`lepton (o) <bond_lepton>`

View File

@ -11,6 +11,7 @@ Available topics are:
- `Reading and parsing of text and text files`_ - `Reading and parsing of text and text files`_
- `Requesting and accessing neighbor lists`_ - `Requesting and accessing neighbor lists`_
- `Choosing between a custom atom style, fix property/atom, and fix STORE/ATOM`_
- `Fix contributions to instantaneous energy, virial, and cumulative energy`_ - `Fix contributions to instantaneous energy, virial, and cumulative energy`_
- `KSpace PPPM FFT grids`_ - `KSpace PPPM FFT grids`_
@ -216,6 +217,30 @@ command:
neighbor->add_request(this, "delete_atoms", NeighConst::REQ_FULL); neighbor->add_request(this, "delete_atoms", NeighConst::REQ_FULL);
Choosing between a custom atom style, fix property/atom, and fix STORE/ATOM
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
There are multiple ways to manage per-atom data within LAMMPS. Often
the per-atom storage is only used locally and managed by the class that
uses it. If the data has to persist between multiple time steps and
migrate with atoms when they move from sub-domain to sub-domain or
across periodic boundaries, then using a custom atom style, or :doc:`fix
property/atom <fix_property_atom>`, or the internal fix STORE/ATOM are
possible options.
- Using the atom style is usually the most programming effort and mostly
needed when the per-atom data is an integral part of the model like a
per-atom charge or diameter and thus should be part of the Atoms
section of a :doc:`data file <read_data>`.
- Fix property/atom is useful if the data is optional or should be
entered by the user, or accessed as a (named) custom property. In this
case the fix should be entered as part of the input (and not
internally) which allows to enter and store its content with data files.
- Fix STORE/ATOM should be used when the data should be accessed internally
only and thus the fix can be created internally.
Fix contributions to instantaneous energy, virial, and cumulative energy Fix contributions to instantaneous energy, virial, and cumulative energy
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

View File

@ -24,6 +24,7 @@ Available topics in mostly chronological order are:
- `Use of "override" instead of "virtual"`_ - `Use of "override" instead of "virtual"`_
- `Simplified and more compact neighbor list requests`_ - `Simplified and more compact neighbor list requests`_
- `Split of fix STORE into fix STORE/GLOBAL and fix STORE/PERATOM`_ - `Split of fix STORE into fix STORE/GLOBAL and fix STORE/PERATOM`_
- `Rename of fix STORE/PERATOM to fix STORE/ATOM and change of arguments`_
- `Use Output::get_dump_by_id() instead of Output::find_dump()`_ - `Use Output::get_dump_by_id() instead of Output::find_dump()`_
- `Refactored grid communication using Grid3d/Grid2d classes instead of GridComm`_ - `Refactored grid communication using Grid3d/Grid2d classes instead of GridComm`_
@ -385,6 +386,34 @@ New:
This change is **required** or else the code will not compile. This change is **required** or else the code will not compile.
Rename of fix STORE/PERATOM to fix STORE/ATOM and change of arguments
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. versionchanged:: TBD
The available functionality of the internal fix to store per-atom
properties was expanded to enable storing data with ghost atoms and to
support binary restart files. With those changes, the fix was renamed
to fix STORE/ATOM and the number and order of (required) arguments has
changed.
Old syntax: ``ID group-ID STORE/PERATOM rflag n1 n2 [n3]``
- *rflag* = 0/1, *no*/*yes* store per-atom values in restart file
- :math:`n1 = 1, n2 = 1, \mathrm{no}\;n3 \to` per-atom vector, single value per atom
- :math:`n1 = 1, n2 > 1, \mathrm{no}\;n3 \to` per-atom array, *n2* values per atom
- :math:`n1 = 1, n2 > 0, n3 > 0 \to` per-atom tensor, *n2* x *n3* values per atom
New syntax: ``ID group-ID STORE/ATOM n1 n2 gflag rflag``
- :math:`n1 = 1, n2 = 0 \to` per-atom vector, single value per atom
- :math:`n1 > 1, n2 = 0 \to` per-atom array, *n1* values per atom
- :math:`n1 > 0, n2 > 0 \to` per-atom tensor, *n1* x *n2* values per atom
- *gflag* = 0/1, *no*/*yes* communicate per-atom values with ghost atoms
- *rflag* = 0/1, *no*/*yes* store per-atom values in restart file
Since this is an internal fix, there is no user visible change.
Use Output::get_dump_by_id() instead of Output::find_dump() Use Output::get_dump_by_id() instead of Output::find_dump()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

View File

@ -0,0 +1,90 @@
.. index:: bond_style harmonic/restrain
bond_style harmonic/restrain command
====================================
Syntax
""""""
.. code-block:: LAMMPS
bond_style harmonic/restrain
Examples
""""""""
.. code-block:: LAMMPS
bond_style harmonic
bond_coeff 5 80.0
Description
"""""""""""
.. versionadded:: TBD
The *harmonic/restrain* bond style uses the potential
.. math::
E = K (r - r_{t=0})^2
where :math:`r_{t=0}` is the distance between the bonded atoms at the
beginning of the first :doc:`run <run>` or :doc:`minimize <minimize>`
command after the bond style has been defined (*t=0*). Note that the
usual 1/2 factor is included in :math:`K`. This will effectively
restrain bonds to their initial length, whatever that is. This is where
this bond style differs from :doc:`bond style harmonic <bond_harmonic>`
where the bond length is set through the per bond type coefficients.
The following coefficient must be defined for each bond type via the
:doc:`bond_coeff <bond_coeff>` command as in the example above, or in
the data file or restart files read by the :doc:`read_data <read_data>`
or :doc:`read_restart <read_restart>` commands
* :math:`K` (energy/distance\^2)
This bond style differs from other options to add harmonic restraints
like :doc:`fix restrain <fix_restrain>` or :doc:`pair style list
<pair_list>` or :doc:`fix colvars <fix_colvars>` in that it requires a
bond topology, and thus the defined bonds will trigger exclusion of
special neighbors from the neighbor list according to the
:doc:`special_bonds <special_bonds>` settings.
Restart info
""""""""""""
This bond style supports the :doc:`write_restart <write_restart>` and
:doc:`read_restart <read_restart>` commands. The state of the initial
bond lengths is stored with restart files and read back.
Restrictions
""""""""""""
This bond style can only be used if LAMMPS was built with the
EXTRA-MOLECULE package. See the :doc:`Build package <Build_package>`
page for more info.
This bond style maintains internal data to determine the original bond
lengths :math:`r_{t=0}`. This information will be written to
:doc:`binary restart files <write_restart>` but **not** to :doc:`data
files <write_data>`. Thus, continuing a simulation is *only* possible
with :doc:`read_restart <read_restart>`. When using the :doc:`read_data
command <read_data>`, the reference bond lengths :math:`r_{t=0}` will be
re-initialized from the current geometry.
This bond style cannot be used with :doc:`fix shake or fix rattle
<fix_shake>`, with :doc:`fix filter/corotate <fix_filter_corotate>`, or
any :doc:`tip4p pair style <pair_lj_cut_tip4p>` since there is no specific
equilibrium distance for a given bond type.
Related commands
""""""""""""""""
:doc:`bond_coeff <bond_coeff>`, :doc:`bond_harmonic <bond_harmonic>`,
:doc:`fix restrain <fix_restrain>`, :doc:`pair style list <pair_list>`
Default
"""""""
none

View File

@ -10,7 +10,7 @@ Syntax
bond_style style args bond_style style args
* style = *none* or *zero* or *hybrid* or *bpm/rotational* or *bpm/spring* or *class2* or *fene* or *fene/expand* or *fene/nm* or *gaussian* or *gromos* or *harmonic* or *harmonic/shift* or *harmonic/shift/cut* or *lepton* or *morse* or *nonlinear* or *oxdna/fene* or *oxdena2/fene* or *oxrna2/fene* or *quartic* or *special* or *table* * style = *none* or *zero* or *hybrid* or *bpm/rotational* or *bpm/spring* or *class2* or *fene* or *fene/expand* or *fene/nm* or *gaussian* or *gromos* or *harmonic* or *harmonic/restrain* *harmonic/shift* or *harmonic/shift/cut* or *lepton* or *morse* or *nonlinear* or *oxdna/fene* or *oxdena2/fene* or *oxrna2/fene* or *quartic* or *special* or *table*
* args = none for any style except *hybrid* * args = none for any style except *hybrid*
@ -93,6 +93,7 @@ accelerated styles exist.
* :doc:`gaussian <bond_gaussian>` - multicentered Gaussian-based bond potential * :doc:`gaussian <bond_gaussian>` - multicentered Gaussian-based bond potential
* :doc:`gromos <bond_gromos>` - GROMOS force field bond * :doc:`gromos <bond_gromos>` - GROMOS force field bond
* :doc:`harmonic <bond_harmonic>` - harmonic bond * :doc:`harmonic <bond_harmonic>` - harmonic bond
* :doc:`harmonic/restrain <bond_harmonic_restrain>` - harmonic bond to restrain to original bond distance
* :doc:`harmonic/shift <bond_harmonic_shift>` - shifted harmonic bond * :doc:`harmonic/shift <bond_harmonic_shift>` - shifted harmonic bond
* :doc:`harmonic/shift/cut <bond_harmonic_shift_cut>` - shifted harmonic bond with a cutoff * :doc:`harmonic/shift/cut <bond_harmonic_shift_cut>` - shifted harmonic bond with a cutoff
* :doc:`lepton <bond_lepton>` - bond potential from evaluating a string * :doc:`lepton <bond_lepton>` - bond potential from evaluating a string

View File

@ -2469,6 +2469,7 @@ nodeless
nodeset nodeset
nodesets nodesets
Noehring Noehring
nofix
Noffset Noffset
noforce noforce
noguess noguess

2
src/.gitignore vendored
View File

@ -492,6 +492,8 @@
/bond_gromos.h /bond_gromos.h
/bond_harmonic.cpp /bond_harmonic.cpp
/bond_harmonic.h /bond_harmonic.h
/bond_harmonic_restrain.cpp
/bond_harmonic_restrain.h
/bond_harmonic_shift.cpp /bond_harmonic_shift.cpp
/bond_harmonic_shift.h /bond_harmonic_shift.h
/bond_harmonic_shift_cut.cpp /bond_harmonic_shift_cut.cpp

View File

@ -19,7 +19,7 @@
#include "comm.h" #include "comm.h"
#include "domain.h" #include "domain.h"
#include "error.h" #include "error.h"
#include "fix_store_peratom.h" #include "fix_store_atom.h"
#include "math_const.h" #include "math_const.h"
#include "math_special.h" #include "math_special.h"
#include "my_page.h" #include "my_page.h"

View File

@ -17,7 +17,7 @@
#include "atom.h" #include "atom.h"
#include "domain.h" #include "domain.h"
#include "error.h" #include "error.h"
#include "fix_store_peratom.h" #include "fix_store_atom.h"
#include "neigh_list.h" #include "neigh_list.h"
#include <cmath> #include <cmath>

View File

@ -20,7 +20,7 @@
#include "domain.h" #include "domain.h"
#include "error.h" #include "error.h"
#include "fix.h" #include "fix.h"
#include "fix_store_peratom.h" #include "fix_store_atom.h"
#include "force.h" #include "force.h"
#include "group.h" #include "group.h"
#include "math_special.h" #include "math_special.h"
@ -861,8 +861,8 @@ void PairAmoeba::init_style()
Fix *myfix; Fix *myfix;
if (first_flag) { if (first_flag) {
id_pole = utils::strdup("AMOEBA_pole"); id_pole = utils::strdup("AMOEBA_pole");
myfix = modify->add_fix(fmt::format("{} {} STORE/PERATOM 1 13",id_pole,group->names[0])); myfix = modify->add_fix(fmt::format("{} {} STORE/ATOM 13 0 0 1",id_pole,group->names[0]));
fixpole = dynamic_cast<FixStorePeratom *>(myfix); fixpole = dynamic_cast<FixStoreAtom *>(myfix);
} }
// creation of per-atom storage // creation of per-atom storage
@ -873,14 +873,14 @@ void PairAmoeba::init_style()
if (first_flag && use_pred) { if (first_flag && use_pred) {
id_udalt = utils::strdup("AMOEBA_udalt"); id_udalt = utils::strdup("AMOEBA_udalt");
myfix = modify->add_fix(fmt::format("{} {} STORE/PERATOM 1 {} 3", myfix = modify->add_fix(fmt::format("{} {} STORE/ATOM {} 3 0 1",
id_udalt, group->names[0], maxualt)); id_udalt, group->names[0], maxualt));
fixudalt = dynamic_cast<FixStorePeratom *>(myfix); fixudalt = dynamic_cast<FixStoreAtom *>(myfix);
id_upalt = utils::strdup("AMOEBA_upalt"); id_upalt = utils::strdup("AMOEBA_upalt");
myfix = modify->add_fix(fmt::format("{} {} STORE/PERATOM 1 {} 3", myfix = modify->add_fix(fmt::format("{} {} STORE/ATOM {} 3 0 1",
id_upalt, group->names[0], maxualt)); id_upalt, group->names[0], maxualt));
fixupalt = dynamic_cast<FixStorePeratom *>(myfix); fixupalt = dynamic_cast<FixStoreAtom *>(myfix);
} }
// create pages for storing pairwise data: // create pages for storing pairwise data:
@ -995,21 +995,21 @@ void PairAmoeba::init_style()
if (id_pole) { if (id_pole) {
myfix = modify->get_fix_by_id(id_pole); myfix = modify->get_fix_by_id(id_pole);
if (!myfix) if (!myfix)
error->all(FLERR,"Could not find internal pair amoeba fix STORE/PERATOM id {}", id_pole); error->all(FLERR,"Could not find internal pair amoeba fix STORE/ATOM id {}", id_pole);
fixpole = dynamic_cast<FixStorePeratom *>(myfix); fixpole = dynamic_cast<FixStoreAtom *>(myfix);
} }
if (id_udalt) { if (id_udalt) {
myfix = modify->get_fix_by_id(id_udalt); myfix = modify->get_fix_by_id(id_udalt);
if (!myfix) if (!myfix)
error->all(FLERR,"Could not find internal pair amoeba fix STORE/PERATOM id {}", id_udalt); error->all(FLERR,"Could not find internal pair amoeba fix STORE/ATOM id {}", id_udalt);
fixudalt = dynamic_cast<FixStorePeratom *>(myfix); fixudalt = dynamic_cast<FixStoreAtom *>(myfix);
myfix = modify->get_fix_by_id(id_upalt); myfix = modify->get_fix_by_id(id_upalt);
if (!myfix) if (!myfix)
error->all(FLERR,"Could not find internal pair amoeba fix STORE/PERATOM id {}", id_upalt); error->all(FLERR,"Could not find internal pair amoeba fix STORE/ATOM id {}", id_upalt);
fixupalt = dynamic_cast<FixStorePeratom *>(myfix); fixupalt = dynamic_cast<FixStoreAtom *>(myfix);
} }
// assign hydrogen neighbors (redID) to each owned atom // assign hydrogen neighbors (redID) to each owned atom

View File

@ -166,9 +166,9 @@ class PairAmoeba : public Pair {
int *amgroup; // AMOEBA polarization group, 1 to Ngroup int *amgroup; // AMOEBA polarization group, 1 to Ngroup
char *id_pole, *id_udalt, *id_upalt; char *id_pole, *id_udalt, *id_upalt;
class FixStorePeratom *fixpole; // stores pole = multipole components class FixStoreAtom *fixpole; // stores pole = multipole components
class FixStorePeratom *fixudalt; // stores udalt = induced dipole history class FixStoreAtom *fixudalt; // stores udalt = induced dipole history
class FixStorePeratom *fixupalt; // stores upalt = induced dipole history class FixStoreAtom *fixupalt; // stores upalt = induced dipole history
// static per-type properties defined in force-field file // static per-type properties defined in force-field file

View File

@ -24,7 +24,7 @@
#include "comm.h" #include "comm.h"
#include "domain.h" #include "domain.h"
#include "error.h" #include "error.h"
#include "fix_store_peratom.h" #include "fix_store_atom.h"
#include "force.h" #include "force.h"
#include "group.h" #include "group.h"
#include "memory.h" #include "memory.h"
@ -67,8 +67,8 @@ ComputeTempCS::ComputeTempCS(LAMMPS *lmp, int narg, char **arg) :
// id = compute-ID + COMPUTE_STORE, fix group = compute group // id = compute-ID + COMPUTE_STORE, fix group = compute group
id_fix = utils::strdup(id + std::string("_COMPUTE_STORE")); id_fix = utils::strdup(id + std::string("_COMPUTE_STORE"));
fix = dynamic_cast<FixStorePeratom *>( fix = dynamic_cast<FixStoreAtom *>(
modify->add_fix(fmt::format("{} {} STORE/PERATOM 0 1", id_fix, group->names[igroup]))); modify->add_fix(fmt::format("{} {} STORE/ATOM 1 0 0 0", id_fix, group->names[igroup])));
// set fix store values = 0 for now // set fix store values = 0 for now
// fill them in via setup() once Comm::borders() has been called // fill them in via setup() once Comm::borders() has been called

View File

@ -54,7 +54,7 @@ class ComputeTempCS : public Compute {
double **vint; double **vint;
char *id_fix; char *id_fix;
class FixStorePeratom *fix; class FixStoreAtom *fix;
void dof_compute(); void dof_compute();
void vcm_pairs(); void vcm_pairs();

View File

@ -54,7 +54,7 @@ https://doi.org/10.1103/PhysRevE.92.043303
#include "domain.h" #include "domain.h"
#include "error.h" #include "error.h"
#include "fix.h" #include "fix.h"
#include "fix_store_peratom.h" #include "fix_store_atom.h"
#include "force.h" #include "force.h"
#include "group.h" #include "group.h"
#include "improper.h" #include "improper.h"
@ -90,8 +90,8 @@ ComputeHMA::ComputeHMA(LAMMPS *lmp, int narg, char **arg) :
// our new fix's group = same as compute group // our new fix's group = same as compute group
id_fix = utils::strdup(std::string(id)+"_COMPUTE_STORE"); id_fix = utils::strdup(std::string(id)+"_COMPUTE_STORE");
fix = dynamic_cast<FixStorePeratom *>( fix = dynamic_cast<FixStoreAtom *>(
modify->add_fix(fmt::format("{} {} STORE/PERATOM 1 3", id_fix, group->names[igroup]))); modify->add_fix(fmt::format("{} {} STORE/ATOM 3 0 0 1", id_fix, group->names[igroup])));
// calculate xu,yu,zu for fix store array // calculate xu,yu,zu for fix store array
// skip if reset from restart file // skip if reset from restart file
@ -196,7 +196,7 @@ void ComputeHMA::setup()
// set fix which stores original atom coords // set fix which stores original atom coords
fix = dynamic_cast<FixStorePeratom *>(modify->get_fix_by_id(id_fix)); fix = dynamic_cast<FixStoreAtom *>(modify->get_fix_by_id(id_fix));
if (!fix) error->all(FLERR,"Could not find hma per-atom store fix ID {}", id_fix); if (!fix) error->all(FLERR,"Could not find hma per-atom store fix ID {}", id_fix);
} }

View File

@ -43,7 +43,7 @@ class ComputeHMA : public Compute {
char *id_fix; char *id_fix;
char *id_temp; char *id_temp;
double finaltemp; double finaltemp;
class FixStorePeratom *fix; class FixStoreAtom *fix;
double boltz, nktv2p, inv_volume; double boltz, nktv2p, inv_volume;
double deltaPcap; double deltaPcap;
double virial_compute(int); double virial_compute(int);

View File

@ -19,7 +19,7 @@
#include "atom.h" #include "atom.h"
#include "domain.h" #include "domain.h"
#include "fix_store_peratom.h" #include "fix_store_atom.h"
#include "group.h" #include "group.h"
#include "update.h" #include "update.h"

View File

@ -0,0 +1,260 @@
/* ----------------------------------------------------------------------
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 "bond_harmonic_restrain.h"
#include "atom.h"
#include "comm.h"
#include "domain.h"
#include "error.h"
#include "fix_store_atom.h"
#include "force.h"
#include "memory.h"
#include "modify.h"
#include "neighbor.h"
#include <cmath>
#include <cstring>
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
BondHarmonicRestrain::BondHarmonicRestrain(LAMMPS *_lmp) : Bond(_lmp), initial(nullptr)
{
writedata = 0;
natoms = -1;
}
/* ---------------------------------------------------------------------- */
BondHarmonicRestrain::~BondHarmonicRestrain()
{
if (initial) modify->delete_fix("BOND_RESTRAIN_X0");
if (allocated) {
memory->destroy(setflag);
memory->destroy(k);
}
}
/* ---------------------------------------------------------------------- */
void BondHarmonicRestrain::compute(int eflag, int vflag)
{
int i1, i2, n, type;
double delx, dely, delz, ebond, fbond;
double rsq, r, r0, dr, rk;
ebond = 0.0;
ev_init(eflag, vflag);
double **x = atom->x;
double **x0 = initial->astore;
double **f = atom->f;
int **bondlist = neighbor->bondlist;
int nbondlist = neighbor->nbondlist;
int nlocal = atom->nlocal;
int newton_bond = force->newton_bond;
for (n = 0; n < nbondlist; n++) {
i1 = bondlist[n][0];
i2 = bondlist[n][1];
type = bondlist[n][2];
delx = x0[i1][0] - x0[i2][0];
dely = x0[i1][1] - x0[i2][1];
delz = x0[i1][2] - x0[i2][2];
domain->minimum_image(delx, dely, delz);
rsq = delx * delx + dely * dely + delz * delz;
r0 = sqrt(rsq);
delx = x[i1][0] - x[i2][0];
dely = x[i1][1] - x[i2][1];
delz = x[i1][2] - x[i2][2];
rsq = delx * delx + dely * dely + delz * delz;
r = sqrt(rsq);
dr = r - r0;
rk = k[type] * dr;
// force & energy
if (r > 0.0)
fbond = -2.0 * rk / r;
else
fbond = 0.0;
if (eflag) ebond = rk * dr;
// apply force to each of 2 atoms
if (newton_bond || i1 < nlocal) {
f[i1][0] += delx * fbond;
f[i1][1] += dely * fbond;
f[i1][2] += delz * fbond;
}
if (newton_bond || i2 < nlocal) {
f[i2][0] -= delx * fbond;
f[i2][1] -= dely * fbond;
f[i2][2] -= delz * fbond;
}
if (evflag) ev_tally(i1, i2, nlocal, newton_bond, ebond, fbond, delx, dely, delz);
}
}
/* ---------------------------------------------------------------------- */
void BondHarmonicRestrain::allocate()
{
allocated = 1;
const int np1 = atom->nbondtypes + 1;
memory->create(k, np1, "bond:k");
memory->create(setflag, np1, "bond:setflag");
for (int i = 1; i < np1; i++) setflag[i] = 0;
}
/* ----------------------------------------------------------------------
set coeffs for one or more types
------------------------------------------------------------------------- */
void BondHarmonicRestrain::coeff(int narg, char **arg)
{
if (narg != 2) error->all(FLERR, "Incorrect args for bond coefficients");
if (!allocated) allocate();
int ilo, ihi;
utils::bounds(FLERR, arg[0], 1, atom->nbondtypes, ilo, ihi, error);
double k_one = utils::numeric(FLERR, arg[1], false, lmp);
int count = 0;
for (int i = ilo; i <= ihi; i++) {
k[i] = k_one;
setflag[i] = 1;
count++;
}
if (count == 0) error->all(FLERR, "Incorrect args for bond coefficients");
}
/* ----------------------------------------------------------------------
initialize custom data storage
------------------------------------------------------------------------- */
void BondHarmonicRestrain::init_style()
{
// store initial positions
if (natoms < 0) {
// create internal fix to store initial positions
initial = dynamic_cast<FixStoreAtom *>(
modify->add_fix("BOND_RESTRAIN_X0 all STORE/ATOM 3 0 1 1"));
if (!initial) error->all(FLERR, "Failure to create internal per-atom storage");
natoms = atom->natoms;
double **x0 = initial->astore;
const double *const *const x = atom->x;
for (int i = 0; i < atom->nlocal; ++i)
for (int j = 0; j < 3; ++j) x0[i][j] = x[i][j];
} else {
// after a restart, natoms is set but initial is a null pointer.
// we add the fix, but do not initialize it. It will pull the data from the restart.
if (!initial) {
initial = dynamic_cast<FixStoreAtom *>(
modify->add_fix("BOND_RESTRAIN_X0 all STORE/ATOM 3 0 1 1"));
if (!initial) error->all(FLERR, "Failure to create internal per-atom storage");
}
}
// must not add atoms
if (natoms < atom->natoms)
error->all(FLERR, "Bond style harmonic/restrain does not support adding atoms");
}
/* ----------------------------------------------------------------------
proc 0 writes out coeffs to restart file
------------------------------------------------------------------------- */
void BondHarmonicRestrain::write_restart(FILE *fp)
{
fwrite(&natoms, sizeof(bigint), 1, fp);
fwrite(&k[1], sizeof(double), atom->nbondtypes, fp);
}
/* ----------------------------------------------------------------------
proc 0 reads coeffs from restart file, bcasts them
------------------------------------------------------------------------- */
void BondHarmonicRestrain::read_restart(FILE *fp)
{
allocate();
if (comm->me == 0) {
utils::sfread(FLERR, &natoms, sizeof(bigint), 1, fp, nullptr, error);
utils::sfread(FLERR, &k[1], sizeof(double), atom->nbondtypes, fp, nullptr, error);
}
MPI_Bcast(&natoms, 1, MPI_LMP_BIGINT, 0, world);
MPI_Bcast(&k[1], atom->nbondtypes, MPI_DOUBLE, 0, world);
for (int i = 1; i <= atom->nbondtypes; i++) setflag[i] = 1;
}
/* ----------------------------------------------------------------------
proc 0 writes to data file
------------------------------------------------------------------------- */
void BondHarmonicRestrain::write_data(FILE *fp)
{
for (int i = 1; i <= atom->nbondtypes; i++) fprintf(fp, "%d %g\n", i, k[i]);
}
/* ---------------------------------------------------------------------- */
double BondHarmonicRestrain::single(int type, double rsq, int i, int j, double &fforce)
{
double **x0 = initial->astore;
double delx = x0[i][0] - x0[j][0];
double dely = x0[i][1] - x0[j][1];
double delz = x0[i][2] - x0[j][2];
domain->minimum_image(delx, dely, delz);
double r0 = sqrt(delx * delx + dely * dely + delz * delz);
double r = sqrt(rsq);
double dr = r - r0;
double rk = k[type] * dr;
fforce = 0;
if (r > 0.0) fforce = -2.0 * rk / r;
return rk * dr;
}
/* ---------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
return ptr to internal members upon request
------------------------------------------------------------------------ */
void *BondHarmonicRestrain::extract(const char *str, int &dim)
{
dim = 1;
if (strcmp(str, "k") == 0) return (void *) k;
return nullptr;
}

View File

@ -0,0 +1,52 @@
/* -*- 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 BOND_CLASS
// clang-format off
BondStyle(harmonic/restrain,BondHarmonicRestrain);
// clang-format on
#else
#ifndef LMP_BOND_HARMONIC_RESTRAIN_H
#define LMP_BOND_HARMONIC_RESTRAIN_H
#include "bond.h"
namespace LAMMPS_NS {
class BondHarmonicRestrain : public Bond {
public:
BondHarmonicRestrain(class LAMMPS *);
~BondHarmonicRestrain() override;
void compute(int, int) override;
void coeff(int, char **) override;
void init_style() override;
double equilibrium_distance(int) override { return -1.0; }; // return invalid value since not applicable
void write_restart(FILE *) override;
void read_restart(FILE *) override;
void write_data(FILE *) override;
double single(int, double, int, int, double &) override;
void *extract(const char *, int &) override;
protected:
double *k;
bigint natoms;
class FixStoreAtom *initial;
virtual void allocate();
};
} // namespace LAMMPS_NS
#endif
#endif

View File

@ -20,7 +20,7 @@
#include "atom.h" #include "atom.h"
#include "error.h" #include "error.h"
#include "fix_store_peratom.h" #include "fix_store_atom.h"
#include "force.h" #include "force.h"
#include "group.h" #include "group.h"
#include "input.h" #include "input.h"
@ -211,8 +211,8 @@ void FixAdaptFEP::post_constructor()
if (diamflag) { if (diamflag) {
id_fix_diam = utils::strdup(id + std::string("_FIX_STORE_DIAM")); id_fix_diam = utils::strdup(id + std::string("_FIX_STORE_DIAM"));
fix_diam = dynamic_cast<FixStorePeratom *>( fix_diam = dynamic_cast<FixStoreAtom *>(
modify->add_fix(fmt::format("{} {} STORE/PERATOM 1 1", id_fix_diam,group->names[igroup]))); modify->add_fix(fmt::format("{} {} STORE/ATOM 1 0 0 1", id_fix_diam,group->names[igroup])));
if (fix_diam->restart_reset) fix_diam->restart_reset = 0; if (fix_diam->restart_reset) fix_diam->restart_reset = 0;
else { else {
double *vec = fix_diam->vstore; double *vec = fix_diam->vstore;
@ -229,8 +229,8 @@ void FixAdaptFEP::post_constructor()
if (chgflag) { if (chgflag) {
id_fix_chg = utils::strdup(id + std::string("_FIX_STORE_CHG")); id_fix_chg = utils::strdup(id + std::string("_FIX_STORE_CHG"));
fix_chg = dynamic_cast<FixStorePeratom *>( fix_chg = dynamic_cast<FixStoreAtom *>(
modify->add_fix(fmt::format("{} {} STORE/PERATOM 1 1",id_fix_chg,group->names[igroup]))); modify->add_fix(fmt::format("{} {} STORE/ATOM 1 0 0 1",id_fix_chg,group->names[igroup])));
if (fix_chg->restart_reset) fix_chg->restart_reset = 0; if (fix_chg->restart_reset) fix_chg->restart_reset = 0;
else { else {
double *vec = fix_chg->vstore; double *vec = fix_chg->vstore;
@ -333,11 +333,11 @@ void FixAdaptFEP::init()
// fixes that store initial per-atom values // fixes that store initial per-atom values
if (id_fix_diam) { if (id_fix_diam) {
fix_diam = dynamic_cast<FixStorePeratom *>(modify->get_fix_by_id(id_fix_diam)); fix_diam = dynamic_cast<FixStoreAtom *>(modify->get_fix_by_id(id_fix_diam));
if (!fix_diam) error->all(FLERR,"Could not find fix adapt/fep storage fix ID {}", id_fix_diam); if (!fix_diam) error->all(FLERR,"Could not find fix adapt/fep storage fix ID {}", id_fix_diam);
} }
if (id_fix_chg) { if (id_fix_chg) {
fix_chg = dynamic_cast<FixStorePeratom *>(modify->get_fix_by_id(id_fix_chg)); fix_chg = dynamic_cast<FixStoreAtom *>(modify->get_fix_by_id(id_fix_chg));
if (!fix_chg) error->all(FLERR,"Could not find fix adapt/fep storage fix ID {}", id_fix_chg); if (!fix_chg) error->all(FLERR,"Could not find fix adapt/fep storage fix ID {}", id_fix_chg);
} }

View File

@ -46,7 +46,7 @@ class FixAdaptFEP : public Fix {
int anypair; int anypair;
int nlevels_respa; int nlevels_respa;
char *id_fix_diam, *id_fix_chg; char *id_fix_diam, *id_fix_chg;
class FixStorePeratom *fix_diam, *fix_chg; class FixStoreAtom *fix_diam, *fix_chg;
struct Adapt { struct Adapt {
int which, ivar; int which, ivar;

View File

@ -23,7 +23,7 @@
#include "comm.h" #include "comm.h"
#include "domain.h" #include "domain.h"
#include "error.h" #include "error.h"
#include "fix_store_peratom.h" #include "fix_store_atom.h"
#include "force.h" #include "force.h"
#include "gpu_extra.h" #include "gpu_extra.h"
#include "info.h" #include "info.h"

View File

@ -23,7 +23,7 @@
#include "comm.h" #include "comm.h"
#include "domain.h" #include "domain.h"
#include "error.h" #include "error.h"
#include "fix_store_peratom.h" #include "fix_store_atom.h"
#include "force.h" #include "force.h"
#include "gpu_extra.h" #include "gpu_extra.h"
#include "info.h" #include "info.h"

View File

@ -24,7 +24,7 @@
#include "error.h" #include "error.h"
#include "finish.h" #include "finish.h"
#include "fix_event_tad.h" #include "fix_event_tad.h"
#include "fix_store_peratom.h" #include "fix_store_atom.h"
#include "force.h" #include "force.h"
#include "integrate.h" #include "integrate.h"
#include "memory.h" #include "memory.h"
@ -133,9 +133,9 @@ void TAD::command(int narg, char **arg)
fix_event = dynamic_cast<FixEventTAD *>(modify->add_fix("tad_event all EVENT/TAD")); fix_event = dynamic_cast<FixEventTAD *>(modify->add_fix("tad_event all EVENT/TAD"));
// create FixStorePeratom object to store revert state // create FixStoreAtom object to store revert state
fix_revert = dynamic_cast<FixStorePeratom *>(modify->add_fix("tad_revert all STORE/PERATOM 0 7")); fix_revert = dynamic_cast<FixStoreAtom *>(modify->add_fix("tad_revert all STORE/ATOM 7 0 0 0"));
// create Finish for timing output // create Finish for timing output

View File

@ -48,15 +48,15 @@ class TAD : public Command {
double time_dynamics, time_quench, time_neb, time_comm, time_output; double time_dynamics, time_quench, time_neb, time_comm, time_output;
double time_start; double time_start;
class NEB *neb; // NEB object class NEB *neb; // NEB object
class Fix *fix_neb; // FixNEB object class Fix *fix_neb; // FixNEB object
class Compute *compute_event; // compute to detect event class Compute *compute_event; // compute to detect event
class FixEventTAD *fix_event; // current event/state class FixEventTAD *fix_event; // current event/state
class FixStorePeratom *fix_revert; // revert state class FixStoreAtom *fix_revert; // revert state
FixEventTAD **fix_event_list; // list of possible events FixEventTAD **fix_event_list; // list of possible events
int n_event_list; // number of events int n_event_list; // number of events
int nmax_event_list; // allocated events int nmax_event_list; // allocated events
int nmin_event_list; // minimum allocation int nmin_event_list; // minimum allocation
char *neb_logfilename; // filename for ulogfile_neb char *neb_logfilename; // filename for ulogfile_neb
FILE *uscreen_neb; // neb universe screen output FILE *uscreen_neb; // neb universe screen output

View File

@ -31,7 +31,7 @@
#include "domain.h" #include "domain.h"
#include "error.h" #include "error.h"
#include "fix.h" #include "fix.h"
#include "fix_store_peratom.h" #include "fix_store_atom.h"
#include "force.h" #include "force.h"
#include "group.h" #include "group.h"
#include "input.h" #include "input.h"
@ -2357,16 +2357,16 @@ int DumpVTK::modify_param(int narg, char **arg)
thresh_value[nthresh] = utils::numeric(FLERR,arg[3],false,lmp); thresh_value[nthresh] = utils::numeric(FLERR,arg[3],false,lmp);
thresh_last[nthresh] = -1; thresh_last[nthresh] = -1;
} else { } else {
thresh_fix = (FixStorePeratom **) thresh_fix = (FixStoreAtom **)
memory->srealloc(thresh_fix,(nthreshlast+1)*sizeof(FixStorePeratom *),"dump:thresh_fix"); memory->srealloc(thresh_fix,(nthreshlast+1)*sizeof(FixStoreAtom *),"dump:thresh_fix");
thresh_fixID = (char **) thresh_fixID = (char **)
memory->srealloc(thresh_fixID,(nthreshlast+1)*sizeof(char *),"dump:thresh_fixID"); memory->srealloc(thresh_fixID,(nthreshlast+1)*sizeof(char *),"dump:thresh_fixID");
memory->grow(thresh_first,(nthreshlast+1),"dump:thresh_first"); memory->grow(thresh_first,(nthreshlast+1),"dump:thresh_first");
std::string threshid = fmt::format("{}{}_DUMP_STORE",id,nthreshlast); std::string threshid = fmt::format("{}{}_DUMP_STORE",id,nthreshlast);
thresh_fixID[nthreshlast] = utils::strdup(threshid); thresh_fixID[nthreshlast] = utils::strdup(threshid);
threshid += fmt::format(" {} STORE/PERATOM 1 1", group->names[igroup]); threshid += fmt::format(" {} STORE/ATOM 1 0 0 1", group->names[igroup]);
thresh_fix[nthreshlast] = dynamic_cast<FixStorePeratom *>(modify->add_fix(threshid)); thresh_fix[nthreshlast] = dynamic_cast<FixStoreAtom *>(modify->add_fix(threshid));
thresh_last[nthreshlast] = nthreshlast; thresh_last[nthreshlast] = nthreshlast;
thresh_first[nthreshlast] = 1; thresh_first[nthreshlast] = 1;

View File

@ -26,7 +26,7 @@
#include "neighbor.h" #include "neighbor.h"
#include "comm.h" #include "comm.h"
#include "domain.h" #include "domain.h"
#include "fix_store_peratom.h" #include "fix_store_atom.h"
#include "force.h" #include "force.h"
#include "imbalance.h" #include "imbalance.h"
#include "imbalance_group.h" #include "imbalance_group.h"
@ -513,9 +513,9 @@ void Balance::weight_storage(char *prefix)
if (prefix) cmd = prefix; if (prefix) cmd = prefix;
cmd += "IMBALANCE_WEIGHTS"; cmd += "IMBALANCE_WEIGHTS";
fixstore = dynamic_cast<FixStorePeratom *>(modify->get_fix_by_id(cmd)); fixstore = dynamic_cast<FixStoreAtom *>(modify->get_fix_by_id(cmd));
if (!fixstore) if (!fixstore)
fixstore = dynamic_cast<FixStorePeratom *>(modify->add_fix(cmd + " all STORE/PERATOM 0 1")); fixstore = dynamic_cast<FixStoreAtom *>(modify->add_fix(cmd + " all STORE/ATOM 1 0 0 0"));
// do not carry weights with atoms during normal atom migration // do not carry weights with atoms during normal atom migration

View File

@ -27,11 +27,11 @@ namespace LAMMPS_NS {
class Balance : public Command { class Balance : public Command {
public: public:
class RCB *rcb; class RCB *rcb;
class FixStorePeratom *fixstore; // per-atom weights stored in FixStorePeratom class FixStoreAtom *fixstore; // per-atom weights stored in FixStorePeratom
int wtflag; // 1 if particle weighting is used int wtflag; // 1 if particle weighting is used
int varflag; // 1 if weight style var(iable) is used int varflag; // 1 if weight style var(iable) is used
int sortflag; // 1 if sorting of comm messages is done int sortflag; // 1 if sorting of comm messages is done
int outflag; // 1 for output of balance results to file int outflag; // 1 for output of balance results to file
Balance(class LAMMPS *); Balance(class LAMMPS *);
~Balance() override; ~Balance() override;

View File

@ -21,7 +21,7 @@
#include "domain.h" #include "domain.h"
#include "error.h" #include "error.h"
#include "fix.h" #include "fix.h"
#include "fix_store_peratom.h" #include "fix_store_atom.h"
#include "group.h" #include "group.h"
#include "input.h" #include "input.h"
#include "lattice.h" #include "lattice.h"
@ -571,8 +571,8 @@ void ComputeChunkAtom::init()
if ((idsflag == ONCE || lockcount) && !fixstore) { if ((idsflag == ONCE || lockcount) && !fixstore) {
id_fix = utils::strdup(id + std::string("_COMPUTE_STORE")); id_fix = utils::strdup(id + std::string("_COMPUTE_STORE"));
fixstore = dynamic_cast<FixStorePeratom *>( fixstore = dynamic_cast<FixStoreAtom *>(
modify->add_fix(fmt::format("{} {} STORE/PERATOM 1 1", id_fix, group->names[igroup]))); modify->add_fix(fmt::format("{} {} STORE/ATOM 1 0 0 1", id_fix, group->names[igroup])));
} }
if ((idsflag != ONCE && !lockcount) && fixstore) { if ((idsflag != ONCE && !lockcount) && fixstore) {

View File

@ -93,7 +93,7 @@ class ComputeChunkAtom : public Compute {
double *varatom; double *varatom;
char *id_fix; char *id_fix;
class FixStorePeratom *fixstore; class FixStoreAtom *fixstore;
class Fix *lockfix; // ptr to FixAveChunk that is locking out setups class Fix *lockfix; // ptr to FixAveChunk that is locking out setups
// null pointer if no lock currently in place // null pointer if no lock currently in place

View File

@ -17,7 +17,7 @@
#include "atom.h" #include "atom.h"
#include "domain.h" #include "domain.h"
#include "error.h" #include "error.h"
#include "fix_store_peratom.h" #include "fix_store_atom.h"
#include "group.h" #include "group.h"
#include "input.h" #include "input.h"
#include "memory.h" #include "memory.h"
@ -74,8 +74,8 @@ ComputeDisplaceAtom::ComputeDisplaceAtom(LAMMPS *lmp, int narg, char **arg) :
// id = compute-ID + COMPUTE_STORE, fix group = compute group // id = compute-ID + COMPUTE_STORE, fix group = compute group
id_fix = utils::strdup(std::string(id) + "_COMPUTE_STORE"); id_fix = utils::strdup(std::string(id) + "_COMPUTE_STORE");
fix = dynamic_cast<FixStorePeratom *>( fix = dynamic_cast<FixStoreAtom *>(
modify->add_fix(fmt::format("{} {} STORE/PERATOM 1 3", id_fix, group->names[igroup]))); modify->add_fix(fmt::format("{} {} STORE/ATOM 3 0 0 1", id_fix, group->names[igroup])));
// calculate xu,yu,zu for fix store array // calculate xu,yu,zu for fix store array
// skip if reset from restart file // skip if reset from restart file
@ -120,7 +120,7 @@ void ComputeDisplaceAtom::init()
{ {
// set fix which stores original atom coords // set fix which stores original atom coords
fix = dynamic_cast<FixStorePeratom *>(modify->get_fix_by_id(id_fix)); fix = dynamic_cast<FixStoreAtom *>(modify->get_fix_by_id(id_fix));
if (!fix) error->all(FLERR,"Could not find compute displace/atom fix with ID {}", id_fix); if (!fix) error->all(FLERR,"Could not find compute displace/atom fix with ID {}", id_fix);
if (refreshflag) { if (refreshflag) {

View File

@ -38,7 +38,7 @@ class ComputeDisplaceAtom : public Compute {
int nmax; int nmax;
double **displace; double **displace;
char *id_fix; char *id_fix;
class FixStorePeratom *fix; class FixStoreAtom *fix;
int refreshflag, ivar, nvmax; // refresh option is enabled int refreshflag, ivar, nvmax; // refresh option is enabled
char *rvar; // for incremental dumps char *rvar; // for incremental dumps

View File

@ -16,7 +16,7 @@
#include "atom.h" #include "atom.h"
#include "domain.h" #include "domain.h"
#include "error.h" #include "error.h"
#include "fix_store_peratom.h" #include "fix_store_atom.h"
#include "group.h" #include "group.h"
#include "modify.h" #include "modify.h"
#include "update.h" #include "update.h"
@ -63,8 +63,8 @@ ComputeMSD::ComputeMSD(LAMMPS *lmp, int narg, char **arg) : Compute(lmp, narg, a
// id = compute-ID + COMPUTE_STORE, fix group = compute group // id = compute-ID + COMPUTE_STORE, fix group = compute group
id_fix = utils::strdup(id + std::string("_COMPUTE_STORE")); id_fix = utils::strdup(id + std::string("_COMPUTE_STORE"));
fix = dynamic_cast<FixStorePeratom *>( fix = dynamic_cast<FixStoreAtom *>(
modify->add_fix(fmt::format("{} {} STORE/PERATOM 1 3", id_fix, group->names[igroup]))); modify->add_fix(fmt::format("{} {} STORE/ATOM 3 0 0 1", id_fix, group->names[igroup])));
// calculate xu,yu,zu for fix store array // calculate xu,yu,zu for fix store array
// skip if reset from restart file // skip if reset from restart file
@ -127,7 +127,7 @@ void ComputeMSD::init()
{ {
// set fix which stores reference atom coords // set fix which stores reference atom coords
fix = dynamic_cast<FixStorePeratom *>(modify->get_fix_by_id(id_fix)); fix = dynamic_cast<FixStoreAtom *>(modify->get_fix_by_id(id_fix));
if (!fix) error->all(FLERR, "Could not find compute msd fix with ID {}", id_fix); if (!fix) error->all(FLERR, "Could not find compute msd fix with ID {}", id_fix);
// nmsd = # of atoms in group // nmsd = # of atoms in group

View File

@ -39,7 +39,7 @@ class ComputeMSD : public Compute {
bigint nmsd; bigint nmsd;
double masstotal; double masstotal;
char *id_fix; char *id_fix;
class FixStorePeratom *fix; class FixStoreAtom *fix;
}; };
} // namespace LAMMPS_NS } // namespace LAMMPS_NS

View File

@ -18,7 +18,7 @@
#include "update.h" #include "update.h"
#include "group.h" #include "group.h"
#include "modify.h" #include "modify.h"
#include "fix_store_peratom.h" #include "fix_store_atom.h"
#include "error.h" #include "error.h"
using namespace LAMMPS_NS; using namespace LAMMPS_NS;
@ -39,8 +39,8 @@ ComputeVACF::ComputeVACF(LAMMPS *lmp, int narg, char **arg) :
// id = compute-ID + COMPUTE_STORE, fix group = compute group // id = compute-ID + COMPUTE_STORE, fix group = compute group
id_fix = utils::strdup(id + std::string("_COMPUTE_STORE")); id_fix = utils::strdup(id + std::string("_COMPUTE_STORE"));
fix = dynamic_cast<FixStorePeratom *>( fix = dynamic_cast<FixStoreAtom *>(
modify->add_fix(fmt::format("{} {} STORE/PERATOM 1 3", id_fix, group->names[igroup]))); modify->add_fix(fmt::format("{} {} STORE/ATOM 3 0 0 1", id_fix, group->names[igroup])));
// store current velocities in fix store array // store current velocities in fix store array
// skip if reset from restart file // skip if reset from restart file
@ -84,7 +84,7 @@ void ComputeVACF::init()
{ {
// set fix which stores original atom velocities // set fix which stores original atom velocities
fix = dynamic_cast<FixStorePeratom *>(modify->get_fix_by_id(id_fix)); fix = dynamic_cast<FixStoreAtom *>(modify->get_fix_by_id(id_fix));
if (!fix) error->all(FLERR,"Could not find compute vacf fix ID {}", id_fix); if (!fix) error->all(FLERR,"Could not find compute vacf fix ID {}", id_fix);
// nvacf = # of atoms in group // nvacf = # of atoms in group

View File

@ -35,7 +35,7 @@ class ComputeVACF : public Compute {
protected: protected:
bigint nvacf; bigint nvacf;
char *id_fix; char *id_fix;
class FixStorePeratom *fix; class FixStoreAtom *fix;
}; };
} // namespace LAMMPS_NS } // namespace LAMMPS_NS

View File

@ -20,7 +20,7 @@
#include "domain.h" #include "domain.h"
#include "error.h" #include "error.h"
#include "fix.h" #include "fix.h"
#include "fix_store_peratom.h" #include "fix_store_atom.h"
#include "group.h" #include "group.h"
#include "input.h" #include "input.h"
#include "memory.h" #include "memory.h"
@ -2005,16 +2005,16 @@ int DumpCustom::modify_param(int narg, char **arg)
thresh_value[nthresh] = utils::numeric(FLERR,arg[3],false,lmp); thresh_value[nthresh] = utils::numeric(FLERR,arg[3],false,lmp);
thresh_last[nthresh] = -1; thresh_last[nthresh] = -1;
} else { } else {
thresh_fix = (FixStorePeratom **) thresh_fix = (FixStoreAtom **)
memory->srealloc(thresh_fix,(nthreshlast+1)*sizeof(FixStorePeratom *),"dump:thresh_fix"); memory->srealloc(thresh_fix,(nthreshlast+1)*sizeof(FixStoreAtom *),"dump:thresh_fix");
thresh_fixID = (char **) thresh_fixID = (char **)
memory->srealloc(thresh_fixID,(nthreshlast+1)*sizeof(char *),"dump:thresh_fixID"); memory->srealloc(thresh_fixID,(nthreshlast+1)*sizeof(char *),"dump:thresh_fixID");
memory->grow(thresh_first,(nthreshlast+1),"dump:thresh_first"); memory->grow(thresh_first,(nthreshlast+1),"dump:thresh_first");
std::string threshid = fmt::format("{}{}_DUMP_STORE",id,nthreshlast); std::string threshid = fmt::format("{}{}_DUMP_STORE",id,nthreshlast);
thresh_fixID[nthreshlast] = utils::strdup(threshid); thresh_fixID[nthreshlast] = utils::strdup(threshid);
threshid += fmt::format(" {} STORE/PERATOM 1 1", group->names[igroup]); threshid += fmt::format(" {} STORE/ATOM 1 0 0 1", group->names[igroup]);
thresh_fix[nthreshlast] = dynamic_cast<FixStorePeratom *>(modify->add_fix(threshid)); thresh_fix[nthreshlast] = dynamic_cast<FixStoreAtom *>(modify->add_fix(threshid));
thresh_last[nthreshlast] = nthreshlast; thresh_last[nthreshlast] = nthreshlast;
thresh_first[nthreshlast] = 1; thresh_first[nthreshlast] = 1;

View File

@ -37,19 +37,19 @@ class DumpCustom : public Dump {
int nevery; // dump frequency for output int nevery; // dump frequency for output
char *idregion; // region ID, nullptr if no region char *idregion; // region ID, nullptr if no region
int nthresh; // # of defined thresholds int nthresh; // # of defined thresholds
int nthreshlast; // # of defined thresholds with value = LAST int nthreshlast; // # of defined thresholds with value = LAST
// //
int *thresh_array; // array to threshold on for each nthresh int *thresh_array; // array to threshold on for each nthresh
int *thresh_op; // threshold operation for each nthresh int *thresh_op; // threshold operation for each nthresh
double *thresh_value; // threshold value for each nthresh double *thresh_value; // threshold value for each nthresh
int *thresh_last; // for threshold value = LAST, int *thresh_last; // for threshold value = LAST,
// index into thresh_fix // index into thresh_fix
// -1 if not LAST, value is numeric // -1 if not LAST, value is numeric
// //
class FixStorePeratom **thresh_fix; // stores values for each threshold LAST class FixStoreAtom **thresh_fix; // stores values for each threshold LAST
char **thresh_fixID; // IDs of thresh_fixes char **thresh_fixID; // IDs of thresh_fixes
int *thresh_first; // 1 the first time a FixStore values accessed int *thresh_first; // 1 the first time a FixStore values accessed
int expand; // flag for whether field args were expanded int expand; // flag for whether field args were expanded
char **earg; // field names with wildcard expansion char **earg; // field names with wildcard expansion

View File

@ -19,7 +19,7 @@
#include "bond.h" #include "bond.h"
#include "domain.h" #include "domain.h"
#include "error.h" #include "error.h"
#include "fix_store_peratom.h" #include "fix_store_atom.h"
#include "force.h" #include "force.h"
#include "group.h" #include "group.h"
#include "input.h" #include "input.h"
@ -278,8 +278,8 @@ void FixAdapt::post_constructor()
if (diamflag && atom->radius_flag) { if (diamflag && atom->radius_flag) {
id_fix_diam = utils::strdup(id + std::string("_FIX_STORE_DIAM")); id_fix_diam = utils::strdup(id + std::string("_FIX_STORE_DIAM"));
fix_diam = dynamic_cast<FixStorePeratom *>( fix_diam = dynamic_cast<FixStoreAtom *>(
modify->add_fix(fmt::format("{} {} STORE/PERATOM 1 1", id_fix_diam,group->names[igroup]))); modify->add_fix(fmt::format("{} {} STORE/ATOM 1 0 0 1", id_fix_diam,group->names[igroup])));
if (fix_diam->restart_reset) fix_diam->restart_reset = 0; if (fix_diam->restart_reset) fix_diam->restart_reset = 0;
else { else {
double *vec = fix_diam->vstore; double *vec = fix_diam->vstore;
@ -296,8 +296,8 @@ void FixAdapt::post_constructor()
if (chgflag && atom->q_flag) { if (chgflag && atom->q_flag) {
id_fix_chg = utils::strdup(id + std::string("_FIX_STORE_CHG")); id_fix_chg = utils::strdup(id + std::string("_FIX_STORE_CHG"));
fix_chg = dynamic_cast<FixStorePeratom *>( fix_chg = dynamic_cast<FixStoreAtom *>(
modify->add_fix(fmt::format("{} {} STORE/PERATOM 1 1",id_fix_chg,group->names[igroup]))); modify->add_fix(fmt::format("{} {} STORE/ATOM 1 0 0 1",id_fix_chg,group->names[igroup])));
if (fix_chg->restart_reset) fix_chg->restart_reset = 0; if (fix_chg->restart_reset) fix_chg->restart_reset = 0;
else { else {
double *vec = fix_chg->vstore; double *vec = fix_chg->vstore;
@ -494,11 +494,11 @@ void FixAdapt::init()
// fixes that store initial per-atom values // fixes that store initial per-atom values
if (id_fix_diam) { if (id_fix_diam) {
fix_diam = dynamic_cast<FixStorePeratom *>(modify->get_fix_by_id(id_fix_diam)); fix_diam = dynamic_cast<FixStoreAtom *>(modify->get_fix_by_id(id_fix_diam));
if (!fix_diam) error->all(FLERR,"Could not find fix adapt storage fix ID {}", id_fix_diam); if (!fix_diam) error->all(FLERR,"Could not find fix adapt storage fix ID {}", id_fix_diam);
} }
if (id_fix_chg) { if (id_fix_chg) {
fix_chg = dynamic_cast<FixStorePeratom *>(modify->get_fix_by_id(id_fix_chg)); fix_chg = dynamic_cast<FixStoreAtom *>(modify->get_fix_by_id(id_fix_chg));
if (!fix_chg) error->all(FLERR,"Could not find fix adapt storage fix ID {}", id_fix_chg); if (!fix_chg) error->all(FLERR,"Could not find fix adapt storage fix ID {}", id_fix_chg);
} }

View File

@ -48,7 +48,7 @@ class FixAdapt : public Fix {
int anypair, anybond, anyangle; int anypair, anybond, anyangle;
int nlevels_respa; int nlevels_respa;
char *id_fix_diam, *id_fix_chg; char *id_fix_diam, *id_fix_chg;
class FixStorePeratom *fix_diam, *fix_chg; class FixStoreAtom *fix_diam, *fix_chg;
double previous_diam_scale, previous_chg_scale; double previous_diam_scale, previous_chg_scale;
int discflag; int discflag;

View File

@ -19,7 +19,7 @@
#include "comm.h" #include "comm.h"
#include "domain.h" #include "domain.h"
#include "error.h" #include "error.h"
#include "fix_store_peratom.h" #include "fix_store_atom.h"
#include "force.h" #include "force.h"
#include "irregular.h" #include "irregular.h"
#include "kspace.h" #include "kspace.h"

View File

@ -11,7 +11,7 @@
See the README file in the top-level LAMMPS directory. See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */ ------------------------------------------------------------------------- */
#include "fix_store_peratom.h" #include "fix_store_atom.h"
#include "atom.h" #include "atom.h"
#include "error.h" #include "error.h"
@ -22,50 +22,59 @@
using namespace LAMMPS_NS; using namespace LAMMPS_NS;
using namespace FixConst; using namespace FixConst;
// INTERNAL fix for storing/communicating per-atom values
// syntax: id group style n1 n2 gflag rflag
// N1 = 1, N2 = 0 is per-atom vector, single value per atom
// N1 > 1, N2 = 0 is per-atom array, N1 values per atom
// N1 > 0, N2 > 0 is per-atom tensor, N1xN2 array per atom
// gflag = 0/1, no/yes communicate per-atom values with ghost atoms
// rflag = 0/1, no/yes store per-atom values in restart file
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
FixStorePeratom::FixStorePeratom(LAMMPS *lmp, int narg, char **arg) : FixStoreAtom::FixStoreAtom(LAMMPS *lmp, int narg, char **arg) :
Fix(lmp, narg, arg), vstore(nullptr), astore(nullptr) Fix(lmp, narg, arg), vstore(nullptr), astore(nullptr)
{ {
if (narg != 5 && narg != 6) if (narg != 7) error->all(FLERR, "Illegal fix STORE/ATOM command: number of args");
error->all(FLERR, "Illegal fix STORE/PERATOM command: number of args");
// syntax: id group style 0/1 n1 n2 (n3), last arg optional
// 0/1 flag = not-store or store peratom values in restart file
// N2 = 1 and no n3 is vector, N2 > 1 and no n3 is array, N3 = tensor
// nvalues = # of peratom values, N = 1 is vector, N > 1 is array
disable = 0; disable = 0;
vecflag = arrayflag = tensorflag = 0;
restart_peratom = utils::inumeric(FLERR, arg[3], false, lmp); n1 = utils::inumeric(FLERR, arg[3], false, lmp);
n2 = utils::inumeric(FLERR, arg[4], false, lmp); n2 = utils::inumeric(FLERR, arg[4], false, lmp);
if (narg == 6) ghostflag = utils::logical(FLERR, arg[5], false, lmp);
n3 = utils::inumeric(FLERR, arg[5], false, lmp); restartflag = utils::logical(FLERR, arg[6], false, lmp);
else
n3 = 1; vecflag = arrayflag = tensorflag = 0;
if (restart_peratom < 0 || restart_peratom > 1) if (n1 == 1 && n2 == 0)
error->all(FLERR, "Illegal fix STORE/PERATOM restart flag: {}", restart_peratom);
if (n2 <= 0 || n3 <= 0)
error->all(FLERR, "Illegal fix STORE/PERATOM dimension args: must be >0: {} {}", n2, n3);
if (n2 == 1 && narg == 5)
vecflag = 1; vecflag = 1;
else if (narg == 5) else if (n1 > 1 && n2 == 0)
arrayflag = 1; arrayflag = 1;
else else if (n1 > 0 && n2 > 0)
tensorflag = 1; tensorflag = 1;
nvalues = n2 * n3; else
error->all(FLERR, "Illegal fix STORE/ATOM dimension args: {} {}", n1, n2);
if (vecflag || arrayflag)
nvalues = n1;
else
nvalues = n1 * n2;
nbytes = nvalues * sizeof(double); nbytes = nvalues * sizeof(double);
if (ghostflag) comm_border = nvalues;
maxexchange = nvalues;
if (restartflag) restart_peratom = 1;
// allocate data structs and register with Atom class
vstore = nullptr; vstore = nullptr;
astore = nullptr; astore = nullptr;
tstore = nullptr; tstore = nullptr;
// allocate data structs and register with Atom class FixStoreAtom::grow_arrays(atom->nmax);
FixStorePeratom::grow_arrays(atom->nmax);
atom->add_callback(Atom::GROW); atom->add_callback(Atom::GROW);
if (restart_peratom) atom->add_callback(Atom::RESTART); if (restartflag) atom->add_callback(Atom::RESTART);
if (ghostflag) atom->add_callback(Atom::BORDER);
// zero the storage // zero the storage
@ -74,23 +83,23 @@ FixStorePeratom::FixStorePeratom(LAMMPS *lmp, int narg, char **arg) :
for (int i = 0; i < nlocal; i++) vstore[i] = 0.0; for (int i = 0; i < nlocal; i++) vstore[i] = 0.0;
} else if (arrayflag) { } else if (arrayflag) {
for (int i = 0; i < nlocal; i++) for (int i = 0; i < nlocal; i++)
for (int j = 0; j < n2; j++) astore[i][j] = 0.0; for (int j = 0; j < n1; j++) astore[i][j] = 0.0;
} else if (tensorflag) { } else if (tensorflag) {
for (int i = 0; i < nlocal; i++) for (int i = 0; i < nlocal; i++)
for (int j = 0; j < n2; j++) for (int j = 0; j < n1; j++)
for (int k = 0; k < n3; k++) tstore[i][j][k] = 0.0; for (int k = 0; k < n2; k++) tstore[i][j][k] = 0.0;
} }
maxexchange = nvalues;
} }
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
FixStorePeratom::~FixStorePeratom() FixStoreAtom::~FixStoreAtom()
{ {
// unregister callbacks to this fix from Atom class // unregister callbacks to this fix from Atom class
atom->delete_callback(id, Atom::GROW); atom->delete_callback(id, Atom::GROW);
if (restart_peratom) atom->delete_callback(id, Atom::RESTART); if (restartflag) atom->delete_callback(id, Atom::RESTART);
if (ghostflag) atom->delete_callback(id, Atom::BORDER);
memory->destroy(vstore); memory->destroy(vstore);
memory->destroy(astore); memory->destroy(astore);
@ -99,7 +108,7 @@ FixStorePeratom::~FixStorePeratom()
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
int FixStorePeratom::setmask() int FixStoreAtom::setmask()
{ {
int mask = 0; int mask = 0;
return mask; return mask;
@ -109,21 +118,21 @@ int FixStorePeratom::setmask()
allocate atom-based array allocate atom-based array
------------------------------------------------------------------------- */ ------------------------------------------------------------------------- */
void FixStorePeratom::grow_arrays(int nmax) void FixStoreAtom::grow_arrays(int nmax)
{ {
if (vecflag) if (vecflag)
memory->grow(vstore, nmax, "store:vstore"); memory->grow(vstore, nmax, "store:vstore");
else if (arrayflag) else if (arrayflag)
memory->grow(astore, nmax, n2, "store:astore"); memory->grow(astore, nmax, n1, "store:astore");
else if (tensorflag) else if (tensorflag)
memory->grow(tstore, nmax, n2, n3, "store:tstore"); memory->grow(tstore, nmax, n1, n2, "store:tstore");
} }
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------
copy values within local atom-based array copy values within local atom-based array
------------------------------------------------------------------------- */ ------------------------------------------------------------------------- */
void FixStorePeratom::copy_arrays(int i, int j, int /*delflag*/) void FixStoreAtom::copy_arrays(int i, int j, int /*delflag*/)
{ {
if (disable) return; if (disable) return;
@ -136,11 +145,65 @@ void FixStorePeratom::copy_arrays(int i, int j, int /*delflag*/)
} }
} }
/* ----------------------------------------------------------------------
pack values for border communication at re-neighboring
------------------------------------------------------------------------- */
int FixStoreAtom::pack_border(int n, int *list, double *buf)
{
int i, j, k;
int m = 0;
if (vecflag) {
for (i = 0; i < n; i++) {
j = list[i];
buf[m++] = vstore[j];
}
} else if (arrayflag) {
for (i = 0; i < n; i++) {
j = list[i];
for (k = 0; k < nvalues; k++) buf[m++] = astore[j][k];
}
} else if (tensorflag) {
for (i = 0; i < n; i++) {
j = list[i];
memcpy(&buf[m], &tstore[j][0][0], nbytes);
m += nvalues;
}
}
return m;
}
/* ----------------------------------------------------------------------
unpack values for border communication at re-neighboring
------------------------------------------------------------------------- */
int FixStoreAtom::unpack_border(int n, int first, double *buf)
{
int i, k, last;
int m = 0;
last = first + n;
if (vecflag) {
for (i = first; i < last; i++) vstore[i] = buf[m++];
} else if (arrayflag) {
for (i = first; i < last; i++)
for (k = 0; k < nvalues; k++) astore[i][k] = buf[m++];
} else if (tensorflag) {
for (i = first; i < last; i++) {
memcpy(&tstore[i][0][0], &buf[m], nbytes);
m += nvalues;
}
}
return m;
}
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------
pack values in local atom-based array for exchange with another proc pack values in local atom-based array for exchange with another proc
------------------------------------------------------------------------- */ ------------------------------------------------------------------------- */
int FixStorePeratom::pack_exchange(int i, double *buf) int FixStoreAtom::pack_exchange(int i, double *buf)
{ {
if (disable) return 0; if (disable) return 0;
@ -159,7 +222,7 @@ int FixStorePeratom::pack_exchange(int i, double *buf)
unpack values in local atom-based array from exchange with another proc unpack values in local atom-based array from exchange with another proc
------------------------------------------------------------------------- */ ------------------------------------------------------------------------- */
int FixStorePeratom::unpack_exchange(int nlocal, double *buf) int FixStoreAtom::unpack_exchange(int nlocal, double *buf)
{ {
if (disable) return 0; if (disable) return 0;
@ -178,7 +241,7 @@ int FixStorePeratom::unpack_exchange(int nlocal, double *buf)
pack values in local atom-based arrays for restart file pack values in local atom-based arrays for restart file
------------------------------------------------------------------------- */ ------------------------------------------------------------------------- */
int FixStorePeratom::pack_restart(int i, double *buf) int FixStoreAtom::pack_restart(int i, double *buf)
{ {
if (disable) { if (disable) {
buf[0] = 0; buf[0] = 0;
@ -203,7 +266,7 @@ int FixStorePeratom::pack_restart(int i, double *buf)
unpack values from atom->extra array to restart the fix unpack values from atom->extra array to restart the fix
------------------------------------------------------------------------- */ ------------------------------------------------------------------------- */
void FixStorePeratom::unpack_restart(int nlocal, int nth) void FixStoreAtom::unpack_restart(int nlocal, int nth)
{ {
if (disable) return; if (disable) return;
@ -229,7 +292,7 @@ void FixStorePeratom::unpack_restart(int nlocal, int nth)
maxsize of any atom's restart data maxsize of any atom's restart data
------------------------------------------------------------------------- */ ------------------------------------------------------------------------- */
int FixStorePeratom::maxsize_restart() int FixStoreAtom::maxsize_restart()
{ {
if (disable) return 1; if (disable) return 1;
return nvalues + 1; return nvalues + 1;
@ -239,17 +302,17 @@ int FixStorePeratom::maxsize_restart()
size of atom nlocal's restart data size of atom nlocal's restart data
------------------------------------------------------------------------- */ ------------------------------------------------------------------------- */
int FixStorePeratom::size_restart(int /*nlocal*/) int FixStoreAtom::size_restart(int /*nlocal*/)
{ {
if (disable) return 1; if (disable) return 1;
return nvalues + 1; return nvalues + 1;
} }
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------
memory usage of global or peratom atom-based array memory usage of per-atom atom-based array
------------------------------------------------------------------------- */ ------------------------------------------------------------------------- */
double FixStorePeratom::memory_usage() double FixStoreAtom::memory_usage()
{ {
return (double) atom->nmax * n2 * n3 * sizeof(double); return (double) atom->nmax * nvalues * sizeof(double);
} }

View File

@ -13,30 +13,32 @@
#ifdef FIX_CLASS #ifdef FIX_CLASS
// clang-format off // clang-format off
FixStyle(STORE/PERATOM,FixStorePeratom); FixStyle(STORE/ATOM,FixStoreAtom);
// clang-format on // clang-format on
#else #else
#ifndef LMP_FIX_STORE_PERATOM_H #ifndef LMP_FIX_STORE_ATOM_H
#define LMP_FIX_STORE_PERATOM_H #define LMP_FIX_STORE_ATOM_H
#include "fix.h" #include "fix.h"
namespace LAMMPS_NS { namespace LAMMPS_NS {
class FixStorePeratom : public Fix { class FixStoreAtom : public Fix {
public: public:
double *vstore; // vector storage double *vstore; // vector storage
double **astore; // array storage double **astore; // array storage
double ***tstore; // tensor (3d array) storage double ***tstore; // tensor (3d array) storage
int disable; // 1 if operations (except grow) are currently disabled int disable; // 1 if operations (except grow) are currently disabled
FixStorePeratom(class LAMMPS *, int, char **); FixStoreAtom(class LAMMPS *, int, char **);
~FixStorePeratom() override; ~FixStoreAtom() override;
int setmask() override; int setmask() override;
void grow_arrays(int) override; void grow_arrays(int) override;
void copy_arrays(int, int, int) override; void copy_arrays(int, int, int) override;
int pack_border(int, int *, double *) override;
int unpack_border(int, int, double *) override;
int pack_exchange(int, double *) override; int pack_exchange(int, double *) override;
int unpack_exchange(int, double *) override; int unpack_exchange(int, double *) override;
int pack_restart(int, double *) override; int pack_restart(int, double *) override;
@ -50,8 +52,10 @@ class FixStorePeratom : public Fix {
int vecflag; // 1 if ncol=1 int vecflag; // 1 if ncol=1
int arrayflag; // 1 if a 2d array (vector per atom) int arrayflag; // 1 if a 2d array (vector per atom)
int tensorflag; // 1 if a 3d array (array per atom) int tensorflag; // 1 if a 3d array (array per atom)
int ghostflag; // 0/1 to communicate values with ghost atoms
int restartflag; // 0/1 to store values in restart files
int n2, n3; // size of 3d dims of per-atom data struct int n1, n2; // size of 3d dims of per-atom data struct
int nvalues; // number of per-atom values int nvalues; // number of per-atom values
int nbytes; // number of per-atom bytes int nbytes; // number of per-atom bytes
}; };

View File

@ -182,7 +182,7 @@ void FixStoreGlobal::restart(char *buf)
} }
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------
memory usage of global or peratom atom-based array memory usage of global data
------------------------------------------------------------------------- */ ------------------------------------------------------------------------- */
double FixStoreGlobal::memory_usage() double FixStoreGlobal::memory_usage()

View File

@ -20,7 +20,7 @@
#include "domain.h" #include "domain.h"
#include "error.h" #include "error.h"
#include "fix.h" #include "fix.h"
#include "fix_store_peratom.h" #include "fix_store_atom.h"
#include "group.h" #include "group.h"
#include "info.h" #include "info.h"
#include "input.h" #include "input.h"
@ -5027,8 +5027,8 @@ VarReader::VarReader(LAMMPS *lmp, char *name, char *file, int flag) :
error->all(FLERR,"Cannot use atomfile-style variable unless an atom map exists"); error->all(FLERR,"Cannot use atomfile-style variable unless an atom map exists");
id_fix = utils::strdup(std::string(name) + "_VARIABLE_STORE"); id_fix = utils::strdup(std::string(name) + "_VARIABLE_STORE");
fixstore = dynamic_cast<FixStorePeratom *>( fixstore = dynamic_cast<FixStoreAtom *>(
modify->add_fix(std::string(id_fix) + " all STORE/PERATOM 0 1")); modify->add_fix(std::string(id_fix) + " all STORE/ATOM 1 0 0 0"));
buffer = new char[CHUNK*MAXLINE]; buffer = new char[CHUNK*MAXLINE];
} }
} }

View File

@ -152,7 +152,7 @@ class Variable : protected Pointers {
class VarReader : protected Pointers { class VarReader : protected Pointers {
public: public:
class FixStorePeratom *fixstore; class FixStoreAtom *fixstore;
char *id_fix; char *id_fix;
VarReader(class LAMMPS *, char *, char *, int); VarReader(class LAMMPS *, char *, char *, int);

View File

@ -691,8 +691,8 @@ TEST(AngleStyle, extract)
} }
auto angle = lmp->force->angle; auto angle = lmp->force->angle;
void *ptr = nullptr; void *ptr = nullptr;
int dim = 0; int dim = 0;
for (auto extract : test_config.extract) { for (auto extract : test_config.extract) {
ptr = angle->extract(extract.first.c_str(), dim); ptr = angle->extract(extract.first.c_str(), dim);
EXPECT_NE(ptr, nullptr); EXPECT_NE(ptr, nullptr);

View File

@ -123,7 +123,7 @@ LAMMPS *init_lammps(int argc, char **argv, const TestConfig &cfg, const bool new
command("run 0 post no"); command("run 0 post no");
command("write_restart " + cfg.basename + ".restart"); command("write_restart " + cfg.basename + ".restart");
command("write_data " + cfg.basename + ".data"); command("write_data " + cfg.basename + ".data nofix");
command("write_coeff " + cfg.basename + "-coeffs.in"); command("write_coeff " + cfg.basename + "-coeffs.in");
return lmp; return lmp;

View File

@ -0,0 +1,89 @@
---
lammps_version: 8 Feb 2023
date_generated: Tue Mar 7 21:07:27 2023
epsilon: 2.5e-13
skip_tests: extract
prerequisites: ! |
atom full
bond harmonic/restrain
pre_commands: ! ""
post_commands: ! ""
input_file: in.fourmol
bond_style: harmonic/restrain
bond_coeff: ! |
1 250.0
2 300.0
3 350.0
4 650.0
5 450.0
equilibrium: 5 -1 -1 -1 -1 -1
extract: ! |
k 1
natoms: 29
init_energy: 0
init_stress: ! |2-
0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00
init_forces: ! |2
1 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00
2 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00
3 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00
4 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00
5 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00
6 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00
7 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00
8 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00
9 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00
10 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00
11 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00
12 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00
13 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00
14 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00
15 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00
16 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00
17 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00
18 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00
19 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00
20 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00
21 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00
22 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00
23 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00
24 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00
25 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00
26 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00
27 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00
28 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00
29 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00
run_energy: 0.009384424442608962
run_stress: ! |2-
1.3334287184173488e+00 3.1110677999939773e-01 -1.4064657849540130e+00 2.6546279385354110e-01 1.5492956756466219e+00 7.2358876924785698e-01
run_forces: ! |2
1 1.1485941046856593e-01 1.4088049450172524e-01 -8.5852076971833030e-02
2 -9.3217481807658653e-02 -7.6867386712704044e-02 1.0932532178570745e-01
3 -2.3741413942894266e-01 -8.5667734110971339e-02 -8.2143831089792743e-02
4 2.3324188168788909e-01 -6.5094431822773302e-02 1.6591701889629748e-01
5 2.6793200848186677e-02 4.1227376782380774e-02 -1.3685685314886964e-01
6 2.4862628338772436e-01 -3.6125357500552457e-01 -7.8230634578348013e-01
7 -3.8706943762359766e-02 1.9888379369193138e-01 9.8933719851963053e-01
8 -3.5267248957722913e-01 4.2911503092501313e-01 1.0190469073820968e-01
9 -5.1632048293607458e-02 -5.5343430872859360e-02 -2.2821606693951479e-01
10 1.2860877826855494e-01 -7.5971599169706849e-01 -5.5343112593256227e-01
11 1.6956002318038377e-01 4.2001247662003161e-01 6.8896503378985918e-01
12 3.4231534762621078e-02 -2.4857235824638585e-01 -6.3964642589377518e-01
13 -2.7815178906130594e-01 1.0946454990993748e-01 5.1669158882660616e-03
14 2.2738751895410908e-01 -4.5437525741145839e-02 5.8956676893113813e-01
15 -4.6207378210972273e-03 1.6438094307388113e-01 5.8917445017986604e-02
16 -1.1399994473799732e-02 1.1329499720204761e-01 -5.0720152745025260e-01
17 -1.1549300733203431e-01 8.0692771502484495e-02 3.0655385964298520e-01
18 1.9145703373728828e+00 1.8373130373081787e+00 -3.9519344330792983e-01
19 -4.7317441908503255e-01 -3.0353033418925196e-01 -5.7175303978447201e-01
20 -1.4413959182878502e+00 -1.5337827031189268e+00 9.6694648309240183e-01
21 -3.3244533656237202e-01 -3.0309080808086836e-01 6.5775553694406208e-01
22 -2.9549353211149859e-01 -7.2150425050573716e-02 -4.6194669575592789e-01
23 6.2793886867387061e-01 3.7524123313144209e-01 -1.9580884118813421e-01
24 8.2698432709098157e-01 -1.4448474780063469e+00 1.2133188519739595e+00
25 -1.5417378702379472e+00 2.4470962384652978e-01 -1.2964818258023694e+00
26 7.1475354314696560e-01 1.2001378541598171e+00 8.3162973828409884e-02
27 2.1885007758012770e-01 -5.7423924185981945e-01 2.7745249319135684e-01
28 -5.2036258696458004e-01 2.2330647386191435e-01 -3.5136945845348061e-01
29 3.0151250938445234e-01 3.5093276799790507e-01 7.3916965262123782e-02
...