Creating a Geometry, Mesh and Material Properties

Before performing a cross-section analysis, the geometry of the cross-section and a finite element mesh must be created. Optionally, material properties can be applied to different regions of the cross-section.

Cross-Section Geometry

The geometry of a cross-section defines its dimensions and shape and involves the creation of a Geometry object. This geometry object stores all the information needed to create a finite element mesh.

class sectionproperties.pre.sections.Geometry(control_points, shift)[source]

Parent class for a cross-section geometry input.

Provides an interface for the user to specify the geometry defining a cross-section. A method is provided for generating a triangular mesh, for translating the cross-section by (x, y) and for plotting the geometry.

Variables:
  • points (list[list[float, float]]) – List of points (x, y) defining the vertices of the cross-section
  • facets (list[list[int, int]]) – List of point index pairs (p1, p2) defining the edges of the cross-section
  • holes (list[list[float, float]]) – List of points (x, y) defining the locations of holes within the cross-section. If there are no holes, provide an empty list [].
  • control_points (list[list[float, float]]) – A list of points (x, y) that define different regions of the cross-section. A control point is an arbitrary point within a region enclosed by facets.
  • shift (list[float, float]) – Vector that shifts the cross-section by (x, y)
  • perimeter (list[int]) – List of facet indices defining the perimeter of the cross-section

Different regions of the geometry can be specified by defining a list of control_points, which are located within unique enclosed areas of the geometry. Different regions can be used to specify different mesh sizes and/or different material properties within the structural cross-section. See the Examples for some example scripts in which different regions are specified through a list of control points.

Creating Common Structural Geometries

In order to make your life easier, there are a number of built-in classes that generate typical structural cross-sections that inherit from the Geometry class. Note that these classes automatically assign a control_point to the geometry object.

Rectangular Section

class sectionproperties.pre.sections.RectangularSection(d, b, shift=[0, 0])[source]

Bases: sectionproperties.pre.sections.Geometry

Constructs a rectangular section with the bottom left corner at the origin (0, 0), with depth d and width b.

Parameters:
  • d (float) – Depth (y) of the rectangle
  • b (float) – Width (x) of the rectangle
  • shift (list[float, float]) – Vector that shifts the cross-section by (x, y)

The following example creates a rectangular cross-section with a depth of 100 and width of 50, and generates a mesh with a maximum triangular area of 5:

import sectionproperties.pre.sections as sections

geometry = sections.RectangularSection(d=100, b=50)
mesh = geometry.create_mesh(mesh_sizes=[5])
../_images/rectangle_geometry.png

Rectangular section geometry.

../_images/rectangle_mesh.png

Mesh generated from the above geometry.

Circular Section

class sectionproperties.pre.sections.CircularSection(d, n, shift=[0, 0])[source]

Bases: sectionproperties.pre.sections.Geometry

Constructs a solid circle centered at the origin (0, 0) with diameter d and using n points to construct the circle.

Parameters:
  • d (float) – Diameter of the circle
  • n (int) – Number of points discretising the circle
  • shift (list[float, float]) – Vector that shifts the cross-section by (x, y)

The following example creates a circular cross-section with a diameter of 50 with 64 points, and generates a mesh with a maximum triangular area of 2.5:

import sectionproperties.pre.sections as sections

geometry = sections.CircularSection(d=50, n=64)
mesh = geometry.create_mesh(mesh_sizes=[2.5])
../_images/circle_geometry.png

Circular section geometry.

../_images/circle_mesh.png

Mesh generated from the above geometry.

Circular Hollow Section (CHS)

class sectionproperties.pre.sections.Chs(d, t, n, shift=[0, 0])[source]

Bases: sectionproperties.pre.sections.Geometry

Constructs a circular hollow section centered at the origin (0, 0), with diameter d and thickness t, using n points to construct the inner and outer circles.

Parameters:
  • d (float) – Outer diameter of the CHS
  • t (float) – Thickness of the CHS
  • n (int) – Number of points discretising the inner and outer circles
  • shift (list[float, float]) – Vector that shifts the cross-section by (x, y)

The following example creates a CHS discretised with 64 points, with a diameter of 48 and thickness of 3.2, and generates a mesh with a maximum triangular area of 1.0:

import sectionproperties.pre.sections as sections

geometry = sections.Chs(d=48, t=3.2, n=64)
mesh = geometry.create_mesh(mesh_sizes=[1.0])
../_images/chs_geometry.png

CHS geometry.

../_images/chs_mesh.png

Mesh generated from the above geometry.

Elliptical Section

class sectionproperties.pre.sections.EllipticalSection(d_y, d_x, n, shift=[0, 0])[source]

