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])
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])
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])
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])
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])
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])
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])
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])
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])
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])
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])
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])
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])
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])
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])
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])
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])
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])
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])
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 oneGeometry
objectThe 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])
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:
The following is printed to the terminal:
Area reduction = 41.97% Ixx reduction = 39.20%
- geometry (
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()
- ax (
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])
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' )