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

[WIP] A new class CrossSection has been introduced in the continuum_mechanics module #16964

Open
wants to merge 2 commits into
base: master
from

Conversation

Projects
None yet
7 participants
@ishanaj
Copy link
Contributor

commented Jun 4, 2019

This PR defines a new class CrossSection to integrate the geometry module with the continuum mechanics module for 2D cross-sectional analysis of beam
The new CrossSection class defines a cross-sectional geometry for the beam using the geometry module of SymPy and also calculates some of the major cross-sectional properties like:

  • area
  • centroid
  • second moment of area
  • section modulus
  • polar modulus
  • first moment of area (yet to be defined)

TODO's:

  • Defining the first moment of area
  • Adding tests
  • Documentation

Release Notes

  • physics.continuum_mechanics
    • Integrated geometry module via a class CrossSection for 2D cross-sectional analysis of beam
a new class CrossSection has been introduced in the continuum
mechanics module which gives the beam module the access to calculations
related to any cross-section
@sympy-bot

This comment has been minimized.

Copy link

commented Jun 4, 2019

Hi, I am the SymPy bot (v147). 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
    • Integrated geometry module via a class CrossSection for 2D cross-sectional analysis of beam (#16964 by @ishanaj)

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

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.

This PR defines a new class `CrossSection` to integrate the geometry module with the continuum mechanics module for 2D cross-sectional analysis of beam
The new `CrossSection` class defines a cross-sectional geometry for the beam using the `geometry` module of SymPy and also calculates some of the major cross-sectional properties like:

- area
- centroid
- second moment of area 
- section modulus
- polar modulus
- first moment of area (yet to be defined)

TODO's:

- [ ] Defining the first moment of area
- [ ] Adding tests 
- [x] Documentation


#### Release Notes

<!-- BEGIN RELEASE NOTES -->
- physics.continuum_mechanics
    - Integrated geometry module via a class `CrossSection` for 2D cross-sectional analysis of beam

<!-- END RELEASE NOTES -->

@ishanaj

This comment has been minimized.

Copy link
Contributor Author

commented Jun 4, 2019

I have tried calculating the section_modulus in terms of the variable y.
where, y is the distance of the layer from the bottom of the cross-section.

This variable y is being entered by the user quite similar to the variable x used in defining a beam, except for the fact that it has no default value.

If this seems ok, we can then go ahead to define first_moment in terms of y

ping @moorepants

shape = shape.lower()

if shape == "circular":
self._circular(self.dimensions)

This comment has been minimized.

Copy link
@oscarbenjamin

oscarbenjamin Jun 4, 2019

Contributor

Probably these should be separate classes each with their own docstring that explains what arguments to provide for dimensions.

self._second_moment = traingle.second_moment_of_area()
self._centroid = traingle.centroid
self._section_modulus = self._second_moment[0]/(self.variable - self._centroid.y)
self._polar_modulus = self._second_moment[0] + self._second_moment[1]

This comment has been minimized.

Copy link
@oscarbenjamin

oscarbenjamin Jun 4, 2019

Contributor

This duplicates the lines above. It would be better to let the user provide a triangle or circle shape as input. Then you can just call all these methods on self.shape.

@oscarbenjamin

This comment has been minimized.

Copy link
Contributor

commented Jun 4, 2019

I think you should change it so that the CrossSection class just takes a shape from the geometry module as input and computes everything by calling methods on the shape object. Then there's no need to have special code for each shape (it already exists in the geometry module).

It would be reasonable though to have a couple of helper functions for creating T- and I-section Polygons though

@jashan498

This comment has been minimized.

Copy link
Contributor

commented Jun 4, 2019

If this seems ok, we can then go ahead to define first_moment in terms of y

I think there is no need to return first_moment in terms of y as it's usually calculated till the boundary of the shape only. When we say first_moment of a shape, we usually mean the whole shape.


class CrossSection(object):
def __init__(self, shape, variable, *dimensions):
self.shape = shape

This comment has been minimized.

Copy link
@czgdp1807

czgdp1807 Jun 5, 2019

Member

I think this should be self._shape = shape because you have defined a property with the same name shape, so may be there will be conflict.

class CrossSection(object):
def __init__(self, shape, variable, *dimensions):
self.shape = shape
self.dimensions = dimensions

This comment has been minimized.

Copy link
@czgdp1807

czgdp1807 Jun 5, 2019

Member

May be self._dimensions = dimensions.

def __init__(self, shape, variable, *dimensions):
self.shape = shape
self.dimensions = dimensions
self.variable = variable

This comment has been minimized.

Copy link
@czgdp1807

czgdp1807 Jun 5, 2019

Member

May be self._variable = variable.

return self._dimensions

@dimensions.setter
def dimensions(self, dim):

This comment has been minimized.

Copy link
@czgdp1807

czgdp1807 Jun 5, 2019

Member

I don't know much about this module, but as far as I know allowing the dimensions to be changed after creating the object may cause wrong results or confusion for the user. May be, you should allow setting the dimensions only once.

@czgdp1807

This comment has been minimized.

Copy link
Member

commented Jun 5, 2019

As far as I can figure out, all the properties of the object can be defined using, property(lambda self: self.<property_name>), occupying much less lines of code. Though you can continue with your code if you follow some other principles of coding.
Out of curiosity, I want to know why CrossSection doesn't inherit Basic? AFAIK, it is the base class for all the other objects in SymPy. Please let me know the reason.

@ishanaj

This comment has been minimized.

Copy link
Contributor Author

commented Jun 5, 2019

@oscarbenjamin

I think you should change it so that the CrossSection class just takes a shape from the geometry module as input and computes everything by calling methods on the shape object. Then there's no need to have special code for each shape (it already exists in the geometry module).

I think one of the major use of the CrossSection class would be to make it easier for the user to define the shape while using the beam module (and also calculating the properties, of course).
I am not sure about directly taking a Polygon object (or any other geometry object) as an input but I have taken the idea of the API from here.
Also, the out of cross-sectional properties listed above, only the first three are predefined in the geometry module.

But I think that the idea of making classes of different shapes (instead of methods _circular, _triangular etc. ) inheriting the CrossSection class and converting the attributes (area, second_moment, etc) to methods might help in reducing the repetitiveness of code.

What do you suggest?

@oscarbenjamin

This comment has been minimized.

Copy link
Contributor

commented Jun 5, 2019

If you design this so that it accepts a shape from the geometry module then a user can input some other shape that you haven't thought of. You don't need new classes for the different shapes: they already exist in the geometry module. Those classes already define the shape specific methods that you need (area, centroid, etc).

Of course you can make helper functions for T and I sections since those are common and presumably aren't designed/needed anywhere else. The helper functions can return Polygons which the user can pass in to CrossSection.

@moorepants

This comment has been minimized.

Copy link
Member

commented Jun 5, 2019

There has been prior work to fully develop entities from the geometry module such that they can be used for cross sections. I personally would much rather see it work with the arbritrary 2D closed geometric shapes than a much more limited class. Has research been done in these prior efforts?

@moorepants

This comment has been minimized.

Copy link
Member

commented Jun 5, 2019

I didn't not read Oscar's comment before writing my prior comment. I agree with Oscar.

@moorepants

This comment has been minimized.

Copy link
Member

commented Jun 5, 2019

Here are some prior successful and unsucessful related work:

  • Implemented function for second moment of area for polygon #13665
  • second_moment_of_area_of_ellipse #14190
  • second moment of area of 2d polygon #13939
  • implemented Shape class that can construct closed 2D Figure and methods area, centroid, second_moment_of_area #14434
  • Area, Centroid and Second moment of area of parabola #14335
@ishanaj

This comment has been minimized.

Copy link
Contributor Author

commented Jun 12, 2019

.......Of course you can make helper functions for T and I sections since those are common and presumably aren't designed/needed anywhere else. The helper functions can return Polygons which the user can pass in to CrossSection.

I am working on it, but I am a bit confused where the T and I section helper functions would lie in the code.
Will they be methods of the CrossSection class or simple functions in the cross section file, or they have to be placed somewhere else?

@oscarbenjamin

This comment has been minimized.

Copy link
Contributor

commented Jun 12, 2019

where the T and I section helper functions would lie in the code.

I'd just put them as functions in the beam module. I don't think they would be needed anywhere else.

"""Returns a point with the centroid coordinates"""
if isinstance(self.shape, Ellipse):
return self.shape.center
return self.shape.centroid

This comment has been minimized.

Copy link
@oscarbenjamin

oscarbenjamin Jun 15, 2019

Contributor

It would be better to add a centroid property to Ellipse rather than special-casing it here

@moorepants

This comment has been minimized.

Copy link
Member

commented Jun 15, 2019

It seems you are working to having CrossSection accept Geomtry objects. I'm not sure why you need a CrossSection class at all. Can you explain the rational? The API we've always had in mind to extend this is something like:

rect_cross_section = Rectangle(w, h)  # a 2D closed shape from the geometry module
beam = Beam(length, modulus_of_elasticity, rect_cross_section)

That will handle most all cases, no? The work is this needed to build out the selection of closed shapes for the user. There are basic shapes and then composite shapes than could be created from boolean operations on the basic shapes.

What attributes and methods will CrossSection have that a 2DCloseShape can't have?

@ishanaj

This comment has been minimized.

Copy link
Contributor Author

commented Jun 15, 2019

What attributes and methods will CrossSection have that a 2DCloseShape can't have?

Section modulus, polar modulus and first moment of a shape is currently not calculated by the geometry module, for which the CrossSection class gives the functionality.

@ishanaj

This comment has been minimized.

Copy link
Contributor Author

commented Jun 15, 2019

Can you explain the rational?

Upto what I had imagined was having a separate class for the beam module which would help in some beam specific calculations of section modulus, first moment etc, which are not of much use in the geometry module.
Also providing ease to define complex sections like T and I shape, also hollow circular shapes etc.

Although initially I had thought of adding an optional method in the beam module to define its cross-sectional shape, since shape of the beam is not everytime required.
But we can also have a CrossSection object as an attribute in the beam class.

I have not looked into the idea of composite shapes from boolean operations.
I would surely want to work on it. Just need a bit more idea about it

@moorepants

This comment has been minimized.

Copy link
Member

commented Jun 16, 2019

Section modulus, polar modulus and first moment of a shape is currently not calculated by the geometry module, for which the CrossSection class gives the functionality.

Some of these have been added to geometry objects and I don't seen any reason not to add them there. These things aren't specific to the notion of a "cross section".

Also providing ease to define complex sections like T and I shape, also hollow circular shapes etc.

I would recommend that all of these be in the geometry module and be created by boolean operations of basic shapes.

@oscarbenjamin

This comment has been minimized.

Copy link
Contributor

commented Jun 16, 2019

@ishanaj Thanks you for working on this and I'm sorry that we keep sending you back and forth. It's just that we want to get the code as good as possible.

I recommend to start as simple as possible: add the shape argument to Beam and get some beam calculations working for a simple shape that already has the properties needed. Then if more work is needed in the geometry module for more complicated calculations or more complicated shapes that can come after.

@ishanaj

This comment has been minimized.

Copy link
Contributor Author

commented Jun 16, 2019

I understand.
Here's what I have concluded to do:

  1. Adding the calculations of some of the properties directly to the geometry module.
  2. Adding shape argument to the beam class and make it work with simple geometries.
  3. Making composite shapes via boolean operations. This is a big task to do but I would surely want to work on it later. I have researched about some of the algorithms like Vatti, and Greiner Hormann algorithm. I will open a discussion once I get to it.
    Is there anything that I can refer to for that?
@moorepants

This comment has been minimized.

Copy link
Member

commented Jun 16, 2019

I would suggest starting by getting the existing 2D shapes to work with Beam. Start with the easy ones: circle, ellipse, triangle, etc. Just getting those to work when passed to Beam instead of a symbol for second moment of area would be a very nice addition. In the process of doing that you will learn numerous things that will help you think about what the geometry objects need to work well with Beam.

@ishanaj

This comment has been minimized.

Copy link
Contributor Author

commented Jun 16, 2019

Will work on it!

@ishanaj

This comment has been minimized.

Copy link
Contributor Author

commented Jun 19, 2019

I was working on it. And there are some tests which are related to variable second moment of area, here. How to tackle that? As with the shape being entered, the second moment is calculated by the geometry module.

@ishanaj

This comment has been minimized.

Copy link
Contributor Author

commented Jun 19, 2019

And also the case of composite beam where a new beam is defined with a new second moment, here

@jashan498

This comment has been minimized.

Copy link
Contributor

commented Jun 19, 2019

I am confused, can you explain little more what changes are you doing on the current API of the beam module? There should be no need to change the older test cases

@ishanaj

This comment has been minimized.

Copy link
Contributor Author

commented Jun 19, 2019

Having the geometry object as an argument instead of the second moment of area. Kind of like:

b = Beam(l, E, Circle((0, 0), 5))
@jashan498

This comment has been minimized.

Copy link
Contributor

commented Jun 19, 2019

How about if we let the user decide whether to input second_moment as Symbol or Polygon. You can check its type (using something like isinstance(e, Symbol)) in this setter and set the value accordingly. By this, it won't interfere with the previous API and you won't need to change the other tests.
What are your views on it @moorepants @oscarbenjamin?

@ishanaj

This comment has been minimized.

Copy link
Contributor Author

commented Jun 19, 2019

As far as I can think there can be two ways to resolve this:

  1. Keeping the API same as what it is currently, and having a function add_cross_section(shape) which would then set the second moment and area values.

  2. Changing the API and having a default value of shape shape=None and in this case the user can manually set the second moment.

@ishanaj

This comment has been minimized.

Copy link
Contributor Author

commented Jun 19, 2019

using something like isinstance(e, Symbol))

This looks good. Of course we can make it other way round and check isinstance(e, Polygon or Ellipse)
So that that even if it is an equation (variable I) or a Piecewise equation (in composite beams), it could be included in the else part.

@oscarbenjamin

This comment has been minimized.

Copy link
Contributor

commented Jun 19, 2019

You could use isinstance(e, GeometryEntity) or something like that.

@moorepants

This comment has been minimized.

Copy link
Member

commented Jun 19, 2019

I think it would be fine to allow either type as an input as suggested with no change to the API.

@ishanaj

This comment has been minimized.

Copy link
Contributor Author

commented Jun 19, 2019

So how would we deal with the Beam3D class as it takes both I and A?

@moorepants

This comment has been minimized.

Copy link
Member

commented Jun 19, 2019

You may be able to parse the inputs to the class in the same way as here to determine what the user is passing in. I personally am fine if you change the Beam3D class without following deprecation guidelines since I doubt anyone is using it. It is not tested fully to know if it works robustly. But we need to make Beam backwards compatible.

@ishanaj ishanaj referenced this pull request Jun 19, 2019

Open

Made Beam class accept cross-section geometries #17055

1 of 2 tasks complete
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.