Bases: sectionproperties.pre.sections.Geometry

Constructs a solid ellipse centered at the origin (0, 0) with vertical diameter d_y and horizontal diameter d_x, using n points to construct the ellipse.

Parameters:
  • d_y (float) – Diameter of the ellipse in the y-dimension
  • d_x (float) – Diameter of the ellipse in the x-dimension
  • n (int) – Number of points discretising the ellipse
  • shift (list[float, float]) – Vector that shifts the cross-section by (x, y)

The following example creates an elliptical cross-section with a vertical diameter of 25 and horizontal diameter of 50, with 40 points, and generates a mesh with a maximum triangular area of 1.0:

import sectionproperties.pre.sections as sections

geometry = sections.EllipticalSection(d_y=25, d_x=50, n=40)
mesh = geometry.create_mesh(mesh_sizes=[1.0])
../_images/ellipse_geometry.png

Elliptical section geometry.

../_images/ellipse_mesh.png

Mesh generated from the above geometry.

Elliptical Hollow Section (EHS)

class sectionproperties.pre.sections.Ehs(d_y, d_x, t, n, shift=[0, 0])[source]

Bases: sectionproperties.pre.sections.Geometry

Constructs an elliptical hollow section centered at the origin (0, 0), with outer vertical diameter d_y, outer horizontal diameter d_x, and thickness t, using n points to construct the inner and outer ellipses.

Parameters:
  • d_y (float) – Diameter of the ellipse in the y-dimension
  • d_x (float) – Diameter of the ellipse in the x-dimension
  • t (float) – Thickness of the EHS
  • n (int) – Number of points discretising the inner and outer ellipses
  • shift (list[float, float]) – Vector that shifts the cross-section by (x, y)

The following example creates a EHS discretised with 30 points, with a outer vertical diameter of 25, outer horizontal diameter of 50, and thickness of 2.0, and generates a mesh with a maximum triangular area of 0.5:

import sectionproperties.pre.sections as sections

geometry = sections.Ehs(d_y=25, d_x=50, t=2.0, n=64)
mesh = geometry.create_mesh(mesh_sizes=[0.5])
../_images/ehs_geometry.png

EHS geometry.

../_images/ehs_mesh.png

Mesh generated from the above geometry.

Rectangular Hollow Section (RHS)

class sectionproperties.pre.sections.Rhs(d, b, t, r_out, n_r, shift=[0, 0])[source]

Bases: sectionproperties.pre.sections.Geometry

Constructs a rectangular hollow section centered at (b/2, d/2), with depth d, width b, thickness t and outer radius r_out, using n_r points to construct the inner and outer radii. If the outer radius is less than the thickness of the RHS, the inner radius is set to zero.

Parameters:
  • d (float) – Depth of the RHS
  • b (float) – Width of the RHS
  • t (float) – Thickness of the RHS
  • r_out (float) – Outer radius of the RHS
  • n_r (int) – Number of points discretising the inner and outer radii
  • shift (list[float, float]) – Vector that shifts the cross-section by (x, y)

The following example creates an RHS with a depth of 100, a width of 50, a thickness of 6 and an outer radius of 9, using 8 points to discretise the inner and outer radii. A mesh is generated with a maximum triangular area of 2.0:

import sectionproperties.pre.sections as sections

geometry = sections.Rhs(d=100, b=50, t=6, r_out=9, n_r=8)
mesh = geometry.create_mesh(mesh_sizes=[2.0])
../_images/rhs_geometry.png

RHS geometry.

../_images/rhs_mesh.png

Mesh generated from the above geometry.

I-Section

class sectionproperties.pre.sections.ISection(d, b, t_f, t_w, r, n_r, shift=[0, 0])[source]

Bases: sectionproperties.pre.sections.Geometry

Constructs an I-section centered at (b/2, d/2), with depth d, width b, flange thickness t_f, web thickness t_w, and root radius r, using n_r points to construct the root radius.

Parameters:
  • d (float) – Depth of the I-section
  • b (float) – Width of the I-section
  • t_f (float) – Flange thickness of the I-section
  • t_w (float) – Web thickness of the I-section
  • r (float) – Root radius of the I-section
  • n_r (int) – Number of points discretising the root radius
  • shift (list[float, float]) – Vector that shifts the cross-section by (x, y)

The following example creates an I-section with a depth of 203, a width of 133, a flange thickness of 7.8, a web thickness of 5.8 and a root radius of 8.9, using 16 points to discretise the root radius. A mesh is generated with a maximum triangular area of 3.0:

import sectionproperties.pre.sections as sections

geometry = sections.ISection(d=203, b=133, t_f=7.8, t_w=5.8, r=8.9, n_r=16)
mesh = geometry.create_mesh(mesh_sizes=[3.0])
../_images/isection_geometry.png

