lythoskinematic 0.1.0__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.
- lythoskinematic-0.1.0/LICENSE +21 -0
- lythoskinematic-0.1.0/PKG-INFO +226 -0
- lythoskinematic-0.1.0/README.md +188 -0
- lythoskinematic-0.1.0/lythoskinematic/__init__.py +31 -0
- lythoskinematic-0.1.0/lythoskinematic/__main__.py +6 -0
- lythoskinematic-0.1.0/lythoskinematic/cli.py +93 -0
- lythoskinematic-0.1.0/lythoskinematic/forms.py +477 -0
- lythoskinematic-0.1.0/lythoskinematic/i18n.py +63 -0
- lythoskinematic-0.1.0/lythoskinematic/kinematics/__init__.py +17 -0
- lythoskinematic-0.1.0/lythoskinematic/kinematics/engine.py +229 -0
- lythoskinematic-0.1.0/lythoskinematic/kinematics/htmlreport.py +157 -0
- lythoskinematic-0.1.0/lythoskinematic/kinematics/i18n.py +119 -0
- lythoskinematic-0.1.0/lythoskinematic/kinematics/plots.py +107 -0
- lythoskinematic-0.1.0/lythoskinematic/kinematics/report.py +100 -0
- lythoskinematic-0.1.0/lythoskinematic/render.py +93 -0
- lythoskinematic-0.1.0/lythoskinematic/rockslope/__init__.py +26 -0
- lythoskinematic-0.1.0/lythoskinematic/rockslope/bolts.py +382 -0
- lythoskinematic-0.1.0/lythoskinematic/rockslope/core.py +75 -0
- lythoskinematic-0.1.0/lythoskinematic/rockslope/planar.py +306 -0
- lythoskinematic-0.1.0/lythoskinematic/rockslope/report.py +337 -0
- lythoskinematic-0.1.0/lythoskinematic/rockslope/style.py +95 -0
- lythoskinematic-0.1.0/lythoskinematic/rockslope/text.py +55 -0
- lythoskinematic-0.1.0/lythoskinematic/rockslope/toppling.py +305 -0
- lythoskinematic-0.1.0/lythoskinematic/rockslope/wedge.py +816 -0
- lythoskinematic-0.1.0/lythoskinematic/stereonet.py +194 -0
- lythoskinematic-0.1.0/lythoskinematic/theme.py +26 -0
- lythoskinematic-0.1.0/lythoskinematic/web/__init__.py +4 -0
- lythoskinematic-0.1.0/lythoskinematic/web/server.py +175 -0
- lythoskinematic-0.1.0/lythoskinematic/web/session.py +637 -0
- lythoskinematic-0.1.0/lythoskinematic/web/static/app.js +630 -0
- lythoskinematic-0.1.0/lythoskinematic/web/static/index.html +82 -0
- lythoskinematic-0.1.0/lythoskinematic/web/static/style.css +245 -0
- lythoskinematic-0.1.0/lythoskinematic/web/strings.py +82 -0
- lythoskinematic-0.1.0/lythoskinematic.egg-info/PKG-INFO +226 -0
- lythoskinematic-0.1.0/lythoskinematic.egg-info/SOURCES.txt +46 -0
- lythoskinematic-0.1.0/lythoskinematic.egg-info/dependency_links.txt +1 -0
- lythoskinematic-0.1.0/lythoskinematic.egg-info/entry_points.txt +2 -0
- lythoskinematic-0.1.0/lythoskinematic.egg-info/requires.txt +10 -0
- lythoskinematic-0.1.0/lythoskinematic.egg-info/top_level.txt +1 -0
- lythoskinematic-0.1.0/pyproject.toml +67 -0
- lythoskinematic-0.1.0/setup.cfg +4 -0
- lythoskinematic-0.1.0/tests/test_bolts.py +47 -0
- lythoskinematic-0.1.0/tests/test_forms.py +191 -0
- lythoskinematic-0.1.0/tests/test_i18n.py +223 -0
- lythoskinematic-0.1.0/tests/test_kinematics.py +176 -0
- lythoskinematic-0.1.0/tests/test_stereonet.py +129 -0
- lythoskinematic-0.1.0/tests/test_validation.py +66 -0
- lythoskinematic-0.1.0/tests/test_web.py +334 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 hdaltuntas
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: lythoskinematic
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Rock slope kinematics and stability: Markland screening on a stereonet, Monte Carlo probability of failure, and limit-equilibrium analysis of wedge, planar and toppling failure with bolt design and PDF reporting.
|
|
5
|
+
Author-email: Hasan Deniz Altuntaş <lythosfea@gmail.com>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/hdaltuntas/lythoskinematic
|
|
8
|
+
Project-URL: Repository, https://github.com/hdaltuntas/lythoskinematic
|
|
9
|
+
Project-URL: Issues, https://github.com/hdaltuntas/lythoskinematic/issues
|
|
10
|
+
Keywords: geotechnical,rock slope,slope stability,kinematic analysis,markland,stereonet,wedge,planar sliding,toppling,limit equilibrium,factor of safety,monte carlo,rock bolt,hoek brown,civil engineering,mining
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Environment :: Web Environment
|
|
13
|
+
Classifier: Intended Audience :: Science/Research
|
|
14
|
+
Classifier: Intended Audience :: Education
|
|
15
|
+
Classifier: Natural Language :: English
|
|
16
|
+
Classifier: Natural Language :: Turkish
|
|
17
|
+
Classifier: Operating System :: OS Independent
|
|
18
|
+
Classifier: Programming Language :: Python :: 3
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
23
|
+
Classifier: Topic :: Scientific/Engineering
|
|
24
|
+
Classifier: Topic :: Scientific/Engineering :: Visualization
|
|
25
|
+
Requires-Python: >=3.10
|
|
26
|
+
Description-Content-Type: text/markdown
|
|
27
|
+
License-File: LICENSE
|
|
28
|
+
Requires-Dist: numpy>=1.24
|
|
29
|
+
Requires-Dist: scipy>=1.10
|
|
30
|
+
Requires-Dist: matplotlib>=3.7
|
|
31
|
+
Requires-Dist: reportlab>=4.0
|
|
32
|
+
Provides-Extra: dev
|
|
33
|
+
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
34
|
+
Requires-Dist: ruff>=0.4; extra == "dev"
|
|
35
|
+
Requires-Dist: build>=1.0; extra == "dev"
|
|
36
|
+
Requires-Dist: twine>=5.0; extra == "dev"
|
|
37
|
+
Dynamic: license-file
|
|
38
|
+
|
|
39
|
+
**English** | [Türkçe](README.tr.md)
|
|
40
|
+
|
|
41
|
+
# Lythos Kinematic
|
|
42
|
+
|
|
43
|
+
Rock slope kinematics and stability, driven from your browser. Two steps, one workflow:
|
|
44
|
+
|
|
45
|
+
1. **Kinematic screening** — the Markland test on a stereonet, pole density and a Monte
|
|
46
|
+
Carlo probability of failure establish *which failure mechanism is possible*.
|
|
47
|
+
2. **Limit equilibrium** — for the mechanism found critical, compute the *factor of
|
|
48
|
+
safety, the required support and the bolt design*.
|
|
49
|
+
|
|
50
|
+
The two steps are bridged: the most critical discontinuity or intersection found during
|
|
51
|
+
screening is written into the limit-equilibrium inputs with one click. The whole
|
|
52
|
+
application — every label, result text, plot and PDF report — is bilingual in **Turkish
|
|
53
|
+
and English**, switchable at runtime.
|
|
54
|
+
|
|
55
|
+
The interface is a small HTTP server on your own machine, driven from a browser. That
|
|
56
|
+
keeps the program usable over a remote session or inside a container, where a desktop
|
|
57
|
+
toolkit would need a display it does not have, and it costs no dependency beyond the
|
|
58
|
+
standard library.
|
|
59
|
+
|
|
60
|
+
> This is the sibling of [LythosFEA](https://github.com/hdaltuntas/lythos) and follows
|
|
61
|
+
> the same architecture. It merges two formerly separate desktop programs,
|
|
62
|
+
> **SlopeKinematics** and **Kinematix**; see [Background](#background).
|
|
63
|
+
|
|
64
|
+
## Screenshots
|
|
65
|
+
|
|
66
|
+
| Kinematic screening | Bolt spacing × length matrix |
|
|
67
|
+
|---|---|
|
|
68
|
+
|  |  |
|
|
69
|
+
|
|
70
|
+
| Probabilistic analysis | Wedge analysis | English interface, dark theme |
|
|
71
|
+
|---|---|---|
|
|
72
|
+
|  |  |  |
|
|
73
|
+
|
|
74
|
+
## Install & run
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
pip install lythoskinematic
|
|
78
|
+
lythos-kinematic # opens the interface in your browser
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
From a clone, with nothing installed but the scientific stack:
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
pip install numpy scipy matplotlib reportlab
|
|
85
|
+
python main.py
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Python 3.10+ is required.
|
|
89
|
+
|
|
90
|
+
## Command line
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
lythos-kinematic # web interface (the default)
|
|
94
|
+
lythos-kinematic web --port 9000 --lang EN --no-browser
|
|
95
|
+
lythos-kinematic example -o inputs.json # a starter input file
|
|
96
|
+
lythos-kinematic screen inputs.json -o screening.pdf
|
|
97
|
+
lythos-kinematic run inputs.json --mode wedge -o wedge.pdf
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
`screen` and `run` read the same JSON the interface saves, so a case set up in the
|
|
101
|
+
browser can be re-run unattended.
|
|
102
|
+
|
|
103
|
+
## What it computes
|
|
104
|
+
|
|
105
|
+
### Kinematic screening
|
|
106
|
+
- **Kinematic tests:** planar sliding, wedge sliding (Markland), flexural toppling
|
|
107
|
+
(Goodman & Bray)
|
|
108
|
+
- **Stereonet:** equal-area (Schmidt) lower-hemisphere projection, pole density contour
|
|
109
|
+
(Kamb counting cone), critical zone sweep, friction / sliding limit cone
|
|
110
|
+
- **Monte Carlo:** overall and component-wise probability of failure accounting for
|
|
111
|
+
discontinuity orientation uncertainty; runs on a background thread, the page stays live
|
|
112
|
+
- **PDF report:** checks, probabilities and the stereonet in one file
|
|
113
|
+
|
|
114
|
+
### Limit equilibrium
|
|
115
|
+
- **Wedge (Swedge):** tetrahedral wedge geometry, Hoek & Bray vector limit equilibrium,
|
|
116
|
+
3D view and stereonet
|
|
117
|
+
- **Planar (RocPlane):** tension crack, water pressure, seismic load, 2D section
|
|
118
|
+
- **Toppling (RocTopple):** Goodman & Bray block toppling, water + seismic + toe anchor
|
|
119
|
+
- **Support design:** force required for a target FS, a clickable bolt spacing × length
|
|
120
|
+
matrix, and a capacity/FS check for the design you pick
|
|
121
|
+
- **PDF report:** project data, input tables, figures, force-balance tables
|
|
122
|
+
|
|
123
|
+
### The bridge
|
|
124
|
+
**"→ Send critical result to limit equilibrium"** transfers the most critical component:
|
|
125
|
+
|
|
126
|
+
| Screening mode | Transferred inputs |
|
|
127
|
+
|---|---|
|
|
128
|
+
| Planar | sliding plane ψp, slope face ψf, friction angle φ |
|
|
129
|
+
| Wedge | Joint 1 and Joint 2 dip/dip dir, slope face dip/dip dir, φ |
|
|
130
|
+
| Toppling | discontinuity dip ψd, slope face ψf, φ |
|
|
131
|
+
|
|
132
|
+
## Layout
|
|
133
|
+
|
|
134
|
+
```
|
|
135
|
+
main.py run from a clone without installing
|
|
136
|
+
lythoskinematic/
|
|
137
|
+
cli.py command line (web · screen · run · example)
|
|
138
|
+
i18n.py language switch; bilingual text helper T("tr", "en")
|
|
139
|
+
forms.py input schema and readers — one definition per field
|
|
140
|
+
stereonet.py shared lower-hemisphere projection (no extra deps)
|
|
141
|
+
render.py figures as PNG, for the browser and the report alike
|
|
142
|
+
theme.py plot palette
|
|
143
|
+
kinematics/ screening core — independent of the interface
|
|
144
|
+
engine.py Markland criteria + Monte Carlo
|
|
145
|
+
plots.py screening stereonet
|
|
146
|
+
htmlreport.py HTML report bodies
|
|
147
|
+
report.py screening PDF report
|
|
148
|
+
i18n.py TR/EN strings
|
|
149
|
+
rockslope/ limit-equilibrium core — independent of the interface
|
|
150
|
+
core.py wedge.py planar.py toppling.py bolts.py report.py style.py text.py
|
|
151
|
+
web/
|
|
152
|
+
server.py HTTP routes (standard library only)
|
|
153
|
+
session.py the one working session: analyses, figures, reports
|
|
154
|
+
strings.py interface text, served to the page
|
|
155
|
+
static/ index.html · style.css · app.js
|
|
156
|
+
tests/ pytest suite
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
Forms are generated from `forms.py`: a field's key, label, unit, range and default are
|
|
160
|
+
written once, in Python, and the page renders whatever the server sends. There is no
|
|
161
|
+
second copy of the labels in JavaScript and nothing to keep in step by hand — switching
|
|
162
|
+
language simply re-fetches the schema.
|
|
163
|
+
|
|
164
|
+
## Background
|
|
165
|
+
|
|
166
|
+
Lythos Kinematic began as two desktop programs, **SlopeKinematics** (kinematics and
|
|
167
|
+
probability, PyQt5) and **Kinematix** (limit equilibrium, bolting and reporting,
|
|
168
|
+
PySide6). Merging them required three changes worth recording:
|
|
169
|
+
|
|
170
|
+
1. **One interface.** Two Qt bindings cannot share a process, and a desktop toolkit needs
|
|
171
|
+
a display. Both interfaces were replaced by this browser-driven one, which also brought
|
|
172
|
+
the two programs' workflows together behind a single set of inputs.
|
|
173
|
+
2. **mplstereonet removed.** Stereonet drawing now comes from one shared implementation in
|
|
174
|
+
`stereonet.py` (equal-area/equal-angle projection, great and small circles, pole density
|
|
175
|
+
via the Kamb counting cone). Both modules plot on exactly the same geometry, and a
|
|
176
|
+
dependency that fails to build on current Python versions is gone.
|
|
177
|
+
3. **One reporting path.** Screening reports used to be printed through Qt; everything now
|
|
178
|
+
goes through the same reportlab template as the limit-equilibrium report, so both
|
|
179
|
+
modules produce the same document, and no display is needed to make a PDF.
|
|
180
|
+
|
|
181
|
+
While unifying the projection, **a radius normalisation bug in the equal-area projection
|
|
182
|
+
was fixed**: horizontal lines (plunge = 0) landed at 70.7 % of the radius instead of on
|
|
183
|
+
the primitive circle, so all data was squeezed into the inner part of the net. The fix is
|
|
184
|
+
pinned by `tests/test_stereonet.py`.
|
|
185
|
+
|
|
186
|
+
## Validation
|
|
187
|
+
|
|
188
|
+
```bash
|
|
189
|
+
pip install -e ".[dev]"
|
|
190
|
+
pytest
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
The cores are pinned against closed-form solutions:
|
|
194
|
+
|
|
195
|
+
- **wedge** — matches the Hoek & Bray closed-form short solution exactly
|
|
196
|
+
(dry 1.696 / flooded 1.065)
|
|
197
|
+
- **planar** — c = 0, dry: tanφ/tanψp
|
|
198
|
+
- **toppling** — Wyllie & Mah Chapter 9 example (block heights, failure modes,
|
|
199
|
+
limit-equilibrium φ ≈ 38°)
|
|
200
|
+
- **kinematics** — the intersection line is cross-checked against the independent vector
|
|
201
|
+
implementation in the limit-equilibrium core; with zero uncertainty the Monte Carlo
|
|
202
|
+
result must reduce to the deterministic 0/100 answer
|
|
203
|
+
- **stereonet** — projection radii against the analytical Schmidt/Wulff values, poles
|
|
204
|
+
against being perpendicular to the dip vector
|
|
205
|
+
- **i18n** — every summary follows the language, the fixed-width label column stays
|
|
206
|
+
aligned in both, the numbers never change, and internal keys are never translated
|
|
207
|
+
- **web** — the schema covers every field, the session's analyses reproduce the validated
|
|
208
|
+
results, background jobs finish without deadlocking the state poll, and the HTTP routes
|
|
209
|
+
return PNG figures, PDF reports and plain error messages rather than stack traces
|
|
210
|
+
|
|
211
|
+
## Releasing
|
|
212
|
+
|
|
213
|
+
`tools/upload_to_pypi.py` builds the distribution and uploads it, from a terminal
|
|
214
|
+
or from an editor such as Thonny: run it and answer the questions. It makes its
|
|
215
|
+
own environment for `build` and `twine`, refuses a version that is already on
|
|
216
|
+
PyPI, and sends nothing before showing what it is about to upload. Set
|
|
217
|
+
`TEST_PYPI = True` at the top to rehearse on TestPyPI.
|
|
218
|
+
|
|
219
|
+
The token is never stored in the repository: it is read from `~/.pypirc` or typed
|
|
220
|
+
in, and passed straight to twine. A project's **first** upload needs a token
|
|
221
|
+
scoped to the entire account — a project-scoped token can only be created once
|
|
222
|
+
the project exists.
|
|
223
|
+
|
|
224
|
+
## License
|
|
225
|
+
|
|
226
|
+
MIT — see [LICENSE](LICENSE).
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
**English** | [Türkçe](README.tr.md)
|
|
2
|
+
|
|
3
|
+
# Lythos Kinematic
|
|
4
|
+
|
|
5
|
+
Rock slope kinematics and stability, driven from your browser. Two steps, one workflow:
|
|
6
|
+
|
|
7
|
+
1. **Kinematic screening** — the Markland test on a stereonet, pole density and a Monte
|
|
8
|
+
Carlo probability of failure establish *which failure mechanism is possible*.
|
|
9
|
+
2. **Limit equilibrium** — for the mechanism found critical, compute the *factor of
|
|
10
|
+
safety, the required support and the bolt design*.
|
|
11
|
+
|
|
12
|
+
The two steps are bridged: the most critical discontinuity or intersection found during
|
|
13
|
+
screening is written into the limit-equilibrium inputs with one click. The whole
|
|
14
|
+
application — every label, result text, plot and PDF report — is bilingual in **Turkish
|
|
15
|
+
and English**, switchable at runtime.
|
|
16
|
+
|
|
17
|
+
The interface is a small HTTP server on your own machine, driven from a browser. That
|
|
18
|
+
keeps the program usable over a remote session or inside a container, where a desktop
|
|
19
|
+
toolkit would need a display it does not have, and it costs no dependency beyond the
|
|
20
|
+
standard library.
|
|
21
|
+
|
|
22
|
+
> This is the sibling of [LythosFEA](https://github.com/hdaltuntas/lythos) and follows
|
|
23
|
+
> the same architecture. It merges two formerly separate desktop programs,
|
|
24
|
+
> **SlopeKinematics** and **Kinematix**; see [Background](#background).
|
|
25
|
+
|
|
26
|
+
## Screenshots
|
|
27
|
+
|
|
28
|
+
| Kinematic screening | Bolt spacing × length matrix |
|
|
29
|
+
|---|---|
|
|
30
|
+
|  |  |
|
|
31
|
+
|
|
32
|
+
| Probabilistic analysis | Wedge analysis | English interface, dark theme |
|
|
33
|
+
|---|---|---|
|
|
34
|
+
|  |  |  |
|
|
35
|
+
|
|
36
|
+
## Install & run
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
pip install lythoskinematic
|
|
40
|
+
lythos-kinematic # opens the interface in your browser
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
From a clone, with nothing installed but the scientific stack:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
pip install numpy scipy matplotlib reportlab
|
|
47
|
+
python main.py
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Python 3.10+ is required.
|
|
51
|
+
|
|
52
|
+
## Command line
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
lythos-kinematic # web interface (the default)
|
|
56
|
+
lythos-kinematic web --port 9000 --lang EN --no-browser
|
|
57
|
+
lythos-kinematic example -o inputs.json # a starter input file
|
|
58
|
+
lythos-kinematic screen inputs.json -o screening.pdf
|
|
59
|
+
lythos-kinematic run inputs.json --mode wedge -o wedge.pdf
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
`screen` and `run` read the same JSON the interface saves, so a case set up in the
|
|
63
|
+
browser can be re-run unattended.
|
|
64
|
+
|
|
65
|
+
## What it computes
|
|
66
|
+
|
|
67
|
+
### Kinematic screening
|
|
68
|
+
- **Kinematic tests:** planar sliding, wedge sliding (Markland), flexural toppling
|
|
69
|
+
(Goodman & Bray)
|
|
70
|
+
- **Stereonet:** equal-area (Schmidt) lower-hemisphere projection, pole density contour
|
|
71
|
+
(Kamb counting cone), critical zone sweep, friction / sliding limit cone
|
|
72
|
+
- **Monte Carlo:** overall and component-wise probability of failure accounting for
|
|
73
|
+
discontinuity orientation uncertainty; runs on a background thread, the page stays live
|
|
74
|
+
- **PDF report:** checks, probabilities and the stereonet in one file
|
|
75
|
+
|
|
76
|
+
### Limit equilibrium
|
|
77
|
+
- **Wedge (Swedge):** tetrahedral wedge geometry, Hoek & Bray vector limit equilibrium,
|
|
78
|
+
3D view and stereonet
|
|
79
|
+
- **Planar (RocPlane):** tension crack, water pressure, seismic load, 2D section
|
|
80
|
+
- **Toppling (RocTopple):** Goodman & Bray block toppling, water + seismic + toe anchor
|
|
81
|
+
- **Support design:** force required for a target FS, a clickable bolt spacing × length
|
|
82
|
+
matrix, and a capacity/FS check for the design you pick
|
|
83
|
+
- **PDF report:** project data, input tables, figures, force-balance tables
|
|
84
|
+
|
|
85
|
+
### The bridge
|
|
86
|
+
**"→ Send critical result to limit equilibrium"** transfers the most critical component:
|
|
87
|
+
|
|
88
|
+
| Screening mode | Transferred inputs |
|
|
89
|
+
|---|---|
|
|
90
|
+
| Planar | sliding plane ψp, slope face ψf, friction angle φ |
|
|
91
|
+
| Wedge | Joint 1 and Joint 2 dip/dip dir, slope face dip/dip dir, φ |
|
|
92
|
+
| Toppling | discontinuity dip ψd, slope face ψf, φ |
|
|
93
|
+
|
|
94
|
+
## Layout
|
|
95
|
+
|
|
96
|
+
```
|
|
97
|
+
main.py run from a clone without installing
|
|
98
|
+
lythoskinematic/
|
|
99
|
+
cli.py command line (web · screen · run · example)
|
|
100
|
+
i18n.py language switch; bilingual text helper T("tr", "en")
|
|
101
|
+
forms.py input schema and readers — one definition per field
|
|
102
|
+
stereonet.py shared lower-hemisphere projection (no extra deps)
|
|
103
|
+
render.py figures as PNG, for the browser and the report alike
|
|
104
|
+
theme.py plot palette
|
|
105
|
+
kinematics/ screening core — independent of the interface
|
|
106
|
+
engine.py Markland criteria + Monte Carlo
|
|
107
|
+
plots.py screening stereonet
|
|
108
|
+
htmlreport.py HTML report bodies
|
|
109
|
+
report.py screening PDF report
|
|
110
|
+
i18n.py TR/EN strings
|
|
111
|
+
rockslope/ limit-equilibrium core — independent of the interface
|
|
112
|
+
core.py wedge.py planar.py toppling.py bolts.py report.py style.py text.py
|
|
113
|
+
web/
|
|
114
|
+
server.py HTTP routes (standard library only)
|
|
115
|
+
session.py the one working session: analyses, figures, reports
|
|
116
|
+
strings.py interface text, served to the page
|
|
117
|
+
static/ index.html · style.css · app.js
|
|
118
|
+
tests/ pytest suite
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
Forms are generated from `forms.py`: a field's key, label, unit, range and default are
|
|
122
|
+
written once, in Python, and the page renders whatever the server sends. There is no
|
|
123
|
+
second copy of the labels in JavaScript and nothing to keep in step by hand — switching
|
|
124
|
+
language simply re-fetches the schema.
|
|
125
|
+
|
|
126
|
+
## Background
|
|
127
|
+
|
|
128
|
+
Lythos Kinematic began as two desktop programs, **SlopeKinematics** (kinematics and
|
|
129
|
+
probability, PyQt5) and **Kinematix** (limit equilibrium, bolting and reporting,
|
|
130
|
+
PySide6). Merging them required three changes worth recording:
|
|
131
|
+
|
|
132
|
+
1. **One interface.** Two Qt bindings cannot share a process, and a desktop toolkit needs
|
|
133
|
+
a display. Both interfaces were replaced by this browser-driven one, which also brought
|
|
134
|
+
the two programs' workflows together behind a single set of inputs.
|
|
135
|
+
2. **mplstereonet removed.** Stereonet drawing now comes from one shared implementation in
|
|
136
|
+
`stereonet.py` (equal-area/equal-angle projection, great and small circles, pole density
|
|
137
|
+
via the Kamb counting cone). Both modules plot on exactly the same geometry, and a
|
|
138
|
+
dependency that fails to build on current Python versions is gone.
|
|
139
|
+
3. **One reporting path.** Screening reports used to be printed through Qt; everything now
|
|
140
|
+
goes through the same reportlab template as the limit-equilibrium report, so both
|
|
141
|
+
modules produce the same document, and no display is needed to make a PDF.
|
|
142
|
+
|
|
143
|
+
While unifying the projection, **a radius normalisation bug in the equal-area projection
|
|
144
|
+
was fixed**: horizontal lines (plunge = 0) landed at 70.7 % of the radius instead of on
|
|
145
|
+
the primitive circle, so all data was squeezed into the inner part of the net. The fix is
|
|
146
|
+
pinned by `tests/test_stereonet.py`.
|
|
147
|
+
|
|
148
|
+
## Validation
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
pip install -e ".[dev]"
|
|
152
|
+
pytest
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
The cores are pinned against closed-form solutions:
|
|
156
|
+
|
|
157
|
+
- **wedge** — matches the Hoek & Bray closed-form short solution exactly
|
|
158
|
+
(dry 1.696 / flooded 1.065)
|
|
159
|
+
- **planar** — c = 0, dry: tanφ/tanψp
|
|
160
|
+
- **toppling** — Wyllie & Mah Chapter 9 example (block heights, failure modes,
|
|
161
|
+
limit-equilibrium φ ≈ 38°)
|
|
162
|
+
- **kinematics** — the intersection line is cross-checked against the independent vector
|
|
163
|
+
implementation in the limit-equilibrium core; with zero uncertainty the Monte Carlo
|
|
164
|
+
result must reduce to the deterministic 0/100 answer
|
|
165
|
+
- **stereonet** — projection radii against the analytical Schmidt/Wulff values, poles
|
|
166
|
+
against being perpendicular to the dip vector
|
|
167
|
+
- **i18n** — every summary follows the language, the fixed-width label column stays
|
|
168
|
+
aligned in both, the numbers never change, and internal keys are never translated
|
|
169
|
+
- **web** — the schema covers every field, the session's analyses reproduce the validated
|
|
170
|
+
results, background jobs finish without deadlocking the state poll, and the HTTP routes
|
|
171
|
+
return PNG figures, PDF reports and plain error messages rather than stack traces
|
|
172
|
+
|
|
173
|
+
## Releasing
|
|
174
|
+
|
|
175
|
+
`tools/upload_to_pypi.py` builds the distribution and uploads it, from a terminal
|
|
176
|
+
or from an editor such as Thonny: run it and answer the questions. It makes its
|
|
177
|
+
own environment for `build` and `twine`, refuses a version that is already on
|
|
178
|
+
PyPI, and sends nothing before showing what it is about to upload. Set
|
|
179
|
+
`TEST_PYPI = True` at the top to rehearse on TestPyPI.
|
|
180
|
+
|
|
181
|
+
The token is never stored in the repository: it is read from `~/.pypirc` or typed
|
|
182
|
+
in, and passed straight to twine. A project's **first** upload needs a token
|
|
183
|
+
scoped to the entire account — a project-scoped token can only be created once
|
|
184
|
+
the project exists.
|
|
185
|
+
|
|
186
|
+
## License
|
|
187
|
+
|
|
188
|
+
MIT — see [LICENSE](LICENSE).
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Lythos Kinematic — kaya şevi kinematiği ve stabilitesi (web tabanlı).
|
|
3
|
+
|
|
4
|
+
İki adımlı bir iş akışı sunar:
|
|
5
|
+
|
|
6
|
+
1. Kinematik tarama — Markland testi, stereonet, kutup yoğunluğu ve
|
|
7
|
+
Monte Carlo olasılık analizi
|
|
8
|
+
2. Limit denge — kama / düzlemsel / devrilme analizi, bulon karelaj ve
|
|
9
|
+
boy tasarımı, PDF rapor
|
|
10
|
+
|
|
11
|
+
Arayüz, tarayıcıdan sürülen yerel bir web sunucusudur (yalnızca standart
|
|
12
|
+
kütüphane); bu sayede uzak oturumda veya kapsayıcı içinde de çalışır.
|
|
13
|
+
|
|
14
|
+
Paket düzeni
|
|
15
|
+
------------
|
|
16
|
+
lythoskinematic.i18n dil anahtarı; çift dilli metin yardımcısı
|
|
17
|
+
lythoskinematic.stereonet ortak alt yarımküre stereonet projeksiyonu
|
|
18
|
+
lythoskinematic.kinematics kinematik tarama çekirdeği (Markland + Monte Carlo)
|
|
19
|
+
lythoskinematic.rockslope limit denge çekirdeği (Hoek & Bray, Goodman & Bray)
|
|
20
|
+
lythoskinematic.forms girdi şeması ve okuyucuları (arayüzden bağımsız)
|
|
21
|
+
lythoskinematic.web yerel web sunucusu ve tarayıcı arayüzü
|
|
22
|
+
|
|
23
|
+
Çalıştırma: lythos-kinematic (veya python -m lythoskinematic)
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
__version__ = "0.1.0"
|
|
27
|
+
|
|
28
|
+
APP_NAME = "Lythos Kinematic"
|
|
29
|
+
ORG = "Lythos"
|
|
30
|
+
|
|
31
|
+
__all__ = ["__version__", "APP_NAME", "ORG"]
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
"""Komut satırı arayüzü."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import argparse
|
|
6
|
+
import sys
|
|
7
|
+
|
|
8
|
+
from . import APP_NAME, __version__
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def main(argv=None) -> int:
|
|
12
|
+
parser = argparse.ArgumentParser(
|
|
13
|
+
prog="lythos-kinematic",
|
|
14
|
+
description="Rock slope kinematics and stability: Markland screening, "
|
|
15
|
+
"Monte Carlo probability and limit-equilibrium analysis.")
|
|
16
|
+
parser.add_argument("--version", action="version", version=f"{APP_NAME} {__version__}")
|
|
17
|
+
sub = parser.add_subparsers(dest="command")
|
|
18
|
+
|
|
19
|
+
web = sub.add_parser("web", help="start the interface in a browser")
|
|
20
|
+
web.add_argument("--port", type=int, default=8778)
|
|
21
|
+
web.add_argument("--host", default="127.0.0.1")
|
|
22
|
+
web.add_argument("--lang", default="TR", choices=["TR", "EN"])
|
|
23
|
+
web.add_argument("--no-browser", action="store_true")
|
|
24
|
+
|
|
25
|
+
screen = sub.add_parser("screen", help="run a kinematic screening from an input file")
|
|
26
|
+
screen.add_argument("inputs", help="path to a .json input file")
|
|
27
|
+
screen.add_argument("-o", "--out", default=None, help="write a PDF report here")
|
|
28
|
+
screen.add_argument("--lang", default="TR", choices=["TR", "EN"])
|
|
29
|
+
|
|
30
|
+
run = sub.add_parser("run", help="run a limit-equilibrium analysis from an input file")
|
|
31
|
+
run.add_argument("inputs", help="path to a .json input file")
|
|
32
|
+
run.add_argument("--mode", default="wedge", choices=["wedge", "planar", "toppling"])
|
|
33
|
+
run.add_argument("-o", "--out", default=None, help="write a PDF report here")
|
|
34
|
+
run.add_argument("--lang", default="TR", choices=["TR", "EN"])
|
|
35
|
+
|
|
36
|
+
example = sub.add_parser("example", help="write a starter input file")
|
|
37
|
+
example.add_argument("-o", "--out", default="lythos_inputs.json")
|
|
38
|
+
|
|
39
|
+
args = parser.parse_args(argv)
|
|
40
|
+
command = args.command or "web"
|
|
41
|
+
|
|
42
|
+
if command == "web":
|
|
43
|
+
from .web.server import serve
|
|
44
|
+
serve(host=getattr(args, "host", "127.0.0.1"), port=getattr(args, "port", 8778),
|
|
45
|
+
open_browser=not getattr(args, "no_browser", False),
|
|
46
|
+
lang=getattr(args, "lang", "TR"))
|
|
47
|
+
return 0
|
|
48
|
+
|
|
49
|
+
if command == "example":
|
|
50
|
+
import json
|
|
51
|
+
|
|
52
|
+
from . import forms
|
|
53
|
+
with open(args.out, "w", encoding="utf-8") as fh:
|
|
54
|
+
json.dump({"format": "lythos-kinematic", "version": 1, **forms.defaults()},
|
|
55
|
+
fh, indent=2, ensure_ascii=False)
|
|
56
|
+
print(args.out)
|
|
57
|
+
return 0
|
|
58
|
+
|
|
59
|
+
import json
|
|
60
|
+
|
|
61
|
+
from .i18n import set_language
|
|
62
|
+
from .web.session import Session
|
|
63
|
+
|
|
64
|
+
set_language(args.lang)
|
|
65
|
+
with open(args.inputs, encoding="utf-8") as fh:
|
|
66
|
+
values = json.load(fh)
|
|
67
|
+
session = Session()
|
|
68
|
+
|
|
69
|
+
if command == "screen":
|
|
70
|
+
result = session.screen(values)
|
|
71
|
+
if not result["ok"]:
|
|
72
|
+
print(result["error"], file=sys.stderr)
|
|
73
|
+
return 1
|
|
74
|
+
payload = result["result"]
|
|
75
|
+
print(f"{payload['mode_label']}: {payload['n_critical']} / {payload['n_items']}")
|
|
76
|
+
for item in payload["items"]:
|
|
77
|
+
print(f" {item['name']:<16} {item['status']}")
|
|
78
|
+
if args.out:
|
|
79
|
+
import time
|
|
80
|
+
while session.state()["job"] == "running": # Monte Carlo bitsin
|
|
81
|
+
time.sleep(0.05)
|
|
82
|
+
print(session.report("screening", args.out))
|
|
83
|
+
return 0
|
|
84
|
+
|
|
85
|
+
result = session.equilibrium(args.mode, values)
|
|
86
|
+
print(result["summary"])
|
|
87
|
+
if args.out:
|
|
88
|
+
print(session.report("equilibrium", args.out))
|
|
89
|
+
return 0
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
if __name__ == "__main__":
|
|
93
|
+
sys.exit(main())
|