git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@13757 f3b2605a-c512-4ea7-a41b-209d697bcdaa

This commit is contained in:
sjplimp
2015-07-28 16:04:10 +00:00
parent d89332f7d5
commit 737f6dc86b
6 changed files with 390 additions and 25 deletions

View File

@ -12,6 +12,7 @@
------------------------------------------------------------------------- */ ------------------------------------------------------------------------- */
#include "stdlib.h" #include "stdlib.h"
#include "string.h"
#include "fix_respa.h" #include "fix_respa.h"
#include "atom.h" #include "atom.h"
#include "force.h" #include "force.h"
@ -29,10 +30,18 @@ FixRespa::FixRespa(LAMMPS *lmp, int narg, char **arg) :
nlevels = force->inumeric(FLERR,arg[3]); 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 // perform initial allocation of atom-based arrays
// register with Atom class // register with Atom class
f_level = NULL; f_level = NULL;
t_level = NULL;
grow_arrays(atom->nmax); grow_arrays(atom->nmax);
atom->add_callback(0); atom->add_callback(0);
} }
@ -48,6 +57,7 @@ FixRespa::~FixRespa()
// delete locally stored arrays // delete locally stored arrays
memory->destroy(f_level); memory->destroy(f_level);
if (store_torque) memory->destroy(t_level);
} }
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
@ -64,6 +74,7 @@ int FixRespa::setmask()
double FixRespa::memory_usage() double FixRespa::memory_usage()
{ {
double bytes = atom->nmax*nlevels*3 * sizeof(double); double bytes = atom->nmax*nlevels*3 * sizeof(double);
if (store_torque) bytes += atom->nmax*nlevels*3 * sizeof(double);
return bytes; return bytes;
} }
@ -74,6 +85,7 @@ double FixRespa::memory_usage()
void FixRespa::grow_arrays(int nmax) void FixRespa::grow_arrays(int nmax)
{ {
memory->grow(f_level,nmax,nlevels,3,"fix_respa:f_level"); 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][1] = f_level[i][k][1];
f_level[j][k][2] = f_level[i][k][2]; 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][1];
buf[m++] = f_level[i][k][2]; 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; 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][1] = buf[m++];
f_level[nlocal][k][2] = 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; return m;
} }

View File

@ -43,7 +43,9 @@ class FixRespa : public Fix {
private: private:
int nlevels; int nlevels;
double ***f_level; // force at each rRESPA level 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
}; };
} }

View File

