lammps - MLIP-3 gives pressure at 0 K (the virial) possibly twice larger than the correct one?
Dear the developers of MLIP-3,
Thank you very much always for your help!
Using lammps with mlip force field, the pressure at 0 K, that is, the virial term, is twice larger than the output from mlip-2 and the stress obtained by the "mlp calculate_efs" command. Attached please find files for fcc Cu for reproduction.Cu_fcc_stress_discrepancy.zip
Details follow. Using the lammps, the pressure is -154834 bar at 0 K. (Please see the file Cu_fcc_stress_discrepancy/a_lammps_mlp3/log.lammps) At 0 K, the kinetic component of the pressure is zero, and this is the same as the virial (or 0 K pressure) (see https://docs.lammps.org/compute_pressure.html).
The virial can be also optained from the "mlp calculate_efs" command. This gives stress (Please see the file Cu_fcc_stress_discrepancy/b_mlip3_cfg_file/out.efs):
PlusStress: xx yy zz yz xz xy
-2.65141 -2.65141 -2.65141 0.00000 -0.00000 -0.00000
These are (pressure tensor) * (volume) in eV. The pressure p is the average of xx, yy, zz component of the pressure.
p V = - 2.65141 eV (per cell)
p = - 2.65141 eV / (3.8 Angstrom)^3
= - 2.65141 * 1.60218e-19 J / (3.8e-10 m)^3
= - 7.7417e9 Pa = - 77417 bar
(1 bar = 1e5 Pa)
2 p = - 154834 bar
So the lammps pressure is possibly twice large? Using lammps with mlip 2, -77417 bar is given. I tried to read the source code and find the reason, why the "virial" (?) variable is twice larger in pair_MLIP.cpp file, but it was not easy to find the reason.
It seems that, in the file ./LAMMPS/USER-MLIP/pair_MLIP.cpp, from the line 140, virial is probably added twice, first in virial_fdotr_compute() file, and then in the block below. So the second block was commented out, although I do not know which side effect it would have. Anyway then the virial was good, at least for the example. Would this be okay?
if (vflag_fdotr) virial_fdotr_compute();
// Comment out the following lines,
// because the virial term is added twice? In the pair_lj_cut.cpp
// file, in the PairLJCut::compute function, after virial_fdotr_compute(),
// the virial was not additionally added.
// The virial_fodtr_compute() function already computes the virial?
//
// if (vflag)
// {
// virial[0] += virstr[0];
// virial[1] += virstr[4];
// virial[2] += virstr[8];
// virial[3] += (virstr[1] + virstr[3]) / 2;
// virial[4] += (virstr[2] + virstr[6]) / 2;
// virial[5] += (virstr[5] + virstr[7]) / 2;
// }