I-section geometry.

../_images/isection_mesh.png

Mesh generated from the above geometry.

Monosymmetric I-Section

class sectionproperties.pre.sections.MonoISection(d, b_t, b_b, t_fb, t_ft, t_w, r, n_r, shift=[0, 0])[source]

Bases: sectionproperties.pre.sections.Geometry

Constructs a monosymmetric I-section centered at (max(b_t, b_b)/2, d/2), with depth d, top flange width b_t, bottom flange width b_b, top flange thickness t_ft, top flange thickness t_fb, web thickness t_w, and root radius r, using n_r points to construct the root radius.

Parameters:
  • d (float) – Depth of the I-section
  • b_t (float) – Top flange width
  • b_b (float) – Bottom flange width
  • t_ft (float) – Top flange thickness of the I-section
  • t_fb (float) – Bottom flange thickness of the I-section
  • t_w (float) – Web thickness of the I-section
  • r (float) – Root radius of the I-section
  • n_r (int) – Number of points discretising the root radius
  • shift (list[float, float]) – Vector that shifts the cross-section by (x, y)

The following example creates a monosymmetric I-section with a depth of 200, a top flange width of 50, a top flange thickness of 12, a bottom flange width of 130, a bottom flange thickness of 8, a web thickness of 6 and a root radius of 8, using 16 points to discretise the root radius. A mesh is generated with a maximum triangular area of 3.0:

import sectionproperties.pre.sections as sections

geometry = sections.MonoISection(
    d=200, b_t=50, b_b=130, t_ft=12, t_fb=8, t_w=6, r=8, n_r=16
)
mesh = geometry.create_mesh(mesh_sizes=[3.0])
../_images/monoisection_geometry.png

I-section geometry.

../_images/monoisection_mesh.png

Mesh generated from the above geometry.

Tapered Flange I-Section

class sectionproperties.pre.sections.TaperedFlangeISection(d, b, t_f, t_w, r_r, r_f, alpha, n_r, shift=[0, 0])[source]

Bases: sectionproperties.pre.sections.Geometry

Constructs a Tapered Flange I-section centered at (b/2, d/2), with depth d, width b, mid-flange thickness t_f, web thickness t_w, root radius r_r, flange radius r_f and flange angle alpha, using n_r points to construct the radii.

Parameters:
  • d (float) – Depth of the Tapered Flange I-section
  • b (float) – Width of the Tapered Flange I-section
  • t_f (float) – Mid-flange thickness of the Tapered Flange I-section (measured at the point equidistant from the face of the web to the edge of the flange)
  • t_w (float) – Web thickness of the Tapered Flange I-section
  • r_r (float) – Root radius of the Tapered Flange I-section
  • r_f (float) – Flange radius of the Tapered Flange I-section
  • alpha (float) – Flange angle of the Tapered Flange I-section (degrees)
  • n_r (int) – Number of points discretising the radii
  • shift (list[float, float]) – Vector that shifts the cross-section by (x, y)

The following example creates a Tapered Flange I-section with a depth of 588, a width of 191, a mid-flange thickness of 27.2, a web thickness of 15.2, a root radius of 17.8, a flange radius of 8.9 and a flange angle of 8°, using 16 points to discretise the radii. A mesh is generated with a maximum triangular area of 20.0:

import sectionproperties.pre.sections as sections

geometry = sections.TaperedFlangeISection(
    d=588, b=191, t_f=27.2, t_w=15.2, r_r=17.8, r_f=8.9, alpha=8, n_r=16
)
mesh = geometry.create_mesh(mesh_sizes=[20.0])
../_images/taperedisection_geometry.png

I-section geometry.

../_images/taperedisection_mesh.png

Mesh generated from the above geometry.

Parallel Flange Channel (PFC) Section

class sectionproperties.pre.sections.PfcSection(d, b, t_f, t_w, r, n_r, shift=[0, 0])[source]

Bases: sectionproperties.pre.sections.Geometry

Constructs a PFC section with the bottom left corner at the origin (0, 0), with depth d, width b, flange thickness t_f, web thickness t_w and root radius r, using n_r points to construct the root radius.

Parameters:
  • d (float) – Depth of the PFC section
  • b (float) – Width of the PFC section
  • t_f (float) – Flange thickness of the PFC section
  • t_w (float) – Web thickness of the PFC section
  • r (float) – Root radius of the PFC section
  • n_r (int) – Number of points discretising the root radius
  • shift (list[float, float]) – Vector that shifts the cross-section by (x, y)

