Key Features • Installation & setup • Continuously Tapered Beam Example •Validation • NREL 5-MW Case Study
Continuous Section Field (CSF) is a Python engine for non-prismatic and non-homogeneous beam-like members, designed as a continuous pre-processor for structural solvers.
CSF treats a member as a continuous field along the axis z, combining two independent (but coupled) descriptions:
- Continuous Geometry via ruled-surface interpolation between arbitrary polygonal end sections (taper, changing topology, multi-cell shapes).
- Continuous Material/Stiffness Laws via user-defined longitudinal functions w(z), optionally applied per polygon (multi-material, degradation laws, staged stiffness, void logic through negative weights).
From this continuous description, CSF evaluates section properties and stiffness/mass fields (e.g., (A(z), I(z), C(z), EA(z), EI(z), GJ(z))) and exports solver-ready station data for force-based beam formulations (e.g., OpenSees forceBeamColumn) using Gauss–Lobatto stationing so the member ends are sampled exactly.
CSF targets linear-elastic beam modeling and preprocessing (visualization, export, validation). It does not model cracking, damage, or nonlinear material behavior.
The common practice of modeling non-prismatic members as a concatenation of equivalent prismatic elements (piecewise-prismatic approach) introduces a non-neutral methodological choice. The numerical solution varies with the number of subdivisions and the location of sampling points. Unlike traditional structural tools limited to predefined geometric templates, CSF treats the cross-section as a fully generic topological entity, providing accurate, continuous calculation of cross-section properties for complex non-prismatic members (tapered beams, wind turbine towers, piles, variable columns, FGM materials).
Geometric Scope and Limitations
This library is not a Finite Element Method (FEM) solver. It provides a geometric and constitutive formulation for a single non-prismatic member, returning sectional properties and stiffness matrices to be used in beam-based structural analysis or external solvers.
CSF models members defined by polygonal end sections connected by straight generator lines (ruled surfaces), with consistent polyline topology between the two ends. Curved outlines are handled via polygonal approximation: increasing the number of polygon sides allows accurate representation of practically curvilinear sections. See: core assumptions
- Algebraic Polygon Logic: Sections defined as collections of 2D vertices with weights. Handles any shape - from standard profiles to fully custom architectural sections.
- Custom Weight Laws (Advanced Material Modeling) Define property variations w(z) independent from geometry. Model thermal degradation, concrete maturation, soil confinement, localized damage, or variable reinforcement density using custom formulas or external data files. [See Full Documentation ] Longitudinally varying homogenization factors ContinuousSectionField (CSF) | Custom Weight Laws User Guide
- Curvature Handling: Discrete segments with arbitrary vertex count → approximate curved surfaces (e.g., circular towers) to any desired precision.
- No Predefined Templates: No restricted "Circle" or "Rectangle" classes — any geometry describable by coordinates is supported (A, I, J, Q, etc.).
- Topological Freedom:
- Hollow sections (e.g., NREL tapered shell)
- Multi-cellular shapes with internal stiffeners
- Composite/multi-material sections via modular ratio weights
- Version 2: fully arbitrary
w(z)per polygon
→ non-linear thickness, modulus, or reinforcement variation
→ access tow₀,w₁, current/initial/end distancesd(i,j),di(i,j),de(i,j), and allmathfunctions - Arbitrary Longitudinal Weight Functions: Each polygon can be assigned a fully arbitrary longitudinal weight function
w(z). This enables:- non-linear variation of thickness, elastic modulus, or reinforcement along the member
- access to initial and final weights (
w₀,w₁) and to geometric distances (d(i,j),di(i,j),de(i,j)), with full support for standardmathfunctions
To use the CSF engine, it is recommended to work inside a virtual environment.
LINUX
# Clone the repository
git clone https://github.com/giovanniboscu/continuous-section-field.git
cd continuous-section-field
# Create and activate virtual environment
python3 -m venv venv
source venv/bin/activate
# Install in editable mode
pip install -e .
python3 example/nrel_5mw_tower.py
python3 example/cilinder_withcheck.py
python3 example/csf_rotated_validation_benchmark.py
WINDOWS
# Clone the repository
git clone https://github.com/giovanniboscu/continuous-section-field.git
cd continuous-section-field
# Create and activate virtual environment
python3 -m venv venv
.\venv\Scripts\activate
# Install in editable mode
pip install -e .
python3 example\nrel_5mw_tower.py
python3 example\cilinder_withcheck.py
python3 example\csf_rotated_validation_benchmark.py
python3 .\example\tsection_opensees.pySections are modeled as ruled surfaces linearly interpolated between two arbitrary end sections
Two section planes are defined:
- start section at ( z = 0 )
- end section at ( z = L )
Both sections are defined in the same local
- The two section planes are parallel and not rotated with respect to each other.
- The beam axis is aligned with the ( z )-axis, normal to the section planes.
All section geometries must be provided in this local reference system.
A section is defined by a set of closed polylines.
- Each polyline represents a material region.
- All polylines must be:
- non self-intersecting
- oriented counter-clockwise (CCW)
- Polylines are closed implicitly; do not repeat the first vertex at the end of the list.
- Longitudinally varying homogenization factors
- ContinuousSectionField (CSF) | Custom Weight Laws User Guide
Each polyline is assigned a scalar weight ( w ), defined as:
where:
-
$E_{\text{ref}}$ is the reference Young’s modulus
Typical values:
-
$w = +1$ : reference material -
$0 < w < 1$ : softer material -
$w > 1$ : stiffer material -
$w = -1$ : void (geometric hole)
All polylines use the same orientation; material addition or removal is controlled
exclusively by the sign of
Two sections must be provided:
- one at
$z = 0$ - one at
$z = L$
Both sections must contain:
- the same number of polylines
This ensures geometric and material continuity along the beam axis.
Polygons in CSF are the fundamental units for both geometry and mechanics:
-
Multi-material sections: Each polygon carries a
weightattribute ($n = E_i / E_{ref}$ ). This allows the modeling of composite sections (e.g., steel-reinforced timber) by calculating the Elastic Centroid. - Hole Modeling (Algebraic Voids): By assigning a weight of -1.0, a polygon acts as a hole. The library automatically subtracts its area and inertia from the total, allowing for effortless modeling of hollow tubes or cellular beams without complex boolean operations.
- Corresponding polylines at
$z = 0$ and$z = L$ are interpolated along the beam axis. - Interpolation is performed point-wise between matching vertices.
The 3D volume is generated by connecting a Start section at
For each vertex
Geometric results:
- Linear Interpolation: Each vertex of the cross-section is described as a linear function of the longitudinal coordinate.
- Ruled Surfaces: This mapping creates ruled surfaces that define a smooth variation of the section, making vertex coordinates polynomial functions of known degree.
- Continuous taper: smooth transition between different shapes (e.g. tapered T-beams, conical tubes)
-
Continuous properties:
$A(z)$ ,$I(z)$ ,$EA(z)$ ,$EI(z)$ ,$GJ(z)$ evaluated at any z (geometry from ruled-surface mapping)
Section properties (area, inertia) are computed from geometry as:
- Geometry is the primary input.
- Section properties are automatically derived.
The library is designed for the analysis of non-prismatic and non-homogeneous members, with section properties varying continuously along the longitudinal axis.
The engine employs a multi-pass analysis combined with Gaussian integration schemes to extract structural parameters with high numerical fidelity. Specifically engineered for tapered and non-homogeneous members, it is ideal for applications where sectional properties vary continuously along the longitudinal axis (e.g., wind turbine towers, bridge girders, or aerospace components).
Unlike traditional frame analysis software that treats members as prismatic, this library treats the member as a Continuous Section Field:
-
Dynamic Computation: Every property is calculated "on-the-fly" at any longitudinal coordinate
$z$ via linear vertex-mapping. - Homogenization & Voids: Full support for material homogenization through positive weights and internal voids or cut-outs through negative weights.
Primary & Centroidal Properties
| ID | Parameter | Symbol | Technical Description |
|---|---|---|---|
| 1 | Area | Total net cross-sectional area | |
| 2 | Centroid Cx | Horizontal coordinate of the geometric centroid | |
| 3 | Centroid Cy | Vertical coordinate of the geometric centroid | |
| 4 | Inertia Ix | Second moment of area about centroidal X-axis | |
| 5 | Inertia Iy | Second moment of area about centroidal Y-axis | |
| 6 | Inertia Ixy | Product of inertia (Zero indicates symmetry) | |
| 7 | Polar Moment | Polar moment of area ( |
Derived Geometric Properties
| ID | Parameter | Symbol | Technical Description |
|---|---|---|---|
| 8 | Principal I1 | Maximum Principal Moment of Area | |
| 9 | Principal I2 | Minimum Principal Moment of Area | |
| 10 | Radius rx | Radius of gyration about X: |
|
| 11 | Radius ry | Radius of gyration about Y: |
Structural Analysis (Strength & Rigidity)
| ID | Parameter | Symbol | Technical Description |
|---|---|---|---|
| 12 | Elastic Modulus Wx | Section modulus for bending about X ( |
|
| 13 | Elastic Modulus Wy | Section modulus for bending about Y ( |
|
| 14 | Torsional Rigidity | Torsional Rigidity (K) The Saint-Venant torsional constant ( Core Engine: Implements a semi-empirical approximation ( Purpose: This estimation is designed to provide numerical stability for 3D Finite Element models (e.g., OpenSees) where a null torsional stiffness would lead to singular matrices. Accuracy: While reliable for solid, compact sections, it is a simplified model. For thin-walled or open profiles, users should treat this value as a preliminary estimate |
Shear-Related Quantities and Auxiliary Outputs
| ID | Parameter | Symbol | Technical Description |
|---|---|---|---|
| 15 | Poly 0 Ix (Origin) | Polygon 0 inertia relative to global origin | |
| 16 | Poly 0 Q_local | Statical moment of Poly 0 relative to centroid | |
| 17 | Section Q_na | Total Statical Moment at Neutral Axis (for |
|
| 18 | Stiffness Shape | Matrix | Dimensionality of the Sectional Stiffness Matrix |
CSF bridges continuous geometric modeling and structural analysis by exporting a solver-ready stiffness field that OpenSees can integrate using a force-based beam formulation.
Key idea: CSF does not approximate a tapered member by arbitrary piecewise-prismatic segments with constant properties.
Instead, CSF provides a set of stiffness samples (one per integration station) and OpenSees is forced to read those samples at the correct locations.
The OpenSees model uses the forceBeamColumn element family, which integrates section flexibility along the member length and is suitable for non-prismatic members when section properties vary longitudinally.
In CSF, the physical beam axis is not necessarily a straight line between two endpoints.
The real centroid offsets (xc_i, yc_i) are computed at each CSF station and represent the measured eccentricity of the section (tilt).
To preserve this in OpenSees, the exported model uses a two-axis representation:
- Reference axis (connection axis): nodes placed on the ideal straight member line.
Boundary conditions and loads are applied here. - Centroid axis (physical axis): nodes placed at
(xc_i, yc_i, z_i)using the CSF offsets.
Beam elements are defined along this axis.
A rigid kinematic coupling is enforced at each station:
rigidLink beamties each reference node to its corresponding centroid node.
This strategy ensures the OpenSees model reproduces:
- the real curvature / eccentricity of the centroid line (
ycvarying along the member), - and the correct eccentric-load coupling (additional moments arise naturally from the offset).
Implementation note:
rigidLinkrequiresconstraints Transformationin OpenSees (Plain constraints may ignore the MPCs).
CSF outputs a sequence of station properties (A, Iy, Iz, J, and optionally E/G), one per station.
Those station values represent the continuous stiffness field sampled at prescribed points.
To force OpenSees to read multiple different sections (not a single section repeated), the integration is defined using beamIntegration UserDefined.
In the current CSF–OpenSees strategy, the member is represented as a chain of elements between consecutive stations (station i → station i+1).
For each element, the section integration is defined as a two-point endpoint sampling:
- at
loc=0: section = stationi - at
loc=1: section = stationi+1 - weights:
0.5, 0.5
This guarantees that the solver consumes the exact CSF station stiffness values at the correct locations without collapsing them into a single prismatic equivalent.
This is not a “fake piecewise-prismatic” model: each segment is not assigned an arbitrary constant section.
Instead, the element reads stiffness at the CSF sampling points (endpoints of each segment) via UserDefined integration.
CSF stations are typically placed according to the Gauss–Lobatto rule, which includes the endpoints of the domain.
Therefore:
- station 1 coincides with the real start of the member,
- station N coincides with the real end of the member.
This is critical for:
- correct support reactions,
- correct tip displacements,
- and unambiguous boundary-condition application at the true physical ends.
A CSF OpenSees geometry file is treated as data, not as a Tcl script to be sourced verbatim. The integration workflow relies on these fields:
- Header:
Beam Lengthand number of stations (Int. Points) geomTransf Linear ...orientation vectorsection Elastic ... xc yclines:A, Iz, Iy, Jdefine geometry-derived section propertiesxc, ycdefine centroid offsets (the “tilt” field)
Material parameters can be provided either:
- inside the file (E, G columns), or
- overridden by the Python builder (forcing E/G from code), if the project requires a purely geometric/stiffness-field input file.
CSF exports a set of stations along the member and the corresponding section properties at each station.
Two distinct concepts are used:
-
Geometric discretization (centroid axis):
The real centroid line is represented as a polyline through the station points(xc_i, yc_i, z_i).
This preserves the physical eccentricity (tilt) field computed by CSF. -
Mechanical sampling (stiffness field):
The stiffness is not approximated by arbitrary constant segments.
Instead, OpenSees reads the CSF station stiffness values usingbeamIntegration UserDefinedso that each segment uses stationiandi+1stiffness at its endpoints.
Increasing the number of CSF stations improves resolution of both:
- centroid-axis curvature (geometric fidelity),
- and stiffness-field sampling (mechanical fidelity), without introducing the methodological ambiguity typical of “piecewise-prismatic” modeling.
examples/cilinder_withcheck.py
To verify the accuracy of the numerical engine, a validation test was performed using a non-tapered hollow cylinder (Steel Pipe). This allows for a direct comparison between the library's results (based on weighted polygons) and exact analytical formulas.
The test script cilinder_withcheck.py models a tower with a diameter of 4.935m and a thickness of 23mm using a 512-sided polygon. The results demonstrate that the polygonal approximation converges to the analytical solution with exceptional precision.
The following table reports the full output of the validation script, comparing Theoretical (Analytical) values with the Numerical results generated by the library.
| Structural Property | Sym | Theoretical | Numerical | Error | Unit |
|---|---|---|---|---|---|
| Net material cross-section | A | 3.54924572e-01 | 3.54915663e-01 | 0.0025% | m² |
| Horizontal center of mass | Cx | 0.00000000e+00 | 5.44816314e-15 | 5.45e-15 (abs) | m |
| Vertical center of mass | Cy | 0.00000000e+00 | -4.12383916e-14 | 4.12e-14 (abs) | m |
| Axial stiffness | EA | 7.45341600e+10 | 7.45322893e+10 | 0.0025% | N |
| Bending stiffness about X | EIxx | 2.24797570e+11 | 2.24786286e+11 | 0.0050% | N·m² |
| Bending stiffness about Y | EIyy | 2.24797570e+11 | 2.24786286e+11 | 0.0050% | N·m² |
| Symmetry check (Ixy) | Ixy | 0.00000000e+00 | 3.45889405e-15 | 3.46e-15 (abs) | m⁴ |
| Torsional stiffness constant | J | 2.14092924e+00 | 2.14082177e+00 | 0.0050% | m⁴ |
| Torsional stiffness (GJ) | GJ | 1.72987083e+11 | 1.72978399e+11 | 0.0050% | N·m² |
| Maximum bending stiffness | EI_max | 2.24797570e+11 | 2.24786286e+11 | 0.0050% | N·m² |
| Minimum bending stiffness | EI_min | 2.24797570e+11 | 2.24786286e+11 | 0.0050% | N·m² |
| Principal axis rotation | Alpha | 0.00000000e+00 | 0.00000000e+00 | 0.0000% (Iso) | deg |
| Buckling radius about X | rx | 1.73667329e+00 | 1.73665150e+00 | 0.0013% | m |
| Buckling radius about Y | ry | 1.73667329e+00 | 1.73665150e+00 | 0.0013% | m |
| First moment of area (Shear) | Q | 2.77471084e-01 | 2.77460637e-01 | 0.0038% | m³ |
| Elastic Section Modulus | W | 4.33825580e-01 | 4.33803803e-01 | 0.0050% | m³ |
| Mass per unit length | m_lin | 2.78615789e+03 | 2.78608796e+03 | 0.0025% | kg/m |
Total Calculated Tower Volume: 31.041 m³
Total Calculated Tower Mass: 243.676 t
| Description | Theoretical | Numerical | Error | Unit |
|---|---|---|---|---|
| Total Tower Mass | 244.067 | 244.061 | 0.0025% | t |
Official research portal of the National Renewable Energy Laboratory providing authoritative wind energy data, reference turbine models, technical reports, and validated simulation tools. It serves as a primary source for benchmark wind turbine definitions, including the NREL 5-MW reference model.
CSF computes continuous sectional properties along the tower height (z) - (A(z)), (EI(z)), (GJ(z)), etc. - compatible with OpenFAST ElastoDyn/SubDyn distributed property requirements and validated against NREL 5‑MW reference data.
example/nrel_5mw_tower.py is to demonstrate the library's performance on complex, real-world structural members, a full-scale model of the NREL 5-MW Reference Wind Turbine Tower was implemented. The geometry and material properties strictly follow the technical report "Definition of a 5-MW Reference Wind Turbine for Offshore System Development" (NREL/TP-500-38060).
The following tables provide a side-by-side comparison between the Numerical results generated by CSF and the Official NREL Reference Data (Table 6-1) pdf official doc.
Density = 8.500 kg/m3
| Elevation [m] | HtFract | TMassDen [kg/m] | TwFAStif [N·m²] | TwSSStif [N·m²] | TwGJStif [N·m²] | TwEAStif [N] | TwFAIner [kg·m] | TwSSIner [kg·m] |
|---|---|---|---|---|---|---|---|---|
| 0.00 | 0.000 | 5590.73 | 6.1431e+11 | 6.1431e+11 | 4.7273e+11 | 1.3812e+11 | 2.49e+04 | 2.49e+04 |
| 8.76 | 0.100 | 5232.30 | 5.3479e+11 | 5.3479e+11 | 4.1154e+11 | 1.2927e+11 | 2.16e+04 | 2.16e+04 |
| 17.52 | 0.200 | 4885.64 | 4.6324e+11 | 4.6324e+11 | 3.5648e+11 | 1.2070e+11 | 1.88e+04 | 1.88e+04 |
| 26.28 | 0.300 | 4550.76 | 3.9911e+11 | 3.9911e+11 | 3.0713e+11 | 1.1243e+11 | 1.62e+04 | 1.62e+04 |
| 35.04 | 0.400 | 4227.65 | 3.4187e+11 | 3.4187e+11 | 2.6307e+11 | 1.0445e+11 | 1.38e+04 | 1.38e+04 |
| 43.80 | 0.500 | 3916.31 | 2.9100e+11 | 2.9100e+11 | 2.2393e+11 | 9.6756e+10 | 1.18e+04 | 1.18e+04 |
| 52.56 | 0.600 | 3616.74 | 2.4601e+11 | 2.4601e+11 | 1.8931e+11 | 8.9355e+10 | 9.96e+03 | 9.96e+03 |
| 61.32 | 0.700 | 3328.95 | 2.0645e+11 | 2.0645e+11 | 1.5887e+11 | 8.2245e+10 | 8.36e+03 | 8.36e+03 |
| 70.08 | 0.800 | 3052.93 | 1.7184e+11 | 1.7184e+11 | 1.3224e+11 | 7.5425e+10 | 6.96e+03 | 6.96e+03 |
| 78.84 | 0.900 | 2788.68 | 1.4177e+11 | 1.4177e+11 | 1.0909e+11 | 6.8897e+10 | 5.74e+03 | 5.74e+03 |
| 87.60 | 1.000 | 2536.21 | 1.1581e+11 | 1.1581e+11 | 8.9122e+10 | 6.2659e+10 | 4.69e+03 | 4.69e+03 |
Total Calculated Tower Volume: 40.8634 m³
Total Calculated Tower Mass: 347.339 t
Official NREL 5-MW Tower Data (Reference Table 6-1) pag. 15 Download Official PDF (NREL)
| Elevation [m] | HtFract | TMassDen [kg/m] | TwFAStif [N·m²] | TwSSStif [N·m²] | TwGJStif [N·m²] | TwEAStif [N] | TwFAIner [kg·m] | TwSSIner [kg·m] |
|---|---|---|---|---|---|---|---|---|
| 0.00 | 0.000 | 5590.9 | 6.143e+11 | 6.143e+11 | 4.728e+11 | 1.381e+11 | 2.49e+04 | 2.49e+04 |
| 8.76 | 0.100 | 5232.4 | 5.348e+11 | 5.348e+11 | 4.116e+11 | 1.293e+11 | 2.16e+04 | 2.16e+04 |
| 17.52 | 0.200 | 4885.8 | 4.633e+11 | 4.633e+11 | 3.565e+11 | 1.207e+11 | 1.88e+04 | 1.88e+04 |
| 26.28 | 0.300 | 4550.9 | 3.991e+11 | 3.991e+11 | 3.071e+11 | 1.124e+11 | 1.62e+04 | 1.62e+04 |
| 35.04 | 0.400 | 4227.8 | 3.419e+11 | 3.419e+11 | 2.631e+11 | 1.044e+11 | 1.38e+04 | 1.38e+04 |
| 43.80 | 0.500 | 3916.4 | 2.910e+11 | 2.9100e+11 | 2.239e+11 | 9.676e+10 | 1.18e+04 | 1.18e+04 |
| 52.56 | 0.600 | 3616.8 | 2.460e+11 | 2.460e+11 | 1.893e+11 | 8.936e+10 | 9.96e+03 | 9.96e+03 |
| 61.32 | 0.700 | 3329.0 | 2.065e+11 | 2.065e+11 | 1.589e+11 | 8.225e+10 | 8.36e+03 | 8.36e+03 |
| 70.08 | 0.800 | 3053.0 | 1.718e+11 | 1.718e+11 | 1.322e+11 | 7.543e+10 | 6.96e+03 | 6.96e+03 |
| 78.84 | 0.900 | 2788.8 | 1.418e+11 | 1.418e+11 | 1.091e+11 | 6.890e+10 | 5.74e+03 | 5.74e+03 |
| 87.60 | 1.000 | 2536.3 | 1.158e+11 | 1.158e+11 | 8.913e+10 | 6.266e+10 | 4.69e+03 | 4.69e+03 |
Total CNREL 5-MW ref Mass: 347,460 t
| Elevation [m] | HtFract | TMassDen [kg/m] | TwFAStif [N·m²] | TwSSStif [N·m²] | TwGJStif [N·m²] | TwEAStif [N] | TwFAIner [kg·m] | TwSSIner [kg·m] |
|---|---|---|---|---|---|---|---|---|
| 0.00% | 0.00% | 0.0030% | 0.0016% | 0.0016% | 0.0148% | 0.0145% | 0.00% | 0.00% |
| 0.00% | 0.00% | 0.0019% | 0.0019% | 0.0019% | 0.0146% | 0.0232% | 0.00% | 0.00% |
| 0.00% | 0.00% | 0.0033% | 0.0130% | 0.0130% | 0.0056% | 0.0000% | 0.00% | 0.00% |
| 0.00% | 0.00% | 0.0031% | 0.0025% | 0.0025% | 0.0098% | 0.0267% | 0.00% | 0.00% |
| 0.00% | 0.00% | 0.0035% | 0.0088% | 0.0088% | 0.0114% | 0.0479% | 0.00% | 0.00% |
| 0.00% | 0.00% | 0.0023% | 0.0000% | 0.0000% | 0.0134% | 0.0041% | 0.00% | 0.00% |
| 0.00% | 0.00% | 0.0017% | 0.0041% | 0.0041% | 0.0158% | 0.0056% | 0.00% | 0.00% |
| 0.00% | 0.00% | 0.0015% | 0.0242% | 0.0242% | 0.0189% | 0.0061% | 0.00% | 0.00% |
| 0.00% | 0.00% | 0.0023% | 0.0233% | 0.0233% | 0.0302% | 0.0066% | 0.00% | 0.00% |
| 0.00% | 0.00% | 0.0043% | 0.0212% | 0.0212% | 0.0092% | 0.0044% | 0.00% | 0.00% |
| 0.00% | 0.00% | 0.0035% | 0.0086% | 0.0086% | 0.0090% | 0.0016% | 0.00% | 0.00% |
- All discrepancies are well below 0.05%.
- Differences are attributable to rounding and numerical precision.
- The generated CSF tower properties faithfully reproduce the NREL 5-MW reference.
This comparison confirms the library's ability to accurately handle continuously varying tapered sections in high-stakes engineering applications.
This project was developed and validated using the following official engineering standards and technical references:
- NREL 5-MW Reference Wind Turbine: The tower validation is based on the official technical report:
Jonkman, J., Butterfield, S., Musial, W., and Scott, G., "Definition of a 5-MW Reference Wind Turbine for Offshore System Development," NREL Technical Report NREL/TP-500-38060, February 2009.
The library is designed with a "self-documenting code" approach. For developers and engineers who wish to dive deeper into the mathematical implementations or extend the library's functionality:
- Well-Commented Source: The main file
section_field.pyis extensively documented with internal comments, docstrings, and explicit assumptions. - Inline Instructions: Every core function (from the Sutherland-Hodgman clipping to the Gaussian quadrature integrals) includes a description of its input parameters and expected physical units.
- Developer Friendly: You can find detailed explanations of the vertex-mapping logic and the stiffness matrix assembly directly above the respective function definitions.
This section demonstrates how to model a structural member where the geometry transitions smoothly between two different T-profiles.
In standard FEM, a tapered beam is often approximated as a series of stepped prismatic segments. CSF instead treats the member as a continuous ruled solid, capturing the exact cubic variation of the moment of inertia
Click to expand the full T-Beam Python example
# ----------------------------------------------------------------------------------
# ----------------------------------------------------------------------------------
# 1. DEFINE START SECTION (Z = 0)
# ----------------------------------------------------------------------------------
# GUIDELINES FOR POLYGON CONSTRUCTION:
# - COUNTER-CLOCKWISE POLYGON
# - VERTICES ORDER: You MUST define vertices in COUNTER-CLOCKWISE (CCW) order.
# This is MANDATORY for the Shoelace/Green's Theorem algorithm to compute a
# POSITIVE Area and correct Moments of Inertia. Clockwise order will result
# in negative area values and mathematically incorrect results.
# - WEIGHT: Use 1.0 for solid parts and -1.0 to define voids/holes.
# - The start section here is a T-shape composed of two not overlapping polygons:
# a "flange" (top horizontal) and a "web" (vertical stem).
# ----------------------------------------------------------------------------------
# Flange Definition: Rectangle from (-1, -0.2) to (1, 0.2)
# Order: Bottom-Left -> Bottom-Right -> Top-Right -> Top-Left (CCW)
poly0_start = Polygon(
vertices=(Pt(-1, -0.2), Pt(1, -0.2), Pt(1, 0.2), Pt(-1, 0.2)),
weight=1.0,
name="flange",
)
# Web Definition: Rectangle from (-0.2, -1.0) to (0.2, 0.2)
# Order: Bottom-Left -> Bottom-Right -> Top-Right -> Top-Left (CCW)
poly1_start = Polygon(
vertices=(Pt(-0.2, -1.0), Pt(0.2, -1.0), Pt(0.2, -0.2), Pt(-0.2, -0.2)),
weight=1.0,
name="web",
)
# ----------------------------------------------------------------------------------
# 2. DEFINE END SECTION (Z = 10)
# ----------------------------------------------------------------------------------
# GEOMETRIC CONSISTENCY:
# - To enable linear interpolation (tapering), the end section must contain the
# same number of polygons with the same names as the start section.
# - The web depth here increases linearly from 1.0 down to 2.5 (negative Y direction),
# creating a tapered profile along the longitudinal Z-axis.
# ----------------------------------------------------------------------------------
# Flange remains unchanged for this prismatic top part
poly0_end = Polygon(
vertices=(Pt(-1, -0.2), Pt(1, -0.2), Pt(1, 0.2), Pt(-1, 0.2)),
weight=1.0,
name="flange",
)
# Web becomes deeper: Y-bottom moves from -1.0 to -2.5
# MAINTAIN CCW ORDER: Bottom-Left -> Bottom-Right -> Top-Right -> Top-Left
poly1_end = Polygon(
vertices=(Pt(-0.2, -2.5), Pt(0.2, -2.5), Pt(0.2, -0.2), Pt(-0.2, -0.2)),
weight=1.0,
name="web",
)
# ----------------------------------------------------------------------------------
# 3. CREATE SECTIONS WITH Z-COORDINATES
# ----------------------------------------------------------------------------------
# Sections act as containers for polygons at a specific coordinate along the beam axis.
# All polygons defined at Z=0.0 are grouped into s0, and those at Z=10.0 into s1.
# ----------------------------------------------------------------------------------
s0 = Section(polygons=(poly0_start, poly1_start), z=0.0)
s1 = Section(polygons=(poly0_end, poly1_end), z=10.0)
# --------------------------------------------------------
# 4. INITIALIZE CONTINUOUS SECTION FIELD
# --------------------------------------------------------
# A linear interpolator is used to generate intermediate
# sections between Z = 0 and Z = 10.
field = ContinuousSectionField(section0=s0, section1=s1)
# --------------------------------------------------------
# 5. PRIMARY SECTION PROPERTIES (Z = 5.0)
# --------------------------------------------------------
# Properties are computed at mid-span.
sec_mid = field.section(5.0)
props = section_properties(sec_mid)
print("\n" + "="*40)
print("PRIMARY PROPERTIES AT Z=5.0 (Centroidal)")
print("="*40)
print(f"A: {props['A']:.4f} # Net Cross-Sectional Area")
print(f"Cx: {props['Cx']:.4f} # Horizontal Centroid location (Global X)")
print(f"Cy: {props['Cy']:.4f} # Vertical Centroid location (Global Y)")
print(f"Ix: {props['Ix']:.4f} # Second Moment of Area about Centroidal X-axis")
print(f"Iy: {props['Iy']:.4f} # Second Moment of Area about Centroidal Y-axis")
print(f"Ixy: {props['Ixy']:.4f} # Product of Inertia (Measure of asymmetry)")
print(f"J: {props['J']:.4f} # Polar Moment of Area (Ix + Iy)")
# 2. DERIVED PROPERTIES (Radius of Gyration, Principal Axes)
derived = section_derived_properties(props)
print("\n" + "-"*40)
print("DERIVED GEOMETRIC PROPERTIES")
print("-"*40)
print(f"rx: {derived['rx']:.4f} # Radius of Gyration about X (sqrt(Ix/A))")
print(f"ry: {derived['ry']:.4f} # Radius of Gyration about Y (sqrt(Iy/A))")
print(f"I1: {derived['I1']:.4f} # Maximum Principal Moment of Area")
print(f"I2: {derived['I2']:.4f} # Minimum Principal Moment of Area")
print(f"Deg: {derived['theta_deg']:.2f}° # Principal Axis Rotation Angle")
# --------------------------------------------------------
# 7. STATICAL MOMENT OF AREA (Q)
# --------------------------------------------------------
# Computed at the neutral axis (y = Cy).
# Used in shear stress calculations.)
Q_na = section_statical_moment_partial(sec_mid, y_cut=props['Cy'])
print("\n" + "-"*40)
print("SHEAR ANALYSIS PROPERTIES")
print("-"*40)
print(f"Q_na: {Q_na:.4f} # Statical Moment of Area above Neutral Axis (for Shear Stress)")
# 8. VOLUMETRIC PROPERTIES
total_vol = integrate_volume(field)
print("\n" + "="*40)
print("GLOBAL FIELD PROPERTIES (3D)")
print("="*40)
print(f"Total Volume: {total_vol:.4f} # Total material volume of the ruled solid")
# Technical Explanation for the negative Cy
print("\n" + "-"*50)
print("TECHNICAL NOTE ON COORDINATES:")
print("-"*50)
print("The negative value for 'Cy' is physically correct.")
print("In this model, the flange is centered at y=0, while the web")
print("extends downwards (from y=0.2 to y=-1.0 at Z=0, and y=-2.5 at Z=10).")
print("Since the majority of the T-section's mass is located below the")
print("global X-axis (y=0), the centroid MUST have a negative Y-coordinate.")
print("This indicates the geometric center is below the drawing origin.")
print("-"*50)
# --------------------------------------------------------
# 9. VISUALIZATION
# --------------------------------------------------------
# - 2D section plot at Z = 5.0
# - 3D ruled solid visualization
viz = Visualizer(field)
# Generate 2D plot for the specified slice
viz.plot_section_2d(z=5.0)
# Generate 3D plot of the interpolated solid
# line_percent determines the density of the longitudinal ruled lines
viz.plot_volume_3d(line_percent=100.0, seed=1)
import matplotlib.pyplot as plt
plt.show()
Click for BibTeX citation
@software{boscu_continuous_2025,
author = {Boscu, Giovanni},
title = {Continuous Section Field (CSF): A geometric and mechanical engine for non-prismatic structural members},
year = {2025},
publisher = {Zenodo},
version = {v1.0.0},
doi = {10.5281/zenodo.18063427},
url = {https://doi.org/10.5281/zenodo.18063427}
}This project is licensed under the GNU General Public License v3.0 - see the LICENSE file for details.