@ -25,6 +25,7 @@
#include "comm.h" #include "comm.h"
#include "memory.h" #include "memory.h"
#include "error.h" #include "error.h"
#include "respa.h"
using namespace LAMMPS_NS; using namespace LAMMPS_NS;
@ -36,8 +37,11 @@ PairHybrid::PairHybrid(LAMMPS *lmp) : Pair(lmp)
styles = NULL; styles = NULL;
keywords = NULL; keywords = NULL;
multiple = NULL; multiple = NULL;
special_lj = NULL;
special_coul = NULL;
outerflag = 0; outerflag = 0;
respaflag = 0;
} }
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
@ -45,13 +49,20 @@ PairHybrid::PairHybrid(LAMMPS *lmp) : Pair(lmp)
PairHybrid::~PairHybrid() PairHybrid::~PairHybrid()
{ {
if (nstyles) { if (nstyles) {
for (int m = 0; m < nstyles; m++) delete styles[m]; for (int m = 0; m < nstyles; m++) {
for (int m = 0; m < nstyles; m++) delete [] keywords[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 [] styles;
delete [] keywords; delete [] keywords;
delete [] multiple; delete [] multiple;
delete [] special_lj;
delete [] special_coul;
delete [] svector; delete [] svector;
if (allocated) { if (allocated) {
@ -98,15 +109,36 @@ void PairHybrid::compute(int eflag, int vflag)
if (vflag % 4 == 2) vflag_substyle = vflag/4 * 4; if (vflag % 4 == 2) vflag_substyle = vflag/4 * 4;
else vflag_substyle = vflag; 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++) { for (m = 0; m < nstyles; m++) {
// invoke compute() unless compute flag is turned off or set_special(m);
// outerflag is set and sub-style has a compute_outer() method
if (styles[m]->compute_flag == 0) continue; if (!respaflag || (respaflag && respa->hybrid_compute[m])) {
if (outerflag && styles[m]->respa_enable)
styles[m]->compute_outer(eflag,vflag_substyle); // invoke compute() unless compute flag is turned off or
else styles[m]->compute(eflag,vflag_substyle); // outerflag is set and sub-style has a compute_outer() method
if (styles[m]->compute_flag == 0) continue;
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) { if (eflag_global) {
eng_vdwl += styles[m]->eng_vdwl; 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(); if (vflag_fdotr) virial_fdotr_compute();
} }
@ -215,6 +249,9 @@ void PairHybrid::settings(int narg, char **arg)
keywords = new char*[narg]; keywords = new char*[narg];
multiple = new int[narg]; multiple = new int[narg];
special_lj = new double*[narg];
special_coul = new double*[narg];
// allocate each sub-style // allocate each sub-style
// allocate uses suffix, but don't store suffix version in keywords, // allocate uses suffix, but don't store suffix version in keywords,
// else syntax in coeff() will not match // 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); styles[nstyles] = force->new_pair(arg[iarg],1,dummy);
force->store_style(keywords[nstyles],arg[iarg],0); force->store_style(keywords[nstyles],arg[iarg],0);
special_lj[nstyles] = special_coul[nstyles] = NULL;
jarg = iarg + 1; jarg = iarg + 1;
while (jarg < narg && !force->pair_map->count(arg[jarg])) jarg++; 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"); 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) // each sub-style makes its neighbor list request(s)
for (istyle = 0; istyle < nstyles; istyle++) styles[istyle]->init_style(); 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(&n,sizeof(int),1,fp);
fwrite(keywords[m],sizeof(char),n,fp); fwrite(keywords[m],sizeof(char),n,fp);
styles[m]->write_restart_settings(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]; keywords = new char*[nstyles];
multiple = new int[nstyles]; multiple = new int[nstyles];
special_lj = new double*[nstyles];
special_coul = new double*[nstyles];
// each sub-style is created via new_pair() // each sub-style is created via new_pair()
// each reads its settings, but no coeff info // 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); MPI_Bcast(keywords[m],n,MPI_CHAR,0,world);
styles[m] = force->new_pair(keywords[m],0,dummy); styles[m] = force->new_pair(keywords[m],0,dummy);
styles[m]->read_restart_settings(fp); 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 // 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) if (styles[map[itype][jtype][m]]->single_enable == 0)
error->one(FLERR,"Pair hybrid sub-style does not support single call"); 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]]-> esum += styles[map[itype][jtype][m]]->
single(i,j,itype,jtype,rsq,factor_coul,factor_lj,fone); single(i,j,itype,jtype,rsq,factor_coul,factor_lj,fone);
fforce += fone; fforce += fone;
@ -716,8 +807,14 @@ void PairHybrid::modify_params(int narg, char **arg)
if (strcmp(arg[1],keywords[m]) == 0) break; if (strcmp(arg[1],keywords[m]) == 0) break;
if (m == nstyles) error->all(FLERR,"Unknown pair_modify hybrid sub-style"); if (m == nstyles) error->all(FLERR,"Unknown pair_modify hybrid sub-style");
if (multiple[m] == 0) { if (multiple[m] == 0) {
Pair::modify_params(narg-2,&arg[2]); // augment special settings for this one pair style
styles[m]->modify_params(narg-2,&arg[2]); 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 { } else {
if (narg < 3) error->all(FLERR,"Illegal pair_modify command"); if (narg < 3) error->all(FLERR,"Illegal pair_modify command");
int multiflag = force->inumeric(FLERR,arg[2]); int multiflag = force->inumeric(FLERR,arg[2]);
@ -725,13 +822,98 @@ void PairHybrid::modify_params(int narg, char **arg)
if (strcmp(arg[1],keywords[m]) == 0 && multiflag == multiple[m]) break; if (strcmp(arg[1],keywords[m]) == 0 && multiflag == multiple[m]) break;
if (m == nstyles) if (m == nstyles)
error->all(FLERR,"Unknown pair_modify hybrid sub-style"); error->all(FLERR,"Unknown pair_modify hybrid sub-style");
Pair::modify_params(narg-3,&arg[3]); // augment special settings for this one pair style
styles[m]->modify_params(narg-3,&arg[3]); 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 { } else {
Pair::modify_params(narg,arg); // augment special settings for all pair styles
for (int m = 0; m < nstyles; m++) styles[m]->modify_params(narg,arg); 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];
} }
} }

View File

@ -26,12 +26,11 @@ PairStyle(hybrid,PairHybrid)
namespace LAMMPS_NS { namespace LAMMPS_NS {
class PairHybrid : public Pair { class PairHybrid : public Pair {
friend class FixGPU;
friend class FixOMP;
friend class Force;
friend class Respa;
public: 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 *); PairHybrid(class LAMMPS *);
virtual ~PairHybrid(); virtual ~PairHybrid();
void compute(int, int); void compute(int, int);
@ -54,13 +53,28 @@ class PairHybrid : public Pair {
int check_ijtype(int, int, char *); int check_ijtype(int, int, char *);
protected: 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 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 **nmap; // # of sub-styles itype,jtype points to
int ***map; // list 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 allocate();
void flags(); void flags();
void modify_special(int, int, char**);
double *save_special();
void set_special(int);
void restore_special(double *);
virtual void modify_requests(); virtual void modify_requests();
}; };

View File

@ -38,6 +38,7 @@
#include "timer.h" #include "timer.h"
#include "memory.h" #include "memory.h"
#include "error.h" #include "error.h"
#include "pair_hybrid.h"
using namespace LAMMPS_NS; 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_pair = level_kspace = -1;
level_inner = level_middle = level_outer = -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; int iarg = nlevels;
while (iarg < narg) { while (iarg < narg) {
if (strcmp(arg[iarg],"bond") == 0) { 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"); if (iarg+2 > narg) error->all(FLERR,"Illegal run_style respa command");
level_kspace = force->inumeric(FLERR,arg[iarg+1]) - 1; level_kspace = force->inumeric(FLERR,arg[iarg+1]) - 1;
iarg += 2; 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"); } 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) if (level_middle >= 0 && level_inner == -1)
error->all(FLERR,"Cannot set respa middle without inner/outer"); 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 // set defaults if user did not specify level
// bond to innermost level // bond to innermost level
// angle same as bond, dihedral same as angle, improper same as dihedral // 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_angle == -1) level_angle = level_bond;
if (level_dihedral == -1) level_dihedral = level_angle; if (level_dihedral == -1) level_dihedral = level_angle;
if (level_improper == -1) level_improper = level_dihedral; 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 >= 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 // 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_inner == i) fprintf(screen," pair-inner");
if (level_middle == i) fprintf(screen," pair-middle"); if (level_middle == i) fprintf(screen," pair-middle");
if (level_outer == i) fprintf(screen," pair-outer"); 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"); if (level_kspace == i) fprintf(screen," kspace");
fprintf(screen,"\n"); 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_inner == i) fprintf(logfile," pair-inner");
if (level_middle == i) fprintf(logfile," pair-middle"); if (level_middle == i) fprintf(logfile," pair-middle");
if (level_outer == i) fprintf(logfile," pair-outer"); 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"); if (level_kspace == i) fprintf(logfile," kspace");
fprintf(logfile,"\n"); 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) if (level_pair < level_improper || level_kspace < level_pair)
error->all(FLERR,"Invalid order of forces within respa levels"); 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 || if (level_inner < level_improper || level_outer < level_inner ||
level_kspace < level_outer) level_kspace < level_outer)
error->all(FLERR,"Invalid order of forces within respa levels"); 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]; 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 // allocate other needed arrays
newton = new int[nlevels]; newton = new int[nlevels];
@ -236,6 +288,10 @@ Respa::~Respa()
delete [] loop; delete [] loop;
delete [] newton; delete [] newton;
delete [] step; 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 // create fix needed for storing atom-based respa level forces
// will delete it at end of run // will delete it at end of run
char **fixarg = new char*[4]; char **fixarg = new char*[5];
fixarg[0] = (char *) "RESPA"; fixarg[0] = (char *) "RESPA";
fixarg[1] = (char *) "all"; fixarg[1] = (char *) "all";
fixarg[2] = (char *) "RESPA"; fixarg[2] = (char *) "RESPA";
fixarg[3] = new char[8]; fixarg[3] = new char[8];
sprintf(fixarg[3],"%d",nlevels); sprintf(fixarg[3],"%d",nlevels);
modify->add_fix(4,fixarg); // 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[3];
delete [] fixarg; delete [] fixarg;
fix_respa = (FixRespa *) modify->fix[modify->nfix-1]; fix_respa = (FixRespa *) modify->fix[modify->nfix-1];
@ -309,6 +371,11 @@ void Respa::init()
if (level_pair == ilevel || level_inner == ilevel || if (level_pair == ilevel || level_inner == ilevel ||
level_middle == ilevel || level_outer == ilevel) level_middle == ilevel || level_outer == ilevel)
newton[ilevel] = 1; 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++) { for (int ilevel = 0; ilevel < nlevels; ilevel++) {
force_clear(newton[ilevel]); force_clear(newton[ilevel]);
modify->setup_pre_force_respa(vflag,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) if (level_pair == ilevel && pair_compute_flag)
force->pair->compute(eflag,vflag); force->pair->compute(eflag,vflag);
if (level_inner == ilevel && pair_compute_flag) if (level_inner == ilevel && pair_compute_flag)
@ -428,6 +500,12 @@ void Respa::setup_minimal(int flag)
for (int ilevel = 0; ilevel < nlevels; ilevel++) { for (int ilevel = 0; ilevel < nlevels; ilevel++) {
force_clear(newton[ilevel]); force_clear(newton[ilevel]);
modify->setup_pre_force_respa(vflag,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) if (level_pair == ilevel && pair_compute_flag)
force->pair->compute(eflag,vflag); force->pair->compute(eflag,vflag);
if (level_inner == ilevel && pair_compute_flag) if (level_inner == ilevel && pair_compute_flag)
@ -574,6 +652,11 @@ void Respa::recurse(int ilevel)
modify->pre_force_respa(vflag,ilevel,iloop); modify->pre_force_respa(vflag,ilevel,iloop);
timer->stamp(); 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) { if (level_pair == ilevel && pair_compute_flag) {
force->pair->compute(eflag,vflag); force->pair->compute(eflag,vflag);
timer->stamp(TIME_PAIR); timer->stamp(TIME_PAIR);
@ -654,12 +737,19 @@ void Respa::copy_f_flevel(int ilevel)
{ {
double ***f_level = fix_respa->f_level; double ***f_level = fix_respa->f_level;
double **f = atom->f; double **f = atom->f;
double ***t_level = fix_respa->t_level;
double **t = atom->torque;
int n = atom->nlocal; int n = atom->nlocal;
for (int i = 0; i < n; i++) { for (int i = 0; i < n; i++) {
f_level[i][ilevel][0] = f[i][0]; f_level[i][ilevel][0] = f[i][0];
f_level[i][ilevel][1] = f[i][1]; f_level[i][ilevel][1] = f[i][1];
f_level[i][ilevel][2] = f[i][2]; 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_level = fix_respa->f_level;
double **f = atom->f; double **f = atom->f;
double ***t_level = fix_respa->t_level;
double **t = atom->torque;
int n = atom->nlocal; int n = atom->nlocal;
for (int i = 0; i < n; i++) { for (int i = 0; i < n; i++) {
f[i][0] = f_level[i][ilevel][0]; f[i][0] = f_level[i][ilevel][0];
f[i][1] = f_level[i][ilevel][1]; f[i][1] = f_level[i][ilevel][1];
f[i][2] = f_level[i][ilevel][2]; 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_level = fix_respa->f_level;
double **f = atom->f; double **f = atom->f;
double ***t_level = fix_respa->t_level;
double **t = atom->torque;
int n = atom->nlocal; int n = atom->nlocal;
for (int ilevel = 1; ilevel < nlevels; ilevel++) { 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][0] += f_level[i][ilevel][0];
f[i][1] += f_level[i][ilevel][1]; f[i][1] += f_level[i][ilevel][1];
f[i][2] += f_level[i][ilevel][2]; 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;
}

View File

@ -39,6 +39,12 @@ class Respa : public Integrate {
int level_improper,level_pair,level_kspace; int level_improper,level_pair,level_kspace;
int level_inner,level_middle,level_outer; 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 **); Respa(class LAMMPS *, int, char **);
virtual ~Respa(); virtual ~Respa();
virtual void init(); virtual void init();
@ -61,6 +67,7 @@ class Respa : public Integrate {
virtual void recurse(int); virtual void recurse(int);
void force_clear(int); void force_clear(int);
void sum_flevel_f(); 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 all together (pair), or in pieces (inner/middle/outer). You can't do
both. 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 E: Must set both respa inner and outer
Cannot use just the inner or outer option with respa without using the Cannot use just the inner or outer option with respa without using the