global/local hyperdynamics src and doc files

This commit is contained in:
Steve Plimpton
2018-10-10 13:39:44 -06:00
parent 1651a21f92
commit fbd610b8a9
13 changed files with 3701 additions and 0 deletions

146
doc/fix_hyper_global.txt Normal file
View File

@ -0,0 +1,146 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
fix hyper/global command :h3
[Syntax:]
fix ID group-ID hyper/global cutbond qfactor Vmax Tequil :pre
ID, group-ID are documented in "fix"_fix.html command
hyper/global = style name of this fix command
cutbond = max distance at which a pair of atoms is considered bonded (distance units)
qfactor = max strain at which bias potential goes to 0.0 (unitless)
Vmax = height of bias potential (energy units)
Tequil = equilibration temperature (temperature units) :ul
[Examples:]
fix 1 all hyper/global 1.0 0.3 0.8 300.0 :pre
[Description:]
This fix is meant to be used with the "hyper"_hyper.html command to
perform a bond-boost hyperdynamics simulation. The role of this fix
is a select a single pair of atoms within the system at each timestep
to add a global bias potential to, which will alter their dynamics.
This is in contrast to the "fix hyper/local"_fix_hyper_local.html
command, which can add a local bias potential to multiple pairs of
atoms at each timestep.
For a system that undergoes rare transition events, where one or more
atoms move across an energy barrier to a new potential energy basin,
the effect of the bias potential is to induce more rapid transitions.
This can lead to a dramatic speed-up in the rate at which events
occurs, without altering their relative frequencies, thus leading to
an overall dramatic speed-up in the effective elapsed time of the
simulation.
Cite various papers.
The current strain of a bond IJ is defined as
Eij = (Rij - R0ij) / R0ij :pre
Emax = is the max of the absolute value of Eij for all IJ bonds.
dVij = Vmax * (1 - (Eij/q)^2) for abs(Eij) < q
= 0 otherwise :pre
Delta Vbias = minimum of dVij for all IJ bonds :pre
The boost factor B = exp(beta * Delta Vbias)
for a single timestep.
Thus the accumulated hypertime is simply
t_hyper = Sum (i = 1 to Nsteps) Bi * dt :pre
The {cutbond} argument is the cutoff distance for defining bonds
between pairs of nearby atoms. A pair of atoms in their equilibrium,
minimum-energy config, which are a distance Rij < cutbond, are
defined as a bonded pair.
The {qfactor} argument is the limiting strain at which
the Vbias (the bias potential) goes to 0.0.
If {qfactor} is too big, then transitions are affected b/c
the bias energy is non-zero at the transitions. If it is
too small than not must boost is achieved for a large system
with many bonds (some bonds Eij always exceeds qfactor).
The {Vmax} argument is the prefactor on the bias potential.
The {Tequil} argument is part of the beta term in the
exponential factor that determines how much boost is
achieved as a function of the bias potential.
[Restart, fix_modify, output, run start/stop, minimize info:]
No information about this fix is written to "binary restart
files"_restart.html.
The "fix_modify"_fix_modify.html {energy} option is supported by this
fix to add the energy of the bias potential to the the system's
potential energy as part of "thermodynamic output"_thermo_style.html.
This fix computes a global scalar and global vector of length 10,
which can be accessed by various "output
commands"_Section_howto.html#howto_15. The scalar is the magnitude of
the bias potential (energy units) applied on the current timestep.
The vector stores the following quantities:
1 = boost factor on this step (unitless)
2 = max strain of any bond on this step (unitless)
3 = ID of first atom in the max-strain bond
4 = ID of second atom in the max-strain bond
5 = average # of bonds/atom on this step :ul
6 = fraction of step with no bias during this run
7 = max drift distance of any atom during this run (distance units)
8 = max bond length during this run (distance units) :ul
9 = cummulative hyper time since fix created (time units)
10 = cummulative count of event timesteps since fix created
11 = cummulative count of atoms in events since fix created :ul
The first 5 quantities are for the current timestep. The quantities
6-8 are for the current run. The quantities 9-11 are cummulative
across multiple runs (since the fix was defined in the input script).
For value 10, events are checked for by the "hyper"_hyper.html command
once every {Nevent} timesteps. This value is the count of the number
of timesteps on which one (or more) events was detected. It is NOT
the number of distinct events, since more than one physical event may
occur in the same {Nevent} time window.
For value 11, each time the "hyper"_hyper.html command checks for an
event, the event compute it uses will flag zero or more atoms as
participating in an event. E.g. atoms that have displaced more than
some distance from the previous quench state. This value is the count
of the number of atoms participating in any of the events that were
found.
The scalar and vector values calculated by this fix are all
"intensive".
No parameter of this fix can be used with the {start/stop} keywords of
the "run"_run.html command. This fix is not invoked during "energy
minimization"_minimize.html.
[Restrictions:]
This fix is part of the REPLICA package. It is only enabled if LAMMPS
was built with that package. See the "Making
LAMMPS"_Section_start.html#start_3 section for more info.
[Related commands:]
"fix hyper/local"_fix_hyper_local.html
[Default:] None

200
doc/fix_hyper_local.txt Normal file
View File

