gensec.geometry¶
Section definition, fiber meshing, and parametric shape factories.
A cross-section in GenSec is represented as a collection of bulk
fibers (from the meshed polygon) and point fibers (rebars,
tendons, FRP strips). The GenericSection
class is the primary section object; RectSection
is a backward-compatible wrapper.
Point fibers (rebars)¶
Point fiber definitions (rebars, FRP strips, tendons).
Phase 2: each fiber has both x and y coordinates for biaxial bending.
- class RebarLayer(
- y: float,
- As: float = 0.0,
- material: Material = None,
- x: float | None = None,
- embedded: bool = True,
- n_bars: int = 1,
- diameter: float = 0.0,
Bases:
objectA point fiber (rebar, FRP strip, tendon, etc.).
Each fiber carries its own
Materialreference, allowing mixed-material sections. For biaxial bending, bothxandycoordinates are needed.The cross-sectional area
Ascan be specified directly or computed automatically fromdiameterandn_bars:\[A_s = n_{\text{bars}} \cdot \frac{\pi}{4} \, d^2\]If both
Asanddiameterare given,Astakes precedence. If onlydiameteris given (withAsomitted or set to 0),Asis computed from the formula above.- Parameters:
y (float) – Vertical coordinate from bottom edge [mm].
As (float, optional) – Cross-sectional area [mm²]. If 0 or omitted, computed from
diameterandn_bars.material (Material) – Constitutive law.
x (float, optional) – Horizontal coordinate from left edge [mm]. If
None, defaults to the section centroid x-coordinate (set during section assembly). For uniaxial bending this is irrelevant.embedded (bool, optional) – If
True(default), the fiber is embedded within the bulk material. The integrator will subtract the bulk material contribution at this location to avoid double-counting the area. Set toFalsefor external elements (e.g. external FRP strips, steel truss chords outside the concrete).n_bars (int, optional) – Number of bars. Default 1. Also used to compute
Aswhendiameteris given.diameter (float, optional) – Bar diameter [mm]. Default 0. When positive and
Asis 0,Asis computed as \(n_{\text{bars}} \cdot \pi/4 \cdot d^2\).
Generic section with polygon meshing¶
Generic cross-section geometry with automatic fiber meshing.
Replaces the former RectSection with a fully general approach:
any cross-section defined as a Shapely polygon (with holes) is
automatically discretized into a fiber mesh suitable for
FiberSolver.
Two meshing strategies are available:
Grid (default): rectangular grid clipped to the polygon boundary. Fast, simple, good for convex or mildly non-convex sections. Resolution controlled by
mesh_size[mm].Triangular: Constrained Delaunay triangulation via the
trianglelibrary. Better for curved boundaries and complex holes. Requirestriangleto be installed.
The class exposes the same attribute interface that
FiberSolver consumes, so the solver,
capacity generator, and plotting modules need no changes.
Dependencies¶
shapely >= 2.0triangle(optional, for triangular meshing)numpy
Examples
Build a rectangular section the quick way:
>>> from gensec.geometry.section import GenericSection
>>> from gensec.geometry.fiber import RebarLayer
>>> from gensec.materials.concrete import Concrete
>>> from gensec.materials.steel import Steel
>>> from shapely.geometry import box
>>> poly = box(0, 0, 300, 600)
>>> sec = GenericSection(poly, Concrete(fck=25), [], mesh_size=10)
>>> sec.n_fibers
1800
Build a circular section with a square hole:
>>> from shapely.geometry import Point, box
>>> outer = Point(0, 0).buffer(500, resolution=64)
>>> hole = box(-100, -100, 100, 100)
>>> poly = outer.difference(hole)
>>> sec = GenericSection(poly, Concrete(fck=30), [], mesh_size=20)
- class GenericSection(polygon: ~shapely.geometry.polygon.Polygon, bulk_material: ~gensec.materials.base.Material, rebars: ~typing.List[~gensec.geometry.fiber.RebarLayer], mesh_size: float = 10.0, mesh_method: 'grid' | 'triangle' = 'grid', bulk_materials: ~typing.List[tuple] = <factory>, n_grid_x: int | None = None, n_grid_y: int | None = None)¶
Bases:
objectCross-section defined by an arbitrary polygon, meshed into fibers.
The section geometry is a
shapely.geometry.Polygon(which may contain holes). The bulk material is assigned to all fibers inside the polygon boundary. Point fibers (rebars, tendons, FRP strips) are placed independently.Coordinate system¶
User-defined. Typically:
\(x\) horizontal, \(y\) vertical (upward).
Origin at bottom-left corner or at centroid, depending on the factory function used.
- param polygon:
Section outline (may include holes).
- type polygon:
shapely.geometry.Polygon
- param bulk_material:
Constitutive law for the bulk (concrete, timber, …).
- type bulk_material:
Material
- param rebars:
Point fibers with their own materials.
- type rebars:
list of RebarLayer
- param mesh_size:
Target fiber size [mm]. For grid meshing, this is the cell side length. For triangular meshing, this controls the maximum triangle area \(\approx 0.5 \cdot \text{mesh\_size}^2\). Default 10.0.
- type mesh_size:
float, optional
- param mesh_method:
Meshing strategy. Default
'grid'.- type mesh_method:
'grid'or'triangle', optional- param bulk_materials:
Additional bulk material zones. Each tuple is
(Polygon, Material). Fibers inside each zone use that zone’s material instead ofbulk_material. Zones are checked in order; first match wins. Default empty (single-material section).- type bulk_materials:
list of tuple, optional
- param n_grid_x:
Explicit number of grid columns for the
'grid'mesher. When set, overrides themesh_size-based computation for the x-direction. DefaultNone(derive frommesh_size).- type n_grid_x:
int or None, optional
- param n_grid_y:
Explicit number of grid rows. Default
None.- type n_grid_y:
int or None, optional
- ivar x_fibers:
x-coordinates of bulk fiber centroids [mm].
- vartype x_fibers:
numpy.ndarray
- ivar y_fibers:
y-coordinates [mm].
- vartype y_fibers:
numpy.ndarray
- ivar A_fibers:
Fiber areas [mm²].
- vartype A_fibers:
numpy.ndarray
- ivar mat_indices:
Material index for each bulk fiber.
0=bulk_material,1..N= zones frombulk_materialslist.- vartype mat_indices:
numpy.ndarray of int
- ivar x_rebars:
x-coordinates of rebar layers [mm].
- vartype x_rebars:
numpy.ndarray
- ivar y_rebars:
y-coordinates [mm].
- vartype y_rebars:
numpy.ndarray
- ivar A_rebars:
Areas [mm²].
- vartype A_rebars:
numpy.ndarray
- ivar embedded_rebars:
- vartype embedded_rebars:
numpy.ndarray of bool
- ivar n_fibers:
Total number of bulk fibers.
- vartype n_fibers:
int
- ivar B:
Bounding box width (x-direction) [mm].
- vartype B:
float
- ivar H:
Bounding box height (y-direction) [mm].
- vartype H:
float
- ivar n_fibers_x:
Number of grid columns (grid mesh only; triangular sets -1).
- vartype n_fibers_x:
int
- ivar n_fibers_y:
Number of grid rows (grid mesh only; triangular sets -1).
- vartype n_fibers_y:
int
- ivar gross_area:
Gross polygon area [mm²].
- vartype gross_area:
float
- raises ValueError:
If the polygon is empty, invalid, or has zero area.
- raises ImportError:
If
mesh_method='triangle'but thetrianglepackage is not installed.
- property bbox¶
Bounding box as
(minx, miny, maxx, maxy).- Return type:
tuple of float
- get_all_bulk_materials()¶
Return the list of all bulk materials (base + zones).
- Returns:
Index-aligned with
mat_indicesvalues.- Return type:
list of Material
- get_material_for_fiber(
- fiber_index,
Return the material object for a given bulk fiber index.
- Parameters:
fiber_index (int)
- Return type:
- mesh_summary()¶
Return a summary dict of mesh quality metrics.
- Returns:
Keys:
n_fibers,total_area,gross_area,area_error_pct,min_fiber_area,max_fiber_area,mean_fiber_area,mesh_method,mesh_size.- Return type:
dict
- property x_centroid¶
Gross centroid x-coordinate [mm].
Computed from the Shapely polygon centroid (exact for arbitrary polygons, unlike the \(B/2\) approximation of the former
RectSection).
- property y_centroid¶
Gross centroid y-coordinate [mm].
Parametric section primitives¶
Factory functions that return shapely.geometry.Polygon objects
for common section shapes. Each polygon can be passed directly to
GenericSection.
Parametric section primitives — factory functions.
Each function returns a shapely.geometry.Polygon that can
be passed directly to GenericSection. All dimensions are in
millimetres.
The coordinate origin convention is bottom-left corner of the
bounding box, consistent with the former RectSection.
Available primitives¶
rect_poly()— Rectangle.circle_poly()— Circle (regular polygon approximation).annulus_poly()— Annular (hollow) circle.tee_poly()— T-section (flange on top).inv_tee_poly()— Inverted T-section (flange on bottom).h_poly()— H / I section (symmetric double-T).single_tee_slab_poly()— Single-tee precast slab (tegolo).double_tee_slab_poly()— Double-tee precast slab (tegolo).box_poly()— Hollow rectangular (box) section.
Examples
>>> from gensec.geometry.primitives import rect_poly
>>> p = rect_poly(300, 600)
>>> p.area
180000.0
>>> from gensec.geometry.primitives import tee_poly
>>> p = tee_poly(bf=800, hf=150, bw=300, hw=450)
>>> p.area
255000.0
- annulus_poly(
- D_ext,
- D_int,
- resolution=64,
Annular (hollow circular) section.
- Parameters:
D_ext (float) – Outer diameter [mm].
D_int (float) – Inner diameter [mm].
resolution (int, optional)
- Returns:
Polygon with an interior hole.
- Return type:
shapely.geometry.Polygon
- Raises:
ValueError – If
D_int >= D_ext.
- box_poly(
- B,
- H,
- tw,
- tf_top,
- tf_bot=None,
Hollow rectangular (box) section.
- Parameters:
B (float) – Outer width [mm].
H (float) – Outer height [mm].
tw (float) – Web (side wall) thickness [mm].
tf_top (float) – Top flange thickness [mm].
tf_bot (float, optional) – Bottom flange thickness [mm]. If
None, same astf_top.
- Returns:
Polygon with one rectangular hole.
- Return type:
shapely.geometry.Polygon
- circle_poly(
- D,
- resolution=64,
Circular section polygon (regular N-gon approximation).
The circle is centred at \((D/2, D/2)\) so that the bounding box starts at the origin.
- Parameters:
D (float) – Diameter [mm].
resolution (int, optional) – Number of vertices on the circumference. Default 64.
- Return type:
shapely.geometry.Polygon
- custom_poly(
- exterior_coords,
- holes=None,
Arbitrary polygon from vertex coordinates.
- Parameters:
exterior_coords (list of tuple) –
[(x0, y0), (x1, y1), ...]. The ring is automatically closed.holes (list of list of tuple, optional) – Each inner list defines a hole boundary.
- Return type:
shapely.geometry.Polygon
- double_tee_slab_poly(
- b_top,
- h_top,
- bw,
- hw,
- stem_spacing,
Double-tee precast slab section (tegolo doppio).
A wide top slab with two stems (ribs) below, symmetrically placed.
┌───────────────────────────────┐ b_top │ top slab │ h_top └──┬────┬───────────────┬────┬──┘ │ s1 │ │ s2 │ hw └────┘ └────┘ bw spacing bw- Parameters:
b_top (float) – Top slab overall width [mm].
h_top (float) – Top slab thickness [mm].
bw (float) – Width of each stem [mm].
hw (float) – Depth of each stem [mm].
stem_spacing (float) – Centre-to-centre distance between the two stems [mm].
- Return type:
shapely.geometry.Polygon
- h_poly(
- bf,
- hf_top,
- hf_bot,
- bw,
- hw,
H / I section (double-T, symmetric about the vertical axis).
┌─────────────────┐ bf │ top flange │ hf_top └──┬─────────┬────┘ │ web │ hw ┌──┴─────────┴────┐ │ bottom flange │ hf_bot └─────────────────┘ bf
- Parameters:
bf (float) – Flange width [mm] (same for top and bottom).
hf_top (float) – Top flange thickness [mm].
hf_bot (float) – Bottom flange thickness [mm].
bw (float) – Web width [mm].
hw (float) – Web height [mm] (between flanges).
- Return type:
shapely.geometry.Polygon
- inv_tee_poly(
- bf,
- hf,
- bw,
- hw,
Inverted T-section (flange on bottom).
Same parameters as
tee_poly()but the flange is at \(y = 0\).- Parameters:
bf (float) – See
tee_poly().hf (float) – See
tee_poly().bw (float) – See
tee_poly().hw (float) – See
tee_poly().
- Return type:
shapely.geometry.Polygon
- rect_poly(
- B,
- H,
Rectangular section polygon.
(0,H) ┌─────────┐ (B,H) │ │ │ │ (0,0) └─────────┘ (B,0)- Parameters:
B (float) – Width [mm].
H (float) – Height [mm].
- Return type:
shapely.geometry.Polygon
- single_tee_slab_poly(
- b_top,
- h_top,
- bw,
- hw,
Single-tee precast slab section (tegolo singolo).
A wide top slab with a single stem (rib) below.
┌───────────────────────┐ b_top │ top slab │ h_top └────┬───────────┬──────┘ │ stem │ hw └───────────┘ bw- Parameters:
b_top (float) – Top slab width [mm].
h_top (float) – Top slab thickness [mm].
bw (float) – Stem width [mm].
hw (float) – Stem depth [mm] (below the slab).
- Return type:
shapely.geometry.Polygon
- tee_poly(
- bf,
- hf,
- bw,
- hw,
T-section with flange on top.
┌─────────────────┐ ← bf │ flange │ hf └──┬─────────┬────┘ │ web │ hw │ │ └─────────┘ bwOrigin at bottom-left of the bounding box.
- Parameters:
bf (float) – Flange width [mm].
hf (float) – Flange thickness [mm].
bw (float) – Web width [mm].
hw (float) – Web height [mm] (below the flange).
- Return type:
shapely.geometry.Polygon
- Raises:
ValueError – If
bw > bf.
Rectangular section (legacy wrapper)¶
Rectangular section factory — convenience wrapper.
RectSection() is a factory function (not a class) that builds
a GenericSection with a rectangular polygon and grid
meshing. It replaces the former RectSection dataclass, which
was a thin delegation wrapper that introduced a mesh-size bug on
anisotropic grids.
The returned object is a GenericSection. All
attributes expected by FiberSolver are
available directly (x_fibers, y_fibers, A_fibers,
B, H, n_fibers_x, n_fibers_y, dx, dy,
polygon, …).
Grid resolution¶
The mesh resolution in the y-direction is controlled by
n_fibers_y. The x-direction follows one of two rules:
Isotropic (default,
n_fibers_x ≤ 1): the x-resolution is derived from the samemesh_size = H / n_fibers_y, giving a square-celled grid. Example: B = 300, H = 600, n_fibers_y = 100 → mesh_size = 6 → n_fibers_x = ceil(300/6) = 50.Explicit (
n_fibers_x > 1): the user-specified value is passed asn_grid_x.
- RectSection(
- B,
- H,
- bulk_material,
- rebars,
- n_fibers_y=100,
- n_fibers_x=1,
Create a rectangular
GenericSection.- Parameters:
B (float) – Width (x-direction) [mm].
H (float) – Height (y-direction) [mm].
bulk_material (Material) – Bulk material (concrete, timber, …).
rebars (list of RebarLayer) – Point fibers.
n_fibers_y (int, optional) – Fiber rows. Controls the isotropic mesh size: \(s = H / n_y\). Default 100.
n_fibers_x (int, optional) – Fiber columns. When
> 1, overrides the x-resolution explicitly. When≤ 1(default), the x-resolution is derived from the isotropic mesh size \(s\).
- Returns:
Fully meshed rectangular section with all attributes expected by the solver (
x_fibers,y_fibers,A_fibers,B,H,n_fibers_x,n_fibers_y,dx,dy,polygon, …).- Return type:
Package-level exports¶
Geometry subpackage.
Provides section definition classes: point fibers (RebarLayer)
and rectangular section assemblies (RectSection).
- class RebarLayer(
- y: float,
- As: float = 0.0,
- material: Material = None,
- x: float | None = None,
- embedded: bool = True,
- n_bars: int = 1,
- diameter: float = 0.0,
Bases:
objectA point fiber (rebar, FRP strip, tendon, etc.).
Each fiber carries its own
Materialreference, allowing mixed-material sections. For biaxial bending, bothxandycoordinates are needed.The cross-sectional area
Ascan be specified directly or computed automatically fromdiameterandn_bars:\[A_s = n_{\text{bars}} \cdot \frac{\pi}{4} \, d^2\]If both
Asanddiameterare given,Astakes precedence. If onlydiameteris given (withAsomitted or set to 0),Asis computed from the formula above.- Parameters:
y (float) – Vertical coordinate from bottom edge [mm].
As (float, optional) – Cross-sectional area [mm²]. If 0 or omitted, computed from
diameterandn_bars.material (Material) – Constitutive law.
x (float, optional) – Horizontal coordinate from left edge [mm]. If
None, defaults to the section centroid x-coordinate (set during section assembly). For uniaxial bending this is irrelevant.embedded (bool, optional) – If
True(default), the fiber is embedded within the bulk material. The integrator will subtract the bulk material contribution at this location to avoid double-counting the area. Set toFalsefor external elements (e.g. external FRP strips, steel truss chords outside the concrete).n_bars (int, optional) – Number of bars. Default 1. Also used to compute
Aswhendiameteris given.diameter (float, optional) – Bar diameter [mm]. Default 0. When positive and
Asis 0,Asis computed as \(n_{\text{bars}} \cdot \pi/4 \cdot d^2\).
- RectSection(
- B,
- H,
- bulk_material,
- rebars,
- n_fibers_y=100,
- n_fibers_x=1,
Create a rectangular
GenericSection.- Parameters:
B (float) – Width (x-direction) [mm].
H (float) – Height (y-direction) [mm].
bulk_material (Material) – Bulk material (concrete, timber, …).
rebars (list of RebarLayer) – Point fibers.
n_fibers_y (int, optional) – Fiber rows. Controls the isotropic mesh size: \(s = H / n_y\). Default 100.
n_fibers_x (int, optional) – Fiber columns. When
> 1, overrides the x-resolution explicitly. When≤ 1(default), the x-resolution is derived from the isotropic mesh size \(s\).
- Returns:
Fully meshed rectangular section with all attributes expected by the solver (
x_fibers,y_fibers,A_fibers,B,H,n_fibers_x,n_fibers_y,dx,dy,polygon, …).- Return type: