649 lines
19 KiB
C++
649 lines
19 KiB
C++
/* ----------------------------------------------------------------------
|
|
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
|
|
http://lammps.sandia.gov, Sandia National Laboratories
|
|
Steve Plimpton, sjplimp@sandia.gov
|
|
|
|
Copyright (2003) Sandia Corporation. Under the terms of Contract
|
|
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
|
|
certain rights in this software. This software is distributed under
|
|
the GNU General Public License.
|
|
|
|
See the README file in the top-level LAMMPS directory.
|
|
------------------------------------------------------------------------- */
|
|
|
|
/* ----------------------------------------------------------------------
|
|
Contributing authors: Stephen Bond (SNL) and
|
|
Andrew Baczewski (Michigan State/SNL)
|
|
------------------------------------------------------------------------- */
|
|
|
|
#include "fix_gld.h"
|
|
#include <mpi.h>
|
|
#include <cmath>
|
|
#include <cstring>
|
|
#include "atom.h"
|
|
#include "force.h"
|
|
#include "update.h"
|
|
#include "respa.h"
|
|
#include "comm.h"
|
|
#include "random_mars.h"
|
|
#include "memory.h"
|
|
#include "error.h"
|
|
#include "group.h"
|
|
|
|
#define GLD_UNIFORM_DISTRO
|
|
|
|
using namespace LAMMPS_NS;
|
|
using namespace FixConst;
|
|
|
|
/* ----------------------------------------------------------------------
|
|
Parses parameters passed to the method, allocates some memory
|
|
------------------------------------------------------------------------- */
|
|
|
|
FixGLD::FixGLD(LAMMPS *lmp, int narg, char **arg) :
|
|
Fix(lmp, narg, arg),
|
|
step_respa(NULL), prony_c(NULL), prony_tau(NULL), s_gld(NULL), random(NULL)
|
|
{
|
|
int narg_min = 8;
|
|
// Check to make sure we have the minimal number of inputs
|
|
if (narg < narg_min) error->all(FLERR,"Illegal fix gld command");
|
|
|
|
time_integrate = 1;
|
|
restart_peratom = 1;
|
|
|
|
// Parse the first set of required input arguments
|
|
// 0 = Fix ID (e.g., 1)
|
|
// 1 = Group ID (e.g., all)
|
|
// 2 = gld (name of this fix)
|
|
// 3 = t_start (Starting target temperature)
|
|
t_start = force->numeric(FLERR,arg[3]);
|
|
|
|
// 4 = t_stop (Stopping target temperature)
|
|
t_stop = force->numeric(FLERR,arg[4]);
|
|
|
|
// 5 = prony_terms (number of terms in Prony series)
|
|
prony_terms = force->inumeric(FLERR,arg[5]);
|
|
|
|
// 6 = seed (random seed)
|
|
int seed = force->inumeric(FLERR,arg[6]);
|
|
|
|
// 7 = series type
|
|
if(strcmp(arg[7],"pprony") == 0) {
|
|
series_type = 1; // series type 1 is 'positive Prony series'
|
|
} else {
|
|
error->all(FLERR,"Fix gld series type must be pprony for now");
|
|
}
|
|
|
|
// Error checking for the first set of required input arguments
|
|
if (seed <= 0) error->all(FLERR,"Illegal fix gld command");
|
|
if (prony_terms <= 0)
|
|
error->all(FLERR,"Fix gld prony terms must be > 0");
|
|
if (t_start < 0)
|
|
error->all(FLERR,"Fix gld start temperature must be >= 0");
|
|
if (t_stop < 0)
|
|
error->all(FLERR,"Fix gld stop temperature must be >= 0");
|
|
if (narg - narg_min < 2*(prony_terms) )
|
|
error->all(FLERR,"Fix gld needs more prony series coefficients");
|
|
|
|
// allocate memory for Prony series force coefficients
|
|
memory->create(prony_c, prony_terms, "gld:prony_c");
|
|
// allocate memory for Prony series timescale coefficients
|
|
memory->create(prony_tau, prony_terms, "gld:prony_tau");
|
|
// allocate memory for Prony series extended variables
|
|
s_gld = NULL;
|
|
grow_arrays(atom->nmax);
|
|
// add callbacks to enable restarts
|
|
atom->add_callback(0);
|
|
atom->add_callback(1);
|
|
|
|
// read in the Prony series coefficients
|
|
int iarg = narg_min;
|
|
int icoeff = 0;
|
|
while (iarg < narg && icoeff < prony_terms) {
|
|
double pc = force->numeric(FLERR,arg[iarg]);
|
|
double ptau = force->numeric(FLERR,arg[iarg+1]);
|
|
|
|
if (pc < 0)
|
|
error->all(FLERR,"Fix gld c coefficients must be >= 0");
|
|
if (ptau <= 0)
|
|
error->all(FLERR,"Fix gld tau coefficients must be > 0");
|
|
|
|
// All atom types to have the same Prony series
|
|
prony_c[icoeff] = pc;
|
|
prony_tau[icoeff] = ptau;
|
|
|
|
icoeff += 1;
|
|
iarg += 2;
|
|
}
|
|
|
|
// initialize Marsaglia RNG with processor-unique seed
|
|
random = new RanMars(lmp,seed + comm->me);
|
|
|
|
// initialize the extended variables
|
|
init_s_gld();
|
|
|
|
// optional arguments
|
|
freezeflag = 0;
|
|
zeroflag = 0;
|
|
|
|
while (iarg < narg) {
|
|
if (strcmp(arg[iarg],"zero") == 0) {
|
|
if (iarg+2 > narg) {
|
|
error->all(FLERR, "Illegal fix gld command");
|
|
}
|
|
if (strcmp(arg[iarg+1],"no") == 0) {
|
|
} else if (strcmp(arg[iarg+1],"yes") == 0) {
|
|
zeroflag = 1;
|
|
} else {
|
|
error->all(FLERR,"Illegal fix gld command");
|
|
}
|
|
iarg += 2;
|
|
}
|
|
else if (strcmp(arg[iarg],"frozen") == 0) {
|
|
if (iarg+2 > narg) {
|
|
error->all(FLERR, "Illegal fix gld command");
|
|
}
|
|
if (strcmp(arg[iarg+1],"no") == 0) {
|
|
} else if (strcmp(arg[iarg+1],"yes") == 0) {
|
|
freezeflag = 1;
|
|
for (int i = 0; i < atom->nlocal; i++) {
|
|
if (atom->mask[i] & groupbit) {
|
|
for (int k = 0; k < 3*prony_terms; k=k+3)
|
|
{
|
|
s_gld[i][k] = 0.0;
|
|
s_gld[i][k+1] = 0.0;
|
|
s_gld[i][k+2] = 0.0;
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
error->all(FLERR, "Illegal fix gld command");
|
|
}
|
|
iarg += 2;
|
|
}
|
|
else error->all(FLERR,"Illegal fix gld command");
|
|
}
|
|
|
|
// Initialize the target temperature
|
|
t_target = t_start;
|
|
}
|
|
|
|
/* ----------------------------------------------------------------------
|
|
Destroys memory allocated by the method
|
|
------------------------------------------------------------------------- */
|
|
|
|
FixGLD::~FixGLD()
|
|
{
|
|
delete random;
|
|
memory->destroy(prony_c);
|
|
memory->destroy(prony_tau);
|
|
memory->destroy(s_gld);
|
|
|
|
// remove callbacks to fix, so atom class stops calling it
|
|
atom->delete_callback(id,0);
|
|
atom->delete_callback(id,1);
|
|
}
|
|
|
|
/* ----------------------------------------------------------------------
|
|
Specifies when the fix is called during the timestep
|
|
------------------------------------------------------------------------- */
|
|
|
|
int FixGLD::setmask()
|
|
{
|
|
int mask = 0;
|
|
mask |= INITIAL_INTEGRATE;
|
|
mask |= FINAL_INTEGRATE;
|
|
mask |= INITIAL_INTEGRATE_RESPA;
|
|
mask |= FINAL_INTEGRATE_RESPA;
|
|
return mask;
|
|
}
|
|
|
|
/* ----------------------------------------------------------------------
|
|
Initialize the method parameters before a run
|
|
------------------------------------------------------------------------- */
|
|
|
|
void FixGLD::init()
|
|
{
|
|
dtv = update->dt;
|
|
dtf = 0.5 * update->dt * force->ftm2v;
|
|
|
|
if (strstr(update->integrate_style,"respa"))
|
|
step_respa = ((Respa *) update->integrate)->step;
|
|
}
|
|
|
|
/* ----------------------------------------------------------------------
|
|
First half of a timestep (V^{n} -> V^{n+1/2}; X^{n} -> X^{n+1})
|
|
------------------------------------------------------------------------- */
|
|
|
|
void FixGLD::initial_integrate(int /*vflag*/)
|
|
{
|
|
double dtfm;
|
|
double ftm2v = force->ftm2v;
|
|
|
|
double fran[3], fsum[3], fsumall[3];
|
|
bigint count;
|
|
|
|
int icoeff;
|
|
|
|
// update v and x of atoms in group
|
|
double **x = atom->x;
|
|
double **v = atom->v;
|
|
double **f = atom->f;
|
|
double *rmass = atom->rmass;
|
|
double *mass = atom->mass;
|
|
int *type = atom->type;
|
|
int *mask = atom->mask;
|
|
int nlocal = atom->nlocal;
|
|
if (igroup == atom->firstgroup) nlocal = atom->nfirst;
|
|
|
|
// set kT to the temperature in mvvv units
|
|
double kT = (force->boltz)*t_target/(force->mvv2e);
|
|
|
|
// zero an accumulator for the total random force
|
|
fsum[0] = fsum[1] = fsum[2] = 0.0;
|
|
|
|
if (rmass) {
|
|
for (int i = 0; i < nlocal; i++)
|
|
if (mask[i] & groupbit) {
|
|
dtfm = dtf / rmass[i];
|
|
// Advance V by dt/2
|
|
v[i][0] += dtfm * f[i][0];
|
|
v[i][1] += dtfm * f[i][1];
|
|
v[i][2] += dtfm * f[i][2];
|
|
for (int k = 0; k < 3*prony_terms; k=k+3) {
|
|
v[i][0] += dtfm * s_gld[i][k];
|
|
v[i][1] += dtfm * s_gld[i][k+1];
|
|
v[i][2] += dtfm * s_gld[i][k+2];
|
|
}
|
|
|
|
// Advance X by dt
|
|
x[i][0] += dtv * v[i][0];
|
|
x[i][1] += dtv * v[i][1];
|
|
x[i][2] += dtv * v[i][2];
|
|
|
|
// Advance S by dt
|
|
icoeff = 0;
|
|
for (int k = 0; k < 3*prony_terms; k=k+3) {
|
|
double theta = exp(-dtv/prony_tau[icoeff]);
|
|
double ck = prony_c[icoeff];
|
|
double vmult = (theta-1.)*ck/ftm2v;
|
|
double rmult = sqrt(2.0*kT*ck/dtv)*(1.-theta)/ftm2v;
|
|
|
|
// random force
|
|
#ifdef GLD_GAUSSIAN_DISTRO
|
|
fran[0] = rmult*random->gaussian();
|
|
fran[1] = rmult*random->gaussian();
|
|
fran[2] = rmult*random->gaussian();
|
|
#endif
|
|
|
|
#ifdef GLD_UNIFORM_DISTRO
|
|
rmult *= sqrt(12.0); // correct variance of uniform distribution
|
|
fran[0] = rmult*(random->uniform() - 0.5);
|
|
fran[1] = rmult*(random->uniform() - 0.5);
|
|
fran[2] = rmult*(random->uniform() - 0.5);
|
|
#endif
|
|
|
|
// sum of random forces
|
|
fsum[0] += fran[0];
|
|
fsum[1] += fran[1];
|
|
fsum[2] += fran[2];
|
|
|
|
s_gld[i][k] *= theta;
|
|
s_gld[i][k+1] *= theta;
|
|
s_gld[i][k+2] *= theta;
|
|
s_gld[i][k] += vmult*v[i][0];
|
|
s_gld[i][k+1] += vmult*v[i][1];
|
|
s_gld[i][k+2] += vmult*v[i][2];
|
|
s_gld[i][k] += fran[0];
|
|
s_gld[i][k+1] += fran[1];
|
|
s_gld[i][k+2] += fran[2];
|
|
|
|
icoeff += 1;
|
|
}
|
|
}
|
|
|
|
} else {
|
|
for (int i = 0; i < nlocal; i++)
|
|
if (mask[i] & groupbit) {
|
|
dtfm = dtf / mass[type[i]];
|
|
// Advance V by dt/2
|
|
v[i][0] += dtfm * f[i][0];
|
|
v[i][1] += dtfm * f[i][1];
|
|
v[i][2] += dtfm * f[i][2];
|
|
for (int k = 0; k < 3*prony_terms; k=k+3) {
|
|
v[i][0] += dtfm * s_gld[i][k];
|
|
v[i][1] += dtfm * s_gld[i][k+1];
|
|
v[i][2] += dtfm * s_gld[i][k+2];
|
|
}
|
|
|
|
// Advance X by dt
|
|
x[i][0] += dtv * v[i][0];
|
|
x[i][1] += dtv * v[i][1];
|
|
x[i][2] += dtv * v[i][2];
|
|
|
|
// Advance S by dt
|
|
icoeff = 0;
|
|
for (int k = 0; k < 3*prony_terms; k=k+3) {
|
|
double theta = exp(-dtv/prony_tau[icoeff]);
|
|
double ck = prony_c[icoeff];
|
|
double vmult = (theta-1.)*ck/ftm2v;
|
|
double rmult = sqrt(2.0*kT*ck/dtv)*(1.-theta)/ftm2v;
|
|
|
|
// random force
|
|
#ifdef GLD_GAUSSIAN_DISTRO
|
|
fran[0] = rmult*random->gaussian();
|
|
fran[1] = rmult*random->gaussian();
|
|
fran[2] = rmult*random->gaussian();
|
|
#endif
|
|
|
|
#ifdef GLD_UNIFORM_DISTRO
|
|
rmult *= sqrt(12.0); // correct variance of uniform distribution
|
|
fran[0] = rmult*(random->uniform() - 0.5);
|
|
fran[1] = rmult*(random->uniform() - 0.5);
|
|
fran[2] = rmult*(random->uniform() - 0.5);
|
|
#endif
|
|
|
|
// sum of random forces
|
|
fsum[0] += fran[0];
|
|
fsum[1] += fran[1];
|
|
fsum[2] += fran[2];
|
|
|
|
s_gld[i][k] *= theta;
|
|
s_gld[i][k+1] *= theta;
|
|
s_gld[i][k+2] *= theta;
|
|
s_gld[i][k] += vmult*v[i][0];
|
|
s_gld[i][k+1] += vmult*v[i][1];
|
|
s_gld[i][k+2] += vmult*v[i][2];
|
|
s_gld[i][k] += fran[0];
|
|
s_gld[i][k+1] += fran[1];
|
|
s_gld[i][k+2] += fran[2];
|
|
|
|
icoeff += 1;
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
// correct the random force, if zeroflag is set
|
|
if (zeroflag) {
|
|
count = group->count(igroup);
|
|
if (count == 0) error->all(FLERR,"Cannot zero gld force for zero atoms");
|
|
|
|
MPI_Allreduce(fsum,fsumall,3,MPI_DOUBLE,MPI_SUM,world);
|
|
fsumall[0] /= (count*prony_terms);
|
|
fsumall[1] /= (count*prony_terms);
|
|
fsumall[2] /= (count*prony_terms);
|
|
for (int i = 0; i < nlocal; i++) {
|
|
if (mask[i] & groupbit) {
|
|
for (int k = 0; k < 3*prony_terms; k=k+3) {
|
|
s_gld[i][k] -= fsumall[0];
|
|
s_gld[i][k+1] -= fsumall[1];
|
|
s_gld[i][k+2] -= fsumall[2];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
/* ----------------------------------------------------------------------
|
|
Second half of a timestep (V^{n+1/2} -> V^{n+1})
|
|
------------------------------------------------------------------------- */
|
|
|
|
void FixGLD::final_integrate()
|
|
{
|
|
double dtfm;
|
|
|
|
// update v of atoms in group
|
|
|
|
double **v = atom->v;
|
|
double **f = atom->f;
|
|
double *rmass = atom->rmass;
|
|
double *mass = atom->mass;
|
|
int *type = atom->type;
|
|
int *mask = atom->mask;
|
|
int nlocal = atom->nlocal;
|
|
if (igroup == atom->firstgroup) nlocal = atom->nfirst;
|
|
|
|
if (rmass) {
|
|
for (int i = 0; i < nlocal; i++)
|
|
if (mask[i] & groupbit) {
|
|
dtfm = dtf / rmass[i];
|
|
v[i][0] += dtfm * f[i][0];
|
|
v[i][1] += dtfm * f[i][1];
|
|
v[i][2] += dtfm * f[i][2];
|
|
for (int k = 0; k < 3*prony_terms; k=k+3) {
|
|
v[i][0] += dtfm * s_gld[i][k];
|
|
v[i][1] += dtfm * s_gld[i][k+1];
|
|
v[i][2] += dtfm * s_gld[i][k+2];
|
|
}
|
|
}
|
|
|
|
} else {
|
|
for (int i = 0; i < nlocal; i++)
|
|
if (mask[i] & groupbit) {
|
|
dtfm = dtf / mass[type[i]];
|
|
v[i][0] += dtfm * f[i][0];
|
|
v[i][1] += dtfm * f[i][1];
|
|
v[i][2] += dtfm * f[i][2];
|
|
for (int k = 0; k < 3*prony_terms; k=k+3) {
|
|
v[i][0] += dtfm * s_gld[i][k];
|
|
v[i][1] += dtfm * s_gld[i][k+1];
|
|
v[i][2] += dtfm * s_gld[i][k+2];
|
|
}
|
|
}
|
|
}
|
|
|
|
// Change the temperature for the next step
|
|
double delta = update->ntimestep - update->beginstep;
|
|
delta /= update->endstep - update->beginstep;
|
|
t_target = t_start + delta * (t_stop - t_start);
|
|
}
|
|
|
|
/* ---------------------------------------------------------------------- */
|
|
|
|
void FixGLD::initial_integrate_respa(int vflag, int ilevel, int /*iloop*/)
|
|
{
|
|
dtv = step_respa[ilevel];
|
|
dtf = 0.5 * step_respa[ilevel] * (force->ftm2v);
|
|
|
|
// innermost level - GLD update of v and x
|
|
// all other levels - GLD update of v
|
|
|
|
if (ilevel == 0) initial_integrate(vflag);
|
|
else final_integrate();
|
|
}
|
|
|
|
/* ---------------------------------------------------------------------- */
|
|
|
|
void FixGLD::final_integrate_respa(int ilevel, int /*iloop*/)
|
|
{
|
|
dtf = 0.5 * step_respa[ilevel] * (force->ftm2v);
|
|
final_integrate();
|
|
}
|
|
|
|
/* ----------------------------------------------------------------------
|
|
Called when a change to the target temperature is requested mid-run
|
|
------------------------------------------------------------------------- */
|
|
|
|
void FixGLD::reset_target(double t_new)
|
|
{
|
|
t_target = t_start = t_stop = t_new;
|
|
}
|
|
|
|
/* ----------------------------------------------------------------------
|
|
Called when a change to the timestep is requested mid-run
|
|
------------------------------------------------------------------------- */
|
|
|
|
void FixGLD::reset_dt()
|
|
{
|
|
// set the time integration constants
|
|
dtv = update->dt;
|
|
dtf = 0.5 * update->dt * (force->ftm2v);
|
|
}
|
|
|
|
/* ----------------------------------------------------------------------
|
|
memory usage of local atom-based arrays
|
|
------------------------------------------------------------------------- */
|
|
|
|
double FixGLD::memory_usage()
|
|
{
|
|
double bytes = atom->nmax*3*prony_terms*sizeof(double);
|
|
return bytes;
|
|
}
|
|
|
|
/* ----------------------------------------------------------------------
|
|
allocate local atom-based arrays
|
|
------------------------------------------------------------------------- */
|
|
|
|
void FixGLD::grow_arrays(int nmax)
|
|
{
|
|
memory->grow(s_gld, nmax, 3*prony_terms,"gld:s_gld");
|
|
}
|
|
|
|
/* ----------------------------------------------------------------------
|
|
copy values within local atom-based arrays
|
|
------------------------------------------------------------------------- */
|
|
|
|
void FixGLD::copy_arrays(int i, int j, int /*delflag*/)
|
|
{
|
|
for (int k = 0; k < 3*prony_terms; k++) {
|
|
s_gld[j][k] = s_gld[i][k];
|
|
}
|
|
}
|
|
|
|
/* ----------------------------------------------------------------------
|
|
Pack extended variables assoc. w/ atom i into buffer for exchange
|
|
with another processor
|
|
------------------------------------------------------------------------- */
|
|
|
|
int FixGLD::pack_exchange(int i, double *buf)
|
|
{
|
|
int m = 0;
|
|
for (int k = 0; k < 3*prony_terms; k++) {
|
|
buf[m++] = s_gld[i][k];
|
|
}
|
|
return m;
|
|
}
|
|
|
|
/* ----------------------------------------------------------------------
|
|
Unpack extended variables from exchange with another processor
|
|
------------------------------------------------------------------------- */
|
|
|
|
int FixGLD::unpack_exchange(int nlocal, double *buf)
|
|
{
|
|
int m = 0;
|
|
for (int k = 0; k < 3*prony_terms; k++) {
|
|
s_gld[nlocal][k] = buf[m++];
|
|
}
|
|
return m;
|
|
}
|
|
|
|
|
|
/* ----------------------------------------------------------------------
|
|
Pack extended variables assoc. w/ atom i into buffer for
|
|
writing to a restart file
|
|
------------------------------------------------------------------------- */
|
|
|
|
int FixGLD::pack_restart(int i, double *buf)
|
|
{
|
|
int m = 0;
|
|
// pack buf[0] this way because other fixes unpack it
|
|
buf[m++] = 3*prony_terms + 1;
|
|
for (int k = 0; k < 3*prony_terms; k=k+3)
|
|
{
|
|
buf[m++] = s_gld[i][k];
|
|
buf[m++] = s_gld[i][k+1];
|
|
buf[m++] = s_gld[i][k+2];
|
|
}
|
|
return m;
|
|
}
|
|
|
|
/* ----------------------------------------------------------------------
|
|
Unpack extended variables to restart the fix from a restart file
|
|
------------------------------------------------------------------------- */
|
|
|
|
void FixGLD::unpack_restart(int nlocal, int nth)
|
|
{
|
|
double **extra = atom->extra;
|
|
|
|
// skip to the nth set of extended variables
|
|
// unpack the Nth first values this way because other fixes pack them
|
|
|
|
int m = 0;
|
|
for (int i = 0; i< nth; i++) m += static_cast<int> (extra[nlocal][m]);
|
|
m++;
|
|
|
|
for (int k = 0; k < 3*prony_terms; k=k+3)
|
|
{
|
|
s_gld[nlocal][k] = extra[nlocal][m++];
|
|
s_gld[nlocal][k+1] = extra[nlocal][m++];
|
|
s_gld[nlocal][k+2] = extra[nlocal][m++];
|
|
}
|
|
}
|
|
|
|
/* ----------------------------------------------------------------------
|
|
Returns the number of items in atomic restart data associated with
|
|
local atom nlocal. Used in determining the total extra data stored by
|
|
fixes on a given processor.
|
|
------------------------------------------------------------------------- */
|
|
|
|
int FixGLD::size_restart(int /*nlocal*/)
|
|
{
|
|
return 3*prony_terms+1;
|
|
}
|
|
|
|
/* ----------------------------------------------------------------------
|
|
Returns the maximum number of items in atomic restart data
|
|
Called in Modify::restart for peratom restart.
|
|
------------------------------------------------------------------------- */
|
|
|
|
int FixGLD::maxsize_restart()
|
|
{
|
|
return 3*prony_terms+1;
|
|
}
|
|
|
|
/* ----------------------------------------------------------------------
|
|
Initializes the extended variables to equilibrium distribution
|
|
at t_start.
|
|
------------------------------------------------------------------------- */
|
|
|
|
void FixGLD::init_s_gld()
|
|
{
|
|
int icoeff;
|
|
double eq_sdev=0.0;
|
|
|
|
// set kT to the temperature in mvvv units
|
|
double kT = (force->boltz)*t_start/(force->mvv2e);
|
|
|
|
#ifdef GLD_GAUSSIAN_DISTRO
|
|
double scale = sqrt(kT)/(force->ftm2v);
|
|
#endif
|
|
|
|
#ifdef GLD_UNIFORM_DISTRO
|
|
double scale = sqrt(12.0*kT)/(force->ftm2v);
|
|
#endif
|
|
|
|
for (int i = 0; i < atom->nlocal; i++) {
|
|
if (atom->mask[i] & groupbit) {
|
|
icoeff = 0;
|
|
for (int k = 0; k < 3*prony_terms; k=k+3) {
|
|
eq_sdev = scale*sqrt(prony_c[icoeff]/prony_tau[icoeff]);
|
|
#ifdef GLD_GAUSSIAN_DISTRO
|
|
s_gld[i][k] = eq_sdev*random->gaussian();
|
|
s_gld[i][k+1] = eq_sdev*random->gaussian();
|
|
s_gld[i][k+2] = eq_sdev*random->gaussian();
|
|
#endif
|
|
|
|
#ifdef GLD_UNIFORM_DISTRO
|
|
s_gld[i][k] = eq_sdev*(random->uniform()-0.5);
|
|
s_gld[i][k+1] = eq_sdev*(random->uniform()-0.5);
|
|
s_gld[i][k+2] = eq_sdev*(random->uniform()-0.5);
|
|
#endif
|
|
icoeff += 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
return;
|
|
}
|