Skip to content

Commit

Permalink
Merge pull request #26569 from mvg2002/Dev_reaction_loads_2
Browse files Browse the repository at this point in the history
Continue: Obtaining reaction loads from apply_support
  • Loading branch information
moorepants committed May 7, 2024
2 parents 0859517 + 1fdbe8c commit e4d0e61
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 37 deletions.
1 change: 1 addition & 0 deletions .mailmap
Original file line number Diff line number Diff line change
Expand Up @@ -926,6 +926,7 @@ Mark Dewing <markdewing@gmail.com>
Mark Dickinson <dickinsm@gmail.com>
Mark Jeromin <mark.jeromin@sysfrog.net>
Mark Shoulson <mark@kli.org>
Mark van Gelder <m.j.vangelder@student.tudelft.nl>
Markus Mohrhard <markus.mohrhard@googlemail.com>
Markus Müller <markus.mueller.1.g@googlemail.com>
Martha Giannoudovardi <maapxa@gmail.com>
Expand Down
78 changes: 45 additions & 33 deletions sympy/physics/continuum_mechanics/beam.py
Original file line number Diff line number Diff line change
Expand Up @@ -420,7 +420,8 @@ def join(self, beam, via="fixed"):

def apply_support(self, loc, type="fixed"):
"""
This method applies support to a particular beam object.
This method applies support to a particular beam object and returns
the symbol of the unknown reaction load(s).

Parameters
==========
Expand All @@ -433,34 +434,40 @@ def apply_support(self, loc, type="fixed"):
- one degree of freedom, type = "pin"
- two degrees of freedom, type = "roller"

Returns
=======
Symbol or tuple of Symbol
The unknown reaction load as a symbol.
- Symbol(reaction_force) if type = "pin" or "roller"
- Symbol(reaction_force), Symbol(reaction_moment) if type = "fixed"

Examples
========
There is a beam of length 30 meters. A moment of magnitude 120 Nm is
There is a beam of length 20 meters. A moment of magnitude 100 Nm is
applied in the clockwise direction at the end of the beam. A pointload
of magnitude 8 N is applied from the top of the beam at the starting
point. There are two simple supports below the beam. One at the end
and another one at a distance of 10 meters from the start. The
deflection is restricted at both the supports.
of magnitude 8 N is applied from the top of the beam at a distance of 10 meters.
There is one fixed support at the start of the beam and a roller at the end.

Using the sign convention of upward forces and clockwise moment
being positive.

>>> from sympy.physics.continuum_mechanics.beam import Beam
>>> from sympy import symbols
>>> E, I = symbols('E, I')
>>> b = Beam(30, E, I)
>>> b.apply_support(10, 'roller')
>>> b.apply_support(30, 'roller')
>>> b.apply_load(-8, 0, -1)
>>> b.apply_load(120, 30, -2)
>>> R_10, R_30 = symbols('R_10, R_30')
>>> b.solve_for_reaction_loads(R_10, R_30)
>>> b = Beam(20, E, I)
>>> p0, m0 = b.apply_support(0, 'fixed')
>>> p1 = b.apply_support(20, 'roller')
>>> b.apply_load(-8, 10, -1)
>>> b.apply_load(100, 20, -2)
>>> b.solve_for_reaction_loads(p0, m0, p1)
>>> b.reaction_loads
{M_0: 20, R_0: -2, R_20: 10}
>>> b.reaction_loads[p0]
-2
>>> b.load
-8*SingularityFunction(x, 0, -1) + 6*SingularityFunction(x, 10, -1)
+ 120*SingularityFunction(x, 30, -2) + 2*SingularityFunction(x, 30, -1)
>>> b.slope()
(-4*SingularityFunction(x, 0, 2) + 3*SingularityFunction(x, 10, 2)
+ 120*SingularityFunction(x, 30, 1) + SingularityFunction(x, 30, 2) + 4000/3)/(E*I)
20*SingularityFunction(x, 0, -2) - 2*SingularityFunction(x, 0, -1)
- 8*SingularityFunction(x, 10, -1) + 100*SingularityFunction(x, 20, -2)
+ 10*SingularityFunction(x, 20, -1)
"""
loc = sympify(loc)
self._applied_supports.append((loc, type))
Expand All @@ -479,6 +486,11 @@ def apply_support(self, loc, type="fixed"):

self._support_as_loads.append((reaction_load, loc, -1, None))

if type in ("pin", "roller"):
return reaction_load
else:
return reaction_load, reaction_moment

