#054 - StructuralCodes | An Open-Source Python Library for Capacity-Based Design
Building on an Open-Source Framework for Global Design Code Integration
Hello everybody,
Christmas looms ever closer, bringing with it the usual chaos, expense, and domestic obligations. Meanwhile, Iโve been thoroughly derailed by my latest unnecessary acquisition: a VR gaming setup (Meta Quest 3 and a PSVR2).
In a burst of unforeseen enthusiasm, Iโve danced more in the last 48 hours than in the preceding 15 years, mercifully unwatched, save for my wife, who now possesses several incriminating clips of me in action.
Expanding StructuralCodes: A Practical Approach to Capacity-Based Design in Python
This article marks the beginning of a thought experiment, one I hope will grow with your input and ideas.
My aim is to build upon the incredible work already done in StructuralCodes, an open-source Python library designed to perform capacity-based design checks for structural elements through a modular and flexible framework.
The contributors behind StructuralCodes, led by Morten Engen, have created something remarkable. Their deliberate design and thoughtful framework provide a strong foundation that the engineering community can build upon.
Currently, StructuralCodes is focused on Eurocode design, but its core architecture is designed to be adaptable to any structural design code. Itโs an excellent example of whatโs possible for open-source tools in structural engineering.
A huge shout out to Morten and the folks who have developed it.
Iโll explore StructuralCodes in greater detail later, but for now, I want to focus on the bigger picture: how can we, as practicing engineers, expand on this foundation to develop tools that work in the real world?
The Goal: Simplicity, Reusability, and Practicality
In consulting, delivering high-impact, practical solutions is the priority. While theoretical exploration has value, the day-to-day realities of engineering demand tools that are simple, reusable, and effective.
My aim is to build on the incredible work already done in StructuralCodes while inviting collaboration from the Flocode community. You, like me, likely understand the practical challenges we face.
What workflows do we need to optimize?
What pain points can we address?
What would make this tool truly useful in your professional practice?
Getting the Framework Right
Getting the framework right from the start is critical. A practical, intuitive, and simple atomic structure lays the foundation for adding complexity later.
This is where I need your input.
Whatโs the cleanest way to approach this problem?
How do we ensure the library remains practical and not just a solo indulgent odyssey?
What features or workflows matter most to you?
Iโll outline my own thoughts in the sections that follow, but this project will only succeed if we work together to shape and refine it. Consider this an open invitation to share your thoughts, experiences, feedback, and ideas.
Why Use Python for Structural Design?
Capacity-based design ensures structures perform safely by prioritizing ductile failure and clear failure hierarchies. Yet many engineers still rely on spreadsheets or proprietary tools, which, while functional, lack flexibility and transparency. Python offers a better approach:
Transparency: Open-source tools allow you to see, validate, and trust the calculations.
Flexibility: Adapt the code to suit your workflows and design codes.
Interoperability: Integrate seamlessly with other tools for automation and efficiency.
However, the challenges are real: design codes evolve, interpretations vary, and disagreements persist.
It doesnโt need to be perfectโit just needs to work. Refinement will come naturally through iteration and use.
structuralcodes
StructuralCodes is an opensource Python library developed by a fantastic group of engineers who have taken on a very difficult but important task.
StructuralCodes facilitates capacity-based design checks for structural elements, ranging from simple code compliance verifications to more complex analyses like moment-curvature relationships, shear capacity evaluations, and material behavior modeling, all through a modular framework that integrates different design codes, material properties, geometric definitions, and section analysis.
For now, StructuralCodes primarily supports Eurocode, and my focus here is to expand on these ideas, adapting them for capacity-based design in generalโand for ACI 318 in particular. Most of my projects rely on US or Canadian codes, for now Iโm focused on the US based ACI 318-19 code.
Early next year, Iโll be hosting Morten Engen, one of the creators of StructuralCodes, on the Flocode podcast. Weโll discuss the complexities and possibilities of the library, digging into the challenges heโs faced and some of the lessons learned.
Iโve already spoken to Morten about some of these topics and heโs keen to collaborate with the Flocode community to expand StructuralCodes.
How Should We Structure Such a Library?
The strength of StructuralCodes lies in its modular framework, which separates materials, geometry, constitutive laws, and design equations.
This structure is intuitive, scalable, and practical, allowing us to focus on specific components of our design. By isolating the shared mechanics of capacity-based design from code-specific details, the library becomes adaptable to multiple global design codes. This is not something we normally need to think about but itโs a helpful thought exercise!
Adapting to different codes is challenging because of their underlying philosophical differences. While the core principles of structural mechanics are universal, the way each code handles safety factors, material properties, and empirical relationships can vary significantly.
Key Differences in Global Design Codes
International structural design codes differ in their philosophical underpinnings and practical implementation. While the fundamentals of structural mechanics are universal, codes like Eurocode, ACI, CSA, and others approach design in ways that reflect regional priorities, practices, and conditions.
Hereโs a high-level overview of how these codes differ:
Eurocode (Europe):
Focuses on probabilistic safety and explicitly addresses serviceability, cracking, and long-term effects.
Safety factors (ฮณc for concrete, ฮณs for steel) are applied separately to materials.
ACI 318 (United States):
Takes a deterministic, practical approach, streamlining calculations with strength reduction factors (ฯ).
Prioritizes strength checks first, with serviceability considered separately.
CSA A23.3 (Canada):
Similar to ACI but emphasizes durability, particularly for cold climates, with stricter crack control provisions.
AS 3600 / NZS 3101 (Australia/New Zealand):
Combines Eurocode and ACI principles, with a strong emphasis on seismic ductility, especially in New Zealand.
IS 456 (India):
Simpler, empirical code with a structure similar to older versions of ACI.
Even small differences, like unit systems (metric vs. imperial) or terminology (fck vs. f'c), reflect deeper variations in design philosophy.
These distinctions are not superficialโthey impact how material properties, safety factors, and load-resisting mechanisms are modeled and validated.
Understanding these nuances is vital for adapting tools like StructuralCodes. For instance, a modular structure allows engineers to switch from Eurocode's probabilistic philosophy to ACI's streamlined strength checks without rewriting core mechanics.
Why the Modular Structure Matters
The modular structure of StructuralCodes is what makes it flexible enough to accommodate these global differences. Hereโs how it works:
Materials and Constitutive Laws
Material definitions (concrete, steel, etc.) form the foundation of any design code. These include parameters like compressive strength, tensile strength, modulus of elasticity, and strain limits.
Constitutive lawsโlike elastic-plastic, parabolic-rectangular, or bilinear modelsโtie these properties to stress-strain behavior.
While the mechanics of material behavior are universal, the specific parameters and limits differ between codes. A modular approach ensures that code-specific material logic can be added without disrupting the shared mechanics.
Geometry and Sections
Geometry defines the shape and reinforcement layout of structural members. Tools like Shapely (used in StructuralCodes) enable mathematical representation of complex shapes, including concrete sections and reinforcement placement.
Section calculators build on this geometry to derive critical properties like bending moment, shear force, and axial force capacities.
This separation allows geometry to remain independent of design codes, ensuring reusability and flexibility. For example, the same rectangular section can be analyzed using Eurocode, ACI, or CSA simply by changing the design equations.
Design Code Equations
Design equations from each code (e.g., Eurocode shear checks, ACI flexural capacity) must be modular and isolated to ensure clarity. Everything else should persist - the structural mechanics are handled separately from the code mandated empirical calculations.
The ability to switch between codesโfor example, using a function like
set_design_code('aci318_19')
โensures the library can grow incrementally without becoming unmanageable.
By modularizing these componentsโmaterials, geometry, constitutive laws, and design equationsโwe can build a framework that is simple, flexible, and scalable to handle different design codes.
The Vision: Keep It Practical
This library must be:
Lightweight: No one wants to read a dissertation to use it.
Flexible: It should work for various codes and workflows.
Easy to Maintain: Over-complicated systems are doomed to fail when time is limited.
Iโve often fallen into the trap of overengineering my own tools. Months later, I return to a project only to rebuild it from scratch because I canโt remember what I was doing. This project must avoid that fate. A clear API, practical documentation, and example-driven tutorials are non-negotiable.
The StructuralCodes documentation is already excellent. Itโs concise, clear, organized and well-written.
Questions for the Community
Iโd love to hear your thoughts on these questions. Below, Iโve added my own perspective to spark discussion. Feel free to challenge, expand, or refine these ideas.
1. Whatโs the most pragmatic way to handle different design codes?
My view: The team behind StructuralCodes has already done an excellent job structuring the library. By separating geometry, materials, design code equations, and constitutive laws, theyโve created a scalable framework. The challenge lies in how design codes handle these aspects differentlyโsome parts can be reused across codes, while others need to be built from scratch. I think we stick with this framework and focus on minimal, iterative expansions.
2. How should we prioritize features?
My view: Start with the basics. Build a simple framework that establishes a scalable pattern. Flexural and shear capacity checks are the obvious starting points. Once we have those, we can expand gradually into more complex checks.
3. Whatโs your preferred approach to managing units?
My view: Ignore unit functionality as much as possible. Engineers can manage their own units, as long as the library provides clarity where empirical equations or constitutive laws require specific unit conventions. Keeping unit handling outside the library avoids unnecessary complexity. Am I wrong? Let me know.
4. How important is support for exotic constitutive laws?
My view: Itโs not important for now. This is a classic 80/20 situationโmost applications will only need the basics. Advanced models can be added later, but the current priority should be simplicity and broad applicability.
5. What level of abstraction is most useful?
My view: Avoid over-abstraction. Each function should clearly reference the same nomenclature used in the design codes. Inputs and outputs need to be well-documented, with clear examples in the docstrings. For example, a flexural capacity function should list all required inputs like section size, moment, and rebar spacing, along with their data types.
6. What challenges do you encounter with capacity-based design tools?
My view: A major challenge is how different engineers interpret code clauses. This wonโt change, and this library isnโt going to solve that. Some empirical equations, like those requiring chart read-offs, will always be tricky, but we can address that by documenting assumptions in the relevant docstrings.
7. How can we ensure the library remains practical for consulting engineers?
My view: Build what we need and use what we need. The library will naturally evolve based on practical use cases. For me, the driving force is solving my own problemsโif it works for me, itโs likely useful for others in the field.
8. Whatโs the best way to handle updates and code changes?
My view: Updates will come as needed. Design codes rarely undergo major overhaulsโmost changes are incremental. The easiest approach is to tweak functions or add new ones as the need arises. I envision updating the library when I personally need a change, proposing a pull request for the community, or maintaining my own fork. The success of this approach will depend on collective goodwill and the toolโs usefulness.
9. Whatโs missing?
My view: This is the big one. What workflows, checks, or challenges do you think the library should address? Personally, I see the basicsโflexure, shear, buckling, deflectionโas the most critical. But Iโm curious about your most common pain points. Where would this library provide the most value to you?
A Call for Collaboration
This project is a fantastic opportunity for students, academics, and practitioners alike. Itโs a chance to work on something that could have a tangible, positive impact on the structural engineering community. Whether itโs sharing insights, proposing features, or contributing code, your input is invaluable.
Let me know your thoughtsโagree, disagree, or have an entirely new perspective? Letโs figure this out together.
Whatโs Next?
This is the first in a series of articles where Iโll think out loud about how to approach this challenge. Iโm hoping to attract contributions from academics, students, and professionals who share an interest in advancing open-source tools for structural design. Your insights and critiques will help refine this idea into something truly useful.
Final Thoughts
This initiative is about collaboration. While I have my own thoughts on how to implement capacity-based design in Python, I recognize that thereโs no one-size-fits-all solution. The strength of this project will come from the collective input and insights of the community.
I want to take a moment to acknowledge Morten and the contributors behind StructuralCodes. What theyโve built is truly impressive and an incredible service to the industry. If youโre working with Eurocodes and havenโt checked it out, you should.
Their work to date demonstrates a level of careful thought and deliberate architecture that becomes more apparent the deeper you explore. Nothing like this exists elsewhere in structural engineering software today. There are some commercial tools like Tedds, Strucalc, Enercalc and others but these are expensive and inflexible. Thatโs a topic for another day.
Itโs frustrating to see that major design codes from CSA, ACI, AISC and CISC still lack official Python libraries. For a field that relies so heavily on precision and consistency, the absence of such tools is, frankly, surprising. Projects like StructuralCodes fill this gap, and they set a standard for what open-source engineering tools can achieve.
Together, we can build something impactfulโsomething practical, flexible, and open-source that bridges the gap between research and consulting. Whether itโs through sharing ideas, offering feedback, or contributing code, I welcome your collaboration.
Looking forward to hearing your thoughts.
See you in the next one.
James ๐
Agree with your points above, James. My first thought was, like yours, to focus on the tasks structural engineers do most frequently - bending checks, shear checks, etc. But on second thought I think there's another aspect which is important - other tools in the industry. I think the priority should be on tasks that are done frequently which don't have good existing tools.
Flexural strength, for example, has a plethora of tools available. Shear capacity doesn't have nearly as much available. Or say, fatigue design of steel? Gunnstein has a fantastic library for doing rainflow analysis (https://github.com/Gunnstein/fatpack), but it would be great to see this put together with a codified method.
With respect to handling Design Code changes: I suspect this will be easy. I'm sure you're intimately familiar with how long it takes for Standards to undergo changes, and then when they do change, there's still errors! I can think of half a dozen off the top of my head in the Australian Bridge code which are still hanging on from 2017 ๐. So I think the open-source community will be able to respond much, much faster.
Love the call to action!
Hey James - to answer your some of short 'survey' questions:
1) I don't have the answer to this question right now as I'm new to collaborative library development!
2) Can treat it somewhat like a code committee (minus the politics) in that there are set targets for codebase updates and some level of 'peer review' after the actual updates to the codes/standards occur.
3) Would initially want "common" resistance checks to be covered (sectional, member), eliminating the need for in-house spreadsheets. Workflow wise would really depend on the portion of the building code or design standard we are looking to develop, could be simple (column design from axial loads derived using code combinations) to very complex (capacity design of LFRS elements) that would rely on some interfacing with a structural analysis package (whether open source or commercial) but the latter is perhaps beyond the scope of this library for now.