Skip to content

Commit 12e2fc7

Browse files
committed
Enhance SOG KSpace Implementation and Documentation
- Updated sog.h to include new methods and variables for improved functionality, including grid settings and spectral kernel calculations. - Added a comprehensive developer workflow document for building, validating, and debugging the SOG and LES kspace styles. - Introduced a detailed derivation document for the SOG discrete Green function on the internal mesh-FFT path, outlining the mathematical framework and implementation specifics.
1 parent 986f5d2 commit 12e2fc7

7 files changed

Lines changed: 1211 additions & 541 deletions

File tree

log.lammps

Lines changed: 34 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,65 +1,67 @@
11
LAMMPS (22 Jul 2025 - Update 4)
2-
using 1 OpenMP thread(s) per MPI task
3-
Loaded 0 plugins from /data/zyjin/dp_pt/dp_devel/deepmd-kit-devel/build/sog_lmp_stable/lmp/plugin
4-
units metal
5-
atom_style charge
6-
boundary p p p
7-
plugin load /data/zyjin/dp_pt/dp_devel/deepmd-kit-devel/build/sog_lmp_stable/lmp/plugin/libdeepmd_lmp.so
2+
units metal
3+
plugin load /data/zyjin/dp_pt/dp_devel/deepmd-kit-devel/build/sog_lmp_stable/lmp/plugin/libdeepmd_lmp.so
84
Loading plugin: deepmd pair style v3.1.3-83-g3cba3c7a-dirty by Han Wang
95
Loading plugin: deepspin pair style v3.1.3-83-g3cba3c7a-dirty by Duo Zhang
106
Loading plugin: compute deeptensor/atom v3.1.3-83-g3cba3c7a-dirty by Han Wang
117
Loading plugin: fix dplr v3.1.3-83-g3cba3c7a-dirty by Han Wang
128
Loading plugin: kspace pppm/dplr v3.1.3-83-g3cba3c7a-dirty by Han Wang
139
Loading plugin: kspace les v3.1.3-83-g3cba3c7a-dirty by DeepMD contributors
1410
Loading plugin: kspace sog v3.1.3-83-g3cba3c7a-dirty by DeepMD contributors
15-
region box block 0 5 0 5 0 5
16-
create_box 1 box
17-
Created orthogonal box = (0 0 0) to (5 5 5)
11+
atom_style charge
12+
region box block 0 10 0 10 0 10
13+
create_box 1 box
14+
Created orthogonal box = (0 0 0) to (10 10 10)
1815
1 by 1 by 1 MPI processor grid
19-
create_atoms 1 single 1 1 1
16+
create_atoms 1 single 5.0 5.0 5.0
2017
Created 1 atoms
21-
using lattice units in orthogonal box = (0 0 0) to (5 5 5)
18+
using lattice units in orthogonal box = (0 0 0) to (10 10 10)
2219
create_atoms CPU = 0.000 seconds
23-
set atom 1 charge 0.1
20+
mass 1 1.0
21+
set atom 1 charge 0.1
2422
Setting atom values ...
2523
1 settings made for charge
26-
mass 1 1.0
27-
pair_style coul/long 2.0
28-
pair_coeff * *
29-
kspace_style les 1e-6 n_dl 1.0 sigma 1.0 remove_self_interaction yes
30-
run 0
24+
25+
pair_style coul/long 6.0
26+
pair_coeff * *
27+
28+
kspace_style sog 1.0e-6 amp 0.1 bandwidth 0.5
29+
thermo_style custom step pe
30+
thermo 1
31+
run 0
3132
WARNING: No fixes with time integration, atoms won't move
3233
For more information see https://docs.lammps.org/err0028 (src/verlet.cpp:60)
3334
PPPM initialization ...
3435
WARNING: System is not charge neutral, net charge = 0.1
35-
For more information see https://docs.lammps.org/err0029 (src/kspace.cpp:330)
36+
For more information see https://docs.lammps.org/err0029 (src/kspace.cpp:335)
3637
using 12-bit tables for long-range coulomb
37-
G vector (1/distance) = 0.70710678
38-
grid = 8 8 8
38+
WARNING: For better accuracy use 'pair_modify table 0' (src/kspace.cpp:373)
39+
G vector (1/distance) = 1
40+
grid = 30 30 30
3941
stencil order = 5
40-
estimated absolute RMS force accuracy = 0.0024650382
41-
estimated relative force accuracy = 0.00017118743
42+
estimated absolute RMS force accuracy = 3.4929588e-07
43+
estimated relative force accuracy = 2.4257256e-08
4244
using double precision KISS FFT
43-
3d grid and FFT values/proc = 4913 512
45+
3d grid and FFT values/proc = 68921 27000
4446
Generated 0 of 0 mixed pair_coeff terms from geometric mixing rule
4547
Neighbor list info ...
4648
update: every = 1 steps, delay = 0 steps, check = yes
4749
max neighbors/atom: 2000, page size: 100000
48-
master list distance cutoff = 4
49-
ghost atom cutoff = 4
50-
binsize = 2, bins = 3 3 3
50+
master list distance cutoff = 8
51+
ghost atom cutoff = 8
52+
binsize = 4, bins = 3 3 3
5153
1 neighbor lists, perpetual/occasional/extra = 1 0 0
5254
(1) pair coul/long, perpetual
5355
attributes: half, newton on
5456
pair build: half/bin/atomonly/newton
5557
stencil: half/bin/3d
5658
bin: standard
57-
Per MPI rank memory allocation (min/avg/max) = 3.446 | 3.446 | 3.446 Mbytes
58-
Step Temp E_pair E_mol TotEng Press
59-
0 0 -0.040864926 0 -0.040864926 -127.91624
60-
Loop time of 1.292e-06 on 1 procs for 0 steps with 1 atoms
59+
Per MPI rank memory allocation (min/avg/max) = 8.426 | 8.426 | 8.426 Mbytes
60+
Step PotEng
61+
0 0.001285803
62+
Loop time of 1.302e-06 on 1 procs for 0 steps with 1 atoms
6163

