Giter VIP home page Giter VIP logo

simplebeam's Introduction

Simple Beam

License: MIT Code style: black PyPI Version

Introduction

A basic beam bending analysis package, intended to do simple beam bending moment & shear force analysis. The method used is McCauley's method, and the implementation is based on SymPy's beam analysis module, just more nicely wrapped for everyday usage.

The use of the term "Simple" does not mean that only simply-supported beams will be included in this package. McCauley's method can handle fixed ended (and even multi-span) beams. However, beams with axial loads, beams in 3-dimensions and frames, trusses etc. will not be included.

This is primarily intended to be a proof of concept package for me - at this point it is not a robust means for doing your engineering analysis. This may change as the package develops.

Installation

Use your preferred virtual environment solution and then simply pip install.

pip install simplebeam

Basic Usage

The following demonstrates basic usage of simplebeam:

>>> from simplebeam import simple, point
>>> length = 1
>>> load = point(position=length/2, magnitude=1)
>>> beam = simple(length=length, loads=load)
>>> beam.max_moment()
0.25

By itself, this seems like overkill - M = PL / 4 would be faster. However, consider the following examples:

>>> from simplebeam import simple, udl
>>> length = 5
>>> l1 = udl(magnitude=-5000)
>>> l2 = udl(magnitude=-5000, start=0, end=3.5)
>>> beam = simple(length=length, elastic_modulus=200e9, second_moment=0.0001, loads=[l1, l2])
>>> beam.max_moment_locations()
((0.0, 0.0), (2.4000000000000004, -28500.0))

>>> beam.plot_deflection()

Or:

>>> from simplebeam import Beam, pin, udl
>>> length = 5
>>> r1 = pin(position=0)
>>> r2 = pin(position=2)
>>> r3 = pin(position=4)
>>> l1 = udl(magnitude=-5000)
>>> beam = Beam(length=length, elastic_modulus=200e9, second_moment=0.0001, restraints=[r1, r2, r3], loads=l1)
>>> beam.plot_moment()

>>> beam.reaction_summary()

                                  Reactions                                   
┌────────────────────────────┬────────────────────────────┬───────────────────┐
│          PositionForceMoment       │
├────────────────────────────┼────────────────────────────┼───────────────────┤
│         0.000e+004.062e+03None        │
│         2.000e+001.062e+04None        │
│         4.000e+001.031e+04None        │
├────────────────────────────┼────────────────────────────┼───────────────────┤
│            Max.            │         1.062e+04None        │
│            Min.            │         4.062e+03None        │
└────────────────────────────┴────────────────────────────┴───────────────────┘

Documentation

You're reading it. Additionally, check the tests folder to see additional uses. I may add documentation at some future point in time but no promises.

Future Development

The following future developments may be done:

  • Implementation of helper methods for different load types.
  • Multiple load cases & load combinations
  • Implementation of beams with pins & varying properties.

Disclaimer

While all efforts have been made to ensure that the appropriate engineering theories etc. have been implemented correctly, it is the user's responsibilty to ensure that all output is correct. In particular, users should be familiar with basic structural mechanics and standard engineering practices.

For example, you should be doing independent checks of tools you take from unknown authors on the internet.

Contributing

Feel free to contribute through a pull request to provide bug fixes, new features or documentation.

Note that the intent of this program is that it will remain focussed on simple 2D beam bending only.

simplebeam's People

Contributors

skane88 avatar

Stargazers

 avatar  avatar Joseph Flack avatar

Watchers

 avatar Joseph Flack avatar

simplebeam's Issues

Add Annotation to Plots

Add functionality to automatically annotate maximums & minimums with their x, y co-ordinates on plots.

  • Basic annotation is probably easy enough.
  • Consider whether need to add multiple annotations for cases where there are multiple peaks. Probably not, because that could result in many annotations and a cluttered plot, especially if curves are generated by the adaptive algorithm. But may be worth trialling anyway.