def apply_load(self, value, start, order, end=None):
"""
This method adds up the loads given to a particular beam object.
Expand Down Expand Up @@ -1754,8 +1766,8 @@ def solve_for_ild_reactions(self, value, *reactions):
>>> E, I = symbols('E, I')
>>> R_0, R_10 = symbols('R_0, R_10')
>>> b = Beam(10, E, I)
>>> b.apply_support(0, 'roller')
>>> b.apply_support(10, 'roller')
>>> p0 = b.apply_support(0, 'roller')
>>> p10 = b.apply_support(10, 'roller')
>>> b.solve_for_ild_reactions(1,R_0,R_10)
>>> b.ild_reactions
{R_0: x/10 - 1, R_10: -x/10}
Expand Down Expand Up @@ -1827,8 +1839,8 @@ def plot_ild_reactions(self, subs=None):
>>> E, I = symbols('E, I')
>>> R_0, R_7 = symbols('R_0, R_7')
>>> b = Beam(10, E, I)
>>> b.apply_support(0, 'roller')
>>> b.apply_support(7, 'roller')
>>> p0 = b.apply_support(0, 'roller')
>>> p7 = b.apply_support(7, 'roller')
>>> b.apply_load(5,4,-1)
>>> b.solve_for_ild_reactions(1,R_0,R_7)
>>> b.ild_reactions
Expand Down Expand Up @@ -1902,8 +1914,8 @@ def solve_for_ild_shear(self, distance, value, *reactions):
>>> E, I = symbols('E, I')
>>> R_0, R_8 = symbols('R_0, R_8')
>>> b = Beam(12, E, I)
>>> b.apply_support(0, 'roller')
>>> b.apply_support(8, 'roller')
>>> p0 = b.apply_support(0, 'roller')
>>> p8 = b.apply_support(8, 'roller')
>>> b.solve_for_ild_reactions(1, R_0, R_8)
>>> b.solve_for_ild_shear(4, 1, R_0, R_8)
>>> b.ild_shear
Expand Down Expand Up @@ -1961,8 +1973,8 @@ def plot_ild_shear(self,subs=None):
>>> E, I = symbols('E, I')
>>> R_0, R_8 = symbols('R_0, R_8')
>>> b = Beam(12, E, I)
>>> b.apply_support(0, 'roller')
>>> b.apply_support(8, 'roller')
>>> p0 = b.apply_support(0, 'roller')
>>> p8 = b.apply_support(8, 'roller')
>>> b.solve_for_ild_reactions(1, R_0, R_8)
>>> b.solve_for_ild_shear(4, 1, R_0, R_8)
>>> b.ild_shear
Expand Down Expand Up @@ -2029,8 +2041,8 @@ def solve_for_ild_moment(self, distance, value, *reactions):
>>> E, I = symbols('E, I')
>>> R_0, R_8 = symbols('R_0, R_8')
>>> b = Beam(12, E, I)
>>> b.apply_support(0, 'roller')
>>> b.apply_support(8, 'roller')
>>> p0 = b.apply_support(0, 'roller')
>>> p8 = b.apply_support(8, 'roller')
>>> b.solve_for_ild_reactions(1, R_0, R_8)
>>> b.solve_for_ild_moment(4, 1, R_0, R_8)
>>> b.ild_moment
Expand Down Expand Up @@ -2087,8 +2099,8 @@ def plot_ild_moment(self,subs=None):
>>> E, I = symbols('E, I')
>>> R_0, R_8 = symbols('R_0, R_8')
>>> b = Beam(12, E, I)
>>> b.apply_support(0, 'roller')
>>> b.apply_support(8, 'roller')
>>> p0 = b.apply_support(0, 'roller')
>>> p8 = b.apply_support(8, 'roller')
>>> b.solve_for_ild_reactions(1, R_0, R_8)
>>> b.solve_for_ild_moment(4, 1, R_0, R_8)
>>> b.ild_moment
Expand Down Expand Up @@ -2177,9 +2189,9 @@ def draw(self, pictorial=True):
>>> b.apply_load(10, 30, 1, 50)
>>> b.apply_load(M, 15, -2)
>>> b.apply_load(-M, 30, -2)
>>> b.apply_support(50, "pin")
>>> b.apply_support(0, "fixed")
>>> b.apply_support(20, "roller")
>>> p50 = b.apply_support(50, "pin")
>>> p0, m0 = b.apply_support(0, "fixed")
>>> p20 = b.apply_support(20, "roller")
>>> p = b.draw() # doctest: +SKIP
>>> p # doctest: +ELLIPSIS
Plot object containing:
Expand Down
26 changes: 22 additions & 4 deletions sympy/physics/continuum_mechanics/tests/test_beam.py
Original file line number Diff line number Diff line change
Expand Up @@ -470,16 +470,34 @@ def test_apply_support():
+ 10*SingularityFunction(x, 4, 3)/3)/(E*I))

b = Beam(30, E, I)
b.apply_support(10, "pin")
b.apply_support(30, "roller")
p0 = b.apply_support(10, "pin")
p1 = b.apply_support(30, "roller")
b.apply_load(-8, 0, -1)
b.apply_load(120, 30, -2)
R_10, R_30 = symbols('R_10, R_30')
b.solve_for_reaction_loads(R_10, R_30)
b.solve_for_reaction_loads(p0, p1)
assert b.slope() == (-4*SingularityFunction(x, 0, 2) + 3*SingularityFunction(x, 10, 2)
+ 120*SingularityFunction(x, 30, 1) + SingularityFunction(x, 30, 2) + Rational(4000, 3))/(E*I)
assert b.deflection() == (x*Rational(4000, 3) - 4*SingularityFunction(x, 0, 3)/3 + SingularityFunction(x, 10, 3)
+ 60*SingularityFunction(x, 30, 2) + SingularityFunction(x, 30, 3)/3 - 12000)/(E*I)
R_10 = Symbol('R_10')
R_30 = Symbol('R_30')
assert p0 == R_10
assert b.reaction_loads == {R_10: 6, R_30: 2}
assert b.reaction_loads[p0] == 6

b = Beam(8, E, I)
p0, m0 = b.apply_support(0, "fixed")
p1 = b.apply_support(8, "roller")
b.apply_load(-5, 0, 0, 8)
b.solve_for_reaction_loads(p0, m0, p1)
R_0 = Symbol('R_0')
M_0 = Symbol('M_0')
R_8 = Symbol('R_8')
assert p0 == R_0
assert m0 == M_0
assert p1 == R_8
assert b.reaction_loads == {R_0: 25, M_0: -40, R_8: 15}
assert b.reaction_loads[m0] == -40

P = Symbol('P', positive=True)
L = Symbol('L', positive=True)
Expand Down

0 comments on commit e4d0e61

Please sign in to comment.