Sympy Beam confused about why certain values cause errors, what the limitations are.

32 views
Skip to first unread message

Jon Durand

unread,
Jan 13, 2020, 9:47:46 PM1/13/20
to sympy
Hello all.

I'm trying to create a script that will take lists of loads and supports entered into excel and feed it into the Sympy Beam package so solve.
At the bottom of this message is example code of what I'm doing.

I've noticed that things get pretty picky when trying to solve for support reactions.
Like the name in string format assigned to the reaction Symbol seems like it must match the numerical value of the location.
For example, the location currently set at a value of "10.5", if that was "11", then further below I'd need R2 = Symbols('R_11). If it was a location of 12, I'd need to update R2 = Symbols('R_12) otherwise the reaction solver throws an error.
Likewise I'm getting an error if I have a decimal location like 10.5.  Below I've included the typical error I get.

Is there any way to accept decimal values for location?
Any help in understanding how these functions work so that I can avoid these errors would be greatly appreciated.

Below the shared code is Alternate Code which is my attempt at being able to feed in any amount of loads without needing to manually change the names of the symbols.
The assignment of variables to symbols seems to work fine. But when it comes to feeding into the solve_for_reaction_load I get the same "tuple out of index range" even if I don't have a decimal location

######### ERROR
line 778, in solve_for_reaction_loads
   + deflection_eqs, (C3, C4) + reactions).args)[0])

IndexError: tuple index out of range



######### Code Starts Here
from sympy.physics.continuum_mechanics.beam import Beam
from sympy import symbols, Piecewise, init_printing
from sympy.plotting import PlotGrid
init_printing(use_unicode=True, wrap_line=False)

beam_E = 5
beam_I = 2
beam_L = 12
b = Beam(beam_L, beam_E, beam_I)
supports = [[0, 'roller'], [10.5, 'roller']]

test_loads = [[1.4, 2.0, -1, None, 'D'],
  [2, 2.0, -1, None, 'L'],
  [3, 10.0, -1, None, 'S'],
  [-1, 2.0, -1, None, 'W'],
  [4, 3.0, -1, None, 'L'],
  [7, 6.0, -1, None, 'W']]


# Apply Loads
for load_info in test_loads:
    b.apply_load(*load_info[:4])

# Apply supports
for support_info in supports:
    b.apply_support(support_info[0], support_info[1])

R1, R2 = symbols('R_0, R_10.5')

b.solve_for_reaction_loads(R1, R2)
################# ALTERNATE CODE
from sympy.physics.continuum_mechanics.beam import Beam
from sympy import symbols, Piecewise, init_printing
from sympy.plotting import PlotGrid
init_printing(use_unicode=True, wrap_line=False)

beam_E = 5
beam_I = 2
beam_L = 12
b = Beam(beam_L, beam_E, beam_I)
supports = [[0, 'roller'], [10, 'roller']]

test_loads = [[1.4, 2.0, -1, None, 'D'],
  [2, 2.0, -1, None, 'L'],
  [3, 10.0, -1, None, 'S'],
  [-1, 2.0, -1, None, 'W'],
  [4, 3.0, -1, None, 'L'],
  [7, 6.0, -1, None, 'W']]


# Apply Loads
for load_info in test_loads:
    b.apply_load(*load_info[:4])

# Apply supports
for support_info in supports:
    b.apply_support(support_info[0], support_info[1])

reac_str = str(b.load)
reactions = ([x for x in reac_str.replace(' ','*').split('*') if '_' in x])
reactions_qty = len(reactions)
reaction_symbols_vars = ','.join( ['R' + str(x) for x in range(len(reactions))] )
reaction_symbols_str = ','.join(reactions)
exec(reaction_symbols_vars + '= symbols("' + reaction_symbols_str +'")')

exec(b.solve_for_reaction_loads(reaction_symbols_vars))

Jon Durand

unread,
Jan 14, 2020, 12:10:34 PM1/14/20
to sympy
Okay I got it working better now. The exec() function was putting it in as a string for the solver instead of as variables. It worked better doing exec from a newly created file instead
of directly in line from the original script. Like this:

