Skip to content

Commit 04005de

Browse files
committed
update for average charge
1 parent 3a9fb62 commit 04005de

4 files changed

Lines changed: 35 additions & 11 deletions

File tree

deepmd/pt/model/model/sog_model.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,13 +180,19 @@ def _corr_redu(positions: torch.Tensor, charges: torch.Tensor) -> torch.Tensor:
180180
)
181181
corr_redu = _corr_redu(coord_for_grad, latent_charge)
182182

183-
force_local = -torch.autograd.grad(
183+
grad_result = torch.autograd.grad(
184184
[corr_redu],
185185
[coord_for_grad],
186186
grad_outputs=[torch.ones_like(corr_redu)],
187187
create_graph=self.training,
188188
retain_graph=True,
189+
allow_unused=True,
189190
)[0]
191+
force_local = (
192+
-grad_result
193+
if grad_result is not None
194+
else torch.zeros_like(coord_for_grad)
195+
)
190196
out: dict[str, torch.Tensor] = {"corr_redu": corr_redu}
191197
out["force_local"] = force_local
192198
if need_virial:

deepmd/pt/model/task/lr_fitting.py

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ def __init__(
129129
type_map: list[str] | None = None,
130130
use_aparam_as_mask: bool = False,
131131
default_fparam: list[float] | None = None,
132+
use_charge_constraint: bool = False,
132133
**kwargs: Any,
133134
) -> None:
134135
super().__init__()
@@ -159,6 +160,7 @@ def __init__(
159160
all(self.trainable) if isinstance(self.trainable, list) else self.trainable
160161
)
161162
self.remove_vaccum_contribution = remove_vaccum_contribution
163+
self.use_charge_constraint = bool(use_charge_constraint)
162164
self.bias_atom_q_bound = 3.0
163165

164166
self.sr_net_dim_out = self._sr_net_out_dim()
@@ -393,6 +395,7 @@ def serialize(self) -> dict:
393395
"trainable_lr": [self.trainable] * (len(self.neuron_lr) + 1),
394396
"layer_name": None,
395397
"use_aparam_as_mask": self.use_aparam_as_mask,
398+
"use_charge_constraint": self.use_charge_constraint,
396399
"spin": None,
397400
}
398401

@@ -402,6 +405,8 @@ def deserialize(cls, data: dict) -> "LRFittingNet":
402405
# Compatibility with old checkpoints.
403406
data.pop("use_type_embed_for_bias_q", None)
404407
data.pop("bias_atom_q_type_embed", None)
408+
if "use_charge_constraint" not in data:
409+
data["use_charge_constraint"] = False
405410
variables = data.pop("@variables")
406411
nets_sr = data.pop("nets_sr")
407412
nets_lr = data.pop("nets_lr")
@@ -657,16 +662,17 @@ def _forward_common(
657662
lr_out = lr_out + self._get_lr_bias(atype)
658663

659664
# Hard charge constraint: enforce sum of latent charges equals target total charge.
660-
q_mean = lr_out.mean(dim=1) # [nf, lr_net_dim_out]
661-
q_target_per_atom = target_total_charge / float(nloc) # [nf]
662-
if lr_out.shape[-1] > 1:
663-
correction = torch.zeros_like(lr_out)
664-
correction[:, :, 0] = q_mean[:, 0] - q_target_per_atom
665-
lr_out = lr_out - correction
666-
else:
667-
q_mean = q_mean.unsqueeze(1) # [nf, 1, 1]
668-
target = q_target_per_atom.view(nf, 1, 1)
669-
lr_out = lr_out - (q_mean - target)
665+
if self.use_charge_constraint:
666+
q_mean = lr_out.mean(dim=1) # [nf, lr_net_dim_out]
667+
q_target_per_atom = target_total_charge / float(nloc) # [nf]
668+
if lr_out.shape[-1] > 1:
669+
correction = torch.zeros_like(lr_out)
670+
correction[:, :, 0] = q_mean[:, 0] - q_target_per_atom
671+
lr_out = lr_out - correction
672+
else:
673+
q_mean = q_mean.unsqueeze(1) # [nf, 1, 1]
674+
target = q_target_per_atom.view(nf, 1, 1)
675+
lr_out = lr_out - (q_mean - target)
670676

671677
mask = self.emask(atype).to(torch.bool)
672678
sr_out = torch.where(mask[:, :, None], sr_out, 0.0)

deepmd/pt/model/task/sog_energy_fitting.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ def __init__(
140140
M: int | None = None,
141141
n_dl: float | int = 1.0,
142142
remove_self_interaction: bool = False,
143+
use_charge_constraint: bool = False,
143144
**kwargs: Any,
144145
) -> None:
145146
super().__init__(
@@ -167,6 +168,7 @@ def __init__(
167168
type_map=type_map,
168169
use_aparam_as_mask=use_aparam_as_mask,
169170
default_fparam=default_fparam,
171+
use_charge_constraint=use_charge_constraint,
170172
**kwargs,
171173
)
172174
if b is None:

deepmd/utils/argcheck.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2131,6 +2131,9 @@ def fitting_sog_energy() -> list[Argument]:
21312131
doc_remove_self_interaction = (
21322132
"Whether to remove self interaction term in long-range correction."
21332133
)
2134+
doc_use_charge_constraint = (
2135+
"Whether to enforce the sum of latent charges equals the target total charge (from fparam column 0)."
2136+
)
21342137

21352138
return [
21362139
Argument(
@@ -2289,6 +2292,13 @@ def fitting_sog_energy() -> list[Argument]:
22892292
default=False,
22902293
doc=doc_only_pt_supported + doc_remove_self_interaction,
22912294
),
2295+
Argument(
2296+
"use_charge_constraint",
2297+
bool,
2298+
optional=True,
2299+
default=False,
2300+
doc=doc_only_pt_supported + doc_use_charge_constraint,
2301+
),
22922302
]
22932303

22942304

0 commit comments

Comments
 (0)