Creating Meshes#

This example demonstrates how a finite element mesh can be generated with sectionproperties.

Import Modules#

We start by importing the necessary modules.

[1]:
from sectionproperties.analysis import Section
from sectionproperties.pre import CompoundGeometry
from sectionproperties.pre.library import (
    box_girder_section,
    rectangular_hollow_section,
    rectangular_section,
)

Simple Mesh#

A mesh of a rectangle is created. The value provided to mesh_sizes is used to limit the maximum triangular area to this value.

[2]:
geom = rectangular_section(d=50, b=50)
geom.create_mesh(mesh_sizes=10)
sec = Section(geometry=geom)
sec.plot_mesh(materials=False)
../../_images/examples_geometry_create_mesh_4_0.svg
[2]:
<Axes: title={'center': 'Finite Element Mesh'}>

We can find the maximum element size by looping through all the elements and computing the area of each element.

[3]:
# initialise maximum area
max_area = 0

# loop through all finite elements
for el in sec.elements:
    res = el.geometric_properties()  # calculate area properties
    el_area = res[0]  # get the area
    max_area = max(max_area, el_area)  # update max_area

print(f"Max. triangular area = {max_area:.2f}")
Max. triangular area = 9.95

Specifying Multiple mesh_sizes#

This example creates a 100 x 9 SHS and shows how the mesh can be refined in specific regions.

[4]:
shs = rectangular_hollow_section(d=100, b=100, t=9, r_out=22.5, n_r=8)

We will split the SHS geometry into corner regions and straight regions.

[5]:
# vertical split at left hand corner
g1, g2 = shs.split_section(point_i=(22.5, 0), vector=(0, 1))
shs = CompoundGeometry(geoms=g1 + g2)  # reform geometry

# vertical split at right hand corner
g1, g2 = shs.split_section(point_i=(77.5, 0), vector=(0, 1))
shs = CompoundGeometry(geoms=g1 + g2)  # reform geometry

# vertical split at bottom corner
g1, g2 = shs.split_section(point_i=(0, 22.5), vector=(1, 0))
shs = CompoundGeometry(geoms=g1 + g2)  # reform geometry

# vertical split at top corner
g1, g2 = shs.split_section(point_i=(0, 77.5), vector=(1, 0))

We will combine the final geometry by sorting the list of split geometries objects. This will allow us to easily control the mesh size of each region. We will sort the geometry list by the y value of each geometry’s control point.

[6]:
geom_list = g1 + g2
geom_list.sort(key=lambda x: x.control_points[0][1])
shs = CompoundGeometry(geoms=geom_list)
shs.plot_geometry()
../../_images/examples_geometry_create_mesh_12_0.svg
[6]:
<Axes: title={'center': 'Cross-Section Geometry'}>

As shown above, regions 0, 3, 4 and 7 are the straight segments, while regions 1, 2, 5 and 6 are the corner segments.

We can generate a mesh with a constant maximum area across all regions by providing only one value to mesh_sizes.

[7]:
shs.create_mesh(mesh_sizes=5)
Section(geometry=shs).plot_mesh(materials=False)
../../_images/examples_geometry_create_mesh_15_0.svg
[7]:
<Axes: title={'center': 'Finite Element Mesh'}>

Alternatively, we can specify a maximum area for each region. Note that providing a zero provides no constraint on the maximum area.

[8]:
mesh_sizes = [2.5, 1, 1, 5, 5, 2, 2, 0]

shs.create_mesh(mesh_sizes=mesh_sizes)
Section(geometry=shs).plot_mesh(materials=False)
../../_images/examples_geometry_create_mesh_17_0.svg
[8]:
<Axes: title={'center': 'Finite Element Mesh'}>

Modifying the Minimum Angle#

We can change the minimum mesh vertex angle by specifying a value for min_angle, by default this is set to 30 degrees. Note that reducing the minimum angle will reduce the mesh quality, but may solve issues with the mesh algorithm not converging. See here for more information. Setting this value to number greater than 33 may cause issues with the meshing algorithm not converging.

[9]:
geom.create_mesh(mesh_sizes=30, min_angle=33)
Section(geom).plot_mesh(materials=False)
geom.create_mesh(mesh_sizes=30, min_angle=5.7)
Section(geom).plot_mesh(materials=False)
../../_images/examples_geometry_create_mesh_19_0.svg
../../_images/examples_geometry_create_mesh_19_1.svg
[9]:
<Axes: title={'center': 'Finite Element Mesh'}>

Generating a coarse mesh#

By setting the argument coarse=True, all quality, area and angle constraints are ignored and a coarse mesh is generated. This can be useful if only geometric or plastic properties are desired (which are mesh independent). Note that if coarse=True, the values provided to mesh_sizes and min_angle will be ignored.

The following example compares the mesh generated for a box girder section, with and without quality constraints.

[10]:
box = box_girder_section(d=1200, b_t=1200, b_b=400, t_ft=100, t_fb=80, t_w=50)
[11]:
box.create_mesh(mesh_sizes=0)
Section(geometry=box).plot_mesh(materials=False)
../../_images/examples_geometry_create_mesh_23_0.svg
[11]:
<Axes: title={'center': 'Finite Element Mesh'}>
[12]:
box.create_mesh(mesh_sizes=0, coarse=True)
Section(geometry=box).plot_mesh(materials=False)
../../_images/examples_geometry_create_mesh_24_0.svg
[12]:
<Axes: title={'center': 'Finite Element Mesh'}>