@ -0,0 +1,200 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
fix hyper/local command :h3
[Syntax:]
fix ID group-ID hyper/local cutbond qfactor Vmax Tequil Dcut alpha boost :pre
ID, group-ID are documented in "fix"_fix.html command :ulb,l
hyper/local = style name of this fix command :l
cutbond = max distance at which a pair of atoms is considered bonded (distance units) :l
qfactor = max strain at which bias potential goes to 0.0 (unitless) :l
Vmax = estimated height of bias potential (energy units) :l
Tequil = equilibration temperature (temperature units) :l
Dcut = min distance between boosted bonds (distance units) :l
alpha = boostostat relaxation time (time units) :l
boost = desired time boost factor (unitless) :l
zero or more keyword/value pairs may be appended :l
keyword = {histo} or {lost} or {check/bias} or {check/coeff}
{histo} values = Nevery Nbin delta Nout
Nevery = histogram bond bias coefficients every this many timesteps
Nbin = # of histogram bins
delta = width of each histogram bin
Nout = output histogram counts every this many timesteps
{lostbond} value = error/warn/ignore
{check/bias} values = Nevery error/warn/ignore
{check/coeff} values = Nevery error/warn/ignore :pre
:ule
[Examples:]
fix 1 all hyper/local 1.0 0.3 0.8 300.0 :pre
[Description:]
This fix is meant to be used with the "hyper"_hyper.html command to
perform a bond-boost hyperdynamics simulation. The role of this fix
is a select a multiple pairs of atoms within the system at each
timestep to add a local bias potential to, which will alter their
dynamics. This is in contrast to the "fix
hyper/global"_fix_hyper_global.html command, which adds a global bias
potential to a single pair of atoms at each timestep.
For a system that undergoes rare transition events, where one or more
atoms move across an energy barrier to a new potential energy basin,
the effect of the bias potential is to induce more rapid transitions.
This can lead to a dramatic speed-up in the rate at which events
occurs, without altering their relative frequencies, thus leading to
an overall dramatic speed-up in the effective wall-clock time of the
simulation.
Cite various papers.
The current strain of a bond IJ is defined as
Eij = (Rij - R0ij) / R0ij
Emax = is the max of the absolute value of Eij for all IJ bonds.
dVij = Vmax * (1 - (Eij/q)^2) for abs(Eij) < q
= 0 otherwise
Delta Vbias = minimum of dVij for all IJ bonds
The boost factor B = exp(beta * Delta Vbias)
for a single timestep.
Thus the accumulated hypertime is simply
t_hyper = Sum (i = 1 to Nsteps) Bi * dt
NOTE: Add eqs for boostostat and boost coeff.
Explain how many bonds are boosted simultaneously
and how to choose boost factor and initial Vmax.
The {cutbond} argument is the cutoff distance for defining bonds
between pairs of nearby atoms. A pair of atoms in their equilibrium,
minimum-energy config, which are a distance Rij < cutbond, are
defined as a bonded pair.
The {qfactor} argument is the limiting strain at which
the Vbias (the bias potential) goes to 0.0.
If qfactor is too big, then transitions are affected b/c
the bias energy is non-zero at the transitions. If it is
too small than not must boost is achieved for a large system
with many bonds (some bonds Eij always exceeds qfactor).
The {Vmax} argument is the initial prefactor on the bias potential.
Should be chosen as estimate of final. Will be adjusted by
boost cooeficient
The {Tequil} argument is part of the beta term in the
exponential factor that determines how much boost is
achieved as a function of the bias potential.
The {Dcut} argument is the distance required between two bonds for
them to be selected as both being boosted. The distance is between
the center points of each bond. Actually between any pair of atoms in
either bond.
The {alpha} argument is a pre-factor on the update equation
for each atom's boostostat:
NOTE: give equation above
Note that the units for {alpha} are in time units, similar
to other thermostat or barostat damping parameters
The {boost} argument is the desired boost factor (e.g. 100x)
that all the atoms in the system will experience.
NOTE: explain how to choose good value for this. If this parameter is
chosen to be too large, then the bias potential applied to pairs of
bonded atoms may become unphysically large, leading to bad dynamics.
If chosen too small, the hyperdynamics run may be inefficient in the
sense that events take a long time to occur.
[Restart, fix_modify, output, run start/stop, minimize info:]
No information about this fix is written to "binary restart
files"_restart.html.
The "fix_modify"_fix_modify.html {energy} option is supported by this
fix to add the energy of the bias potential to the the system's
potential energy as part of "thermodynamic output"_thermo_style.html.
This fix computes a global scalar and global vector of length 23,
which can be accessed by various "output
commands"_Section_howto.html#howto_15. The scalar is the magnitude of
the bias potential (energy units) applied on the current timestep,
summed over all biased bonds. The vector stores the following
quantities:
1 = # of boosted bonds on this step
2 = max strain of any bond on this step (unitless)
3 = average bias potential for all bonds on this step (energy units)
4 = average bonds/atom on this step
5 = average neighbor bonds/bond on this step :ul
6 = fraction of steps and bonds with no bias during this run
7 = max drift distance of any atom during this run (distance units)
8 = max bond length during this run (distance units)
9 = average # of boosted bonds/step during this run
10 = average bias potential for all bonds during this run (energy units)
11 = max bias potential for any bond during this run (energy units)
12 = min bias potential for any bond during this run (energy units)
13 = max distance from my box of any ghost atom with maxstrain < qfactor during th
is run (distance units)
14 = max distance outside my box of any ghost atom with any maxstrain during this run (distance units)
15 = count of ghost neighbor atoms not found on reneighbor steps during this run
16 = count of lost bond partners during this run
17 = average bias coeff for lost bond partners during this run
18 = count of bias overlaps found during this run
19 = count of non-matching bias coefficients found during this run :ul
20 = cummulative hyper time since fix created (time units)
21 = cummulative count of event timesteps since fix created
22 = cummulative count of atoms in events since fix created
23 = cummulative # of new bonds since fix created :ul
The first quantities (1-5) are for the current timestep. The
quantities 6-19 are for the current hyper run. They are reset each
time a new hyper run is performed. The quantities 20-23 are
cummulative across multiple hyper runs, They are only set to initial
values once, when this fix is defined in the input script.
For value 6, the numerator is a count of all biased bonds on every
timestep whose bias value = 0.0. The denominator is the count of all
biased bonds on all timesteps.
For values 13 and 14, the maxstrain of a ghost atom is the maxstrain
of any bond it is part of, and it is checked for ghost atoms within
the bond neighbor cutoff.
The scalar and vector values calculated by this fix are all
"intensive".
No parameter of this fix can be used with the {start/stop} keywords of
the "run"_run.html command. This fix is not invoked during "energy
minimization"_minimize.html.
[Restrictions:]
This fix is part of the REPLICA package. It is only enabled if LAMMPS
was built with that package. See the "Making
LAMMPS"_Section_start.html#start_3 section for more info.
[Related commands:]
"hyper"_hyper.html, "fix hyper/global"_fix_hyper_global.html
[Default:] None

117
doc/hyper.txt Normal file
View File

@ -0,0 +1,117 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
hyper command :h3
[Syntax:]
hyper N Nevent fixID computeID keyword values ... :pre
N = # of timesteps to run :ulb,l
Nevent = check for events every this many steps :l
fixID = ID of a fix that applies a global or local bias potential :l
computeID = ID of a compute that identifies when an event has occurred :l
zero or more keyword/value pairs may be appended :l
keyword = {min} or {time} :l
{min} values = etol ftol maxiter maxeval
etol = stopping tolerance for energy, used in quenching
ftol = stopping tolerance for force, used in quenching
maxiter = max iterations of minimize, used in quenching
maxeval = max number of force/energy evaluations, used in quenching
{time} value = {steps} or {clock}
{steps} = simulation runs for N timesteps (default)
{clock} = simulation runs until hyper time exceeds N timesteps :pre
:ule
[Examples:]
hyper 5000 100 global event :pre
[Description:]
Run a bond-boost hyperdynamics (HD) simulation where time is
accelerated by application of a bias potential to a one or more pairs
of atoms in the system. This command can be used to run both global
and local hyperdyamics. In global HD a single bond (nearby pair of
atoms) within the system is biased on a given timestep. In local HD
multiple bonds (separated by a sufficient distance) can be biased
simultaneously at each timestep.
Make next paragraph more HD-specific.
Both global and local HD are described in "this paper"_#Voter2013 by
Art Voter and collaborators. They are methods for performing
accelerated dynamics that is suitable for infrequent-event systems
that obey first-order kinetics. A good overview of accelerated
dynamics methods for such systems in given in "this review
paper"_#Voter2002prd from the same group. To quote from the paper:
"The dynamical evolution is characterized by vibrational excursions
within a potential basin, punctuated by occasional transitions between
basins." The transition probability is characterized by p(t) =
k*exp(-kt) where k is the rate constant. Running multiple replicas
gives an effective enhancement in the timescale spanned by the
multiple simulations, while waiting for an event to occur.
How different than PRD.
An HD run has several stages, which are repeated each time an "event"
occurs, as defined below. The logic for a HD run is as follows:
quench
reset list of bonds :pre
while (time remains):
run dynamics for Nevery steps
quench
check for an event
if event occurred: reset list of bonds
restore pre-quench state :pre
Explain each of the steps above. Explain what list of bonds is and
how event is detected.
Explain the specified fix and compute.
Statistics about the number of events, the number of bonds that a bias
potential is applied to, the accumulated hyper time, etc are stored by
the fix and can be output with thermodynamic output.
:line
[Restrictions:]
This command can only be used if LAMMPS was built with the REPLICA
package. See the "Making LAMMPS"_Section_start.html#start_3 section
for more info on packages.
NOTE: is this true?
This command cannot be used when any fixes are defined that keep track
of elapsed time to perform time-dependent operations. Examples
include the "ave" fixes such as "fix ave/chunk"_fix_ave_chunk.html.
Also "fix dt/reset"_fix_dt_reset.html and "fix
deposit"_fix_deposit.html.
[Related commands:]
"fix hyper/global"_fix_hyper_global.html, "fix
hyper/local"_fix_hyper_local.html, "compute
event/displace"_compute_event_displace.html
[Default:]
The option defaults are min = 0.1 0.1 40 50 and time = steps.
:line
:link(Voter2013)
[(Voter2013)] S. Y. Kim, D. Perez, A. F. Voter, J Chem Phys, 139,
144110 (2013).
:link(Voter2002prd)
[(Voter2002)] Voter, Montalenti, Germann, Annual Review of Materials
Research 32, 321 (2002).