The following example creates a PFC section with a depth of 250, a width of 90, a flange thickness of 15, a web thickness of 8 and a root radius of 12, using 8 points to discretise the root radius. A mesh is generated with a maximum triangular area of 5.0:

import sectionproperties.pre.sections as sections

geometry = sections.PfcSection(d=250, b=90, t_f=15, t_w=8, r=12, n_r=8)
mesh = geometry.create_mesh(mesh_sizes=[5.0])
../_images/pfc_geometry.png

PFC geometry.

../_images/pfc_mesh.png

Mesh generated from the above geometry.

Tapered Flange Channel Section

class sectionproperties.pre.sections.TaperedFlangeChannel(d, b, t_f, t_w, r_r, r_f, alpha, n_r, shift=[0, 0])[source]

Bases: sectionproperties.pre.sections.Geometry

Constructs a Tapered Flange Channel section with the bottom left corner at the origin (0, 0), with depth d, width b, mid-flange thickness t_f, web thickness t_w, root radius r_r, flange radius r_f and flange angle alpha, using n_r points to construct the radii.

Parameters:
  • d (float) – Depth of the Tapered Flange Channel section
  • b (float) – Width of the Tapered Flange Channel section
  • t_f (float) – Mid-flange thickness of the Tapered Flange Channel section (measured at the point equidistant from the face of the web to the edge of the flange)
  • t_w (float) – Web thickness of the Tapered Flange Channel section
  • r_r (float) – Root radius of the Tapered Flange Channel section
  • r_f (float) – Flange radius of the Tapered Flange Channel section
  • alpha (float) – Flange angle of the Tapered Flange Channel section (degrees)
  • n_r (int) – Number of points discretising the radii
  • shift (list[float, float]) – Vector that shifts the cross-section by (x, y)

The following example creates a Tapered Flange Channel section with a depth of 10, a width of 3.5, a mid-flange thickness of 0.575, a web thickness of 0.475, a root radius of 0.575, a flange radius of 0.4 and a flange angle of 8°, using 16 points to discretise the radii. A mesh is generated with a maximum triangular area of 0.02:

import sectionproperties.pre.sections as sections

geometry = sections.TaperedFlangeChannel(
    d=10, b=3.5, t_f=0.575, t_w=0.475, r_r=0.575, r_f=0.4, alpha=8, n_r=16
)
mesh = geometry.create_mesh(mesh_sizes=[0.02])
../_images/taperedchannel_geometry.png

I-section geometry.

../_images/taperedchannel_mesh.png

Mesh generated from the above geometry.

Tee Section

class sectionproperties.pre.sections.TeeSection(d, b, t_f, t_w, r, n_r, shift=[0, 0])[source]

Bases: sectionproperties.pre.sections.Geometry

Constructs a Tee section with the top left corner at (0, d), with depth d, width b, flange thickness t_f, web thickness t_w and root radius r, using n_r points to construct the root radius.

Parameters:
  • d (float) – Depth of the Tee section
  • b (float) – Width of the Tee section
  • t_f (float) – Flange thickness of the Tee section
  • t_w (float) – Web thickness of the Tee section
  • r (float) – Root radius of the Tee section
  • n_r (int) – Number of points discretising the root radius
  • shift (list[float, float]) – Vector that shifts the cross-section by (x, y)

The following example creates a Tee section with a depth of 200, a width of 100, a flange thickness of 12, a web thickness of 6 and a root radius of 8, using 8 points to discretise the root radius. A mesh is generated with a maximum triangular area of 3.0:

import sectionproperties.pre.sections as sections

geometry = sections.TeeSection(d=200, b=100, t_f=12, t_w=6, r=8, n_r=8)
mesh = geometry.create_mesh(mesh_sizes=[3.0])
../_images/tee_geometry.png

Tee section geometry.

../_images/tee_mesh.png

Mesh generated from the above geometry.

Angle Section

class sectionproperties.pre.sections.AngleSection(d, b, t, r_r, r_t, n_r, shift=[0, 0])[source]

Bases: sectionproperties.pre.sections.Geometry

Constructs an angle section with the bottom left corner at the origin (0, 0), with depth d, width b, thickness t, root radius r_r and toe radius r_t, using n_r points to construct the radii.

Parameters:
  • d (float) – Depth of the angle section
  • b (float) – Width of the angle section
  • t (float) – Thickness of the angle section
  • r_r (float) – Root radius of the angle section
  • r_t (float) – Toe radius of the angle section
  • n_r (int) – Number of points discretising the radii
  • shift (list[float, float]) – Vector that shifts the cross-section by (x, y)

The following example creates an angle section with a depth of 150, a width of 100, a thickness of 8, a root radius of 12 and a toe radius of 5, using 16 points to discretise the radii. A mesh is generated with a maximum triangular area of 2.0:

