Skip to content

Commit d6d3eba

Browse files
committed
更新SOGKSpace以支持CubeS₂的cubes2_phi_max参数,重构核参数计算,添加自能量修正功能
1 parent f4ca744 commit d6d3eba

6 files changed

Lines changed: 329 additions & 53 deletions

File tree

deepmd/pt/model/model/sog_model.py

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -113,20 +113,31 @@ def _build_sog_lib_direct_kernel(
113113
dtype=real_dtype,
114114
)
115115

116-
kernel = sog_lib.Sog(
117-
sog_arguments={
118-
"use_atomwise": False,
119-
"n_dl": float(fitting.n_dl),
120-
"amp": amp_internal_runtime,
116+
nlayers = getattr(self.atomic_model.descriptor, "nlayers", 1) if hasattr(self.atomic_model, "descriptor") else 1
117+
# Build sog_arguments dict — prefer cubes2_phi_max, fall back to n_dl
118+
sog_args: dict = {
119+
"use_atomwise": False,
120+
"amp": amp_internal_runtime,
121121
"bandwidth": bw2_runtime,
122122
"kernel_param_mode": "internal",
123123
"kernel_tensor_mode": "external",
124124
"remove_self_interaction": bool(fitting.remove_self_interaction),
125125
"nufft": False,
126126
"use_nufft": False,
127+
"use_cubes2_fft": True,
128+
"nlayers": nlayers,
127129
"norm_factor": E2_PER_ANGSTROM_TO_EV,
128130
"trainable_kernel": False,
129-
},
131+
}
132+
# Prefer cubes2_phi_max (new API), fall back to n_dl (legacy)
133+
if getattr(fitting, "cubes2_phi_max", None) is not None:
134+
sog_args["cubes2_phi_max"] = float(fitting.cubes2_phi_max)
135+
elif getattr(fitting, "n_dl", None) is not None:
136+
sog_args["n_dl"] = float(fitting.n_dl)
137+
# else: auto-default from SOG lib's Table III
138+
139+
kernel = sog_lib.Sog(
140+
sog_arguments=sog_args,
130141
r_cut=float(self.get_rcut()),
131142
)
132143
return kernel

deepmd/pt/model/task/sog_energy_fitting.py

Lines changed: 30 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -101,8 +101,11 @@ class SOGEnergyFittingNet(LRFittingNet):
101101
Base bandwidth used by SOG parameterization.
102102
M : int
103103
Number of geometric bandwidth levels.
104-
n_dl : float
105-
NUFFT long-range grid density control factor.
104+
n_dl : float, optional (deprecated)
105+
Legacy grid density control. Use `cubes2_phi_max` instead.
106+
cubes2_phi_max : float, optional
107+
φ = Δ/r_c grid control factor. Auto-defaults from Predescu 2020 Table III
108+
when not specified. See sog lib documentation for recommended values.
106109
remove_self_interaction : bool
107110
If True, remove self interaction term in long-range correction.
108111
external_kspace : bool
@@ -141,7 +144,8 @@ def __init__(
141144
b: float | torch.Tensor | None = None,
142145
sigma: float | torch.Tensor | None = None,
143146
M: int | None = None,
144-
n_dl: float | int = 1.0,
147+
n_dl: float | int | None = None,
148+
cubes2_phi_max: float | None = None,
145149
remove_self_interaction: bool = False,
146150
external_kspace: bool = False,
147151
**kwargs: Any,
@@ -174,27 +178,25 @@ def __init__(
174178
**kwargs,
175179
)
176180
if b is None:
177-
b_tensor = torch.as_tensor(SOG_DEFAULT_B, dtype=dtype, device=device)
181+
b_value = SOG_DEFAULT_B # sog lib default (b=2)
178182
else:
179183
b_tensor = torch.as_tensor(b, dtype=dtype, device=device)
180-
if b_tensor.numel() == 0:
181-
b_tensor = torch.as_tensor(SOG_DEFAULT_B, dtype=dtype, device=device)
182-
b_value = float(b_tensor.reshape(-1)[0].item())
184+
b_value = float(b_tensor.reshape(-1)[0].item())
183185
if b_value <= 0.0:
184186
raise ValueError("`b` should be positive.")
185187

186188
if sigma is None:
187-
sigma_tensor = torch.as_tensor(SOG_DEFAULT_SIGMA, dtype=dtype, device=device)
189+
sigma_value = SOG_DEFAULT_SIGMA # will be overridden by sog lib via rcut
188190
else:
189191
sigma_tensor = torch.as_tensor(sigma, dtype=dtype, device=device)
190-
if sigma_tensor.numel() == 0:
191-
sigma_tensor = torch.as_tensor(SOG_DEFAULT_SIGMA, dtype=dtype, device=device)
192-
sigma_value = float(sigma_tensor.reshape(-1)[0].item())
192+
sigma_value = float(sigma_tensor.reshape(-1)[0].item())
193193
if sigma_value <= 0.0:
194194
raise ValueError("`sigma` should be positive.")
195195

196-
m_value = SOG_DEFAULT_M if M is None else int(M)
197-
m_value = max(1, m_value)
196+
if M is None:
197+
m_value = SOG_DEFAULT_M # sog lib default (M=12)
198+
else:
199+
m_value = max(1, int(M))
198200

199201
if bandwidth is None:
200202
b_base = torch.tensor(b_value, dtype=dtype, device=device)
@@ -233,11 +235,18 @@ def __init__(
233235
# Store amp as sog-lib internal amplitude (already includes bw^2 factor).
234236
amp_tensor *= bandwidth_tensor
235237

236-
n_dl_value = float(n_dl)
237-
if (not np.isfinite(n_dl_value)) or n_dl_value <= 0.0:
238-
raise ValueError("`n_dl` should be a positive finite number.")
238+
# Grid control: prefer cubes2_phi_max, fall back to n_dl (deprecated)
239+
if n_dl is not None:
240+
n_dl_value = float(n_dl)
241+
if (not np.isfinite(n_dl_value)) or n_dl_value <= 0.0:
242+
raise ValueError("`n_dl` should be a positive finite number.")
243+
if cubes2_phi_max is not None:
244+
phi_val = float(cubes2_phi_max)
245+
if (not np.isfinite(phi_val)) or phi_val <= 0.0:
246+
raise ValueError("`cubes2_phi_max` should be positive finite.")
239247

240-
self.n_dl = n_dl_value
248+
self.n_dl = float(n_dl) if n_dl is not None else None
249+
self.cubes2_phi_max = float(cubes2_phi_max) if cubes2_phi_max is not None else None
241250
self.amp = torch.nn.Parameter(
242251
amp_tensor,
243252
requires_grad=bool(self.trainable),
@@ -282,7 +291,10 @@ def serialize(self) -> dict:
282291
data["b"] = float(self.b)
283292
data["sigma"] = float(self.sigma)
284293
data["M"] = int(self.M)
285-
data["n_dl"] = self.n_dl
294+
if self.cubes2_phi_max is not None:
295+
data["cubes2_phi_max"] = self.cubes2_phi_max
296+
if self.n_dl is not None:
297+
data["n_dl"] = self.n_dl # legacy
286298
data["remove_self_interaction"] = bool(self.remove_self_interaction)
287299
data["external_kspace"] = bool(self.external_kspace)
288300
return data

deepmd/utils/argcheck.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2276,11 +2276,13 @@ def fitting_sog_energy() -> list[Argument]:
22762276
doc=doc_only_pt_supported + doc_M,
22772277
),
22782278
Argument(
2279-
"n_dl",
2279+
"cubes2_phi_max",
22802280
[float, int],
22812281
optional=True,
2282-
default=1.0,
2283-
doc=doc_only_pt_supported + doc_n_dl,
2282+
default=None,
2283+
doc=doc_only_pt_supported
2284+
+ "φ = Δ/r_c grid control for CubeS₂ FFT solver. "
2285+
+ "Auto-defaults from Predescu 2020 Table III when not set.",
22842286
),
22852287
Argument(
22862288
"remove_self_interaction",

source/build_pt_gcc13/log.lammps

Lines changed: 93 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,96 @@
1-
LAMMPS (30 Mar 2026 - Development - patch_30Mar2026-1074-g7f680de296)
1+
LAMMPS (30 Mar 2026 - Development - 7f680de296)
22
OMP_NUM_THREADS environment is not set. Defaulting to 1 thread.
33
using 1 OpenMP thread(s) per MPI task
4+
# Minimal SOG virial test: orthogonal box, single step.
5+
6+
units metal
7+
atom_style charge
8+
boundary p p p
9+
10+
plugin load /data/home/public/jiangzhen/dp/deepmd-kit/build/sog_lmp_develop_plugin/lmp/plugin/libdeepmd_lmp.so
11+
Loading plugin: deepmd pair style by Han Wang
12+
Loading plugin: deepspin pair style by Duo Zhang
13+
Loading plugin: compute deeptensor/atom by Han Wang
14+
Loading plugin: fix dplr by Han Wang
15+
Loading plugin: kspace pppm/dplr by Han Wang
16+
Loading plugin: kspace les by DeepMD contributors
17+
Loading plugin: kspace sog by DeepMD contributors
18+
19+
lattice fcc 4.0
20+
Lattice spacing in x,y,z = 4 4 4
21+
region box block 0 3 0 3 0 3
22+
create_box 1 box
23+
Created orthogonal box = (0 0 0) to (12 12 12)
24+
1 by 1 by 1 MPI processor grid
25+
create_atoms 1 random 256 12345 NULL
26+
Created 256 atoms
27+
using lattice units in orthogonal box = (0 0 0) to (12 12 12)
28+
create_atoms CPU = 0.000 seconds
29+
30+
mass 1 1.0
31+
set type 1 charge 0.5
32+
Setting atom values ...
33+
256 settings made for charge
34+
35+
pair_style coul/long 10.0
36+
pair_coeff 1 1
37+
kspace_style sog 1e-6 spline cubes2_4 b 2.0 m 12 n_dl 2.0 remove_self_interaction yes use_finufft no
38+
39+
neighbor 2.0 bin
40+
neigh_modify every 1 delay 0 check yes
41+
42+
timestep 0.001
43+
thermo 1
44+
45+
run 1
46+
WARNING: No fixes with time integration, atoms won't move
47+
For more information see https://docs.lammps.org/err0028 (src/verlet.cpp:60)
48+
WARNING: System is not charge neutral, net charge = 128
49+
For more information see https://docs.lammps.org/err0029 (src/kspace.cpp:328)
50+
Generated 0 of 0 mixed pair_coeff terms from geometric mixing rule
51+
Neighbor list info ...
52+
update: every = 1 steps, delay = 0 steps, check = yes
53+
max neighbors/atom: 2000, page size: 100000
54+
master list distance cutoff = 12
55+
ghost atom cutoff = 12
56+
binsize = 6, bins = 2 2 2
57+
1 neighbor lists, perpetual/occasional/extra = 1 0 0
58+
(1) pair coul/long, perpetual
59+
attributes: half, newton on
60+
pair build: half/bin/atomonly/newton
61+
stencil: half/bin/3d
62+
bin: standard
63+
SOG virial check (analytic vs r_i-F_i): xx: ana=-0.0630387 rF=-0.35395 diff=0.291 (82.19%) yy: ana=-0.0544381 rF=0.0280625 diff=-0.0825 (293.99%) zz: ana=0.0213709 rF=0.065452 diff=-0.0441 (67.35%) xy: ana=0.000874211 rF=0.128377 diff=-0.128 (99.32%) xz: ana=-0.000350028 rF=0.0197886 diff=-0.0201 (101.77%) yz: ana=0.00274303 rF=-0.0172367 diff=0.02 (115.91%)
64+
Per MPI rank memory allocation (min/avg/max) = 4.053 | 4.053 | 4.053 Mbytes
65+
Step Temp E_pair E_mol TotEng Press
66+
0 0 42582.875 0 42582.875 13200403
67+
SOG virial check (analytic vs r_i-F_i): xx: ana=-0.0630387 rF=-0.35395 diff=0.291 (82.19%) yy: ana=-0.0544381 rF=0.0280625 diff=-0.0825 (293.99%) zz: ana=0.0213709 rF=0.065452 diff=-0.0441 (67.35%) xy: ana=0.000874211 rF=0.128377 diff=-0.128 (99.32%) xz: ana=-0.000350028 rF=0.0197886 diff=-0.0201 (101.77%) yz: ana=0.00274303 rF=-0.0172367 diff=0.02 (115.91%)
68+
1 0 42582.875 0 42582.875 13200403
69+
Loop time of 0.00210485 on 1 procs for 1 steps with 256 atoms
70+
71+
Performance: 41.048 ns/day, 0.585 hours/ns, 475.093 timesteps/s, 121.624 katom-step/s
72+
99.2% CPU use with 1 MPI tasks x 1 OpenMP threads
73+
74+
MPI task timing breakdown:
75+
Section | min time | avg time | max time |%varavg| %total
76+
---------------------------------------------------------------
77+
Pair | 0.0018666 | 0.0018666 | 0.0018666 | 0.0 | 88.68
78+
Kspace | 0.00020703 | 0.00020703 | 0.00020703 | 0.0 | 9.84
79+
Neigh | 0 | 0 | 0 | 0.0 | 0.00
80+
Comm | 2.0878e-05 | 2.0878e-05 | 2.0878e-05 | 0.0 | 0.99
81+
Output | 4.647e-06 | 4.647e-06 | 4.647e-06 | 0.0 | 0.22
82+
Modify | 5.88e-07 | 5.88e-07 | 5.88e-07 | 0.0 | 0.03
83+
Other | | 5.057e-06 | | | 0.24
84+
85+
Nlocal: 256 ave 256 max 256 min
86+
Histogram: 1 0 0 0 0 0 0 0 0 0
87+
Nghost: 6656 ave 6656 max 6656 min
88+
Histogram: 1 0 0 0 0 0 0 0 0 0
89+
Neighs: 137723 ave 137723 max 137723 min
90+
Histogram: 1 0 0 0 0 0 0 0 0 0
91+
92+
Total # of neighbors = 137723
93+
Ave neighs/atom = 537.98047
94+
Neighbor list builds = 0
95+
Dangerous builds = 0
496
Total wall time: 0:00:00

0 commit comments

Comments
 (0)