View File

@ -0,0 +1,95 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
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 <stdlib.h>
#include <string.h>
#include "fix_event_hyper.h"
#include "atom.h"
#include "update.h"
#include "domain.h"
#include "neighbor.h"
#include "comm.h"
#include "universe.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
using namespace FixConst;
/* ---------------------------------------------------------------------- */
FixEventHyper::FixEventHyper(LAMMPS *lmp, int narg, char **arg) :
FixEvent(lmp, narg, arg)
{
if (narg != 3) error->all(FLERR,"Illegal fix event command");
restart_global = 1;
event_number = 0;
event_timestep = update->ntimestep;
clock = 0;
}
/* ----------------------------------------------------------------------
save current atom coords as an event (via call to base class)
called when an event occurs in some replica
set event_timestep = when event occurred in a particular replica
update clock = elapsed time since last event, across all replicas
------------------------------------------------------------------------- */
void FixEventHyper::store_event_hyper(bigint ntimestep, int delta_clock)
{
store_event();
event_timestep = ntimestep;
clock += delta_clock;
event_number++;
}
/* ----------------------------------------------------------------------
pack entire state of Fix into one write
------------------------------------------------------------------------- */
void FixEventHyper::write_restart(FILE *fp)
{
int n = 0;
double list[6];
list[n++] = event_number;
list[n++] = event_timestep;
list[n++] = clock;
list[n++] = replica_number;
list[n++] = correlated_event;
list[n++] = ncoincident;
if (comm->me == 0) {
int size = n * sizeof(double);
fwrite(&size,sizeof(int),1,fp);
fwrite(list,sizeof(double),n,fp);
}
}
/* ----------------------------------------------------------------------
use state info from restart file to restart the Fix
------------------------------------------------------------------------- */
void FixEventHyper::restart(char *buf)
{
int n = 0;
double *list = (double *) buf;
event_number = static_cast<int> (list[n++]);
event_timestep = static_cast<bigint> (list[n++]);
clock = static_cast<bigint> (list[n++]);
replica_number = static_cast<int> (list[n++]);
correlated_event = static_cast<int> (list[n++]);
ncoincident = static_cast<int> (list[n++]);
}

View File

@ -0,0 +1,60 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
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 FIX_CLASS
FixStyle(EVENT/HYPER,FixEventHyper)
#else
#ifndef LMP_FIX_EVENT_HYPER_H
#define LMP_FIX_EVENT_HYPER_H
#include "fix_event.h"
namespace LAMMPS_NS {
class FixEventHyper : public FixEvent {
public:
int event_number; // event counter
bigint event_timestep; // timestep of last event on any replica
bigint clock; // total elapsed timesteps across all replicas
int replica_number; // replica where last event occured
int correlated_event; // 1 if last event was correlated, 0 otherwise
int ncoincident; // # of simultaneous events on different replicas
FixEventHyper(class LAMMPS *, int, char **);
~FixEventHyper() {}
void write_restart(FILE *);
void restart(char *);
// methods specific to FixEventHyper, invoked by hyper
void store_event_hyper(bigint, int);
};
}
#endif
#endif
/* ERROR/WARNING messages:
E: Illegal ... command
Self-explanatory. Check the input script syntax and compare to the
documentation for the command. You can use -echo screen as a
command-line option when running LAMMPS to see the offending line.
*/

35
src/REPLICA/fix_hyper.cpp Normal file
View File

@ -0,0 +1,35 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
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 <string.h>
#include "fix_hyper.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
FixHyper::FixHyper(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) {}
/* ----------------------------------------------------------------------
extract hyper flag setting for all Fixes that perform hyperdynamics
------------------------------------------------------------------------- */
void *FixHyper::extract(const char *str, int &dim)
{
dim = 0;
if (strcmp(str,"hyperflag") == 0) {
return &hyperflag;
}
return NULL;
}

43
src/REPLICA/fix_hyper.h Normal file
View File

@ -0,0 +1,43 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
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.
------------------------------------------------------------------------- */
#ifndef LMP_FIX_HYPER_H
#define LMP_FIX_HYPER_H
#include "fix.h"
namespace LAMMPS_NS {
class FixHyper : public Fix {
public:
FixHyper(class LAMMPS *, int, char **);
virtual ~FixHyper() {}
void *extract(const char *, int &);
// must be provided by child class
virtual void init_hyper() = 0;
virtual void build_bond_list(int) = 0;
virtual double query(int) = 0;
protected:
int hyperflag;
};
}
#endif
/* ERROR/WARNING messages:
*/

View File

