updated and slightly refactored tabulation for vashishta pair style
- tables are now dimensioned by nelements instead of ntypes - tables are only created if used - correctly identify max size of table - add test for illegal cutoff for tabulation - allocated memory for tables is accounted for - add example input using 16-bit tables
This commit is contained in:
76
examples/vashishta/in.indiumphosphide-tabulated
Normal file
76
examples/vashishta/in.indiumphosphide-tabulated
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
# calculate the energy volume curve for InP zincblende
|
||||||
|
|
||||||
|
# define volume range and filename
|
||||||
|
|
||||||
|
variable ndelta equal 100
|
||||||
|
variable volatom_min equal 20.0
|
||||||
|
variable volatom_max equal 29.0
|
||||||
|
variable evsvolfile string evsvol.dat
|
||||||
|
|
||||||
|
# set up cell
|
||||||
|
|
||||||
|
units metal
|
||||||
|
|
||||||
|
boundary p p p
|
||||||
|
|
||||||
|
# setup loop variables for box volume
|
||||||
|
|
||||||
|
variable amin equal ${volatom_min}^(1/3)*2
|
||||||
|
variable delta equal (${volatom_max}-${volatom_min})/${ndelta}
|
||||||
|
variable scale equal (${delta}/v_volatom+1)^(1/3)
|
||||||
|
|
||||||
|
# set up 8 atom InP zincblende unit cell
|
||||||
|
|
||||||
|
lattice diamond ${amin}
|
||||||
|
|
||||||
|
region box prism &
|
||||||
|
0 1 &
|
||||||
|
0 1 &
|
||||||
|
0 1 &
|
||||||
|
0 0 0
|
||||||
|
|
||||||
|
create_box 2 box
|
||||||
|
|
||||||
|
create_atoms 1 box &
|
||||||
|
basis 5 2 &
|
||||||
|
basis 6 2 &
|
||||||
|
basis 7 2 &
|
||||||
|
basis 8 2
|
||||||
|
|
||||||
|
mass 1 114.76
|
||||||
|
mass 2 30.98
|
||||||
|
|
||||||
|
# choose potential
|
||||||
|
|
||||||
|
pair_style vashishta
|
||||||
|
pair_coeff * * InP.vashishta In P
|
||||||
|
pair_modify table 16
|
||||||
|
|
||||||
|
# setup neighbor style
|
||||||
|
|
||||||
|
neighbor 1.0 nsq
|
||||||
|
neigh_modify once no every 1 delay 0 check yes
|
||||||
|
|
||||||
|
# setup output
|
||||||
|
|
||||||
|
thermo_style custom step temp pe press vol
|
||||||
|
thermo_modify norm no
|
||||||
|
variable volatom equal vol/atoms
|
||||||
|
variable eatom equal pe/atoms
|
||||||
|
print "# Volume [A^3/atom] Energy [eV/atom]" file ${evsvolfile}
|
||||||
|
|
||||||
|
# loop over range of volumes
|
||||||
|
|
||||||
|
label loop
|
||||||
|
variable i loop ${ndelta}
|
||||||
|
|
||||||
|
change_box all x scale ${scale} y scale ${scale} z scale ${scale} remap
|
||||||
|
|
||||||
|
# calculate energy
|
||||||
|
# no energy minimization needed for zincblende
|
||||||
|
|
||||||
|
run 0
|
||||||
|
print "${volatom} ${eatom}" append ${evsvolfile}
|
||||||
|
|
||||||
|
next i
|
||||||
|
jump SELF loop
|
||||||
29
examples/vashishta/in.sio2-tabulated
Normal file
29
examples/vashishta/in.sio2-tabulated
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
# test Vashishta potential for quartz
|
||||||
|
|
||||||
|
units metal
|
||||||
|
boundary p p p
|
||||||
|
|
||||||
|
atom_style atomic
|
||||||
|
|
||||||
|
read_data data.quartz
|
||||||
|
|
||||||
|
replicate 4 4 4
|
||||||
|
velocity all create 2000.0 277387 mom yes
|
||||||
|
displace_atoms all move 0.05 0.9 0.4 units box
|
||||||
|
|
||||||
|
pair_style vashishta
|
||||||
|
pair_coeff * * SiO.1990.vashishta Si O
|
||||||
|
pair_modify table 16
|
||||||
|
|
||||||
|
neighbor 0.3 bin
|
||||||
|
neigh_modify delay 10
|
||||||
|
|
||||||
|
fix 1 all nve
|
||||||
|
thermo 10
|
||||||
|
timestep 0.001
|
||||||
|
|
||||||
|
#dump 1 all cfg 10 *.cfg mass type xs ys zs vx vy vz fx fy fz
|
||||||
|
#dump_modify 1 element Si O
|
||||||
|
|
||||||
|
run 100
|
||||||
|
|
||||||
@ -97,9 +97,8 @@ void PairVashishta::modify_params(int narg, char **arg)
|
|||||||
if (iarg+2 > narg) error->all(FLERR,"Illegal pair_modify command");
|
if (iarg+2 > narg) error->all(FLERR,"Illegal pair_modify command");
|
||||||
|
|
||||||
nTablebits = force->inumeric(FLERR,arg[iarg+1]);
|
nTablebits = force->inumeric(FLERR,arg[iarg+1]);
|
||||||
if (nTablebits > sizeof(float)*CHAR_BIT) {
|
if ((nTablebits < 0) || (nTablebits > sizeof(int)*CHAR_BIT-1))
|
||||||
error->all(FLERR,"Too many total bits for bitmapped lookup table");
|
error->all(FLERR,"Illegal interpolation table size");
|
||||||
}
|
|
||||||
|
|
||||||
if (nTablebits == 0) {
|
if (nTablebits == 0) {
|
||||||
useTable = false;
|
useTable = false;
|
||||||
@ -112,11 +111,12 @@ void PairVashishta::modify_params(int narg, char **arg)
|
|||||||
if (iarg+2 > narg) error->all(FLERR,"Illegal pair_modify command");
|
if (iarg+2 > narg) error->all(FLERR,"Illegal pair_modify command");
|
||||||
|
|
||||||
tabinner = force->numeric(FLERR,arg[iarg+1]);
|
tabinner = force->numeric(FLERR,arg[iarg+1]);
|
||||||
|
if (tabinner <= 0.0)
|
||||||
|
error->all(FLERR,"Illegal inner cutoff for tabulation");
|
||||||
iarg += 2;
|
iarg += 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
updateTables();
|
||||||
createTable();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PairVashishta::validateNeigh3Body() {
|
void PairVashishta::validateNeigh3Body() {
|
||||||
@ -129,40 +129,34 @@ void PairVashishta::validateNeigh3Body() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PairVashishta::createTable()
|
void PairVashishta::updateTables()
|
||||||
{
|
{
|
||||||
int ntypes = atom->ntypes+1;
|
memory->destroy(forceTable);
|
||||||
tabinnersq = tabinner*tabinner;
|
memory->destroy(potentialTable);
|
||||||
|
forceTable = NULL;
|
||||||
|
potentialTable = NULL;
|
||||||
|
|
||||||
int ntable = 1;
|
if (!useTable) return;
|
||||||
for (int i = 0; i < nTablebits; i++) ntable *= 2;
|
|
||||||
|
int ntable = 1<<nTablebits;
|
||||||
|
tabinnersq = tabinner*tabinner;
|
||||||
|
|
||||||
deltaR2 = (cutmax*cutmax - tabinnersq) / (ntable-1);
|
deltaR2 = (cutmax*cutmax - tabinnersq) / (ntable-1);
|
||||||
oneOverDeltaR2 = 1.0/deltaR2;
|
oneOverDeltaR2 = 1.0/deltaR2;
|
||||||
|
|
||||||
memory->destroy(forceTable);
|
memory->create(forceTable,nelements,nelements,ntable+1,"pair:vashishta:forceTable");
|
||||||
memory->destroy(potentialTable);
|
memory->create(potentialTable,nelements,nelements,ntable+1,"pair:vashishta:potentialTable");
|
||||||
memory->create(forceTable,ntypes,ntypes,ntable+1,"pair:vashishta:forceTable");
|
|
||||||
memory->create(potentialTable,ntypes,ntypes,ntable+1,"pair:vashishta:potentialTable");
|
|
||||||
|
|
||||||
for (int ii = 0; ii < ntypes; ii++) {
|
for (int i = 0; i < nelements; i++) {
|
||||||
int i = map[ii];
|
for (int j = 0; j < nelements; j++) {
|
||||||
for (int jj = 0; jj < ntypes; jj++) {
|
|
||||||
int j = map[jj];
|
|
||||||
if (i < 0 || j < 0 || ii == 0 || jj == 0) {
|
|
||||||
for(int tableIndex=0; tableIndex<=ntable; tableIndex++) {
|
|
||||||
forceTable[ii][jj][tableIndex] = 0;
|
|
||||||
potentialTable[ii][jj][tableIndex] = 0;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
int ijparam = elem2param[i][j][j];
|
int ijparam = elem2param[i][j][j];
|
||||||
for(int tableIndex=0; tableIndex<=ntable; tableIndex++) {
|
for(int idx=0; idx <= ntable; idx++) {
|
||||||
double rsq = tabinnersq + tableIndex*deltaR2;
|
double rsq = tabinnersq + idx*deltaR2;
|
||||||
double fpair, eng;
|
double fpair, eng;
|
||||||
twobody(¶ms[ijparam], rsq, fpair, 1, eng, false /* Don't ask for tabulated since we are generating it now*/ );
|
// call analytical version of two-body term function
|
||||||
forceTable[ii][jj][tableIndex] = fpair;
|
twobody(¶ms[ijparam], rsq, fpair, 1, eng, false);
|
||||||
potentialTable[ii][jj][tableIndex] = eng;
|
forceTable[i][j][idx] = fpair;
|
||||||
}
|
potentialTable[i][j][idx] = eng;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -642,7 +636,7 @@ void PairVashishta::setup_params()
|
|||||||
if (params[m].r0 > cutmax) cutmax = params[m].r0;
|
if (params[m].r0 > cutmax) cutmax = params[m].r0;
|
||||||
}
|
}
|
||||||
|
|
||||||
createTable();
|
updateTables();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------- */
|
||||||
@ -660,12 +654,12 @@ void PairVashishta::twobody(Param *param, double rsq, double &fforce,
|
|||||||
int tableIndex = (rsq - tabinnersq)*oneOverDeltaR2;
|
int tableIndex = (rsq - tabinnersq)*oneOverDeltaR2;
|
||||||
double fraction = (rsq - tabinnersq)*oneOverDeltaR2 - tableIndex; // double - int will only keep the 0.xxxx part
|
double fraction = (rsq - tabinnersq)*oneOverDeltaR2 - tableIndex; // double - int will only keep the 0.xxxx part
|
||||||
|
|
||||||
double force0 = forceTable[param->ielement+1][param->jelement+1][tableIndex];
|
double force0 = forceTable[param->ielement][param->jelement][tableIndex];
|
||||||
double force1 = forceTable[param->ielement+1][param->jelement+1][tableIndex+1];
|
double force1 = forceTable[param->ielement][param->jelement][tableIndex+1];
|
||||||
fforce = (1.0 - fraction)*force0 + fraction*force1; // force is linearly interpolated between the two values
|
fforce = (1.0 - fraction)*force0 + fraction*force1; // force is linearly interpolated between the two values
|
||||||
if(evflag) {
|
if(evflag) {
|
||||||
double energy0 = potentialTable[param->ielement+1][param->jelement+1][tableIndex];
|
double energy0 = potentialTable[param->ielement][param->jelement][tableIndex];
|
||||||
double energy1 = potentialTable[param->ielement+1][param->jelement+1][tableIndex+1];
|
double energy1 = potentialTable[param->ielement][param->jelement][tableIndex+1];
|
||||||
eng = (1.0 - fraction)*energy0 + fraction*energy1;
|
eng = (1.0 - fraction)*energy0 + fraction*energy1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -747,3 +741,15 @@ void PairVashishta::threebody(Param *paramij, Param *paramik, Param *paramijk,
|
|||||||
|
|
||||||
if (eflag) eng = facrad;
|
if (eflag) eng = facrad;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------------
|
||||||
|
* add memory usage for tabulation
|
||||||
|
* ---------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
double PairVashishta::memory_usage()
|
||||||
|
{
|
||||||
|
double bytes = Pair::memory_usage();
|
||||||
|
if (useTable)
|
||||||
|
bytes += 2*nelements*nelements*sizeof(double)*(1<<nTablebits);
|
||||||
|
return bytes;
|
||||||
|
}
|
||||||
|
|||||||
@ -34,6 +34,7 @@ class PairVashishta : public Pair {
|
|||||||
void coeff(int, char **);
|
void coeff(int, char **);
|
||||||
virtual double init_one(int, int);
|
virtual double init_one(int, int);
|
||||||
virtual void init_style();
|
virtual void init_style();
|
||||||
|
virtual double memory_usage();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
struct Param {
|
struct Param {
|
||||||
@ -71,7 +72,7 @@ class PairVashishta : public Pair {
|
|||||||
virtual void allocate();
|
virtual void allocate();
|
||||||
void read_file(char *);
|
void read_file(char *);
|
||||||
void setup_params();
|
void setup_params();
|
||||||
void createTable();
|
void updateTables();
|
||||||
void validateNeigh3Body();
|
void validateNeigh3Body();
|
||||||
void twobody(Param *, double, double &, int, double &, bool tabulated = false);
|
void twobody(Param *, double, double &, int, double &, bool tabulated = false);
|
||||||
void threebody(Param *, Param *, Param *, double, double, double *, double *,
|
void threebody(Param *, Param *, Param *, double, double, double *, double *,
|
||||||
|
|||||||
Reference in New Issue
Block a user