Dear Lammps user and developer,
I am currently working on modifying the pair_coul_long potential to describe the Coulomb interaction between 100 electrons and a large perovskite system. The goal is to add another cutoff distant to the pair_coul_long potential so that when the distance between an electron and perovskite atoms is smaller than cutoff1 (r<cutoff1 ), the E=q1q2/cutoff1 (constant) and F=0; while r>=cutoff1 and < cutoff2, E and F just follow the normal Coulomb interaction.
I am trying to achieve this in two ways:
The first one is modifying the pair_coul_long.cpp, by changing the PairCoulLong2::compute and PairCoulLong2::single subroutine, I can set the real space F=0 and E=E_cutoff1 when r<cutoff1. But I did not find an efficient way to modify the kspace energy and force.
I am also trying to let the real space F= - kspace F by defining a vector equals to “f2group” in the Ewlad.cpp and call this vector in the pair_coul_long.cpp:
Ewald::compute_group_group:
…
f2group[0] *= qscale;
f2group[1] *= qscale;
f2group[2] *= qscale;
yf2group[0] += f2group[0];
yf2group[1] += f2group[1];
yf2group[2] += f2group[2];
…
I also defined the yf2group vector in ksapce.h.
Then in PairCoulLong2::compute:
…
if (rsq < 9.61) {
r2inv = 1.0/9.61;
r = sqrt(9.61);
grij = g_ewald * r;
expm2 = exp(-grij*grij);
t = 1.0 / (1.0 + EWALD_P*grij);
erfc = t * (A1+t*(A2+t*(A3+t*(A4+t*A5)))) * expm2;
prefactor = qqrd2e * scale[itype][jtype] * qtmp*q[j]/r;
fpair = 0;
f[i][0] -= yvector_kspace[0];
f[i][1] -= yvector_kspace[1];
f[i][2] -= yvector_kspace[2];
if (newton_pair || j < nlocal) {
f[j][0] += yvector_kspace[0];
f[j][1] += yvector_kspace[1];
f[j][2] += yvector_kspace[2];
}
…
else if (rsq >= 9.61 && rsq < cut_coulsq) {
r2inv = 1.0/rsq;
r = sqrt(rsq);
grij = g_ewald * r;
expm2 = exp(-grij*grij);
t = 1.0 / (1.0 + EWALD_P*grij);
erfc = t * (A1+t*(A2+t*(A3+t*(A4+t*A5)))) * expm2;
prefactor = qqrd2e * scale[itype][jtype] * qtmp*q[j]/r;
forcecoul = prefactor * (erfc + EWALD_Fgrijexpm2);
…
But when I run the simulation, the kspace contribution is still there and when I echo the “yf2group”, it is 0. I think it might because the compute_group_group.cpp calculates the real space and kspace energy and force simultaneously, so I cannot let the real space force equals the negative force calculated by the kspace.cpp.
Is there any way to exclude the kspace force and energy when r smaller than cuoff1?
The other way is following the previous answer https://lammps.sandia.gov/threads/msg83130.html
you can use logical expressions in atom style and equal style expressions. here you need to use, of course, an atom style variable. those logicals would evaluate to either 1.0 (if true) or 0.0 (if false) and thus if you multiply those with the force contribution for a given section and sum each segment, you can define a piecewise force.
axel.
But I am not sure how to write the true or false command, like how to determine if the distance between each electron and each perovskite atoms is smaller than the cutoff1?
I am using lammps-7Aug19.
Does anyone have other suggestions than these two ways?
Thank you very much for your help!
Best,
Yang Hong