62-
154.8% CPU use with 1 MPI tasks x 1 OpenMP threads
64+
153.6% CPU use with 1 MPI tasks x no OpenMP threads
6365

6466
MPI task timing breakdown:
6567
Section | min time | avg time | max time |%varavg| %total
@@ -70,7 +72,7 @@ Neigh | 0 | 0 | 0 | 0.0 | 0.00
7072
Comm | 0 | 0 | 0 | 0.0 | 0.00
7173
Output | 0 | 0 | 0 | 0.0 | 0.00
7274
Modify | 0 | 0 | 0 | 0.0 | 0.00
73-
Other | | 1.292e-06 | | |100.00
75+
Other | | 1.302e-06 | | |100.00
7476

7577
Nlocal: 1 ave 1 max 1 min
7678
Histogram: 1 0 0 0 0 0 0 0 0 0

source/lmp/pair_deepmd.cpp

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,14 @@
22
#include <string.h>
33

44
#include <cassert>
5+
#include <cctype>
6+
#include <cmath>
7+
#include <cstdlib>
58
#include <iomanip>
69
#include <iostream>
710
#include <limits>
811
#include <map>
12+
#include <regex>
913
#include <sstream>
1014

1115
#include "atom.h"
@@ -35,6 +39,21 @@
3539
using namespace LAMMPS_NS;
3640
using namespace std;
3741

42+
namespace {
43+
44+
bool has_json_suffix(const std::string& path) {
45+
if (path.size() < 5) {
46+
return false;
47+
}
48+
std::string suffix = path.substr(path.size() - 5);
49+
for (char& c : suffix) {
50+
c = static_cast<char>(std::tolower(static_cast<unsigned char>(c)));
51+
}
52+
return suffix == ".json";
53+
}
54+
55+
} // namespace
56+
3857
static const char cite_user_deepmd_package[] =
3958
"USER-DEEPMD package:\n\n"
4059
"@article{Wang_ComputPhysCommun_2018_v228_p178,\n"
@@ -121,12 +140,90 @@ PairDeepMD::PairDeepMD(LAMMPS* lmp)
121140
: PairDeepBaseModel(
122141
lmp, cite_user_deepmd_package, deep_pot, deep_pot_model_devi) {
123142
latent_charge_to_q = false;
143+
model_n_dl = 0.0;
144+
has_model_n_dl = 0;
124145
}
125146

