CivilKit Buckling guide
Two ways to go past the app's buttons, both in Python and both on the same buckling engine.
Extensions are small apps that run inside CivilKit Buckling, with a form, results and charts, shared as
.ckext files. The Python console runs your own scripts in the page, written for the
cufsm-rs-py package.
Which one?#
| An extension | A console script | |
|---|---|---|
| For | a tool other people use: a form, a check, results and calc lines | your own work: loops of analyses, studies, searches, tables |
| Written as | build_ui and check, calling the engine through capabilities | a plain script: import cufsm_rs, the API of pip install cufsm-rs-py |
| Python | MicroPython, in a sandbox, 20 seconds a call | MicroPython, or full Python with numpy, scipy and matplotlib when you agree to its download |
| Shared as | a .ckext file or the store, with a Verified badge from worked examples | a .py file, which also runs on your own machine |
| Start at | Using extensions, the tutorial | The Python console |
Extensions#
An extension is a small app that runs inside CivilKit Buckling: a form, a check, results, calc lines and charts,
written in Python. It is packed as a .ckext file. The engineering numbers come from the buckling engine;
the module decides what to ask for, in what order, and which clause equations to apply.
- Use an extensionInstall from the store or a file, run it, accept a section it proposes.
- Write your first moduleStep by step in the module builder: yield, local buckling, a worked example, Verified.
- Capability referenceEvery call a module can make to the engine, with arguments, returns and units.
- UI referenceEvery form, result, chart and drawing node the app renders.
The Python console#
The console (More › Python on a phone, the Python
tab on a desktop) runs cufsm-rs-py scripts in the page: hundreds of analyses in a loop, each one feeding a design
check, with printed tables and figures. A script that runs here runs on your own machine after
pip install cufsm-rs-py, with the same numbers.
- The Python consoleWhere it is, Run and Stop, examples, output and figures, drafts.
- MicroPython and full PythonHow the console picks a runtime, what it downloads, and what runs where.
- Python API referenceEvery name in
cufsm_rs, with arguments, defaults, units and returns. - Python examplesDesign searches, studies and the README quickstart, each a link that opens it.
- Engine APIThe Rust engine's C / wasm interface, for calling it from JavaScript or C.
The rest of this page introduces extensions.
What a module is for#
The app solves the elastic buckling problem: the signature curve, its minima, the modes and first yield. A module turns those numbers into something you would otherwise work out on paper or in a spreadsheet:
- A design check: for example the Direct Strength Method column strength from the signature curve (the DSM compression module).
- A section generator: a C or Z with rounded corners, meshed the way CUFSM's template does, offered to the analysis (Rounded C / Z section).
- A study: many engine solves in a loop, with charts and a table (Thickness study).
- Your office's procedure: the checks your firm always makes, with its own factors, written once and shared as a file.
The bundle#
A .ckext is a zip file with three entries:
manifest.json what the module is, where it plugs in, which capabilities it calls
main.py MicroPython: build_ui() draws the form, check() computes
tests/worked-examples.json cited examples; when every one reproduces its numbers the module is Verified
Keep the three in a folder and let the command line pack them (node tools/ckext.mjs pack my-module,
see the ckext command line), or write them in the app's
module builder, which exports the zip for you. Zipping by hand also works, from inside the
folder so the paths are relative: zip -r my-module.ckext manifest.json main.py tests.
manifest.json#
{
"id": "yourname.squash-load",
"name": "Squash load",
"version": "1.0.0",
"civilkitApi": "^1.0",
"description": "The section's squash load Py = A fy, from the engine's first yield.",
"license": "MIT",
"contributes": [{ "point": "buckling.tool", "id": "squash-load" }],
"capabilities": ["firstYield"]
}
| Field | Required | What it is |
|---|---|---|
id | yes | The module's identity, reverse-domain style (yourname.squash-load). Installing a bundle with an id that is already installed replaces it. |
name | yes | Shown in the Extensions list and the module's title bar. |
version | yes | Semantic version, 1.0.0. The store offers Update when its version differs from yours. |
civilkitApi | yes | "^1.0": the host API this module was written for. |
contributes | yes | [{ "point": "buckling.tool", "id": "…" }]. buckling.tool is the one contribution point Buckling has: a tool that opens from Extensions. |
capabilities | no, but needed | The engine calls the module makes. A call to anything not listed stops the module with Capability 'x' not declared in the module manifest. See declaring capabilities. |
description, license, author, homepage | no | Shown to the user. They confer no trust. |
tests | no | The worked examples' path inside the bundle, if not tests/worked-examples.json. |
main.py#
MicroPython, not CPython. json and math are there; most of the standard library is not.
The host calls two functions:
build_ui(inputs, result, calcLines)returns the form as a tree of plain dicts (the UI reference lists every node). It is called when the module opens, with{},[],[], and after every check with the inputs and whatcheckreturned.check(inputs)computes, and returns{"result": [rows], "calcLines": [lines]}. It runs when the user presses a button whoseactionis"run-check", or changes a field.
The whole of a working module:
import json, civilkit
def build_ui(inputs, result, calcLines):
return {"type": "panel", "title": "Squash load", "children": [
{"type": "field", "id": "fy", "label": "fy (MPa)", "inputType": "number",
"default": inputs.get("fy", 450)},
{"type": "button", "id": "run", "label": "Run", "action": "run-check"},
{"type": "result", "items": result},
]}
def check(inputs):
fy = float(inputs.get("fy") or 450)
y = json.loads(civilkit.firstYield(json.dumps({"fy": fy})))
return {
"result": [{"label": "Py", "value": y["Py"] / 1000, "unit": "kN"}],
"calcLines": [{"label": "Squash load", "eq": "Py = A fy = %.5g kN" % (y["Py"] / 1000)}],
}
civilkit is the host module. Each capability takes and returns a JSON string, hence the
json.dumps and json.loads. How build_ui and check are called has the details.
tests/worked-examples.json#
A list of examples, each a fixture model, the inputs, the numbers you expect and where they come from. The module is Verified when every example reproduces its expected numbers within 0.1 %; otherwise it is Community. Worked examples and the badge covers the format and the rules.
The rule: numbers come from capabilities#
Engineering numbers come from the engine. Section properties, reference stresses, first yield, buckling load factors and their minima come from capabilities. A module's own code is orchestration plus the clause equations it cites, such as the DSM strength curves. Its worked examples must reproduce cited numbers: a hand calculation or a published example, never the engine's own output pasted back in.
This is what makes a Verified badge mean something. The engine is tested against CUFSM to 1e-12 by its own suite; a module that re-derives a property in Python has a second, untested implementation. Write the equations a standard gives you, and ask the engine for everything it can tell you.
The same format as CivilKit Studio#
A Buckling module is a normal .ckext, the same format CivilKit Studio's extensions use. Shared between the
two apps:
- the bundle (
manifest.json,main.py,tests/worked-examples.json); - the
build_ui/checkcontract and the JSON UI tree, drawn by the same renderer; - the worked-example format, the 0.1 % matching rule and the Verified / Community badge;
- the headless test report's shape (
badge,examples,form,run,capabilities).
What differs is declared, not implied: Buckling's contribution point is buckling.tool (Studio's is
design-check), and its capabilities are about the section and its buckling,
in N, mm and MPa. Each app refuses the other's modules at install, naming the right app:
This module is for CivilKit Studio: its contribution points (design-check) are not among this app's (buckling.tool).
The engine#
Every number a capability returns comes from cufsm-rs, a Rust port of CUFSM, the finite strip software by Benjamin W. Schafer and co-workers (with Sándor Ádány for constrained FSM, cFSM), compiled to WebAssembly. It runs in your browser, in the same sandboxed worker as the module, so capability calls are synchronous and there is no server. Units are N, mm and MPa throughout (N·mm for moments, N·mm² for the bimoment).
This guide#
Extensions:
- Using extensions: install, badges, run, View code, proposals, the sandbox.
- Tutorial: your first module in the builder, from the starter to Verified and exported.
- Capability reference: every call, its argument, return, units and errors.
- UI reference: every node type and property the app renders.
- Worked examples and the badge: the format, the tolerance, sources.
- The ckext command line: pack and test without a browser; building the store.
- Reference modules: the three shipped modules, annotated.
Python:
- The Python console: where it is, the toolbar,
?py=links, output, drafts. - MicroPython and full Python: the two runtimes, the download prompt, what runs where.
- Python API reference:
cufsm_rsandcufsm_rs.plot, name by name. - Python examples: each shipped script, its runtime and a link.
- Engine API (Rust / wasm): the C interface every part of the app is built on.
And Troubleshooting and FAQ, for both: error messages, limits and questions.
Open source#
CivilKit Buckling is open source, part of CivilKit, open structural engineering tools by Mage Engineering. The code, this guide and the reference modules are on GitHub at mageaustralia/civilkit-buckling.
- Licence: the Apache License 2.0. You may use, change, fork and host it. The third-party parts (cufsm-rs and CUFSM, MicroPython, fflate, and Pyodide when you download it) keep their own licences, listed in THIRD_PARTY_NOTICES.
- The name: "CivilKit", "CivilKit Buckling" and the CivilKit logo are not part of the licence. A changed copy goes by its own name and may say it is based on CivilKit Buckling; the trademark note says more.
- Contributing: issues and pull requests are welcome; the README's Contributing section says how. To add a tool without touching the app, write an extension: start with the tutorial.
The engine is cufsm-rs (Rust) and, for your own machine,
cufsm-rs-py (pip install cufsm-rs-py). Both are
ports of CUFSM, by Benjamin W. Schafer and co-workers at Johns Hopkins
University, to whom this project owes its method.