@@ -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 )
0 commit comments