def plot_results(

Update Triangular helper method

def triangular(*, magnitude, load_length, start=None) -> Load:
"""
Generate a triangular load.
:param magnitude: The peak magnitude of the UDL load.
:param start: The starting point of the UDL. If None, starts at the beginning of the
beam.
:param length: The length of the UDL load to apply.
Note that start + load_length must be less than the length of the beam.
:return: A Load object representing the UDL load.
"""
# note that the length of the load is required so that the slope of the ramp load
# can be determined - sympy uses the slope of the load, not the peak magnitude
# to determine the ramp load.
if start is None:
start = 0
end = start + load_length
slope = magnitude / load_length
return Load(order="ramp", magnitude=slope, start=start, end=end)

Update to generate loads that are decreasing as well as increasing along the beam's length.

Load Cases and Combinations

Consider how to implement multiple load cases and combinations.

  • Probably need a Case object, possibly subclasses for Combinations? Or just implement combinations with a table?
  • Need to consider how to allow combinations of combinations without getting cycles.

Move Beam Results to Separate Class

Moving Beam results to a separate class allows getting rid of pylint declarative at top of class. Will likely also allow for easier of load combinations. Suggest following approach for best UX:

  • Still need to retain ability to get results with as little typing as possible.
  • Also want to retain as many explicit calls as possible (e.g. .moment_at_point() which is very clear what is going on).
  • Could create a Results object to store results and and access as a property of Beam - e.g. Beam.Results
  • could subclass Dict or otherwise implement the indexing protocol to allow for indexed access to load combinations? E.g. call to Beam.Results gives the whole results object (possibly just displays a __repr__ with key stats in the terminal?). Calling Beam.Results['combination'] gets results for a specific combination? May need two objects- Results and ResultCase.
  • If there is only one load case / combination, calling a property of the Results class should just return the results for the one combination / case.
  • the current ._symbeam object of Beam probably needs to be stored in the Results class after generation.

Allow Plotting Multiple Results

Update plotting to show multiple results.

  • Probably need list of curve types as an allowed input.
  • Probably need a loop somewhere to generate multiple axes.
  • Probably need to plot results stacked above each other because it doesn't make sense to plot on the same axes.

def plot_results(
self,
result_type: ResultType | str,
min_points: int = 101,
user_points: list[float] | float | None = None,
fast: bool = True,
):
"""
Plot the results along the length of the beam.
:param result_type: A ResultType object or the following strings:
'shear', 'moment', 'slope', 'deflection' or 's', 'm', 'sl', 'd'
:param min_points: The minimum no. of points to return.
:param user_points: Points to keep at user defined locations.
:param fast: If fast, only evaluate at min_points and user_points. If not fast,
use an adaptive algorithm to try and find any singularities in the beam
curves. If the fast method doesn't give correct results,
consider trying the slow method.
"""
result_map = {
"s": ResultType.SHEAR,
"m": ResultType.MOMENT,
"sl": ResultType.SLOPE,
"d": ResultType.DEFLECTION,
"shear": ResultType.SHEAR,
"moment": ResultType.MOMENT,
"slope": ResultType.SLOPE,
"deflection": ResultType.DEFLECTION,
}
if isinstance(result_type, str):
result_type = result_map[result_type]
match result_type:
case ResultType.LOAD:
curve = self._load_curve
y_label = "Load"
case ResultType.SHEAR:
curve = self.shear_curve
y_label = "Shear"
case ResultType.MOMENT:
curve = self.moment_curve
y_label = "Moment"
case ResultType.SLOPE:
curve = self.slope_curve
y_label = "Slope"
case ResultType.DEFLECTION:
curve = self.deflection_curve
y_label = "Deflection"
case _:
raise ResultError("Invalid Result Type Requested")
x, y = curve(min_points=min_points, user_points=user_points, fast=fast)
fig, ax = plt.subplots()
ax.plot(x, y, linewidth=2)
ax.fill_between(x, y, alpha=0.3)
ax.set_xlabel("Length")
ax.set_ylabel(y_label)
ax.grid(True)
fig.show()

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.