@@ -379,7 +379,7 @@ def eval(
379379 else :
380380 if atomic_weight is not None :
381381 raise ValueError (
382- "atomic_weight is not supported when spin is provided. "
382+ "atomic_weight is not supported when spin is provided."
383383 )
384384 out = self ._eval_func (self ._eval_model_spin , numb_test , natoms )(
385385 coords ,
@@ -533,43 +533,9 @@ def _eval_model(
533533 else :
534534 aparam_input = None
535535 if atomic_weight is not None :
536- # Validate atomic_weight shape
537- if atomic_weight .ndim == 1 :
538- # (natoms,) - broadcast across frames
539- if atomic_weight .shape [0 ] != natoms :
540- raise ValueError (
541- f"atomic_weight shape { atomic_weight .shape } incompatible with number of atoms { natoms } "
542- )
543- atomic_weight = np .tile (atomic_weight , (nframes , 1 ))
544- elif atomic_weight .ndim == 2 :
545- # (nframes, natoms) or (natoms, k)
546- if (
547- atomic_weight .shape [0 ] == natoms
548- and atomic_weight .shape [1 ] != nframes
549- ):
550- # (natoms, k) - broadcast across frames
551- atomic_weight = np .tile (atomic_weight , (nframes , 1 , 1 ))
552- elif (
553- atomic_weight .shape [0 ] != nframes
554- or atomic_weight .shape [1 ] != natoms
555- ):
556- raise ValueError (
557- f"atomic_weight shape { atomic_weight .shape } incompatible with nframes={ nframes } and natoms={ natoms } "
558- )
559- elif atomic_weight .ndim == 3 :
560- # (nframes, natoms, k)
561- if (
562- atomic_weight .shape [0 ] != nframes
563- or atomic_weight .shape [1 ] != natoms
564- ):
565- raise ValueError (
566- f"atomic_weight shape { atomic_weight .shape } incompatible with nframes={ nframes } and natoms={ natoms } "
567- )
568- else :
569- raise ValueError (
570- f"atomic_weight must have 1, 2, or 3 dimensions, got { atomic_weight .ndim } "
571- )
572-
536+ atomic_weight = self ._validate_and_reshape_atomic_weight (
537+ atomic_weight , nframes , natoms
538+ )
573539 atomic_weight_input = to_torch_tensor (
574540 atomic_weight .reshape (nframes , natoms , - 1 )
575541 )
@@ -613,7 +579,6 @@ def _eval_model_spin(
613579 fparam : np .ndarray | None ,
614580 aparam : np .ndarray | None ,
615581 request_defs : list [OutputVariableDef ],
616- atomic_weight : Optional [np .ndarray ] = None ,
617582 ) -> tuple [np .ndarray , ...]:
618583 model = self .dp .to (DEVICE )
619584
@@ -655,49 +620,7 @@ def _eval_model_spin(
655620 )
656621 else :
657622 aparam_input = None
658- if atomic_weight is not None :
659- # Validate atomic_weight shape for spin model
660- if atomic_weight .ndim == 1 :
661- # (natoms,) - broadcast across frames
662- if atomic_weight .shape [0 ] != natoms :
663- raise ValueError (
664- f"atomic_weight shape { atomic_weight .shape } incompatible with number of atoms { natoms } "
665- )
666- atomic_weight = np .tile (atomic_weight , (nframes , 1 ))
667- elif atomic_weight .ndim == 2 :
668- # (nframes, natoms) or (natoms, k)
669- if (
670- atomic_weight .shape [0 ] == natoms
671- and atomic_weight .shape [1 ] != nframes
672- ):
673- # (natoms, k) - broadcast across frames
674- atomic_weight = np .tile (atomic_weight , (nframes , 1 , 1 ))
675- elif (
676- atomic_weight .shape [0 ] != nframes
677- or atomic_weight .shape [1 ] != natoms
678- ):
679- raise ValueError (
680- f"atomic_weight shape { atomic_weight .shape } incompatible with nframes={ nframes } and natoms={ natoms } "
681- )
682- elif atomic_weight .ndim == 3 :
683- # (nframes, natoms, k)
684- if (
685- atomic_weight .shape [0 ] != nframes
686- or atomic_weight .shape [1 ] != natoms
687- ):
688- raise ValueError (
689- f"atomic_weight shape { atomic_weight .shape } incompatible with nframes={ nframes } and natoms={ natoms } "
690- )
691- else :
692- raise ValueError (
693- f"atomic_weight must have 1, 2, or 3 dimensions, got { atomic_weight .ndim } "
694- )
695-
696- atomic_weight_input = to_torch_tensor (
697- atomic_weight .reshape (nframes , natoms , - 1 )
698- )
699- else :
700- atomic_weight_input = None
623+ atomic_weight_input = None
701624
702625 do_atomic_virial = any (
703626 x .category == OutputVariableCategory .DERV_C_REDU for x in request_defs
@@ -954,3 +877,60 @@ def eval_fitting_last_layer(
954877 fitting_net = model .eval_fitting_last_layer ()
955878 model .set_eval_fitting_last_layer_hook (False )
956879 return to_numpy_array (fitting_net )
880+
881+ def _validate_and_reshape_atomic_weight (
882+ self ,
883+ atomic_weight : np .ndarray ,
884+ nframes : int ,
885+ natoms : int ,
886+ ) -> np .ndarray :
887+ """Validate and reshape atomic_weight to (nframes, natoms, k).
888+
889+ Parameters
890+ ----------
891+ atomic_weight : np.ndarray
892+ Input atomic weights with various possible shapes
893+ nframes : int
894+ Number of frames
895+ natoms : int
896+ Number of atoms
897+
898+ Returns
899+ -------
900+ np.ndarray
901+ Reshaped atomic_weight with shape (nframes, natoms, k)
902+
903+ Raises
904+ ------
905+ ValueError
906+ If atomic_weight shape is incompatible
907+ """
908+ # Validate atomic_weight shape
909+ if atomic_weight .ndim == 1 :
910+ # (natoms,) - broadcast across frames
911+ if atomic_weight .shape [0 ] != natoms :
912+ raise ValueError (
913+ f"atomic_weight shape { atomic_weight .shape } incompatible with number of atoms { natoms } "
914+ )
915+ atomic_weight = np .tile (atomic_weight , (nframes , 1 ))
916+ elif atomic_weight .ndim == 2 :
917+ # (nframes, natoms) or (natoms, k)
918+ if atomic_weight .shape [0 ] == natoms and atomic_weight .shape [1 ] != nframes :
919+ # (natoms, k) - broadcast across frames
920+ atomic_weight = np .tile (atomic_weight , (nframes , 1 , 1 ))
921+ elif atomic_weight .shape [0 ] != nframes or atomic_weight .shape [1 ] != natoms :
922+ raise ValueError (
923+ f"atomic_weight shape { atomic_weight .shape } incompatible with nframes={ nframes } and natoms={ natoms } "
924+ )
925+ elif atomic_weight .ndim == 3 :
926+ # (nframes, natoms, k)
927+ if atomic_weight .shape [0 ] != nframes or atomic_weight .shape [1 ] != natoms :
928+ raise ValueError (
929+ f"atomic_weight shape { atomic_weight .shape } incompatible with nframes={ nframes } and natoms={ natoms } "
930+ )
931+ else :
932+ raise ValueError (
933+ f"atomic_weight must have 1, 2, or 3 dimensions, got { atomic_weight .ndim } "
934+ )
935+
936+ return atomic_weight
0 commit comments