osis-python 0.5.0__tar.gz → 0.5.1__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.0/src/osis_python.egg-info → osis_python-0.5.1}/PKG-INFO +1 -1
- {osis_python-0.5.0 → osis_python-0.5.1/src/osis_python.egg-info}/PKG-INFO +1 -1
- {osis_python-0.5.0 → osis_python-0.5.1}/src/osis_python.egg-info/SOURCES.txt +2 -2
- {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/__init__.py +1 -1
- {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/core/apdl_sync.py +53 -11
- {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/core/sync_apdl_cli.py +7 -19
- osis_python-0.5.0/src/pyosis/transfer/sync_exec.py → osis_python-0.5.1/src/pyosis/transfer/out_to_python.py +13 -117
- {osis_python-0.5.0 → osis_python-0.5.1}/LICENSE +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/README.md +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/pyproject.toml +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/setup.cfg +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/src/osis_python.egg-info/dependency_links.txt +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/src/osis_python.egg-info/requires.txt +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/src/osis_python.egg-info/top_level.txt +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/boundary/__init__.py +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/boundary/interface.py +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/boundary/manager.py +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/control/__init__.py +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/control/control.py +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/control/io.py +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/control/manager.py +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/control/nonlinear.py +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/core/__init__.py +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/core/all_func.py +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/core/basic_manager.py +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/core/build.py +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/core/client.py +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/core/command.py +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/core/engine.py +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/dynamic/__init__.py +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/dynamic/load_to_mass.py +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/dynamic/manager.py +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/dynamic/modal.py +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/dynamic/seismic.py +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/element/__init__.py +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/element/interface.py +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/element/manager.py +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/general/__init__.py +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/general/interface.py +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/geometry/__init__.py +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/geometry/interface.py +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/geometry/manager.py +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/live/__init__.py +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/live/analysis.py +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/live/grade.py +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/live/lane.py +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/live/manager.py +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/load/__init__.py +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/load/loadcase.py +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/load/manager.py +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/load/static.py +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/load/tendon.py +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/material/__init__.py +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/material/interface.py +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/material/manager.py +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/node/__init__.py +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/node/interface.py +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/node/manager.py +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/post/__init__.py +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/post/combine.py +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/post/design_check.py +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/post/display.py +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/post/manager.py +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/project/__init__.py +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/project/interface.py +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/project/manager.py +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/property/__init__.py +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/property/component_thickness.py +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/property/coordinate.py +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/property/creep_shrink.py +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/property/damping.py +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/property/manager.py +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/property/pu_curve.py +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/quick_building/__init__.py +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/quick_building/interface.py +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/result/__init__.py +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/result/check.py +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/result/env.py +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/result/loadcase.py +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/result/manager.py +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/result/result.py +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/section/__init__.py +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/section/common.py +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/section/composite.py +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/section/manager.py +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/section/numeric.py +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/section/param.py +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/section/rebar.py +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/section/rib.py +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/section/steel.py +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/settlement/__init__.py +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/settlement/interface.py +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/settlement/manager.py +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/stability/__init__.py +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/stability/buckling.py +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/stability/manager.py +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/stage/__init__.py +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/stage/define.py +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/stage/manager.py +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/stage/overall.py +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/thickness/__init__.py +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/thickness/interface.py +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/thickness/manager.py +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/transfer/__init__.py +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/transfer/generator.py +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/transfer/matrix.py +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/transfer/parser.py +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/transfer/routes.py +0 -0
- {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/transfer/split.py +0 -0
|
@@ -101,7 +101,7 @@ src/pyosis/thickness/manager.py
|
|
|
101
101
|
src/pyosis/transfer/__init__.py
|
|
102
102
|
src/pyosis/transfer/generator.py
|
|
103
103
|
src/pyosis/transfer/matrix.py
|
|
104
|
+
src/pyosis/transfer/out_to_python.py
|
|
104
105
|
src/pyosis/transfer/parser.py
|
|
105
106
|
src/pyosis/transfer/routes.py
|
|
106
|
-
src/pyosis/transfer/split.py
|
|
107
|
-
src/pyosis/transfer/sync_exec.py
|
|
107
|
+
src/pyosis/transfer/split.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.1"
|
|
11
11
|
__author__ = "CCCC Highway Consultant Co. Ltd." # 中交公路规划设计院 - 工程技术研究中心 - lzh - wjh - myf
|
|
12
12
|
|
|
13
13
|
from .core.engine import OSISEngine
|
|
@@ -21,17 +21,24 @@ from dataclasses import dataclass
|
|
|
21
21
|
from pathlib import Path
|
|
22
22
|
from typing import TYPE_CHECKING
|
|
23
23
|
|
|
24
|
+
from ..transfer import parse_text
|
|
25
|
+
from ..transfer.out_to_python import write_prep_outputs
|
|
26
|
+
|
|
24
27
|
if TYPE_CHECKING:
|
|
25
28
|
from .engine import OSISEngine
|
|
26
29
|
|
|
27
30
|
SYNC_STATE_FILE = ".apdl_sync.json"
|
|
28
31
|
|
|
32
|
+
# 默认 .out 文件名(位于项目根目录)
|
|
33
|
+
DEFAULT_EXPORT_NAME = "_pyosis_sync.out"
|
|
34
|
+
|
|
29
35
|
# 忽略 TIME: 行,避免时间戳导致 MD5 每次不同
|
|
30
36
|
_TIME_LINE_PATTERN = re.compile(
|
|
31
37
|
r"^//-+ TIME:.*//\s*$",
|
|
32
38
|
re.MULTILINE | re.IGNORECASE,
|
|
33
39
|
)
|
|
34
40
|
|
|
41
|
+
|
|
35
42
|
@dataclass
|
|
36
43
|
class ApdlSyncResult:
|
|
37
44
|
"""APDL 同步结果。"""
|
|
@@ -107,6 +114,49 @@ def _save_persisted_hash(state_path: Path, out_path: Path, file_hash: str) -> No
|
|
|
107
114
|
)
|
|
108
115
|
|
|
109
116
|
|
|
117
|
+
# 解析项目目录
|
|
118
|
+
def _get_project_dir(engine: "OSISEngine") -> Path | None:
|
|
119
|
+
try:
|
|
120
|
+
proj_dir = engine.project.get_directory()
|
|
121
|
+
except RuntimeError:
|
|
122
|
+
return None
|
|
123
|
+
if not proj_dir:
|
|
124
|
+
return None
|
|
125
|
+
return Path(proj_dir)
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
# 解析 (out_path, prep_dir)
|
|
129
|
+
def _resolve_project_paths(engine: "OSISEngine") -> tuple[Path, Path]:
|
|
130
|
+
"""返回 (默认 out_path, prep_dir)。prep_dir 不存在会自动创建。"""
|
|
131
|
+
proj_dir = _get_project_dir(engine)
|
|
132
|
+
if proj_dir is None:
|
|
133
|
+
raise RuntimeError("无法获取 OSIS 项目目录")
|
|
134
|
+
prep_dir = proj_dir / "py" / "prep"
|
|
135
|
+
prep_dir.mkdir(parents=True, exist_ok=True)
|
|
136
|
+
return proj_dir / DEFAULT_EXPORT_NAME, prep_dir
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
# 确保 .out 文件存在
|
|
140
|
+
def _ensure_out_file(
|
|
141
|
+
engine: "OSISEngine",
|
|
142
|
+
out_path: Path,
|
|
143
|
+
*,
|
|
144
|
+
force_export: bool,
|
|
145
|
+
) -> Path:
|
|
146
|
+
"""确保 .out 存在;不存在或 force_export 时调用 engine.export_apdl。"""
|
|
147
|
+
if out_path.is_file() and not force_export:
|
|
148
|
+
return out_path
|
|
149
|
+
|
|
150
|
+
out_path.parent.mkdir(parents=True, exist_ok=True)
|
|
151
|
+
print(f"执行 export_apdl → {out_path}")
|
|
152
|
+
engine.export_apdl(str(out_path))
|
|
153
|
+
|
|
154
|
+
if not out_path.is_file() or out_path.stat().st_size == 0:
|
|
155
|
+
raise FileNotFoundError(f"导出失败或未生成有效 .out 文件: {out_path}")
|
|
156
|
+
|
|
157
|
+
return out_path
|
|
158
|
+
|
|
159
|
+
|
|
110
160
|
# 执行 APDL 同步
|
|
111
161
|
def perform_apdl_sync(
|
|
112
162
|
engine: "OSISEngine",
|
|
@@ -118,22 +168,14 @@ def perform_apdl_sync(
|
|
|
118
168
|
|
|
119
169
|
无项目路径时返回 None。
|
|
120
170
|
"""
|
|
121
|
-
|
|
122
|
-
from ..transfer.sync_exec import (
|
|
123
|
-
get_project_dir_optional,
|
|
124
|
-
resolve_out_file,
|
|
125
|
-
resolve_project_paths,
|
|
126
|
-
write_prep_outputs,
|
|
127
|
-
)
|
|
128
|
-
|
|
129
|
-
if get_project_dir_optional(engine) is None:
|
|
171
|
+
if _get_project_dir(engine) is None:
|
|
130
172
|
return None
|
|
131
173
|
|
|
132
174
|
session: ApdlSessionStore = engine._apdl_session
|
|
133
175
|
|
|
134
|
-
default_out, prep_dir =
|
|
176
|
+
default_out, prep_dir = _resolve_project_paths(engine)
|
|
135
177
|
out_path = Path(path) if path is not None else default_out
|
|
136
|
-
out_path =
|
|
178
|
+
out_path = _ensure_out_file(engine, out_path, force_export=force_export)
|
|
137
179
|
|
|
138
180
|
text = _read_out_text(out_path)
|
|
139
181
|
file_hash = _text_hash(text)
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
"""OSIS 界面操作后触发 pyosis APDL 同步的 CLI 入口。
|
|
2
|
+
|
|
3
|
+
仅负责触发 perform_apdl_sync;prep 模块的执行不在本模块职责范围内。
|
|
4
|
+
|
|
2
5
|
用法:
|
|
3
6
|
python -m pyosis.core.sync_apdl_cli
|
|
4
7
|
退出码:
|
|
@@ -9,30 +12,15 @@
|
|
|
9
12
|
from __future__ import annotations
|
|
10
13
|
|
|
11
14
|
import sys
|
|
12
|
-
from typing import TYPE_CHECKING
|
|
13
15
|
|
|
16
|
+
from .apdl_sync import perform_apdl_sync
|
|
14
17
|
from .engine import OSISEngine
|
|
15
18
|
|
|
16
|
-
if TYPE_CHECKING:
|
|
17
|
-
from .apdl_sync import ApdlSyncResult
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
def _print_result(result: ApdlSyncResult) -> None:
|
|
21
|
-
|
|
22
|
-
if result.changed:
|
|
23
|
-
print("命令流有变化,已重新生成并执行 prep")
|
|
24
|
-
else:
|
|
25
|
-
print("命令流未变化,已 export,未重新执行 prep")
|
|
26
|
-
|
|
27
|
-
summary = result.summary()
|
|
28
|
-
if summary:
|
|
29
|
-
print(f"摘要: {summary}")
|
|
30
|
-
|
|
31
|
-
|
|
32
19
|
|
|
33
20
|
def main() -> int:
|
|
21
|
+
engine = OSISEngine()
|
|
34
22
|
try:
|
|
35
|
-
result =
|
|
23
|
+
result = perform_apdl_sync(engine)
|
|
36
24
|
except Exception as exc:
|
|
37
25
|
print(f"sync_apdl 失败: {exc}", file=sys.stderr)
|
|
38
26
|
return 1
|
|
@@ -41,7 +29,7 @@ def main() -> int:
|
|
|
41
29
|
print("跳过:未获取到项目路径")
|
|
42
30
|
return 0
|
|
43
31
|
|
|
44
|
-
|
|
32
|
+
print(result.summary())
|
|
45
33
|
return 0
|
|
46
34
|
|
|
47
35
|
|
|
@@ -1,29 +1,22 @@
|
|
|
1
|
-
"""transfer
|
|
1
|
+
"""transfer 同步链路的纯文本处理工具:把 .out 文本转换为 pyosis prep 模块。
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
只负责文本解析与 Python 代码生成:
|
|
4
|
+
- 解析 OSIS 导出的命令流(parse_text)
|
|
5
|
+
- 按模块分桶并生成 prep 模块(_1_control.py … _10_stage.py + main.py)
|
|
4
6
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
7
|
+
不负责:
|
|
8
|
+
- .out 文件的获取(export_apdl) —— 由调用方管理
|
|
9
|
+
- prep 模块的执行(import + builder 调用) —— 由调用方管理
|
|
8
10
|
"""
|
|
9
11
|
|
|
10
12
|
from __future__ import annotations
|
|
11
13
|
|
|
12
|
-
import importlib.util
|
|
13
|
-
import sys
|
|
14
14
|
from collections import defaultdict
|
|
15
|
-
from dataclasses import dataclass
|
|
16
15
|
from pathlib import Path
|
|
17
|
-
from typing import TYPE_CHECKING
|
|
18
16
|
|
|
19
17
|
from pyosis.transfer.generator import generate_lines
|
|
20
18
|
from pyosis.transfer.parser import ParsedCommand
|
|
21
19
|
|
|
22
|
-
if TYPE_CHECKING:
|
|
23
|
-
from pyosis.core.engine import OSISEngine
|
|
24
|
-
|
|
25
|
-
DEFAULT_EXPORT_NAME = "_pyosis_sync.out"
|
|
26
|
-
|
|
27
20
|
# 模块文件名
|
|
28
21
|
MODULE_FILES = {
|
|
29
22
|
"CONTROL": "_1_control.py",
|
|
@@ -55,56 +48,6 @@ MODULE_BUILDERS = {
|
|
|
55
48
|
MODULE_ORDER = tuple(MODULE_FILES.keys())
|
|
56
49
|
|
|
57
50
|
|
|
58
|
-
@dataclass
|
|
59
|
-
class ExecResult:
|
|
60
|
-
index: int
|
|
61
|
-
line: str
|
|
62
|
-
ok: bool
|
|
63
|
-
error: str
|
|
64
|
-
|
|
65
|
-
# 获取项目目录
|
|
66
|
-
def get_project_dir_optional(engine: OSISEngine) -> Path | None:
|
|
67
|
-
try:
|
|
68
|
-
proj_dir = engine.project.get_directory()
|
|
69
|
-
except RuntimeError:
|
|
70
|
-
return None
|
|
71
|
-
if not proj_dir:
|
|
72
|
-
return None
|
|
73
|
-
return Path(proj_dir)
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
# 解析项目路径
|
|
77
|
-
def resolve_project_paths(engine: OSISEngine) -> tuple[Path, Path]:
|
|
78
|
-
"""返回 (out_path, prep_dir)。"""
|
|
79
|
-
proj_dir = get_project_dir_optional(engine)
|
|
80
|
-
if proj_dir is None:
|
|
81
|
-
raise RuntimeError("无法获取 OSIS 项目目录")
|
|
82
|
-
prep_dir = proj_dir / "py" / "prep"
|
|
83
|
-
prep_dir.mkdir(parents=True, exist_ok=True)
|
|
84
|
-
return proj_dir / DEFAULT_EXPORT_NAME, prep_dir
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
# 解析 .out 文件
|
|
88
|
-
def resolve_out_file(
|
|
89
|
-
engine: OSISEngine,
|
|
90
|
-
out_path: Path,
|
|
91
|
-
*,
|
|
92
|
-
force_export: bool = False,
|
|
93
|
-
) -> Path:
|
|
94
|
-
"""确保 .out 存在;不存在或 force_export 时 export_apdl。"""
|
|
95
|
-
if out_path.is_file() and not force_export:
|
|
96
|
-
return out_path
|
|
97
|
-
|
|
98
|
-
out_path.parent.mkdir(parents=True, exist_ok=True)
|
|
99
|
-
print(f"执行 export_apdl → {out_path}")
|
|
100
|
-
engine.export_apdl(str(out_path))
|
|
101
|
-
|
|
102
|
-
if not out_path.is_file() or out_path.stat().st_size == 0:
|
|
103
|
-
raise FileNotFoundError(f"导出失败或未生成有效 .out 文件: {out_path}")
|
|
104
|
-
|
|
105
|
-
return out_path
|
|
106
|
-
|
|
107
|
-
|
|
108
51
|
# 按模块分桶
|
|
109
52
|
def _bucket_by_module(parsed: list[ParsedCommand]) -> dict[str, list[ParsedCommand]]:
|
|
110
53
|
buckets: dict[str, list[ParsedCommand]] = defaultdict(list)
|
|
@@ -132,7 +75,7 @@ def _write_prep_module(prep_dir: Path, module: str, lines: list[str]) -> Path:
|
|
|
132
75
|
fname = MODULE_FILES[module]
|
|
133
76
|
builder = MODULE_BUILDERS[module]
|
|
134
77
|
empty = not lines
|
|
135
|
-
doc = f"由 pyosis.transfer.
|
|
78
|
+
doc = f"由 pyosis.transfer.out_to_python 从 .out 自动生成: {module}"
|
|
136
79
|
if empty:
|
|
137
80
|
doc += "(无命令)"
|
|
138
81
|
|
|
@@ -154,6 +97,7 @@ def _write_prep_module(prep_dir: Path, module: str, lines: list[str]) -> Path:
|
|
|
154
97
|
path.write_text("\n".join(body_lines), encoding="utf-8")
|
|
155
98
|
return path
|
|
156
99
|
|
|
100
|
+
|
|
157
101
|
def _write_main_py(prep_dir: Path) -> Path:
|
|
158
102
|
"""写入 main.py:依次执行 _1_control … _10_stage。"""
|
|
159
103
|
import_lines = [
|
|
@@ -164,7 +108,7 @@ def _write_main_py(prep_dir: Path) -> Path:
|
|
|
164
108
|
call_lines = [f" {MODULE_BUILDERS[mod]}(eng)" for mod in MODULE_ORDER]
|
|
165
109
|
|
|
166
110
|
body_lines = [
|
|
167
|
-
'"""由 pyosis.transfer.
|
|
111
|
+
'"""由 pyosis.transfer.out_to_python 自动生成:依次执行 prep 模块。"""',
|
|
168
112
|
"",
|
|
169
113
|
"from __future__ import annotations",
|
|
170
114
|
"",
|
|
@@ -183,8 +127,9 @@ def _write_main_py(prep_dir: Path) -> Path:
|
|
|
183
127
|
path.write_text("\n".join(body_lines), encoding="utf-8")
|
|
184
128
|
return path
|
|
185
129
|
|
|
130
|
+
|
|
186
131
|
def write_prep_outputs(parsed: list[ParsedCommand], prep_dir: Path) -> tuple[int, list[Path]]:
|
|
187
|
-
"""写入 _0_engine.py 与 _1~_10 prep
|
|
132
|
+
"""写入 _0_engine.py 与 _1~_10 prep 模块 + main.py,返回 (代码行数, 文件路径列表)。
|
|
188
133
|
|
|
189
134
|
每个标准模块都会写入文件;.out 中无对应命令时生成 pass stub,避免遗留旧 prep。
|
|
190
135
|
"""
|
|
@@ -204,53 +149,4 @@ def write_prep_outputs(parsed: list[ParsedCommand], prep_dir: Path) -> tuple[int
|
|
|
204
149
|
encoding="utf-8",
|
|
205
150
|
)
|
|
206
151
|
prep_paths.append(_write_main_py(prep_dir))
|
|
207
|
-
return code_line_count, prep_paths
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
# 加载 prep 模块
|
|
211
|
-
def _load_prep_module(prep_dir: Path, filename: str):
|
|
212
|
-
path = prep_dir / filename
|
|
213
|
-
if not path.is_file():
|
|
214
|
-
return None
|
|
215
|
-
spec = importlib.util.spec_from_file_location(path.stem, path)
|
|
216
|
-
mod = importlib.util.module_from_spec(spec)
|
|
217
|
-
assert spec.loader is not None
|
|
218
|
-
spec.loader.exec_module(mod)
|
|
219
|
-
return mod
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
# 执行 prep 模块
|
|
223
|
-
def execute_prep_modules(prep_dir: Path, engine: OSISEngine) -> list[ExecResult]:
|
|
224
|
-
"""按 _1_control … _10_stage 顺序执行 prep 模块。"""
|
|
225
|
-
prep_dir = prep_dir.resolve()
|
|
226
|
-
if str(prep_dir) not in sys.path:
|
|
227
|
-
sys.path.insert(0, str(prep_dir))
|
|
228
|
-
|
|
229
|
-
results: list[ExecResult] = []
|
|
230
|
-
step = 0
|
|
231
|
-
|
|
232
|
-
for module in MODULE_ORDER:
|
|
233
|
-
fname = MODULE_FILES[module]
|
|
234
|
-
builder_name = MODULE_BUILDERS[module]
|
|
235
|
-
mod = _load_prep_module(prep_dir, fname)
|
|
236
|
-
if mod is None:
|
|
237
|
-
print(f"[SKIP] {fname} 不存在")
|
|
238
|
-
continue
|
|
239
|
-
builder = getattr(mod, builder_name, None)
|
|
240
|
-
if builder is None:
|
|
241
|
-
print(f"[SKIP] {fname} 无函数 {builder_name}")
|
|
242
|
-
continue
|
|
243
|
-
|
|
244
|
-
step += 1
|
|
245
|
-
desc = f"{fname} → {builder_name}(engine)"
|
|
246
|
-
try:
|
|
247
|
-
builder(engine)
|
|
248
|
-
results.append(ExecResult(step, desc, True, ""))
|
|
249
|
-
print(f"[OK] {step}: {desc}")
|
|
250
|
-
except Exception as exc:
|
|
251
|
-
msg = str(exc)
|
|
252
|
-
results.append(ExecResult(step, desc, False, msg))
|
|
253
|
-
print(f"[FAIL] {step}: {desc}")
|
|
254
|
-
print(f" {msg}")
|
|
255
|
-
|
|
256
|
-
return results
|
|
152
|
+
return code_line_count, prep_paths
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|