with open('temp.py', 'w') as f:
    f.write('b.solve_for_reaction_loads(' + reaction_symbols_vars + ')')
exec(open("./temp.py").read())
os.remove('temp.py')

Now my script seems to be applying and solving loads correctly. But I still have some troubleshooting to do as for certain support combinations or support locations I'll get an error of:
     deflection_curve = deflection_curve.subs({C4: constants[0][0]})
     IndexError: list index out of range

It's probably a similar issue to what I was getting before. Hopefully I'll figure things out.

Jason Moore

unread,
Jan 14, 2020, 1:17:15 PM1/14/20
to sympy
Using exec() is generally not a good idea. It is useful for some rare needs, but I'd recommend avoiding it if you can.

Jason

--
You received this message because you are subscribed to the Google Groups "sympy" group.
To unsubscribe from this group and stop receiving emails from it, send an email to sympy+un...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/sympy/03ed2c87-092f-401e-8f68-4985f97b7400%40googlegroups.com.

Jon Durand

unread,
Jan 14, 2020, 1:26:57 PM1/14/20
to sympy
Duly noted. I will try to think of another way but I might not be able to.

On a separate note, would you or someone else know if Sympy Beam has an option to solve for the I or E values instead of the reaction values?

Jason Moore

unread,
Jan 14, 2020, 1:39:54 PM1/14/20
to sympy
Jon,

You should be able to use SymPy's solve() function to solve for any unknowns in the equations that Beam generates.

Jason

On Tue, Jan 14, 2020 at 10:27 AM Jon Durand <jon.du...@gmail.com> wrote:
Duly noted. I will try to think of another way but I might not be able to.

On a separate note, would you or someone else know if Sympy Beam has an option to solve for the I or E values instead of the reaction values?

--
You received this message because you are subscribed to the Google Groups "sympy" group.
To unsubscribe from this group and stop receiving emails from it, send an email to sympy+un...@googlegroups.com.

Jon Durand

unread,
Jan 14, 2020, 2:21:47 PM1/14/20
to sympy
There's definitely some stuff I still don't understand about how all this works.
I'm going to type out my thought process from what I have tried so far.

So if I do b.deflection() I can see the deflection equation which has 'x' and 'I' as variables.
If I do b.deflection().subs(x,4) that equation simplifies so that only 'I' is variable.
do the above as my 'eqn' and do solve(eqn, I) I get an empty list [].
But that's probably because it's trying to solve the value of deflection not the value of I.

So I need to solve the equation for second_moment
If I do b.second_moment() hoping to get an equation I can solve I get the error: 'Symbol' object is not callable

Looking through the beam examples pages I didn't see any of solving for anything other than reactions.
Would you know of any other pages that have examples of solving in Sympy specifically within the Beam library.

Jason Moore

unread,
Jan 14, 2020, 5:38:53 PM1/14/20
to sympy
There are no examples of solving equations from Beam for variables other than the reactions.

Can't you simply multiply the deflection equation by I to solve for it? Isn't it a trivial solution if E and I are constants?

Jason

--
You received this message because you are subscribed to the Google Groups "sympy" group.
To unsubscribe from this group and stop receiving emails from it, send an email to sympy+un...@googlegroups.com.

Jon Durand

unread,
Jan 16, 2020, 12:22:52 PM1/16/20
to sympy
Yes sorry, that is easy. Sometimes I get tunnel vision on the programming I lose sight of basic theory.

Jon Durand

unread,
Jan 16, 2020, 12:26:44 PM1/16/20
to sympy
Trying to get a matplotlib figure object from the different beam plotting, I found I could do b.plot_shear_force()._backend.fig
However that does not seem to work with b.draw(pictorial = True)._backend.fig even though both b.plot_shear_force() and b.draw(pictorial = True) return sympy.plotting.plot.Plot objects.
Would anyone know why that might be, or how to get a figure from draw()?
Reply all
Reply to author
Forward
0 new messages