osis-python 0.5.1__tar.gz → 0.5.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.
- {osis_python-0.5.1/src/osis_python.egg-info → osis_python-0.5.2}/PKG-INFO +1 -1
- {osis_python-0.5.1 → osis_python-0.5.2/src/osis_python.egg-info}/PKG-INFO +1 -1
- {osis_python-0.5.1 → osis_python-0.5.2}/src/osis_python.egg-info/SOURCES.txt +4 -1
- {osis_python-0.5.1 → osis_python-0.5.2}/src/pyosis/__init__.py +1 -1
- {osis_python-0.5.1 → osis_python-0.5.2}/src/pyosis/boundary/manager.py +13 -1
- {osis_python-0.5.1 → osis_python-0.5.2}/src/pyosis/core/__init__.py +2 -0
- {osis_python-0.5.1 → osis_python-0.5.2}/src/pyosis/core/client.py +11 -2
- {osis_python-0.5.1 → osis_python-0.5.2}/src/pyosis/core/command.py +11 -2
- {osis_python-0.5.1 → osis_python-0.5.2}/src/pyosis/core/engine.py +8 -4
- osis_python-0.5.2/src/pyosis/core/exceptions.py +32 -0
- osis_python-0.5.2/src/pyosis/core/references.py +87 -0
- {osis_python-0.5.1 → osis_python-0.5.2}/src/pyosis/dynamic/manager.py +2 -2
- {osis_python-0.5.1 → osis_python-0.5.2}/src/pyosis/element/manager.py +13 -1
- {osis_python-0.5.1 → osis_python-0.5.2}/src/pyosis/general/interface.py +15 -19
- {osis_python-0.5.1 → osis_python-0.5.2}/src/pyosis/geometry/manager.py +8 -0
- {osis_python-0.5.1 → osis_python-0.5.2}/src/pyosis/live/manager.py +15 -0
- {osis_python-0.5.1 → osis_python-0.5.2}/src/pyosis/load/manager.py +34 -0
- {osis_python-0.5.1 → osis_python-0.5.2}/src/pyosis/load/tendon.py +18 -0
- {osis_python-0.5.1 → osis_python-0.5.2}/src/pyosis/material/manager.py +8 -1
- {osis_python-0.5.1 → osis_python-0.5.2}/src/pyosis/node/manager.py +8 -0
- {osis_python-0.5.1 → osis_python-0.5.2}/src/pyosis/property/manager.py +49 -4
- {osis_python-0.5.1 → osis_python-0.5.2}/src/pyosis/section/manager.py +36 -7
- {osis_python-0.5.1 → osis_python-0.5.2}/src/pyosis/section/param.py +17 -8
- {osis_python-0.5.1 → osis_python-0.5.2}/src/pyosis/thickness/manager.py +8 -0
- {osis_python-0.5.1 → osis_python-0.5.2}/src/pyosis/transfer/generator.py +3 -2
- {osis_python-0.5.1 → osis_python-0.5.2}/src/pyosis/transfer/out_to_python.py +99 -5
- osis_python-0.5.2/tests/test_delete_occupied.py +432 -0
- {osis_python-0.5.1 → osis_python-0.5.2}/LICENSE +0 -0
- {osis_python-0.5.1 → osis_python-0.5.2}/README.md +0 -0
- {osis_python-0.5.1 → osis_python-0.5.2}/pyproject.toml +0 -0
- {osis_python-0.5.1 → osis_python-0.5.2}/setup.cfg +0 -0
- {osis_python-0.5.1 → osis_python-0.5.2}/src/osis_python.egg-info/dependency_links.txt +0 -0
- {osis_python-0.5.1 → osis_python-0.5.2}/src/osis_python.egg-info/requires.txt +0 -0
- {osis_python-0.5.1 → osis_python-0.5.2}/src/osis_python.egg-info/top_level.txt +0 -0
- {osis_python-0.5.1 → osis_python-0.5.2}/src/pyosis/boundary/__init__.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.2}/src/pyosis/boundary/interface.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.2}/src/pyosis/control/__init__.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.2}/src/pyosis/control/control.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.2}/src/pyosis/control/io.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.2}/src/pyosis/control/manager.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.2}/src/pyosis/control/nonlinear.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.2}/src/pyosis/core/all_func.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.2}/src/pyosis/core/apdl_sync.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.2}/src/pyosis/core/basic_manager.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.2}/src/pyosis/core/build.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.2}/src/pyosis/core/sync_apdl_cli.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.2}/src/pyosis/dynamic/__init__.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.2}/src/pyosis/dynamic/load_to_mass.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.2}/src/pyosis/dynamic/modal.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.2}/src/pyosis/dynamic/seismic.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.2}/src/pyosis/element/__init__.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.2}/src/pyosis/element/interface.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.2}/src/pyosis/general/__init__.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.2}/src/pyosis/geometry/__init__.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.2}/src/pyosis/geometry/interface.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.2}/src/pyosis/live/__init__.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.2}/src/pyosis/live/analysis.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.2}/src/pyosis/live/grade.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.2}/src/pyosis/live/lane.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.2}/src/pyosis/load/__init__.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.2}/src/pyosis/load/loadcase.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.2}/src/pyosis/load/static.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.2}/src/pyosis/material/__init__.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.2}/src/pyosis/material/interface.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.2}/src/pyosis/node/__init__.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.2}/src/pyosis/node/interface.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.2}/src/pyosis/post/__init__.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.2}/src/pyosis/post/combine.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.2}/src/pyosis/post/design_check.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.2}/src/pyosis/post/display.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.2}/src/pyosis/post/manager.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.2}/src/pyosis/project/__init__.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.2}/src/pyosis/project/interface.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.2}/src/pyosis/project/manager.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.2}/src/pyosis/property/__init__.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.2}/src/pyosis/property/component_thickness.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.2}/src/pyosis/property/coordinate.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.2}/src/pyosis/property/creep_shrink.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.2}/src/pyosis/property/damping.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.2}/src/pyosis/property/pu_curve.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.2}/src/pyosis/quick_building/__init__.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.2}/src/pyosis/quick_building/interface.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.2}/src/pyosis/result/__init__.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.2}/src/pyosis/result/check.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.2}/src/pyosis/result/env.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.2}/src/pyosis/result/loadcase.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.2}/src/pyosis/result/manager.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.2}/src/pyosis/result/result.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.2}/src/pyosis/section/__init__.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.2}/src/pyosis/section/common.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.2}/src/pyosis/section/composite.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.2}/src/pyosis/section/numeric.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.2}/src/pyosis/section/rebar.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.2}/src/pyosis/section/rib.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.2}/src/pyosis/section/steel.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.2}/src/pyosis/settlement/__init__.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.2}/src/pyosis/settlement/interface.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.2}/src/pyosis/settlement/manager.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.2}/src/pyosis/stability/__init__.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.2}/src/pyosis/stability/buckling.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.2}/src/pyosis/stability/manager.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.2}/src/pyosis/stage/__init__.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.2}/src/pyosis/stage/define.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.2}/src/pyosis/stage/manager.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.2}/src/pyosis/stage/overall.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.2}/src/pyosis/thickness/__init__.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.2}/src/pyosis/thickness/interface.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.2}/src/pyosis/transfer/__init__.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.2}/src/pyosis/transfer/matrix.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.2}/src/pyosis/transfer/parser.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.2}/src/pyosis/transfer/routes.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.2}/src/pyosis/transfer/split.py +0 -0
|
@@ -23,6 +23,8 @@ src/pyosis/core/build.py
|
|
|
23
23
|
src/pyosis/core/client.py
|
|
24
24
|
src/pyosis/core/command.py
|
|
25
25
|
src/pyosis/core/engine.py
|
|
26
|
+
src/pyosis/core/exceptions.py
|
|
27
|
+
src/pyosis/core/references.py
|
|
26
28
|
src/pyosis/core/sync_apdl_cli.py
|
|
27
29
|
src/pyosis/dynamic/__init__.py
|
|
28
30
|
src/pyosis/dynamic/load_to_mass.py
|
|
@@ -104,4 +106,5 @@ src/pyosis/transfer/matrix.py
|
|
|
104
106
|
src/pyosis/transfer/out_to_python.py
|
|
105
107
|
src/pyosis/transfer/parser.py
|
|
106
108
|
src/pyosis/transfer/routes.py
|
|
107
|
-
src/pyosis/transfer/split.py
|
|
109
|
+
src/pyosis/transfer/split.py
|
|
110
|
+
tests/test_delete_occupied.py
|
|
@@ -7,7 +7,7 @@ A library for extending OSIS functionality.
|
|
|
7
7
|
A library that allows users to use CAE with great flexibility.
|
|
8
8
|
"""
|
|
9
9
|
|
|
10
|
-
__version__ = "0.5.
|
|
10
|
+
__version__ = "0.5.2"
|
|
11
11
|
__author__ = "CCCC Highway Consultant Co. Ltd." # 中交公路规划设计院 - 工程技术研究中心 - lzh - wjh - myf
|
|
12
12
|
|
|
13
13
|
from .core.engine import OSISEngine
|
|
@@ -23,6 +23,7 @@ from typing import Any, Literal
|
|
|
23
23
|
from enum import IntEnum
|
|
24
24
|
|
|
25
25
|
from ..core.client import osis_client
|
|
26
|
+
from ..core import get_references, raise_if_occupied
|
|
26
27
|
from .interface import (
|
|
27
28
|
osis_boundary_general,
|
|
28
29
|
osis_boundary_elstcspt,
|
|
@@ -638,6 +639,10 @@ class BoundaryManager:
|
|
|
638
639
|
return 1
|
|
639
640
|
return max(bd.no for bd in boundaries) + 1
|
|
640
641
|
|
|
642
|
+
def get_dependencies(self, no: int) -> dict[str, list]:
|
|
643
|
+
"""查询边界被谁引用"""
|
|
644
|
+
return get_references("Boundary", no=no)
|
|
645
|
+
|
|
641
646
|
# ── 增删改 ────────────────────────────────
|
|
642
647
|
def create(self, no: int | None, type: str, *args: Any, **kwargs: Any) -> Boundary:
|
|
643
648
|
"""创建边界(便捷入口,内部转发到对应 create_* 方法)
|
|
@@ -846,7 +851,14 @@ class BoundaryManager:
|
|
|
846
851
|
return self.get(no) # type: ignore[return-value]
|
|
847
852
|
|
|
848
853
|
def delete(self, no: int) -> None:
|
|
849
|
-
"""删除边界
|
|
854
|
+
"""删除边界
|
|
855
|
+
|
|
856
|
+
Raises:
|
|
857
|
+
DependencyError: 存在依赖项时
|
|
858
|
+
RuntimeError: 删除失败时抛出异常
|
|
859
|
+
"""
|
|
860
|
+
deps = self.get_dependencies(no)
|
|
861
|
+
raise_if_occupied("Boundary", deps, no=no)
|
|
850
862
|
ok, err = osis_boundary_del(no)
|
|
851
863
|
if not ok:
|
|
852
864
|
raise RuntimeError(f"删除边界 {no} 失败: {err}")
|
|
@@ -26,6 +26,8 @@ session.mount("https://", adapter) # 如果你后续用HTTPS
|
|
|
26
26
|
|
|
27
27
|
DEFAULT_PORT = 18080
|
|
28
28
|
DEFAULT_URL = "http://localhost"
|
|
29
|
+
DEFAULT_TIMEOUT = 300
|
|
30
|
+
DEFAULT_SOLVE_TIMEOUT = 600
|
|
29
31
|
|
|
30
32
|
def set_osis_url(url):
|
|
31
33
|
'''
|
|
@@ -42,12 +44,19 @@ def set_osis_port(port):
|
|
|
42
44
|
DEFAULT_PORT = port
|
|
43
45
|
|
|
44
46
|
# ========== 通用客户端函数(复用连接池) ==========
|
|
45
|
-
def osis_client(
|
|
47
|
+
def osis_client(
|
|
48
|
+
func_name: str,
|
|
49
|
+
payload: dict,
|
|
50
|
+
base_url=None,
|
|
51
|
+
timeout: float | None = None,
|
|
52
|
+
) -> dict:
|
|
46
53
|
"""
|
|
47
54
|
通用 OSIS 接口客户端(复用连接池,高效批量调用)
|
|
48
55
|
Args:
|
|
49
56
|
func_name: C++ 接口名(如 "OSIS_Run")
|
|
50
57
|
payload: 请求参数字典(自动序列化为 JSON)
|
|
58
|
+
base_url: url
|
|
59
|
+
timeout: HTTP 超时秒数,默认 DEFAULT_TIMEOUT
|
|
51
60
|
Returns:
|
|
52
61
|
异常时返回 (False, 错误信息)
|
|
53
62
|
"""
|
|
@@ -59,7 +68,7 @@ def osis_client(func_name: str, payload: dict, base_url=None) -> dict:
|
|
|
59
68
|
url,
|
|
60
69
|
data=json.dumps(payload, ensure_ascii=False).encode("utf-8"),
|
|
61
70
|
headers={"Content-Type": "application/json; charset=utf-8"},
|
|
62
|
-
timeout=
|
|
71
|
+
timeout=timeout if timeout is not None else DEFAULT_TIMEOUT,
|
|
63
72
|
)
|
|
64
73
|
|
|
65
74
|
data = None
|
|
@@ -19,7 +19,11 @@ from .client import osis_client
|
|
|
19
19
|
# f.write(f"[{timestamp}] {text}\n")
|
|
20
20
|
# f.close()
|
|
21
21
|
|
|
22
|
-
def osis_run(
|
|
22
|
+
def osis_run(
|
|
23
|
+
strCmd: str = "",
|
|
24
|
+
mode: Literal["stash", "exec"] = "exec",
|
|
25
|
+
timeout: float | None = None,
|
|
26
|
+
) -> tuple[bool, str]:
|
|
23
27
|
"""
|
|
24
28
|
http 模拟 C++ 原生 OSIS_Run 函数
|
|
25
29
|
Args:
|
|
@@ -27,11 +31,16 @@ def osis_run(strCmd: str="", mode: Literal["stash", "exec"]="exec") -> tuple[boo
|
|
|
27
31
|
mode: 运行模式,此参数为了同时执行多条命令提高效率
|
|
28
32
|
* 使用 stash 仅会将命令流存到OSIS中,不会执行
|
|
29
33
|
* 收到 exec 信号才会执行暂存包括当前的所有命令流。
|
|
34
|
+
timeout: HTTP 超时秒数,默认由 osis_client 决定
|
|
30
35
|
|
|
31
36
|
Returns:
|
|
32
37
|
tuple (bool, str): 是否成功,失败原因
|
|
33
38
|
"""
|
|
34
|
-
response = osis_client(
|
|
39
|
+
response = osis_client(
|
|
40
|
+
"OSIS_Run",
|
|
41
|
+
{"strCmd": strCmd, "mode": mode},
|
|
42
|
+
timeout=timeout,
|
|
43
|
+
)
|
|
35
44
|
return response['success'], response['error']
|
|
36
45
|
|
|
37
46
|
def _log(text, log_dir="pyosis_logs"):
|
|
@@ -69,7 +69,7 @@ class OSISEngine:
|
|
|
69
69
|
- tendon: 钢束管理器(含 prop/shape 子管理器)
|
|
70
70
|
- live: 活载管理器(含 grade/lane/case 子管理器)
|
|
71
71
|
- geometry: 几何管理器(三维样条曲线)
|
|
72
|
-
- property
|
|
72
|
+
- prop: 属性管理器(property 坐标系、收缩徐变、阻尼等)
|
|
73
73
|
- thickness: 厚度管理器(壳厚度特性)
|
|
74
74
|
- control: 控制管理器(全局参数、分析设置)
|
|
75
75
|
- project: 项目管理器(创建、打开、保存项目)
|
|
@@ -246,9 +246,13 @@ class OSISEngine:
|
|
|
246
246
|
if not ok:
|
|
247
247
|
raise RuntimeError(f"执行失败: {err}")
|
|
248
248
|
|
|
249
|
-
def solve(self) -> None:
|
|
250
|
-
"""求解工程
|
|
251
|
-
|
|
249
|
+
def solve(self, timeout: float | None = None) -> None:
|
|
250
|
+
"""求解工程
|
|
251
|
+
|
|
252
|
+
Args:
|
|
253
|
+
timeout: HTTP 超时秒数,默认 600(10 分钟)
|
|
254
|
+
"""
|
|
255
|
+
ok, err = osis_solve(timeout=timeout)
|
|
252
256
|
if not ok:
|
|
253
257
|
raise RuntimeError(f"求解失败: {err}")
|
|
254
258
|
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"""
|
|
2
|
+
pyosis 自定义异常
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
class DependencyError(RuntimeError):
|
|
6
|
+
"""删除实体时存在依赖项
|
|
7
|
+
|
|
8
|
+
Attributes:
|
|
9
|
+
entity_type: 实体类型字符串,如 "Material"
|
|
10
|
+
id_value: 实体编号(int)或名称(str)
|
|
11
|
+
no: 按编号寻址时的编号,否则为 None
|
|
12
|
+
name: 按名称寻址时的名称,否则为 None
|
|
13
|
+
dependencies: 依赖关系字典
|
|
14
|
+
"""
|
|
15
|
+
def __init__(self, entity_type: str, id_value: int | str, dependencies: dict[str, list]):
|
|
16
|
+
self.entity_type = entity_type
|
|
17
|
+
self.id_value = id_value
|
|
18
|
+
self.dependencies = dependencies
|
|
19
|
+
if isinstance(id_value, int):
|
|
20
|
+
self.no = id_value
|
|
21
|
+
self.name = None
|
|
22
|
+
label = f"#{id_value}"
|
|
23
|
+
else:
|
|
24
|
+
self.no = None
|
|
25
|
+
self.name = id_value
|
|
26
|
+
label = id_value
|
|
27
|
+
|
|
28
|
+
lines = [f"无法删除 {entity_type} {label},存在以下依赖:"]
|
|
29
|
+
for kind, refs in dependencies.items():
|
|
30
|
+
if refs:
|
|
31
|
+
lines.append(f" - {kind}: {refs}")
|
|
32
|
+
super().__init__("\n".join(lines))
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"""
|
|
2
|
+
通用引用查询客户端封装
|
|
3
|
+
|
|
4
|
+
后端 C++ 暴露 /GetReferences 接口,根据 entityType 字符串分派
|
|
5
|
+
到对应 Info 类的 getRelated* 方法。
|
|
6
|
+
"""
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
from typing import Literal
|
|
9
|
+
from .client import osis_client
|
|
10
|
+
from .exceptions import DependencyError
|
|
11
|
+
|
|
12
|
+
# 支持的实体类型(与 C++ GetReferences.cpp 中的 if-else 分支对齐)
|
|
13
|
+
EntityType = Literal[
|
|
14
|
+
"Material", "Section", "Node", "Element", "Boundary",
|
|
15
|
+
"TendonShape", "TendonProp", "LoadCase", "LiveGrade", "LiveLane",
|
|
16
|
+
"CoorSys", "CreepShrink", "PUCurve", "ShellThickness",
|
|
17
|
+
"Damping", "Spline",
|
|
18
|
+
]
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
"""
|
|
22
|
+
通用引用查询客户端封装
|
|
23
|
+
后端 /GetReferences 统一字符串协议:{entityType, idKey("no"|"name"), idValue}
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def get_references(entity_type: str, *, no: int | None = None, name: str | None = None) -> dict[str, list]:
|
|
29
|
+
"""查询某个实体被哪些其他实体引用
|
|
30
|
+
|
|
31
|
+
Args:
|
|
32
|
+
entity_type: 实体类型,如 "Material" / "Node" / "TendonShape" / "LoadCase"
|
|
33
|
+
no: 按编号寻址时传(Material/Section/Node/Element)
|
|
34
|
+
name: 按名称寻址时传(TendonShape/LoadCase/...)
|
|
35
|
+
no 与 name 二选一。
|
|
36
|
+
|
|
37
|
+
Returns:
|
|
38
|
+
引用关系字典,如 {"elements":[101,102], "loads":["自重"], ...}
|
|
39
|
+
无依赖时返回空字典。
|
|
40
|
+
|
|
41
|
+
Raises:
|
|
42
|
+
ValueError: no/name 都没传,或都传了
|
|
43
|
+
RuntimeError: 查询失败
|
|
44
|
+
"""
|
|
45
|
+
if no is not None and name is not None:
|
|
46
|
+
raise ValueError("no 与 name 只能传一个")
|
|
47
|
+
if no is None and name is None:
|
|
48
|
+
raise ValueError("必须提供 no 或 name")
|
|
49
|
+
|
|
50
|
+
if no is not None:
|
|
51
|
+
id_key, id_value = "no", str(no)
|
|
52
|
+
else:
|
|
53
|
+
id_key, id_value = "name", name
|
|
54
|
+
|
|
55
|
+
resp = osis_client("GetReferences", {
|
|
56
|
+
"entityType": entity_type,
|
|
57
|
+
"idKey": id_key,
|
|
58
|
+
"idValue": id_value,
|
|
59
|
+
})
|
|
60
|
+
if not resp.get("success"):
|
|
61
|
+
raise RuntimeError(f"查询 {entity_type}({id_key}={id_value}) 引用失败: {resp.get('error')}")
|
|
62
|
+
return resp.get("data") or {}
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def raise_if_occupied(
|
|
66
|
+
entity_type: str,
|
|
67
|
+
deps: dict[str, list],
|
|
68
|
+
*,
|
|
69
|
+
no: int | None = None,
|
|
70
|
+
name: str | None = None,
|
|
71
|
+
) -> None:
|
|
72
|
+
"""存在非空依赖时抛出 DependencyError。
|
|
73
|
+
|
|
74
|
+
Args:
|
|
75
|
+
entity_type: 实体类型,如 "Material" / "TendonShape"
|
|
76
|
+
deps: get_references / get_dependencies 返回的依赖字典
|
|
77
|
+
no: 按编号寻址时传
|
|
78
|
+
name: 按名称寻址时传
|
|
79
|
+
"""
|
|
80
|
+
non_empty = {k: v for k, v in deps.items() if v}
|
|
81
|
+
if not non_empty:
|
|
82
|
+
return
|
|
83
|
+
if no is None and name is None:
|
|
84
|
+
raise ValueError("必须提供 no 或 name")
|
|
85
|
+
id_value = no if no is not None else name
|
|
86
|
+
raise DependencyError(entity_type, id_value, non_empty)
|
|
87
|
+
|
|
@@ -579,7 +579,7 @@ class RspecAnalManager:
|
|
|
579
579
|
|
|
580
580
|
def _load(self) -> list[RspecAnal]:
|
|
581
581
|
"""从服务端加载所有反应谱工况信息"""
|
|
582
|
-
resp = osis_client("
|
|
582
|
+
resp = osis_client("GetAllRespSpecInfo", {})
|
|
583
583
|
if not resp['success']:
|
|
584
584
|
raise RuntimeError(f"{resp['error']}")
|
|
585
585
|
rsp = [RspecAnal._from_dict(d) for d in resp.get("data", [])]
|
|
@@ -594,7 +594,7 @@ class RspecAnalManager:
|
|
|
594
594
|
names = [str(name)]
|
|
595
595
|
if not isinstance(names, list):
|
|
596
596
|
raise TypeError(f"不支持的名称类型: {type(name)}")
|
|
597
|
-
resp = osis_client("
|
|
597
|
+
resp = osis_client("GetRespSpecInfoByNames", {"name": names})
|
|
598
598
|
if not resp['success']:
|
|
599
599
|
raise RuntimeError(f"{resp['error']}")
|
|
600
600
|
rsp = [RspecAnal._from_dict(d) if d else None for d in resp.get("data", [])]
|
|
@@ -15,6 +15,7 @@ from dataclasses import dataclass, field
|
|
|
15
15
|
from typing import Any, Literal
|
|
16
16
|
from enum import Enum
|
|
17
17
|
from ..core.client import osis_client
|
|
18
|
+
from ..core import get_references, raise_if_occupied
|
|
18
19
|
from .interface import (
|
|
19
20
|
osis_element_beam3d,
|
|
20
21
|
osis_element_truss,
|
|
@@ -555,6 +556,10 @@ class ElementManager:
|
|
|
555
556
|
ele_no = [ele.no for ele in elements]
|
|
556
557
|
return max(ele_no) + 1
|
|
557
558
|
|
|
559
|
+
def get_dependencies(self, no: int) -> dict[str, list]:
|
|
560
|
+
"""查询单元被谁引用"""
|
|
561
|
+
return get_references("Element", no=no)
|
|
562
|
+
|
|
558
563
|
# ── 增删改 ────────────────────────────────
|
|
559
564
|
def create(self, no: int | None, type: str, *args: Any, **kwargs: Any) -> Element:
|
|
560
565
|
"""创建单元(便捷入口,内部转发到对应 create_* 方法)
|
|
@@ -699,7 +704,14 @@ class ElementManager:
|
|
|
699
704
|
return self.get(no)
|
|
700
705
|
|
|
701
706
|
def delete(self, no: int) -> None:
|
|
702
|
-
"""删除单元
|
|
707
|
+
"""删除单元
|
|
708
|
+
|
|
709
|
+
Raises:
|
|
710
|
+
DependencyError: 存在依赖项时
|
|
711
|
+
RuntimeError: 删除失败时抛出异常
|
|
712
|
+
"""
|
|
713
|
+
deps = self.get_dependencies(no)
|
|
714
|
+
raise_if_occupied("Element", deps, no=no)
|
|
703
715
|
ok, err = osis_element_del(no)
|
|
704
716
|
if not ok:
|
|
705
717
|
raise RuntimeError(f"删除单元 {no} 失败: {err}")
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from typing import Any, Dict, Literal, List, Union, Sequence
|
|
2
2
|
from ..core import REGISTRY, osis_run
|
|
3
|
-
from ..core.client import osis_client
|
|
3
|
+
from ..core.client import DEFAULT_SOLVE_TIMEOUT, osis_client
|
|
4
4
|
|
|
5
5
|
def osis_matrix(matrix_name: str, matrix_data: Union[List, int, float, str]):
|
|
6
6
|
"""
|
|
@@ -11,7 +11,7 @@ def osis_matrix(matrix_name: str, matrix_data: Union[List, int, float, str]):
|
|
|
11
11
|
matrix_data: 任意维度的列表(1维/2维/3维/...)或单个数值(0维)
|
|
12
12
|
|
|
13
13
|
Returns:
|
|
14
|
-
|
|
14
|
+
tuple (bool, str): 是否成功,失败原因
|
|
15
15
|
|
|
16
16
|
Example:
|
|
17
17
|
>>> # 2维矩阵示例
|
|
@@ -92,14 +92,10 @@ def osis_matrix(matrix_name: str, matrix_data: Union[List, int, float, str]):
|
|
|
92
92
|
new_indices = indices + [idx]
|
|
93
93
|
generate_assignments(elem, new_indices)
|
|
94
94
|
else:
|
|
95
|
-
# 处理数值赋值
|
|
96
95
|
value = data
|
|
97
|
-
|
|
98
|
-
# 格式化数值
|
|
99
|
-
if isinstance(value, int) or isinstance(value, float):
|
|
96
|
+
if isinstance(value, (int, float)):
|
|
100
97
|
val_str = str(value)
|
|
101
98
|
else:
|
|
102
|
-
# 其他类型尝试转为string
|
|
103
99
|
val_str = f"\"{value}\""
|
|
104
100
|
idx_parts = list(indices)
|
|
105
101
|
if not is_charn:
|
|
@@ -107,17 +103,11 @@ def osis_matrix(matrix_name: str, matrix_data: Union[List, int, float, str]):
|
|
|
107
103
|
idx_parts.append(0)
|
|
108
104
|
idx_str = ",".join(map(str, idx_parts))
|
|
109
105
|
assign_cmd = f"{matrix_name}[{idx_str}] = {val_str}"
|
|
110
|
-
# _log(assign_cmd)
|
|
111
|
-
# osis_run(assign_cmd, "stash")
|
|
112
106
|
all_cmds.append(assign_cmd)
|
|
113
|
-
|
|
114
|
-
# 开始递归生成赋值语句(OSIS索引从0开始)
|
|
107
|
+
|
|
115
108
|
generate_assignments(matrix_data, [])
|
|
116
|
-
|
|
117
|
-
# 返回拼接后的完整命令字符串
|
|
118
|
-
# str_cmds = "\n".join(all_cmds)
|
|
109
|
+
|
|
119
110
|
str_cmds = ";".join(all_cmds)
|
|
120
|
-
# _log(str_cmds)
|
|
121
111
|
return osis_run(str_cmds, "exec")
|
|
122
112
|
|
|
123
113
|
def output_result_for_calc_book():
|
|
@@ -154,12 +144,18 @@ def osis_clc():
|
|
|
154
144
|
"""
|
|
155
145
|
pass
|
|
156
146
|
|
|
157
|
-
|
|
158
|
-
def osis_solve():
|
|
147
|
+
def osis_solve(timeout: float | None = None):
|
|
159
148
|
"""
|
|
160
149
|
求解工程
|
|
161
|
-
|
|
150
|
+
|
|
151
|
+
Args:
|
|
152
|
+
timeout: HTTP 超时秒数,默认 600(10 分钟)
|
|
153
|
+
|
|
162
154
|
Returns:
|
|
163
155
|
tuple (bool, str): 是否成功,失败原因
|
|
164
156
|
"""
|
|
165
|
-
|
|
157
|
+
return osis_run(
|
|
158
|
+
"Solve;",
|
|
159
|
+
"exec",
|
|
160
|
+
timeout=timeout if timeout is not None else DEFAULT_SOLVE_TIMEOUT,
|
|
161
|
+
)
|
|
@@ -19,6 +19,7 @@ from enum import Enum
|
|
|
19
19
|
from typing import Literal, Any
|
|
20
20
|
|
|
21
21
|
from ..core.client import osis_client
|
|
22
|
+
from ..core import get_references, raise_if_occupied
|
|
22
23
|
from .interface import (
|
|
23
24
|
osis_spline3d_general,
|
|
24
25
|
osis_spline3d_natural,
|
|
@@ -286,6 +287,10 @@ class GeometryManager:
|
|
|
286
287
|
raise RuntimeError(f"创建3D圆弧 {name} 失败: {err}")
|
|
287
288
|
return self.get(name)
|
|
288
289
|
|
|
290
|
+
def get_dependencies(self, name: str) -> dict[str, list]:
|
|
291
|
+
"""查询几何样条被谁引用"""
|
|
292
|
+
return get_references("Spline", name=name)
|
|
293
|
+
|
|
289
294
|
def delete(self, name: str) -> None:
|
|
290
295
|
"""删除三维样条曲线
|
|
291
296
|
|
|
@@ -293,8 +298,11 @@ class GeometryManager:
|
|
|
293
298
|
name: 曲线名称
|
|
294
299
|
|
|
295
300
|
Raises:
|
|
301
|
+
DependencyError: 存在依赖项时
|
|
296
302
|
RuntimeError: 删除失败时抛出异常
|
|
297
303
|
"""
|
|
304
|
+
deps = self.get_dependencies(name)
|
|
305
|
+
raise_if_occupied("Spline", deps, name=name)
|
|
298
306
|
ok, err = osis_spline3d_del(name)
|
|
299
307
|
if not ok:
|
|
300
308
|
raise RuntimeError(f"删除样条曲线 {name} 失败: {err}")
|
|
@@ -17,6 +17,7 @@ from dataclasses import dataclass, field
|
|
|
17
17
|
from typing import Literal, Any
|
|
18
18
|
|
|
19
19
|
from ..core.client import osis_client
|
|
20
|
+
from ..core import get_references, raise_if_occupied
|
|
20
21
|
from .grade import (
|
|
21
22
|
osis_livegrade_highway,
|
|
22
23
|
osis_livegrade_vehicle,
|
|
@@ -499,6 +500,10 @@ class LiveGradeManager:
|
|
|
499
500
|
]
|
|
500
501
|
return grades
|
|
501
502
|
|
|
503
|
+
def get_dependencies(self, name: str) -> dict[str, list]:
|
|
504
|
+
"""查询活载等级被谁引用"""
|
|
505
|
+
return get_references("LiveGrade", name=name)
|
|
506
|
+
|
|
502
507
|
def create(
|
|
503
508
|
self,
|
|
504
509
|
name: str,
|
|
@@ -713,8 +718,11 @@ class LiveGradeManager:
|
|
|
713
718
|
name: 活载等级名称
|
|
714
719
|
|
|
715
720
|
Raises:
|
|
721
|
+
DependencyError: 存在依赖项时
|
|
716
722
|
RuntimeError: 删除失败时抛出异常
|
|
717
723
|
"""
|
|
724
|
+
deps = self.get_dependencies(name)
|
|
725
|
+
raise_if_occupied("LiveGrade", deps, name=name)
|
|
718
726
|
ok, err = osis_livegrade_del(name)
|
|
719
727
|
if not ok:
|
|
720
728
|
raise RuntimeError(f"删除活载等级 {name} 失败: {err}")
|
|
@@ -815,6 +823,10 @@ class LaneManager:
|
|
|
815
823
|
]
|
|
816
824
|
return lanes
|
|
817
825
|
|
|
826
|
+
def get_dependencies(self, name: str) -> dict[str, list]:
|
|
827
|
+
"""查询车道被谁引用"""
|
|
828
|
+
return get_references("LiveLane", name=name)
|
|
829
|
+
|
|
818
830
|
def create(
|
|
819
831
|
self,
|
|
820
832
|
name: str,
|
|
@@ -966,8 +978,11 @@ class LaneManager:
|
|
|
966
978
|
name: 车道名称
|
|
967
979
|
|
|
968
980
|
Raises:
|
|
981
|
+
DependencyError: 存在依赖项时
|
|
969
982
|
RuntimeError: 删除失败时抛出异常
|
|
970
983
|
"""
|
|
984
|
+
deps = self.get_dependencies(name)
|
|
985
|
+
raise_if_occupied("LiveLane", deps, name=name)
|
|
971
986
|
ok, err = osis_lane_del(name)
|
|
972
987
|
if not ok:
|
|
973
988
|
raise RuntimeError(f"删除车道 {name} 失败: {err}")
|
|
@@ -17,6 +17,7 @@ from typing import Literal, Any
|
|
|
17
17
|
from enum import Enum
|
|
18
18
|
|
|
19
19
|
from ..core.client import osis_client
|
|
20
|
+
from ..core import get_references, raise_if_occupied
|
|
20
21
|
from .loadcase import (
|
|
21
22
|
osis_loadcase,
|
|
22
23
|
osis_loadcase_del,
|
|
@@ -38,6 +39,7 @@ from .tendon import (
|
|
|
38
39
|
osis_tendon_shape_mod,
|
|
39
40
|
osis_layout_tendons,
|
|
40
41
|
osis_wipe_tendons,
|
|
42
|
+
osis_bottom_tendons,
|
|
41
43
|
)
|
|
42
44
|
from .static import (
|
|
43
45
|
osis_load_gravity,
|
|
@@ -860,6 +862,17 @@ class TendonShape:
|
|
|
860
862
|
if not ok:
|
|
861
863
|
raise RuntimeError(f"擦除钢束 {self.name} 失败: {err}")
|
|
862
864
|
|
|
865
|
+
def bottom(self, b_bot: int, *bot: int) -> None:
|
|
866
|
+
"""定义是否沿梁单元底板布置钢束形状
|
|
867
|
+
|
|
868
|
+
Args:
|
|
869
|
+
b_bot: 0=不沿底板布置,1=沿底板布置
|
|
870
|
+
*bot: 底板布置对应的样条曲线行号,数量不限(Bot_i, Bot_j, ...)
|
|
871
|
+
"""
|
|
872
|
+
ok, err = osis_bottom_tendons(self.name, b_bot, *bot)
|
|
873
|
+
if not ok:
|
|
874
|
+
raise RuntimeError(f"设置钢束 {self.name} 底板布置失败: {err}")
|
|
875
|
+
|
|
863
876
|
def rename(self, new_name: str) -> None:
|
|
864
877
|
"""重命名钢束形状
|
|
865
878
|
|
|
@@ -897,6 +910,10 @@ class TendonPropManager:
|
|
|
897
910
|
]
|
|
898
911
|
return props
|
|
899
912
|
|
|
913
|
+
def get_dependencies(self, name: str) -> dict[str, list]:
|
|
914
|
+
"""查询钢束特性被谁引用"""
|
|
915
|
+
return get_references("TendonProp", name=name)
|
|
916
|
+
|
|
900
917
|
def create(
|
|
901
918
|
self,
|
|
902
919
|
name: str,
|
|
@@ -1207,8 +1224,11 @@ class TendonPropManager:
|
|
|
1207
1224
|
name: 钢束特性名称
|
|
1208
1225
|
|
|
1209
1226
|
Raises:
|
|
1227
|
+
DependencyError: 存在依赖项时
|
|
1210
1228
|
RuntimeError: 删除失败时抛出异常
|
|
1211
1229
|
"""
|
|
1230
|
+
deps = self.get_dependencies(name)
|
|
1231
|
+
raise_if_occupied("TendonProp", deps, name=name)
|
|
1212
1232
|
ok, err = osis_tendon_prop_del(name)
|
|
1213
1233
|
if not ok:
|
|
1214
1234
|
raise RuntimeError(f"删除钢束特性 {name} 失败: {err}")
|
|
@@ -1308,6 +1328,10 @@ class TendonShapeManager:
|
|
|
1308
1328
|
]
|
|
1309
1329
|
return shapes
|
|
1310
1330
|
|
|
1331
|
+
def get_dependencies(self, name: str) -> dict[str, list]:
|
|
1332
|
+
"""查询钢束形状被谁引用"""
|
|
1333
|
+
return get_references("TendonShape", name=name)
|
|
1334
|
+
|
|
1311
1335
|
def create(
|
|
1312
1336
|
self,
|
|
1313
1337
|
name: str,
|
|
@@ -1463,8 +1487,11 @@ class TendonShapeManager:
|
|
|
1463
1487
|
name: 钢束形状名称
|
|
1464
1488
|
|
|
1465
1489
|
Raises:
|
|
1490
|
+
DependencyError: 存在依赖项时
|
|
1466
1491
|
RuntimeError: 删除失败时抛出异常
|
|
1467
1492
|
"""
|
|
1493
|
+
deps = self.get_dependencies(name)
|
|
1494
|
+
raise_if_occupied("TendonShape", deps, name=name)
|
|
1468
1495
|
ok, err = osis_tendon_shape_del(name)
|
|
1469
1496
|
if not ok:
|
|
1470
1497
|
raise RuntimeError(f"删除钢束形状 {name} 失败: {err}")
|
|
@@ -1628,6 +1655,10 @@ class LoadCaseManager:
|
|
|
1628
1655
|
]
|
|
1629
1656
|
return loadcases
|
|
1630
1657
|
|
|
1658
|
+
def get_dependencies(self, name: str) -> dict[str, list]:
|
|
1659
|
+
"""查询荷载工况被谁引用"""
|
|
1660
|
+
return get_references("LoadCase", name=name)
|
|
1661
|
+
|
|
1631
1662
|
# ── 增删改 ────────────────────────────────
|
|
1632
1663
|
|
|
1633
1664
|
def create(
|
|
@@ -1690,8 +1721,11 @@ class LoadCaseManager:
|
|
|
1690
1721
|
name: 荷载工况名称
|
|
1691
1722
|
|
|
1692
1723
|
Raises:
|
|
1724
|
+
DependencyError: 存在依赖项时
|
|
1693
1725
|
RuntimeError: 删除失败时抛出异常
|
|
1694
1726
|
"""
|
|
1727
|
+
deps = self.get_dependencies(name)
|
|
1728
|
+
raise_if_occupied("LoadCase", deps, name=name)
|
|
1695
1729
|
ok, err = osis_loadcase_del(name)
|
|
1696
1730
|
if not ok:
|
|
1697
1731
|
raise RuntimeError(f"删除荷载工况 {name} 失败: {err}")
|
|
@@ -328,3 +328,21 @@ def osis_wipe_tendons(strShapeName: str):
|
|
|
328
328
|
tuple (bool, str): 是否成功,失败原因
|
|
329
329
|
'''
|
|
330
330
|
pass
|
|
331
|
+
|
|
332
|
+
@REGISTRY.register("BottomTS")
|
|
333
|
+
def osis_bottom_tendons(TdShapeName: str, bBot: int, *Bot: int):
|
|
334
|
+
'''
|
|
335
|
+
定义是否沿梁单元底板布置钢束形状
|
|
336
|
+
|
|
337
|
+
Args:
|
|
338
|
+
TdShapeName (str): 钢束形状名称
|
|
339
|
+
bBot (int): 是否沿底板布置
|
|
340
|
+
* 0 = 不沿底板布置
|
|
341
|
+
* 1 = 沿底板布置
|
|
342
|
+
*Bot (int): 底板布置钢束对应的样条曲线行号,数量不限
|
|
343
|
+
(如 Bot_i, Bot_j, Bot_k, ...)
|
|
344
|
+
|
|
345
|
+
Returns:
|
|
346
|
+
tuple (bool, str): 是否成功,失败原因
|
|
347
|
+
'''
|
|
348
|
+
pass
|
|
@@ -23,7 +23,7 @@ from .interface import (
|
|
|
23
23
|
osis_material_del,
|
|
24
24
|
osis_material_mod,
|
|
25
25
|
)
|
|
26
|
-
|
|
26
|
+
from ..core import get_references, raise_if_occupied
|
|
27
27
|
|
|
28
28
|
# ──────────────────────────────────────────────
|
|
29
29
|
# 数据类
|
|
@@ -118,6 +118,10 @@ class MaterialManager:
|
|
|
118
118
|
|
|
119
119
|
return materials
|
|
120
120
|
|
|
121
|
+
def get_dependencies(self, no: int) -> dict[str, list]:
|
|
122
|
+
"""查询材料被谁引用"""
|
|
123
|
+
return get_references("Material", no=no)
|
|
124
|
+
|
|
121
125
|
def _next_no(self) -> int:
|
|
122
126
|
"""生成下一个可用材料编号
|
|
123
127
|
|
|
@@ -342,8 +346,11 @@ class MaterialManager:
|
|
|
342
346
|
no: 材料编号
|
|
343
347
|
|
|
344
348
|
Raises:
|
|
349
|
+
DependencyError: 存在依赖项时(force=False 才会抛)
|
|
345
350
|
RuntimeError: 删除失败时抛出异常
|
|
346
351
|
"""
|
|
352
|
+
deps = self.get_dependencies(no)
|
|
353
|
+
raise_if_occupied("Material", deps, no=no)
|
|
347
354
|
ok, err = osis_material_del(no)
|
|
348
355
|
if not ok:
|
|
349
356
|
raise RuntimeError(f"删除材料 {no} 失败: {err}")
|