Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

continuum_mechanics: Added plotting methods #14967

Merged
merged 11 commits into from Aug 14, 2018

Conversation

Projects
None yet
6 participants
@jashan498
Copy link
Contributor

jashan498 commented Jul 24, 2018

Brief description of what is fixed or changed

Methods to plot Shear force, Bending moment, Slope and Delfection has been added.
plot_all was also added which plots Shear force, Bending moment and Delfection on a single graph.

Here is an example of how plots look.

Release Notes

  • physics.continuum_mechanics
    • added methods to plot shear force, bending moment, slope and deflection.

jashan498 added some commits Jul 24, 2018

Added plotting methods for:
Shear Force
Bending Moment
Slope
Deflection and a combined plot for all.
@sympy-bot

This comment has been minimized.

Copy link

sympy-bot commented Jul 24, 2018

Hi, I am the SymPy bot (v128). I'm here to help you write a release notes entry. Please read the guide on how to write release notes.

Your release notes are in good order.

Here is what the release notes will look like:

  • physics.continuum_mechanics
    • added methods to plot shear force, bending moment, slope and deflection. (#14967 by @jashan498)

This will be added to https://github.com/sympy/sympy/wiki/Release-Notes-for-1.2.1.

Note: This comment will be updated with the latest check if you edit the pull request. You need to reload the page to see it.

Click here to see the pull request description that was parsed.

#### Brief description of what is fixed or changed
Methods to plot Shear force, Bending moment, Slope and Delfection has been added. 
`plot_all` was also added which plots Shear force, Bending moment and Delfection on a single graph.

[Here](https://github.com/jashan498/beam_examples/blob/master/beam_plots.ipynb) is an example of how plots look.

#### Release Notes

<!-- Write the release notes for this release below. See
https://github.com/sympy/sympy/wiki/Writing-Release-Notes for more information
on how to write release notes. If there is no release notes entry for this PR,
write "NO ENTRY". The bot will check your release notes automatically to see
if they are formatted correctly. -->

<!-- BEGIN RELEASE NOTES -->
* physics.continuum_mechanics
  * added methods to plot shear force, bending moment, slope and deflection.
<!-- END RELEASE NOTES -->

Update

The release notes on the wiki have been updated.

@asmeurer

This comment has been minimized.

Copy link
Member

asmeurer commented Jul 24, 2018

I think this could use a release notes entry. Put it under * physics.continuum_mechanics.

@jashan498

This comment has been minimized.

Copy link
Contributor Author

jashan498 commented Jul 24, 2018

Why docsrting of methods containing plot failing? For example, one of the test failures is:

_________ sympy.physics.continuum_mechanics.beam.Beam.plot_shear_force _________
File "/home/travis/virtualenv/python2.7.14/lib/python2.7/site-packages/sympy/physics/continuum_mechanics/beam.py", line 1151, in sympy.physics.continuum_mechanics.beam.Beam.plot_shear_force
Failed example:
    b.plot_shear_force()
Expected:
    Plot object containing:
        [0]: cartesian line: -13750*SingularityFunction(x, 0, 0) + 5000*SingularityFunction(x, 2, 0)
        + 10000*SingularityFunction(x, 4, 1) - 31250*SingularityFunction(x, 8, 0)
        - 10000*SingularityFunction(x, 8, 1) for x over (0.0, 8.0)
Got:
    29795.5 |                                                      / 
            |                                                    ..  
            |                                                   /    
            |                                                 ..     
            |                                               ..       
            |                                              /         
            |                                            ..          
            |                                          ..            
    8022.73 | ----------------------------------------/--------------
            |                                       ..               
            |                                     ..                 
            |                                    /                   
            |                                  ..                    
            |                                ..                      
            |                               /                        
            |               ................                         
            |                                                        
     -13750 | ..............                                         
              0                      4                          8
    Plot object containing:
    [0]: cartesian line: -13750*SingularityFunction(x, 0, 0) + 5000*SingularityFunction(x, 2, 0) + 10000*SingularityFunction(x, 4, 1) - 31250*SingularityFunction(x, 8, 0) - 10000*SingularityFunction(x, 8, 1) for x over (0.0, 8.0)

But [0]: cartesian line seems identical for both Expected and Got.
Also bin/doctest beam is passing all docstrings locally.

@jashan498 jashan498 changed the title continuum_mechanice: Added plotting methods continuum_mechanics: Added plotting methods Jul 24, 2018

@jashan498

This comment has been minimized.

Copy link
Contributor Author

jashan498 commented Jul 26, 2018

jashan498 added some commits Jul 26, 2018

@jashan498 jashan498 force-pushed the jashan498:3dbeam branch from 54fef81 to bce9287 Jul 27, 2018

@@ -1116,6 +1118,267 @@ def max_deflection(self):
else:
return None

@doctest_depends_on(modules=('matplotlib',))

This comment has been minimized.

@jashan498

jashan498 Jul 28, 2018

Author Contributor

There is no need to use doctest_depend_on after #14984.

jashan498 added some commits Jul 28, 2018

@jashan498 jashan498 force-pushed the jashan498:3dbeam branch from 0e8c036 to 24708b4 Jul 28, 2018

@parsoyaarihant parsoyaarihant added the GSoC label Jul 28, 2018

@moorepants
Copy link
Member

moorepants left a comment

This looks great! Very useful convenience methods. Please address the few comments i have.

Parameters
==========
var : dictionary

This comment has been minimized.

@moorepants

moorepants Jul 28, 2018

Member

Maybe call this subs instead of var as it resembles the subs() method on SymPy expressions.

line.label= labels[n]
line.line_color = colors[n]
p.legend = True
return p.show()

This comment has been minimized.

@moorepants

moorepants Jul 28, 2018

Member

Always return the matplotlib axes and do not call show. It is convention to let the user call show.

return plot(deflection.subs(var), (self.variable, 0, length), title='Deflection',
xlabel='position', ylabel='Value', line_color='r')

def plot_all(self, var={}):

This comment has been minimized.

@moorepants

moorepants Jul 28, 2018

Member

I recommend that this create a subplot since the units are different for all of them.

This comment has been minimized.

@moorepants

moorepants Jul 28, 2018

Member

Would simply plot() be a sufficient name?

This comment has been minimized.

@jashan498

jashan498 Jul 29, 2018

Author Contributor

One plot method already exists in plotting module. Is it okay to give same name to this method?

This comment has been minimized.

@moorepants

moorepants Jul 30, 2018

Member

I don't see why not.

But now that I think about this, here we have a "beam". If I were a new user and saw a "plot" method I guess I'd think it would show a diagram of the beam (like what you see in the problem description in engr. books). If I saw "plot_all" I'd probably guess it'd plot multiple things but it isn't that informative about what will be plotted. Maybe "plot" should be reserved for showing a diagram of the beam and "plot_diagrams" or "plot_all" or something better would be for this method. This method you have plots a "shear diagram", "moment diagram", "slope curve", and "deflection curve". Maybe "plot_loaded_results" or "plot_loading_results"...not thinking of a great concise name.

@jashan498

This comment has been minimized.

Copy link
Contributor Author

jashan498 commented Jul 30, 2018

@moorepants I used matplotlib and numpy straightaway in plot_loading_results method rather than using SymPy's plot as plot was unable to make subplots (I even tried using _backend).

This is how resultant plot looks like now:

>>> from sympy.physics.continuum_mechanics.beam import Beam
>>> from sympy import symbols
>>> R1, R2 = symbols('R1, R2')
>>> b = Beam(8, 200*(10**9), 400*(10**-6))
>>> b.apply_load(5000, 2, -1)
>>> b.apply_load(R1, 0, -1)
>>> b.apply_load(R2, 8, -1)
>>> b.apply_load(10000, 4, 0, end=8)
>>> b.bc_deflection = [(0, 0), (8, 0)]
>>> b.solve_for_reaction_loads(R1, R2)
>>> plt = b.plot_loading_results()
>>> plt.show()

loading_results

@moorepants

This comment has been minimized.

Copy link
Member

moorepants commented Jul 30, 2018

The subplot looks good. Do you think a 4 x1 plot would be better than a 2x2? All of the plots share the x axis (beam length) and in text books you often see them plotted 4x1.

@@ -1116,9 +1118,289 @@ def max_deflection(self):
else:
return None

def plot_shear_force(self, subs={}):

This comment has been minimized.

@moorepants

moorepants Jul 30, 2018

Member

I recommend subs=None. Having mutables as a default arg can sometimes cause confusion.

>>> b.apply_load(10000, 4, 0, end=8)
>>> b.bc_deflection = [(0, 0), (8, 0)]
>>> b.solve_for_reaction_loads(R1, R2)
>>> b.plot_shear_force()

This comment has been minimized.

@moorepants

moorepants Jul 30, 2018

Member

What happens if you call the plot methods and the beam has not been solved yet? i.e. you've only done:

b = Beam()
b.plot_shear_force()

This comment has been minimized.

@jashan498

jashan498 Jul 31, 2018

Author Contributor

It returns only co-ordinate axes without a plot as there is no load present on the beam.

This comment has been minimized.

@moorepants

moorepants Aug 14, 2018

Member

Ok that's fine.

"""
import matplotlib.pyplot as plt
from numpy import linspace
from sympy import lambdify

This comment has been minimized.

@moorepants

moorepants Jul 30, 2018

Member

Import these at the top with sympy.external.import_module().

axs[1, 1].set_title("Deflection")
fig.tight_layout() # For better spacing between subplots

return fig

This comment has been minimized.

@moorepants

moorepants Jul 30, 2018

Member

It is convention to return axs not fig.

This comment has been minimized.

@jashan498

jashan498 Jul 31, 2018

Author Contributor

but type(axs) = <class 'numpy.ndarray'>, how to use .show() on it to see the plot?

>>> from sympy import symbols
>>> l, E, G, I, A = symbols('l, E, G, I, A')
>>> b = Beam_3d(l, E, G, I, A)
>>> b = Beam3D(l, E, G, I, A)

This comment has been minimized.

@moorepants

moorepants Jul 30, 2018

Member

It would be better to make this change in a separate PR.

imports are now done through import_module
plot_loading_results now retuens a 4x1 subplot figure
@jashan498

This comment has been minimized.

Copy link
Contributor Author

jashan498 commented Jul 31, 2018

This is how 4x1 looks like now:
load

@moorepants

This comment has been minimized.

Copy link
Member

moorepants commented Jul 31, 2018

I like the 4x1 better, how bout you? I makes the beams seem longer and slender, which is what they are.

@moorepants

This comment has been minimized.

Copy link
Member

moorepants commented Jul 31, 2018

One more note. The deflection curves are traditionally show with forces applied pointing down and the be deflecting downwards. I'm sure this is a sign convention thing.

@jashan498

This comment has been minimized.

Copy link
Contributor Author

jashan498 commented Jul 31, 2018

Initially, I thought 4x1 is too long horizontally but yeah you are right they represent beam's length so they should be like that. Also its easier to read than 2x2.

Yes, the deflection curve is upwards in this case because while applying load I assumed downward direction to be positive (See its downward in this example where downward load is negative).

@moorepants

This comment has been minimized.

Copy link
Member

moorepants commented Jul 31, 2018

Here is a typical figure from a textbook:

selection_218

I suggest that you work to emulate this wrt to sign conventions, etc.

@jashan498

This comment has been minimized.

Copy link
Contributor Author

jashan498 commented Jul 31, 2018

Have a look at this notebook.

@jashan498

This comment has been minimized.

Copy link
Contributor Author

jashan498 commented Jul 31, 2018

Btw plot_resulting_loads is creating two plots in jupyter notebook everytime. Creates only one when used in terminal.

@moorepants

This comment has been minimized.

Copy link
Member

moorepants commented Jul 31, 2018

Don't return the figure, return the axes in that function.

axs[3].set_title("Deflection")
fig.tight_layout() # For better spacing between subplots

return fig

This comment has been minimized.

@moorepants

moorepants Jul 31, 2018

Member

Change to return axs.

axs[1].set_title("Bending Moment")
axs[2].plot(points, slope(points), color='m')
axs[2].set_title("Slope")
axs[3].plot(points, deflection(points), color='r')

This comment has been minimized.

@moorepants

moorepants Jul 31, 2018

Member

I recommend cycling through matplotlib's standard color cycler instead of explicitly naming the colors.

@jashan498 jashan498 force-pushed the jashan498:3dbeam branch from f8cee2e to 75c2f7c Jul 31, 2018

@jashan498 jashan498 force-pushed the jashan498:3dbeam branch from 75c2f7c to b8b2aa6 Jul 31, 2018

@parsoyaarihant parsoyaarihant removed their request for review Aug 1, 2018

slope = lambdify(variable, self.slope().subs(subs).rewrite(Piecewise), 'numpy')
deflection = lambdify(variable, self.deflection().subs(subs).rewrite(Piecewise), 'numpy')

points = linspace(0, float(length))

This comment has been minimized.

@moorepants

moorepants Aug 7, 2018

Member

I suggest setting the option num= to be a function of the length. You may want to guarantee some standard number of points per unit length, so plots always look good.

This comment has been minimized.

@jashan498

jashan498 Aug 8, 2018

Author Contributor

Added num=5*length

@jashan498

This comment has been minimized.

Copy link
Contributor Author

jashan498 commented Aug 14, 2018

@moorepants @parsoyaarihant is there anything else that needs to be changed?

@moorepants

This comment has been minimized.

Copy link
Member

moorepants commented Aug 14, 2018

Did you address my comments on the signs of the plots so that they look like the textbook snippet I shared?

@jashan498

This comment has been minimized.

Copy link
Contributor Author

jashan498 commented Aug 14, 2018

Yeah, see this comment.

@moorepants

This comment has been minimized.

Copy link
Member

moorepants commented Aug 14, 2018

Ok great. Let's merge this.

@moorepants moorepants merged commit 89b82fb into sympy:master Aug 14, 2018

2 checks passed

continuous-integration/travis-ci/pr The Travis CI build passed
Details
sympy-bot/release-notes The release notes look OK
Details
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.