Skip to content

Commit 8e884d0

Browse files
Merge pull request #325 from robbievanleeuwen/concrete-tee-fix
Fix concrete_tee_section() top bar distribution
2 parents 2ea83cd + bf2469d commit 8e884d0

File tree

2 files changed

+100
-30
lines changed

2 files changed

+100
-30
lines changed

docs/user_guide/geometry.rst

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,8 @@ from a shapely :class:`~shapely.Polygon`.
7979
geom = CompoundGeometry(geoms=[geom_sq1, geom_sq2])
8080
geom.plot_geometry()
8181

82+
.. _label-from-points:
83+
8284
Cartesian Coordinates
8385
^^^^^^^^^^^^^^^^^^^^^
8486

@@ -114,6 +116,8 @@ Various CAD files can be imported to creating ``sectionproperties`` geometries.
114116
pip install sectionproperties[dxf]
115117
pip install sectionproperties[rhino]
116118
119+
.. _label-geometry-dxf:
120+
117121
``.dxf``
118122
""""""""
119123

@@ -149,6 +153,8 @@ files using the
149153
saving each region as a separate ``.dxf`` file, importing each region individually
150154
using ``Geometry.from_dxf()``, then combining the regions using the ``+`` operator.
151155

156+
.. _label-geometry-3dm:
157+
152158
Rhino
153159
"""""
154160

@@ -251,6 +257,8 @@ generate typical structural cross-sections, resulting in
251257
:class:`~sectionproperties.pre.geometry.CompoundGeometry` objects. These typical
252258
cross-sections reside in the ``sectionproperties.pre.library`` module.
253259

260+
.. _label-primitive-library:
261+
254262
Primitive Sections
255263
""""""""""""""""""
256264

@@ -287,6 +295,8 @@ Steel Sections
287295
~sectionproperties.pre.library.steel_sections.box_girder_section
288296
~sectionproperties.pre.library.steel_sections.bulb_section
289297

298+
.. _label-concrete-library:
299+
290300
Concrete Sections
291301
"""""""""""""""""
292302

@@ -298,6 +308,8 @@ Concrete Sections
298308
~sectionproperties.pre.library.concrete_sections.concrete_tee_section
299309
~sectionproperties.pre.library.concrete_sections.concrete_circular_section
300310

