Add relax_box function. Adapted documentation.

This commit is contained in:
Julien Guénolé
2017-08-11 13:39:13 +02:00
parent 8053375a72
commit d156263f54
6 changed files with 119 additions and 6 deletions

View File

@ -28,7 +28,10 @@ keyword = {dmax} or {line} or {delaystep} or {dt_grow} or {dt_shrink}
{tmin} value = {float} for adaptglok {tmin} value = {float} for adaptglok
{integrator} value = {eulerimplicit} or {eulerexplicit} or {verlet} {integrator} value = {eulerimplicit} or {eulerexplicit} or {verlet}
or {leapfrog} for adaptglok or {leapfrog} for adaptglok
{halfstepback} value = {yes} or {no} for adaptglok :pre {halfstepback} value = {yes} or {no} for adaptglok :pre
{relaxbox} value = {no} or {iso} or {axial} for adaptglok
{relaxbox_modulus} value = {float} for adaptglok
{relaxbox_rate} value = {float} for adaptglok
:ule :ule
[Examples:] [Examples:]
@ -84,6 +87,12 @@ to adapt them for particular cases.
In particular for debugging purpose, it is possible to switch off the In particular for debugging purpose, it is possible to switch off the
the backstep when downhill, by using and {halfstepback}. the backstep when downhill, by using and {halfstepback}.
The style {adaptglok} allows for a basic box relaxation to a stress-free
state by choosing {relaxbox} {iso} or {axial}. One should give an
approximated value for the bulk modulus {relaxbox_modulus} of the system.
The default value of the relaxation rate {relaxbox_rate} should be
optimum in most situations.
[Restrictions:] none [Restrictions:] none
[Related commands:] [Related commands:]
@ -94,4 +103,5 @@ the backstep when downhill, by using and {halfstepback}.
The option defaults are dmax = 0.1, line = quadratic, integrator = eulerimplicit, delaystep = 20, The option defaults are dmax = 0.1, line = quadratic, integrator = eulerimplicit, delaystep = 20,
dt_grow = 1.1, dt_shrink = 0.5, alpha0 = 0.25, alpha_shrink = 0.99, dt_grow = 1.1, dt_shrink = 0.5, alpha0 = 0.25, alpha_shrink = 0.99,
tmax = 2.0, tmin = 0.02, adaptstep = yes and halfstepback = yes. tmax = 2.0, tmin = 0.02, adaptstep = yes, halfstepback = yes,
relaxbox = no, relaxbox_modulus = 1000000 and relaxbox_rate = 0.33.

View File

@ -66,6 +66,8 @@ fit the published and unpublished optimizations of the method described
in "(Bitzek)"_#Bitzek. It includes a temporization of the variable in "(Bitzek)"_#Bitzek. It includes a temporization of the variable
timestep, a backstep when downhill and different integration timestep, a backstep when downhill and different integration
schemes. schemes.
Note that a basic scheme for having a stress-free simulation box is
implemented within that style.
Either the {quickmin} and {fire} styles are useful in the context of Either the {quickmin} and {fire} styles are useful in the context of
nudged elastic band (NEB) calculations via the "neb"_neb.html command. nudged elastic band (NEB) calculations via the "neb"_neb.html command.

View File

