Repository: sympy/sympy

Issue:
No function for calculating polar moment of inertia and section modulus in continuum_mechanics in beam.py
There is currently no function to calculate polar moment of inertia and section modulus of the beam . Both of these quantities are important in further future works in this module.

Discussion:

Patch:
diff --git a/sympy/physics/continuum_mechanics/beam.py b/sympy/physics/continuum_mechanics/beam.py
index f4bca0cd94..80c7b9adcc 100644
--- a/sympy/physics/continuum_mechanics/beam.py
+++ b/sympy/physics/continuum_mechanics/beam.py
@@ -13,6 +13,16 @@
 from sympy.integrals import integrate
 from sympy.series import limit
 from sympy.plotting import plot, PlotGrid
+from sympy.external import import_module
+from sympy.utilities.decorator import doctest_depends_on
+from sympy import lambdify
+from sympy.core.compatibility import iterable
+
+matplotlib = import_module('matplotlib', __import__kwargs={'fromlist':['pyplot']})
+numpy = import_module('numpy', __import__kwargs={'fromlist':['linspace']})
+
+__doctest_requires__ = {('Beam.plot_loading_results',): ['matplotlib']}
+
 
 class Beam(object):
     """
@@ -1645,6 +1655,29 @@ def boundary_conditions(self):
         """
         return self._boundary_conditions
 
+    def polar_moment(self):
+        """
+        Returns the polar moment of area of the beam
+        about the X axis with respect to the centroid.
+
+        Examples
+        ========
+
+        >>> from sympy.physics.continuum_mechanics.beam import Beam3D
+        >>> from sympy import symbols
+        >>> l, E, G, I, A = symbols('l, E, G, I, A')
+        >>> b = Beam3D(l, E, G, I, A)
+        >>> b.polar_moment()
+        2*I
+        >>> I1 = [9, 15]
+        >>> b = Beam3D(l, E, G, I1, A)
+        >>> b.polar_moment()
+        24
+        """
+        if not iterable(self.second_moment):
+            return 2*self.second_moment
+        return sum(self.second_moment)
+
     def apply_load(self, value, start, order, dir="y"):
         """
         This method adds up the force load to a particular beam object.


Test patch:
diff --git a/sympy/physics/continuum_mechanics/tests/test_beam.py b/sympy/physics/continuum_mechanics/tests/test_beam.py
index 980bcb1d76..5299ce7c98 100644
--- a/sympy/physics/continuum_mechanics/tests/test_beam.py
+++ b/sympy/physics/continuum_mechanics/tests/test_beam.py
@@ -501,6 +501,7 @@ def test_Beam3D():
     b.bc_deflection = [(0, [0, 0, 0]), (l, [0, 0, 0])]
     b.solve_slope_deflection()
 
+    assert b.polar_moment() == 2*I
     assert b.shear_force() == [0, -q*x, 0]
     assert b.bending_moment() == [0, 0, -m*x + q*x**2/2]
     expected_deflection = (x*(A*G*q*x**3/4 + A*G*x**2*(-l*(A*G*l*(l*q - 2*m) +
@@ -540,6 +541,14 @@ def test_Beam3D():
     assert b3.reaction_loads == {R1: -120, R2: -120, R3: -1350, R4: -2700}
 
 
+def test_polar_moment_Beam3D():
+    l, E, G, A, I1, I2 = symbols('l, E, G, A, I1, I2')
+    I = [I1, I2]
+
+    b = Beam3D(l, E, G, I, A)
+    assert b.polar_moment() == I1 + I2
+
+
 def test_parabolic_loads():
 
     E, I, L = symbols('E, I, L', positive=True, real=True)