126147
PairDeepMD::~PairDeepMD() {
127148
// Ensure base class destructor is called
128149
}
129150

151+
bool PairDeepMD::parse_model_n_dl_from_json(const std::string& model_path,
152+
double& n_dl_out) const {
153+
if (!has_json_suffix(model_path)) {
154+
return false;
155+
}
156+
157+
std::string content;
158+
try {
159+
deepmd_compat::read_file_to_string(model_path, content);
160+
} catch (...) {
161+
return false;
162+
}
163+
164+
static const std::regex n_dl_pattern(
165+
R"("n_dl"\s*:\s*([-+]?(?:\d+\.?\d*|\.\d+)(?:[eE][-+]?\d+)?))");
166+
167+
std::smatch match;
168+
if (!std::regex_search(content, match, n_dl_pattern)) {
169+
return false;
170+
}
171+
172+
const double candidate = std::strtod(match[1].str().c_str(), nullptr);
173+
if (!(std::isfinite(candidate) && candidate > 0.0)) {
174+
return false;
175+
}
176+
177+
n_dl_out = candidate;
178+
return true;
179+
}
180+
181+
void PairDeepMD::detect_model_n_dl(const std::vector<std::string>& models) {
182+
has_model_n_dl = 0;
183+
model_n_dl = 0.0;
184+
185+
double first_n_dl = 0.0;
186+
bool found = false;
187+
188+
for (const auto& model_path : models) {
189+
double parsed = 0.0;
190+
if (!parse_model_n_dl_from_json(model_path, parsed)) {
191+
continue;
192+
}
193+
if (!found) {
194+
first_n_dl = parsed;
195+
found = true;
196+
continue;
197+
}
198+
if (std::fabs(parsed - first_n_dl) > 1e-12 && comm->me == 0) {
199+
error->warning(
200+
FLERR,
201+
"pair_style deepmd found inconsistent n_dl across model JSON files; "
202+
"using the first model value");
203+
}
204+
}
205+
206+
if (found) {
207+
has_model_n_dl = 1;
208+
model_n_dl = first_n_dl;
209+
}
210+
}
211+
212+
void* PairDeepMD::extract(const char* str, int& dim) {
213+
if (strcmp(str, "deepmd_model_n_dl") == 0) {
214+
dim = 0;
215+
if (has_model_n_dl) {
216+
return (void*)&model_n_dl;
217+
}
218+
return nullptr;
219+
}
220+
if (strcmp(str, "deepmd_model_n_dl_available") == 0) {
221+
dim = 0;
222+
return (void*)&has_model_n_dl;
223+
}
224+
return PairDeepBaseModel::extract(str, dim);
225+
}
226+
130227
void PairDeepMD::compute(int eflag, int vflag) {
131228
if (numb_models == 0) {
132229
return;
@@ -615,6 +712,7 @@ void PairDeepMD::settings(int narg, char** arg) {
615712
for (int ii = 0; ii < iarg; ++ii) {
616713
models.push_back(arg[ii]);
617714
}
715+
detect_model_n_dl(models);
618716
numb_models = models.size();
619717
if (numb_models == 1) {
620718
try {

source/lmp/pair_deepmd.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ class PairDeepMD : public PairDeepBaseModel {
4444
public:
4545
PairDeepMD(class LAMMPS*);
4646
~PairDeepMD() override;
47+
void* extract(const char*, int&) override;
4748
void settings(int, char**) override;
4849
void coeff(int, char**) override;
4950
void compute(int, int) override;
@@ -55,8 +56,14 @@ class PairDeepMD : public PairDeepBaseModel {
5556
deepmd_compat::DeepPotModelDevi deep_pot_model_devi;
5657

5758
private:
59+
bool parse_model_n_dl_from_json(const std::string& model_path,
60+
double& n_dl_out) const;
61+
void detect_model_n_dl(const std::vector<std::string>& models);
62+
5863
CommBrickDeepMD* commdata_;
5964
bool latent_charge_to_q;
65+
double model_n_dl;
66+
int has_model_n_dl;
6067
};
6168

6269
} // namespace LAMMPS_NS

0 commit comments

Comments
 (0)