311+
.. _label-bridge-library:
312+
301313
Bridge Sections
302314
"""""""""""""""
303315

@@ -423,6 +435,8 @@ value.
423435
.. automethod:: sectionproperties.pre.geometry.CompoundGeometry.offset_perimeter
424436
:noindex:
425437

438+
.. _label-geometry-set:
439+
426440
Set Operations
427441
^^^^^^^^^^^^^^
428442

src/sectionproperties/pre/library/concrete_sections.py

Lines changed: 86 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -392,12 +392,15 @@ def concrete_tee_section(
392392
conc_mat: Material object to assign to the concrete area
393393
steel_mat: Material object to assign to the steel area
394394
395+
Raises:
396+
ValueError: Geometry generation failed
397+
395398
Returns:
396399
Reinforced concrete tee section geometry
397400
398401
Example:
399402
The following example creates a 900 mm deep x 450 mm wide concrete tee beam with
400-
a 150 mm deep x 1800 mm wide flange. The tee beam is reinforced with 5 x 24 mm
403+
a 150 mm deep x 1800 mm wide flange. The tee beam is reinforced with 12 x 24 mm
401404
top bars, 5 x 28 mm bottom bars and 4 x 16 mm side bars, with 42 mm cover all
402405
around (30 mm cover + 12 mm tie). A coarse finite element mesh is generated to
403406
show the different material regions:
@@ -434,7 +437,7 @@ def concrete_tee_section(
434437
b_f=1800,
435438
dia_top=24,
436439
area_top=450,
437-
n_top=5,
440+
n_top=12,
438441
c_top=42,
439442
dia_bot=28,
440443
area_bot=620,
@@ -452,38 +455,91 @@ def concrete_tee_section(
452455
geom.create_mesh(mesh_sizes=[0]) # a size of zero creates a coarse mesh
453456
Section(geometry=geom).plot_mesh()
454457
"""
455-
# generate rectangular section of the beam
456-
geom = concrete_rectangular_section(
457-
d=d,
458-
b=b,
459-
dia_top=dia_top,
460-
area_top=area_top,
461-
n_top=n_top,
462-
c_top=c_top,
463-
dia_bot=dia_bot,
464-
area_bot=area_bot,
465-
n_bot=n_bot,
466-
c_bot=c_bot,
467-
dia_side=dia_side,
468-
area_side=area_side,
469-
n_side=n_side,
470-
c_side=c_side,
471-
n_circle=n_circle,
472-
conc_mat=conc_mat,
473-
steel_mat=steel_mat,
458+
# generate concrete geometry
459+
beam = primitive_sections.rectangular_section(b=b, d=d - d_f, material=conc_mat)
460+
flange = primitive_sections.rectangular_section(b=b_f, d=d_f, material=conc_mat)
461+
geom = beam + flange.align_to(other=beam, on="top").shift_section(
462+
x_offset=-(b_f / 2 - b / 2)
474463
)
464+
geom = geom.shift_section(x_offset=-b / 2)
465+
466+
# calculate reinforcing bar dimensions for top and bottom layers
467+
if n_top == 1:
468+
x_i_top = 0
469+
spacing_top = 0
470+
else:
471+
if c_side:
472+
x_i_top = -b_f / 2 + c_side + dia_top / 2
473+
spacing_top = (b_f - 2 * c_side - dia_top) / (n_top - 1)
474+
else:
475+
x_i_top = -b_f / 2 + c_top + dia_top / 2
476+
spacing_top = (b_f - 2 * c_top - dia_top) / (n_top - 1)
477+
478+
if n_bot == 1:
479+
x_i_bot = 0
480+
spacing_bot = 0
481+
else:
482+
if c_side:
483+
x_i_bot = -b / 2 + c_side + dia_bot / 2
484+
spacing_bot = (b - 2 * c_side - dia_bot) / (n_bot - 1)
485+
else:
486+
x_i_bot = -b / 2 + c_bot + dia_bot / 2
487+
spacing_bot = (b - 2 * c_bot - dia_bot) / (n_bot - 1)
475488

476-
# add flange
477-
left_flange = (
478-
primitive_sections.rectangular_section(
479-
d=d_f, b=(b_f - b) / 2, material=conc_mat
489+
# calculate reinforcing bar dimensions for side layers if specified
490+
if dia_side and n_side != 0:
491+
x_i_side_left = -b / 2 + c_side + dia_side / 2
492+
x_i_side_right = -x_i_side_left
493+
494+
spacing_side = (d - c_top - c_bot - dia_top / 2 - dia_bot / 2) / (n_side + 1)
495+
else:
496+
x_i_side_left = 0
497+
x_i_side_right = 0
498+
spacing_side = 0
499+
500+
# add top bars
501+
for idx in range(n_top):
502+
bar = primitive_sections.circular_section_by_area(
503+
area=area_top,
504+
n=n_circle,
505+
material=steel_mat,
506+
).shift_section(
507+
x_offset=x_i_top + spacing_top * idx,
508+
y_offset=d - c_top - dia_top / 2,
480509
)
481-
.align_to(other=geom, on="left")
482-
.align_to(other=geom, on="top", inner=True)
483-
)
484-
right_flange = left_flange.mirror_section(axis="y", mirror_point=(b / 2, 0))
510+
geom = (geom - bar) + bar
511+
512+
# add bot bars
513+
for i in range(n_bot):
514+
bar = primitive_sections.circular_section_by_area(
515+
area=area_bot,
516+
n=n_circle,
517+
material=steel_mat,
518+
).shift_section(
519+
x_offset=x_i_bot + spacing_bot * i,
520+
y_offset=c_bot + dia_bot / 2,
521+
)
522+
geom = (geom - bar) + bar
523+
524+
# add side bars
525+
if area_side:
526+
for i in range(n_side):
527+
bar_left = primitive_sections.circular_section_by_area(
528+
area=area_side,
529+
n=n_circle,
530+
material=steel_mat,
531+
).shift_section(
532+
x_offset=x_i_side_left,
533+
y_offset=c_bot + dia_bot / 2 + spacing_side * (i + 1),
534+
)
535+
bar_right = bar_left.shift_section(x_offset=x_i_side_right - x_i_side_left)
536+
537+
geom = (geom - bar_left - bar_right) + bar_left + bar_right
485538

486-
return geom + left_flange + right_flange
539+
if isinstance(geom, geometry.CompoundGeometry):
540+
return geom
541+
else:
542+
raise ValueError("Concrete section generation failed.")
487543

488544

489545
def concrete_circular_section(

0 commit comments

Comments
 (0)