@ -0,0 +1,497 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
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 <mpi.h>
#include <math.h>
#include <stdio.h>
#include <string.h>
#include "fix_hyper_global.h"
#include "atom.h"
#include "update.h"
#include "force.h"
#include "domain.h"
#include "comm.h"
#include "neighbor.h"
#include "neigh_request.h"
#include "neigh_list.h"
#include "modify.h"
#include "math_extra.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
using namespace FixConst;
#define DELTA 16384
#define VECLEN 5
/* ---------------------------------------------------------------------- */
FixHyperGlobal::FixHyperGlobal(LAMMPS *lmp, int narg, char **arg) :
FixHyper(lmp, narg, arg)
{
// NOTE: add NULL declarations
// NOTE: count/output # of timesteps on which bias is non-zero
// NOTE: require newton on?
if (atom->map_style == 0)
error->all(FLERR,"Fix hyper/global command requires atom map");
if (narg != 7) error->all(FLERR,"Illegal fix hyper/global command");
hyperflag = 1;
scalar_flag = 1;
vector_flag = 1;
size_vector = 11;
global_freq = 1;
extscalar = 0;
extvector = 0;
cutbond = force->numeric(FLERR,arg[3]);
qfactor = force->numeric(FLERR,arg[4]);
vmax = force->numeric(FLERR,arg[5]);
tequil = force->numeric(FLERR,arg[6]);
if (cutbond < 0.0 || qfactor <= 0.0 || vmax < 0.0 || tequil <= 0.0)
error->all(FLERR,"Illegal fix hyper/global command");
invqfactorsq = 1.0 / (qfactor*qfactor);
cutbondsq = cutbond*cutbond;
beta = 1.0 / (force->boltz * tequil);
maxbond = 0;
nblocal = 0;
blist = NULL;
maxold = 0;
xold = NULL;
tagold = NULL;
me = comm->me;
firstflag = 1;
bcastflag = 0;
for (int i = 0; i < VECLEN; i++) outvec[i] = 0.0;
nevent = 0;
nevent_atom = 0;
t_hyper = 0.0;
}
/* ---------------------------------------------------------------------- */
FixHyperGlobal::~FixHyperGlobal()
{
memory->sfree(blist);
memory->destroy(xold);
memory->destroy(tagold);
}
/* ---------------------------------------------------------------------- */
int FixHyperGlobal::setmask()
{
int mask = 0;
mask |= PRE_NEIGHBOR;
mask |= PRE_FORCE;
mask |= PRE_REVERSE;
mask |= THERMO_ENERGY;
return mask;
}
/* ---------------------------------------------------------------------- */
void FixHyperGlobal::init_hyper()
{
maxdriftsq = 0.0;
maxbondlen = 0.0;
nobias = 0;
}
/* ---------------------------------------------------------------------- */
void FixHyperGlobal::init()
{
dt = update->dt;
// need an occasional half neighbor list
int irequest = neighbor->request(this,instance_me);
neighbor->requests[irequest]->pair = 0;
neighbor->requests[irequest]->fix = 1;
neighbor->requests[irequest]->occasional = 1;
}
/* ---------------------------------------------------------------------- */
void FixHyperGlobal::init_list(int id, NeighList *ptr)
{
list = ptr;
}
/* ---------------------------------------------------------------------- */
void FixHyperGlobal::setup_pre_neighbor()
{
pre_neighbor();
}
/* ---------------------------------------------------------------------- */
void FixHyperGlobal::setup_pre_reverse(int eflag, int vflag)
{
// no increment in nobias or hyper time when pre-run forces are calculated
int nobias_hold = nobias;
double t_hyper_hold = t_hyper;
pre_reverse(eflag,vflag);
nobias = nobias_hold;
t_hyper = t_hyper_hold;
}
/* ---------------------------------------------------------------------- */
void FixHyperGlobal::pre_neighbor()
{
int i,m,jnum,iold,jold,ilocal,jlocal;
double distsq;
// reset local IDs for owned bond atoms, since atoms have migrated
// uses xold and tagold from when bonds were created
// must be done after ghost atoms are setup via comm->borders()
double **x = atom->x;
int flag = 0;
for (m = 0; m < nblocal; m++) {
iold = blist[m].iold;
jold = blist[m].jold;
ilocal = atom->map(tagold[iold]);
jlocal = atom->map(tagold[jold]);
ilocal = domain->closest_image(xold[iold],ilocal);
jlocal = domain->closest_image(xold[iold],jlocal);
blist[m].i = ilocal;
blist[m].j = jlocal;
if (ilocal < 0 || jlocal < 0) flag++;
else {
distsq = MathExtra::distsq3(x[ilocal],xold[iold]);
maxdriftsq = MAX(distsq,maxdriftsq);
}
}
if (flag) error->one(FLERR,"Fix hyper/global bond atom not found");
}
/* ---------------------------------------------------------------------- */
void FixHyperGlobal::pre_reverse(int eflag, int vflag)
{
int i,j,m,imax,jmax;
double xtmp,ytmp,ztmp,delx,dely,delz;
double r,r0,estrain,rmax,r0max,emax,dt_boost;
double vbias,fbias,fbiasr;
// compute current strain of each owned bond
// emax = maximum strain of any bond I own
// imax,jmax = local indices of my 2 atoms in that bond
double **x = atom->x;
emax = 0.0;
for (m = 0; m < nblocal; m++) {
i = blist[m].i;
j = blist[m].j;
delx = x[i][0] - x[j][0];
dely = x[i][1] - x[j][1];
delz = x[i][2] - x[j][2];
r = sqrt(delx*delx + dely*dely + delz*delz);
maxbondlen = MAX(r,maxbondlen);
r0 = blist[m].r0;
estrain = fabs(r-r0) / r0;
if (estrain > emax) {
emax = estrain;
rmax = r;
r0max = r0;
imax = i;
jmax = j;
}
}
// perform Allreduce() on pairme = double/int pair
// finds max strain and what proc owns it
// owner = proc that owns that bond
pairme.value = emax;
pairme.proc = me;
MPI_Allreduce(&pairme,&pairall,1,MPI_DOUBLE_INT,MPI_MAXLOC,world);
owner = pairall.proc;
bcastflag = 1;
// all procs acquire t_hyper from owner proc
// MPI_Bcast call by owner proc is below
for (int i = 0; i < VECLEN; i++) outvec[i] = 0.0;
if (owner != me) {
MPI_Bcast(&t_hyper,1,MPI_DOUBLE,owner,world);
return;
}
// I own the bond with max strain
// compute Vbias and apply force to atoms imax,jmax
// NOTE: logic would need to be different for newton off
double **f = atom->f;
vbias = fbias = 0.0;
dt_boost = 1.0;
if (emax < qfactor) {
vbias = vmax * (1.0 - emax*emax*invqfactorsq);
fbias = 2.0 * vmax * emax / (qfactor*qfactor * r0max);
dt_boost = exp(beta*vbias);
delx = x[imax][0] - x[jmax][0];
dely = x[imax][1] - x[jmax][1];
delz = x[imax][2] - x[jmax][2];
fbiasr = fbias / rmax;
f[imax][0] += delx*fbiasr;
f[imax][1] += dely*fbiasr;
f[imax][2] += delz*fbiasr;
f[jmax][0] -= delx*fbiasr;
f[jmax][1] -= dely*fbiasr;
f[jmax][2] -= delz*fbiasr;
} else nobias++;
// NOTE: should there be a virial contribution from boosted bond?
// output quantities
outvec[0] = vbias;
outvec[1] = dt_boost;
outvec[2] = emax;
outvec[3] = atom->tag[imax];
outvec[4] = atom->tag[jmax];
t_hyper += dt_boost*dt;
MPI_Bcast(&t_hyper,1,MPI_DOUBLE,owner,world);
}
/* ---------------------------------------------------------------------- */
void FixHyperGlobal::build_bond_list(int natom)
{
int i,j,n,ii,jj,inum,jnum;
double xtmp,ytmp,ztmp,delx,dely,delz,rsq;
int *ilist,*jlist,*numneigh,**firstneigh;
tagint *bptr;
double *rptr;
if (natom) {
nevent++;
nevent_atom += natom;
}
// trigger neighbor list build
neighbor->build_one(list);
// identify bonds assigned to each owned atom
// do not create a bond between two non-group atoms
double **x = atom->x;
int *mask = atom->mask;
inum = list->inum;
ilist = list->ilist;
numneigh = list->numneigh;
firstneigh = list->firstneigh;
nblocal = 0;
for (ii = 0; ii < inum; ii++) {
i = ilist[ii];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
jlist = firstneigh[i];
jnum = numneigh[i];
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
j &= NEIGHMASK;
// skip if neither atom I or J are in fix group
if (!(mask[i] & groupbit) && !(mask[j] & groupbit)) continue;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
if (rsq < cutbondsq) {
if (nblocal == maxbond) grow_bond();
blist[nblocal].i = i;
blist[nblocal].j = j;
blist[nblocal].iold = i;
blist[nblocal].jold = j;
blist[nblocal].r0 = sqrt(rsq);
nblocal++;
}
}
}
// store IDs and coords for owned+ghost atoms at time of bond creation
// realloc xold and tagold as needed
if (atom->nmax > maxold) {
memory->destroy(xold);
memory->destroy(tagold);
maxold = atom->nmax;
memory->create(xold,maxold,3,"hyper/global:xold");
memory->create(tagold,maxold,"hyper/global:tagold");
}
tagint *tag = atom->tag;
int nall = atom->nlocal + atom->nghost;
for (i = 0; i < nall; i++) {
xold[i][0] = x[i][0];
xold[i][1] = x[i][1];
xold[i][2] = x[i][2];
tagold[i] = tag[i];
}
}
/* ----------------------------------------------------------------------
grow bond list by a chunk
------------------------------------------------------------------------- */
void FixHyperGlobal::grow_bond()
{
// NOTE: could add int arg to do initial large alloc:
// maxbond = maxbond/DELTA * DELTA; maxbond += DELTA;
maxbond += DELTA;
if (maxbond < 0 || maxbond > MAXSMALLINT)
error->one(FLERR,"Fix hyper/local per-processor bond count is too big");
blist = (OneBond *)
memory->srealloc(blist,maxbond*sizeof(OneBond),"hyper/local:blist");
}
/* ---------------------------------------------------------------------- */
double FixHyperGlobal::compute_scalar()
{
if (bcastflag) {
MPI_Bcast(outvec,VECLEN,MPI_DOUBLE,owner,world);
bcastflag = 0;
}
return outvec[0];
}
/* ---------------------------------------------------------------------- */
double FixHyperGlobal::compute_vector(int i)
{
if (bcastflag) {
MPI_Bcast(outvec,VECLEN,MPI_DOUBLE,owner,world);
bcastflag = 0;
}
// 11 vector outputs returned for i = 0-10
// i = 0 = boost factor on this step
// i = 1 = max strain of any bond on this step
// i = 2 = ID of atom I in max-strain bond on this step
// i = 3 = ID of atom J in max-strain bond on this step
// i = 4 = ave bonds/atom on this step
// i = 5 = fraction of steps with no bias during this run
// i = 6 = max drift of any atom during this run
// i = 7 = max bond length during this run
// i = 8 = cummulative hyper time since fix created
// i = 9 = cummulative # of event timesteps since fix created
// i = 10 = cummulative # of atoms in events since fix created
if (i == 0) return outvec[1];
if (i == 1) return outvec[2];
if (i == 2) return outvec[3];
if (i == 3) return outvec[4];
if (i == 4) {
int allbonds; // NOTE: bigint?
MPI_Allreduce(&nblocal,&allbonds,1,MPI_INT,MPI_SUM,world);
return 2.0*allbonds/atom->natoms;
}
if (i == 5) {
if (update->ntimestep == update->firststep) return 0.0;
int allnobias;
MPI_Allreduce(&nobias,&allnobias,1,MPI_INT,MPI_SUM,world);
return 1.0*allnobias / (update->ntimestep - update->firststep);
}
if (i == 6) {
double alldriftsq;
MPI_Allreduce(&maxdriftsq,&alldriftsq,1,MPI_DOUBLE,MPI_MAX,world);
return sqrt(alldriftsq);
}
if (i == 7) {
double allbondlen;
MPI_Allreduce(&maxbondlen,&allbondlen,1,MPI_DOUBLE,MPI_MAX,world);
return allbondlen;
}
if (i == 8) return t_hyper;
if (i == 9) return (double) nevent;
if (i == 10) return (double) nevent_atom;
}
/* ----------------------------------------------------------------------
wrapper on compute_vector()
used by hyper.cpp to call FixHyper
------------------------------------------------------------------------- */
double FixHyperGlobal::query(int i)
{
if (i == 1) return compute_vector(8); // cummulative hyper time
if (i == 2) return compute_vector(9); // nevent
if (i == 3) return compute_vector(10); // nevent_atom
if (i == 4) return compute_vector(4); // ave bonds/atom
if (i == 5) return compute_vector(6); // maxdrift
if (i == 6) return compute_vector(7); // maxbondlen
if (i == 7) return compute_vector(5); // fraction with zero bias
error->all(FLERR,"Invalid query to fix hyper/global");
}
/* ----------------------------------------------------------------------
memory usage of local atom-based arrays
------------------------------------------------------------------------- */
double FixHyperGlobal::memory_usage()
{
double bytes = maxbond * sizeof(OneBond); // blist
return bytes;
}

