@@ -1065,10 +1065,50 @@ def _higher(
10651065 except :
10661066 connectivity = mol .property ("connectivity" )
10671067
1068+ # First loop over all of the physical atoms connected to the bridge atom
1069+ # to determine whether any aren't bonded to ghost atoms. This avoids
1070+ # removing angle and dihedral terms when it's not necessary.
1071+
1072+ # Count of disconnected physical atoms.
1073+ num_disconnected = 0
1074+
1075+ for idx in physical :
1076+ # Get the angles and dihedrals.
1077+ angles = mol .property ("angle" + suffix )
1078+ dihedrals = mol .property ("dihedral" + suffix )
1079+
1080+ connected_to_ghost = False
1081+
1082+ # Angles.
1083+ for p in angles .potentials ():
1084+ idx0 = info .atom_idx (p .atom0 ())
1085+ idx1 = info .atom_idx (p .atom1 ())
1086+ idx2 = info .atom_idx (p .atom2 ())
1087+
1088+ if idx == idx0 and idx2 in ghosts or idx == idx2 and idx0 in ghosts :
1089+ connected_to_ghost = True
1090+ break
1091+
1092+ # Dihedrals.
1093+ if not connected_to_ghost :
1094+ for p in dihedrals .potentials ():
1095+ idx0 = info .atom_idx (p .atom0 ())
1096+ idx1 = info .atom_idx (p .atom1 ())
1097+ idx2 = info .atom_idx (p .atom2 ())
1098+ idx3 = info .atom_idx (p .atom3 ())
1099+ idxs = [idx0 , idx1 , idx2 , idx3 ]
1100+
1101+ if idx in idxs and any ([x in ghosts for x in idxs ]):
1102+ connected_to_ghost = True
1103+ break
1104+
1105+ if not connected_to_ghost :
1106+ num_disconnected += 1
1107+
10681108 # Now remove all bonded interactions between the ghost atoms and one of the
10691109 # physical atoms connected to the bridge atom, hence reducing the problem to
10701110 # that of a triple junction.
1071- while len (physical ) > 3 :
1111+ while len (physical ) - num_disconnected > 3 :
10721112 # Pop the first physical atom index from the list.
10731113 idx = physical .pop (0 )
10741114
0 commit comments