Merge pull request #718 from timattox/USER-DPD_es_RNG

USER-DPD: External State RNG
This commit is contained in:
Steve Plimpton 2018-01-08 09:13:11 -07:00 committed by GitHub
commit 3bb8294f31
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 305 additions and 119 deletions

1
src/.gitignore vendored
View File

@ -547,6 +547,7 @@
/fix_shake.h
/fix_shardlow.cpp
/fix_shardlow.h
/random_external_state.h
/fix_smd.cpp
/fix_smd.h
/fix_species.cpp

View File

@ -61,6 +61,7 @@
using namespace LAMMPS_NS;
using namespace FixConst;
using namespace random_external_state;
#define EPSILON 1.0e-10
#define EPSILON_SQUARED ((EPSILON) * (EPSILON))
@ -89,10 +90,6 @@ FixShardlowKokkos<DeviceType>::FixShardlowKokkos(LAMMPS *lmp, int narg, char **a
// if(k_pairDPDE){
comm_forward = 3;
comm_reverse = 5;
maxRNG = 0;
#ifdef DPD_USE_RAN_MARS
pp_random = NULL;
#endif
// } else {
// comm_forward = 3;
// comm_reverse = 3;
@ -121,13 +118,6 @@ template<class DeviceType>
FixShardlowKokkos<DeviceType>::~FixShardlowKokkos()
{
ghostmax = 0;
#ifdef DPD_USE_RAN_MARS
if (pp_random) {
for (int i = 1; i < maxRNG; ++i) delete pp_random[i];
delete[] pp_random;
pp_random = NULL;
}
#endif
}
/* ---------------------------------------------------------------------- */
@ -279,11 +269,7 @@ void FixShardlowKokkos<DeviceType>::ssa_update_dpd(
int start_ii, int count, int id
)
{
#ifdef DPD_USE_RAN_MARS
class RanMars *pRNG = pp_random[id];
#else
rand_type rand_gen = rand_pool.get_state(id);
#endif
es_RNG_t RNGstate = d_rand_state(id);
int ct = count;
int ii = start_ii;
@ -345,12 +331,7 @@ void FixShardlowKokkos<DeviceType>::ssa_update_dpd(
double halfsigma_ij = STACKPARAMS?m_params[itype][jtype].halfsigma:params(itype,jtype).halfsigma;
double halfgamma_ij = halfsigma_ij*halfsigma_ij*boltz_inv*theta_ij_inv;
double sigmaRand = halfsigma_ij*wr*dtsqrt*ftm2v *
#ifdef DPD_USE_RAN_MARS
pRNG->gaussian();
#else
rand_gen.normal();
#endif
double sigmaRand = halfsigma_ij*wr*dtsqrt*ftm2v * es_normal(RNGstate);
const double mass_j = masses(massPerI ? j : jtype);
double massinv_j = 1.0 / mass_j;
@ -412,9 +393,7 @@ void FixShardlowKokkos<DeviceType>::ssa_update_dpd(
v(i, 2) = vzi;
}
#ifndef DPD_USE_RAN_MARS
rand_pool.free_state(rand_gen);
#endif
d_rand_state(id) = RNGstate;
}
#endif
@ -431,11 +410,7 @@ void FixShardlowKokkos<DeviceType>::ssa_update_dpde(
int start_ii, int count, int id
) const
{
#ifdef DPD_USE_RAN_MARS
class RanMars *pRNG = pp_random[id];
#else
rand_type rand_gen = rand_pool.get_state(id);
#endif
es_RNG_t RNGstate = d_rand_state(id);
int ct = count;
int ii = start_ii;
@ -506,12 +481,7 @@ void FixShardlowKokkos<DeviceType>::ssa_update_dpde(
double halfsigma_ij = STACKPARAMS?m_params[itype][jtype].halfsigma:params(itype,jtype).halfsigma;
double halfgamma_ij = halfsigma_ij*halfsigma_ij*boltz_inv*theta_ij_inv;
double sigmaRand = halfsigma_ij*wr*dtsqrt*ftm2v *
#ifdef DPD_USE_RAN_MARS
pRNG->gaussian();
#else
rand_gen.normal();
#endif
double sigmaRand = halfsigma_ij*wr*dtsqrt*ftm2v * es_normal(RNGstate);
const double mass_j = masses(massPerI ? j : jtype);
double mass_ij_div_neg4_ftm2v = mass_j*mass_i_div_neg4_ftm2v;
@ -520,12 +490,7 @@ void FixShardlowKokkos<DeviceType>::ssa_update_dpde(
// Compute uCond
double kappa_ij = STACKPARAMS?m_params[itype][jtype].kappa:params(itype,jtype).kappa;
double alpha_ij = STACKPARAMS?m_params[itype][jtype].alpha:params(itype,jtype).alpha;
double del_uCond = alpha_ij*wr*dtsqrt *
#ifdef DPD_USE_RAN_MARS
pRNG->gaussian();
#else
rand_gen.normal();
#endif
double del_uCond = alpha_ij*wr*dtsqrt * es_normal(RNGstate);
del_uCond += kappa_ij*(theta_i_inv - theta_j_inv)*wdt;
uCond[j] -= del_uCond;
@ -601,9 +566,7 @@ void FixShardlowKokkos<DeviceType>::ssa_update_dpde(
ii++;
}
#ifndef DPD_USE_RAN_MARS
rand_pool.free_state(rand_gen);
#endif
d_rand_state(id) = RNGstate;
}
@ -644,20 +607,16 @@ void FixShardlowKokkos<DeviceType>::initial_integrate(int vflag)
maxWorkItemCt = (int) ssa_gitemLoc.dimension_1();
}
if (maxWorkItemCt > maxRNG) {
#ifdef DPD_USE_RAN_MARS
if (pp_random) {
for (int i = 1; i < maxRNG; ++i) delete pp_random[i];
delete[] pp_random;
pp_random = NULL;
es_RNG_t serial_rand_state;
es_init(serial_rand_state, pairDPDE->seed + comm->me);
d_rand_state = es_RNGs_type("Kokkos::fix_shardlow::rand_state",maxWorkItemCt);
typename es_RNGs_type::HostMirror h_rand_state = create_mirror_view(d_rand_state);
for (int i = 0; i < maxWorkItemCt; ++i) {
es_genNextParallelState(serial_rand_state, h_rand_state(i));
}
pp_random = new RanMars*[maxWorkItemCt];
for (int i = 1; i < maxWorkItemCt; ++i) {
pp_random[i] = new RanMars(lmp, k_pairDPDE->seed + comm->me + comm->nprocs*i);
}
pp_random[0] = k_pairDPDE->random;
#else
rand_pool.init(k_pairDPDE->seed + comm->me, maxWorkItemCt);
#endif
deep_copy(d_rand_state,h_rand_state);
maxRNG = maxWorkItemCt;
}

View File

@ -93,17 +93,6 @@ class FixShardlowKokkos : public FixShardlow {
#endif
PairDPDfdtEnergyKokkos<DeviceType> *k_pairDPDE;
int maxRNG;
#ifdef DPD_USE_RAN_MARS
class RanMars **pp_random;
#elif defined(DPD_USE_Random_XorShift1024)
Kokkos::Random_XorShift1024_Pool<DeviceType> rand_pool;
typedef typename Kokkos::Random_XorShift1024_Pool<DeviceType>::generator_type rand_type;
#else
Kokkos::Random_XorShift64_Pool<DeviceType> rand_pool;
typedef typename Kokkos::Random_XorShift64_Pool<DeviceType>::generator_type rand_type;
#endif
Kokkos::DualView<params_ssa**,Kokkos::LayoutRight,DeviceType> k_params;
typename Kokkos::DualView<params_ssa**,
Kokkos::LayoutRight,DeviceType>::t_dev_const_um params;
@ -127,6 +116,10 @@ class FixShardlowKokkos : public FixShardlow {
typename AT::t_float_1d_randomread masses;
typename AT::t_efloat_1d dpdTheta;
// Storage for the es_RNG state variables
typedef Kokkos::View<random_external_state::es_RNG_t*,DeviceType> es_RNGs_type;
es_RNGs_type d_rand_state;
double dtsqrt; // = sqrt(update->dt);
int ghostmax;
int nlocal, nghost;

View File

@ -48,7 +48,6 @@
#include "neighbor.h"
#include "neigh_list.h"
#include "neigh_request.h"
#include "random_mars.h"
#include "memory.h"
#include "domain.h"
#include "modify.h"
@ -60,6 +59,7 @@
using namespace LAMMPS_NS;
using namespace FixConst;
using namespace random_external_state;
#define EPSILON 1.0e-10
#define EPSILON_SQUARED ((EPSILON) * (EPSILON))
@ -87,6 +87,7 @@ static const char cite_fix_shardlow[] =
FixShardlow::FixShardlow(LAMMPS *lmp, int narg, char **arg) :
Fix(lmp, narg, arg), pairDPD(NULL), pairDPDE(NULL), v_t0(NULL)
,rand_state(NULL)
{
if (lmp->citeme) lmp->citeme->add(cite_fix_shardlow);
@ -99,6 +100,7 @@ FixShardlow::FixShardlow(LAMMPS *lmp, int narg, char **arg) :
if (pairDPDE == NULL)
pairDPDE = (PairDPDfdtEnergy *) force->pair_match("dpd/fdt/energy/kk",1);
maxRNG = 0;
if(pairDPDE){
comm_forward = 3;
comm_reverse = 5;
@ -116,6 +118,8 @@ FixShardlow::FixShardlow(LAMMPS *lmp, int narg, char **arg) :
FixShardlow::~FixShardlow()
{
memory->destroy(rand_state);
maxRNG = 0;
}
/* ---------------------------------------------------------------------- */
@ -173,12 +177,12 @@ void FixShardlow::setup(int vflag)
NOTE: only implemented for orthogonal boxes, not triclinic
------------------------------------------------------------------------- */
void FixShardlow::ssa_update_dpd(
int i,
int *jlist,
int jlen
int start_ii,
int count,
int id
)
{
class RanMars *pRNG;
es_RNG_t RNGstate = rand_state[id];
double **x = atom->x;
double **v = atom->v;
double *rmass = atom->rmass;
@ -192,6 +196,16 @@ void FixShardlow::ssa_update_dpd(
const double dt = update->dt;
int ct = count;
int ii = start_ii;
while (ct-- > 0) {
const int i = list->ilist[ii];
const int *jlist = list->firstneigh[ii];
const int jlen = list->numneigh[ii];
ii++;
if (jlen <= 0) continue;
const double xtmp = x[i][0];
const double ytmp = x[i][1];
const double ztmp = x[i][2];
@ -203,7 +217,6 @@ void FixShardlow::ssa_update_dpd(
int itype = type[i];
pRNG = pairDPD->random;
cut2_i = pairDPD->cutsq[itype];
cut_i = pairDPD->cut[itype];
sigma_i = pairDPD->sigma[itype];
@ -254,7 +267,7 @@ void FixShardlow::ssa_update_dpd(
double halfsigma_ij = 0.5*sigma_i[jtype];
double halfgamma_ij = halfsigma_ij*halfsigma_ij*boltz_inv*theta_ij_inv;
double sigmaRand = halfsigma_ij*wr*dtsqrt*ftm2v * pRNG->gaussian();
double sigmaRand = halfsigma_ij*wr*dtsqrt*ftm2v * es_normal(RNGstate);
double mass_j = (rmass) ? rmass[j] : mass[jtype];
double massinv_j = 1.0 / mass_j;
@ -316,6 +329,9 @@ void FixShardlow::ssa_update_dpd(
v[i][2] = vzi;
}
rand_state[id] = RNGstate;
}
/* ----------------------------------------------------------------------
Perform the stochastic integration and Shardlow update for constant energy
Allow for both per-type and per-atom mass
@ -323,12 +339,12 @@ void FixShardlow::ssa_update_dpd(
NOTE: only implemented for orthogonal boxes, not triclinic
------------------------------------------------------------------------- */
void FixShardlow::ssa_update_dpde(
int i,
int *jlist,
int jlen
int start_ii,
int count,
int id
)
{
class RanMars *pRNG;
es_RNG_t RNGstate = rand_state[id];
double **x = atom->x;
double **v = atom->v;
double *rmass = atom->rmass;
@ -346,6 +362,16 @@ void FixShardlow::ssa_update_dpde(
const double dt = update->dt;
int ct = count;
int ii = start_ii;
while (ct-- > 0) {
const int i = list->ilist[ii];
const int *jlist = list->firstneigh[ii];
const int jlen = list->numneigh[ii];
ii++;
if (jlen <= 0) continue;
const double xtmp = x[i][0];
const double ytmp = x[i][1];
const double ztmp = x[i][2];
@ -359,7 +385,6 @@ void FixShardlow::ssa_update_dpde(
double uCond_i = uCond[i];
int itype = type[i];
pRNG = pairDPDE->random;
cut2_i = pairDPDE->cutsq[itype];
cut_i = pairDPDE->cut[itype];
sigma_i = pairDPDE->sigma[itype];
@ -415,7 +440,7 @@ void FixShardlow::ssa_update_dpde(
double halfsigma_ij = 0.5*sigma_i[jtype];
double halfgamma_ij = halfsigma_ij*halfsigma_ij*boltz_inv*theta_ij_inv;
double sigmaRand = halfsigma_ij*wr*dtsqrt*ftm2v * pRNG->gaussian();
double sigmaRand = halfsigma_ij*wr*dtsqrt*ftm2v * es_normal(RNGstate);
double mass_j = (rmass) ? rmass[j] : mass[jtype];
double mass_ij_div_neg4_ftm2v = mass_j*mass_i_div_neg4_ftm2v;
@ -424,7 +449,7 @@ void FixShardlow::ssa_update_dpde(
// Compute uCond
double kappa_ij = kappa_i[jtype];
double alpha_ij = sqrt(boltz2*kappa_ij);
double del_uCond = alpha_ij*wr*dtsqrt * pRNG->gaussian();
double del_uCond = alpha_ij*wr*dtsqrt * es_normal(RNGstate);
del_uCond += kappa_ij*(theta_i_inv - theta_j_inv)*wdt;
uCond[j] -= del_uCond;
@ -499,6 +524,9 @@ void FixShardlow::ssa_update_dpde(
uCond[i] = uCond_i;
}
rand_state[id] = RNGstate;
}
void FixShardlow::initial_integrate(int vflag)
{
int i,ii,inum;
@ -507,7 +535,6 @@ void FixShardlow::initial_integrate(int vflag)
int nlocal = atom->nlocal;
int nghost = atom->nghost;
int airnum;
const bool useDPDE = (pairDPDE != NULL);
// NOTE: this logic is specific to orthogonal boxes, not triclinic
@ -530,6 +557,31 @@ void FixShardlow::initial_integrate(int vflag)
error->one(FLERR, msg);
}
NPairHalfBinNewtonSSA *np_ssa = dynamic_cast<NPairHalfBinNewtonSSA*>(list->np);
if (!np_ssa) error->one(FLERR, "NPair wasn't a NPairHalfBinNewtonSSA object");
int ssa_phaseCt = np_ssa->ssa_phaseCt;
int *ssa_phaseLen = np_ssa->ssa_phaseLen;
int **ssa_itemLoc = np_ssa->ssa_itemLoc;
int **ssa_itemLen = np_ssa->ssa_itemLen;
int ssa_gphaseCt = np_ssa->ssa_gphaseCt;
int *ssa_gphaseLen = np_ssa->ssa_gphaseLen;
int **ssa_gitemLoc = np_ssa->ssa_gitemLoc;
int **ssa_gitemLen = np_ssa->ssa_gitemLen;
int maxWorkItemCt = np_ssa->ssa_maxPhaseLen;
if (maxWorkItemCt > maxRNG) {
uint64_t my_seed = comm->me + (useDPDE ? pairDPDE->seed : pairDPD->seed);
es_RNG_t serial_rand_state;
es_init(serial_rand_state, my_seed);
memory->grow(rand_state, maxWorkItemCt, "FixShardlow:rand_state");
for (int i = 0; i < maxWorkItemCt; ++i) {
es_genNextParallelState(serial_rand_state, rand_state[i]);
}
maxRNG = maxWorkItemCt;
}
#ifdef DEBUG_SSA_PAIR_CT
for (int i = 0; i < 2; ++i)
for (int j = 0; j < 3; ++j)
@ -545,13 +597,6 @@ void FixShardlow::initial_integrate(int vflag)
dtsqrt = sqrt(update->dt);
NPairHalfBinNewtonSSA *np_ssa = dynamic_cast<NPairHalfBinNewtonSSA*>(list->np);
if (!np_ssa) error->one(FLERR, "NPair wasn't a NPairHalfBinNewtonSSA object");
int ssa_phaseCt = np_ssa->ssa_phaseCt;
int *ssa_phaseLen = np_ssa->ssa_phaseLen;
int **ssa_itemLoc = np_ssa->ssa_itemLoc;
int **ssa_itemLen = np_ssa->ssa_itemLen;
// process neighbors in the local AIR
for (int workPhase = 0; workPhase < ssa_phaseCt; ++workPhase) {
int workItemCt = ssa_phaseLen[workPhase];
@ -559,22 +604,14 @@ void FixShardlow::initial_integrate(int vflag)
for (int workItem = 0; workItem < workItemCt; ++workItem) {
int ct = ssa_itemLen[workPhase][workItem];
ii = ssa_itemLoc[workPhase][workItem];
while (ct-- > 0) {
int len = list->numneigh[ii];
if (len > 0) {
if (useDPDE) ssa_update_dpde(ilist[ii], list->firstneigh[ii], len);
else ssa_update_dpd(ilist[ii], list->firstneigh[ii], len);
}
ii++;
}
if (useDPDE) ssa_update_dpde(ii, ct, workItem);
else ssa_update_dpd(ii, ct, workItem);
}
}
ii = inum;
//Loop over all 13 outward directions (7 stages)
for (airnum = 1; airnum <=7; airnum++){
int ct = list->AIRct_ssa[airnum];
for (int workPhase = 0; workPhase < ssa_gphaseCt; ++workPhase) {
int workItemCt = ssa_gphaseLen[workPhase];
// Communicate the updated velocities to all nodes
comm->forward_comm_fix(this);
@ -585,12 +622,11 @@ void FixShardlow::initial_integrate(int vflag)
memset(&(atom->uMech[nlocal]), 0, sizeof(double)*nghost);
}
// process neighbors in this AIR
while (ct-- > 0) {
int len = list->numneigh[ii];
if (useDPDE) ssa_update_dpde(ilist[ii], list->firstneigh[ii], len);
else ssa_update_dpd(ilist[ii], list->firstneigh[ii], len);
ii++;
for (int workItem = 0; workItem < workItemCt; ++workItem) {
int ct = ssa_gitemLen[workPhase][workItem];
ii = ssa_gitemLoc[workPhase][workItem];
if (useDPDE) ssa_update_dpde(ii, ct, workItem);
else ssa_update_dpd(ii, ct, workItem);
}
// Communicate the ghost deltas to the atom owners
@ -699,6 +735,7 @@ double FixShardlow::memory_usage()
{
double bytes = 0.0;
bytes += sizeof(double)*3*atom->nghost; // v_t0[]
bytes += sizeof(*rand_state)*maxRNG; // rand_state[]
return bytes;
}

View File

@ -21,6 +21,8 @@ FixStyle(shardlow,FixShardlow)
#define LMP_FIX_SHARDLOW_H
#include "fix.h"
#include "random_external_state.h"
#include <math.h>
namespace LAMMPS_NS {
@ -52,12 +54,14 @@ class FixShardlow : public Fix {
class PairDPDfdt *pairDPD;
class PairDPDfdtEnergy *pairDPDE;
double (*v_t0)[3];
int maxRNG;
private:
random_external_state::es_RNG_t *rand_state;
double dtsqrt; // = sqrt(update->dt);
void ssa_update_dpd(int, int *, int); // Constant Temperature
void ssa_update_dpde(int, int *, int); // Constant Energy
void ssa_update_dpd(int, int, int); // Constant Temperature
void ssa_update_dpde(int, int, int); // Constant Energy
};

View File

@ -42,6 +42,10 @@ NPairHalfBinNewtonSSA::NPairHalfBinNewtonSSA(LAMMPS *lmp) : NPair(lmp)
ssa_phaseLen = NULL;
ssa_itemLoc = NULL;
ssa_itemLen = NULL;
ssa_gphaseCt = 7;
memory->create(ssa_gphaseLen,ssa_gphaseCt,"NPairHalfBinNewtonSSA:ssa_gphaseLen");
memory->create(ssa_gitemLoc,ssa_gphaseCt,1,"NPairHalfBinNewtonSSA:ssa_gitemLoc");
memory->create(ssa_gitemLen,ssa_gphaseCt,1,"NPairHalfBinNewtonSSA:ssa_gitemLen");
}
/* ---------------------------------------------------------------------- */
@ -54,6 +58,10 @@ NPairHalfBinNewtonSSA::~NPairHalfBinNewtonSSA()
memory->destroy(ssa_phaseLen);
memory->destroy(ssa_itemLoc);
memory->destroy(ssa_itemLen);
ssa_gphaseCt = 0;
memory->destroy(ssa_gphaseLen);
memory->destroy(ssa_gitemLoc);
memory->destroy(ssa_gitemLen);
}
/* ----------------------------------------------------------------------
@ -236,13 +244,14 @@ void NPairHalfBinNewtonSSA::build(NeighList *list)
if (ssa_phaseCt != workPhase) error->one(FLERR,"ssa_phaseCt was wrong");
list->AIRct_ssa[0] = list->inum = inum;
list->inum = inum;
// loop over AIR ghost atoms, storing their local neighbors
// since these are ghosts, must check if stencil bin is out of bounds
for (int airnum = 1; airnum <= 7; airnum++) {
for (workPhase = 0; workPhase < ssa_gphaseCt; workPhase++) {
int locAIRct = 0;
for (i = gairhead_ssa[airnum]; i >= 0; i = bins[i]) {
ssa_gitemLoc[workPhase][0] = inum + gnum; // record where workItem starts in ilist
for (i = gairhead_ssa[workPhase+1]; i >= 0; i = bins[i]) {
n = 0;
neighptr = ipage->vget();
@ -305,7 +314,8 @@ void NPairHalfBinNewtonSSA::build(NeighList *list)
if (ipage->status())
error->one(FLERR,"Neighbor (ghost) list overflow, boost neigh_modify one");
}
list->AIRct_ssa[airnum] = locAIRct;
ssa_gitemLen[workPhase][0] = locAIRct;
ssa_gphaseLen[workPhase] = 1;
}
list->gnum = gnum;
}

View File

@ -33,13 +33,18 @@ class NPairHalfBinNewtonSSA : public NPair {
int *ssa_phaseLen;
int **ssa_itemLoc;
int **ssa_itemLen;
int ssa_gphaseCt;
int *ssa_gphaseLen;
int **ssa_gitemLoc;
int **ssa_gitemLen;
int ssa_maxPhaseLen;
NPairHalfBinNewtonSSA(class LAMMPS *);
~NPairHalfBinNewtonSSA();
void build(class NeighList *);
private:
int ssa_maxPhaseCt;
int ssa_maxPhaseLen;
};
}

View File

@ -44,11 +44,11 @@ class PairDPDfdt : public Pair {
double **sigma;
double temperature;
int seed;
class RanMars *random;
protected:
double cut_global;
int seed;
bool splitFDT_flag;
bool a0_is_zero;

View File

@ -0,0 +1,179 @@
/* -*- 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.
------------------------------------------------------------------------- */
/*
This random_external_state.h file was derrived from the Kokkos
file algorithms/src/Kokkos_Random.hpp and adapted to work
without Kokkos installed, as well as being converted to a form
that has no internal state. All RNG state information is kept
outside this "class", and is passed in by reference by the caller.
*/
/*
//@HEADER
// ************************************************************************
//
// Kokkos v. 2.0
// Copyright (2014) Sandia Corporation
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the Corporation nor the names of the
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov)
//
// ************************************************************************
//@HEADER
*/
#ifndef LMP_RANDOM_EXTERNALSTATE_H
#define LMP_RANDOM_EXTERNALSTATE_H
#include <math.h>
#include "accelerator_kokkos.h"
#ifdef LMP_KOKKOS
#define RND_INLINE KOKKOS_INLINE_FUNCTION
#else
#define RND_INLINE inline
#endif
/// \file random_external_state.h
/// \brief Pseudorandom number generators
///
/// These generators are based on Vigna, Sebastiano (2014). "An
/// experimental exploration of Marsaglia's xorshift generators,
/// scrambled." See: http://arxiv.org/abs/1402.6246
// A replacement for the Kokkos Random_XorShift64 class that uses
// an external state variable, instead of a class member variable.
namespace random_external_state {
typedef uint64_t es_RNG_t;
enum {MAX_URAND = 0xffffffffU};
enum {MAX_URAND64 = 0xffffffffffffffffULL-1};
RND_INLINE
uint32_t es_urand(es_RNG_t &state_) {
state_ ^= state_ >> 12;
state_ ^= state_ << 25;
state_ ^= state_ >> 27;
es_RNG_t tmp = state_ * 2685821657736338717ULL;
tmp = tmp>>16;
return static_cast<uint32_t>(tmp&MAX_URAND);
}
RND_INLINE
uint64_t es_urand64(es_RNG_t &state_) {
state_ ^= state_ >> 12;
state_ ^= state_ << 25;
state_ ^= state_ >> 27;
return (state_ * 2685821657736338717ULL) - 1;
}
RND_INLINE
int es_rand(es_RNG_t &state_) {
return static_cast<int>(es_urand(state_)/2);
}
RND_INLINE
double es_drand(es_RNG_t &state_) {
return 1.0 * es_urand64(state_)/MAX_URAND64;
}
//Marsaglia polar method for drawing a standard normal distributed random number
RND_INLINE
double es_normal(es_RNG_t &state_) {
double S, U;
do {
U = 2.0*es_drand(state_) - 1.0;
const double V = 2.0*es_drand(state_) - 1.0;
S = U*U+V*V;
} while ((S >= 1.0) || (S == 0.0));
return U*sqrt(-2.0*log(S)/S);
}
RND_INLINE
double es_normalPair(es_RNG_t &state_, double &second) {
double S, U, V;
do {
U = 2.0*es_drand(state_) - 1.0;
V = 2.0*es_drand(state_) - 1.0;
S = U*U+V*V;
} while ((S >= 1.0) || (S == 0.0));
const double fac = sqrt(-2.0*log(S)/S);
second = V*fac;
return U*fac;
}
// Use es_init() to init a serial RNG, that is then
// used to generate the initial state of your k parallel
// RNGs with k calls to genNextParallelState()
RND_INLINE
void es_init(es_RNG_t &serial_state, uint64_t seed) {
if(seed==0) seed = uint64_t(1318319);
serial_state = seed;
for(int i = 0; i < 17; i++) es_rand(serial_state);
}
// Call genNextParallelState() once for each RNG to generate
// the initial state for that RNG.
RND_INLINE
void es_genNextParallelState(es_RNG_t &serial_state, es_RNG_t &new_state) {
int n1 = es_rand(serial_state);
int n2 = es_rand(serial_state);
int n3 = es_rand(serial_state);
int n4 = es_rand(serial_state);
new_state = ((((static_cast<es_RNG_t>(n1)) & 0xffff)<<00) |
(((static_cast<es_RNG_t>(n2)) & 0xffff)<<16) |
(((static_cast<es_RNG_t>(n3)) & 0xffff)<<32) |
(((static_cast<es_RNG_t>(n4)) & 0xffff)<<48));
}
}
#endif
/* ERROR/WARNING messages:
E: Invalid seed for Marsaglia random # generator
The initial seed for this random number generator must be a positive
integer less than or equal to 900 million.
*/

View File

@ -88,7 +88,6 @@ NeighList::NeighList(LAMMPS *lmp) : Pointers(lmp)
// USER-DPD package
for (int i = 0; i < 8; i++) AIRct_ssa[i] = 0;
np = NULL;
}

View File

@ -92,7 +92,6 @@ class NeighList : protected Pointers {
// USER-DPD package and Shardlow Splitting Algorithm (SSA) support
int AIRct_ssa[8]; // count of how many atoms in each AIR
class NPair *np; // ptr to NPair instance I depend on
// methods