View File

@ -0,0 +1,110 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
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 FIX_CLASS
FixStyle(hyper/global,FixHyperGlobal)
#else
#ifndef LMP_FIX_HYPER_GLOBAL_H
#define LMP_FIX_HYPER_GLOBAL_H
#include "fix_hyper.h"
namespace LAMMPS_NS {
class FixHyperGlobal : public FixHyper {
public:
FixHyperGlobal(class LAMMPS *, int, char **);
~FixHyperGlobal();
int setmask();
void init();
void init_list(int, class NeighList *);
void setup_pre_neighbor();
void setup_pre_reverse(int, int);
void pre_neighbor();
void pre_reverse(int, int);
double compute_scalar();
double compute_vector(int);
double query(int);
double memory_usage();
// extra methods visible to callers
void init_hyper();
void build_bond_list(int);
private:
int me;
double cutbond,qfactor,vmax,tequil;
int firstflag,bcastflag,owner,nevent,nevent_atom;
double cutbondsq,beta,dt,t_hyper,invqfactorsq;
double outvec[5]; // same as VECLEN in *.cpp
double maxbondlen; // max length of any bond
double maxdriftsq; // max distance any atom drifts from original pos
int nobias; // # of steps when bias = 0, b/c bond too long
class NeighList *list;
// list of my owned bonds
// persists on a proc from one event until the next
int maxbond; // allocated size of blist
struct OneBond { // single IJ bond, atom I is owner
int i,j; // current local indices of 2 bond atoms
int iold,jold; // local indices when bonds were formed
double r0; // relaxed bond length
};
struct OneBond *blist; // list of owned bonds
int nblocal; // # of owned bonds
// coords and IDs of owned+ghost atoms when bonds were formed
// persists on a proc from one event until the next
int maxold; // allocated size of old atoms
double **xold; // coords of atoms when bonds were formed
tagint *tagold; // IDs of atoms when bonds were formed
// MPI data struct for finding bond with max strain via Allreduce
struct Two {
double value;
int proc;
};
Two pairme,pairall;
// internal methods
void grow_bond();
};
}
#endif
#endif
/* ERROR/WARNING messages:
E: Illegal ... command
Self-explanatory. Check the input script syntax and compare to the
documentation for the command. You can use -echo screen as a
command-line option when running LAMMPS to see the offending line.
*/

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,175 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
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 FIX_CLASS
FixStyle(hyper/local,FixHyperLocal)
#else
#ifndef LMP_FIX_HYPER_LOCAL_H
#define LMP_FIX_HYPER_LOCAL_H
#include "fix_hyper.h"
namespace LAMMPS_NS {
class FixHyperLocal : public FixHyper {
public:
FixHyperLocal(class LAMMPS *, int, char **);
~FixHyperLocal();
int setmask();
void init();
void init_list(int, class NeighList *);
void setup_pre_neighbor();
void setup_pre_reverse(int, int);
void pre_neighbor();
void pre_reverse(int, int);
void min_pre_neighbor();
double compute_scalar();
double compute_vector(int);
double query(int);
int pack_forward_comm(int, int *, double *, int, int *);
void unpack_forward_comm(int, int, double *);
int pack_reverse_comm(int, int, double *);
void unpack_reverse_comm(int, int *, double *);
void grow_arrays(int);
void copy_arrays(int, int, int);
int pack_exchange(int, double *);
int unpack_exchange(int, double *);
double memory_usage();
// extra methods visible to callers
void init_hyper();
void build_bond_list(int);
private:
int me;
double cutbond,qfactor,vmax,tequil,dcut;
double alpha_user; // timescale to apply boostostat (time units)
double alpha; // unitless dt/alpha_user
double boosttarget; // target value of boost
int histoflag;
int lostbond,lostbond_partner;
double lostbond_coeff;
int checkbias,checkbias_every,checkbias_flag,checkbias_count;
int checkcoeff,checkcoeff_every,checkcoeff_flag,checkcoeff_count;
int setupflag; // 1 during setup, 0 during run
int firstflag; // set for first time bond_build takes place
int nostrainyet; // 1 until maxstrain is first computed
int nboost_running,nobias_running;
int nbondbuild;
double time_bondbuild;
bigint starttime;
double sumboostcoeff; // sum of aveboost at every timestep
int allbonds; // sum of bond count on this step
double allboost; // sum of boostcoeff on all bonds on this step
int nnewbond; // running tally of number of new bonds created
int maxbondperatom; // max # of bonds any atom ever has
int commflag; // flag for communication mode
int nevent; // # of events that trigger bond rebuild
int nevent_atom; // # of atoms that experienced an event
double cutbondsq,dcutsq;
double beta,t_hyper,invqfactorsq;
double mybias;
double maxbondlen; // cummulative max length of any bond
double maxdriftsq; // max distance any atom drifts from original pos
double maxboostcoeff; // cummulative max boost coeff for any bond
double minboostcoeff; // cummulative min boost coeff for any bond
double rmaxever,rmaxeverbig;
int ghost_toofar;
double timefirst,timesecond,timethird,timefourth;
double timefifth,timesixth,timeseventh,timetotal;
// data structs for per-atom and per-bond info
// all of these are for current owned and ghost atoms
// except list and old2now are for atom indices at time of last bond build
class NeighList *list; // full neigh list up to Dcut distance
// created only when bonds are rebuilt
int *old2now; // o2n[i] = current local index of old atom i
// stored for old owned and ghost atoms
// I = old index when bonds were last created
// old indices are stored in old neighbor list
double **xold; // coords of owned+ghost atoms when bonds created
tagint *tagold; // global IDs of owned+ghost atoms when b created
int maxold; // allocated size of old2now
int maxbond; // allocated size of bonds
int old_nall; // nlocal+nghost when old2now was last setup
struct OneBond { // single IJ bond, atom I is owner
double r0; // original relaxed bond length
double boostcoeff; // boost coefficient
tagint jtag; // global index of J atom in bond IJ
int j; // local index of J atom in bond IJ
};
struct OneBond **bonds; // 2d array of bonds for owned atoms
int *numbond; // number of bonds for each owned atom
double *maxstrain; // max-strain of any bond atom I is part of
// for owned and ghost atoms
double *maxstrain_region; // max-strain of any neighbor atom J of atom I
// for owned and ghost atoms
int *maxstrain_bondindex; // index of max-strain bond of each atom I
// just for owned atoms
tagint *biasflag; // atoms in biased bonds marked with bond partner
// for owned and ghost atoms
// list of boosted bonds that this proc will bias
int maxboost; // allocated size of boost list
int nboost; // # of boosted bonds I own
int *boost; // index of atom I in each boosted bond
// histogramming of bond boost cooeficients
int histo_flag,histo_every,histo_count,histo_print,histo_steps;
double histo_delta,invhisto_delta,histo_lo;
bigint *histo,*allhisto;
// DEBUG: MPI data struct for finding min/max bias coeffs via Allreduce
struct Two {
double value;
int proc;
};
Two pairme,pairall;
};
}
#endif
#endif
/* ERROR/WARNING messages:
E: Illegal ... command
Self-explanatory. Check the input script syntax and compare to the
documentation for the command. You can use -echo screen as a
command-line option when running LAMMPS to see the offending line.
*/