import sectionproperties.pre.sections as sections

geometry = sections.AngleSection(d=150, b=100, t=8, r_r=12, r_t=5, n_r=16)
mesh = geometry.create_mesh(mesh_sizes=[2.0])
../_images/angle_geometry.png

Angle section geometry.

../_images/angle_mesh.png

Cee Section

class sectionproperties.pre.sections.CeeSection(d, b, l, t, r_out, n_r, shift=[0, 0])[source]

Bases: sectionproperties.pre.sections.Geometry

Constructs a Cee section with the bottom left corner at the origin (0, 0), with depth d, width b, lip l, thickness t and outer radius r_out, using n_r points to construct the radius. If the outer radius is less than the thickness of the Cee Section, the inner radius is set to zero.

Parameters:
  • d (float) – Depth of the Cee section
  • b (float) – Width of the Cee section
  • l (float) – Lip of the Cee section
  • t (float) – Thickness of the Cee section
  • r_out (float) – Outer radius of the Cee section
  • n_r (int) – Number of points discretising the outer radius
  • shift (list[float, float]) – Vector that shifts the cross-section by (x, y)
Raises:

Exception – Lip length must be greater than the outer radius

The following example creates a Cee section with a depth of 125, a width of 50, a lip of 30, a thickness of 1.5 and an outer radius of 6, using 8 points to discretise the radius. A mesh is generated with a maximum triangular area of 0.25:

import sectionproperties.pre.sections as sections

geometry = sections.CeeSection(d=125, b=50, l=30, t=1.5, r_out=6, n_r=8)
mesh = geometry.create_mesh(mesh_sizes=[0.25])
../_images/cee_geometry.png

Cee section geometry.

../_images/cee_mesh.png

Zed Section

class sectionproperties.pre.sections.ZedSection(d, b_l, b_r, l, t, r_out, n_r, shift=[0, 0])[source]

Bases: sectionproperties.pre.sections.Geometry

Constructs a Zed section with the bottom left corner at the origin (0, 0), with depth d, left flange width b_l, right flange width b_r, lip l, thickness t and outer radius r_out, using n_r points to construct the radius. If the outer radius is less than the thickness of the Zed Section, the inner radius is set to zero.

Parameters:
  • d (float) – Depth of the Zed section
  • b_l (float) – Left flange width of the Zed section
  • b_r (float) – Right flange width of the Zed section
  • l (float) – Lip of the Zed section
  • t (float) – Thickness of the Zed section
  • r_out (float) – Outer radius of the Zed section
  • n_r (int) – Number of points discretising the outer radius
  • shift (list[float, float]) – Vector that shifts the cross-section by (x, y)
Raises:

Exception – Lip length must be greater than the outer radius

The following example creates a Zed section with a depth of 100, a left flange width of 40, a right flange width of 50, a lip of 20, a thickness of 1.2 and an outer radius of 5, using 8 points to discretise the radius. A mesh is generated with a maximum triangular area of 0.15:

import sectionproperties.pre.sections as sections

geometry = sections.ZedSection(d=100, b_l=40, b_r=50, l=20, t=1.2, r_out=5, n_r=8)
mesh = geometry.create_mesh(mesh_sizes=[0.15])
../_images/zed_geometry.png

Zed section geometry.

../_images/zed_mesh.png

Cruciform Section

class sectionproperties.pre.sections.CruciformSection(d, b, t, r, n_r, shift=[0, 0])[source]

Bases: sectionproperties.pre.sections.Geometry

Constructs a cruciform section centered at the origin (0, 0), with depth d, width b, thickness t and root radius r, using n_r points to construct the root radius.

Parameters:
  • d (float) – Depth of the cruciform section
  • b (float) – Width of the cruciform section
  • t (float) – Thickness of the cruciform section
  • r (float) – Root radius of the cruciform section
  • n_r (int) – Number of points discretising the root radius
  • shift (list[float, float]) – Vector that shifts the cross-section by (x, y)

The following example creates a cruciform section with a depth of 250, a width of 175, a thickness of 12 and a root radius of 16, using 16 points to discretise the radius. A mesh is generated with a maximum triangular area of 5.0:

import sectionproperties.pre.sections as sections

geometry = sections.CruciformSection(d=250, b=175, t=12, r=16, n_r=16)
mesh = geometry.create_mesh(mesh_sizes=[5.0])
../_images/cruciform_geometry.png

Cruciform section geometry.

../_images/cruciform_mesh.png

Polygon Section

class sectionproperties.pre.sections.PolygonSection(d, t, n_sides, r_in=0, n_r=1, rot=0, shift=[0, 0])[source]

