git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@13757 f3b2605a-c512-4ea7-a41b-209d697bcdaa
This commit is contained in:
131
src/respa.cpp
131
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);
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user