Correct calculation of cut off distance
This commit is contained in:
@ -51,18 +51,19 @@ using namespace FixConst;
|
||||
static constexpr double CONV_TO_EV = 14.4;
|
||||
static constexpr double SMALL = 1.0e-14;
|
||||
static constexpr double QSUMSMALL = 0.00001;
|
||||
static constexpr double ANGSTROM_TO_BOHRRADIUS = 1.8897261259;
|
||||
|
||||
static const char cite_fix_qtpie_reaxff[] =
|
||||
"fix qtpie/reaxff command: doi:https://doi.org/10.1016/j.cplett.2007.02.065\n\n"
|
||||
"@article{chen2007qtpie,\n"
|
||||
"title={QTPIE: Charge transfer with polarization current equalization. A fluctuating charge model with correct asymptotics},\n"
|
||||
"author={Chen, Jiahao and Martinez, Todd J},\n"
|
||||
"journal={Chemical physics letters},\n"
|
||||
"volume={438},\n"
|
||||
"number={4-6},\n"
|
||||
"pages={315--320},\n"
|
||||
"year={2007},\n"
|
||||
"publisher={Elsevier}\n"
|
||||
"fix qtpie/reaxff command: doi\n\n"
|
||||
"@article{,\n"
|
||||
"title={},\n"
|
||||
"author={},\n"
|
||||
"journal={},\n"
|
||||
"volume={},\n"
|
||||
"number={},\n"
|
||||
"pages={},\n"
|
||||
"year={},\n"
|
||||
"publisher={}\n"
|
||||
"}\n\n";
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
@ -233,6 +234,12 @@ void FixQtpieReaxFF::pertype_parameters(char *arg)
|
||||
|
||||
MPI_Bcast(gauss_exp,ntypes+1,MPI_DOUBLE,0,world);
|
||||
|
||||
// define a cutoff distance (in atomic units) beyond which overlap integrals are neglected
|
||||
// in calc_chi_eff()
|
||||
const double emin = find_min(gauss_exp,ntypes+1);
|
||||
const int olap_cut = 10; // overlap integrals are neglected if less than pow(10,-olap_cut)
|
||||
dist_cutoff = sqrt(1/emin*log(pow(10.0,2.0*olap_cut)));
|
||||
|
||||
// read chi, eta and gamma
|
||||
|
||||
if (utils::strmatch(arg,"^reaxff")) {
|
||||
@ -1139,8 +1146,6 @@ void FixQtpieReaxFF::calc_chi_eff()
|
||||
{
|
||||
memset(&chi_eff[0],0,atom->nmax*sizeof(double));
|
||||
|
||||
const int KSCREEN = 10;
|
||||
const double ANG_TO_BOHRRAD = 1.8897259886; // 1 Ang = 1.8897259886 Bohr radius
|
||||
const auto x = (const double * const *)atom->x;
|
||||
const int ntypes = atom->ntypes;
|
||||
const int *type = atom->type;
|
||||
@ -1148,6 +1153,14 @@ void FixQtpieReaxFF::calc_chi_eff()
|
||||
double dist,overlap,sum_n,sum_d,ea,eb,chia,chib,phia,phib,p,m;
|
||||
int i,j;
|
||||
|
||||
// check ghost atoms are stored up to the distance cutoff for overlap integrals
|
||||
const double comm_cutoff = MAX(neighbor->cutneighmax,comm->cutghostuser);
|
||||
if(comm_cutoff < dist_cutoff/ANGSTROM_TO_BOHRRADIUS) {
|
||||
error->all(FLERR,"comm cutoff = {} Angstrom is smaller than distance cutoff = {} Angstrom "
|
||||
"for overlap integrals in {}. Increase comm cutoff with comm_modify",
|
||||
comm_cutoff, dist_cutoff/ANGSTROM_TO_BOHRRADIUS, style);
|
||||
}
|
||||
|
||||
// efield energy is in real units of kcal/mol, factor needed for conversion to eV
|
||||
const double qe2f = force->qe2f;
|
||||
const double factor = 1.0/qe2f;
|
||||
@ -1157,17 +1170,6 @@ void FixQtpieReaxFF::calc_chi_eff()
|
||||
efield->update_efield_variables();
|
||||
}
|
||||
|
||||
// use integral pre-screening for overlap calculations
|
||||
const double emin = find_min(gauss_exp,ntypes+1);
|
||||
const double dist_cutoff = sqrt(pow(emin,-1.0)*log(pow(M_PI/(2.0*emin),3.0)*pow(10.0,2.0*KSCREEN)));
|
||||
|
||||
const double comm_cutoff = MAX(neighbor->cutneighmax,comm->cutghostuser);
|
||||
if(comm_cutoff < dist_cutoff/ANG_TO_BOHRRAD) {
|
||||
error->all(FLERR,"comm cutoff = {} Angstrom is smaller than distance cutoff = {} Angstrom "
|
||||
"for overlap integral in {}. Increase comm cutoff with comm_modify",
|
||||
comm_cutoff, dist_cutoff/ANG_TO_BOHRRAD, style);
|
||||
}
|
||||
|
||||
// compute chi_eff for each local atom
|
||||
for (i = 0; i < nn; i++) {
|
||||
ea = gauss_exp[type[i]];
|
||||
@ -1184,23 +1186,17 @@ void FixQtpieReaxFF::calc_chi_eff()
|
||||
sum_d = 0.0;
|
||||
|
||||
for (j = 0; j < nt; j++) {
|
||||
dist = distance(x[i],x[j])*ANG_TO_BOHRRAD; // distance between atoms as a multiple of Bohr radius
|
||||
dist = distance(x[i],x[j])*ANGSTROM_TO_BOHRRADIUS; // in atomic units
|
||||
|
||||
if (dist < dist_cutoff) {
|
||||
eb = gauss_exp[type[j]];
|
||||
chib = chi[type[j]];
|
||||
|
||||
// The expressions below are in atomic units
|
||||
// Implementation from Chen Jiahao, Theory and applications of fluctuating-charge models, 2009 (with normalization constants added)
|
||||
// overlap integral of two normalised 1s Gaussian type orbitals
|
||||
p = ea + eb;
|
||||
m = ea * eb / p;
|
||||
overlap = pow((4.0*m/p),0.75) * exp(-m*dist*dist);
|
||||
|
||||
// Implementation from T. Halgaker et al., Molecular electronic-structure theory, 2000
|
||||
// p = ea + eb;
|
||||
// m = ea * eb / p;
|
||||
// Overlap = pow((M_PI / p), 1.5) * exp(-m * R * R);
|
||||
|
||||
if (efield) {
|
||||
if (efield->varflag != FixEfield::ATOM) {
|
||||
phib = factor*(x[j][0]*efield->ex + x[j][1]*efield->ey + x[j][2]*efield->ez);
|
||||
@ -1226,11 +1222,11 @@ void FixQtpieReaxFF::calc_chi_eff()
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
double FixQtpieReaxFF::find_min(double *array, int array_length)
|
||||
double FixQtpieReaxFF::find_min(const double *array, const int array_length)
|
||||
{
|
||||
// since types start from 1, gaussian exponents start from 1
|
||||
// index of first gaussian orbital exponent is 1
|
||||
double smallest = array[1];
|
||||
for (int i = 1; i < array_length; i++)
|
||||
for (int i = 2; i < array_length; i++)
|
||||
{
|
||||
if (array[i] < smallest)
|
||||
smallest = array[i];
|
||||
|
||||
@ -82,15 +82,16 @@ class FixQtpieReaxFF : public Fix {
|
||||
double *Hdia_inv;
|
||||
double *b_s, *b_t;
|
||||
double *b_prc, *b_prm;
|
||||
double *chi_eff; // array of effective electronegativities
|
||||
double *chi_eff; // array of effective electronegativities
|
||||
|
||||
//CG storage
|
||||
double *p, *q, *r, *d;
|
||||
int imax, maxwarn;
|
||||
|
||||
char *pertype_option; // argument to determine how per-type info is obtained
|
||||
char *gauss_file; // input file for gaussian exponents
|
||||
double *gauss_exp; // array of gaussian exponents
|
||||
char *gauss_file; // input file for gaussian orbital exponents
|
||||
double *gauss_exp; // array of gaussian orbital exponents for each atom type
|
||||
double dist_cutoff; // separation distance beyond which to neglect overlap integrals
|
||||
|
||||
void pertype_parameters(char *);
|
||||
void init_shielding();
|
||||
@ -129,7 +130,7 @@ class FixQtpieReaxFF : public Fix {
|
||||
void vector_add(double *, double, double *, int);
|
||||
|
||||
void calc_chi_eff();
|
||||
double find_min(double*, int);
|
||||
double find_min(const double*, const int);
|
||||
double distance(const double*, const double*);
|
||||
|
||||
int matvecs_s, matvecs_t; // Iteration count for each system
|
||||
|
||||
Reference in New Issue
Block a user