Bases: sectionproperties.pre.sections.Geometry

Constructs a regular hollow polygon section centered at (0, 0), with a pitch circle diameter of bounding polygon d, thickness t, number of sides n_sides and an optional inner radius r_in, using n_r points to construct the inner and outer radii (if radii is specified).

Parameters:
  • d (float) – Pitch circle diameter of the outer bounding polygon (i.e. diameter of circle that passes through all vertices of the outer polygon)
  • t (float) – Thickness of the polygon section wall
  • r_in (float) – Inner radius of the polygon corners. By default, if not specified, a polygon with no corner radii is generated.
  • n_r (int) – Number of points discretising the inner and outer radii, ignored if no inner radii is specified
  • rot – Initial counterclockwise rotation in degrees. By default bottom face is aligned with x axis.
  • shift (list[float, float]) – Vector that shifts the cross-section by (x, y)
Raises:

Exception – Number of sides in polygon must be greater than or equal to 3

The following example creates an Octagonal section (8 sides) with a diameter of 200, a thickness of 6 and an inner radius of 20, using 12 points to discretise the inner and outer radii. A mesh is generated with a maximum triangular area of 5:

import sectionproperties.pre.sections as sections

geometry = sections.PolygonSection(d=200, t=6, n_sides=8, r_in=20, n_r=12)
mesh = geometry.create_mesh(mesh_sizes=[5])
../_images/polygon_geometry.png

Octagonal section geometry.

../_images/polygon_mesh.png

Mesh generated from the above geometry.

Box Girder Section

class sectionproperties.pre.sections.BoxGirderSection(d, b_t, b_b, t_ft, t_fb, t_w, shift=[0, 0])[source]

Bases: sectionproperties.pre.sections.Geometry

Constructs a Box Girder section centered at at (max(b_t, b_b)/2, d/2), with depth d, top width b_t, bottom width b_b, top flange thickness t_ft, bottom flange thickness t_fb and web thickness t_w.

Parameters:
  • d (float) – Depth of the Box Girder section
  • b_t (float) – Top width of the Box Girder section
  • b_b (float) – Bottom width of the Box Girder section
  • t_ft (float) – Top lange thickness of the Box Girder section
  • t_fb (float) – Bottom flange thickness of the Box Girder section
  • t_w (float) – Web thickness of the Box Girder section
  • shift (list[float, float]) – Vector that shifts the cross-section by (x, y)

The following example creates a Box Gider section with a depth of 1200, a top width of 1200, a bottom width of 400, a top flange thickness of 16, a bottom flange thickness of 12 and a web thickness of 8. A mesh is generated with a maximum triangular area of 5.0:

import sectionproperties.pre.sections as sections

geometry = sections.BoxGirderSection(d=1200, b_t=1200, b_b=400, t_ft=100, t_fb=80, t_w=50)
mesh = geometry.create_mesh(mesh_sizes=[200.0])
../_images/box_girder_geometry.png

Box Girder geometry.

../_images/box_girder_mesh.png

Mesh generated from the above geometry.

Arbitrary Cross-Section Geometries

If none of the above classes gives you what you need, you can create a CustomSection geometry object, which is defined by a list of points (nodes), facets (node connectivities) and hole locations:

class sectionproperties.pre.sections.CustomSection(points, facets, holes, control_points, shift=[0, 0], perimeter=[])[source]

Bases: sectionproperties.pre.sections.Geometry

Constructs a cross-section from a list of points, facets, holes and a user specified control point.

Parameters:
  • points (list[list[float, float]]) – List of points (x, y) defining the vertices of the cross-section
  • facets (list[list[int, int]]) – List of point index pairs (p1, p2) defining the edges of the cross-section
  • holes (list[list[float, float]]) – List of points (x, y) defining the locations of holes within the cross-section. If there are no holes, provide an empty list [].
  • control_points (list[list[float, float]]) – A list of points (x, y) that define different regions of the cross-section. A control point is an arbitrary point within a region enclosed by facets.
  • shift (list[float, float]) – Vector that shifts the cross-section by (x, y)
  • perimeter – List of facet indices defining the perimeter of the cross-section

The following example creates a hollow trapezium with a base width of 100, top width of 50, height of 50 and a wall thickness of 10. A mesh is generated with a maximum triangular area of 2.0:

import sectionproperties.pre.sections as sections

points = [[0, 0], [100, 0], [75, 50], [25, 50], [15, 10], [85, 10], [70, 40], [30, 40]]
facets = [[0, 1], [1, 2], [2, 3], [3, 0], [4, 5], [5, 6], [6, 7], [7, 4]]
holes = [[50, 25]]
control_points = [[5, 5]]
perimeter = [0, 1, 2, 3]

