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

This commit is contained in:
sjplimp
2013-07-22 23:02:25 +00:00
parent 6412ac8543
commit 2135141fe9
4 changed files with 3659 additions and 3686 deletions

View File

@ -101,7 +101,7 @@ MSM::MSM(LAMMPS *lmp, int narg, char **arg) : KSpace(lmp, narg, arg)
peratom_allocate_flag = 0;
order = 8;
order = 10;
}
/* ----------------------------------------------------------------------
@ -254,57 +254,6 @@ void MSM::init()
}
}
/* ----------------------------------------------------------------------
estimate cutoff for a given grid spacing and error
------------------------------------------------------------------------- */
double MSM::estimate_cutoff(double h, double prd)
{
double a;
int p = order - 1;
double Mp,cprime,error_scaling;
Mp = cprime = error_scaling = 1;
// Mp values from Table 5.1 of Hardy's thesis
// cprime values from equation 4.17 of Hardy's thesis
// error scaling from empirical fitting to convert to rms force errors
if (p == 3) {
Mp = 9;
cprime = 1.0/6.0;
error_scaling = 0.39189561;
} else if (p == 5) {
Mp = 825;
cprime = 1.0/30.0;
error_scaling = 0.150829428;
} else if (p == 7) {
Mp = 130095;
cprime = 1.0/140.0;
error_scaling = 0.049632967;
} else if (p == 9) {
Mp = 34096545;
cprime = 1.0/630.0;
error_scaling = 0.013520855;
} else {
error->all(FLERR,"MSM order must be 4, 6, 8, or 10");
}
// equation 4.1 from Hardy's thesis
double C_p = 4.0*cprime*Mp/3.0;
// use empirical parameters to convert to rms force errors
C_p *= error_scaling;
// equation 3.200 from Hardy's thesis
a = C_p*pow(h,(p-1))/accuracy;
// include dependency of error on other terms
a *= q2/(prd*sqrt(double(atom->natoms)));
a = pow(a,1.0/double(p));
return a;
}
/* ----------------------------------------------------------------------
estimate 1d grid RMS force error for MSM
------------------------------------------------------------------------- */
@ -340,7 +289,7 @@ double MSM::estimate_1d_error(double h, double prd)
}
// equation 4.1 from Hardy's thesis
double C_p = 4.0*cprime*Mp/3.0;
C_p = 4.0*cprime*Mp/3.0;
// use empirical parameters to convert to rms force errors
C_p *= error_scaling;
@ -676,6 +625,7 @@ void MSM::allocate()
{
// interpolation coeffs
order_allocated = order;
memory->create2d_offset(phi1d,3,-order,order,"msm:phi1d");
memory->create2d_offset(dphi1d,3,-order,order,"msm:dphi1d");
@ -719,8 +669,8 @@ void MSM::allocate()
void MSM::deallocate()
{
memory->destroy2d_offset(phi1d,-order);
memory->destroy2d_offset(dphi1d,-order);
memory->destroy2d_offset(phi1d,-order_allocated);
memory->destroy2d_offset(dphi1d,-order_allocated);
if (cg_all) delete cg_all;
@ -1012,28 +962,6 @@ void MSM::set_grid_global()
nz_max = nz_msm_max;
}
// adjust Coulombic cutoff to give desired error (if requested)
if (adjust_cutoff_flag) {
hx = xprd/nx_max;
hy = yprd/ny_max;
hz = zprd/nz_max;
double ax,ay,az;
ax = estimate_cutoff(hx,xprd);
ay = estimate_cutoff(hy,yprd);
az = estimate_cutoff(hz,zprd);
cutoff = sqrt(ax*ax + ay*ay + az*az)/sqrt(3.0);
int itmp;
double *p_cutoff = (double *) force->pair->extract("cut_coul",itmp);
*p_cutoff = cutoff;
char str[128];
sprintf(str,"Adjusting Coulombic cutoff for MSM, new cutoff = %g",cutoff);
if (me == 0) error->warning(FLERR,str);
}
// scale grid for triclinic skew
if (triclinic && !gridflag) {
@ -1048,16 +976,61 @@ void MSM::set_grid_global()
}
// boost grid size until it is factorable by 2
// round up or down, depending on which is closer
int flag = 0;
int xlevels,ylevels,zlevels;
double k,r;
while (!factorable(nx_max,flag,xlevels)) nx_max++;
while (!factorable(ny_max,flag,ylevels)) ny_max++;
while (!factorable(nz_max,flag,zlevels)) nz_max++;
while (!factorable(nx_max,flag,xlevels)) {
double k = log(nx_max)/log(2.0);
double r = k - floor(k);
if (r > 0.5) nx_max++;
else nx_max--;
}
while (!factorable(ny_max,flag,ylevels)) {
double k = log(ny_max)/log(2.0);
double r = k - floor(k);
if (r > 0.5) ny_max++;
else ny_max--;
}
while (!factorable(nz_max,flag,zlevels)) {
double k = log(nz_max)/log(2.0);
double r = k - floor(k);
if (r > 0.5) nz_max++;
else nz_max--;
}
if (flag && gridflag && me == 0)
error->warning(FLERR,"Number of MSM mesh points increased to be a multiple of 2");
error->warning(FLERR,"Number of MSM mesh points changed to be a multiple of 2");
// adjust Coulombic cutoff to give desired error (if requested)
if (adjust_cutoff_flag) {
hx = xprd/nx_max;
hy = yprd/ny_max;
hz = zprd/nz_max;
int p = order - 1;
double Lx2 = xprd*xprd;
double Ly2 = yprd*yprd;
double Lz2 = zprd*zprd;
double hx2pm2 = pow(hx,2.0*p-2.0);
double hy2pm2 = pow(hy,2.0*p-2.0);
double hz2pm2 = pow(hz,2.0*p-2.0);
estimate_1d_error(1.0,1.0); // make sure that C_p is defined
double k = q2*C_p/accuracy/sqrt(double(atom->natoms));
double sum = hx2pm2/Lx2 + hy2pm2/Ly2 + hz2pm2/Lz2;
cutoff = pow(k*k*sum/3.0,1.0/(2.0*p));
int itmp;
double *p_cutoff = (double *) force->pair->extract("cut_coul",itmp);
*p_cutoff = cutoff;
char str[128];
sprintf(str,"Adjusting Coulombic cutoff for MSM, new cutoff = %g",cutoff);
if (me == 0) error->warning(FLERR,str);
}
if (triclinic == 0) {
h_x = xprd/nx_max;
@ -2265,7 +2238,7 @@ void MSM::restriction(int n)
{
//fprintf(screen,"Restricting from level %i to %i\n\n",n,n+1);
const int p = order-1;
int p = order-1;
double ***qgrid1 = qgrid[n];
double ***qgrid2 = qgrid[n+1];
@ -2287,8 +2260,7 @@ void MSM::restriction(int n)
// zero out charge on coarser grid
memset(&(qgrid2[nzlo_out[n+1]][nylo_out[n+1]][nxlo_out[n+1]]),0,
ngrid[n+1]*sizeof(double));
memset(&(qgrid2[nzlo_out[n+1]][nylo_out[n+1]][nxlo_out[n+1]]),0,ngrid[n+1]*sizeof(double));
for (kp = nzlo_in[n+1]; kp <= nzhi_in[n+1]; kp++)
for (jp = nylo_in[n+1]; jp <= nyhi_in[n+1]; jp++)
@ -2339,7 +2311,7 @@ void MSM::prolongation(int n)
{
//fprintf(screen,"Prolongating from level %i to %i\n\n",n+1,n);
const int p = order-1;
int p = order-1;
double ***egrid1 = egrid[n];
double ***egrid2 = egrid[n+1];

View File

@ -46,6 +46,7 @@ class MSM : public KSpace {
double volume;
double *delxinv,*delyinv,*delzinv;
double h_x,h_y,h_z;
double C_p;
int *nx_msm,*ny_msm,*nz_msm;
int *nxlo_in,*nylo_in,*nzlo_in;
@ -97,7 +98,6 @@ class MSM : public KSpace {
void set_proc_grid(int);
void set_grid_local();
void setup_grid();
double estimate_cutoff(double,double);
double estimate_1d_error(double,double);
double estimate_3d_error();
double estimate_total_error();

File diff suppressed because it is too large Load Diff

View File

@ -1,204 +1,204 @@
/* -*- 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.
------------------------------------------------------------------------- */
#ifndef LMP_KSPACE_H
#define LMP_KSPACE_H
#include "pointers.h"
#ifdef FFT_SINGLE
typedef float FFT_SCALAR;
#define MPI_FFT_SCALAR MPI_FLOAT
#else
typedef double FFT_SCALAR;
#define MPI_FFT_SCALAR MPI_DOUBLE
#endif
namespace LAMMPS_NS {
class KSpace : protected Pointers {
friend class ThrOMP;
friend class FixOMP;
public:
double energy; // accumulated energies
double energy_1,energy_6;
double virial[6]; // accumlated virial
double *eatom,**vatom; // accumulated per-atom energy/virial
double e2group; // accumulated group-group energy
double f2group[3]; // accumulated group-group force
int triclinic_support; // 1 if supports triclinic geometries
int ewaldflag; // 1 if a Ewald solver
int pppmflag; // 1 if a PPPM solver
int msmflag; // 1 if a MSM solver
int dispersionflag; // 1 if a LJ/dispersion solver
int tip4pflag; // 1 if a TIP4P solver
int dipoleflag; // 1 if a dipole solver
int differentiation_flag;
int slabflag;
double slab_volfactor;
int order,order_6;
double accuracy; // accuracy of KSpace solver (force units)
double accuracy_absolute; // user-specifed accuracy in force units
double accuracy_relative; // user-specified dimensionless accuracy
// accurary = acc_rel * two_charge_force
double two_charge_force; // force in user units of two point
// charges separated by 1 Angstrom
double g_ewald,g_ewald_6;
int nx_pppm,ny_pppm,nz_pppm; // global FFT grid for Coulombics
int nx_pppm_6,ny_pppm_6,nz_pppm_6; // global FFT grid for dispersion
int nx_msm_max,ny_msm_max,nz_msm_max;
int group_group_enable; // 1 if style supports group/group calculation
unsigned int datamask;
unsigned int datamask_ext;
int compute_flag; // 0 if skip compute()
int fftbench; // 0 if skip FFT timing
int stagger_flag; // 1 if using staggered PPPM grids
KSpace(class LAMMPS *, int, char **);
virtual ~KSpace();
void triclinic_check();
void modify_params(int, char **);
void *extract(const char *);
void compute_dummy(int, int);
// triclinic
void x2lamdaT(double *, double *);
void lamda2xT(double *, double *);
void lamda2xvector(double *, double *);
void kspacebbox(double, double *);
// general child-class methods
virtual void init() = 0;
virtual void setup() = 0;
virtual void setup_grid() {};
virtual void compute(int, int) = 0;
virtual void compute_group_group(int, int, int) {};
virtual void pack_forward(int, FFT_SCALAR *, int, int *) {};
virtual void unpack_forward(int, FFT_SCALAR *, int, int *) {};
virtual void pack_reverse(int, FFT_SCALAR *, int, int *) {};
virtual void unpack_reverse(int, FFT_SCALAR *, int, int *) {};
virtual int timing(int, double &, double &) {return 0;}
virtual int timing_1d(int, double &) {return 0;}
virtual int timing_3d(int, double &) {return 0;}
virtual double memory_usage() {return 0.0;}
/* ----------------------------------------------------------------------
compute gamma for MSM and pair styles
see Eq 4 from Parallel Computing 35 (2009) 164–177
------------------------------------------------------------------------- */
double gamma(const double &rho) const {
if (rho <= 1.0) {
const int split_order = order/2;
const double rho2 = rho*rho;
double g = gcons[split_order][0];
double rho_n = rho2;
for (int n=1; n<=split_order; n++) {
g += gcons[split_order][n]*rho_n;
rho_n *= rho2;
}
return g;
} else
return (1.0/rho);
}
/* ----------------------------------------------------------------------
compute the derivative of gamma for MSM and pair styles
see Eq 4 from Parallel Computing 35 (2009) 164-177
------------------------------------------------------------------------- */
double dgamma(const double &rho) const {
if (rho <= 1.0) {
const int split_order = order/2;
const double rho2 = rho*rho;
double dg = dgcons[split_order][0]*rho;
double rho_n = rho*rho2;
for (int n=1; n<split_order; n++) {
dg += dgcons[split_order][n]*rho_n;
rho_n *= rho2;
}
return dg;
} else
return (-1.0/rho/rho);
}
protected:
int gridflag,gridflag_6;
int gewaldflag,gewaldflag_6;
int minorder,overlap_allowed;
int adjust_cutoff_flag;
int suffix_flag; // suffix compatibility flag
double scale;
double **gcons,**dgcons; // accumulated per-atom energy/virial
int evflag,evflag_atom;
int eflag_either,eflag_global,eflag_atom;
int vflag_either,vflag_global,vflag_atom;
int maxeatom,maxvatom;
void pair_check();
void ev_setup(int, int);
double estimate_table_accuracy(double, double);
};
}
#endif
/* ERROR/WARNING messages:
E: KSpace style does not yet support triclinic geometries
UNDOCUMENTED
E: KSpace solver requires a pair style
No pair style is defined.
E: KSpace style is incompatible with Pair style
Setting a kspace style requires that a pair style with a long-range
Coulombic or dispersion component be used.
W: For better accuracy use 'pair_modify table 0'
The user-specified force accuracy cannot be achieved unless the table
feature is disabled by using 'pair_modify table 0'.
E: Illegal ... command
Self-explanatory. Check the input script syntax and compare to the
documentation for the command. You can use -echo screen as a
command-line option when running LAMMPS to see the offending line.
E: Bad kspace_modify slab parameter
Kspace_modify value for the slab/volume keyword must be >= 2.0.
W: Kspace_modify slab param < 2.0 may cause unphysical behavior
The kspace_modify slab parameter should be larger to insure periodic
grids padded with empty space do not overlap.
*/
/* -*- 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.
------------------------------------------------------------------------- */
#ifndef LMP_KSPACE_H
#define LMP_KSPACE_H
#include "pointers.h"
#ifdef FFT_SINGLE
typedef float FFT_SCALAR;
#define MPI_FFT_SCALAR MPI_FLOAT
#else
typedef double FFT_SCALAR;
#define MPI_FFT_SCALAR MPI_DOUBLE
#endif
namespace LAMMPS_NS {
class KSpace : protected Pointers {
friend class ThrOMP;
friend class FixOMP;
public:
double energy; // accumulated energies
double energy_1,energy_6;
double virial[6]; // accumlated virial
double *eatom,**vatom; // accumulated per-atom energy/virial
double e2group; // accumulated group-group energy
double f2group[3]; // accumulated group-group force
int triclinic_support; // 1 if supports triclinic geometries
int ewaldflag; // 1 if a Ewald solver
int pppmflag; // 1 if a PPPM solver
int msmflag; // 1 if a MSM solver
int dispersionflag; // 1 if a LJ/dispersion solver
int tip4pflag; // 1 if a TIP4P solver
int dipoleflag; // 1 if a dipole solver
int differentiation_flag;
int slabflag;
double slab_volfactor;
int order,order_6,order_allocated;
double accuracy; // accuracy of KSpace solver (force units)
double accuracy_absolute; // user-specifed accuracy in force units
double accuracy_relative; // user-specified dimensionless accuracy
// accurary = acc_rel * two_charge_force
double two_charge_force; // force in user units of two point
// charges separated by 1 Angstrom
double g_ewald,g_ewald_6;
int nx_pppm,ny_pppm,nz_pppm; // global FFT grid for Coulombics
int nx_pppm_6,ny_pppm_6,nz_pppm_6; // global FFT grid for dispersion
int nx_msm_max,ny_msm_max,nz_msm_max;
int group_group_enable; // 1 if style supports group/group calculation
unsigned int datamask;
unsigned int datamask_ext;
int compute_flag; // 0 if skip compute()
int fftbench; // 0 if skip FFT timing
int stagger_flag; // 1 if using staggered PPPM grids
KSpace(class LAMMPS *, int, char **);
virtual ~KSpace();
void triclinic_check();
void modify_params(int, char **);
void *extract(const char *);
void compute_dummy(int, int);
// triclinic
void x2lamdaT(double *, double *);
void lamda2xT(double *, double *);
void lamda2xvector(double *, double *);
void kspacebbox(double, double *);
// general child-class methods
virtual void init() = 0;
virtual void setup() = 0;
virtual void setup_grid() {};
virtual void compute(int, int) = 0;
virtual void compute_group_group(int, int, int) {};
virtual void pack_forward(int, FFT_SCALAR *, int, int *) {};
virtual void unpack_forward(int, FFT_SCALAR *, int, int *) {};
virtual void pack_reverse(int, FFT_SCALAR *, int, int *) {};
virtual void unpack_reverse(int, FFT_SCALAR *, int, int *) {};
virtual int timing(int, double &, double &) {return 0;}
virtual int timing_1d(int, double &) {return 0;}
virtual int timing_3d(int, double &) {return 0;}
virtual double memory_usage() {return 0.0;}
/* ----------------------------------------------------------------------
compute gamma for MSM and pair styles
see Eq 4 from Parallel Computing 35 (2009) 164–177
------------------------------------------------------------------------- */
double gamma(const double &rho) const {
if (rho <= 1.0) {
const int split_order = order/2;
const double rho2 = rho*rho;
double g = gcons[split_order][0];
double rho_n = rho2;
for (int n=1; n<=split_order; n++) {
g += gcons[split_order][n]*rho_n;
rho_n *= rho2;
}
return g;
} else
return (1.0/rho);
}
/* ----------------------------------------------------------------------
compute the derivative of gamma for MSM and pair styles
see Eq 4 from Parallel Computing 35 (2009) 164-177
------------------------------------------------------------------------- */
double dgamma(const double &rho) const {
if (rho <= 1.0) {
const int split_order = order/2;
const double rho2 = rho*rho;
double dg = dgcons[split_order][0]*rho;
double rho_n = rho*rho2;
for (int n=1; n<split_order; n++) {
dg += dgcons[split_order][n]*rho_n;
rho_n *= rho2;
}
return dg;
} else
return (-1.0/rho/rho);
}
protected:
int gridflag,gridflag_6;
int gewaldflag,gewaldflag_6;
int minorder,overlap_allowed;
int adjust_cutoff_flag;
int suffix_flag; // suffix compatibility flag
double scale;
double **gcons,**dgcons; // accumulated per-atom energy/virial
int evflag,evflag_atom;
int eflag_either,eflag_global,eflag_atom;
int vflag_either,vflag_global,vflag_atom;
int maxeatom,maxvatom;
void pair_check();
void ev_setup(int, int);
double estimate_table_accuracy(double, double);
};
}
#endif
/* ERROR/WARNING messages:
E: KSpace style does not yet support triclinic geometries
UNDOCUMENTED
E: KSpace solver requires a pair style
No pair style is defined.
E: KSpace style is incompatible with Pair style
Setting a kspace style requires that a pair style with a long-range
Coulombic or dispersion component be used.
W: For better accuracy use 'pair_modify table 0'
The user-specified force accuracy cannot be achieved unless the table
feature is disabled by using 'pair_modify table 0'.
E: Illegal ... command
Self-explanatory. Check the input script syntax and compare to the
documentation for the command. You can use -echo screen as a
command-line option when running LAMMPS to see the offending line.
E: Bad kspace_modify slab parameter
Kspace_modify value for the slab/volume keyword must be >= 2.0.
W: Kspace_modify slab param < 2.0 may cause unphysical behavior
The kspace_modify slab parameter should be larger to insure periodic
grids padded with empty space do not overlap.
*/