some small formating change but does not work anymore

This commit is contained in:
Emile Maras
2017-05-18 16:48:20 +02:00
parent 640edbc1d4
commit 8daba01151
4 changed files with 647 additions and 735 deletions

View File

@ -1,15 +1,6 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR Free Software Foundation, Inc.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lws,http://lammps.sandia.gov) :link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
@ -20,107 +11,145 @@ fix neb command :h3
fix ID group-ID neb Kspring keyword value :pre
ID, group-ID are documented in "fix"_fix.html command
neb = style name of this fix command
Kspring = parallel spring constant (force/distance units) :ul
keyword = {idealpos} or {nearestneigh} or {PerpSpring} or {freeend}
{idealpos} value = none = each replica is attached with a spring to its interpolated ideal position (default value)
{nearestneigh} value = none = each replica is attached with a spring with the previous and next replica.
{PerpSpring} value = KspringPerpend
{freeend} value = ini or final or finalWithRespToIni or finalAndInterWithRespToIni
ID, group-ID are documented in "fix"_fix.html command neb = style name of this
fix command Kspring = parallel spring constant (force/distance units) :ul
keyword = {idealpos} or {neigh} or {perp} or {freeend} {idealpos} value = none =
each replica is attached with a spring to its interpolated ideal position
(default value) {neigh} value = none = each replica is attached with a spring
with the previous and next replica. {perp} value = spring constant for the
perpendicular spring {freeend} value = ini or final or finaleini or final2eini
[Examples:]
fix 1 active neb 10.0 :pre
fix 2 all neb 1.0 PerpSpring 1.0 freeend final :pre
fix 1 all neb 1.0 nearestneigh freeend finalAndInterWithRespToIni :pre
fix 1 active neb 10.0 :pre fix 2 all neb 1.0 perp 1.0 freeend final :pre fix 1
all neb 1.0 neigh freeend final2eini :pre
[Description:]
Add a nudging force to atoms in the group for a multi-replica simulation run via the "neb"_neb.html command to perform a nudged elastic band (NEB) calculation for finding the transition state. Hi-level
explanations of NEB are given with the "neb"_neb.html command and in "Section_howto 5"_Section_howto.html#howto_5 of the manual. The fix neb command must be used with the "neb" command and defines how
nudging inter-replica forces are computed.
A NEB calculation is divided in two stages. In the first stage n replicas are relaxed toward a MEP and in a second stage, the climbing image scheme (see "(Henkelman2)"_#Henkelman2) is turned on so that the replica having the highest energy relaxes toward the saddle point (i.e. the point of highest energy along the MEP).
Add a nudging force to atoms in the group for a multi-replica simulation run via
the "neb"_neb.html command to perform a nudged elastic band (NEB) calculation
for finding the transition state. Hi-level explanations of NEB are given with
the "neb"_neb.html command and in "Section_howto 5"_Section_howto.html#howto_5
of the manual. The fix neb command must be used with the "neb" command and
defines how nudging inter-replica forces are computed. A NEB calculation is
divided in two stages. In the first stage n replicas are relaxed toward a MEP
and in a second stage, the climbing image scheme (see
"(Henkelman2)"_#Henkelman2) is turned on so that the replica having the highest
energy relaxes toward the saddle point (i.e. the point of highest energy along
the MEP).
One purpose of the nudging forces is to keep the replicas equally spaced.
During the NEB, the 3N-length vector of interatomic force Fi = -Grad(V) of replicas i is altered. For all intermediate replicas (i.e. for 1<i<n) except for the climbing replica the force vector becomes:
One purpose of the nudging forces is to keep the replicas equally spaced.
During the NEB, the 3N-length vector of interatomic force Fi = -Grad(V) of
replicas i is altered. For all intermediate replicas (i.e. for 1<i<n) except for
the climbing replica the force vector becomes:
Fi = -Grad(V) + (Grad(V) dot That) That + Fspringparallel + Fspringperp :pre
That is the unit "tangent" vector for replica i and is a function of Ri, Ri-1,
Ri+1, and the potential energy of the 3 replicas; it points roughly in the direction of (Ri+i - Ri-1) (see the
"(Henkelman1)"_#Henkelman1 paper for details).
Ri are the atomic coordinates of replica i; Ri-1 and Ri+1 are the
coordinates of its neighbor replicas.
The term (Grad(V) dot That) is used to remove the component of the gradient parallel to the path which would tend to distribute the replica unevenly along the path.
Fspringparallel is an artificial spring force which is applied only in the tangent direction and which maintains the replicas equally spaced (see below for more information).
Fspringperp is an optinal artificial spring which is applied only perpendicular to the tangent and which prevent the paths from forming too acute kinks (see below for more information).
Ri+1, and the potential energy of the 3 replicas; it points roughly in the
direction of (Ri+i - Ri-1) (see the "(Henkelman1)"_#Henkelman1 paper for
details). Ri are the atomic coordinates of replica i; Ri-1 and Ri+1 are the
coordinates of its neighbor replicas. The term (Grad(V) dot That) is used to
remove the component of the gradient parallel to the path which would tend to
distribute the replica unevenly along the path. Fspringparallel is an
artificial spring force which is applied only in the tangent direction and which
maintains the replicas equally spaced (see below for more information).
Fspringperp is an optinal artificial spring which is applied only perpendicular
to the tangent and which prevent the paths from forming too acute kinks (see
below for more information).
In the second stage of the NEB, the interatomic force Fi for the climbing replica (which is the replica of highest energy) becomes :
In the second stage of the NEB, the interatomic force Fi for the climbing
replica (which is the replica of highest energy) becomes :
Fi = -Grad(V) + 2 (Grad(V) dot That) That :pre
By default, the force acting on the first and last replicas is not altered so that during the NEB relaxation, these ending replicas relax toward local minima. However it is possible to use the key word {freeend} to allow either the initial or the final replica to relax toward a MEP while constraining its energy.
The interatomic force Fi for the free end image becomes :
By default, the force acting on the first and last replicas is not altered so
that during the NEB relaxation, these ending replicas relax toward local
minima. However it is possible to use the key word {freeend} to allow either the
initial or the final replica to relax toward a MEP while constraining its
energy. The interatomic force Fi for the free end image becomes :
Fi = -Grad(V)+ (Grad(V) dot That + E-ETarget) That when Grad(V) dot That < 0
Fi = -Grad(V)+ (Grad(V) dot That + ETarget- E) That when Grad(V) dot That > 0
Fi = -Grad(V)+ (Grad(V) dot That + E-ETarget) That when Grad(V) dot That < 0 Fi
= -Grad(V)+ (Grad(V) dot That + ETarget- E) That when Grad(V) dot That > 0
where E is the energy of the free end replica and ETarget is the target energy.
When the value {ini} ({final}) is used after the keyword {freeend}, the first (last) replica is considered as a free end. The target energy is set to the energy of the replica at starting of the NEB calculation. When the value {finalWithRespToIni} or {finalAndInterWithRespToIni} is used the last image is considered as a free end and the target energy is equal to the energy of the first replica (which can evolve during the NEB relaxation).
With the value {finalWithRespToIni}, when the initial path is too far from the MEP, an intermediate repilica might relax "faster" and get a lower energy than the last replica. The benefit of the free end is then lost since this intermediate replica will relax toward a local minima. This behavior can be prevented by using the value {finalAndInterWithRespToIni} which remove entirely the contribution of the gradient for all intermediate replica which have a lower energy than the initial one thus preventing these replicae to over-relax. After converging a NEB with the {finalAndInterWithRespToIni} value it
is recommended to check that all intermediate replica have a larger energy than the initial replica. Finally note that if the last replica converges toward a local minimum with a larger energy than the energy of the first replica, a free end neb calculation with the value {finalWithRespToIni} or {finalAndInterWithRespToIni} cannot reach the convergence criteria.
When the value {ini} ({final}) is used after the keyword {freeend}, the first
(last) replica is considered as a free end. The target energy is set to the
energy of the replica at starting of the NEB calculation. When the value
{finaleini} or {final2eini} is used the last image is considered as a free end
and the target energy is equal to the energy of the first replica (which can
evolve during the NEB relaxation). With the value {finaleini}, when the initial
path is too far from the MEP, an intermediate repilica might relax "faster" and
get a lower energy than the last replica. The benefit of the free end is then
lost since this intermediate replica will relax toward a local minima. This
behavior can be prevented by using the value {final2eini} which remove entirely
the contribution of the gradient for all intermediate replica which have a lower
energy than the initial one thus preventing these replicae to over-relax. After
converging a NEB with the {final2eini} value it is recommended to check that all
intermediate replica have a larger energy than the initial replica. Finally note
that if the last replica converges toward a local minimum with a larger energy
than the energy of the first replica, a free end neb calculation with the value
{finaleini} or {final2eini} cannot reach the convergence criteria.
:line
The keywords {idealpos} and {nearestneigh} allow to specify how to parallel spring force is computed.
If the keyword {idealpos} is used or by default, the spring force is computed as suggested in "(E)"_#E :
The keywords {idealpos} and {neigh} allow to specify how to parallel spring
force is computed. If the keyword {idealpos} is used or by default, the spring
force is computed as suggested in "(E)"_#E :
Fspringparallel=-{Kspring}* (RD-RDideal)/(2 meanDist)
where RD is the "reaction coordinate" see "neb"_neb.html section, and RDideal is the ideal RD for which all the images are equally spaced (i.e. RDideal = (i-1)*meanDist when the climbing image is off, where i is the replica number). The meanDist is the average distance between replicas.
where RD is the "reaction coordinate" see "neb"_neb.html section, and RDideal is
the ideal RD for which all the images are equally spaced (i.e. RDideal =
(i-1)*meanDist when the climbing image is off, where i is the replica
number). The meanDist is the average distance between replicas.
If the keyword {nearestneigh} is used, the parallel spring force is computed as in "(Henkelman1)"_#Henkelman1 by connecting each intermediate replica with the previous and the next image:
If the keyword {neigh} is used, the parallel spring force is computed as in
"(Henkelman1)"_#Henkelman1 by connecting each intermediate replica with the
previous and the next image:
Fspringparallel= {Kspring}* (|Ri+1 - Ri| - |Ri - Ri-1|)
The parallel spring force associated with the key word idealpos should usually be more efficient at keeping the images equally spaced.
The parallel spring force associated with the key word idealpos should usually
be more efficient at keeping the images equally spaced.
:line
The keyword {PerpSpring} allows to add a spring force perpendicular to the path in order to prevent the path from becoming too kinky. It can improve significantly the convergence of the NEB when the resolution is poor (i.e. when too few images are used) (see "(Maras)"_#Maras).
The perpendicular spring force is given by
The keyword {perp} allows to add a spring force perpendicular to the path in
order to prevent the path from becoming too kinky. It can improve significantly
the convergence of the NEB when the resolution is poor (i.e. when too few images
are used) (see "(Maras)"_#Maras). The perpendicular spring force is given by
Fspringperp = {Kspringperp} * f(Ri-1,Ri,Ri+1) (Ri+1 + Ri-1 - 2 Ri)
f(Ri-1 Ri R+1) is a smooth scalar function of the angle Ri-1 Ri Ri+1. It is equal to 0 when the path is straight and is equal to 1 when the angle Ri-1 Ri Ri+1 is accute. f(Ri-1 Ri R+1) is defined in "(Jonsson)"_#Jonsson
f(Ri-1 Ri R+1) is a smooth scalar function of the angle Ri-1 Ri Ri+1. It is
equal to 0 when the path is straight and is equal to 1 when the angle Ri-1 Ri
Ri+1 is accute. f(Ri-1 Ri R+1) is defined in "(Jonsson)"_#Jonsson
:line
[Restart, fix_modify, output, run start/stop, minimize info:]
No information about this fix is written to "binary restart
files"_restart.html. None of the "fix_modify"_fix_modify.html options
are relevant to this fix. No global or per-atom quantities are stored
by this fix for access by various "output
commands"_Section_howto.html#howto_15. No parameter of this fix can
be used with the {start/stop} keywords of the "run"_run.html command.
No information about this fix is written to "binary restart files"_restart.html.
None of the "fix_modify"_fix_modify.html options are relevant to this fix. No
global or per-atom quantities are stored by this fix for access by various
"output commands"_Section_howto.html#howto_15. No parameter of this fix can be
used with the {start/stop} keywords of the "run"_run.html command.
The forces due to this fix are imposed during an energy minimization,
as invoked by the "minimize"_minimize.html command via the
"neb"_neb.html command.
The forces due to this fix are imposed during an energy minimization, as invoked
by the "minimize"_minimize.html command via the "neb"_neb.html command.
[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.
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.
[Related commands:]
@ -128,18 +157,17 @@ for more info on packages.
[Default:] none
:link(Henkelman)
[(Henkelman1)] Henkelman and Jonsson, J Chem Phys, 113, 9978-9985 (2000).
:link(Henkelman1) [(Henkelman1)] Henkelman and Jonsson, J Chem Phys, 113,
9978-9985 (2000).
:link(Henkelman)
[(Henkelman2)] Henkelman, Uberuaga, Jonsson, J Chem Phys, 113,
:link(Henkelman2) [(Henkelman2)] Henkelman, Uberuaga, Jonsson, J Chem Phys, 113,
9901-9904 (2000).
:link(E)
[(E)] E, Ren, Vanden-Eijnden, Phys Rev B, 66, 052301 (2002)
:link(E) [(E)] E, Ren, Vanden-Eijnden, Phys Rev B, 66, 052301 (2002)
:link(Jonsson)
[(Jonsson)] Jonsson, Mills and Jacobsen, in Classical and Quantum Dynamics in Condensed Phase Simulations, edited by Berne, Ciccotti, and Coker ͑World Scientific, Singapore, 1998͒, p. 385
:link(Jonsson) [(Jonsson)] Jonsson, Mills and Jacobsen, in Classical and Quantum
Dynamics in Condensed Phase Simulations, edited by Berne, Ciccotti, and Coker
͑World Scientific, Singapore, 1998͒, p. 385
:link(Maras)
[(Maras)] Maras, Trushin, Stukowski, Ala-Nissila, Jonsson, Comp Phys Comm, 205, 13-21 (2016)
:link(Maras) [(Maras)] Maras, Trushin, Stukowski, Ala-Nissila, Jonsson, Comp
Phys Comm, 205, 13-21 (2016)

View File

@ -1,7 +1,6 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lws,http://lammps.sandia.gov) :link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
@ -12,407 +11,362 @@ neb command :h3
neb etol ftol N1 N2 Nevery file-style arg keyword :pre
etol = stopping tolerance for energy (energy units) :ulb,l
ftol = stopping tolerance for force (force units) :l
N1 = max # of iterations (timesteps) to run initial NEB :l
N2 = max # of iterations (timesteps) to run barrier-climbing NEB :l
Nevery = print replica energies and reaction coordinates every this many timesteps :l
file-style= {final} or {each} or {none} :l
{final} arg = filename
filename = file with initial coords for final replica
coords for intermediate replicas are linearly interpolated between first and last replica
{each} arg = filename
filename = unique filename for each replica (except first) with its initial coords
{none} arg = no argument
all replicas assumed to already have their initial coords :pre
keyword = {verbose} :pre
:ule
etol = stopping tolerance for energy (energy units) :ulb,l ftol = stopping
tolerance for force (force units) :l N1 = max # of iterations (timesteps) to run
initial NEB :l N2 = max # of iterations (timesteps) to run barrier-climbing NEB
:l Nevery = print replica energies and reaction coordinates every this many
timesteps :l file-style= {final} or {each} or {none} :l {final} arg = filename
filename = file with initial coords for final replica coords for intermediate
replicas are linearly interpolated between first and last replica {each} arg =
filename filename = unique filename for each replica (except first) with its
initial coords {none} arg = no argument all replicas assumed to already have
their initial coords :pre keyword = {verbose} :pre :ule
[Examples:]
neb 0.1 0.0 1000 500 50 final coords.final
neb 0.0 0.001 1000 500 50 each coords.initial.$i
neb 0.0 0.001 1000 500 50 none verbose :pre
neb 0.1 0.0 1000 500 50 final coords.final neb 0.0 0.001 1000 500 50 each
coords.initial.$i neb 0.0 0.001 1000 500 50 none verbose :pre
[Description:]
Perform a nudged elastic band (NEB) calculation using multiple
replicas of a system. Two or more replicas must be used; the first
and last are the end points of the transition path.
Perform a nudged elastic band (NEB) calculation using multiple replicas of a
system. Two or more replicas must be used; the first and last are the end
points of the transition path.
NEB is a method for finding both the atomic configurations and height
of the energy barrier associated with a transition state, e.g. for an
atom to perform a diffusive hop from one energy basin to another in a
coordinated fashion with its neighbors. The implementation in LAMMPS
follows the discussion in these 4 papers: "(HenkelmanA)"_#HenkelmanA,
"(HenkelmanB)"_#HenkelmanB, "(Nakano)"_#Nakano and "(Maras)"_#Maras.
NEB is a method for finding both the atomic configurations and height of the
energy barrier associated with a transition state, e.g. for an atom to perform a
diffusive hop from one energy basin to another in a coordinated fashion with its
neighbors. The implementation in LAMMPS follows the discussion in these 4
papers: "(HenkelmanA)"_#HenkelmanA, "(HenkelmanB)"_#HenkelmanB,
"(Nakano)"_#Nakano3 and "(Maras)"_#Maras.
Each replica runs on a partition of one or more processors. Processor
partitions are defined at run-time using the -partition command-line
switch; see "Section 2.7"_Section_start.html#start_7 of the manual.
Note that if you have MPI installed, you can run a multi-replica
simulation with more replicas (partitions) than you have physical
processors, e.g you can run a 10-replica simulation on just one or two
processors. You will simply not get the performance speed-up you
would see with one or more physical processors per replica. See
"Section 6.5"_Section_howto.html#howto_5 of the manual for further
partitions are defined at run-time using the -partition command-line switch; see
"Section 2.7"_Section_start.html#start_7 of the manual. Note that if you have
MPI installed, you can run a multi-replica simulation with more replicas
(partitions) than you have physical processors, e.g you can run a 10-replica
simulation on just one or two processors. You will simply not get the
performance speed-up you would see with one or more physical processors per
replica. See "Section 6.5"_Section_howto.html#howto_5 of the manual for further
discussion.
NOTE: As explained below, a NEB calculation perfoms a damped dynamics
minimization across all the replicas. The mimimizer uses whatever
timestep you have defined in your input script, via the
"timestep"_timestep.html command. Often NEB will converge more
quickly if you use a timestep about 10x larger than you would normally
use for dynamics simulations.
minimization across all the replicas. The mimimizer uses whatever timestep you
have defined in your input script, via the "timestep"_timestep.html command.
Often NEB will converge more quickly if you use a timestep about 10x larger than
you would normally use for dynamics simulations.
When a NEB calculation is performed, it is assumed that each replica
is running the same system, though LAMMPS does not check for this.
I.e. the simulation domain, the number of atoms, the interaction
potentials, and the starting configuration when the neb command is
issued should be the same for every replica.
When a NEB calculation is performed, it is assumed that each replica is running
the same system, though LAMMPS does not check for this. I.e. the simulation
domain, the number of atoms, the interaction potentials, and the starting
configuration when the neb command is issued should be the same for every
replica.
In a NEB calculation each replica is connected to other replicas by inter-replica
nudging forces. These forces are imposed by the "fix neb"_fix_neb.html
command, which must be used in conjunction with the neb command. The
group used to define the fix neb command defines the NEB atoms which
are the only ones that inter-replica springs are applied to. If the
group does not include all atoms, then non-NEB atoms have no
inter-replica springs and the forces they feel and their motion is
computed in the usual way due only to other atoms within their
replica. Conceptually, the non-NEB atoms provide a background force
field for the NEB atoms. They can be allowed to move during the NEB
minimiation procedure (which will typically induce different
coordinates for non-NEB atoms in different replicas), or held fixed
using other LAMMPS commands such as "fix setforce"_fix_setforce.html.
Note that the "partition"_partition.html command can be used to invoke
a command on a subset of the replicas, e.g. if you wish to hold NEB or
non-NEB atoms fixed in only the end-point replicas.
In a NEB calculation each replica is connected to other replicas by
inter-replica nudging forces. These forces are imposed by the "fix
neb"_fix_neb.html command, which must be used in conjunction with the neb
command. The group used to define the fix neb command defines the NEB atoms
which are the only ones that inter-replica springs are applied to. If the group
does not include all atoms, then non-NEB atoms have no inter-replica springs and
the forces they feel and their motion is computed in the usual way due only to
other atoms within their replica. Conceptually, the non-NEB atoms provide a
background force field for the NEB atoms. They can be allowed to move during
the NEB minimization procedure (which will typically induce different
coordinates for non-NEB atoms in different replicas), or held fixed using other
LAMMPS commands such as "fix setforce"_fix_setforce.html. Note that the
"partition"_partition.html command can be used to invoke a command on a subset
of the replicas, e.g. if you wish to hold NEB or non-NEB atoms fixed in only the
end-point replicas.
The initial atomic configuration for each of the replicas can be
specified in different manners via the {file-style} setting, as
discussed below. Only atoms whose initial coordinates should differ
from the current configuration need be specified.
The initial atomic configuration for each of the replicas can be specified in
different manners via the {file-style} setting, as discussed below. Only atoms
whose initial coordinates should differ from the current configuration need be
specified.
Conceptually, the initial and final configurations for the first replica should
be states on either side of an energy barrier.
be states on either side of an energy barrier.
As explained below, the initial configurations of intermediate
replicas can be atomic coordinates interpolated in a linear fashion
between the first and last replicas. This is often adequate for
simple transitions. For more complex transitions, it may lead to slow
convergence or even bad results if the minimum energy path (MEP, see
below) of states over the barrier cannot be correctly converged to
from such an initial path. In this case, you will want to
generate initial states for the intermediate replicas that are
geometrically closer to the MEP and read them in.
As explained below, the initial configurations of intermediate replicas can be
atomic coordinates interpolated in a linear fashion between the first and last
replicas. This is often adequate for simple transitions. For more complex
transitions, it may lead to slow convergence or even bad results if the minimum
energy path (MEP, see below) of states over the barrier cannot be correctly
converged to from such an initial path. In this case, you will want to generate
initial states for the intermediate replicas that are geometrically closer to
the MEP and read them in.
:line
For a {file-style} setting of {final}, a filename is specified which
contains atomic coordinates for zero or more atoms, in the format
described below. For each atom that appears in the file, the new
coordinates are assigned to that atom in the final replica. Each
intermediate replica also assigns a new position to that atom in an
interpolated manner. This is done by using the current position of
the atom as the starting point and the read-in position as the final
point. The distance between them is calculated, and the new position
is assigned to be a fraction of the distance. E.g. if there are 10
replicas, the 2nd replica will assign a position that is 10% of the
distance along a line between the starting and final point, and the
9th replica will assign a position that is 90% of the distance along
the line. Note that for this procedure to produce consistent coordinates
across all the replicas, the current coordinates need to be the same
in all replicas. LAMMPS does not check for this, but invalid initial
configurations will likely result if it is not the case.
For a {file-style} setting of {final}, a filename is specified which contains
atomic coordinates for zero or more atoms, in the format described below. For
each atom that appears in the file, the new coordinates are assigned to that
atom in the final replica. Each intermediate replica also assigns a new
position to that atom in an interpolated manner. This is done by using the
current position of the atom as the starting point and the read-in position as
the final point. The distance between them is calculated, and the new position
is assigned to be a fraction of the distance. E.g. if there are 10 replicas,
the 2nd replica will assign a position that is 10% of the distance along a line
between the starting and final point, and the 9th replica will assign a position
that is 90% of the distance along the line. Note that for this procedure to
produce consistent coordinates across all the replicas, the current coordinates
need to be the same in all replicas. LAMMPS does not check for this, but
invalid initial configurations will likely result if it is not the case.
NOTE: The "distance" between the starting and final point is
calculated in a minimum-image sense for a periodic simulation box.
This means that if the two positions are on opposite sides of a box
(periodic in that dimension), the distance between them will be small,
because the periodic image of one of the atoms is close to the other.
Similarly, even if the assigned position resulting from the
interpolation is outside the periodic box, the atom will be wrapped
NOTE: The "distance" between the starting and final point is calculated in a
minimum-image sense for a periodic simulation box. This means that if the two
positions are on opposite sides of a box (periodic in that dimension), the
distance between them will be small, because the periodic image of one of the
atoms is close to the other. Similarly, even if the assigned position resulting
from the interpolation is outside the periodic box, the atom will be wrapped
back into the box when the NEB calculation begins.
For a {file-style} setting of {each}, a filename is specified which is
assumed to be unique to each replica. This can be done by
using a variable in the filename, e.g.
For a {file-style} setting of {each}, a filename is specified which is assumed
to be unique to each replica. This can be done by using a variable in the
filename, e.g.
variable i equal part
neb 0.0 0.001 1000 500 50 each coords.initial.$i :pre
variable i equal part neb 0.0 0.001 1000 500 50 each coords.initial.$i :pre
which in this case will substitute the partition ID (0 to N-1) for the
variable I, which is also effectively the replica ID. See the
"variable"_variable.html command for other options, such as using
world-, universe-, or uloop-style variables.
which in this case will substitute the partition ID (0 to N-1) for the variable
I, which is also effectively the replica ID. See the "variable"_variable.html
command for other options, such as using world-, universe-, or uloop-style
variables.
Each replica (except the first replica) will read its file, formatted
as described below, and for any atom that appears in the file, assign
the specified coordinates to this atom. The various files do not need
to contain the same set of atoms.
Each replica (except the first replica) will read its file, formatted as
described below, and for any atom that appears in the file, assign the specified
coordinates to this atom. The various files do not need to contain the same set
of atoms.
For a {file-style} setting of {none}, no filename is specified. Each
replica is assumed to already be in its initial configuration at the
time the neb command is issued. This allows each replica to define
its own configuration by reading a replica-specific data or restart or
dump file, via the "read_data"_read_data.html,
"read_restart"_read_restart.html, or "read_dump"_read_dump.html
commands. The replica-specific names of these files can be specified
as in the discussion above for the {each} file-style. Also see the
section below for how a NEB calculation can produce restart files, so
that a long calculation can be restarted if needed.
For a {file-style} setting of {none}, no filename is specified. Each replica is
assumed to already be in its initial configuration at the time the neb command
is issued. This allows each replica to define its own configuration by reading
a replica-specific data or restart or dump file, via the
"read_data"_read_data.html, "read_restart"_read_restart.html, or
"read_dump"_read_dump.html commands. The replica-specific names of these files
can be specified as in the discussion above for the {each} file-style. Also see
the section below for how a NEB calculation can produce restart files, so that a
long calculation can be restarted if needed.
NOTE: None of the {file-style} settings change the initial
configuration of any atom in the first replica. The first replica
must thus be in the correct initial configuration at the time the neb
command is issued.
NOTE: None of the {file-style} settings change the initial configuration of any
atom in the first replica. The first replica must thus be in the correct
initial configuration at the time the neb command is issued.
:line
A NEB calculation proceeds in two stages, each of which is a
minimization procedure, performed via damped dynamics. To enable
this, you must first define a damped dynamics
"min_style"_min_style.html, such as {quickmin} or {fire}. The {cg},
{sd}, and {hftn} styles cannot be used, since they perform iterative
line searches in their inner loop, which cannot be easily synchronized
across multiple replicas.
A NEB calculation proceeds in two stages, each of which is a minimization
procedure, performed via damped dynamics. To enable this, you must first define
a damped dynamics "min_style"_min_style.html, such as {quickmin} or {fire}. The
{cg}, {sd}, and {hftn} styles cannot be used, since they perform iterative line
searches in their inner loop, which cannot be easily synchronized across
multiple replicas.
The minimizer tolerances for energy and force are set by {etol} and
{ftol}, the same as for the "minimize"_minimize.html command.
The minimizer tolerances for energy and force are set by {etol} and {ftol}, the
same as for the "minimize"_minimize.html command.
A non-zero {etol} means that the NEB calculation will terminate if the
energy criterion is met by every replica. The energies being compared
to {etol} do not include any contribution from the inter-replica nudging
forces, since these are non-conservative. A non-zero {ftol} means
that the NEB calculation will terminate if the force criterion is met
by every replica. The forces being compared to {ftol} include the
inter-replica nudging forces.
A non-zero {etol} means that the NEB calculation will terminate if the energy
criterion is met by every replica. The energies being compared to {etol} do not
include any contribution from the inter-replica nudging forces, since these are
non-conservative. A non-zero {ftol} means that the NEB calculation will
terminate if the force criterion is met by every replica. The forces being
compared to {ftol} include the inter-replica nudging forces.
The maximum number of iterations in each stage is set by {N1} and
{N2}. These are effectively timestep counts since each iteration of
damped dynamics is like a single timestep in a dynamics
"run"_run.html. During both stages, the potential energy of each
replica and its normalized distance along the reaction path (reaction
coordinate RD) will be printed to the screen and log file every
{Nevery} timesteps. The RD is 0 and 1 for the first and last replica.
For intermediate replicas, it is the cumulative distance (normalized
by the total cumulative distance) between adjacent replicas, where
"distance" is defined as the length of the 3N-vector of differences in
atomic coordinates, where N is the number of NEB atoms involved in the
transition. These outputs allow you to monitor NEB's progress in
finding a good energy barrier. {N1} and {N2} must both be multiples
of {Nevery}.
The maximum number of iterations in each stage is set by {N1} and {N2}. These
are effectively timestep counts since each iteration of damped dynamics is like
a single timestep in a dynamics "run"_run.html. During both stages, the
potential energy of each replica and its normalized distance along the reaction
path (reaction coordinate RD) will be printed to the screen and log file every
{Nevery} timesteps. The RD is 0 and 1 for the first and last replica. For
intermediate replicas, it is the cumulative distance (normalized by the total
cumulative distance) between adjacent replicas, where "distance" is defined as
the length of the 3N-vector of differences in atomic coordinates, where N is the
number of NEB atoms involved in the transition. These outputs allow you to
monitor NEB's progress in finding a good energy barrier. {N1} and {N2} must
both be multiples of {Nevery}.
In the first stage of NEB, the set of replicas should converge toward
a minimum energy path (MEP) of conformational states that transition
over a barrier. The MEP for a transition is defined as a sequence of
3N-dimensional states, each of which has a potential energy gradient parallel to the MEP itself.
The configuration of highest energy along a MEP corresponds to a saddle point.
The replica states will also be roughly equally spaced along the MEP
due to the inter-replica nugding force added by the "fix
neb"_fix_neb.html command.
In the first stage of NEB, the set of replicas should converge toward a minimum
energy path (MEP) of conformational states that transition over a barrier. The
MEP for a transition is defined as a sequence of 3N-dimensional states, each of
which has a potential energy gradient parallel to the MEP itself. The
configuration of highest energy along a MEP corresponds to a saddle point. The
replica states will also be roughly equally spaced along the MEP due to the
inter-replica nugding force added by the "fix neb"_fix_neb.html command.
In the second stage of NEB, the replica with the highest energy
is selected and the inter-replica forces on it are converted to a
force that drives its atom coordinates to the top or saddle point of
the barrier, via the barrier-climbing calculation described in
"(HenkelmanB)"_#HenkelmanB. As before, the other replicas rearrange
themselves along the MEP so as to be roughly equally spaced.
In the second stage of NEB, the replica with the highest energy is selected and
the inter-replica forces on it are converted to a force that drives its atom
coordinates to the top or saddle point of the barrier, via the barrier-climbing
calculation described in "(HenkelmanB)"_#HenkelmanB. As before, the other
replicas rearrange themselves along the MEP so as to be roughly equally spaced.
When both stages are complete, if the NEB calculation was successful, the configurations of the replicas should be along (close to) the MEP and the replica with the highest energy should be an atomic configuration at (close to) the saddle point of
the transition. The potential energies for the set of
replicas represents the energy profile of the transition along the
MEP.
When both stages are complete, if the NEB calculation was successful, the
configurations of the replicas should be along (close to) the MEP and the
replica with the highest energy should be an atomic configuration at (close to)
the saddle point of the transition. The potential energies for the set of
replicas represents the energy profile of the transition along the MEP.
:line
A few other settings in your input script are required or advised to
perform a NEB calculation. See the NOTE about the choice of timestep
at the beginning of this doc page.
A few other settings in your input script are required or advised to perform a
NEB calculation. See the NOTE about the choice of timestep at the beginning of
this doc page.
An atom map must be defined which it is not by default for "atom_style
atomic"_atom_style.html problems. The "atom_modify
map"_atom_modify.html command can be used to do this.
atomic"_atom_style.html problems. The "atom_modify map"_atom_modify.html
command can be used to do this.
The minimizers in LAMMPS operate on all atoms in your system, even
non-NEB atoms, as defined above. To prevent non-NEB atoms from moving
during the minimization, you should use the "fix
setforce"_fix_setforce.html command to set the force on each of those
atoms to 0.0. This is not required, and may not even be desired in
some cases, but if those atoms move too far (e.g. because the initial
state of your system was not well-minimized), it can cause problems
for the NEB procedure.
The minimizers in LAMMPS operate on all atoms in your system, even non-NEB
atoms, as defined above. To prevent non-NEB atoms from moving during the
minimization, you should use the "fix setforce"_fix_setforce.html command to set
the force on each of those atoms to 0.0. This is not required, and may not even
be desired in some cases, but if those atoms move too far (e.g. because the
initial state of your system was not well-minimized), it can cause problems for
the NEB procedure.
The damped dynamics "minimizers"_min_style.html, such as {quickmin}
and {fire}), adjust the position and velocity of the atoms via an
Euler integration step. Thus you must define an appropriate
"timestep"_timestep.html to use with NEB. As mentioned above, NEB
will often converge more quickly if you use a timestep about 10x
larger than you would normally use for dynamics simulations.
The damped dynamics "minimizers"_min_style.html, such as {quickmin} and {fire}),
adjust the position and velocity of the atoms via an Euler integration step.
Thus you must define an appropriate "timestep"_timestep.html to use with NEB.
As mentioned above, NEB will often converge more quickly if you use a timestep
about 10x larger than you would normally use for dynamics simulations.
:line
Each file read by the neb command containing atomic coordinates used
to initialize one or more replicas must be formatted as follows.
Each file read by the neb command containing atomic coordinates used to
initialize one or more replicas must be formatted as follows.
The file can be ASCII text or a gzipped text file (detected by a .gz
suffix). The file can contain initial blank lines or comment lines
starting with "#" which are ignored. The first non-blank, non-comment
line should list N = the number of lines to follow. The N successive
lines contain the following information:
The file can be ASCII text or a gzipped text file (detected by a .gz suffix).
The file can contain initial blank lines or comment lines starting with "#"
which are ignored. The first non-blank, non-comment line should list N = the
number of lines to follow. The N successive lines contain the following
information:
ID1 x1 y1 z1
ID2 x2 y2 z2
...
IDN xN yN zN :pre
ID1 x1 y1 z1 ID2 x2 y2 z2 ... IDN xN yN zN :pre
The fields are the atom ID, followed by the x,y,z coordinates.
The lines can be listed in any order. Additional trailing information
on the line is OK, such as a comment.
The fields are the atom ID, followed by the x,y,z coordinates. The lines can be
listed in any order. Additional trailing information on the line is OK, such as
a comment.
Note that for a typical NEB calculation you do not need to specify
initial coordinates for very many atoms to produce differing starting
and final replicas whose intermediate replicas will converge to the
energy barrier. Typically only new coordinates for atoms
geometrically near the barrier need be specified.
Note that for a typical NEB calculation you do not need to specify initial
coordinates for very many atoms to produce differing starting and final replicas
whose intermediate replicas will converge to the energy barrier. Typically only
new coordinates for atoms geometrically near the barrier need be specified.
Also note there is no requirement that the atoms in the file
correspond to the NEB atoms in the group defined by the "fix
neb"_fix_neb.html command. Not every NEB atom need be in the file,
and non-NEB atoms can be listed in the file.
Also note there is no requirement that the atoms in the file correspond to the
NEB atoms in the group defined by the "fix neb"_fix_neb.html command. Not every
NEB atom need be in the file, and non-NEB atoms can be listed in the file.
:line
Four kinds of output can be generated during a NEB calculation: energy
barrier statistics, thermodynamic output by each replica, dump files,
and restart files.
Four kinds of output can be generated during a NEB calculation: energy barrier
statistics, thermodynamic output by each replica, dump files, and restart files.
When running with multiple partitions (each of which is a replica in
this case), the print-out to the screen and master log.lammps file
contains a line of output, printed once every {Nevery} timesteps. It
contains the timestep, the maximum force per replica, the maximum
force per atom (in any replica), potential gradients in the initial,
final, and climbing replicas, the forward and backward energy barriers,
the total reaction coordinate (RDT), and the normalized reaction
coordinate and potential energy of each replica.
When running with multiple partitions (each of which is a replica in this case),
the print-out to the screen and master log.lammps file contains a line of
output, printed once every {Nevery} timesteps. It contains the timestep, the
maximum force per replica, the maximum force per atom (in any replica),
potential gradients in the initial, final, and climbing replicas, the forward
and backward energy barriers, the total reaction coordinate (RDT), and the
normalized reaction coordinate and potential energy of each replica.
The "maximum force per replica" is
the two-norm of the 3N-length force vector for the atoms in each
replica, maximized across replicas, which is what the {ftol} setting
is checking against. In this case, N is all the atoms in each
replica. The "maximum force per atom" is the maximum force component
of any atom in any replica. The potential gradients are the two-norm
of the 3N-length force vector solely due to the interaction potential i.e.
without adding in inter-replica forces.
The "maximum force per replica" is the two-norm of the 3N-length force vector
for the atoms in each replica, maximized across replicas, which is what the
{ftol} setting is checking against. In this case, N is all the atoms in each
replica. The "maximum force per atom" is the maximum force component of any
atom in any replica. The potential gradients are the two-norm of the 3N-length
force vector solely due to the interaction potential i.e. without adding in
inter-replica forces.
The "reaction coordinate" (RD) for each
replica is the two-norm of the 3N-length vector of distances between
its atoms and the preceding replica's atoms, added to the RD of the
preceding replica. The RD of the first replica RD1 = 0.0;
the RD of the final replica RDN = RDT, the total reaction coordinate.
The normalized RDs are divided by RDT,
so that they form a monotonically increasing sequence
from zero to one. When computing RD, N only includes the atoms
being operated on by the fix neb command.
The "reaction coordinate" (RD) for each replica is the two-norm of the 3N-length
vector of distances between its atoms and the preceding replica's atoms, added
to the RD of the preceding replica. The RD of the first replica RD1 = 0.0; the
RD of the final replica RDN = RDT, the total reaction coordinate. The
normalized RDs are divided by RDT, so that they form a monotonically increasing
sequence from zero to one. When computing RD, N only includes the atoms being
operated on by the fix neb command.
The forward (reverse) energy barrier is the potential energy of the highest
replica minus the energy of the first (last) replica.
Supplementary informations for all replicas can be printed out to the screen and master
log.lammps file by adding the verbose keyword. These informations include the following.
The "path angle" (pathangle) for the replica i which is the angle
between the 3N-length vectors (Ri-1 - Ri) and (Ri+1 - Ri) (where Ri is the
Supplementary informations for all replicas can be printed out to the screen and
master log.lammps file by adding the verbose keyword. These informations include
the following. The "path angle" (pathangle) for the replica i which is the
angle between the 3N-length vectors (Ri-1 - Ri) and (Ri+1 - Ri) (where Ri is the
atomic coordinates of replica i). A "path angle" of 180 indicates that replicas
i-1, i and i+1 are aligned.
"angletangrad" is the angle between the 3N-length tangent vector and
the 3N-length force vector at image i. The tangent vector is calculated as in "(HenkelmanA)"_#HenkelmanA for all intermediate replicas and at R2 - R1 and RM - RM-1 for the first and last replica, respectively.
"anglegrad" is the angle between the 3N-length energy gradient vector of replica i and that of
replica i+1. It is not defined for the final replica and reads nan.
gradV is the norm of the energy gradient of image i.
ReplicaForce is the two-norm of the 3N-length force vector (including nudging forces) for replica i.
MaxAtomForce is the maximum force component of any atom in replica i.
i-1, i and i+1 are aligned. "angletangrad" is the angle between the 3N-length
tangent vector and the 3N-length force vector at image i. The tangent vector is
calculated as in "(HenkelmanA)"_#HenkelmanA for all intermediate replicas and at
R2 - R1 and RM - RM-1 for the first and last replica, respectively. "anglegrad"
is the angle between the 3N-length energy gradient vector of replica i and that
of replica i+1. It is not defined for the final replica and reads nan. gradV is
the norm of the energy gradient of image i. ReplicaForce is the two-norm of the
3N-length force vector (including nudging forces) for replica i. MaxAtomForce
is the maximum force component of any atom in replica i.
When a NEB calculation does not converge properly, these suplementary
informations can help understanding what is going wrong. For instance when the
path angle becomes accute the definition of tangent used in the NEB
calculation is questionable and the NEB cannot may diverge
"(Maras)"_#Maras.
path angle becomes accute the definition of tangent used in the NEB calculation
is questionable and the NEB cannot may diverge "(Maras)"_#Maras.
When running on multiple partitions, LAMMPS produces additional log
files for each partition, e.g. log.lammps.0, log.lammps.1, etc. For a
NEB calculation, these contain the thermodynamic output for each
replica.
When running on multiple partitions, LAMMPS produces additional log files for
each partition, e.g. log.lammps.0, log.lammps.1, etc. For a NEB calculation,
these contain the thermodynamic output for each replica.
If "dump"_dump.html commands in the input script define a filename
that includes a {universe} or {uloop} style "variable"_variable.html,
then one dump file (per dump command) will be created for each
replica. At the end of the NEB calculation, the final snapshot in
each file will contain the sequence of snapshots that transition the
system over the energy barrier. Earlier snapshots will show the
convergence of the replicas to the MEP.
If "dump"_dump.html commands in the input script define a filename that includes
a {universe} or {uloop} style "variable"_variable.html, then one dump file (per
dump command) will be created for each replica. At the end of the NEB
calculation, the final snapshot in each file will contain the sequence of
snapshots that transition the system over the energy barrier. Earlier snapshots
will show the convergence of the replicas to the MEP.
Likewise, "restart"_restart.html filenames can be specified with a
{universe} or {uloop} style "variable"_variable.html, to generate
restart files for each replica. These may be useful if the NEB
calculation fails to converge properly to the MEP, and you wish to
restart the calculation from an intermediate point with altered
parameters.
Likewise, "restart"_restart.html filenames can be specified with a {universe} or
{uloop} style "variable"_variable.html, to generate restart files for each
replica. These may be useful if the NEB calculation fails to converge properly
to the MEP, and you wish to restart the calculation from an intermediate point
with altered parameters.
There are 2 Python scripts provided in the tools/python directory,
neb_combine.py and neb_final.py, which are useful in analyzing output
from a NEB calculation. Assume a NEB simulation with M replicas, and
the NEB atoms labelled with a specific atom type.
neb_combine.py and neb_final.py, which are useful in analyzing output from a NEB
calculation. Assume a NEB simulation with M replicas, and the NEB atoms labeled
with a specific atom type.
The neb_combine.py script extracts atom coords for the NEB atoms from
all M dump files and creates a single dump file where each snapshot
contains the NEB atoms from all the replicas and one copy of non-NEB
atoms from the first replica (presumed to be identical in other
replicas). This can be visualized/animated to see how the NEB atoms
relax as the NEB calculation proceeds.
The neb_combine.py script extracts atom coords for the NEB atoms from all M dump
files and creates a single dump file where each snapshot contains the NEB atoms
from all the replicas and one copy of non-NEB atoms from the first replica
(presumed to be identical in other replicas). This can be visualized/animated
to see how the NEB atoms relax as the NEB calculation proceeds.
The neb_final.py script extracts the final snapshot from each of the M
dump files to create a single dump file with M snapshots. This can be
visualized to watch the system make its transition over the energy
barrier.
The neb_final.py script extracts the final snapshot from each of the M dump
files to create a single dump file with M snapshots. This can be visualized to
watch the system make its transition over the energy barrier.
To illustrate, here are images from the final snapshot produced by the
neb_combine.py script run on the dump files produced by the two
example input scripts in examples/neb. Click on them to see a larger
image.
neb_combine.py script run on the dump files produced by the two example input
scripts in examples/neb. Click on them to see a larger image.
:image(JPG/hop1_small.jpg,JPG/hop1.jpg)
:image(JPG/hop2_small.jpg,JPG/hop2.jpg)
:image(JPG/hop1_small.jpg,JPG/hop1.jpg) :image(JPG/hop2_small.jpg,JPG/hop2.jpg)
: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.
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.
:line
:line [Related commands:]
[Related commands:]
"prd"_prd.html, "temper"_temper.html, "fix
langevin"_fix_langevin.html, "fix viscous"_fix_viscous.html
"prd"_prd.html, "temper"_temper.html, "fix langevin"_fix_langevin.html, "fix
viscous"_fix_viscous.html
[Default:] none
:line
:link(HenkelmanA)
[(HenkelmanA)] Henkelman and Jonsson, J Chem Phys, 113, 9978-9985 (2000).
:link(HenkelmanA) [(HenkelmanA)] Henkelman and Jonsson, J Chem Phys, 113,
9978-9985 (2000).
:link(HenkelmanB)
[(HenkelmanB)] Henkelman, Uberuaga, Jonsson, J Chem Phys, 113,
:link(HenkelmanB) [(HenkelmanB)] Henkelman, Uberuaga, Jonsson, J Chem Phys, 113,
9901-9904 (2000).
:link(Nakano)
[(Nakano)] Nakano, Comp Phys Comm, 178, 280-289 (2008).
:link(Nakano3) [(Nakano)] Nakano, Comp Phys Comm, 178, 280-289 (2008).
:link(Maras)
[(Maras)] Maras, Trushin, Stukowski, Ala-Nissila, Jonsson, Comp Phys Comm, 205, 13-21 (2016)
:link(Maras) [(Maras)] Maras, Trushin, Stukowski, Ala-Nissila, Jonsson, Comp
Phys Comm, 205, 13-21 (2016)

View File

@ -27,9 +27,11 @@
#include "memory.h"
#include "error.h"
#include "force.h"
#include "math_const.h"
using namespace LAMMPS_NS;
using namespace FixConst;
using namespace MathConst;
enum{SINGLE_PROC_DIRECT,SINGLE_PROC_MAP,MULTI_PROC};
/* ---------------------------------------------------------------------- */
@ -55,35 +57,34 @@ FixNEB::FixNEB(LAMMPS *lmp, int narg, char **arg) :
int iarg =4;
while (iarg < narg){
if (strcmp (arg[iarg],"idealpos")==0)
{NEBLongRange = true;
iarg+=1;}
else if (strcmp (arg[iarg],"nearestneigh")==0)
{NEBLongRange = false;
StandardNEB = true;
iarg+=1;}
else if (strcmp (arg[iarg],"PerpSpring")==0)
{PerpSpring=true;
kspringPerp = force->numeric(FLERR,arg[iarg+1]);
if (kspringPerp < 0.0) error->all(FLERR,"Illegal fix neb command. The perpendicular spring force was not provided properly");
if (strcmp (arg[iarg],"idealpos")==0){
NEBLongRange = true;
iarg+=1;}
else if (strcmp (arg[iarg],"neigh")==0){
NEBLongRange = false;
StandardNEB = true;
iarg+=1;}
else if (strcmp (arg[iarg],"perp")==0){
PerpSpring=true;
kspringPerp = force->numeric(FLERR,arg[iarg+1]);
if (kspringPerp < 0.0) error->all(FLERR,"Illegal fix neb command. The perpendicular spring force was not provided properly");
iarg+=2;
}
else if (strcmp (arg[iarg],"freeend")==0)
{
if (strcmp (arg[iarg+1],"ini")==0)
FreeEndIni=true;
else if (strcmp (arg[iarg+1],"final")==0)
FreeEndFinal=true;
else if (strcmp (arg[iarg+1],"final")==0)
FreeEndFinal=true;
else if (strcmp (arg[iarg+1],"finalWithRespToIni")==0)
FreeEndFinalWithRespToEIni=true;
else if (strcmp (arg[iarg+1],"finalAndInterWithRespToIni")==0)
{FinalAndInterWithRespToEIni=true;
FreeEndFinalWithRespToEIni=true;}
iarg+=2;}
else {error->all(FLERR,"Illegal fix neb command. Unknown keyword");}
}
}
else if (strcmp (arg[iarg],"freeend")==0){
if (strcmp (arg[iarg+1],"ini")==0)
FreeEndIni=true;
else if (strcmp (arg[iarg+1],"final")==0)
FreeEndFinal=true;
else if (strcmp (arg[iarg+1],"final")==0)
FreeEndFinal=true;
else if (strcmp (arg[iarg+1],"finaleini")==0)
FreeEndFinalWithRespToEIni=true;
else if (strcmp (arg[iarg+1],"final2eini")==0){
FinalAndInterWithRespToEIni=true;
FreeEndFinalWithRespToEIni=true;}
iarg+=2;}
else {error->all(FLERR,"Illegal fix neb command. Unknown keyword");}
}
// nreplica = number of partitions
// ireplica = which world I am in universe
@ -97,7 +98,7 @@ FixNEB::FixNEB(LAMMPS *lmp, int narg, char **arg) :
nprocs_universe = universe->nprocs;
nreplica = universe->nworlds;
ireplica = universe->iworld;
if (ireplica > 0) procprev = universe->root_proc[ireplica-1];
else procprev = -1;
if (ireplica < nreplica-1) procnext = universe->root_proc[ireplica+1];
@ -106,13 +107,10 @@ FixNEB::FixNEB(LAMMPS *lmp, int narg, char **arg) :
int *iroots = new int[nreplica];
MPI_Group uworldgroup,rootgroup;
if (NEBLongRange ){
for (int iIm =0; iIm < nreplica;iIm++)
{
iroots[iIm]=universe->root_proc[iIm];
}
for (int iIm =0; iIm < nreplica;iIm++){
iroots[iIm]=universe->root_proc[iIm];}
MPI_Comm_group(uworld, &uworldgroup);
MPI_Group_incl(uworldgroup, nreplica, iroots, &rootgroup);
// MPI_Comm_create_group(uworld, rootgroup, 0, &rootworld);
MPI_Comm_create(uworld, rootgroup, &rootworld);
}
@ -179,7 +177,7 @@ FixNEB::~FixNEB()
memory->destroy(counts);
memory->destroy(displacements);
if (NEBLongRange)
if (NEBLongRange)
memory->destroy(nlenall);
}
@ -216,7 +214,7 @@ void FixNEB::init()
// comm mode for inter-replica exchange of coords
if (nreplica == nprocs_universe &&
nebatoms == atom->natoms && atom->sortfreq == 0)
nebatoms == atom->natoms && atom->sortfreq == 0)
cmode = SINGLE_PROC_DIRECT;
else if (nreplica == nprocs_universe) cmode = SINGLE_PROC_MAP;
else cmode = MULTI_PROC;
@ -266,15 +264,12 @@ void FixNEB::min_post_force(int vflag)
MPI_Status status;
MPI_Request request;
double vIni =0.0;
// veng = PE of this replica
// vprev,vnext = PEs of adjacent replicas
// only proc 0 in each replica communicates
vprev=vnext=veng = pe->compute_scalar();
if (ireplica < nreplica-1 && me ==0)
MPI_Send(&veng,1,MPI_DOUBLE,procnext,0,uworld);
if (ireplica > 0 && me ==0)
if (ireplica > 0 && me ==0)
MPI_Recv(&vprev,1,MPI_DOUBLE,procprev,0,uworld,&status);
if (ireplica > 0 && me == 0)
@ -287,39 +282,32 @@ void FixNEB::min_post_force(int vflag)
MPI_Bcast(&vnext,1,MPI_DOUBLE,0,world);
}
if (FreeEndFinal)
{
if (update->ntimestep==0)
{EFinalIni = veng;}
}
if (FreeEndFinal){
if (update->ntimestep==0){EFinalIni = veng;}
}
if (ireplica==0)
vIni=veng;
if (FreeEndFinalWithRespToEIni ) {
if (FreeEndFinalWithRespToEIni ){
if ( me ==0){
int procFirst;
procFirst=universe->root_proc[0];
MPI_Bcast(&vIni,1,MPI_DOUBLE,procFirst,uworld); //MPI_Recv(&vIni,1,MPI_DOUBLE,procFirst,0,uworld,&status);
MPI_Bcast(&vIni,1,MPI_DOUBLE,procFirst,uworld); //MPI_Recv(&vIni,1,MPI_DOUBLE,procFirst,0,uworld,&status);
}
if (cmode == MULTI_PROC) {
MPI_Bcast(&vIni,1,MPI_DOUBLE,0,world);
}
}
if (FreeEndIni && ireplica==0 )
{
if (me == 0 )
if (update->ntimestep==0)
{
EIniIni = veng;
if (cmode == MULTI_PROC)
MPI_Bcast(&EIniIni,1,MPI_DOUBLE,0,world);
}
if (FreeEndIni && ireplica==0 ){
if (me == 0 )
if (update->ntimestep==0){
EIniIni = veng;
if (cmode == MULTI_PROC)
MPI_Bcast(&EIniIni,1,MPI_DOUBLE,0,world);
}
}
// communicate atoms to/from adjacent replicas to fill xprev,xnext
inter_replica_comm();
// trigger potential energy computation on next timestep
@ -349,7 +337,7 @@ void FixNEB::min_post_force(int vflag)
if (ireplica < nreplica-1)
MPI_Irecv(xnext[0],3*nlocal,MPI_DOUBLE,procnext,0,uworld,&request);
MMY_PI_Irecv(xnext[0],3*nlocal,MPI_DOUBLE,procnext,0,uworld,&request);
if (ireplica > 0)
MPI_Send(x[0],3*nlocal,MPI_DOUBLE,procprev,0,uworld);
if (ireplica < nreplica-1) MPI_Wait(&request,&status);
@ -392,57 +380,52 @@ void FixNEB::min_post_force(int vflag)
dotpath = 0.0;
dottangrad = 0.0;
if (ireplica ==nreplica-1){
for (int i = 0; i < nlocal; i++)
if (mask[i] & groupbit) {
delxp = x[i][0] - xprev[i][0];
delyp = x[i][1] - xprev[i][1];
delzp = x[i][2] - xprev[i][2];
domain->minimum_image(delxp,delyp,delzp);
plen += delxp*delxp + delyp*delyp + delzp*delzp;
dottangrad += delxp* f[i][0]+ delyp*f[i][1]+delzp*f[i][2];
gradlen += f[i][0]*f[i][0] + f[i][1]*f[i][1] + f[i][2]*f[i][2];
if (FreeEndFinal||FreeEndFinalWithRespToEIni){
tangent[i][0]=delxp;
tangent[i][1]=delyp;
tangent[i][2]=delzp;
tlen += tangent[i][0]*tangent[i][0] + tangent[i][1]*tangent[i][1] +
tangent[i][2]*tangent[i][2];
dot += f[i][0]*tangent[i][0] + f[i][1]*tangent[i][1] + f[i][2]*tangent[i][2];
}
}
delxp = x[i][0] - xprev[i][0];
delyp = x[i][1] - xprev[i][1];
delzp = x[i][2] - xprev[i][2];
domain->minimum_image(delxp,delyp,delzp);
plen += delxp*delxp + delyp*delyp + delzp*delzp;
dottangrad += delxp* f[i][0]+ delyp*f[i][1]+delzp*f[i][2];
gradlen += f[i][0]*f[i][0] + f[i][1]*f[i][1] + f[i][2]*f[i][2];
if (FreeEndFinal||FreeEndFinalWithRespToEIni){
tangent[i][0]=delxp;
tangent[i][1]=delyp;
tangent[i][2]=delzp;
tlen += tangent[i][0]*tangent[i][0] + tangent[i][1]*tangent[i][1] +
tangent[i][2]*tangent[i][2];
dot += f[i][0]*tangent[i][0] + f[i][1]*tangent[i][1] + f[i][2]*tangent[i][2];
}
}
}
else if (ireplica == 0){
for (int i = 0; i < nlocal; i++)
if (mask[i] & groupbit) {
delxn = xnext[i][0] - x[i][0];
delyn = xnext[i][1] - x[i][1];
delzn = xnext[i][2] - x[i][2];
domain->minimum_image(delxn,delyn,delzn);
nlen += delxn*delxn + delyn*delyn + delzn*delzn;
gradnextlen += fnext[i][0]*fnext[i][0] + fnext[i][1]*fnext[i][1] +fnext[i][2] * fnext[i][2];
dotgrad += f[i][0]*fnext[i][0] + f[i][1]*fnext[i][1] +
f[i][2]*fnext[i][2];
dottangrad += delxn* f[i][0]+ delyn*f[i][1]+delzn*f[i][2];
gradlen += f[i][0]*f[i][0] + f[i][1]*f[i][1] + f[i][2]*f[i][2];
if (FreeEndIni)
{
tangent[i][0]=delxn;
tangent[i][1]=delyn;
tangent[i][2]=delzn;
tlen += tangent[i][0]*tangent[i][0] + tangent[i][1]*tangent[i][1] +
tangent[i][2]*tangent[i][2];
dot += f[i][0]*tangent[i][0] + f[i][1]*tangent[i][1] + f[i][2]*tangent[i][2];
}
delxn = xnext[i][0] - x[i][0];
delyn = xnext[i][1] - x[i][1];
delzn = xnext[i][2] - x[i][2];
domain->minimum_image(delxn,delyn,delzn);
nlen += delxn*delxn + delyn*delyn + delzn*delzn;
gradnextlen += fnext[i][0]*fnext[i][0] + fnext[i][1]*fnext[i][1] +fnext[i][2] * fnext[i][2];
dotgrad += f[i][0]*fnext[i][0] + f[i][1]*fnext[i][1] +
f[i][2]*fnext[i][2];
dottangrad += delxn* f[i][0]+ delyn*f[i][1]+delzn*f[i][2];
gradlen += f[i][0]*f[i][0] + f[i][1]*f[i][1] + f[i][2]*f[i][2];
if (FreeEndIni)
{
tangent[i][0]=delxn;
tangent[i][1]=delyn;
tangent[i][2]=delzn;
tlen += tangent[i][0]*tangent[i][0] + tangent[i][1]*tangent[i][1] +
tangent[i][2]*tangent[i][2];
dot += f[i][0]*tangent[i][0] + f[i][1]*tangent[i][1] + f[i][2]*tangent[i][2];
}
}
}
else //not the first or last replica
@ -452,61 +435,59 @@ void FixNEB::min_post_force(int vflag)
for (int i = 0; i < nlocal; i++)
if (mask[i] & groupbit) {
delxp = x[i][0] - xprev[i][0];
delyp = x[i][1] - xprev[i][1];
delzp = x[i][2] - xprev[i][2];
domain->minimum_image(delxp,delyp,delzp);
plen += delxp*delxp + delyp*delyp + delzp*delzp;
if (mask[i] & groupbit) {
delxp = x[i][0] - xprev[i][0];
delyp = x[i][1] - xprev[i][1];
delzp = x[i][2] - xprev[i][2];
domain->minimum_image(delxp,delyp,delzp);
plen += delxp*delxp + delyp*delyp + delzp*delzp;
delxn = xnext[i][0] - x[i][0];
delyn = xnext[i][1] - x[i][1];
delzn = xnext[i][2] - x[i][2];
domain->minimum_image(delxn,delyn,delzn); domain->minimum_image(delxn,delyn,delzn);
delxn = xnext[i][0] - x[i][0];
delyn = xnext[i][1] - x[i][1];
delzn = xnext[i][2] - x[i][2];
domain->minimum_image(delxn,delyn,delzn); domain->minimum_image(delxn,delyn,delzn);
if (vnext > veng && veng > vprev) {
tangent[i][0]=delxn;
tangent[i][1]=delyn;
tangent[i][2]=delzn;
}
else if (vnext < veng && veng < vprev) {
tangent[i][0]=delxp;
tangent[i][1]=delyp;
tangent[i][2]=delzp;
}
else {
if (vnext > vprev) {
tangent[i][0] = vmax*delxn + vmin*delxp;
tangent[i][1] = vmax*delyn + vmin*delyp;
tangent[i][2] = vmax*delzn + vmin*delzp;
} else {
tangent[i][0] = vmin*delxn + vmax*delxp;
tangent[i][1] = vmin*delyn + vmax*delyp;
tangent[i][2] = vmin*delzn + vmax*delzp;
}
if (vnext > veng && veng > vprev) {
tangent[i][0]=delxn;
tangent[i][1]=delyn;
tangent[i][2]=delzn;
}
else if (vnext < veng && veng < vprev) {
tangent[i][0]=delxp;
tangent[i][1]=delyp;
tangent[i][2]=delzp;
}
else {
if (vnext > vprev) {
tangent[i][0] = vmax*delxn + vmin*delxp;
tangent[i][1] = vmax*delyn + vmin*delyp;
tangent[i][2] = vmax*delzn + vmin*delzp;
} else {
tangent[i][0] = vmin*delxn + vmax*delxp;
tangent[i][1] = vmin*delyn + vmax*delyp;
tangent[i][2] = vmin*delzn + vmax*delzp;
}
}
}
nlen += delxn*delxn + delyn*delyn + delzn*delzn;
tlen += tangent[i][0]*tangent[i][0] + tangent[i][1]*tangent[i][1] +
tangent[i][2]*tangent[i][2];
gradlen += f[i][0]*f[i][0] + f[i][1]*f[i][1] + f[i][2]*f[i][2];
dotpath += delxp*delxn + delyp*delyn + delzp*delzn;
dottangrad += tangent[i][0]* f[i][0]+ tangent[i][1]*f[i][1]+tangent[i][2]*f[i][2];
nlen += delxn*delxn + delyn*delyn + delzn*delzn;
tlen += tangent[i][0]*tangent[i][0] + tangent[i][1]*tangent[i][1] +
tangent[i][2]*tangent[i][2];
gradlen += f[i][0]*f[i][0] + f[i][1]*f[i][1] + f[i][2]*f[i][2];
dotpath += delxp*delxn + delyp*delyn + delzp*delzn;
dottangrad += tangent[i][0]* f[i][0]+ tangent[i][1]*f[i][1]+tangent[i][2]*f[i][2];
gradnextlen += fnext[i][0]*fnext[i][0] + fnext[i][1]*fnext[i][1] +fnext[i][2] * fnext[i][2];
dotgrad += f[i][0]*fnext[i][0] + f[i][1]*fnext[i][1] +
f[i][2]*fnext[i][2];
gradnextlen += fnext[i][0]*fnext[i][0] + fnext[i][1]*fnext[i][1] +fnext[i][2] * fnext[i][2];
dotgrad += f[i][0]*fnext[i][0] + f[i][1]*fnext[i][1] +
f[i][2]*fnext[i][2];
springF[i][0]=kspringPerp*(delxn-delxp);
springF[i][1]=kspringPerp*(delyn-delyp);
springF[i][2]=kspringPerp*(delzn-delzp);
}
}
springF[i][0]=kspringPerp*(delxn-delxp);
springF[i][1]=kspringPerp*(delyn-delyp);
springF[i][2]=kspringPerp*(delzn-delzp);
}
}
double lenall;
MPI_Allreduce(&nlen,&lenall,1,MPI_DOUBLE,MPI_SUM,world);
@ -525,7 +506,6 @@ void FixNEB::min_post_force(int vflag)
gradnextlen = sqrt(lenall);
double dotpathall;
double dottangradall;
@ -561,146 +541,109 @@ void FixNEB::min_post_force(int vflag)
}
if(ireplica==0) dottangrad = dottangrad/(nlen*gradlen);
if(ireplica==nreplica-1) dottangrad = dottangrad/(plen*gradlen);
if(ireplica < nreplica-1)
{
dotgrad = dotgrad /(gradlen*gradnextlen);
}
if(ireplica < nreplica-1){
dotgrad = dotgrad /(gradlen*gradnextlen);
}
if(FreeEndIni&&ireplica == 0)
{
if (tlen > 0.0) {
double dotall;
MPI_Allreduce(&dot,&dotall,1,MPI_DOUBLE,MPI_SUM,world);
dot=dotall;
double tleninv = 1.0/tlen;
dot *= tleninv;
if (dot<0)
prefactor = -dot - (veng-EIniIni);
else prefactor = -dot + (veng-EIniIni);
for (int i = 0; i < nlocal; i++)
if (mask[i] & groupbit) {
f[i][0] += prefactor *tangent[i][0];
f[i][1] += prefactor *tangent[i][1];
f[i][2] += prefactor *tangent[i][2];
}
}
if(FreeEndIni&&ireplica == 0) {
if (tlen > 0.0) {
double dotall;
MPI_Allreduce(&dot,&dotall,1,MPI_DOUBLE,MPI_SUM,world);
dot=dotall;
double tleninv = 1.0/tlen;
dot *= tleninv;
if (dot<0)
prefactor = -dot - (veng-EIniIni);
else prefactor = -dot + (veng-EIniIni);
for (int i = 0; i < nlocal; i++)
if (mask[i] & groupbit) {
f[i][0] += prefactor *tangent[i][0];
f[i][1] += prefactor *tangent[i][1];
f[i][2] += prefactor *tangent[i][2];
}
}
}
if(FreeEndFinal&&ireplica == nreplica -1)
{if (tlen > 0.0) {
double dotall;
MPI_Allreduce(&dot,&dotall,1,MPI_DOUBLE,MPI_SUM,world);
dot=dotall;
double tleninv = 1.0/tlen;
dot *= tleninv;
if (dot<0)
prefactor = -dot - (veng-EFinalIni);
else prefactor = -dot + (veng-EFinalIni);
for (int i = 0; i < nlocal; i++)
if (mask[i] & groupbit) {
f[i][0] += prefactor *tangent[i][0];
f[i][1] += prefactor *tangent[i][1];
f[i][2] += prefactor *tangent[i][2];
}
if(FreeEndFinal&&ireplica == nreplica -1){
if (tlen > 0.0) {
double dotall;
MPI_Allreduce(&dot,&dotall,1,MPI_DOUBLE,MPI_SUM,world);
dot=dotall;
double tleninv = 1.0/tlen;
dot *= tleninv;
if (dot<0)
prefactor = -dot - (veng-EFinalIni);
else prefactor = -dot + (veng-EFinalIni);
for (int i = 0; i < nlocal; i++)
if (mask[i] & groupbit) {
f[i][0] += prefactor *tangent[i][0];
f[i][1] += prefactor *tangent[i][1];
f[i][2] += prefactor *tangent[i][2];
}
}
}
}
if(FreeEndFinalWithRespToEIni&&ireplica == nreplica -1)
{if (tlen > 0.0) {
double dotall;
MPI_Allreduce(&dot,&dotall,1,MPI_DOUBLE,MPI_SUM,world);
dot=dotall;
double tleninv = 1.0/tlen;
dot *= tleninv;
if (dot<0)
prefactor = -dot - (veng-vIni);
else prefactor = -dot + (veng-vIni);
for (int i = 0; i < nlocal; i++)
if (mask[i] & groupbit) {
f[i][0] += prefactor *tangent[i][0];
f[i][1] += prefactor *tangent[i][1];
f[i][2] += prefactor *tangent[i][2];
}
if(FreeEndFinalWithRespToEIni&&ireplica == nreplica -1){
if (tlen > 0.0) {
double dotall;
MPI_Allreduce(&dot,&dotall,1,MPI_DOUBLE,MPI_SUM,world);
dot=dotall;
double tleninv = 1.0/tlen;
dot *= tleninv;
if (dot<0)
prefactor = -dot - (veng-vIni);
else prefactor = -dot + (veng-vIni);
for (int i = 0; i < nlocal; i++)
if (mask[i] & groupbit) {
f[i][0] += prefactor *tangent[i][0];
f[i][1] += prefactor *tangent[i][1];
f[i][2] += prefactor *tangent[i][2];
}
}
}
}
double lentot = 0;
double meanDist,idealPos,lenuntilIm,lenuntilClimber;
lenuntilClimber=0;
if(NEBLongRange)
{
if (cmode == SINGLE_PROC_DIRECT or cmode == SINGLE_PROC_MAP)
{MPI_Allgather(&nlen,1,MPI_DOUBLE,&nlenall[0],1,MPI_DOUBLE,uworld);}
else
{
/* int procRootiIm;
double nlentmp;
if (cmode == SINGLE_PROC_DIRECT or cmode == SINGLE_PROC_MAP)
{MPI_Allgather(&nlen,1,MPI_DOUBLE,&nlenall[0],1,MPI_DOUBLE,uworld);}
else{
if (me == 0)
MPI_Allgather(&nlen,1,MPI_DOUBLE,&nlenall[0],1,MPI_DOUBLE,rootworld);
for (int iIm = 0; i < nreplica; i++)
{
procRootiIm=universe->root_proc[iIm];
if (ireplica == iIm && me ==0)
{ nlentmp=nlen;
MPI_Bcast(&nlentmp,1,MPI_DOUBLE,procRootiIm,uworld);
}
else
{
MPI_Bcast(&nlentmp,1,MPI_DOUBLE,procRootiIm,uworld);
}
nlenall[iIm]=nlen;
}
*/
if (me == 0)
MPI_Allgather(&nlen,1,MPI_DOUBLE,&nlenall[0],1,MPI_DOUBLE,rootworld);
MPI_Bcast(nlenall,nreplica,MPI_DOUBLE,0,world);
}
MPI_Bcast(nlenall,nreplica,MPI_DOUBLE,0,world);
}
lenuntilIm = 0;
for (int i = 0; i < ireplica; i++)
lenuntilIm += nlenall[i];
lenuntilIm += nlenall[i];
for (int i = 0; i < nreplica; i++)
lentot += nlenall[i];
lentot += nlenall[i];
meanDist = lentot/(nreplica -1);
if (rclimber>0)
{
for (int i = 0; i < rclimber; i++)
lenuntilClimber += nlenall[i];
double meanDistBeforeClimber = lenuntilClimber/rclimber;
double meanDistAfterClimber = (lentot-lenuntilClimber)/(nreplica-rclimber-1);
if (ireplica<rclimber)
idealPos = ireplica * meanDistBeforeClimber;
else
idealPos = lenuntilClimber+ (ireplica-rclimber)*meanDistAfterClimber;
}
if (rclimber>0) {
for (int i = 0; i < rclimber; i++)
lenuntilClimber += nlenall[i];
double meanDistBeforeClimber = lenuntilClimber/rclimber;
double meanDistAfterClimber = (lentot-lenuntilClimber)/(nreplica-rclimber-1);
if (ireplica<rclimber)
idealPos = ireplica * meanDistBeforeClimber;
else
idealPos = lenuntilClimber+ (ireplica-rclimber)*meanDistAfterClimber;
}
else{
idealPos = ireplica * meanDist;
idealPos = ireplica * meanDist;
}
@ -710,14 +653,12 @@ void FixNEB::min_post_force(int vflag)
if (ireplica == 0 || ireplica == nreplica-1) return ;
double AngularContr;
double pi;
double thetapath;
pi = 4.0*atan(1.0);
dotpath = dotpath/(plen*nlen);
AngularContr = 0.5 *(1+cos(pi * dotpath));
AngularContr = 0.5 *(1+cos(MY_PI * dotpath));
@ -725,10 +666,9 @@ AngularContr = 0.5 *(1+cos(pi * dotpath));
dotSpringTangent=0;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit)
{
dot += f[i][0]*tangent[i][0] + f[i][1]*tangent[i][1] + f[i][2]*tangent[i][2];
dotSpringTangent+=springF[i][0]*tangent[i][0]+springF[i][1]*tangent[i][1]+springF[i][2]*tangent[i][2];}
if (mask[i] & groupbit) {
dot += f[i][0]*tangent[i][0] + f[i][1]*tangent[i][1] + f[i][2]*tangent[i][2];
dotSpringTangent+=springF[i][0]*tangent[i][0]+springF[i][1]*tangent[i][1]+springF[i][2]*tangent[i][2];}
}
@ -740,41 +680,32 @@ AngularContr = 0.5 *(1+cos(pi * dotpath));
dot=dotall;
// double prefactor, prefSpring;
double ToDisp;
if (ireplica == rclimber) {
prefactor = -2.0*dot;
}
else {
if(NEBLongRange)
{prefactor = -dot - kspring*(lenuntilIm-idealPos)/(2*meanDist);}
else if (StandardNEB)
{prefactor = -dot + kspring*(nlen-plen);}
if (FinalAndInterWithRespToEIni&& veng<vIni)
{
for (int i = 0; i < nlocal; i++)
if (mask[i] & groupbit) {
f[i][0] = 0;
f[i][1] = 0;
f[i][2] = 0;
}
prefactor = kspring*(nlen-plen);
AngularContr=0;
}
if (FinalAndInterWithRespToEIni&& veng<vIni){
for (int i = 0; i < nlocal; i++)
if (mask[i] & groupbit) {
f[i][0] = 0;
f[i][1] = 0;
f[i][2] = 0;
}
prefactor = kspring*(nlen-plen);
AngularContr=0;
}
}
for (int i = 0; i < nlocal; i++)
if (mask[i] & groupbit) {
f[i][0] += prefactor*tangent[i][0] +AngularContr*(springF[i][0] -dotSpringTangent*tangent[i][0]);
f[i][1] += prefactor*tangent[i][1]+ AngularContr*(springF[i][1] - dotSpringTangent*tangent[i][1]);
f[i][2] += prefactor*tangent[i][2]+ AngularContr*(springF[i][2] - dotSpringTangent*tangent[i][2]);
@ -824,7 +755,6 @@ void FixNEB::inter_replica_comm()
if (ireplica < nreplica-1)
MPI_Send(x[0],3*nlocal,MPI_DOUBLE,procnext,0,uworld);
if (ireplica > 0) MPI_Wait(&request,MPI_STATUS_IGNORE);
if (ireplica < nreplica-1)
MPI_Irecv(xnext[0],3*nlocal,MPI_DOUBLE,procnext,0,uworld,&request);
if (ireplica > 0)
@ -878,7 +808,6 @@ void FixNEB::inter_replica_comm()
xprev[m][2] = xrecv[i][2];
}
}
if (ireplica < nreplica-1) {
MPI_Irecv(xrecv[0],3*nebatoms,MPI_DOUBLE,procnext,0,uworld,&requests[0]);
MPI_Irecv(frecv[0],3*nebatoms,MPI_DOUBLE,procnext,0,uworld,&requests[0]);
@ -1019,11 +948,10 @@ void FixNEB::reallocate()
memory->destroy(fnext);
memory->destroy(springF);
if (NEBLongRange)
{memory->destroy(nlenall);
memory->create(nlenall,nreplica,"neb:nlenall");
}
if (NEBLongRange){
memory->destroy(nlenall);
memory->create(nlenall,nreplica,"neb:nlenall");
}
if (cmode != SINGLE_PROC_DIRECT) {

View File

@ -9,7 +9,7 @@
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
------------------------------------------------------------------------- */
// lmptype.h must be first b/c this file uses MAXBIGINT and includes mpi.h
// due to OpenMPI bug which sets INT64_MAX via its mpi.h
@ -37,8 +37,10 @@
#include "memory.h"
#include "error.h"
#include "force.h"
#include "math_const.h"
using namespace LAMMPS_NS;
using namespace MathConst;
#define MAXLINE 256
#define CHUNK 1024
@ -50,7 +52,7 @@ NEB::NEB(LAMMPS *lmp) : Pointers(lmp) {}
/* ----------------------------------------------------------------------
internal NEB constructor, called from TAD
------------------------------------------------------------------------- */
------------------------------------------------------------------------- */
NEB::NEB(LAMMPS *lmp, double etol_in, double ftol_in, int n1steps_in,
int n2steps_in, int nevery_in, double *buf_init, double *buf_final)
@ -103,7 +105,7 @@ NEB::~NEB()
/* ----------------------------------------------------------------------
perform NEB on multiple replicas
------------------------------------------------------------------------- */
------------------------------------------------------------------------- */
void NEB::command(int narg, char **arg)
{
@ -153,7 +155,7 @@ void NEB::command(int narg, char **arg)
} else if (strcmp(arg[5],"none") == 0) {
if (narg != 6 and narg !=7) error->universe_all(FLERR,"Illegal NEB command");
} else error->universe_all(FLERR,"Illegal NEB command");
Verbose=false;
if (strcmp(arg[narg-1],"verbose") == 0) Verbose=true;
// run the NEB calculation
@ -163,7 +165,7 @@ void NEB::command(int narg, char **arg)
/* ----------------------------------------------------------------------
run NEB on multiple replicas
------------------------------------------------------------------------- */
------------------------------------------------------------------------- */
void NEB::run()
{
@ -215,27 +217,27 @@ void NEB::run()
if (universe->uscreen)
if (Verbose)
fprintf(universe->uscreen,"Step MaxReplicaForce MaxAtomForce "
"GradV0 GradV1 GradVc "
"EBF EBR RDT "
"RD1 PE1 RD2 PE2 ... RDN PEN pathangle1 angletangrad1 anglegrad1 gradV1 ReplicaForce1 MaxAtomForce1 pathangle2 angletangrad2 ... ReplicaForceN MaxAtomForceN\n");
"GradV0 GradV1 GradVc "
"EBF EBR RDT "
"RD1 PE1 RD2 PE2 ... RDN PEN pathangle1 angletangrad1 anglegrad1 gradV1 ReplicaForce1 MaxAtomForce1 pathangle2 angletangrad2 ... ReplicaForceN MaxAtomForceN\n");
else
fprintf(universe->uscreen,"Step MaxReplicaForce MaxAtomForce "
"GradV0 GradV1 GradVc "
"EBF EBR RDT "
"RD1 PE1 RD2 PE2 ... RDN PEN\n");
fprintf(universe->uscreen,"Step MaxReplicaForce MaxAtomForce "
"GradV0 GradV1 GradVc "
"EBF EBR RDT "
"RD1 PE1 RD2 PE2 ... RDN PEN\n");
if (universe->ulogfile)
if (Verbose)
fprintf(universe->ulogfile,"Step MaxReplicaForce MaxAtomForce "
"GradV0 GradV1 GradVc "
"EBF EBR RDT "
"RD1 PE1 RD2 PE2 ... RDN PEN pathangle1 angletangrad1 anglegrad1 gradV1 ReplicaForce1 MaxAtomForce1 pathangle2 angletangrad2 ... ReplicaForceN MaxAtomForceN\n");
"GradV0 GradV1 GradVc "
"EBF EBR RDT "
"RD1 PE1 RD2 PE2 ... RDN PEN pathangle1 angletangrad1 anglegrad1 gradV1 ReplicaForce1 MaxAtomForce1 pathangle2 angletangrad2 ... ReplicaForceN MaxAtomForceN\n");
else
fprintf(universe->ulogfile,"Step MaxReplicaForce MaxAtomForce "
"GradV0 GradV1 GradVc "
"EBF EBR RDT "
"RD1 PE1 RD2 PE2 ... RDN PEN\n");
fprintf(universe->ulogfile,"Step MaxReplicaForce MaxAtomForce "
"GradV0 GradV1 GradVc "
"EBF EBR RDT "
"RD1 PE1 RD2 PE2 ... RDN PEN\n");
}
print_status();
@ -299,26 +301,26 @@ void NEB::run()
if (universe->uscreen)
if (Verbose)
fprintf(universe->uscreen,"Step MaxReplicaForce MaxAtomForce "
"GradV0 GradV1 GradVc "
"EBF EBR RDT "
"RD1 PE1 RD2 PE2 ... RDN PEN pathangle1 angletangrad1 anglegrad1 gradV1 ReplicaForce1 MaxAtomForce1 pathangle2 angletangrad2 ... ReplicaForceN MaxAtomForceN\n");
"GradV0 GradV1 GradVc "
"EBF EBR RDT "
"RD1 PE1 RD2 PE2 ... RDN PEN pathangle1 angletangrad1 anglegrad1 gradV1 ReplicaForce1 MaxAtomForce1 pathangle2 angletangrad2 ... ReplicaForceN MaxAtomForceN\n");
else
fprintf(universe->uscreen,"Step MaxReplicaForce MaxAtomForce "
"GradV0 GradV1 GradVc "
"EBF EBR RDT "
"RD1 PE1 RD2 PE2 ... RDN PEN\n");
"GradV0 GradV1 GradVc "
"EBF EBR RDT "
"RD1 PE1 RD2 PE2 ... RDN PEN\n");
if (universe->ulogfile)
if (Verbose)
fprintf(universe->ulogfile,"Step MaxReplicaForce MaxAtomForce "
"GradV0 GradV1 GradVc "
"EBF EBR RDT "
"RD1 PE1 RD2 PE2 ... RDN PEN pathangle1 angletangrad1 anglegrad1 gradV1 ReplicaForce1 MaxAtomForce1 pathangle2 angletangrad2 ... ReplicaForceN MaxAtomForceN\n");
"GradV0 GradV1 GradVc "
"EBF EBR RDT "
"RD1 PE1 RD2 PE2 ... RDN PEN pathangle1 angletangrad1 anglegrad1 gradV1 ReplicaForce1 MaxAtomForce1 pathangle2 angletangrad2 ... ReplicaForceN MaxAtomForceN\n");
else
fprintf(universe->ulogfile,"Step MaxReplicaForce MaxAtomForce "
"GradV0 GradV1 GradVc "
"EBF EBR RDT "
"RD1 PE1 RD2 PE2 ... RDN PEN\n");
fprintf(universe->ulogfile,"Step MaxReplicaForce MaxAtomForce "
"GradV0 GradV1 GradVc "
"EBF EBR RDT "
"RD1 PE1 RD2 PE2 ... RDN PEN\n");
}
print_status();
@ -351,17 +353,17 @@ void NEB::run()
/* ----------------------------------------------------------------------
read initial config atom coords from file
flag = 0
only first replica opens file and reads it
first replica bcasts lines to all replicas
final replica stores coords
intermediate replicas interpolate from coords
new coord = replica fraction between current and final state
initial replica does nothing
only first replica opens file and reads it
first replica bcasts lines to all replicas
final replica stores coords
intermediate replicas interpolate from coords
new coord = replica fraction between current and final state
initial replica does nothing
flag = 1
each replica (except first) opens file and reads it
each replica stores coords
initial replica does nothing
------------------------------------------------------------------------- */
each replica (except first) opens file and reads it
each replica stores coords
initial replica does nothing
------------------------------------------------------------------------- */
void NEB::readfile(char *file, int flag)
{
@ -524,7 +526,7 @@ void NEB::readfile(char *file, int flag)
/* ----------------------------------------------------------------------
universe proc 0 opens NEB data file
test if gzipped
------------------------------------------------------------------------- */
------------------------------------------------------------------------- */
void NEB::open(char *file)
{
@ -558,7 +560,7 @@ void NEB::open(char *file)
/* ----------------------------------------------------------------------
query fix NEB for info on each replica
universe proc 0 prints current NEB status
------------------------------------------------------------------------- */
------------------------------------------------------------------------- */
void NEB::print_status()
{
@ -568,7 +570,7 @@ void NEB::print_status()
double fnorminf = update->minimize->fnorm_inf();
double fmaxatom;
MPI_Allreduce(&fnorminf,&fmaxatom,1,MPI_DOUBLE,MPI_MAX,roots);
if (Verbose)
{
freplica = new double[nreplica];
@ -585,9 +587,9 @@ void NEB::print_status()
if (Verbose)
{
one[4] = fneb->dotpath;
one[5] = fneb->dottangrad;
one[6] = fneb->dotgrad;
one[4] = fneb->dotpath;
one[5] = fneb->dottangrad;
one[6] = fneb->dotgrad;
}
@ -632,7 +634,7 @@ void NEB::print_status()
ebf = all[irep][0]-all[0][0];
ebr = all[irep][0]-all[nreplica-1][0];
}
double pi=3.14159265;
if (me_universe == 0) {
if (universe->uscreen) {
fprintf(universe->uscreen,BIGINT_FORMAT " %12.8g %12.8g ",
@ -643,10 +645,10 @@ void NEB::print_status()
for (int i = 0; i < nreplica; i++)
fprintf(universe->uscreen,"%12.8g %12.8g ",rdist[i],all[i][0]);
if (Verbose)
{fprintf(universe->uscreen,"%12.5g %12.5g %12.5g %12.5g %12.5g %12.5g",NAN,180-acos(all[0][5])*180/pi,180-acos(all[0][6])*180/pi,all[0][3],freplica[0],fmaxatomInRepl[0]);
{fprintf(universe->uscreen,"%12.5g %12.5g %12.5g %12.5g %12.5g %12.5g",NAN,180-acos(all[0][5])*180/MY_PI,180-acos(all[0][6])*180/MY_PI,all[0][3],freplica[0],fmaxatomInRepl[0]);
for (int i = 1; i < nreplica-1; i++)
fprintf(universe->uscreen,"%12.5g %12.5g %12.5g %12.5g %12.5g %12.5g",180-acos(all[i][4])*180/pi,180-acos(all[i][5])*180/pi,180-acos(all[i][6])*180/pi,all[i][3],freplica[i],fmaxatomInRepl[i]);
fprintf(universe->uscreen,"%12.5g %12.5g %12.5g %12.5g %12.5g %12.5g",NAN,180-acos(all[nreplica-1][5])*180/pi,NAN,all[nreplica-1][3],freplica[nreplica-1],fmaxatomInRepl[nreplica-1]);
fprintf(universe->uscreen,"%12.5g %12.5g %12.5g %12.5g %12.5g %12.5g",180-acos(all[i][4])*180/MY_PI,180-acos(all[i][5])*180/MY_PI,180-acos(all[i][6])*180/MY_PI,all[i][3],freplica[i],fmaxatomInRepl[i]);
fprintf(universe->uscreen,"%12.5g %12.5g %12.5g %12.5g %12.5g %12.5g",NAN,180-acos(all[nreplica-1][5])*180/MY_PI,NAN,all[nreplica-1][3],freplica[nreplica-1],fmaxatomInRepl[nreplica-1]);
}
fprintf(universe->uscreen,"\n");
}
@ -660,10 +662,10 @@ void NEB::print_status()
for (int i = 0; i < nreplica; i++)
fprintf(universe->ulogfile,"%12.8g %12.8g ",rdist[i],all[i][0]);
if (Verbose)
{fprintf(universe->ulogfile,"%12.5g %12.5g %12.5g %12.5g %12.5g %12.5g",NAN,180-acos(all[0][5])*180/pi,180-acos(all[0][6])*180/pi,all[0][3],freplica[0],fmaxatomInRepl[0]);
{fprintf(universe->ulogfile,"%12.5g %12.5g %12.5g %12.5g %12.5g %12.5g",NAN,180-acos(all[0][5])*180/MY_PI,180-acos(all[0][6])*180/MY_PI,all[0][3],freplica[0],fmaxatomInRepl[0]);
for (int i = 1; i < nreplica-1; i++)
fprintf(universe->ulogfile,"%12.5g %12.5g %12.5g %12.5g %12.5g %12.5g",180-acos(all[i][4])*180/pi,180-acos(all[i][5])*180/pi,180-acos(all[i][6])*180/pi,all[i][3],freplica[i],fmaxatomInRepl[i]);
fprintf(universe->ulogfile,"%12.5g %12.5g %12.5g %12.5g %12.5g %12.5g",NAN,180-acos(all[nreplica-1][5])*180/pi,NAN,all[nreplica-1][3],freplica[nreplica-1],fmaxatomInRepl[nreplica-1]);
fprintf(universe->ulogfile,"%12.5g %12.5g %12.5g %12.5g %12.5g %12.5g",180-acos(all[i][4])*180/MY_PI,180-acos(all[i][5])*180/MY_PI,180-acos(all[i][6])*180/MY_PI,all[i][3],freplica[i],fmaxatomInRepl[i]);
fprintf(universe->ulogfile,"%12.5g %12.5g %12.5g %12.5g %12.5g %12.5g",NAN,180-acos(all[nreplica-1][5])*180/MY_PI,NAN,all[nreplica-1][3],freplica[nreplica-1],fmaxatomInRepl[nreplica-1]);
}
fprintf(universe->ulogfile,"\n");
fflush(universe->ulogfile);