geometry = sections.CustomSection(
    points, facets, holes, control_points, perimeter=perimeter
)
mesh = geometry.create_mesh(mesh_sizes=[2.0])
../_images/custom_geometry.png

Custom section geometry.

../_images/custom_mesh.png

Mesh generated from the above geometry.

Note

Ensure that the control_points you choose lie within the CustomSection. If any of the control_points are outside the region, on an edge or within a hole, the meshing algorithm will likely not treat distinct areas within the CustomSection as a separate regions and mesh refinements may not work as anticipated.

Note

In order to calculate the perimeter of the cross-section be sure to enter the facet indices that correspond to the perimeter of your cross-section.

Merging Geometries

If you wish to merge multiple Geometry objects into a single object, you can use the MergedSection class:

class sectionproperties.pre.sections.MergedSection(sections)[source]

Bases: sectionproperties.pre.sections.Geometry

Merges a number of section geometries into one geometry. Note that for the meshing algorithm to work, there needs to be connectivity between all regions of the provided geometries. Overlapping of geometries is permitted.

Parameters:sections (list[Geometry]) – A list of geometry objects to merge into one Geometry object

The following example creates a combined cross-section with a 150x100x6 RHS placed on its side on top of a 200UB25.4. A mesh is generated with a maximum triangle size of 5.0 for the I-section and 2.5 for the RHS:

import sectionproperties.pre.sections as sections

isection = sections.ISection(d=203, b=133, t_f=7.8, t_w=5.8, r=8.9, n_r=8)
box = sections.Rhs(d=100, b=150, t=6, r_out=15, n_r=8, shift=[-8.5, 203])

geometry = sections.MergedSection([isection, box])
geometry.clean_geometry()
mesh = geometry.create_mesh(mesh_sizes=[5.0, 2.5])
../_images/merged_geometry.png

Merged section geometry.

../_images/merged_mesh.png

Note

There must be connectivity between the Geometry objects that you wish to merge. It is currently not possible to analyse a cross-section that is composed of two or more unconnected domains.

Note

You may need to overwrite the perimeter facets list if predefined sections are used. Enabling labels while plotting the geometry is an easy way to manually identify the facet indices that make up the perimeter of the cross-section.

Cleaning the Geometry

When creating a merged section often there are overlapping facets or duplicate nodes. These geometry artefacts can cause difficulty for the meshing algorithm. It is therefore recommended to clean the geometry after merging sections which may result in overlapping or intersecting facets, or duplicate nodes. Cleaning the geometry can be carried out by using the clean_geometry() method:

Geometry.clean_geometry(verbose=False)[source]

Peforms a full clean on the geometry.

Parameters:verbose (bool) – If set to true, information related to the geometry cleaning process is printed to the terminal.

Note

Cleaning the geometry is always recommended when creating a merged section, which may result in overlapping or intersecting facets, or duplicate nodes.

Perimeter Offset

The perimeter of a cross-section geometry can be offset by using the offset_perimeter() method:

sectionproperties.pre.offset.offset_perimeter(geometry, offset, side='left', plot_offset=False)[source]

Offsets the perimeter of a geometry of a Geometry object by a certain distance. Note that the perimeter facet list must be entered in a consecutive order.

Parameters:
  • geometry (Geometry) – Cross-section geometry object
  • offset (float) – Offset distance for the perimeter
  • side (string) – Side of the perimeter offset, either ‘left’ or ‘right’. E.g. ‘left’ for a counter-clockwise offsets the perimeter inwards.
  • plot_offset (bool) – If set to True, generates a plot comparing the old and new geometry

The following example ‘corrodes’ a 200UB25 I-section by 1.5 mm and compares a few of the section properties:

import sectionproperties.pre.sections as sections
from sectionproperties.pre.offset import offset_perimeter
from sectionproperties.analysis.cross_section import CrossSection

# calculate original section properties
original_geometry = sections.ISection(d=203, b=133, t_f=7.8, t_w=5.8, r=8.9, n_r=16)
original_mesh = original_geometry.create_mesh(mesh_sizes=[3.0])
original_section = CrossSection(original_geometry, original_mesh)
original_section.calculate_geometric_properties()
original_area = original_section.get_area()
(original_ixx, _, _) = original_section.get_ic()

# calculate corroded section properties
corroded_geometry = offset_perimeter(original_geometry, 1.5, plot_offset=True)
corroded_mesh = corroded_geometry.create_mesh(mesh_sizes=[3.0])
corroded_section = CrossSection(corroded_geometry, corroded_mesh)
corroded_section.calculate_geometric_properties()
corroded_area = corroded_section.get_area()
(corroded_ixx, _, _) = corroded_section.get_ic()

