Merge pull request 'docs: rewrite READMEs dry and blunt, rename Studio to OTKO' (#1) from rewrite-readmes into main
Some checks failed
CI / lint (push) Has been cancelled
CI / test (macos-latest, 3.10) (push) Has been cancelled
CI / test (macos-latest, 3.11) (push) Has been cancelled
CI / test (macos-latest, 3.12) (push) Has been cancelled
CI / test (ubuntu-latest, 3.10) (push) Has been cancelled
CI / test (ubuntu-latest, 3.11) (push) Has been cancelled
CI / test (ubuntu-latest, 3.12) (push) Has been cancelled
CI / test (windows-latest, 3.10) (push) Has been cancelled
CI / test (windows-latest, 3.11) (push) Has been cancelled
CI / test (windows-latest, 3.12) (push) Has been cancelled
Some checks failed
CI / lint (push) Has been cancelled
CI / test (macos-latest, 3.10) (push) Has been cancelled
CI / test (macos-latest, 3.11) (push) Has been cancelled
CI / test (macos-latest, 3.12) (push) Has been cancelled
CI / test (ubuntu-latest, 3.10) (push) Has been cancelled
CI / test (ubuntu-latest, 3.11) (push) Has been cancelled
CI / test (ubuntu-latest, 3.12) (push) Has been cancelled
CI / test (windows-latest, 3.10) (push) Has been cancelled
CI / test (windows-latest, 3.11) (push) Has been cancelled
CI / test (windows-latest, 3.12) (push) Has been cancelled
Reviewed-on: #1
This commit is contained in:
commit
7665b7d031
11 changed files with 233 additions and 263 deletions
|
|
@ -1,8 +1,8 @@
|
|||
# Contributing
|
||||
|
||||
Thanks for your interest. This project is in an early phase; the bar for
|
||||
incoming changes is on architecture cleanliness rather than feature
|
||||
breadth.
|
||||
Early-stage project. The bar is architecture cleanliness, not feature
|
||||
count. If your change breaks a layering rule below, it won't merge —
|
||||
no matter how useful the feature.
|
||||
|
||||
## Dev setup
|
||||
|
||||
|
|
|
|||
159
README.md
159
README.md
|
|
@ -3,14 +3,13 @@
|
|||
</p>
|
||||
|
||||
<p align="center">
|
||||
A modern, SAP2000-style desktop GUI for
|
||||
<a href="https://openseespydoc.readthedocs.io/">OpenSeesPy</a> —
|
||||
built for structural and earthquake engineers who want a visual
|
||||
modeling environment without leaving the OpenSees ecosystem.
|
||||
A SAP2000-style desktop GUI for
|
||||
<a href="https://openseespydoc.readthedocs.io/">OpenSeesPy</a>.
|
||||
Draw the model, click run, look at the diagrams.
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<em>Status: Pre-alpha. Active development. APIs and file formats will change.</em>
|
||||
<em>Pre-alpha. Under active development. APIs and file formats will change.</em>
|
||||
</p>
|
||||
|
||||
---
|
||||
|
|
@ -19,21 +18,20 @@
|
|||
|
||||
## Why
|
||||
|
||||
OpenSees is the gold-standard nonlinear FEM solver for earthquake
|
||||
engineering, but its native interface is Tcl/Python scripts.
|
||||
OTKO adds a visual front-end so you can:
|
||||
OpenSees does nonlinear FEM well. Its user interface is a script.
|
||||
OTKO puts a visual front-end on it:
|
||||
|
||||
- Click to draw nodes, frames, supports, and loads on a snapped grid.
|
||||
- Draw nodes, frames, supports, and loads on a snapped grid.
|
||||
- Assign materials, sections, and load patterns through dialogs.
|
||||
- Run static, modal, pushover, and time-history analyses with progress
|
||||
and cancel support.
|
||||
- Inspect results visually — deformed shape, mode shapes, force
|
||||
and cancel.
|
||||
- Look at the results — deformed shape, mode shapes, force
|
||||
diagrams, pushover curves, time-history plots, hysteresis loops.
|
||||
- Save the model as a single `.osmodel` JSON file that round-trips
|
||||
cleanly (diff-able in Git, scriptable from Python).
|
||||
- Save the model as one `.osmodel` JSON file. Diffs cleanly in Git,
|
||||
builds cleanly from Python.
|
||||
|
||||
Behind the GUI, the same `core` Pydantic model is fully usable from a
|
||||
script or Jupyter notebook — the GUI is one frontend, not the only one.
|
||||
Underneath, the `core` Pydantic model works fine from a script or
|
||||
notebook. The GUI is a front-end, not the whole product.
|
||||
|
||||
## What works today
|
||||
|
||||
|
|
@ -53,11 +51,11 @@ script or Jupyter notebook — the GUI is one frontend, not the only one.
|
|||
mode shapes, axial / shear / moment diagrams, pushover curves
|
||||
(in display units), time-history plots, hysteresis loops,
|
||||
response-spectrum SRSS / CQC, snapshot + video export.
|
||||
- **Persistence** — projects save as a single JSON `.osmodel` file
|
||||
(Pydantic-validated, round-trip-clean).
|
||||
- **Examples** — 20+ verified examples bundled, including the OpenSees
|
||||
Wiki Examples-1 through Example-4 family and a fiber-section RC frame
|
||||
pushover. See [`examples/README.md`](examples/README.md).
|
||||
- **Persistence** — one JSON `.osmodel` per project, Pydantic-validated,
|
||||
round-trips clean.
|
||||
- **Examples** — 20+ verified examples, including OpenSees
|
||||
Wiki Examples 1–4 and a fiber-section RC frame pushover.
|
||||
See [`examples/README.md`](examples/README.md).
|
||||
|
||||
## Tech stack
|
||||
|
||||
|
|
@ -74,22 +72,22 @@ script or Jupyter notebook — the GUI is one frontend, not the only one.
|
|||
|
||||
## Architecture
|
||||
|
||||
Strict MVVM + service layer. The `core` package is pure Python — no Qt,
|
||||
no OpenSeesPy imports — and is fully unit-testable in isolation.
|
||||
Strict MVVM + service layer. `core` is pure Python — no Qt,
|
||||
no OpenSeesPy imports — and unit-tests in isolation.
|
||||
|
||||
```
|
||||
views (Qt) → viewmodels → services (OpenSeesRunner, Persistence) → core (model)
|
||||
```
|
||||
|
||||
See [`docs/architecture.md`](docs/architecture.md) for the long form,
|
||||
including the canonical OpenSeesPy command sequence the runner emits.
|
||||
Long version in [`docs/architecture.md`](docs/architecture.md),
|
||||
including the OpenSeesPy command order the runner emits.
|
||||
|
||||
## Install (development)
|
||||
|
||||
**Desktop GUI** (includes Qt, PyVista, pyqtgraph, imageio):
|
||||
**Desktop GUI** (Qt, PyVista, pyqtgraph, imageio):
|
||||
|
||||
```bash
|
||||
git clone https://github.com/ogunc/otko.git
|
||||
git clone ssh://git@smill-home.ddns.net/smill/otko.git
|
||||
cd otko
|
||||
|
||||
python -m venv .venv
|
||||
|
|
@ -99,22 +97,21 @@ source .venv/bin/activate # Linux / macOS
|
|||
pip install -e ".[gui,dev]"
|
||||
```
|
||||
|
||||
**Headless / web reuse** (core + services only, no Qt pulled in):
|
||||
**Headless** (core + services only, no Qt):
|
||||
|
||||
```bash
|
||||
pip install -e .
|
||||
```
|
||||
|
||||
This installs only the headless base set (pydantic, numpy, h5py, openseespy).
|
||||
It is the correct install for web backends, scripts, and Jupyter notebooks that
|
||||
reuse `otko.core` or `otko.services` without the GUI.
|
||||
That pulls pydantic, numpy, h5py, openseespy and nothing else.
|
||||
Use it for scripts, notebooks, and web backends that reuse
|
||||
`otko.core` or `otko.services` without the GUI.
|
||||
|
||||
Python 3.10+ is required. On Windows use **3.12+** — the `openseespywin==3.8.0.0`
|
||||
wheel has no 3.11 build (`Requires-Python >=3.12`). Pin both
|
||||
`openseespy==3.8.0.0` and `openseespywin==3.8.0.0` (already pinned
|
||||
in `pyproject.toml`).
|
||||
Python 3.10+. On Windows use **3.12+** — `openseespywin==3.8.0.0`
|
||||
has no 3.11 wheel (`Requires-Python >=3.12`). Both pins already
|
||||
live in `pyproject.toml`.
|
||||
|
||||
## Quick start — the 60-second tour
|
||||
## Quick start
|
||||
|
||||
```bash
|
||||
python -m otko
|
||||
|
|
@ -122,22 +119,20 @@ python -m otko
|
|||
|
||||
Then:
|
||||
|
||||
1. **File → Open** → pick `examples/cantilever.osmodel`.
|
||||
1. **File → Open** → `examples/cantilever.osmodel`.
|
||||
2. **Analyze → Cases** → run `Tip-Load`.
|
||||
3. **Display → Show Force Diagram** → component **M3** → linear moment
|
||||
peaking at 50 kN·m at the fixed end. Component **V2** → constant
|
||||
-10 kN.
|
||||
4. **Display → Show Deformed Shape** → the classic cantilever curve.
|
||||
3. **Display → Show Force Diagram** → **M3**: linear moment,
|
||||
50 kN·m at the fixed end. **V2**: constant -10 kN.
|
||||
4. **Display → Show Deformed Shape** → cantilever curve, as advertised.
|
||||
|
||||
For a nonlinear walkthrough, open `examples/portal_pushover.osmodel`,
|
||||
run the `Push-X` case, then **Display → Show Pushover Curve** — you'll
|
||||
see the elastic ramp followed by a yield plateau as the fiber-section
|
||||
hinges form at the column bases.
|
||||
Nonlinear version: open `examples/portal_pushover.osmodel`,
|
||||
run `Push-X`, **Display → Show Pushover Curve**. Elastic ramp,
|
||||
then a yield plateau as the base hinges form.
|
||||
|
||||
## Run the test suite
|
||||
|
||||
```bash
|
||||
pytest tests/unit # pure-logic tests, milliseconds
|
||||
pytest tests/unit # pure logic, milliseconds
|
||||
pytest tests/gui # Qt event-loop tests (pytest-qt)
|
||||
pytest tests/integration # real OpenSeesPy runs on bundled examples
|
||||
```
|
||||
|
|
@ -147,57 +142,47 @@ CI runs lint + the non-`slow` subset on Linux / macOS / Windows
|
|||
|
||||
## Roadmap
|
||||
|
||||
See [`docs/roadmap.md`](docs/roadmap.md) for the phase-by-phase plan.
|
||||
Phases 0–7 (modeling, analysis, post-processing) are largely done.
|
||||
Phase 8 (earthquake-engineering primitives — isolators, ground-motion
|
||||
library, IDA, fiber-section editor polish) is the active edge.
|
||||
[`docs/roadmap.md`](docs/roadmap.md) has the phase-by-phase plan.
|
||||
Phases 0–7 (modeling, analysis, post-processing) are mostly done.
|
||||
Phase 8 (isolators, ground-motion library, IDA, fiber-section
|
||||
editor polish) is where the open work is.
|
||||
|
||||
## We're looking for collaborators
|
||||
## Collaborators wanted
|
||||
|
||||
This project is most useful to researchers and engineers who already
|
||||
work with OpenSees and want a faster path from "idea" to "model" —
|
||||
**and who would rather build that path together than alone.**
|
||||
Most useful to people who already work with OpenSees and want a
|
||||
shorter path from idea to model — and would rather build it together
|
||||
than alone. Open an issue or say hi if you are:
|
||||
|
||||
If any of the following sounds like you, please open an issue or
|
||||
say hi:
|
||||
- A **structural / earthquake engineer** who knows OpenSees Tcl
|
||||
or OpenSeesPy and can tell us when a feature is almost right
|
||||
but not quite.
|
||||
- A **researcher** running pushover, IDA, or response-spectrum studies
|
||||
who can check the GUI against hand-built scripts.
|
||||
- A **Python / Qt developer** into scientific desktop apps,
|
||||
VTK rendering, or Pydantic schema design.
|
||||
- A **student** learning FEM and GUI architecture at the same time —
|
||||
the examples and tests are meant to read as documentation.
|
||||
- A **UX / icon designer** willing to argue about dialogs, toolbar
|
||||
icons, and visual language.
|
||||
|
||||
- 🌉 **Structural / earthquake engineers** comfortable with OpenSees Tcl
|
||||
or OpenSeesPy who can spot when a feature is "almost right but not
|
||||
quite" — that calibration feedback is gold.
|
||||
- 🧪 **Researchers** running pushover, IDA, or response-spectrum studies
|
||||
who want to validate the GUI against their hand-built scripts.
|
||||
- 🐍 **Python / Qt developers** interested in scientific desktop apps,
|
||||
PyVista / VTK rendering, or Pydantic-driven schema design.
|
||||
- 📚 **Students** who want to learn structural FEM and modern GUI
|
||||
architecture at the same time — example walkthroughs and tests are
|
||||
designed to read as documentation.
|
||||
- 🎨 **UX / icon designers** willing to help shape the dialog set,
|
||||
toolbar icons, and overall visual language.
|
||||
|
||||
Open issues, bug reports, and reproducible test cases are just as
|
||||
valuable as code. See [`CONTRIBUTING.md`](CONTRIBUTING.md) for the dev
|
||||
setup and the architectural rules enforced in review.
|
||||
Bug reports and reproducible test cases count as contributions.
|
||||
See [`CONTRIBUTING.md`](CONTRIBUTING.md) for setup and the rules
|
||||
enforced in review.
|
||||
|
||||
## License
|
||||
|
||||
OTKO is released under the **GNU Affero General Public
|
||||
License v3.0** ([`LICENSE`](LICENSE)).
|
||||
OTKO is **GNU Affero General Public License v3.0**
|
||||
([`LICENSE`](LICENSE)). Read the license itself, not just this:
|
||||
|
||||
Plain-language summary (not legal advice — read the license itself):
|
||||
|
||||
- ✅ Use it for **research, education, and personal projects** with no
|
||||
obligation other than keeping the copyright notice intact.
|
||||
- ✅ Modify and fork it freely.
|
||||
- ⚠️ If you **distribute** it, modified or not, you must release your
|
||||
full source under AGPL-3.0.
|
||||
- ⚠️ If you **run it as a network service** (e.g. host a modified
|
||||
version as a SaaS), you must release your modifications under
|
||||
- Research, education, personal projects: fine, keep the copyright
|
||||
notice.
|
||||
- Fork and modify: fine.
|
||||
- Distribute it (modified or not): release your full source under
|
||||
AGPL-3.0.
|
||||
- Run a modified version as a network service: release your
|
||||
modifications under AGPL-3.0.
|
||||
|
||||
In other words: anyone is free to learn from and build on this code,
|
||||
but commercial forks and proprietary derivatives must contribute their
|
||||
changes back to the community. If your use case needs a different
|
||||
arrangement (e.g. a closed-source commercial license), please open an
|
||||
issue to discuss.
|
||||
Commercial forks stay open. If you need a different arrangement
|
||||
(e.g. closed-source commercial license), open an issue.
|
||||
|
||||
Copyright © 2026 Ozan and contributors.
|
||||
|
|
|
|||
|
|
@ -24,11 +24,11 @@ the reverse.
|
|||
|
||||
### Why this matters
|
||||
|
||||
- The `core` package is testable without a display server, without OpenSees,
|
||||
and without Qt. CI runs `pytest tests/unit/` in milliseconds.
|
||||
- Replacing OpenSeesPy with another solver (e.g. `xara`, a future fork) only
|
||||
touches `services/opensees_runner.py`.
|
||||
- A future CLI or Jupyter frontend reuses `core` and `services` unchanged.
|
||||
- `core` tests without a display server, without OpenSees, without Qt.
|
||||
CI runs `pytest tests/unit/` in milliseconds.
|
||||
- Swapping solvers (e.g. `xara`, a future fork) touches
|
||||
`services/opensees_runner.py` and nothing else.
|
||||
- A future CLI or notebook front-end reuses `core` and `services` as-is.
|
||||
|
||||
## Package map
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
| **Category** | Schema group (material family, element type, etc.) |
|
||||
| **Object** | Name as it appears in gidopensees BOOK/CONDITION |
|
||||
| **OTKO name** | Corresponding class in `core/` (if any) |
|
||||
| **In Studio?** | ✅ fully supported · 🟡 partial · ❌ missing |
|
||||
| **In OTKO?** | ✅ fully supported · 🟡 partial · ❌ missing |
|
||||
| **In gidopensees?** | ✅ · ❌ |
|
||||
| **Priority** | P0 = already done · P1 = Phase 8 target · P2 = later |
|
||||
|
||||
|
|
@ -28,7 +28,7 @@ Priority rationale:
|
|||
|
||||
## 1. Uniaxial Materials
|
||||
|
||||
| Category | Object (gidopensees) | OTKO name | In Studio? | In gidopensees? | Priority |
|
||||
| Category | Object (gidopensees) | OTKO name | In OTKO? | In gidopensees? | Priority |
|
||||
|---|---|---|---|---|---|
|
||||
| Uniaxial / linear | Elastic | `ElasticUniaxial` | ✅ | ✅ | P0 |
|
||||
| Uniaxial / elastic-plastic | Elastic_Perfectly_Plastic | `ElasticPP` | ✅ | ✅ | P0 |
|
||||
|
|
@ -43,7 +43,7 @@ Priority rationale:
|
|||
|
||||
## 2. Steel Uniaxial Materials
|
||||
|
||||
| Category | Object (gidopensees) | OTKO name | In Studio? | In gidopensees? | Priority |
|
||||
| Category | Object (gidopensees) | OTKO name | In OTKO? | In gidopensees? | Priority |
|
||||
|---|---|---|---|---|---|
|
||||
| Steel | Steel01 | `Steel01` | ✅ | ✅ | P0 |
|
||||
| Steel | Steel02 | `Steel02` | ✅ | ✅ | P0 |
|
||||
|
|
@ -53,7 +53,7 @@ Priority rationale:
|
|||
|
||||
## 3. Concrete Uniaxial Materials
|
||||
|
||||
| Category | Object (gidopensees) | OTKO name | In Studio? | In gidopensees? | Priority |
|
||||
| Category | Object (gidopensees) | OTKO name | In OTKO? | In gidopensees? | Priority |
|
||||
|---|---|---|---|---|---|
|
||||
| Concrete | Concrete01_(Zero_tensile_strength) | `Concrete01` | ✅ | ✅ | P0 |
|
||||
| Concrete | Concrete02_(Linear_tension_softening) | `Concrete02` | ✅ | ✅ | P0 |
|
||||
|
|
@ -63,7 +63,7 @@ Priority rationale:
|
|||
|
||||
## 4. Combined Materials
|
||||
|
||||
| Category | Object (gidopensees) | OTKO name | In Studio? | In gidopensees? | Priority |
|
||||
| Category | Object (gidopensees) | OTKO name | In OTKO? | In gidopensees? | Priority |
|
||||
|---|---|---|---|---|---|
|
||||
| Combination | Series | — | ❌ | ✅ | P1 |
|
||||
| Combination | Parallel | — | ❌ | ✅ | P1 |
|
||||
|
|
@ -71,7 +71,7 @@ Priority rationale:
|
|||
|
||||
## 5. nD (Multi-dimensional) Materials
|
||||
|
||||
| Category | Object (gidopensees) | OTKO name | In Studio? | In gidopensees? | Priority |
|
||||
| Category | Object (gidopensees) | OTKO name | In OTKO? | In gidopensees? | Priority |
|
||||
|---|---|---|---|---|---|
|
||||
| nD | Elastic_Isotropic | `ElasticIsotropic` | ✅ | ✅ | P0 |
|
||||
| nD | Elastic_Orthotropic | — | ❌ | ✅ | P2 |
|
||||
|
|
@ -84,7 +84,7 @@ Priority rationale:
|
|||
|
||||
## 6. Sections
|
||||
|
||||
| Category | Object (gidopensees) | OTKO name | In Studio? | In gidopensees? | Priority |
|
||||
| Category | Object (gidopensees) | OTKO name | In OTKO? | In gidopensees? | Priority |
|
||||
|---|---|---|---|---|---|
|
||||
| Section | Elastic_Section | `ElasticSection` | ✅ | ✅ | P0 |
|
||||
| Section | Fiber | `FiberSection` | ✅ | ✅ | P0 |
|
||||
|
|
@ -97,7 +97,7 @@ Priority rationale:
|
|||
|
||||
## 7. Beam-Column Elements
|
||||
|
||||
| Category | Object (gidopensees) | OTKO name | In Studio? | In gidopensees? | Priority |
|
||||
| Category | Object (gidopensees) | OTKO name | In OTKO? | In gidopensees? | Priority |
|
||||
|---|---|---|---|---|---|
|
||||
| Frame | Elastic_Beam-Column | `ElasticBeamColumn` | ✅ | ✅ | P0 |
|
||||
| Frame | Elastic_Timoshenko_Beam-Column | — | ❌ | ✅ | P1 |
|
||||
|
|
@ -108,14 +108,14 @@ Priority rationale:
|
|||
|
||||
## 8. Truss Elements
|
||||
|
||||
| Category | Object (gidopensees) | OTKO name | In Studio? | In gidopensees? | Priority |
|
||||
| Category | Object (gidopensees) | OTKO name | In OTKO? | In gidopensees? | Priority |
|
||||
|---|---|---|---|---|---|
|
||||
| Truss | Truss | `TrussElement` | ✅ | ✅ | P0 |
|
||||
| Truss | Corotational_Truss | `CorotTrussElement` | ✅ | ✅ | P0 |
|
||||
|
||||
## 9. Surface / Plate Elements
|
||||
|
||||
| Category | Object (gidopensees) | OTKO name | In Studio? | In gidopensees? | Priority |
|
||||
| Category | Object (gidopensees) | OTKO name | In OTKO? | In gidopensees? | Priority |
|
||||
|---|---|---|---|---|---|
|
||||
| Surface | Quad | `QuadElement` | ✅ | ✅ | P0 |
|
||||
| Surface | Shell (ShellMITC4 / MITC4) | — | ❌ | ✅ | P1 |
|
||||
|
|
@ -125,13 +125,13 @@ Priority rationale:
|
|||
|
||||
## 10. Solid Elements
|
||||
|
||||
| Category | Object (gidopensees) | OTKO name | In Studio? | In gidopensees? | Priority |
|
||||
| Category | Object (gidopensees) | OTKO name | In OTKO? | In gidopensees? | Priority |
|
||||
|---|---|---|---|---|---|
|
||||
| Solid | Standard_Brick_Element | — | ❌ | ✅ | P2 |
|
||||
|
||||
## 11. Zero-Length / Special Elements
|
||||
|
||||
| Category | Object (gidopensees) | OTKO name | In Studio? | In gidopensees? | Priority |
|
||||
| Category | Object (gidopensees) | OTKO name | In OTKO? | In gidopensees? | Priority |
|
||||
|---|---|---|---|---|---|
|
||||
| Special | Auto_Zero_Length (per-DOF uniaxial) | `ZeroLengthElement` | ✅ | ✅ | P0 |
|
||||
| Special | Auto_equal_constraint (auto equalDOF) | `EqualDOFConstraint` | ✅ | ✅ | P0 |
|
||||
|
|
@ -140,7 +140,7 @@ Priority rationale:
|
|||
|
||||
## 12. Restraints (Boundary Conditions)
|
||||
|
||||
| Category | Object (gidopensees) | OTKO name | In Studio? | In gidopensees? | Priority |
|
||||
| Category | Object (gidopensees) | OTKO name | In OTKO? | In gidopensees? | Priority |
|
||||
|---|---|---|---|---|---|
|
||||
| Restraint | Point_Restraints | Node.restraint (6-tuple) | ✅ | ✅ | P0 |
|
||||
| Restraint | Line_Restraints (auto-apply to nodes on line) | — | ❌ | ✅ | P2 |
|
||||
|
|
@ -148,7 +148,7 @@ Priority rationale:
|
|||
|
||||
## 13. Nodal Loads & Displacements
|
||||
|
||||
| Category | Object (gidopensees) | OTKO name | In Studio? | In gidopensees? | Priority |
|
||||
| Category | Object (gidopensees) | OTKO name | In OTKO? | In gidopensees? | Priority |
|
||||
|---|---|---|---|---|---|
|
||||
| Load | Point_Forces | `NodalLoad` | ✅ | ✅ | P0 |
|
||||
| Load | Line_Forces (nodal, along a line) | — | ❌ | ✅ | P2 |
|
||||
|
|
@ -160,7 +160,7 @@ Priority rationale:
|
|||
|
||||
## 14. Ground Motions
|
||||
|
||||
| Category | Object (gidopensees) | OTKO name | In Studio? | In gidopensees? | Priority |
|
||||
| Category | Object (gidopensees) | OTKO name | In OTKO? | In gidopensees? | Priority |
|
||||
|---|---|---|---|---|---|
|
||||
| Ground motion | Point_Ground_Motion_from_Record | `PathTimeSeries` + `UniformExcitationPattern` | ✅ | ✅ | P0 |
|
||||
| Ground motion | Point_Sine_Ground_Motion | — (no `TrigTimeSeries`) | ❌ | ✅ | P1 |
|
||||
|
|
@ -168,7 +168,7 @@ Priority rationale:
|
|||
|
||||
## 15. Constraints
|
||||
|
||||
| Category | Object (gidopensees) | OTKO name | In Studio? | In gidopensees? | Priority |
|
||||
| Category | Object (gidopensees) | OTKO name | In OTKO? | In gidopensees? | Priority |
|
||||
|---|---|---|---|---|---|
|
||||
| Constraint | Point_Equal_constraint (master + slave) | `EqualDOFConstraint` | ✅ | ✅ | P0 |
|
||||
| Constraint | Line_Equal_constraint (slave nodes on line) | — | ❌ | ✅ | P1 |
|
||||
|
|
@ -179,7 +179,7 @@ Priority rationale:
|
|||
|
||||
## 16. Mass
|
||||
|
||||
| Category | Object (gidopensees) | OTKO name | In Studio? | In gidopensees? | Priority |
|
||||
| Category | Object (gidopensees) | OTKO name | In OTKO? | In gidopensees? | Priority |
|
||||
|---|---|---|---|---|---|
|
||||
| Mass | Point_Mass | node mass (Properties dock + SetMassCommand) | ✅ | ✅ | P0 |
|
||||
| Mass | Line_Mass (auto-lump to nodes) | — | ❌ | ✅ | P1 |
|
||||
|
|
@ -188,7 +188,7 @@ Priority rationale:
|
|||
|
||||
## 17. Rayleigh Damping
|
||||
|
||||
| Category | Object (gidopensees) | OTKO name | In Studio? | In gidopensees? | Priority |
|
||||
| Category | Object (gidopensees) | OTKO name | In OTKO? | In gidopensees? | Priority |
|
||||
|---|---|---|---|---|---|
|
||||
| Damping | Global αM + βK (TransientCase fields) | `TransientCase.rayleigh_alpha_m/beta_k` | ✅ | 🟡 | P0 |
|
||||
| Damping | Mode-1 stiffness-proportional βK auto-compute | `TransientCase.rayleigh_mode1_damping` | ✅ | ❌ | P0 |
|
||||
|
|
@ -205,7 +205,7 @@ Priority rationale:
|
|||
| ❌ P1 targets (Phase 8 additions) | 23 |
|
||||
| ❌ P2 deferred | 21 |
|
||||
|
||||
**Top P1 targets** (highest EQ-engineering impact, not in Studio yet):
|
||||
**Top P1 targets** (highest EQ-engineering impact, not in OTKO yet):
|
||||
|
||||
1. `ElasticPP_with_Gap` — bearing pad / isolation gap nonlinearity
|
||||
2. `Viscous` / `Viscous_Damper` — supplemental damping devices
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@
|
|||
<!-- Wordmark -->
|
||||
<g font-family="Segoe UI, Inter, Helvetica, Arial, sans-serif">
|
||||
<text x="200" y="92" font-size="56" font-weight="700" letter-spacing="-1">
|
||||
<tspan fill="#E8EDF5">Open</tspan><tspan fill="#7BB1F0">Sees</tspan><tspan fill="#E8EDF5"> Studio</tspan>
|
||||
<tspan fill="#E8EDF5">OTKO</tspan>
|
||||
</text>
|
||||
<text x="202" y="124" font-size="16" font-weight="500" letter-spacing="3" fill="#8FA2BF">
|
||||
A SAP2000-STYLE GUI FOR OPENSEESPY
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.1 KiB |
|
|
@ -1,9 +1,8 @@
|
|||
# Roadmap
|
||||
|
||||
OTKO is built in eight phases. Phases 0–7 ship the core GUI
|
||||
plus all the post-processing tooling we need for verification work.
|
||||
Phase 8 layers in the earthquake-engineering primitives that turn the
|
||||
GUI from "OpenSees frontend" into a usable research tool.
|
||||
Eight phases. 0–7 are the core GUI plus post-processing. Phase 8 is the
|
||||
earthquake-engineering primitives — the part that makes it a research
|
||||
tool instead of a model viewer.
|
||||
|
||||
Status legend: ✅ done · 🟡 partial · ⬜ planned · ✂️ deferred / out-of-scope.
|
||||
|
||||
|
|
|
|||
|
|
@ -1,34 +1,34 @@
|
|||
# Example models
|
||||
|
||||
Pre-built `.osmodel` files plus the Python scripts that produce them.
|
||||
Each model is set up with whichever case types the post-processing
|
||||
features need, so you can exercise the full GUI without manually
|
||||
defining materials, sections, loads, and analysis cases.
|
||||
Pre-built `.osmodel` files plus the Python scripts that generate them.
|
||||
Each one carries the case types the post-processing views need, so you
|
||||
can exercise the GUI without defining materials, sections, loads, and
|
||||
cases by hand.
|
||||
|
||||
## Files
|
||||
|
||||
| Model | Nodes | Elements | Cases | Best for demonstrating |
|
||||
| Model | Nodes | Elements | Cases | Shows |
|
||||
|---|---|---|---|---|
|
||||
| `cantilever.osmodel` | 6 | 5 | Static × 2, Modal | Point & distributed loads, force diagrams, deformed shape, mode shapes |
|
||||
| `portal_frame.osmodel` | 4 | 3 | Static, Modal, Transient | All Display features, simplest 3D |
|
||||
| `space_frame_3d.osmodel` | 12 | 16 | Static, Modal, Transient (5% damping) | Realistic 3D rendering, multiple modes, damped EQ time-history |
|
||||
| `cantilever.osmodel` | 6 | 5 | Static × 2, Modal | Point + distributed loads, force diagrams, deformed shape, mode shapes |
|
||||
| `portal_frame.osmodel` | 4 | 3 | Static, Modal, Transient | All Display features, smallest 3D |
|
||||
| `space_frame_3d.osmodel` | 12 | 16 | Static, Modal, Transient (5% damping) | 3D rendering, multiple modes, damped EQ time-history |
|
||||
| `sdof_pushover.osmodel` | 2 | 1 | Pushover, Modal | Monotonic pushover curve, HystereticMaterial |
|
||||
| `portal_pushover.osmodel` | 4 | 3 | Pushover, Modal | Fiber sections, BeamWithHinges, nonlinear pushover with yielding |
|
||||
| `ex1a_canti2d.osmodel` | 2 | 1 | Static preload, Pushover, Transient EQ | Original OpenSees Ex 1a with shared gravity, push, and earthquake cases |
|
||||
| `ex1b_portal2d.osmodel` | 4 | 3 | Static preload, Pushover, Transient EQ | Original OpenSees Ex 1b elastic portal frame with distributed gravity |
|
||||
| `ex2a_canti2d_elastic_element.osmodel` | 2 | 1 | Static preload, Pushover, Transient EQ | Variable-driven cantilever example with derived parameters |
|
||||
| `ex2b_canti2d_inelastic_section.osmodel` | 2 | 1 | Static preload, Pushover, Transient EQ | First nonlinear cantilever with aggregated uniaxial section |
|
||||
| `ex2c_canti2d_inelastic_fiber_section.osmodel` | 2 | 1 | Static preload, Pushover, Transient EQ | Fiber-section cantilever with coupled axial-flexural nonlinearity |
|
||||
| `ex3_canti2d_elastic_element.osmodel` | 2 | 1 | Static preload, Pushover, Transient EQ | Example 3 elastic build with unit-scaled parameters |
|
||||
| `ex3_canti2d_inelastic_section.osmodel` | 2 | 1 | Static preload, Pushover, Transient EQ | Example 3 aggregated-section nonlinear build |
|
||||
| `ex3_canti2d_inelastic_fiber_section.osmodel` | 2 | 1 | Static preload, Pushover, Transient EQ | Example 3 fiber-section nonlinear build |
|
||||
| `ex4_portal2d_elastic_element.osmodel` | 4 | 3 | Static preload, Pushover, Transient sine | Example 4 elastic portal frame with separated build/analysis workflow |
|
||||
| `ex4_portal2d_inelastic_section.osmodel` | 4 | 3 | Static preload, Pushover, Transient sine | Example 4 aggregated-section portal frame variant |
|
||||
| `ex4_portal2d_inelastic_fiber_section.osmodel` | 4 | 3 | Static preload, Pushover, Transient sine | Example 4 fiber-section portal frame variant |
|
||||
| `ex1a_canti2d_eq.osmodel` | 2 | 1 | Static preload, Transient EQ | OpenSees Ex 1a style gravity + base excitation workflow |
|
||||
| `eigen_two_storey_shear_frame.osmodel` | 6 | 6 | Modal | equalDOF floor constraints, mode shapes, eigenvalue workflow |
|
||||
| `eigen_two_storey_one_bay_frame.osmodel` | 6 | 6 | Modal | classic elastic frame modal example, sway mode shapes |
|
||||
| `concrete04_cantilever.osmodel` | 2 | 1 | Static (gravity), Pushover | Popovics Concrete04 fiber section; proof-of-concept for the Concrete04 end-to-end stack |
|
||||
| `portal_pushover.osmodel` | 4 | 3 | Pushover, Modal | Fiber sections, BeamWithHinges, yielding pushover |
|
||||
| `ex1a_canti2d.osmodel` | 2 | 1 | Static preload, Pushover, Transient EQ | OpenSees Ex 1a, shared gravity + push + quake |
|
||||
| `ex1b_portal2d.osmodel` | 4 | 3 | Static preload, Pushover, Transient EQ | OpenSees Ex 1b elastic portal, distributed gravity |
|
||||
| `ex2a_canti2d_elastic_element.osmodel` | 2 | 1 | Static preload, Pushover, Transient EQ | Ex 2a cantilever, dimensions as named parameters |
|
||||
| `ex2b_canti2d_inelastic_section.osmodel` | 2 | 1 | Static preload, Pushover, Transient EQ | Ex 2b, aggregated axial+flexure section |
|
||||
| `ex2c_canti2d_inelastic_fiber_section.osmodel` | 2 | 1 | Static preload, Pushover, Transient EQ | Ex 2c, fiber section, coupled axial-flexure |
|
||||
| `ex3_canti2d_elastic_element.osmodel` | 2 | 1 | Static preload, Pushover, Transient EQ | Ex 3 elastic build, unit-scaled parameters |
|
||||
| `ex3_canti2d_inelastic_section.osmodel` | 2 | 1 | Static preload, Pushover, Transient EQ | Ex 3 aggregated-section build |
|
||||
| `ex3_canti2d_inelastic_fiber_section.osmodel` | 2 | 1 | Static preload, Pushover, Transient EQ | Ex 3 fiber-section build |
|
||||
| `ex4_portal2d_elastic_element.osmodel` | 4 | 3 | Static preload, Pushover, Transient sine | Ex 4 elastic portal, build/analysis split |
|
||||
| `ex4_portal2d_inelastic_section.osmodel` | 4 | 3 | Static preload, Pushover, Transient sine | Ex 4 aggregated-section portal |
|
||||
| `ex4_portal2d_inelastic_fiber_section.osmodel` | 4 | 3 | Static preload, Pushover, Transient sine | Ex 4 fiber-section portal |
|
||||
| `ex1a_canti2d_eq.osmodel` | 2 | 1 | Static preload, Transient EQ | Ex 1a gravity + base excitation only |
|
||||
| `eigen_two_storey_shear_frame.osmodel` | 6 | 6 | Modal | equalDOF floor constraints, shear-frame modes |
|
||||
| `eigen_two_storey_one_bay_frame.osmodel` | 6 | 6 | Modal | Chopra 10.5 frame, sway modes, no constraints |
|
||||
| `concrete04_cantilever.osmodel` | 2 | 1 | Static (gravity), Pushover | Concrete04 fiber section end-to-end |
|
||||
|
||||
## Quick tour
|
||||
|
||||
|
|
@ -38,37 +38,36 @@ File → Open → cantilever.osmodel
|
|||
Analyze → Cases → run "Tip-Load"
|
||||
Display → Show Force Diagram → component "M3" → linear moment, max at fixed end (50 kN·m)
|
||||
→ component "V2" → constant -10 kN along the whole span
|
||||
→ component "N" → ~zero (no axial load applied)
|
||||
→ component "N" → ~zero (no axial load)
|
||||
→ component "T" → ~zero (no torsion → console hint, no diagram)
|
||||
Display → Show Deformed Shape → classic cantilever curve
|
||||
Display → Show Deformed Shape → cantilever curve
|
||||
```
|
||||
The load is applied along the global Y axis (perpendicular to the beam,
|
||||
in the horizontal plane). With the default 3D vertical-reference
|
||||
convention this gives V2 / M3 — i.e. the "in-plane bending" pair.
|
||||
Load runs along global Y (perpendicular to the beam, horizontal plane).
|
||||
With the default 3D vertical-reference convention that lands on the
|
||||
V2 / M3 pair — the in-plane bending pair.
|
||||
|
||||
**Distributed load (UDL) variant** — run the second case to see a
|
||||
parabolic moment diagram:
|
||||
UDL variant, parabolic moment:
|
||||
```
|
||||
Analyze → Cases → run "Uniform-Load"
|
||||
Display → Show Force Diagram → M3 → parabolic, max 25 kN·m at fixed end
|
||||
→ V2 → linear, max 10 kN at fixed end
|
||||
```
|
||||
|
||||
### 2. Mode shapes — `portal_frame.osmodel` or `space_frame_3d.osmodel`
|
||||
### 2. Mode shapes — `space_frame_3d.osmodel`
|
||||
```
|
||||
File → Open → space_frame_3d.osmodel
|
||||
Analyze → Cases → run "Modal-6"
|
||||
Display → Animate Mode Shape → mode 1 = X-sway, mode 2 = Y-sway
|
||||
→ ▶ Play, scrub timeline, change scale
|
||||
→ Play, scrub timeline, change scale
|
||||
```
|
||||
|
||||
### 3. Time-history & hysteresis — `portal_frame.osmodel` or `space_frame_3d.osmodel`
|
||||
### 3. Time-history and hysteresis — `space_frame_3d.osmodel`
|
||||
```
|
||||
File → Open → space_frame_3d.osmodel
|
||||
Analyze → Cases → run "EQ-4s" (~5-10 sec on a modern laptop)
|
||||
Display → Time-History Plot
|
||||
- Node 12 (roof corner) + DOF 1 (X displacement) → "Add trace"
|
||||
- Node 9 + DOF 1 → another trace, compare phase
|
||||
- Node 9 + DOF 1 → second trace, compare phase
|
||||
Display → Hysteresis Plot
|
||||
- X = Node 12 / DOF 1, Y = Node 12 / DOF 3 → orbit
|
||||
```
|
||||
|
|
@ -78,137 +77,129 @@ Display → Hysteresis Plot
|
|||
File → Open → sdof_pushover.osmodel
|
||||
Analyze → Cases → run "Push-X"
|
||||
Display → Show Pushover Curve
|
||||
→ linear segment from origin, then softens through yield
|
||||
→ linear from origin, then softens through yield
|
||||
```
|
||||
Note: this demo keeps the column elastic (proper nonlinear hinges require
|
||||
BeamWithHingesElement with fibre sections — infrastructure is in place,
|
||||
fibre-section editor is future work).
|
||||
Column stays elastic here. Real nonlinear hinges need
|
||||
BeamWithHinges + fiber sections; the machinery exists, the
|
||||
fiber-section editor is still rough.
|
||||
|
||||
### 5. Nonlinear pushover with fiber hinges — `portal_pushover.osmodel`
|
||||
```
|
||||
File → Open → portal_pushover.osmodel
|
||||
Analyze → Cases → run "Push-X"
|
||||
Display → Show Pushover Curve
|
||||
→ initial linear stiffness, then yield plateau as base hinges form
|
||||
→ peak base shear corresponds to concrete crushing + rebar yield
|
||||
→ linear stiffness, then yield plateau as base hinges form
|
||||
→ peak base shear = concrete crushing + rebar yield
|
||||
```
|
||||
The columns use BeamWithHingesElements with FiberSections (concrete core
|
||||
+ rebar layers) wrapped in a SectionAggregator (torsion spring).
|
||||
Columns are BeamWithHinges + FiberSections (concrete core, rebar
|
||||
layers) wrapped in a SectionAggregator for torsion.
|
||||
|
||||
### 6. Gravity + time-history chain — `ex1a_canti2d_eq.osmodel`
|
||||
```bash
|
||||
```
|
||||
File → Open → ex1a_canti2d_eq.osmodel
|
||||
Analyze → Cases → run "Earthquake"
|
||||
Display → Time-History Plot
|
||||
- Node 2 + DOF 1 (Ux) → horizontal response of the cantilever tip
|
||||
- Node 2 + DOF 2 (Uy) → verify gravity stays essentially locked
|
||||
- Node 2 + DOF 1 (Ux) → tip horizontal response
|
||||
- Node 2 + DOF 2 (Uy) → gravity should stay locked
|
||||
```
|
||||
This model is intentionally tiny but important for workflow coverage:
|
||||
it demonstrates the general transient recipe of
|
||||
`Static preload → loadConst reset → UniformExcitation transient`
|
||||
using a real ground-motion record imported into a `PathTimeSeries`.
|
||||
Tiny model, exists for one reason: the standard transient recipe
|
||||
`static preload → loadConst reset → UniformExcitation transient`
|
||||
against a real ground-motion record in a `PathTimeSeries`.
|
||||
|
||||
### 7. Original OpenSees Ex 1a bundle — `ex1a_canti2d.osmodel`
|
||||
```bash
|
||||
### 7. OpenSees Ex 1a bundle — `ex1a_canti2d.osmodel`
|
||||
```
|
||||
File → Open → ex1a_canti2d.osmodel
|
||||
Analyze → Cases → run "Push" or "Earthquake"
|
||||
Display → Show Pushover Curve / Time-History Plot
|
||||
```
|
||||
This is the original cantilever-column Example 1a packaged as one model
|
||||
with a shared gravity preload plus both lateral load variants. It is a
|
||||
good small benchmark for checking that pushover and transient workflows
|
||||
behave consistently on the same geometry.
|
||||
Cantilever column with shared gravity preload and both lateral
|
||||
variants. Small benchmark for checking pushover and transient agree
|
||||
on the same geometry.
|
||||
|
||||
### 8. Original OpenSees Ex 1b bundle — `ex1b_portal2d.osmodel`
|
||||
```bash
|
||||
### 8. OpenSees Ex 1b bundle — `ex1b_portal2d.osmodel`
|
||||
```
|
||||
File → Open → ex1b_portal2d.osmodel
|
||||
Analyze → Cases → run "Push" or "Earthquake"
|
||||
Display → Show Pushover Curve / Time-History Plot
|
||||
```
|
||||
This is the original elastic portal-frame Example 1b bundled as one
|
||||
project. It is especially useful because the gravity preload is carried
|
||||
by a distributed beam load instead of nodal loads only.
|
||||
Elastic portal frame. Gravity comes from a distributed beam load
|
||||
instead of nodal loads, which is the whole point of keeping it
|
||||
around.
|
||||
|
||||
### 9. Variable-driven cantilever example — `ex2a_canti2d_elastic_element.osmodel`
|
||||
```bash
|
||||
### 9. Ex 2a, parameter-driven — `ex2a_canti2d_elastic_element.osmodel`
|
||||
```
|
||||
File → Open → ex2a_canti2d_elastic_element.osmodel
|
||||
Analyze → Cases → run "Push" or "Earthquake"
|
||||
Display → Show Pushover Curve / Time-History Plot
|
||||
```
|
||||
This is the Ex2a cantilever tutorial recast as a project model. It is
|
||||
useful when we want the same basic physics as Ex1a but with all major
|
||||
dimensions and derived quantities exposed as named parameters.
|
||||
Same physics as Ex 1a, but dimensions and derived quantities are
|
||||
named parameters instead of literals.
|
||||
|
||||
### 10. Nonlinear aggregated-section cantilever — `ex2b_canti2d_inelastic_section.osmodel`
|
||||
```bash
|
||||
### 10. Ex 2b, aggregated section — `ex2b_canti2d_inelastic_section.osmodel`
|
||||
```
|
||||
File → Open → ex2b_canti2d_inelastic_section.osmodel
|
||||
Analyze → Cases → run "Push" or "Earthquake"
|
||||
Display → Show Pushover Curve / Time-History Plot
|
||||
```
|
||||
This is the first nonlinear cantilever benchmark in the tutorial series.
|
||||
It demonstrates how separate axial and flexural uniaxial responses can
|
||||
be aggregated into one section and used by a force-based beam-column element.
|
||||
First nonlinear cantilever in the series. Separate axial and flexural
|
||||
uniaxial responses aggregated into one section on a force-based
|
||||
beam-column.
|
||||
|
||||
### 11. Fiber-section cantilever example — `ex2c_canti2d_inelastic_fiber_section.osmodel`
|
||||
```bash
|
||||
### 11. Ex 2c, fiber section — `ex2c_canti2d_inelastic_fiber_section.osmodel`
|
||||
```
|
||||
File → Open → ex2c_canti2d_inelastic_fiber_section.osmodel
|
||||
Analyze → Cases → run "Push" or "Earthquake"
|
||||
Display → Show Pushover Curve / Time-History Plot
|
||||
```
|
||||
This is the Ex2c fiber-section counterpart to Ex2b. It is useful for
|
||||
checking coupled axial-flexural section behavior with inelastic concrete
|
||||
and steel materials assigned directly to fibers and rebar layers.
|
||||
Ex 2b's fiber counterpart. Coupled axial-flexure with concrete and
|
||||
steel assigned to fibers and rebar layers directly.
|
||||
|
||||
### 12. Example 3 build variants — `ex3_canti2d_*.osmodel`
|
||||
```bash
|
||||
### 12. Ex 3 family — `ex3_canti2d_*.osmodel`
|
||||
```
|
||||
File → Open → ex3_canti2d_elastic_element.osmodel
|
||||
Analyze → Cases → run "Push" or "Earthquake"
|
||||
```
|
||||
The Example 3 family is useful when we want the same cantilever analyses
|
||||
to run on three different build styles: elastic element, aggregated
|
||||
uniaxial section, and fiber section, all with unit-scaled parameters.
|
||||
Same cantilever analyses on three build styles: elastic element,
|
||||
aggregated uniaxial section, fiber section. All unit-scaled.
|
||||
|
||||
### 13. Modal shear-building example — `eigen_two_storey_shear_frame.osmodel`
|
||||
```bash
|
||||
### 13. Modal shear building — `eigen_two_storey_shear_frame.osmodel`
|
||||
```
|
||||
File → Open → eigen_two_storey_shear_frame.osmodel
|
||||
Analyze → Cases → run "Modal-2"
|
||||
Display → Animate Mode Shape
|
||||
- mode 1 → in-phase storey sway
|
||||
- mode 2 → out-of-phase storey sway
|
||||
- mode 1 → stories sway in phase
|
||||
- mode 2 → stories sway out of phase
|
||||
```
|
||||
This example is useful for validating modal workflows on a tiny model
|
||||
that still needs multi-point constraints (`equalDOF`) to behave like an
|
||||
idealized shear frame.
|
||||
Validates modal workflows on a model small enough to check by hand,
|
||||
with `equalDOF` doing the shear-frame duty.
|
||||
|
||||
### 9. Modal elastic frame example — `eigen_two_storey_one_bay_frame.osmodel`
|
||||
```bash
|
||||
File → Open → eigen_two_storey_one_bay_frame.osmodel
|
||||
Analyze → Cases → run "Modal-2"
|
||||
Display → Animate Mode Shape
|
||||
- mode 1 → in-phase sway of the two storeys
|
||||
- mode 2 → upper storey reverses relative to the first storey
|
||||
### 14. Modal frame, Chopra 10.5 — `eigen_two_storey_one_bay_frame.osmodel`
|
||||
```
|
||||
This is the Chopra Example 10.5 frame counterpart to the shear-building
|
||||
example above. It gives us a small modal benchmark with ordinary
|
||||
beam-column frame behavior and no multi-point constraints.
|
||||
File → Open → eigen_two_storey_one_bay_frame.osmodel
|
||||
Analyze → Cases → run "Modal-2"
|
||||
Display → Animate Mode Shape
|
||||
- mode 1 → in-phase sway of both stories
|
||||
- mode 2 → top story reverses against the first
|
||||
```
|
||||
Companion to the shear building above. Ordinary beam-column behavior,
|
||||
no multi-point constraints.
|
||||
|
||||
### 13. Example 4 portal-frame variants
|
||||
```bash
|
||||
File -> Open -> ex4_portal2d_elastic_element.osmodel
|
||||
Analyze -> Cases -> run "Push" or "Sine-Uniform"
|
||||
Display -> Show Pushover Curve / Time-History Plot
|
||||
### 15. Ex 4 portal family — `ex4_portal2d_*.osmodel`
|
||||
```
|
||||
The Example 4 family keeps the OpenSees split between model-building
|
||||
and analysis files, but moves it into project variants. These are
|
||||
useful benchmarks for pinned-base frame sway, distributed gravity on the
|
||||
beam, and support-motion dynamics without depending on an external
|
||||
earthquake file. The fiber-section transient is intentionally retained
|
||||
as a strong nonlinear stress test and may stop early while still
|
||||
producing useful partial histories.
|
||||
File → Open → ex4_portal2d_elastic_element.osmodel
|
||||
Analyze → Cases → run "Push" or "Sine-Uniform"
|
||||
Display → Show Pushover Curve / Time-History Plot
|
||||
```
|
||||
Keeps the OpenSees split between model-building and analysis files,
|
||||
recast as project variants. Covers pinned-base sway, distributed
|
||||
girder gravity, and support-motion dynamics without an external quake
|
||||
file. The fiber transient is kept as a nonlinear stress test — it may
|
||||
stop early and still produce usable partial histories.
|
||||
|
||||
## Regenerating the .osmodel files
|
||||
|
||||
If you change the Python scripts, run them to regenerate the saved models:
|
||||
Scripts are the source of truth, `.osmodel` files are build artifacts
|
||||
checked in for convenience. Change a script, rerun it:
|
||||
|
||||
```bash
|
||||
python examples/cantilever.py
|
||||
|
|
@ -232,6 +223,5 @@ python examples/eigen_two_storey_shear_frame.py
|
|||
python examples/eigen_two_storey_one_bay_frame.py
|
||||
```
|
||||
|
||||
Each script builds the project, saves it, reloads it, and asserts a clean
|
||||
round-trip. The Python source is the source of truth; the `.osmodel` files
|
||||
are generated artifacts checked in for convenience.
|
||||
Each script builds the project, saves it, reloads it, and asserts a
|
||||
clean round-trip.
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
OpenSees Wiki:
|
||||
https://opensees.berkeley.edu/wiki/index.php?title=OpenSees_Example_1b._Elastic_Portal_Frame
|
||||
|
||||
This packages the original Example 1b portal frame into one OpenSees
|
||||
Studio project with shared gravity preload and both lateral-load cases:
|
||||
This packages the original Example 1b portal frame into one OTKO
|
||||
project with shared gravity preload and both lateral-load cases:
|
||||
|
||||
- static pushover
|
||||
- base-excitation earthquake analysis with ``BM68elc.acc``
|
||||
|
|
|
|||
|
|
@ -1,25 +1,24 @@
|
|||
# core/catalog — GiD schema catalog
|
||||
|
||||
This package contains **auto-generated Pydantic v2 schema descriptions** for
|
||||
all OpenSees materials and conditions defined in the
|
||||
Auto-generated Pydantic v2 schema descriptions for every OpenSees
|
||||
material and condition in the
|
||||
[gidopensees](https://github.com/rclab-auth/gidopensees) GiD preprocessor.
|
||||
|
||||
## Public import surface
|
||||
## Use
|
||||
|
||||
```python
|
||||
from otko.core.catalog import CATALOG
|
||||
|
||||
# Look up a Spec class by its gidopensees name
|
||||
Steel02Spec = CATALOG["Steel02"]
|
||||
spec = Steel02Spec() # instantiate with defaults
|
||||
spec = Steel02Spec() # defaults
|
||||
spec.model_dump_json() # serialize
|
||||
```
|
||||
|
||||
`CATALOG` is a `dict[str, type[BaseModel]]` mapping every material's
|
||||
gidopensees name (e.g. `"Steel02"`) to its generated `Spec` class.
|
||||
It contains exactly 58 entries (one per material in `OpenSees.mat`).
|
||||
`CATALOG` maps each material's gidopensees name (e.g. `"Steel02"`) to its
|
||||
generated `Spec` class. 58 entries, one per material in `OpenSees.mat`.
|
||||
|
||||
Per-book discriminated Union types are available in `generated/__init__.py`:
|
||||
Per-book discriminated unions live in `generated/__init__.py`:
|
||||
|
||||
```python
|
||||
from otko.core.catalog.generated import UniaxialSteelMaterials
|
||||
|
|
@ -29,7 +28,7 @@ Condition specs live under `generated/conditions/`.
|
|||
|
||||
## Regenerating
|
||||
|
||||
Run the codegen tool any time the upstream `schemas.json` changes:
|
||||
When upstream `schemas.json` changes, rerun codegen:
|
||||
|
||||
```bash
|
||||
python -m tools.gidopensees_import.codegen \
|
||||
|
|
@ -39,17 +38,15 @@ python -m tools.gidopensees_import.codegen \
|
|||
|
||||
## Do not hand-edit `generated/`
|
||||
|
||||
Files under `generated/` are overwritten on each codegen run.
|
||||
Hand-curated overrides, corrections, or extensions belong in
|
||||
`curated/` (currently empty — reserved for future use).
|
||||
Codegen overwrites it. Put overrides, corrections, and extensions in
|
||||
`curated/` (empty for now, reserved).
|
||||
|
||||
## Scope note
|
||||
|
||||
Catalog Spec classes are **schema descriptions only**. They capture the
|
||||
field names, types, defaults, and UI metadata from the gidopensees
|
||||
definition files. They are **not yet wired into the OpenSees runtime**.
|
||||
The mapping from a `Spec` to an actual `uniaxialMaterial` call is a
|
||||
future deliverable tracked in the ADR.
|
||||
Spec classes are schema descriptions: field names, types, defaults, UI
|
||||
metadata from the gidopensees definition files. They are not wired into
|
||||
the runtime. Mapping a `Spec` to an actual `uniaxialMaterial` call is
|
||||
still open — see the ADR.
|
||||
|
||||
## Attribution
|
||||
|
||||
|
|
@ -57,7 +54,6 @@ Schema data from [gidopensees](https://github.com/rclab-auth/gidopensees),
|
|||
Copyright (C) Reinforced Concrete Laboratory, Aristotle University of
|
||||
Thessaloniki (AUTh).
|
||||
|
||||
`CATALOG` exposes the 58 material specs only; condition specs are intentionally
|
||||
kept in a separate namespace (`generated/conditions/`, 39 specs) so that
|
||||
material and boundary-condition objects remain independently importable and
|
||||
do not pollute each other's namespace.
|
||||
`CATALOG` holds the 58 material specs. Condition specs stay in their own
|
||||
namespace (`generated/conditions/`, 39 specs) so the two don't pollute
|
||||
each other.
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ class OpenSeesAnalysisRunner(OpenSeesEmitter):
|
|||
if isinstance(case, ResponseSpectrumCase):
|
||||
return self._run_response_spectrum(case)
|
||||
if isinstance(case, TransientCase):
|
||||
target = results_dir or Path(tempfile.mkdtemp(prefix="osstudio_"))
|
||||
target = results_dir or Path(tempfile.mkdtemp(prefix="otko_"))
|
||||
return self._run_transient(case, target)
|
||||
raise TypeError(f"Unsupported analysis case type: {type(case).__name__}")
|
||||
|
||||
|
|
|
|||
|
|
@ -363,7 +363,7 @@ def export_opspy(project: Project, case_id: int | None = None) -> str:
|
|||
|
||||
Returns:
|
||||
The script source. The header pins ``openseespy==3.5.1.12``,
|
||||
the Studio version and the display units.
|
||||
the OTKO version and the display units.
|
||||
|
||||
Raises:
|
||||
ValueError: If ``case_id`` matches no analysis case.
|
||||
|
|
|
|||
Loading…
Reference in a new issue