timoshenko-engine 2.0.1__tar.gz → 2.0.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- timoshenko_engine-2.0.2/PKG-INFO +234 -0
- timoshenko_engine-2.0.2/README.md +201 -0
- {timoshenko_engine-2.0.1 → timoshenko_engine-2.0.2}/pyproject.toml +2 -1
- {timoshenko_engine-2.0.1 → timoshenko_engine-2.0.2}/src/timoshenko/__init__.py +1 -1
- timoshenko_engine-2.0.2/src/timoshenko_engine.egg-info/PKG-INFO +234 -0
- {timoshenko_engine-2.0.1 → timoshenko_engine-2.0.2}/tests/test_package.py +20 -0
- {timoshenko_engine-2.0.1 → timoshenko_engine-2.0.2}/tests/test_project_report.py +16 -1
- timoshenko_engine-2.0.1/PKG-INFO +0 -237
- timoshenko_engine-2.0.1/README.md +0 -205
- timoshenko_engine-2.0.1/src/timoshenko_engine.egg-info/PKG-INFO +0 -237
- {timoshenko_engine-2.0.1 → timoshenko_engine-2.0.2}/LICENSE +0 -0
- {timoshenko_engine-2.0.1 → timoshenko_engine-2.0.2}/setup.cfg +0 -0
- {timoshenko_engine-2.0.1 → timoshenko_engine-2.0.2}/src/timoshenko/_validation.py +0 -0
- {timoshenko_engine-2.0.1 → timoshenko_engine-2.0.2}/src/timoshenko/adapters.py +0 -0
- {timoshenko_engine-2.0.1 → timoshenko_engine-2.0.2}/src/timoshenko/assets.py +0 -0
- {timoshenko_engine-2.0.1 → timoshenko_engine-2.0.2}/src/timoshenko/beams.py +0 -0
- {timoshenko_engine-2.0.1 → timoshenko_engine-2.0.2}/src/timoshenko/csv_source.py +0 -0
- {timoshenko_engine-2.0.1 → timoshenko_engine-2.0.2}/src/timoshenko/health.py +0 -0
- {timoshenko_engine-2.0.1 → timoshenko_engine-2.0.2}/src/timoshenko/mechanics.py +0 -0
- {timoshenko_engine-2.0.1 → timoshenko_engine-2.0.2}/src/timoshenko/modal.py +0 -0
- {timoshenko_engine-2.0.1 → timoshenko_engine-2.0.2}/src/timoshenko/monitor.py +0 -0
- {timoshenko_engine-2.0.1 → timoshenko_engine-2.0.2}/src/timoshenko/mqtt.py +0 -0
- {timoshenko_engine-2.0.1 → timoshenko_engine-2.0.2}/src/timoshenko/multichannel.py +0 -0
- {timoshenko_engine-2.0.1 → timoshenko_engine-2.0.2}/src/timoshenko/observations.py +0 -0
- {timoshenko_engine-2.0.1 → timoshenko_engine-2.0.2}/src/timoshenko/oma.py +0 -0
- {timoshenko_engine-2.0.1 → timoshenko_engine-2.0.2}/src/timoshenko/plugins.py +0 -0
- {timoshenko_engine-2.0.1 → timoshenko_engine-2.0.2}/src/timoshenko/polygon.py +0 -0
- {timoshenko_engine-2.0.1 → timoshenko_engine-2.0.2}/src/timoshenko/pressure.py +0 -0
- {timoshenko_engine-2.0.1 → timoshenko_engine-2.0.2}/src/timoshenko/project.py +0 -0
- {timoshenko_engine-2.0.1 → timoshenko_engine-2.0.2}/src/timoshenko/report.py +0 -0
- {timoshenko_engine-2.0.1 → timoshenko_engine-2.0.2}/src/timoshenko/sections.py +0 -0
- {timoshenko_engine-2.0.1 → timoshenko_engine-2.0.2}/src/timoshenko/sensors.py +0 -0
- {timoshenko_engine-2.0.1 → timoshenko_engine-2.0.2}/src/timoshenko/sensorthings.py +0 -0
- {timoshenko_engine-2.0.1 → timoshenko_engine-2.0.2}/src/timoshenko/session.py +0 -0
- {timoshenko_engine-2.0.1 → timoshenko_engine-2.0.2}/src/timoshenko/shafts.py +0 -0
- {timoshenko_engine-2.0.1 → timoshenko_engine-2.0.2}/src/timoshenko/stability.py +0 -0
- {timoshenko_engine-2.0.1 → timoshenko_engine-2.0.2}/src/timoshenko/storage.py +0 -0
- {timoshenko_engine-2.0.1 → timoshenko_engine-2.0.2}/src/timoshenko/strength.py +0 -0
- {timoshenko_engine-2.0.1 → timoshenko_engine-2.0.2}/src/timoshenko/structure.py +0 -0
- {timoshenko_engine-2.0.1 → timoshenko_engine-2.0.2}/src/timoshenko/uncertainty.py +0 -0
- {timoshenko_engine-2.0.1 → timoshenko_engine-2.0.2}/src/timoshenko/update.py +0 -0
- {timoshenko_engine-2.0.1 → timoshenko_engine-2.0.2}/src/timoshenko/vibration.py +0 -0
- {timoshenko_engine-2.0.1 → timoshenko_engine-2.0.2}/src/timoshenko_engine.egg-info/SOURCES.txt +0 -0
- {timoshenko_engine-2.0.1 → timoshenko_engine-2.0.2}/src/timoshenko_engine.egg-info/dependency_links.txt +0 -0
- {timoshenko_engine-2.0.1 → timoshenko_engine-2.0.2}/src/timoshenko_engine.egg-info/entry_points.txt +0 -0
- {timoshenko_engine-2.0.1 → timoshenko_engine-2.0.2}/src/timoshenko_engine.egg-info/requires.txt +0 -0
- {timoshenko_engine-2.0.1 → timoshenko_engine-2.0.2}/src/timoshenko_engine.egg-info/top_level.txt +0 -0
- {timoshenko_engine-2.0.1 → timoshenko_engine-2.0.2}/tests/test_adapters.py +0 -0
- {timoshenko_engine-2.0.1 → timoshenko_engine-2.0.2}/tests/test_formulas.py +0 -0
- {timoshenko_engine-2.0.1 → timoshenko_engine-2.0.2}/tests/test_modal.py +0 -0
- {timoshenko_engine-2.0.1 → timoshenko_engine-2.0.2}/tests/test_polygon.py +0 -0
- {timoshenko_engine-2.0.1 → timoshenko_engine-2.0.2}/tests/test_storage_session.py +0 -0
- {timoshenko_engine-2.0.1 → timoshenko_engine-2.0.2}/tests/test_uncertainty.py +0 -0
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: timoshenko-engine
|
|
3
|
+
Version: 2.0.2
|
|
4
|
+
Summary: Composable structural engineering calculations and analysis primitives for Python applications.
|
|
5
|
+
Author: Ayberk Korkmaz
|
|
6
|
+
License-Expression: Apache-2.0
|
|
7
|
+
Project-URL: Homepage, https://github.com/Ayberkrk/timoshenko
|
|
8
|
+
Project-URL: Repository, https://github.com/Ayberkrk/timoshenko
|
|
9
|
+
Project-URL: Issues, https://github.com/Ayberkrk/timoshenko/issues
|
|
10
|
+
Project-URL: Documentation, https://github.com/Ayberkrk/timoshenko/tree/main/docs
|
|
11
|
+
Project-URL: Changelog, https://github.com/Ayberkrk/timoshenko/blob/main/docs/changelog.md
|
|
12
|
+
Keywords: civil engineering,structural engineering,structural health monitoring,modal analysis,digital twin
|
|
13
|
+
Classifier: Development Status :: 3 - Alpha
|
|
14
|
+
Classifier: Intended Audience :: Science/Research
|
|
15
|
+
Classifier: Intended Audience :: Developers
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
21
|
+
Classifier: Topic :: Scientific/Engineering
|
|
22
|
+
Requires-Python: >=3.10
|
|
23
|
+
Description-Content-Type: text/markdown
|
|
24
|
+
License-File: LICENSE
|
|
25
|
+
Requires-Dist: numpy>=1.24
|
|
26
|
+
Provides-Extra: mqtt
|
|
27
|
+
Requires-Dist: paho-mqtt<3,>=2.1; extra == "mqtt"
|
|
28
|
+
Provides-Extra: test
|
|
29
|
+
Requires-Dist: pytest>=7; extra == "test"
|
|
30
|
+
Provides-Extra: docs
|
|
31
|
+
Requires-Dist: mkdocs-material<10,>=9.5; extra == "docs"
|
|
32
|
+
Dynamic: license-file
|
|
33
|
+
|
|
34
|
+
<p align="center">
|
|
35
|
+
<img src="https://raw.githubusercontent.com/Ayberkrk/timoshenko/main/assets/timoshenko-logo.png" alt="Timoshenko Engine logo" width="920">
|
|
36
|
+
</p>
|
|
37
|
+
|
|
38
|
+
<h1 align="center">Timoshenko Engine</h1>
|
|
39
|
+
|
|
40
|
+
<p align="center">
|
|
41
|
+
Reusable structural engineering building blocks for Python applications.
|
|
42
|
+
</p>
|
|
43
|
+
|
|
44
|
+
<p align="center">
|
|
45
|
+
<a href="https://pypi.org/project/timoshenko-engine/"><img alt="PyPI" src="https://img.shields.io/pypi/v/timoshenko-engine?style=for-the-badge"></a>
|
|
46
|
+
<img alt="Python versions" src="https://img.shields.io/pypi/pyversions/timoshenko-engine?style=for-the-badge">
|
|
47
|
+
<img alt="Alpha" src="https://img.shields.io/badge/stage-alpha-orange?style=for-the-badge">
|
|
48
|
+
<img alt="Apache 2.0 license" src="https://img.shields.io/badge/license-Apache--2.0-green?style=for-the-badge">
|
|
49
|
+
<a href="https://github.com/Ayberkrk/timoshenko/actions/workflows/tests.yml"><img alt="Tests" src="https://github.com/Ayberkrk/timoshenko/actions/workflows/tests.yml/badge.svg"></a>
|
|
50
|
+
</p>
|
|
51
|
+
|
|
52
|
+
Timoshenko packages common structural calculations, modal analysis, sensor
|
|
53
|
+
workflows, and monitoring components so applications can reuse them instead
|
|
54
|
+
of rebuilding the same foundations for every project. It is an embeddable
|
|
55
|
+
Python library, not a hosted monitoring service or a general finite-element
|
|
56
|
+
solver.
|
|
57
|
+
|
|
58
|
+
> **Alpha:** the API may still change between releases. Every behavior change
|
|
59
|
+
> is listed in the [changelog](https://github.com/Ayberkrk/timoshenko/blob/main/docs/changelog.md).
|
|
60
|
+
|
|
61
|
+
## Install
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
python -m pip install timoshenko-engine
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
The distribution is named `timoshenko-engine`; the import package is
|
|
68
|
+
`timoshenko`. Optional MQTT support is an extra:
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
python -m pip install "timoshenko-engine[mqtt]"
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Quick start
|
|
75
|
+
|
|
76
|
+
Compare measured vibration with a reference model. This example simulates a
|
|
77
|
+
record in which both modes are 5% below the model:
|
|
78
|
+
|
|
79
|
+
```python
|
|
80
|
+
import numpy as np
|
|
81
|
+
import timoshenko as tm
|
|
82
|
+
|
|
83
|
+
structure = tm.Structure(
|
|
84
|
+
structure_id="building-01",
|
|
85
|
+
story_masses_kg=[120_000.0, 110_000.0],
|
|
86
|
+
story_stiffness_n_m=[85_000_000.0, 70_000_000.0],
|
|
87
|
+
)
|
|
88
|
+
print(structure.natural_frequencies_hz) # (2.626, 6.476)
|
|
89
|
+
|
|
90
|
+
fs = 100.0
|
|
91
|
+
t = np.arange(60_000) / fs
|
|
92
|
+
f1, f2 = (0.95 * f for f in structure.natural_frequencies_hz)
|
|
93
|
+
signal = np.sin(2 * np.pi * f1 * t) + 0.4 * np.sin(2 * np.pi * f2 * t)
|
|
94
|
+
sensors = tm.SensorData(signal, sampling_hz=fs, unit="m/s^2")
|
|
95
|
+
|
|
96
|
+
result = tm.monitor(structure, sensors, review_threshold_pct=3.0)
|
|
97
|
+
print(result.structure.update_scale_factor) # 0.903, since stiffness scales with frequency squared
|
|
98
|
+
for change in result.health.mode_changes:
|
|
99
|
+
print(change.mode_number, change.change_pct) # 1 -5.0, then 2 -5.0
|
|
100
|
+
print(result.health.review_recommended) # True
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Real records load from CSV or JSON with
|
|
104
|
+
`tm.load_sensors("acceleration.csv", sampling_hz=100.0, column="acc")`. The
|
|
105
|
+
steps inside `tm.monitor` are also available separately as `tm.modal.identify`,
|
|
106
|
+
`tm.update`, and `tm.health.assess`. The review flag is raised only when you
|
|
107
|
+
pass a threshold: a meaningful value depends on the structure and its
|
|
108
|
+
environmental variability, so the engine does not choose one.
|
|
109
|
+
|
|
110
|
+
## Engineering calculations
|
|
111
|
+
|
|
112
|
+
Closed-form functions take and return SI units and validate their inputs:
|
|
113
|
+
|
|
114
|
+
```python
|
|
115
|
+
import timoshenko as tm
|
|
116
|
+
|
|
117
|
+
section = tm.rectangle_section(width_m=0.3, height_m=0.6)
|
|
118
|
+
beam = tm.simply_supported_uniform_load(
|
|
119
|
+
20_000.0, 6.0, 30e9, section.second_moment_y_m4,
|
|
120
|
+
shear_modulus_pa=12.5e9, area_m2=section.area_m2,
|
|
121
|
+
)
|
|
122
|
+
print(beam.bending_m, beam.shear_m) # 2.083 mm bending, 0.048 mm shear
|
|
123
|
+
|
|
124
|
+
frequency = tm.propagate_uncertainty(
|
|
125
|
+
tm.natural_frequency_hz,
|
|
126
|
+
{"mass_kg": 250.0, "stiffness_n_m": 4e5},
|
|
127
|
+
standard_uncertainties={"mass_kg": 5.0, "stiffness_n_m": 8e3},
|
|
128
|
+
)
|
|
129
|
+
print(frequency.estimate, frequency.standard_uncertainty) # 6.366 Hz ± 0.090 Hz
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
## What it provides
|
|
133
|
+
|
|
134
|
+
| Area | Components |
|
|
135
|
+
|---|---|
|
|
136
|
+
| Engineering calculations | Section properties (including polygons with holes), beam deflection with shear, torsion, Euler buckling, plane stress, thin-wall pressure, SDOF vibration, Rayleigh damping, and GUM / Monte Carlo uncertainty |
|
|
137
|
+
| Structural models | Lumped-mass shear-building models and their natural frequencies |
|
|
138
|
+
| Modal analysis | Single-channel peak picking with resolution-checked damping, and multi-channel FDD with complex mode shapes |
|
|
139
|
+
| Model comparison | Nearest-frequency mode pairing, global stiffness updating, and evidence-oriented health assessment |
|
|
140
|
+
| Monitoring | Bounded rolling-window sessions, restart from local history, and source adapters for CSV, MQTT, and OGC SensorThings |
|
|
141
|
+
| Data and reporting | Project manifests with SHA-256 provenance, local SQLite history, and standalone HTML reports |
|
|
142
|
+
|
|
143
|
+
Sensor collection, alarm policy, and engineering interpretation remain with the
|
|
144
|
+
application that embeds Timoshenko.
|
|
145
|
+
|
|
146
|
+
## Multi-channel modal analysis
|
|
147
|
+
|
|
148
|
+
Frequency domain decomposition needs synchronized channels with a common
|
|
149
|
+
sample rate and unit:
|
|
150
|
+
|
|
151
|
+
```python
|
|
152
|
+
signals = tm.load_multichannel_csv(
|
|
153
|
+
"aligned_accelerometers.csv",
|
|
154
|
+
columns=["deck_left", "deck_center", "deck_right"],
|
|
155
|
+
sampling_hz=100.0,
|
|
156
|
+
units=["m/s^2"] * 3,
|
|
157
|
+
)
|
|
158
|
+
fdd = tm.identify_fdd(signals, nperseg=1024, max_modes=5)
|
|
159
|
+
for mode in fdd.modes:
|
|
160
|
+
print(mode.frequency_hz, mode.shape_real)
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
## Monitoring sessions
|
|
164
|
+
|
|
165
|
+
A host application feeds timestamped observation batches. The session aligns
|
|
166
|
+
samples to the sample grid, waits for a fresh contiguous window after gaps, and
|
|
167
|
+
analyzes every configured hop:
|
|
168
|
+
|
|
169
|
+
```python
|
|
170
|
+
session = tm.MonitoringSession(
|
|
171
|
+
structure,
|
|
172
|
+
sensor_ids=["deck-left", "deck-right"],
|
|
173
|
+
units=["m/s^2", "m/s^2"],
|
|
174
|
+
sampling_hz=100.0,
|
|
175
|
+
window_samples=2048,
|
|
176
|
+
hop_samples=512,
|
|
177
|
+
analysis_options={"nperseg": 512, "max_modes": 4},
|
|
178
|
+
review_threshold_pct=5.0,
|
|
179
|
+
)
|
|
180
|
+
result = session.ingest(batch) # batch: tm.ObservationBatch from your gateway or a source adapter
|
|
181
|
+
for report in result.reports:
|
|
182
|
+
tm.report.save_html(report, "reports/latest.html")
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
The session does not open network connections or run in the background. Use
|
|
186
|
+
`tm.SessionRunner` with a source such as `tm.CSVObservationSource` or
|
|
187
|
+
`tm.MqttObservationSource` to drive it.
|
|
188
|
+
|
|
189
|
+
## Documentation
|
|
190
|
+
|
|
191
|
+
- [Documentation home](https://github.com/Ayberkrk/timoshenko/blob/main/docs/index.md)
|
|
192
|
+
- [API reference](https://github.com/Ayberkrk/timoshenko/blob/main/docs/api.md)
|
|
193
|
+
- [Numerical methods and limits](https://github.com/Ayberkrk/timoshenko/blob/main/docs/numerical-methods.md)
|
|
194
|
+
- [Architecture](https://github.com/Ayberkrk/timoshenko/blob/main/docs/architecture.md)
|
|
195
|
+
- [Monitoring sessions](https://github.com/Ayberkrk/timoshenko/blob/main/docs/live-sessions.md) and [source adapters](https://github.com/Ayberkrk/timoshenko/blob/main/docs/adapters.md)
|
|
196
|
+
- [Runnable examples](https://github.com/Ayberkrk/timoshenko/tree/main/examples), including a [cross-check of PyNite shear-deformable beams](https://github.com/Ayberkrk/timoshenko/blob/main/docs/pynite-verification.md)
|
|
197
|
+
- [Changelog](https://github.com/Ayberkrk/timoshenko/blob/main/docs/changelog.md)
|
|
198
|
+
|
|
199
|
+
## Limits and engineering posture
|
|
200
|
+
|
|
201
|
+
- Timoshenko is alpha software and is not a structural safety certification tool.
|
|
202
|
+
- The shear-building model is a small lumped-mass reference model, not a full FEM solver.
|
|
203
|
+
- Modal identification is a screening estimate. A single sensor may miss a mode near a modal node; unpaired peaks are reported rather than compared with the wrong mode.
|
|
204
|
+
- Damping is a coarse screening estimate, reported only when the averaged spectrum resolves the half-power bandwidth. FDD does not estimate damping.
|
|
205
|
+
- The model update applies a single stiffness scale. It cannot locate or size local damage.
|
|
206
|
+
- A frequency shift is evidence for human review, not a damage verdict. Temperature, sensor placement, boundary conditions, and other effects also shift measured frequencies.
|
|
207
|
+
- Closed-form mechanics and section functions rely on their documented ideal assumptions. They are not code-compliance checks.
|
|
208
|
+
|
|
209
|
+
## Development
|
|
210
|
+
|
|
211
|
+
```bash
|
|
212
|
+
python -m pip install -e ".[test]"
|
|
213
|
+
python -m pytest
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
To preview the documentation site:
|
|
217
|
+
|
|
218
|
+
```bash
|
|
219
|
+
python -m pip install -e ".[docs]"
|
|
220
|
+
python -m mkdocs serve
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
Bug reports and pull requests are welcome in the
|
|
224
|
+
[issue tracker](https://github.com/Ayberkrk/timoshenko/issues).
|
|
225
|
+
|
|
226
|
+
## Citation
|
|
227
|
+
|
|
228
|
+
If you use Timoshenko in research, please cite it using the metadata in
|
|
229
|
+
[`CITATION.cff`](https://github.com/Ayberkrk/timoshenko/blob/main/CITATION.cff)
|
|
230
|
+
(GitHub's "Cite this repository" button reads the same file).
|
|
231
|
+
|
|
232
|
+
## License
|
|
233
|
+
|
|
234
|
+
Apache License 2.0. See [LICENSE](https://github.com/Ayberkrk/timoshenko/blob/main/LICENSE).
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="https://raw.githubusercontent.com/Ayberkrk/timoshenko/main/assets/timoshenko-logo.png" alt="Timoshenko Engine logo" width="920">
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
<h1 align="center">Timoshenko Engine</h1>
|
|
6
|
+
|
|
7
|
+
<p align="center">
|
|
8
|
+
Reusable structural engineering building blocks for Python applications.
|
|
9
|
+
</p>
|
|
10
|
+
|
|
11
|
+
<p align="center">
|
|
12
|
+
<a href="https://pypi.org/project/timoshenko-engine/"><img alt="PyPI" src="https://img.shields.io/pypi/v/timoshenko-engine?style=for-the-badge"></a>
|
|
13
|
+
<img alt="Python versions" src="https://img.shields.io/pypi/pyversions/timoshenko-engine?style=for-the-badge">
|
|
14
|
+
<img alt="Alpha" src="https://img.shields.io/badge/stage-alpha-orange?style=for-the-badge">
|
|
15
|
+
<img alt="Apache 2.0 license" src="https://img.shields.io/badge/license-Apache--2.0-green?style=for-the-badge">
|
|
16
|
+
<a href="https://github.com/Ayberkrk/timoshenko/actions/workflows/tests.yml"><img alt="Tests" src="https://github.com/Ayberkrk/timoshenko/actions/workflows/tests.yml/badge.svg"></a>
|
|
17
|
+
</p>
|
|
18
|
+
|
|
19
|
+
Timoshenko packages common structural calculations, modal analysis, sensor
|
|
20
|
+
workflows, and monitoring components so applications can reuse them instead
|
|
21
|
+
of rebuilding the same foundations for every project. It is an embeddable
|
|
22
|
+
Python library, not a hosted monitoring service or a general finite-element
|
|
23
|
+
solver.
|
|
24
|
+
|
|
25
|
+
> **Alpha:** the API may still change between releases. Every behavior change
|
|
26
|
+
> is listed in the [changelog](https://github.com/Ayberkrk/timoshenko/blob/main/docs/changelog.md).
|
|
27
|
+
|
|
28
|
+
## Install
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
python -m pip install timoshenko-engine
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
The distribution is named `timoshenko-engine`; the import package is
|
|
35
|
+
`timoshenko`. Optional MQTT support is an extra:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
python -m pip install "timoshenko-engine[mqtt]"
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Quick start
|
|
42
|
+
|
|
43
|
+
Compare measured vibration with a reference model. This example simulates a
|
|
44
|
+
record in which both modes are 5% below the model:
|
|
45
|
+
|
|
46
|
+
```python
|
|
47
|
+
import numpy as np
|
|
48
|
+
import timoshenko as tm
|
|
49
|
+
|
|
50
|
+
structure = tm.Structure(
|
|
51
|
+
structure_id="building-01",
|
|
52
|
+
story_masses_kg=[120_000.0, 110_000.0],
|
|
53
|
+
story_stiffness_n_m=[85_000_000.0, 70_000_000.0],
|
|
54
|
+
)
|
|
55
|
+
print(structure.natural_frequencies_hz) # (2.626, 6.476)
|
|
56
|
+
|
|
57
|
+
fs = 100.0
|
|
58
|
+
t = np.arange(60_000) / fs
|
|
59
|
+
f1, f2 = (0.95 * f for f in structure.natural_frequencies_hz)
|
|
60
|
+
signal = np.sin(2 * np.pi * f1 * t) + 0.4 * np.sin(2 * np.pi * f2 * t)
|
|
61
|
+
sensors = tm.SensorData(signal, sampling_hz=fs, unit="m/s^2")
|
|
62
|
+
|
|
63
|
+
result = tm.monitor(structure, sensors, review_threshold_pct=3.0)
|
|
64
|
+
print(result.structure.update_scale_factor) # 0.903, since stiffness scales with frequency squared
|
|
65
|
+
for change in result.health.mode_changes:
|
|
66
|
+
print(change.mode_number, change.change_pct) # 1 -5.0, then 2 -5.0
|
|
67
|
+
print(result.health.review_recommended) # True
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Real records load from CSV or JSON with
|
|
71
|
+
`tm.load_sensors("acceleration.csv", sampling_hz=100.0, column="acc")`. The
|
|
72
|
+
steps inside `tm.monitor` are also available separately as `tm.modal.identify`,
|
|
73
|
+
`tm.update`, and `tm.health.assess`. The review flag is raised only when you
|
|
74
|
+
pass a threshold: a meaningful value depends on the structure and its
|
|
75
|
+
environmental variability, so the engine does not choose one.
|
|
76
|
+
|
|
77
|
+
## Engineering calculations
|
|
78
|
+
|
|
79
|
+
Closed-form functions take and return SI units and validate their inputs:
|
|
80
|
+
|
|
81
|
+
```python
|
|
82
|
+
import timoshenko as tm
|
|
83
|
+
|
|
84
|
+
section = tm.rectangle_section(width_m=0.3, height_m=0.6)
|
|
85
|
+
beam = tm.simply_supported_uniform_load(
|
|
86
|
+
20_000.0, 6.0, 30e9, section.second_moment_y_m4,
|
|
87
|
+
shear_modulus_pa=12.5e9, area_m2=section.area_m2,
|
|
88
|
+
)
|
|
89
|
+
print(beam.bending_m, beam.shear_m) # 2.083 mm bending, 0.048 mm shear
|
|
90
|
+
|
|
91
|
+
frequency = tm.propagate_uncertainty(
|
|
92
|
+
tm.natural_frequency_hz,
|
|
93
|
+
{"mass_kg": 250.0, "stiffness_n_m": 4e5},
|
|
94
|
+
standard_uncertainties={"mass_kg": 5.0, "stiffness_n_m": 8e3},
|
|
95
|
+
)
|
|
96
|
+
print(frequency.estimate, frequency.standard_uncertainty) # 6.366 Hz ± 0.090 Hz
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
## What it provides
|
|
100
|
+
|
|
101
|
+
| Area | Components |
|
|
102
|
+
|---|---|
|
|
103
|
+
| Engineering calculations | Section properties (including polygons with holes), beam deflection with shear, torsion, Euler buckling, plane stress, thin-wall pressure, SDOF vibration, Rayleigh damping, and GUM / Monte Carlo uncertainty |
|
|
104
|
+
| Structural models | Lumped-mass shear-building models and their natural frequencies |
|
|
105
|
+
| Modal analysis | Single-channel peak picking with resolution-checked damping, and multi-channel FDD with complex mode shapes |
|
|
106
|
+
| Model comparison | Nearest-frequency mode pairing, global stiffness updating, and evidence-oriented health assessment |
|
|
107
|
+
| Monitoring | Bounded rolling-window sessions, restart from local history, and source adapters for CSV, MQTT, and OGC SensorThings |
|
|
108
|
+
| Data and reporting | Project manifests with SHA-256 provenance, local SQLite history, and standalone HTML reports |
|
|
109
|
+
|
|
110
|
+
Sensor collection, alarm policy, and engineering interpretation remain with the
|
|
111
|
+
application that embeds Timoshenko.
|
|
112
|
+
|
|
113
|
+
## Multi-channel modal analysis
|
|
114
|
+
|
|
115
|
+
Frequency domain decomposition needs synchronized channels with a common
|
|
116
|
+
sample rate and unit:
|
|
117
|
+
|
|
118
|
+
```python
|
|
119
|
+
signals = tm.load_multichannel_csv(
|
|
120
|
+
"aligned_accelerometers.csv",
|
|
121
|
+
columns=["deck_left", "deck_center", "deck_right"],
|
|
122
|
+
sampling_hz=100.0,
|
|
123
|
+
units=["m/s^2"] * 3,
|
|
124
|
+
)
|
|
125
|
+
fdd = tm.identify_fdd(signals, nperseg=1024, max_modes=5)
|
|
126
|
+
for mode in fdd.modes:
|
|
127
|
+
print(mode.frequency_hz, mode.shape_real)
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## Monitoring sessions
|
|
131
|
+
|
|
132
|
+
A host application feeds timestamped observation batches. The session aligns
|
|
133
|
+
samples to the sample grid, waits for a fresh contiguous window after gaps, and
|
|
134
|
+
analyzes every configured hop:
|
|
135
|
+
|
|
136
|
+
```python
|
|
137
|
+
session = tm.MonitoringSession(
|
|
138
|
+
structure,
|
|
139
|
+
sensor_ids=["deck-left", "deck-right"],
|
|
140
|
+
units=["m/s^2", "m/s^2"],
|
|
141
|
+
sampling_hz=100.0,
|
|
142
|
+
window_samples=2048,
|
|
143
|
+
hop_samples=512,
|
|
144
|
+
analysis_options={"nperseg": 512, "max_modes": 4},
|
|
145
|
+
review_threshold_pct=5.0,
|
|
146
|
+
)
|
|
147
|
+
result = session.ingest(batch) # batch: tm.ObservationBatch from your gateway or a source adapter
|
|
148
|
+
for report in result.reports:
|
|
149
|
+
tm.report.save_html(report, "reports/latest.html")
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
The session does not open network connections or run in the background. Use
|
|
153
|
+
`tm.SessionRunner` with a source such as `tm.CSVObservationSource` or
|
|
154
|
+
`tm.MqttObservationSource` to drive it.
|
|
155
|
+
|
|
156
|
+
## Documentation
|
|
157
|
+
|
|
158
|
+
- [Documentation home](https://github.com/Ayberkrk/timoshenko/blob/main/docs/index.md)
|
|
159
|
+
- [API reference](https://github.com/Ayberkrk/timoshenko/blob/main/docs/api.md)
|
|
160
|
+
- [Numerical methods and limits](https://github.com/Ayberkrk/timoshenko/blob/main/docs/numerical-methods.md)
|
|
161
|
+
- [Architecture](https://github.com/Ayberkrk/timoshenko/blob/main/docs/architecture.md)
|
|
162
|
+
- [Monitoring sessions](https://github.com/Ayberkrk/timoshenko/blob/main/docs/live-sessions.md) and [source adapters](https://github.com/Ayberkrk/timoshenko/blob/main/docs/adapters.md)
|
|
163
|
+
- [Runnable examples](https://github.com/Ayberkrk/timoshenko/tree/main/examples), including a [cross-check of PyNite shear-deformable beams](https://github.com/Ayberkrk/timoshenko/blob/main/docs/pynite-verification.md)
|
|
164
|
+
- [Changelog](https://github.com/Ayberkrk/timoshenko/blob/main/docs/changelog.md)
|
|
165
|
+
|
|
166
|
+
## Limits and engineering posture
|
|
167
|
+
|
|
168
|
+
- Timoshenko is alpha software and is not a structural safety certification tool.
|
|
169
|
+
- The shear-building model is a small lumped-mass reference model, not a full FEM solver.
|
|
170
|
+
- Modal identification is a screening estimate. A single sensor may miss a mode near a modal node; unpaired peaks are reported rather than compared with the wrong mode.
|
|
171
|
+
- Damping is a coarse screening estimate, reported only when the averaged spectrum resolves the half-power bandwidth. FDD does not estimate damping.
|
|
172
|
+
- The model update applies a single stiffness scale. It cannot locate or size local damage.
|
|
173
|
+
- A frequency shift is evidence for human review, not a damage verdict. Temperature, sensor placement, boundary conditions, and other effects also shift measured frequencies.
|
|
174
|
+
- Closed-form mechanics and section functions rely on their documented ideal assumptions. They are not code-compliance checks.
|
|
175
|
+
|
|
176
|
+
## Development
|
|
177
|
+
|
|
178
|
+
```bash
|
|
179
|
+
python -m pip install -e ".[test]"
|
|
180
|
+
python -m pytest
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
To preview the documentation site:
|
|
184
|
+
|
|
185
|
+
```bash
|
|
186
|
+
python -m pip install -e ".[docs]"
|
|
187
|
+
python -m mkdocs serve
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
Bug reports and pull requests are welcome in the
|
|
191
|
+
[issue tracker](https://github.com/Ayberkrk/timoshenko/issues).
|
|
192
|
+
|
|
193
|
+
## Citation
|
|
194
|
+
|
|
195
|
+
If you use Timoshenko in research, please cite it using the metadata in
|
|
196
|
+
[`CITATION.cff`](https://github.com/Ayberkrk/timoshenko/blob/main/CITATION.cff)
|
|
197
|
+
(GitHub's "Cite this repository" button reads the same file).
|
|
198
|
+
|
|
199
|
+
## License
|
|
200
|
+
|
|
201
|
+
Apache License 2.0. See [LICENSE](https://github.com/Ayberkrk/timoshenko/blob/main/LICENSE).
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "timoshenko-engine"
|
|
7
|
-
version = "2.0.
|
|
7
|
+
version = "2.0.2"
|
|
8
8
|
description = "Composable structural engineering calculations and analysis primitives for Python applications."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.10"
|
|
@@ -45,6 +45,7 @@ Homepage = "https://github.com/Ayberkrk/timoshenko"
|
|
|
45
45
|
Repository = "https://github.com/Ayberkrk/timoshenko"
|
|
46
46
|
Issues = "https://github.com/Ayberkrk/timoshenko/issues"
|
|
47
47
|
Documentation = "https://github.com/Ayberkrk/timoshenko/tree/main/docs"
|
|
48
|
+
Changelog = "https://github.com/Ayberkrk/timoshenko/blob/main/docs/changelog.md"
|
|
48
49
|
|
|
49
50
|
[tool.setuptools]
|
|
50
51
|
package-dir = { "" = "src" }
|
|
@@ -59,7 +59,7 @@ from .update import update
|
|
|
59
59
|
from .uncertainty import UncertaintyError, UncertaintyResult, propagate as propagate_uncertainty
|
|
60
60
|
from .vibration import RayleighDampingResult, damping_ratio, harmonic_response, natural_frequency_hz, rayleigh_damping_coefficients
|
|
61
61
|
|
|
62
|
-
__version__ = "2.0.
|
|
62
|
+
__version__ = "2.0.2"
|
|
63
63
|
|
|
64
64
|
__all__ = [
|
|
65
65
|
"HealthAssessment",
|