@ -63,7 +63,10 @@ Min::Min(LAMMPS *lmp) : Pointers(lmp)
tmax = 2.0; tmax = 2.0;
tmin = 0.02; tmin = 0.02;
integrator = 0; integrator = 0;
relaxbox_modulus = 1000000;
relaxbox_rate = 0.33;
halfstepback_flag = 1; halfstepback_flag = 1;
relaxbox_flag = 0;
elist_global = elist_atom = NULL; elist_global = elist_atom = NULL;
vlist_global = vlist_atom = NULL; vlist_global = vlist_atom = NULL;
@ -687,6 +690,21 @@ void Min::modify_params(int narg, char **arg)
else if (strcmp(arg[iarg+1],"no") == 0) halfstepback_flag = 0; else if (strcmp(arg[iarg+1],"no") == 0) halfstepback_flag = 0;
else error->all(FLERR,"Illegal min_modify command"); else error->all(FLERR,"Illegal min_modify command");
iarg += 2; iarg += 2;
} else if (strcmp(arg[iarg],"relaxbox") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal min_modify command");
if (strcmp(arg[iarg+1],"no") == 0) relaxbox_flag = 0;
else if (strcmp(arg[iarg+1],"iso") == 0) relaxbox_flag = 1;
else if (strcmp(arg[iarg+1],"axial") == 0) relaxbox_flag = 2;
else error->all(FLERR,"Illegal min_modify command");
iarg += 2;
} else if (strcmp(arg[iarg],"relaxbox_modulus") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal min_modify command");
relaxbox_modulus = force->numeric(FLERR,arg[iarg+1]);
iarg += 2;
} else if (strcmp(arg[iarg],"relaxbox_rate") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal min_modify command");
relaxbox_rate = force->numeric(FLERR,arg[iarg+1]);
iarg += 2;
} else if (strcmp(arg[iarg],"integrator") == 0) { } else if (strcmp(arg[iarg],"integrator") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal min_modify command"); if (iarg+2 > narg) error->all(FLERR,"Illegal min_modify command");
if (strcmp(arg[iarg+1],"eulerimplicit") == 0) integrator = 0; if (strcmp(arg[iarg+1],"eulerimplicit") == 0) integrator = 0;

View File

@ -63,7 +63,10 @@ class Min : protected Pointers {
double alpha0,alpha_shrink; // mixing velocities+forces coefficient (adaptglok) double alpha0,alpha_shrink; // mixing velocities+forces coefficient (adaptglok)
double tmax,tmin; // timestep max, min (adaptglok) double tmax,tmin; // timestep max, min (adaptglok)
int integrator; // choose the style of time integrator (adaptglok) int integrator; // choose the style of time integrator (adaptglok)
double relaxbox_modulus; // Bulk modulus used for box relax (for adaptglok)
double relaxbox_rate; // for box relaxation to 0 pressure (for adaptglok)
int halfstepback_flag; // 1: half step backward when v.f <= 0.0 (adaptglok) int halfstepback_flag; // 1: half step backward when v.f <= 0.0 (adaptglok)
int relaxbox_flag; // 1: box relaxation iso; 2: axial
int nelist_global,nelist_atom; // # of PE,virial computes to check int nelist_global,nelist_atom; // # of PE,virial computes to check
int nvlist_global,nvlist_atom; int nvlist_global,nvlist_atom;

View File

@ -20,6 +20,10 @@
#include "output.h" #include "output.h"
#include "timer.h" #include "timer.h"
#include "error.h" #include "error.h"
#include "variable.h"
#include "modify.h"
#include "compute.h"
#include "domain.h"
using namespace LAMMPS_NS; using namespace LAMMPS_NS;
@ -42,6 +46,13 @@ void MinAdaptGlok::init()
dtmin = tmin * dt; dtmin = tmin * dt;
alpha = alpha0; alpha = alpha0;
last_negative = ntimestep_fire = update->ntimestep; last_negative = ntimestep_fire = update->ntimestep;
if (relaxbox_flag){
int icompute = modify->find_compute("thermo_temp");
temperature = modify->compute[icompute];
icompute = modify->find_compute("thermo_press");
pressure = modify->compute[icompute];
}
} }
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
@ -69,6 +80,68 @@ void MinAdaptGlok::reset_vectors()
if (nvec) fvec = atom->f[0]; if (nvec) fvec = atom->f[0];
} }
/* ----------------------------------------------------------------------
save current box state for converting atoms to lamda coords
------------------------------------------------------------------------- */
void MinAdaptGlok::save_box_state()
{
boxlo[0] = domain->boxlo[0];
boxlo[1] = domain->boxlo[1];
boxlo[2] = domain->boxlo[2];
for (int i = 0; i < 6; i++)
h_inv[i] = domain->h_inv[i];
}
/* ----------------------------------------------------------------------
deform the simulation box and remap the particles
------------------------------------------------------------------------- */
void MinAdaptGlok::relax_box()
{
int i,n;
// rescale simulation box from linesearch starting point
// scale atom coords for all atoms or only for fix group atoms
double **x = atom->x;
double epsilon;
double *current_pressure_v;
int *mask = atom->mask;
n = atom->nlocal + atom->nghost;
save_box_state();
// convert pertinent atoms and rigid bodies to lamda coords
domain->x2lamda(n);
// ensure the virial is tallied
update->vflag_global = update->ntimestep;
// compute pressure and change simulation box
pressure->compute_scalar();
pressure->compute_vector();
epsilon = pressure->scalar / relaxbox_modulus;
current_pressure_v = pressure->vector;
for (int i = 0; i < 3; i++) {
if (relaxbox_flag == 2) epsilon = current_pressure_v[i] / relaxbox_modulus;
domain->boxhi[i] += domain->boxhi[i] * epsilon * relaxbox_rate;;
}
// reset global and local box to new size/shape
domain->set_global_box();
domain->set_local_box();
// convert atoms and back to box coords
domain->lamda2x(n);
save_box_state();
}
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
int MinAdaptGlok::iterate(int maxiter) int MinAdaptGlok::iterate(int maxiter)
@ -123,7 +196,11 @@ int MinAdaptGlok::iterate(int maxiter)
ntimestep = ++update->ntimestep; ntimestep = ++update->ntimestep;
niter++; niter++;
// vdotfall = v dot f // Relax the simulation box
if (relaxbox_flag) relax_box();
// vdotfall = v dot f
// Euler || Leap Frog integration // Euler || Leap Frog integration
@ -132,6 +209,7 @@ int MinAdaptGlok::iterate(int maxiter)
double **f = atom->f; double **f = atom->f;
} }
int nlocal = atom->nlocal; int nlocal = atom->nlocal;
double **x = atom->x;
vdotf = 0.0; vdotf = 0.0;
for (int i = 0; i < nlocal; i++) for (int i = 0; i < nlocal; i++)
@ -243,9 +321,7 @@ int MinAdaptGlok::iterate(int maxiter)
MPI_Allreduce(&dtvone,&dtv,1,MPI_DOUBLE,MPI_MIN,universe->uworld); MPI_Allreduce(&dtvone,&dtv,1,MPI_DOUBLE,MPI_MIN,universe->uworld);
} }
double **x = atom->x; // Semi-implicit Euler integration
// Semi-implicit Euler integration
if (integrator == 0) { if (integrator == 0) {

View File

@ -31,12 +31,16 @@ class MinAdaptGlok : public Min {
void init(); void init();
void setup_style(); void setup_style();
void reset_vectors(); void reset_vectors();
void save_box_state();
void relax_box();
int iterate(int); int iterate(int);
private: private:
double dt,dtmax,dtmin,dtinit; double dt,dtmax,dtmin,dtinit;
double alpha; double alpha;
bigint last_negative,ntimestep_fire; bigint last_negative,ntimestep_fire;
class Compute *temperature,*pressure;
double boxlo[3],h_inv[6];
}; };
} }