Skip to content

Commit 4214202

Browse files
fix(motor): enhance I_22 documentation for transverse inertia in ring clusters
1 parent da558ef commit 4214202

1 file changed

Lines changed: 44 additions & 4 deletions

File tree

rocketpy/motors/ring_cluster_motor.py

Lines changed: 44 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -115,10 +115,50 @@ def _evaluate_propellant_inertia(self):
115115
def I_22(self):
116116
"""Assembled (dry + propellant) transverse inertia about the e_2 axis.
117117
118-
Overrides :meth:`Motor.I_22`, which assumes ``I_22 == I_11`` by
119-
axisymmetry. A ring cluster is not axisymmetric for small ``number``
120-
(notably ``number == 2``), so ``I_22`` differs from ``I_11`` and must be
121-
computed from the separately-evaluated ``_22`` components.
118+
Overrides :meth:`Motor.I_22`, which returns ``I_11`` directly on the
119+
assumption that the motor is axisymmetric. That assumption does not hold
120+
for every ring cluster, so ``I_22`` is computed here from the
121+
separately-evaluated ``_22`` components (see
122+
:meth:`_evaluate_propellant_inertia` and :meth:`_calculate_dry_inertia`).
123+
124+
When ``I_22`` equals ``I_11``
125+
-----------------------------
126+
The relevant property is not continuous axisymmetry (which a discrete
127+
cluster of ``number`` motors never has for finite ``number``) but
128+
*transverse isotropy* of the inertia tensor: ``I_11 == I_22`` and
129+
``I_12 == 0``, i.e. every transverse axis is a principal axis with the
130+
same moment. A rigid body has this whenever it possesses a discrete
131+
rotational-symmetry axis of order ``n >= 3`` -- geometric axisymmetry is
132+
sufficient but not necessary.
133+
134+
For a ring cluster the motors sit at angles ``theta_k = 2*pi*k/number``,
135+
``k = 0 .. number-1``, all at radius ``radius``. The transverse
136+
anisotropy is driven by
137+
138+
I_22 - I_11 proportional to sum_k (x_k**2 - y_k**2)
139+
= radius**2 * sum_k cos(2*theta_k)
140+
= radius**2 * Re( sum_k exp(i * 4*pi*k / number) ).
141+
142+
That geometric series vanishes unless ``exp(i*4*pi/number) == 1``, i.e.
143+
unless ``number`` divides 2. Hence:
144+
145+
* ``number == 2`` -- the ``m = 2`` angular term does not cancel
146+
(``sum cos(2*theta_k) == 2``); the cluster is transversely anisotropic
147+
and ``I_22 != I_11``. This is the case this override exists for.
148+
* ``number >= 3`` -- the term cancels exactly for *every* such value
149+
(odd, even, prime alike); ``I_22 == I_11`` analytically, and this
150+
method returns the same value as :meth:`I_11` up to floating-point
151+
round-off.
152+
153+
Note that parity or primality of ``number`` is irrelevant: three or more
154+
equally-spaced motors already annihilate the ``m = 2`` harmonic, so e.g.
155+
``number == 3`` and ``number == 5`` are both transversely isotropic. The
156+
sole non-trivial anisotropic configuration (given the ``number >= 2``
157+
constraint enforced in ``__init__``) is ``number == 2``.
158+
159+
The implementation nonetheless sums every motor's contribution
160+
explicitly rather than special-casing ``number == 2``, so the result is
161+
exact for all configurations.
122162
"""
123163
prop_I_22 = parallel_axis_theorem_from_com(
124164
self.propellant_I_22,

0 commit comments

Comments
 (0)