# compare section properties
print("Area reduction = {0:.2f}%".format(
    100 * (original_area - corroded_area) / original_area))
print("Ixx reduction = {0:.2f}%".format(
    100 *(original_ixx - corroded_ixx) / original_ixx))

The following plot is generated by the above example:

../_images/offset_example.png

200UB25 with 1.5 mm corrosion.

The following is printed to the terminal:

Area reduction = 41.97%
Ixx reduction = 39.20%

Note

All the built-in sections in the sections module are built using an anti-clockwise facet direction. As a result, side=’left’ will reduce the cross-section, while side=’right’ will increase the cross-section.

Note

The control_points may need to be manually re-assigned if reducing the cross-section moves the control_point outside the geometry.

Warning

This feature is a beta addition and as a result may produce some errors if the offsetting drastically changes the geometry.

Visualising the Geometry

Geometry objects can be visualised by using the plot_geometry() method:

Geometry.plot_geometry(ax=None, pause=True, labels=False, perimeter=False)[source]

Plots the geometry defined by the input section. If no axes object is supplied a new figure and axis is created.

Parameters:
  • ax (matplotlib.axes.Axes) – Axes object on which the mesh is plotted
  • pause (bool) – If set to true, the figure pauses the script until the window is closed. If set to false, the script continues immediately after the window is rendered.
  • labels (bool) – If set to true, node and facet labels are displayed
  • perimeter (bool) – If set to true, boldens the perimeter of the cross-section
Returns:

Matplotlib figure and axes objects (fig, ax)

Return type:

(matplotlib.figure.Figure, matplotlib.axes)

The following example creates a CHS discretised with 64 points, with a diameter of 48 and thickness of 3.2, and plots the geometry:

import sectionproperties.pre.sections as sections

geometry = sections.Chs(d=48, t=3.2, n=64)
geometry.plot_geometry()
../_images/chs_geometry.png

Geometry generated by the above example.

Generating a Mesh

A finite element mesh is required to perform a cross-section analysis. A finite element mesh can be created by using the create_mesh() method:

Geometry.create_mesh(mesh_sizes)[source]

Creates a quadratic triangular mesh from the Geometry object.

Parameters:mesh_sizes – A list of maximum element areas corresponding to each region within the cross-section geometry.
Returns:Object containing generated mesh data
Return type:meshpy.triangle.MeshInfo
Raises:AssertionError – If the number of mesh sizes does not match the number of regions

The following example creates a circular cross-section with a diameter of 50 with 64 points, and generates a mesh with a maximum triangular area of 2.5:

import sectionproperties.pre.sections as sections

geometry = sections.CircularSection(d=50, n=64)
mesh = geometry.create_mesh(mesh_sizes=[2.5])
../_images/circle_mesh.png

Mesh generated from the above geometry.

Warning

The length of mesh_sizes must match the number of regions in the geometry object.

Defining Material Properties

Composite cross-sections can be analysed by specifying different material properties for each section of the mesh. Materials are defined in sectionproperties by creating a Material object:

class sectionproperties.pre.pre.Material(name, elastic_modulus, poissons_ratio, yield_strength, color='w')[source]

Bases: object

Class for structural materials.

Provides a way of storing material properties related to a specific material. The color can be a multitude of different formats, refer to https://matplotlib.org/api/colors_api.html and https://matplotlib.org/examples/color/named_colors.html for more information.

Parameters:
  • name (string) – Material name
  • elastic_modulus (float) – Material modulus of elasticity
  • poissons_ratio (float) – Material Poisson’s ratio
  • yield_strength (float) – Material yield strength
  • color (matplotlib.colors) – Material color for rendering
Variables:
  • name (string) – Material name
  • elastic_modulus (float) – Material modulus of elasticity
  • poissons_ratio (float) – Material Poisson’s ratio
  • shear_modulus (float) – Material shear modulus, derived from the elastic modulus and Poisson’s ratio assuming an isotropic material
  • yield_strength (float) – Material yield strength
  • color (matplotlib.colors) – Material color for rendering

The following example creates materials for concrete, steel and timber:

from sectionproperties.pre.pre import Material

concrete = Material(
    name='Concrete', elastic_modulus=30.1e3, poissons_ratio=0.2, yield_strength=32,
        color='lightgrey'
)
steel = Material(
    name='Steel', elastic_modulus=200e3, poissons_ratio=0.3, yield_strength=500,
        color='grey'
)
timber = Material(
    name='Timber', elastic_modulus=8e3, poissons_ratio=0.35, yield_strength=20,
        color='burlywood'
)