548
src/REPLICA/hyper.cpp Normal file
View File

@ -0,0 +1,548 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
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 <math.h>
#include <stdlib.h>
#include <string.h>
#include "hyper.h"
#include "update.h"
#include "atom.h"
#include "domain.h"
#include "region.h"
#include "integrate.h"
#include "min.h"
#include "force.h"
#include "neighbor.h"
#include "modify.h"
#include "compute_event_displace.h"
#include "fix_hyper.h"
#include "fix_event_hyper.h"
#include "output.h"
#include "dump.h"
#include "finish.h"
#include "timer.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
enum{NOHYPER,GLOBAL,LOCAL};
/* ---------------------------------------------------------------------- */
Hyper::Hyper(LAMMPS *lmp) : Pointers(lmp) {}
/* ----------------------------------------------------------------------
perform hyperdynamics simulation
------------------------------------------------------------------------- */
void Hyper::command(int narg, char **arg)
{
MPI_Comm_rank(world,&me);
MPI_Comm_size(world,&nprocs);
// error checks
if (domain->box_exist == 0)
error->all(FLERR,"Hyper command before simulation box is defined");
if (narg < 4) error->all(FLERR,"Illegal hyper command");
int nsteps = force->inumeric(FLERR,arg[0]);
t_event = force->inumeric(FLERR,arg[1]);
char *id_fix = new char[strlen(arg[2])+1];
strcpy(id_fix,arg[2]);
char *id_compute = new char[strlen(arg[3])+1];
strcpy(id_compute,arg[3]);
options(narg-4,&arg[4]);
// total # of timesteps must be multiple of t_event
if (t_event <= 0)
error->all(FLERR,"Invalid t_event in hyper command");
if (nsteps % t_event)
error->all(FLERR,"Hyper nsteps must be multiple of t_event");
if (rebond < 0)
error->all(FLERR,"Invalid rebond in hyper command");
if (rebond && rebond % t_event)
error->all(FLERR,"Hyper rebond must be multiple of t_event");
// FixHyper class performs global or local hyperdynamics
int hyperenable,hyperstyle;
if (strcmp(id_fix,"NULL") == 0) {
hyperenable = 0;
hyperstyle = NOHYPER;
} else {
int ifix = modify->find_fix(id_fix);
if (ifix < 0) error->all(FLERR,"Could not find fix ID for hyper");
fix_hyper = (FixHyper *) modify->fix[ifix];
int dim;
int *hyperflag = (int *) fix_hyper->extract("hyperflag",dim);
if (hyperflag == NULL || *hyperflag == 0)
error->all(FLERR,"Hyper fix is not a valid hyperdynamics fix");
if (*hyperflag == 1) hyperstyle = GLOBAL;
if (*hyperflag == 2) hyperstyle = LOCAL;
hyperenable = 1;
}
// create FixEventHyper class to store event and pre-quench states
char **args = new char*[3];
args[0] = (char *) "hyper_event";
args[1] = (char *) "all";
args[2] = (char *) "EVENT/HYPER";
modify->add_fix(3,args);
fix_event = (FixEventHyper *) modify->fix[modify->nfix-1];
delete [] args;
// create Finish for timing output
finish = new Finish(lmp);
// assign FixEventHyper to event-detection compute
// necessary so it will know atom coords at last event
int icompute = modify->find_compute(id_compute);
if (icompute < 0) error->all(FLERR,"Could not find compute ID for hyper");
compute_event = (ComputeEventDisplace *) modify->compute[icompute];
compute_event->reset_extra_compute_fix("hyper_event");
// reset reneighboring criteria since will perform minimizations
neigh_every = neighbor->every;
neigh_delay = neighbor->delay;
neigh_dist_check = neighbor->dist_check;
if (neigh_every != 1 || neigh_delay != 0 || neigh_dist_check != 1) {
if (me == 0)
error->warning(FLERR,"Resetting reneighboring criteria during hyper");
}
neighbor->every = 1;
neighbor->delay = 0;
neighbor->dist_check = 1;
// initialize hyper as if one long dynamics run
update->whichflag = 1;
update->nsteps = nsteps;
update->beginstep = update->firststep = update->ntimestep;
update->endstep = update->laststep = update->firststep + nsteps;
if (update->laststep < 0)
error->all(FLERR,"Too many timesteps");
lmp->init();
// init minimizer settings and minimizer itself
update->etol = etol;
update->ftol = ftol;
update->max_eval = maxeval;
// cannot use hyper with a changing box
// removing this restriction would require saving/restoring box params
if (domain->box_change)
error->all(FLERR,"Cannot use hyper with a changing box");
// cannot use hyper with time-dependent fixes or regions
for (int i = 0; i < modify->nfix; i++)
if (modify->fix[i]->time_depend)
error->all(FLERR,"Cannot use hyper with a time-dependent fix defined");
for (int i = 0; i < domain->nregion; i++)
if (domain->regions[i]->dynamic_check())
error->all(FLERR,"Cannot use hyper with a time-dependent region defined");
// perform hyperdynamics simulation
timer->init();
timer->barrier_start();
time_start = timer->get_wall(Timer::TOTAL);
nbuild = ndanger = 0;
time_dynamics = time_quench = 0.0;
double clock = 0.0;
if (hyperenable) fix_hyper->init_hyper();
timer->barrier_start();
time_start = timer->get_wall(Timer::TOTAL);
// perform initial minimization and bond list creation
int nevent = 0;
int nevent_atoms = 0;
fix_event->store_state_quench();
quench(1);
if (dumpflag)
for (int idump = 0; idump < ndump; idump++)
output->dump[dumplist[idump]]->write();
fix_event->store_event();
if (hyperenable) fix_hyper->build_bond_list(0);
fix_event->restore_state_quench();
// main loop: dynamics, store state, quench, check event, restore state
int ecount;
int istep = 0;
while (istep < nsteps) {
dynamics(t_event,time_dynamics);
fix_event->store_state_quench();
quench(0);
ecount = compute_event->all_events();
if (ecount) {
nevent++;
nevent_atoms += ecount;
if (dumpflag)
for (int idump = 0; idump < ndump; idump++)
output->dump[dumplist[idump]]->write();
fix_event->store_event();
if (hyperenable) fix_hyper->build_bond_list(ecount);
} else if (rebond && update->ntimestep % rebond == 0) {
fix_event->store_event();
if (hyperenable) fix_hyper->build_bond_list(ecount);
}
fix_event->restore_state_quench();
// NOTE: replace clock with hypertime
//clock = clock + t_event*universe->nworlds;
if (stepmode == 0) istep = update->ntimestep - update->beginstep;
else istep = clock;
}
if (stepmode) nsteps = update->ntimestep - update->beginstep;
// set total timers and counters so Finish() will process them
timer->set_wall(Timer::TOTAL,time_start);
timer->barrier_stop();
timer->set_wall(Timer::DYNAMICS,time_dynamics);
timer->set_wall(Timer::QUENCH,time_quench);
neighbor->ncalls = nbuild;
neighbor->ndanger = ndanger;
update->nsteps = nsteps;
if (me == 0) {
if (screen) fprintf(screen,"Final hyper stats ...\n\n");
if (logfile) fprintf(logfile,"Final hyper stats ...\n\n");
}
// subset of quantities also available in fix hyper output
int nevent_running = 0;
int nevent_atoms_running = 0;
double t_hyper = 0.0;
double avebonds = 0.0;
double maxdrift = 0.0;
double maxbondlen = 0.0;
double fraczero = 1.0;
double nnewbond,avenboost,aveboostcoeff,maxboostcoeff,minboostcoeff;
double maxbondperatom,neighbondperbond,aveboostnow;
double tbondbuild,rmaxever,rmaxeverbig,allghost_toofar;
double lostbond,lostbondcoeff,biasoverlap,nonmatchbiascoeff;
if (hyperenable) {
t_hyper = fix_hyper->query(1);
nevent_running = fix_hyper->query(2);
nevent_atoms_running = fix_hyper->query(3);
avebonds = fix_hyper->query(4);
maxdrift = fix_hyper->query(5);
maxbondlen = fix_hyper->query(6);
fraczero = fix_hyper->query(7);
if (hyperstyle == LOCAL) {
nnewbond = fix_hyper->query(8);
maxbondperatom = fix_hyper->query(9);
avenboost = fix_hyper->query(10);
aveboostcoeff = fix_hyper->query(11);
maxboostcoeff = fix_hyper->query(12);
minboostcoeff = fix_hyper->query(13);
neighbondperbond = fix_hyper->query(14);
aveboostnow = fix_hyper->query(15);
tbondbuild = fix_hyper->query(16);
rmaxever = fix_hyper->query(17);
rmaxeverbig = fix_hyper->query(18);
allghost_toofar = fix_hyper->query(19);
lostbond = fix_hyper->query(20);
lostbondcoeff = fix_hyper->query(21);
biasoverlap = fix_hyper->query(22);
nonmatchbiascoeff = fix_hyper->query(23);
}
}
if (me == 0) {
if (screen) {
fprintf(screen,"Cummulative quantities for fix hyper:\n");
fprintf(screen," hyper time = %g\n",t_hyper);
fprintf(screen," event timesteps = %d\n",nevent_running);
fprintf(screen," # of atoms in events = %d\n",nevent_atoms_running);
fprintf(screen,"Quantities for this hyper run:\n");
fprintf(screen," event timesteps = %d\n",nevent);
fprintf(screen," # of atoms in events = %d\n",nevent_atoms);
fprintf(screen," max length of any bond = %g\n",maxbondlen);
fprintf(screen," max drift distance of any atom = %g\n",maxdrift);
fprintf(screen," fraction of steps & bonds with zero bias = %g\n",
fraczero);
fprintf(screen,"Current quantities:\n");
fprintf(screen," ave bonds/atom = %g\n",avebonds);
if (hyperstyle == LOCAL) {
fprintf(screen,"Cummulative quantities specific to fix hyper/local:\n");
fprintf(screen," # of new bonds formed = %g\n",nnewbond);
fprintf(screen," max bonds/atom = %g\n",maxbondperatom);
fprintf(screen,"Quantities for this hyper run specific to "
"fix hyper/local:\n");
fprintf(screen," ave boosted bonds/step = %g\n",avenboost);
fprintf(screen," ave boost coeff of all bonds = %g\n",aveboostcoeff);
fprintf(screen," max boost coeff of any bond = %g\n",maxboostcoeff);
fprintf(screen," min boost coeff of any bond = %g\n",minboostcoeff);
fprintf(screen," max dist from my box of any "
"non-maxstrain bond ghost atom = %g\n",rmaxever);
fprintf(screen," max dist from my box of any bond ghost atom = %g\n",
rmaxeverbig);
fprintf(screen," count of bond ghost neighbors "
"not found on reneighbor steps = %g\n",allghost_toofar);
fprintf(screen," lost bond partners = %g\n",lostbond);
fprintf(screen," ave bias coeff for lost bond partners = %g\n",
lostbondcoeff);
fprintf(screen," bias overlaps = %g\n",biasoverlap);
fprintf(screen," non-matching bias coeffs = %g\n",nonmatchbiascoeff);
fprintf(screen," CPU time for bond builds = %g\n",tbondbuild);
fprintf(screen,"Current quantities specific to fix hyper/local:\n");
fprintf(screen," neighbor bonds/bond = %g\n",neighbondperbond);
fprintf(screen," ave boost coeff for all bonds = %g\n",aveboostnow);
}
fprintf(screen,"\n");
}
if (logfile) {
fprintf(logfile,"Cummulative quantities for fix hyper:\n");
fprintf(logfile," hyper time = %g\n",t_hyper);
fprintf(logfile," event timesteps = %d\n",nevent_running);
fprintf(logfile," # of atoms in events = %d\n",nevent_atoms_running);
fprintf(logfile,"Quantities for this hyper run:\n");
fprintf(logfile," event timesteps = %d\n",nevent);
fprintf(logfile," # of atoms in events = %d\n",nevent_atoms);
fprintf(logfile," max length of any bond = %g\n",maxbondlen);
fprintf(logfile," max drift distance of any atom = %g\n",maxdrift);
fprintf(logfile," fraction of steps & bonds with zero bias = %g\n",
fraczero);
fprintf(logfile,"Current quantities:\n");
fprintf(logfile," ave bonds/atom = %g\n",avebonds);
if (hyperstyle == LOCAL) {
fprintf(logfile,"Cummulative quantities specific tofix hyper/local:\n");
fprintf(logfile," # of new bonds formed = %g\n",nnewbond);
fprintf(logfile," max bonds/atom = %g\n",maxbondperatom);
fprintf(logfile,"Quantities for this hyper run specific to "
"fix hyper/local:\n");
fprintf(logfile," ave boosted bonds/step = %g\n",avenboost);
fprintf(logfile," ave boost coeff of all bonds = %g\n",aveboostcoeff);
fprintf(logfile," max boost coeff of any bond = %g\n",maxboostcoeff);
fprintf(logfile," min boost coeff of any bond = %g\n",minboostcoeff);
fprintf(logfile," max dist from my box of any "
"non-maxstrain bond ghost atom = %g\n",rmaxever);
fprintf(logfile," max dist from my box of any bond ghost atom = %g\n",
rmaxeverbig);
fprintf(logfile," count of ghost bond neighbors "
"not found on reneighbor steps = %g\n",allghost_toofar);
fprintf(logfile," lost bond partners = %g\n",lostbond);
fprintf(logfile," ave bias coeff for lost bond partners = %g\n",
lostbondcoeff);
fprintf(logfile," bias overlaps = %g\n",biasoverlap);
fprintf(logfile," non-matching bias coeffs = %g\n",nonmatchbiascoeff);
fprintf(logfile," CPU time for bond builds = %g\n",tbondbuild);
fprintf(logfile,"Current quantities specific to fix hyper/local:\n");
fprintf(logfile," neighbor bonds/bond = %g\n",neighbondperbond);
fprintf(logfile," ave boost coeff for all bonds = %g\n",aveboostnow);
}
fprintf(logfile,"\n");
}
}
// timing stats
finish->end(4);
update->whichflag = 0;
update->firststep = update->laststep = 0;
update->beginstep = update->endstep = 0;
// reset reneighboring criteria
neighbor->every = neigh_every;
neighbor->delay = neigh_delay;
neighbor->dist_check = neigh_dist_check;
delete [] id_fix;
delete [] id_compute;
memory->destroy(dumplist);
delete finish;
modify->delete_fix("hyper_event");
compute_event->reset_extra_compute_fix(NULL);
}
/* ----------------------------------------------------------------------
short dynamics run
------------------------------------------------------------------------- */
void Hyper::dynamics(int nsteps, double &time_category)
{
update->whichflag = 1;
update->nsteps = nsteps;
// full init works
// need to try partial init or setup
lmp->init();
update->integrate->setup(0);
// this may be needed if don't do full init
//modify->addstep_compute_all(update->ntimestep);
bigint ncalls = neighbor->ncalls;
timer->barrier_start();
update->integrate->run(nsteps);
timer->barrier_stop();
time_dynamics += timer->get_wall(Timer::TOTAL);
nbuild += neighbor->ncalls - ncalls;
ndanger += neighbor->ndanger;
update->integrate->cleanup();
finish->end(0);
}
/* ----------------------------------------------------------------------
quench minimization
flag = 1 to trigger output of memory in setup() call
------------------------------------------------------------------------- */
void Hyper::quench(int flag)
{
bigint ntimestep_hold = update->ntimestep;
bigint endstep_hold = update->endstep;
// need to change whichflag so that minimize->setup() calling
// modify->setup() will call fix->min_setup()
update->whichflag = 2;
update->nsteps = maxiter;
update->endstep = update->laststep = update->firststep + maxiter;
if (update->laststep < 0)
error->all(FLERR,"Too many iterations");
update->restrict_output = 1;
// full init works
lmp->init();
update->minimize->setup(flag);
// partial init does not work
//modify->addstep_compute_all(update->ntimestep);
//update->minimize->setup_minimal(1);
// NOTE: what doing with ncalls?
int ncalls = neighbor->ncalls;
timer->barrier_start();
update->minimize->run(maxiter);
timer->barrier_stop();
time_quench += timer->get_wall(Timer::TOTAL);
update->minimize->cleanup();
finish->end(0);
// reset timestep as if quench did not occur
// clear timestep storage from computes, since now invalid
update->restrict_output = 0;
update->ntimestep = ntimestep_hold;
update->endstep = update->laststep = endstep_hold;
for (int i = 0; i < modify->ncompute; i++)
if (modify->compute[i]->timeflag) modify->compute[i]->clearstep();
}
/* ----------------------------------------------------------------------
parse optional parameters at end of hyper input line
------------------------------------------------------------------------- */
void Hyper::options(int narg, char **arg)
{
// set defaults
etol = 1.0e-4;
ftol = 1.0e-4;
maxiter = 40;
maxeval = 50;
stepmode = 0;
dumpflag = 0;
ndump = 0;
dumplist = NULL;
rebond = 0;
int iarg = 0;
while (iarg < narg) {
if (strcmp(arg[iarg],"min") == 0) {
if (iarg+5 > narg) error->all(FLERR,"Illegal hyper command");
etol = force->numeric(FLERR,arg[iarg+1]);
ftol = force->numeric(FLERR,arg[iarg+2]);
maxiter = force->inumeric(FLERR,arg[iarg+3]);
maxeval = force->inumeric(FLERR,arg[iarg+4]);
if (maxiter < 0) error->all(FLERR,"Illegal hyper command");
iarg += 5;
} else if (strcmp(arg[iarg],"time") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal hyper command");
if (strcmp(arg[iarg+1],"steps") == 0) stepmode = 0;
else if (strcmp(arg[iarg+1],"clock") == 0) stepmode = 1;
else error->all(FLERR,"Illegal hyper command");
iarg += 2;
} else if (strcmp(arg[iarg],"dump") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal hyper command");
dumpflag = 1;
int idump = output->find_dump(arg[iarg+1]);
if (idump < 0)
error->all(FLERR,"Dump ID in hyper command does not exist");
memory->grow(dumplist,ndump+1,"hyper:dumplist");
dumplist[ndump++] = idump;
iarg += 2;
} else if (strcmp(arg[iarg],"rebond") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal hyper command");
rebond = force->inumeric(FLERR,arg[iarg+1]);
iarg += 2;
} else error->all(FLERR,"Illegal hyper command");
}
}

65
src/REPLICA/hyper.h Normal file
View File

@ -0,0 +1,65 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
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 COMMAND_CLASS
CommandStyle(hyper,Hyper)
#else
#ifndef LMP_HYPER_H
#define LMP_HYPER_H
#include "pointers.h"
namespace LAMMPS_NS {
class Hyper : protected Pointers {
public:
Hyper(class LAMMPS *);
~Hyper() {}
void command(int, char **);
private:
int me,nprocs;
int t_event;
double etol,ftol;
int maxiter,maxeval;
int stepmode,dumpflag,ndump,rebond;
int *dumplist;
int neigh_every,neigh_delay,neigh_dist_check;
int quench_reneighbor;
bigint nbuild,ndanger;
double time_dynamics,time_quench;
double time_start;
class FixHyper *fix_hyper;
class FixEventHyper *fix_event;
class ComputeEventDisplace *compute_event;
class Finish *finish;
void dynamics(int, double &);
void quench(int flag);
void options(int, char **);
};
}
#endif
#endif
/* ERROR/WARNING messages:
*/