git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@13757 f3b2605a-c512-4ea7-a41b-209d697bcdaa
This commit is contained in:
@ -12,6 +12,7 @@
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
#include "stdlib.h"
|
||||
#include "string.h"
|
||||
#include "fix_respa.h"
|
||||
#include "atom.h"
|
||||
#include "force.h"
|
||||
@ -29,10 +30,18 @@ FixRespa::FixRespa(LAMMPS *lmp, int narg, char **arg) :
|
||||
|
||||
nlevels = force->inumeric(FLERR,arg[3]);
|
||||
|
||||
// optional arguments
|
||||
store_torque = 0;
|
||||
for (int iarg=4; iarg < narg; ++iarg) {
|
||||
if (strcmp(arg[iarg],"torque") == 0)
|
||||
store_torque = 1;
|
||||
}
|
||||
|
||||
// perform initial allocation of atom-based arrays
|
||||
// register with Atom class
|
||||
|
||||
f_level = NULL;
|
||||
t_level = NULL;
|
||||
grow_arrays(atom->nmax);
|
||||
atom->add_callback(0);
|
||||
}
|
||||
@ -48,6 +57,7 @@ FixRespa::~FixRespa()
|
||||
// delete locally stored arrays
|
||||
|
||||
memory->destroy(f_level);
|
||||
if (store_torque) memory->destroy(t_level);
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
@ -64,6 +74,7 @@ int FixRespa::setmask()
|
||||
double FixRespa::memory_usage()
|
||||
{
|
||||
double bytes = atom->nmax*nlevels*3 * sizeof(double);
|
||||
if (store_torque) bytes += atom->nmax*nlevels*3 * sizeof(double);
|
||||
return bytes;
|
||||
}
|
||||
|
||||
@ -74,6 +85,7 @@ double FixRespa::memory_usage()
|
||||
void FixRespa::grow_arrays(int nmax)
|
||||
{
|
||||
memory->grow(f_level,nmax,nlevels,3,"fix_respa:f_level");
|
||||
if (store_torque) memory->grow(t_level,nmax,nlevels,3,"fix_respa:t_level");
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
@ -87,6 +99,13 @@ void FixRespa::copy_arrays(int i, int j, int delflag)
|
||||
f_level[j][k][1] = f_level[i][k][1];
|
||||
f_level[j][k][2] = f_level[i][k][2];
|
||||
}
|
||||
if (store_torque) {
|
||||
for (int k = 0; k < nlevels; k++) {
|
||||
t_level[j][k][0] = t_level[i][k][0];
|
||||
t_level[j][k][1] = t_level[i][k][1];
|
||||
t_level[j][k][2] = t_level[i][k][2];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
@ -101,6 +120,13 @@ int FixRespa::pack_exchange(int i, double *buf)
|
||||
buf[m++] = f_level[i][k][1];
|
||||
buf[m++] = f_level[i][k][2];
|
||||
}
|
||||
if (store_torque) {
|
||||
for (int k = 0; k < nlevels; k++) {
|
||||
buf[m++] = t_level[i][k][0];
|
||||
buf[m++] = t_level[i][k][1];
|
||||
buf[m++] = t_level[i][k][2];
|
||||
}
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
@ -116,5 +142,12 @@ int FixRespa::unpack_exchange(int nlocal, double *buf)
|
||||
f_level[nlocal][k][1] = buf[m++];
|
||||
f_level[nlocal][k][2] = buf[m++];
|
||||
}
|
||||
if (store_torque) {
|
||||
for (int k = 0; k < nlevels; k++) {
|
||||
t_level[nlocal][k][0] = buf[m++];
|
||||
t_level[nlocal][k][1] = buf[m++];
|
||||
t_level[nlocal][k][2] = buf[m++];
|
||||
}
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
@ -43,7 +43,9 @@ class FixRespa : public Fix {
|
||||
|
||||
private:
|
||||
int nlevels;
|
||||
int store_torque; // 1 if torques should be stored in addition to forces
|
||||
double ***f_level; // force at each rRESPA level
|
||||
double ***t_level; // torque at each rRESPA level
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@ -25,6 +25,7 @@
|
||||
#include "comm.h"
|
||||
#include "memory.h"
|
||||
#include "error.h"
|
||||
#include "respa.h"
|
||||
|
||||
using namespace LAMMPS_NS;
|
||||
|
||||
@ -36,8 +37,11 @@ PairHybrid::PairHybrid(LAMMPS *lmp) : Pair(lmp)
|
||||
styles = NULL;
|
||||
keywords = NULL;
|
||||
multiple = NULL;
|
||||
special_lj = NULL;
|
||||
special_coul = NULL;
|
||||
|
||||
outerflag = 0;
|
||||
respaflag = 0;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
@ -45,13 +49,20 @@ PairHybrid::PairHybrid(LAMMPS *lmp) : Pair(lmp)
|
||||
PairHybrid::~PairHybrid()
|
||||
{
|
||||
if (nstyles) {
|
||||
for (int m = 0; m < nstyles; m++) delete styles[m];
|
||||
for (int m = 0; m < nstyles; m++) delete [] keywords[m];
|
||||
for (int m = 0; m < nstyles; m++) {
|
||||
delete styles[m];
|
||||
delete [] keywords[m];
|
||||
if (special_lj[m]) delete [] special_lj[m];
|
||||
if (special_coul[m]) delete [] special_coul[m];
|
||||
}
|
||||
}
|
||||
delete [] styles;
|
||||
delete [] keywords;
|
||||
delete [] multiple;
|
||||
|
||||
delete [] special_lj;
|
||||
delete [] special_coul;
|
||||
|
||||
delete [] svector;
|
||||
|
||||
if (allocated) {
|
||||
@ -98,8 +109,22 @@ void PairHybrid::compute(int eflag, int vflag)
|
||||
if (vflag % 4 == 2) vflag_substyle = vflag/4 * 4;
|
||||
else vflag_substyle = vflag;
|
||||
|
||||
double *saved_special = save_special();
|
||||
|
||||
// check if we are running with r-RESPA using the hybrid keyword
|
||||
|
||||
Respa *respa = NULL;
|
||||
if (strstr(update->integrate_style,"respa")) {
|
||||
respa = (Respa *) update->integrate;
|
||||
if (respa->nhybrid_styles > 0) respaflag = 1;
|
||||
}
|
||||
|
||||
for (m = 0; m < nstyles; m++) {
|
||||
|
||||
set_special(m);
|
||||
|
||||
if (!respaflag || (respaflag && respa->hybrid_compute[m])) {
|
||||
|
||||
// invoke compute() unless compute flag is turned off or
|
||||
// outerflag is set and sub-style has a compute_outer() method
|
||||
|
||||
@ -107,6 +132,13 @@ void PairHybrid::compute(int eflag, int vflag)
|
||||
if (outerflag && styles[m]->respa_enable)
|
||||
styles[m]->compute_outer(eflag,vflag_substyle);
|
||||
else styles[m]->compute(eflag,vflag_substyle);
|
||||
}
|
||||
|
||||
restore_special(saved_special);
|
||||
|
||||
// jump to next sub-style if r-RESPA does not want global accumulated data
|
||||
|
||||
if (respaflag && !respa->tally_global) continue;
|
||||
|
||||
if (eflag_global) {
|
||||
eng_vdwl += styles[m]->eng_vdwl;
|
||||
@ -131,6 +163,8 @@ void PairHybrid::compute(int eflag, int vflag)
|
||||
}
|
||||
}
|
||||
|
||||
delete [] saved_special;
|
||||
|
||||
if (vflag_fdotr) virial_fdotr_compute();
|
||||
}
|
||||
|
||||
@ -215,6 +249,9 @@ void PairHybrid::settings(int narg, char **arg)
|
||||
keywords = new char*[narg];
|
||||
multiple = new int[narg];
|
||||
|
||||
special_lj = new double*[narg];
|
||||
special_coul = new double*[narg];
|
||||
|
||||
// allocate each sub-style
|
||||
// allocate uses suffix, but don't store suffix version in keywords,
|
||||
// else syntax in coeff() will not match
|
||||
@ -233,6 +270,7 @@ void PairHybrid::settings(int narg, char **arg)
|
||||
|
||||
styles[nstyles] = force->new_pair(arg[iarg],1,dummy);
|
||||
force->store_style(keywords[nstyles],arg[iarg],0);
|
||||
special_lj[nstyles] = special_coul[nstyles] = NULL;
|
||||
|
||||
jarg = iarg + 1;
|
||||
while (jarg < narg && !force->pair_map->count(arg[jarg])) jarg++;
|
||||
@ -421,6 +459,28 @@ void PairHybrid::init_style()
|
||||
if (used == 0) error->all(FLERR,"Pair hybrid sub-style is not used");
|
||||
}
|
||||
|
||||
// check if special_lj/special_coul overrides are compatible
|
||||
for (istyle = 0; istyle < nstyles; istyle++) {
|
||||
if (special_lj[istyle]) {
|
||||
for (i = 1; i < 4; ++i) {
|
||||
if (((force->special_lj[i] == 0.0) || (force->special_lj[i] == 1.0))
|
||||
&& (force->special_lj[i] != special_lj[istyle][i]))
|
||||
error->all(FLERR,"Pair_modify special setting incompatible with"
|
||||
" global special_bonds setting");
|
||||
}
|
||||
}
|
||||
|
||||
if (special_coul[istyle]) {
|
||||
for (i = 1; i < 4; ++i) {
|
||||
if (((force->special_coul[i] == 0.0)
|
||||
|| (force->special_coul[i] == 1.0))
|
||||
&& (force->special_coul[i] != special_coul[istyle][i]))
|
||||
error->all(FLERR,"Pair_modify special setting incompatible with"
|
||||
"global special_bonds setting");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// each sub-style makes its neighbor list request(s)
|
||||
|
||||
for (istyle = 0; istyle < nstyles; istyle++) styles[istyle]->init_style();
|
||||
@ -610,6 +670,13 @@ void PairHybrid::write_restart(FILE *fp)
|
||||
fwrite(&n,sizeof(int),1,fp);
|
||||
fwrite(keywords[m],sizeof(char),n,fp);
|
||||
styles[m]->write_restart_settings(fp);
|
||||
// write out per style special settings, if present
|
||||
n = (special_lj[m] == NULL) ? 0 : 1;
|
||||
fwrite(&n,sizeof(int),1,fp);
|
||||
if (n) fwrite(special_lj[m],sizeof(double),4,fp);
|
||||
n = (special_coul[m] == NULL) ? 0 : 1;
|
||||
fwrite(&n,sizeof(int),1,fp);
|
||||
if (n) fwrite(special_coul[m],sizeof(double),4,fp);
|
||||
}
|
||||
}
|
||||
|
||||
@ -629,6 +696,9 @@ void PairHybrid::read_restart(FILE *fp)
|
||||
keywords = new char*[nstyles];
|
||||
multiple = new int[nstyles];
|
||||
|
||||
special_lj = new double*[nstyles];
|
||||
special_coul = new double*[nstyles];
|
||||
|
||||
// each sub-style is created via new_pair()
|
||||
// each reads its settings, but no coeff info
|
||||
|
||||
@ -641,6 +711,22 @@ void PairHybrid::read_restart(FILE *fp)
|
||||
MPI_Bcast(keywords[m],n,MPI_CHAR,0,world);
|
||||
styles[m] = force->new_pair(keywords[m],0,dummy);
|
||||
styles[m]->read_restart_settings(fp);
|
||||
// read back per style special settings, if present
|
||||
special_lj[m] = special_coul[m] = NULL;
|
||||
if (me == 0) fread(&n,sizeof(int),1,fp);
|
||||
MPI_Bcast(&n,1,MPI_INT,0,world);
|
||||
if (n > 0 ) {
|
||||
special_lj[m] = new double[4];
|
||||
if (me == 0) fread(special_lj[m],sizeof(double),4,fp);
|
||||
MPI_Bcast(special_lj[m],4,MPI_DOUBLE,0,world);
|
||||
}
|
||||
if (me == 0) fread(&n,sizeof(int),1,fp);
|
||||
MPI_Bcast(&n,1,MPI_INT,0,world);
|
||||
if (n > 0 ) {
|
||||
special_coul[m] = new double[4];
|
||||
if (me == 0) fread(special_coul[m],sizeof(double),4,fp);
|
||||
MPI_Bcast(special_coul[m],4,MPI_DOUBLE,0,world);
|
||||
}
|
||||
}
|
||||
|
||||
// multiple[i] = 1 to M if sub-style used multiple times, else 0
|
||||
@ -681,6 +767,11 @@ double PairHybrid::single(int i, int j, int itype, int jtype,
|
||||
if (styles[map[itype][jtype][m]]->single_enable == 0)
|
||||
error->one(FLERR,"Pair hybrid sub-style does not support single call");
|
||||
|
||||
if ((special_lj[map[itype][jtype][m]] != NULL) ||
|
||||
(special_coul[map[itype][jtype][m]] != NULL))
|
||||
error->one(FLERR,"Pair hybrid single calls do not support"
|
||||
" per sub-style special bond values");
|
||||
|
||||
esum += styles[map[itype][jtype][m]]->
|
||||
single(i,j,itype,jtype,rsq,factor_coul,factor_lj,fone);
|
||||
fforce += fone;
|
||||
@ -716,8 +807,14 @@ void PairHybrid::modify_params(int narg, char **arg)
|
||||
if (strcmp(arg[1],keywords[m]) == 0) break;
|
||||
if (m == nstyles) error->all(FLERR,"Unknown pair_modify hybrid sub-style");
|
||||
if (multiple[m] == 0) {
|
||||
// augment special settings for this one pair style
|
||||
if (strcmp(arg[2],"special") == 0) {
|
||||
if (narg < 7) error->all(FLERR,"Illegal pair_modify special command");
|
||||
modify_special(m,narg-3,&arg[3]);
|
||||
} else {
|
||||
Pair::modify_params(narg-2,&arg[2]);
|
||||
styles[m]->modify_params(narg-2,&arg[2]);
|
||||
}
|
||||
} else {
|
||||
if (narg < 3) error->all(FLERR,"Illegal pair_modify command");
|
||||
int multiflag = force->inumeric(FLERR,arg[2]);
|
||||
@ -725,15 +822,100 @@ void PairHybrid::modify_params(int narg, char **arg)
|
||||
if (strcmp(arg[1],keywords[m]) == 0 && multiflag == multiple[m]) break;
|
||||
if (m == nstyles)
|
||||
error->all(FLERR,"Unknown pair_modify hybrid sub-style");
|
||||
// augment special settings for this one pair style
|
||||
if (strcmp(arg[3],"special") == 0) {
|
||||
if (narg < 8) error->all(FLERR,"Illegal pair_modify special command");
|
||||
modify_special(m,narg-4,&arg[4]);
|
||||
} else {
|
||||
Pair::modify_params(narg-3,&arg[3]);
|
||||
styles[m]->modify_params(narg-3,&arg[3]);
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
// augment special settings for all pair styles
|
||||
if (strcmp(arg[0],"special") == 0) {
|
||||
if (narg < 5) error->all(FLERR,"Illegal pair_modify special command");
|
||||
for (int m = 0; m < nstyles; m++) modify_special(m,narg-1,&arg[1]);
|
||||
} else {
|
||||
Pair::modify_params(narg,arg);
|
||||
for (int m = 0; m < nstyles; m++) styles[m]->modify_params(narg,arg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
store a local per pair style override for special_lj and special_coul
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void PairHybrid::modify_special(int m, int narg, char **arg)
|
||||
{
|
||||
double special[4];
|
||||
int i;
|
||||
|
||||
special[0] = 1.0;
|
||||
special[1] = force->numeric(FLERR,arg[1]);
|
||||
special[2] = force->numeric(FLERR,arg[2]);
|
||||
special[3] = force->numeric(FLERR,arg[3]);
|
||||
|
||||
if (strcmp(arg[0],"lj/coul") == 0) {
|
||||
if (!special_lj[m]) special_lj[m] = new double[4];
|
||||
if (!special_coul[m]) special_coul[m] = new double[4];
|
||||
for (i = 0; i < 4; ++i)
|
||||
special_lj[m][i] = special_coul[m][i] = special[i];
|
||||
|
||||
} else if (strcmp(arg[0],"lj") == 0) {
|
||||
if (!special_lj[m]) special_lj[m] = new double[4];
|
||||
for (i = 0; i < 4; ++i)
|
||||
special_lj[m][i] = special[i];
|
||||
|
||||
} else if (strcmp(arg[0],"coul") == 0) {
|
||||
if (!special_coul[m]) special_coul[m] = new double[4];
|
||||
for (i = 0; i < 4; ++i)
|
||||
special_coul[m][i] = special[i];
|
||||
|
||||
} else error->all(FLERR,"Illegal pair_modify special command");
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
override global special bonds settings with per substyle values
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void PairHybrid::set_special(int m)
|
||||
{
|
||||
int i;
|
||||
if (special_lj[m])
|
||||
for (i = 0; i < 4; ++i) force->special_lj[i] = special_lj[m][i];
|
||||
if (special_coul[m])
|
||||
for (i = 0; i < 4; ++i) force->special_coul[i] = special_coul[m][i];
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
store global special settings
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
double * PairHybrid::save_special()
|
||||
{
|
||||
double *saved = new double[8];
|
||||
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
saved[i] = force->special_lj[i];
|
||||
saved[i+4] = force->special_coul[i];
|
||||
}
|
||||
return saved;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
restore global special settings from saved data
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void PairHybrid::restore_special(double *saved)
|
||||
{
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
force->special_lj[i] = saved[i];
|
||||
force->special_coul[i] = saved[i+4];
|
||||
}
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
extract a ptr to a particular quantity stored by pair
|
||||
|
||||
@ -26,12 +26,11 @@ PairStyle(hybrid,PairHybrid)
|
||||
namespace LAMMPS_NS {
|
||||
|
||||
class PairHybrid : public Pair {
|
||||
friend class FixGPU;
|
||||
friend class FixOMP;
|
||||
friend class Force;
|
||||
friend class Respa;
|
||||
public:
|
||||
int nstyles; // # of sub-styles
|
||||
Pair **styles; // list of Pair style classes
|
||||
char **keywords; // style name of each Pair style
|
||||
int *multiple; // 0 if style used once, else Mth instance
|
||||
|
||||
PairHybrid(class LAMMPS *);
|
||||
virtual ~PairHybrid();
|
||||
void compute(int, int);
|
||||
@ -54,13 +53,28 @@ class PairHybrid : public Pair {
|
||||
int check_ijtype(int, int, char *);
|
||||
|
||||
protected:
|
||||
int nstyles; // # of sub-styles
|
||||
Pair **styles; // list of Pair style classes
|
||||
char **keywords; // style name of each Pair style
|
||||
int *multiple; // 0 if style used once, else Mth instance
|
||||
|
||||
int outerflag; // toggle compute() when invoked by outer()
|
||||
int respaflag; // 1 if different substyles are assigned to
|
||||
// different r-RESPA levels
|
||||
|
||||
int **nmap; // # of sub-styles itype,jtype points to
|
||||
int ***map; // list of sub-styles itype,jtype points to
|
||||
double **special_lj; // list of per style LJ exclusion factors
|
||||
double **special_coul; // list of per style Coulomb exclusion factors
|
||||
|
||||
void allocate();
|
||||
void flags();
|
||||
|
||||
void modify_special(int, int, char**);
|
||||
double *save_special();
|
||||
void set_special(int);
|
||||
void restore_special(double *);
|
||||
|
||||
virtual void modify_requests();
|
||||
};
|
||||
|
||||
|
||||
129
src/respa.cpp
129
src/respa.cpp
@ -38,6 +38,7 @@
|
||||
#include "timer.h"
|
||||
#include "memory.h"
|
||||
#include "error.h"
|
||||
#include "pair_hybrid.h"
|
||||
|
||||
using namespace LAMMPS_NS;
|
||||
|
||||
@ -65,6 +66,11 @@ Respa::Respa(LAMMPS *lmp, int narg, char **arg) : Integrate(lmp, narg, arg)
|
||||
level_pair = level_kspace = -1;
|
||||
level_inner = level_middle = level_outer = -1;
|
||||
|
||||
// defaults for hybrid pair styles
|
||||
nhybrid_styles = 0;
|
||||
tally_global = 1;
|
||||
pair_compute = 1;
|
||||
|
||||
int iarg = nlevels;
|
||||
while (iarg < narg) {
|
||||
if (strcmp(arg[iarg],"bond") == 0) {
|
||||
@ -107,6 +113,22 @@ Respa::Respa(LAMMPS *lmp, int narg, char **arg) : Integrate(lmp, narg, arg)
|
||||
if (iarg+2 > narg) error->all(FLERR,"Illegal run_style respa command");
|
||||
level_kspace = force->inumeric(FLERR,arg[iarg+1]) - 1;
|
||||
iarg += 2;
|
||||
} else if (strcmp(arg[iarg],"hybrid") == 0) {
|
||||
// the hybrid keyword requires a hybrid pair style
|
||||
if (!strstr(force->pair_style,"hybrid"))
|
||||
error->all(FLERR,"Illegal run_style respa command");
|
||||
PairHybrid *hybrid = (PairHybrid *) force->pair;
|
||||
nhybrid_styles = hybrid->nstyles;
|
||||
// each hybrid sub-style needs to be assigned to a respa level
|
||||
if (iarg+nhybrid_styles > narg)
|
||||
error->all(FLERR,"Illegal run_style respa command");
|
||||
hybrid_level = new int[nhybrid_styles];
|
||||
hybrid_compute = new int[nhybrid_styles];
|
||||
for (int i=0; i < nhybrid_styles; ++i) {
|
||||
++iarg;
|
||||
hybrid_level[i] = force->inumeric(FLERR,arg[iarg])-1;
|
||||
}
|
||||
++iarg;
|
||||
} else error->all(FLERR,"Illegal run_style respa command");
|
||||
}
|
||||
|
||||
@ -127,6 +149,10 @@ Respa::Respa(LAMMPS *lmp, int narg, char **arg) : Integrate(lmp, narg, arg)
|
||||
if (level_middle >= 0 && level_inner == -1)
|
||||
error->all(FLERR,"Cannot set respa middle without inner/outer");
|
||||
|
||||
// cannot combine hybrid with any of pair/inner/middle/outer
|
||||
if ((nhybrid_styles > 0) && (level_pair >= 0 || level_inner >= 0
|
||||
|| level_middle >= 0 || level_outer >= 0))
|
||||
error->all(FLERR,"Cannot set respa hybrid and any of pair/inner/middle/outer");
|
||||
// set defaults if user did not specify level
|
||||
// bond to innermost level
|
||||
// angle same as bond, dihedral same as angle, improper same as dihedral
|
||||
@ -138,9 +164,23 @@ Respa::Respa(LAMMPS *lmp, int narg, char **arg) : Integrate(lmp, narg, arg)
|
||||
if (level_angle == -1) level_angle = level_bond;
|
||||
if (level_dihedral == -1) level_dihedral = level_angle;
|
||||
if (level_improper == -1) level_improper = level_dihedral;
|
||||
if (level_pair == -1 && level_inner == -1) level_pair = nlevels-1;
|
||||
|
||||
if (level_pair == -1 && level_inner == -1 && nhybrid_styles < 1)
|
||||
level_pair = nlevels-1;
|
||||
|
||||
if (level_kspace == -1 && level_pair >= 0) level_kspace = level_pair;
|
||||
if (level_kspace == -1 && level_pair == -1) level_kspace = level_outer;
|
||||
if (level_kspace == -1 && level_pair == -1) {
|
||||
if (nhybrid_styles < 1) {
|
||||
level_kspace = level_outer;
|
||||
} else {
|
||||
int max_hybrid_level = -1;
|
||||
for (int i=0; i < nhybrid_styles; ++i) {
|
||||
if (max_hybrid_level < hybrid_level[i])
|
||||
max_hybrid_level = hybrid_level[i];
|
||||
}
|
||||
level_kspace = max_hybrid_level;
|
||||
}
|
||||
}
|
||||
|
||||
// print respa levels
|
||||
|
||||
@ -157,6 +197,9 @@ Respa::Respa(LAMMPS *lmp, int narg, char **arg) : Integrate(lmp, narg, arg)
|
||||
if (level_inner == i) fprintf(screen," pair-inner");
|
||||
if (level_middle == i) fprintf(screen," pair-middle");
|
||||
if (level_outer == i) fprintf(screen," pair-outer");
|
||||
for (int j=0;j<nhybrid_styles;j++) {
|
||||
if (hybrid_level[j] == i) fprintf(screen, " hybrid-%d",j+1);
|
||||
}
|
||||
if (level_kspace == i) fprintf(screen," kspace");
|
||||
fprintf(screen,"\n");
|
||||
}
|
||||
@ -173,6 +216,9 @@ Respa::Respa(LAMMPS *lmp, int narg, char **arg) : Integrate(lmp, narg, arg)
|
||||
if (level_inner == i) fprintf(logfile," pair-inner");
|
||||
if (level_middle == i) fprintf(logfile," pair-middle");
|
||||
if (level_outer == i) fprintf(logfile," pair-outer");
|
||||
for (int j=0;j<nhybrid_styles;j++) {
|
||||
if (hybrid_level[j] == i) fprintf(logfile, " hybrid-%d",j+1);
|
||||
}
|
||||
if (level_kspace == i) fprintf(logfile," kspace");
|
||||
fprintf(logfile,"\n");
|
||||
}
|
||||
@ -188,7 +234,7 @@ Respa::Respa(LAMMPS *lmp, int narg, char **arg) : Integrate(lmp, narg, arg)
|
||||
if (level_pair < level_improper || level_kspace < level_pair)
|
||||
error->all(FLERR,"Invalid order of forces within respa levels");
|
||||
}
|
||||
if (level_pair == -1 && level_middle == -1) {
|
||||
if (level_pair == -1 && level_middle == -1 && nhybrid_styles < 1) {
|
||||
if (level_inner < level_improper || level_outer < level_inner ||
|
||||
level_kspace < level_outer)
|
||||
error->all(FLERR,"Invalid order of forces within respa levels");
|
||||
@ -223,6 +269,12 @@ Respa::Respa(LAMMPS *lmp, int narg, char **arg) : Integrate(lmp, narg, arg)
|
||||
cutoff[3] = cutoff[1];
|
||||
}
|
||||
|
||||
// ensure that pair->compute() is run properly when the "hybrid" keyword is not used.
|
||||
if (nhybrid_styles < 1) {
|
||||
pair_compute = 1;
|
||||
tally_global = 1;
|
||||
}
|
||||
|
||||
// allocate other needed arrays
|
||||
|
||||
newton = new int[nlevels];
|
||||
@ -236,6 +288,10 @@ Respa::~Respa()
|
||||
delete [] loop;
|
||||
delete [] newton;
|
||||
delete [] step;
|
||||
if (nhybrid_styles > 0) {
|
||||
delete [] hybrid_level;
|
||||
delete [] hybrid_compute;
|
||||
}
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
@ -254,13 +310,19 @@ void Respa::init()
|
||||
// create fix needed for storing atom-based respa level forces
|
||||
// will delete it at end of run
|
||||
|
||||
char **fixarg = new char*[4];
|
||||
char **fixarg = new char*[5];
|
||||
fixarg[0] = (char *) "RESPA";
|
||||
fixarg[1] = (char *) "all";
|
||||
fixarg[2] = (char *) "RESPA";
|
||||
fixarg[3] = new char[8];
|
||||
sprintf(fixarg[3],"%d",nlevels);
|
||||
// if supported, we also store torques on a per-level basis
|
||||
if (atom->torque_flag) {
|
||||
fixarg[4] = (char *) "torque";
|
||||
modify->add_fix(5,fixarg);
|
||||
} else {
|
||||
modify->add_fix(4,fixarg);
|
||||
}
|
||||
delete [] fixarg[3];
|
||||
delete [] fixarg;
|
||||
fix_respa = (FixRespa *) modify->fix[modify->nfix-1];
|
||||
@ -309,6 +371,11 @@ void Respa::init()
|
||||
if (level_pair == ilevel || level_inner == ilevel ||
|
||||
level_middle == ilevel || level_outer == ilevel)
|
||||
newton[ilevel] = 1;
|
||||
|
||||
if (nhybrid_styles > 0) {
|
||||
set_compute_flags(ilevel);
|
||||
if (pair_compute) newton[ilevel] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -360,6 +427,11 @@ void Respa::setup()
|
||||
for (int ilevel = 0; ilevel < nlevels; ilevel++) {
|
||||
force_clear(newton[ilevel]);
|
||||
modify->setup_pre_force_respa(vflag,ilevel);
|
||||
|
||||
if (nhybrid_styles > 0) {
|
||||
set_compute_flags(ilevel);
|
||||
force->pair->compute(eflag,vflag);
|
||||
}
|
||||
if (level_pair == ilevel && pair_compute_flag)
|
||||
force->pair->compute(eflag,vflag);
|
||||
if (level_inner == ilevel && pair_compute_flag)
|
||||
@ -428,6 +500,12 @@ void Respa::setup_minimal(int flag)
|
||||
for (int ilevel = 0; ilevel < nlevels; ilevel++) {
|
||||
force_clear(newton[ilevel]);
|
||||
modify->setup_pre_force_respa(vflag,ilevel);
|
||||
|
||||
if (nhybrid_styles > 0) {
|
||||
set_compute_flags(ilevel);
|
||||
force->pair->compute(eflag,vflag);
|
||||
}
|
||||
|
||||
if (level_pair == ilevel && pair_compute_flag)
|
||||
force->pair->compute(eflag,vflag);
|
||||
if (level_inner == ilevel && pair_compute_flag)
|
||||
@ -574,6 +652,11 @@ void Respa::recurse(int ilevel)
|
||||
modify->pre_force_respa(vflag,ilevel,iloop);
|
||||
|
||||
timer->stamp();
|
||||
if (nhybrid_styles > 0) {
|
||||
set_compute_flags(ilevel);
|
||||
force->pair->compute(eflag,vflag);
|
||||
timer->stamp(TIME_PAIR);
|
||||
}
|
||||
if (level_pair == ilevel && pair_compute_flag) {
|
||||
force->pair->compute(eflag,vflag);
|
||||
timer->stamp(TIME_PAIR);
|
||||
@ -654,12 +737,19 @@ void Respa::copy_f_flevel(int ilevel)
|
||||
{
|
||||
double ***f_level = fix_respa->f_level;
|
||||
double **f = atom->f;
|
||||
double ***t_level = fix_respa->t_level;
|
||||
double **t = atom->torque;
|
||||
int n = atom->nlocal;
|
||||
|
||||
for (int i = 0; i < n; i++) {
|
||||
f_level[i][ilevel][0] = f[i][0];
|
||||
f_level[i][ilevel][1] = f[i][1];
|
||||
f_level[i][ilevel][2] = f[i][2];
|
||||
if (fix_respa->store_torque) {
|
||||
t_level[i][ilevel][0] = t[i][0];
|
||||
t_level[i][ilevel][1] = t[i][1];
|
||||
t_level[i][ilevel][2] = t[i][2];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -671,12 +761,19 @@ void Respa::copy_flevel_f(int ilevel)
|
||||
{
|
||||
double ***f_level = fix_respa->f_level;
|
||||
double **f = atom->f;
|
||||
double ***t_level = fix_respa->t_level;
|
||||
double **t = atom->torque;
|
||||
int n = atom->nlocal;
|
||||
|
||||
for (int i = 0; i < n; i++) {
|
||||
f[i][0] = f_level[i][ilevel][0];
|
||||
f[i][1] = f_level[i][ilevel][1];
|
||||
f[i][2] = f_level[i][ilevel][2];
|
||||
if (fix_respa->store_torque) {
|
||||
t[i][0] = t_level[i][ilevel][0];
|
||||
t[i][1] = t_level[i][ilevel][1];
|
||||
t[i][2] = t_level[i][ilevel][2];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -690,6 +787,8 @@ void Respa::sum_flevel_f()
|
||||
|
||||
double ***f_level = fix_respa->f_level;
|
||||
double **f = atom->f;
|
||||
double ***t_level = fix_respa->t_level;
|
||||
double **t = atom->torque;
|
||||
int n = atom->nlocal;
|
||||
|
||||
for (int ilevel = 1; ilevel < nlevels; ilevel++) {
|
||||
@ -697,6 +796,28 @@ void Respa::sum_flevel_f()
|
||||
f[i][0] += f_level[i][ilevel][0];
|
||||
f[i][1] += f_level[i][ilevel][1];
|
||||
f[i][2] += f_level[i][ilevel][2];
|
||||
if (fix_respa->store_torque) {
|
||||
t[i][0] += t_level[i][ilevel][0];
|
||||
t[i][1] += t_level[i][ilevel][1];
|
||||
t[i][2] += t_level[i][ilevel][2];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
set flags for when some hybrid forces should be computed
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void Respa::set_compute_flags(int ilevel)
|
||||
{
|
||||
|
||||
if (nhybrid_styles < 1) return;
|
||||
|
||||
pair_compute = 0;
|
||||
for (int i=0; i<nhybrid_styles; ++i) {
|
||||
hybrid_compute[i] = (hybrid_level[i] == ilevel) ? 1 : 0;
|
||||
if (hybrid_compute[i]) pair_compute = 1;
|
||||
}
|
||||
tally_global = (ilevel == nlevels-1) ? 1 : 0;
|
||||
}
|
||||
|
||||
13
src/respa.h
13
src/respa.h
@ -39,6 +39,12 @@ class Respa : public Integrate {
|
||||
int level_improper,level_pair,level_kspace;
|
||||
int level_inner,level_middle,level_outer;
|
||||
|
||||
int nhybrid_styles; // number of hybrid pair styles
|
||||
int *hybrid_level; // level to compute pair hybrid sub-style at
|
||||
int *hybrid_compute; // selects whether to compute sub-style forces
|
||||
int tally_global; // 1 if pair style should tally global accumulators
|
||||
int pair_compute; // 1 if pair force need to be computed
|
||||
|
||||
Respa(class LAMMPS *, int, char **);
|
||||
virtual ~Respa();
|
||||
virtual void init();
|
||||
@ -61,6 +67,7 @@ class Respa : public Integrate {
|
||||
virtual void recurse(int);
|
||||
void force_clear(int);
|
||||
void sum_flevel_f();
|
||||
void set_compute_flags(int ilevel);
|
||||
};
|
||||
|
||||
}
|
||||
@ -86,6 +93,12 @@ In the rRESPA integrator, you must compute pairwise potentials either
|
||||
all together (pair), or in pieces (inner/middle/outer). You can't do
|
||||
both.
|
||||
|
||||
E: Cannot set respa hybrid and any of pair/inner/middle/outer
|
||||
|
||||
In the rRESPA integrator, you must compute pairwise potentials either
|
||||
all together (pair), with different cutoff regions (inner/middle/outer),
|
||||
or per hybrid sub-style (hybrid). You cannot mix those.
|
||||
|
||||
E: Must set both respa inner and outer
|
||||
|
||||
Cannot use just the inner or outer option with respa without using the
|
||||
|
||||
Reference in New Issue
Block a user