@@ -298,15 +298,30 @@ def get_weighted_torques(data_container, bead, rot_axes, force_partitioning=0.5)
298298 """
299299 Function to calculate the moment of inertia weighted torques for a given bead.
300300
301- Input
302- -----
303- bead : the part of the molecule to be considered
304- rot_axes : the axes relative to which the forces and coordinates are located
305- frame : the frame number from the trajectory
306-
307- Output
308- ------
309- weighted_torque : the mass weighted sum of the torques in the bead
301+ This function computes torques in a rotated frame and then weights them using
302+ the moment of inertia tensor. To prevent numerical instability, it treats
303+ extremely small diagonal elements of the moment of inertia tensor as zero
304+ (since values below machine precision are effectively zero). This avoids
305+ unnecessary use of extended precision (e.g., float128).
306+
307+ Additionally, if the computed torque is already zero, the function skips
308+ the division step, reducing unnecessary computations and potential errors.
309+
310+ Parameters
311+ ----------
312+ data_container : object
313+ Contains atomic positions and forces.
314+ bead : object
315+ The part of the molecule to be considered.
316+ rot_axes : np.ndarray
317+ The axes relative to which the forces and coordinates are located.
318+ force_partitioning : float, optional
319+ Factor to adjust force contributions, default is 0.5.
320+
321+ Returns
322+ -------
323+ np.ndarray
324+ The mass-weighted sum of the torques in the bead.
310325 """
311326
312327 torques = np .zeros ((3 ,))
@@ -336,17 +351,30 @@ def get_weighted_torques(data_container, bead, rot_axes, force_partitioning=0.5)
336351 moment_of_inertia = bead .moment_of_inertia ()
337352
338353 for dimension in range (3 ):
339- # Check if the moment of inertia is valid for square root calculation
340- inertia_value = moment_of_inertia [dimension , dimension ]
354+ # Skip calculation if torque is already zero
355+ if np .isclose (torques [dimension ], 0 ):
356+ weighted_torque [dimension ] = 0
357+ continue
358+
359+ # Check for zero moment of inertia
360+ if np .isclose (moment_of_inertia [dimension , dimension ], 0 ):
361+ raise ZeroDivisionError (
362+ f"Attempted to divide by zero moment of inertia in dimension "
363+ f"{ dimension } ."
364+ )
341365
342- if np .isclose (inertia_value , 0 ):
366+ # Check for negative moment of inertia
367+ if moment_of_inertia [dimension , dimension ] < 0 :
343368 raise ValueError (
344- f"Invalid moment of inertia value: { inertia_value } . "
369+ f"Negative value encountered for moment of inertia: "
370+ f"{ moment_of_inertia [dimension , dimension ]} "
345371 f"Cannot compute weighted torque."
346372 )
347373
348- # compute weighted torque if moment of inertia is valid
349- weighted_torque [dimension ] = torques [dimension ] / np .sqrt (inertia_value )
374+ # Compute weighted torque
375+ weighted_torque [dimension ] = torques [dimension ] / np .sqrt (
376+ moment_of_inertia [dimension , dimension ]
377+ )
350378
351379 return weighted_torque
352380
0 commit comments