osis-python 0.5.5__tar.gz → 0.6.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.
Files changed (117) hide show
  1. {osis_python-0.5.5/src/osis_python.egg-info → osis_python-0.6.2}/PKG-INFO +95 -44
  2. {osis_python-0.5.5 → osis_python-0.6.2}/README.md +94 -43
  3. {osis_python-0.5.5 → osis_python-0.6.2/src/osis_python.egg-info}/PKG-INFO +95 -44
  4. {osis_python-0.5.5 → osis_python-0.6.2}/src/osis_python.egg-info/SOURCES.txt +1 -0
  5. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/__init__.py +1 -1
  6. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/boundary/manager.py +193 -36
  7. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/control/manager.py +178 -24
  8. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/core/engine.py +16 -1
  9. osis_python-0.6.2/src/pyosis/core/solver.py +163 -0
  10. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/dynamic/manager.py +141 -24
  11. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/element/manager.py +226 -37
  12. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/geometry/manager.py +31 -6
  13. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/live/manager.py +43 -18
  14. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/load/manager.py +494 -351
  15. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/material/manager.py +26 -7
  16. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/project/manager.py +42 -24
  17. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/property/manager.py +263 -84
  18. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/result/check.py +5 -4
  19. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/result/env.py +1 -1
  20. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/result/loadcase.py +1 -1
  21. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/section/manager.py +284 -41
  22. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/settlement/manager.py +84 -27
  23. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/stability/manager.py +42 -31
  24. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/thickness/manager.py +36 -14
  25. {osis_python-0.5.5 → osis_python-0.6.2}/LICENSE +0 -0
  26. {osis_python-0.5.5 → osis_python-0.6.2}/pyproject.toml +0 -0
  27. {osis_python-0.5.5 → osis_python-0.6.2}/setup.cfg +0 -0
  28. {osis_python-0.5.5 → osis_python-0.6.2}/src/osis_python.egg-info/dependency_links.txt +0 -0
  29. {osis_python-0.5.5 → osis_python-0.6.2}/src/osis_python.egg-info/requires.txt +0 -0
  30. {osis_python-0.5.5 → osis_python-0.6.2}/src/osis_python.egg-info/top_level.txt +0 -0
  31. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/boundary/__init__.py +0 -0
  32. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/boundary/interface.py +0 -0
  33. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/control/__init__.py +0 -0
  34. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/control/control.py +0 -0
  35. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/control/io.py +0 -0
  36. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/control/nonlinear.py +0 -0
  37. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/core/__init__.py +0 -0
  38. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/core/all_func.py +0 -0
  39. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/core/apdl_sync.py +0 -0
  40. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/core/basic_manager.py +0 -0
  41. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/core/build.py +0 -0
  42. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/core/client.py +0 -0
  43. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/core/command.py +0 -0
  44. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/core/exceptions.py +0 -0
  45. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/core/references.py +0 -0
  46. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/core/sync_apdl_cli.py +0 -0
  47. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/display/__init__.py +0 -0
  48. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/display/interface.py +0 -0
  49. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/display/manager.py +0 -0
  50. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/dynamic/__init__.py +0 -0
  51. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/dynamic/load_to_mass.py +0 -0
  52. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/dynamic/modal.py +0 -0
  53. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/dynamic/seismic.py +0 -0
  54. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/element/__init__.py +0 -0
  55. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/element/interface.py +0 -0
  56. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/general/__init__.py +0 -0
  57. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/general/interface.py +0 -0
  58. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/geometry/__init__.py +0 -0
  59. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/geometry/interface.py +0 -0
  60. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/live/__init__.py +0 -0
  61. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/live/analysis.py +0 -0
  62. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/live/grade.py +0 -0
  63. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/live/lane.py +0 -0
  64. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/load/__init__.py +0 -0
  65. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/load/loadcase.py +0 -0
  66. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/load/static.py +0 -0
  67. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/load/tendon.py +0 -0
  68. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/material/__init__.py +0 -0
  69. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/material/interface.py +0 -0
  70. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/node/__init__.py +0 -0
  71. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/node/interface.py +0 -0
  72. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/node/manager.py +0 -0
  73. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/post/__init__.py +0 -0
  74. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/post/combine.py +0 -0
  75. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/post/design_check.py +0 -0
  76. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/post/display.py +0 -0
  77. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/post/manager.py +0 -0
  78. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/project/__init__.py +0 -0
  79. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/project/interface.py +0 -0
  80. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/property/__init__.py +0 -0
  81. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/property/component_thickness.py +0 -0
  82. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/property/coordinate.py +0 -0
  83. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/property/creep_shrink.py +0 -0
  84. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/property/damping.py +0 -0
  85. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/property/pu_curve.py +0 -0
  86. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/quick_building/__init__.py +0 -0
  87. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/quick_building/interface.py +0 -0
  88. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/result/__init__.py +0 -0
  89. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/result/manager.py +0 -0
  90. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/result/result.py +0 -0
  91. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/section/__init__.py +0 -0
  92. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/section/common.py +0 -0
  93. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/section/composite.py +0 -0
  94. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/section/numeric.py +0 -0
  95. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/section/param.py +0 -0
  96. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/section/rebar.py +0 -0
  97. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/section/rib.py +0 -0
  98. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/section/steel.py +0 -0
  99. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/settlement/__init__.py +0 -0
  100. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/settlement/interface.py +0 -0
  101. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/stability/__init__.py +0 -0
  102. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/stability/buckling.py +0 -0
  103. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/stage/__init__.py +0 -0
  104. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/stage/define.py +0 -0
  105. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/stage/manager.py +0 -0
  106. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/stage/overall.py +0 -0
  107. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/thickness/__init__.py +0 -0
  108. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/thickness/interface.py +0 -0
  109. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/transfer/__init__.py +0 -0
  110. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/transfer/generator.py +0 -0
  111. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/transfer/matrix.py +0 -0
  112. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/transfer/out_to_python.py +0 -0
  113. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/transfer/parser.py +0 -0
  114. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/transfer/routes.py +0 -0
  115. {osis_python-0.5.5 → osis_python-0.6.2}/src/pyosis/transfer/split.py +0 -0
  116. {osis_python-0.5.5 → osis_python-0.6.2}/tests/test_delete_occupied.py +0 -0
  117. {osis_python-0.5.5 → osis_python-0.6.2}/tests/test_project_manager.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: osis-python
3
- Version: 0.5.5
3
+ Version: 0.6.2
4
4
  Summary: A Python client library for Osis APDL
5
5
  Author-email: "CCCC Highway Consultant Co. Ltd." <support@osisbim.com>
6
6
  License-Expression: MIT
@@ -55,6 +55,7 @@ pip install osis-python -i https://pypi.org/simple
55
55
 
56
56
  - OSIS >= 5.0 (includes the required Python runtime environment)
57
57
  - Python >= 3.8
58
+ - **Solver-only mode** additionally requires the solver distribution that ships `PySolver.dll` (e.g. `D:\OSIS_Solver\Rbin64`).
58
59
 
59
60
  ## Quick Start
60
61
 
@@ -76,22 +77,22 @@ engine.control.set_calc_tendon(True)
76
77
  engine.control.set_calc_creep(True)
77
78
 
78
79
  # Create sections
79
- sec = engine.section.create_circle("CircleSection", d=0.5, tw=0.02)
80
+ sec = engine.section.create_circle(no=1, name="CircleSection", d=0.5)
80
81
 
81
82
  # Create materials
82
- mat = engine.material.create_conc("C30Concrete", eCode="JTG3362_2018", eGrade="C30")
83
+ mat = engine.material.create_conc(no=1, name="C30Concrete", code="JTG3362_2018", grade="C30")
83
84
 
84
85
  # Create nodes
85
- n1 = engine.node.create(0, 0, 0)
86
- n2 = engine.node.create(15, 0, 0)
86
+ n1 = engine.node.create(no=1, x=0, y=0, z=0)
87
+ n2 = engine.node.create(no=2, x=15, y=0, z=0)
87
88
 
88
89
  # Create elements
89
90
  elem = engine.element.create_beam3d(
90
- n1.no, n2.no, nMat=mat.no, nSec1=sec.no, nSec2=sec.no
91
+ no=1, node1=n1.no, node2=n2.no, nMat=mat.no, nSec1=sec.no, nSec2=sec.no
91
92
  )
92
93
 
93
94
  # Create boundaries
94
- bd = engine.boundary.create_general(bX=1, bY=1, bZ=1, bRX=1, bRY=1, bRZ=1)
95
+ bd = engine.boundary.create_general(no=1, x=1, y=1, z=1, rx=1, ry=1, rz=1, rw=1)
95
96
  bd.assign("a", [n1.no])
96
97
 
97
98
  # Create load case and add loads
@@ -134,10 +135,35 @@ If you don't need the convenience methods of Engine, you can also import individ
134
135
  from pyosis.material import material_manager
135
136
  from pyosis.node import node_manager
136
137
 
137
- mat = material_manager.create_conc("C30", eCode="JTG3362_2018", eGrade="C30")
138
+ mat = material_manager.create_conc(no=1, name="C30", code="JTG3362_2018", grade="C30")
138
139
  node = node_manager.create(0, 0, 0)
139
140
  ```
140
141
 
142
+ ### 4. Using OSISSolver — Start the Solver Directly (Solver-Only Mode)
143
+
144
+ By default, `OSISEngine()` connects to an already-running OSIS GUI process. If you want to drive the solver **without opening the GUI** (e.g. for headless batch runs, CI, or server-side automation), use `OSISSolver` to load the solver DLL directly via ctypes and launch its HTTP server:
145
+
146
+ ```python
147
+ from pyosis.core.solver import OSISSolver
148
+ from pyosis.core.engine import OSISEngine
149
+
150
+ # Load <install>/PySolver.dll and start the HTTP server (default port 18080)
151
+ solver = OSISSolver(osis_install_path=r"D:\OSIS_Solver\Rbin64")
152
+ engine = OSISEngine.from_solver(solver)
153
+
154
+ # Create a project (type 101 = bridge analysis), then build the model as usual
155
+ engine.project.create(101, r"D:\work\my_bridge\my_bridge.sis")
156
+ engine.control.set_gravity_acceleration(9.8066)
157
+ # ... build sections / materials / nodes / elements ...
158
+ engine.solve()
159
+ ```
160
+
161
+ Notes on solver-only mode:
162
+
163
+ - `osis_install_path` must be the directory containing `PySolver.dll` (and its dependency DLLs).
164
+ - The solver needs a project to exist before model commands run: call `engine.project.create()` / `open()` first.
165
+ - Crash minidumps are written to `<install>\Error\dmp\` (created on startup).
166
+
141
167
  ## Core Architecture
142
168
 
143
169
  ### Manager System
@@ -165,66 +191,84 @@ pyosis adopts a Manager pattern to organize code. Each module corresponds to a M
165
191
  | ResultManager | `engine.result` | Result export (load case / envelope / check results) |
166
192
  | ControlManager | `engine.control` | Global control parameters |
167
193
  | ProjectManager | `engine.project` | Project operations |
194
+ | DisplayManager | `engine.display` | Display control (show/hide boundaries, loads, tendons; view orientation; display switches) |
168
195
 
169
196
  ### Sub-Managers
170
197
 
171
198
  Some managers contain sub-managers, accessed via attributes:
172
199
 
173
200
  ```python
174
- # Element groups
175
- grp = engine.element.group.create("MainGirderElements")
176
- grp.add([1, 2, 3])
201
+ # Element groups (create + add elements in one call)
202
+ engine.element.group.create("MainGirderElements", "c") # create empty group
203
+ engine.element.group.create("MainGirderElements", "a", "1to3") # add elements 1-3
177
204
 
178
205
  # Boundary groups
179
- bg = engine.boundary.group.create("AbutmentBoundaries")
180
- bg.add([1, 2])
206
+ engine.boundary.group.create("AbutmentBoundaries", "c")
207
+ engine.boundary.group.create("AbutmentBoundaries", "a", "1to2")
181
208
 
182
209
  # Various boundary types
183
- engine.boundary.create_general(bX=1, bY=1, bZ=1, bRX=1, bRY=1, bRZ=1) # General support
184
- engine.boundary.create_master_slave(nMast=1, nSlav=2, dDir=1) # Master-slave
185
- engine.boundary.create_release(nElem=1, iReleaseEnd=2) # End release
186
- engine.boundary.create_elstcspt(nNode=1, dK=[1e9, 1e9, 1e9, 0, 0, 0]) # Elastic support
187
- engine.boundary.create_general_elstcspt(nNode=1, bX=1, bY=1, bZ=1, dKx=1e9, dKy=1e9, dKz=1e9) # General elastic
188
- engine.boundary.create_rigid(nNode1=1, nNode2=2) # Rigid link
189
- engine.boundary.create_section_factor(nElem=1, iEnd=1) # Section factor
210
+ engine.boundary.create_general(no=1, x=1, y=1, z=1, rx=1, ry=1, rz=1, rw=1) # General support
211
+ engine.boundary.create_master_slave(no=1, node=1, dx=1, dy=1, dz=1, rx=0, ry=1, rz=1, coincident=2) # Master-slave
212
+ engine.boundary.create_rigid(no=1, nNodeI=1) # Rigid link
213
+ engine.boundary.create_elstcspt(no=1, coor="", x=0, dx=1e9, y=0, dy=1e9, z=0, dz=1e9) # Elastic support
190
214
 
191
215
  # Tendons
192
216
  prop = engine.tendon.prop.create_in(
193
- "15-10", mat_no=1, e_code="GBT5224_2014",
194
- diameter=15.2, n_num=10, d_pipe=0.09
217
+ name="15-10", mat=3, code="GBT5224_2014",
218
+ diameter=15.2, num=10, pipe=0.09,
195
219
  )
196
220
  shape = engine.tendon.shape.create_arc3d(
197
- "N1", n_num=2, prop="15-10",
221
+ name="N1", n_num=2, prop="15-10",
198
222
  element_group="MainGirderElements", curve_name="curve1"
199
223
  )
200
224
 
201
225
  # Live loads
202
- grade = engine.live.grade.create("HighwayClassI")
203
- lane = engine.live.lane.create("Lane1")
204
- case = engine.live.case.create("LiveLoadCase 1")
226
+ grade = engine.live.grade.create(name="HighwayClassI", code="JTGD60_2015", type="HIGHWAY_I")
227
+ lane = engine.live.lane.create(name="Lane1", type="VE")
228
+ case = engine.live.case.create(name="LiveLoadCase 1", code="JTGD60_2015")
229
+ ```
230
+
231
+ ### Display Control
232
+
233
+ ```python
234
+ # Show/hide boundaries, loads and tendons
235
+ engine.display.disp_ctrl("bc", "all", "all", 1) # Show all boundaries
236
+ engine.display.disp_ctrl("lg", "nforce", "all", 0) # Hide all concentrated forces
237
+ engine.display.disp_ctrl("td", "all", ["T1", "T2"], 1) # Show specific tendons
238
+
239
+ # View orientation
240
+ engine.display.set_view("top") # standard / top / right / front
241
+
242
+ # Display switch
243
+ engine.display.set_plsm(1) # 0 = off, 1 = on
205
244
  ```
206
245
 
207
246
  ### Property & Thickness Management
208
247
 
209
248
  ```python
210
- # Coordinate systems
211
- engine.prop.coord.create_local("CS1", origin=[0, 0, 0], x_axis=[1, 0, 0], y_axis=[0, 1, 0])
249
+ # Coordinate systems (三点定义)
250
+ engine.prop.coord.create_three_point(
251
+ no=1, p1x=0, p1y=0, p1z=0,
252
+ p2x=1, p2y=0, p2z=0,
253
+ p3x=0, p3y=1, p3z=0,
254
+ )
212
255
 
213
- # Creep and shrinkage
214
- engine.prop.creep_shrink.create("Creep1", eCode="JTG3362_2018", eGrade="C30")
256
+ # Creep and shrinkage(no, name, avg_humidity, birth_time, type_coeff, shrink_birth)
257
+ engine.prop.creep_shrink.create(no=1, name="Creep1", avg_humidity=70.0,
258
+ birth_time=7, type_coeff=5.0, shrink_birth=3)
215
259
 
216
- # Damping
217
- engine.prop.damping.create("Damping1", dDmp=0.05)
260
+ # Damping (Rayleigh 自定义系数)
261
+ engine.prop.damping.create_rayleigh_custom(name="Damping1", alpha=0.05, beta=0.005)
218
262
 
219
- # P-U curve (for soil-structure interaction)
220
- engine.prop.pu_curve.create("PU1", data=[(0, 0), (0.01, 1000), (0.02, 1500)])
263
+ # P-U curve (no, name, curve_type, num, values)
264
+ # curve_type: 1=水平位移推力 2=竖向位移推力 3=竖向力位移
265
+ engine.prop.pu_curve.create(no=1, name="PU1", curve_type=1, num=3, values=[0, 0.01, 1000, 0.02, 1500])
221
266
 
222
- # Element thickness assignment
223
- engine.prop.thickness.assign_element(nElem=1, dThick=0.3)
267
+ # Element thickness assignment (thickness, op, *elems)
268
+ engine.prop.assign_component_thickness(thickness=0.3, op="a", elems=[1])
224
269
 
225
- # Shell thickness properties
226
- engine.thickness.create_uniform("Thick1", dThick=0.3)
227
- engine.thickness.create_tapered("Thick2", dThick1=0.2, dThick2=0.4)
270
+ # Shell thickness (no, in_plane, out_plane)
271
+ engine.thickness.create(no=1, in_plane=0.3, out_plane=0.3)
228
272
  ```
229
273
 
230
274
  ### Geometry Queries
@@ -264,10 +308,10 @@ Some `create_*` functions support explicit numbering via the `no` parameter. If
264
308
 
265
309
  ```python
266
310
  # Auto-assigned number
267
- sec = engine.section.create_circle("Section1", d=0.5)
311
+ sec = engine.section.create_circle(name="Section1", d=0.5)
268
312
 
269
313
  # Explicit number
270
- sec = engine.section.create_circle("Section1", d=0.5, no=100)
314
+ sec = engine.section.create_circle(name="Section1", d=0.5, no=100)
271
315
  ```
272
316
 
273
317
  ## Result Export
@@ -324,7 +368,7 @@ engine.section.create_circle("CircleSection2", d=0.180, tw=0.008, no=2)
324
368
 
325
369
  # Materials
326
370
  engine.material.create_steel(
327
- "Steel1", eCode="JTGD64_2015", eGrade="Q345", dDmp=0.05, no=1
371
+ "Steel1", code="JTGD64_2015", grade="Q345", dmp=0.05, no=1
328
372
  )
329
373
 
330
374
  # Nodes
@@ -354,6 +398,13 @@ lc.create_nforce(4, dFx=200000, dFy=0, dFz=0)
354
398
  engine.solve()
355
399
  ```
356
400
 
357
- ## More Resources
401
+ ## End-to-End Demo
402
+
403
+ See [`tests/pyosis_demo.py`](tests/pyosis_demo.py) for a runnable end-to-end example that:
404
+
405
+ - Starts the solver directly via `OSISSolver` (no GUI required)
406
+ - Builds the 25m 简支小箱梁 example model (10 prep modules)
407
+ - Runs `engine.solve()`
408
+ - Exports LCND / LCEF / EnvND / EnvEF results to CSV
358
409
 
359
- - [tests/](tests/): Example code for each module
410
+ The demo reuses the prep modules from `tests/output/output_py/25m简支小箱梁中梁-solveronly/`, so it serves both as a smoke test and a copy-paste template.
@@ -24,6 +24,7 @@ pip install osis-python -i https://pypi.org/simple
24
24
 
25
25
  - OSIS >= 5.0 (includes the required Python runtime environment)
26
26
  - Python >= 3.8
27
+ - **Solver-only mode** additionally requires the solver distribution that ships `PySolver.dll` (e.g. `D:\OSIS_Solver\Rbin64`).
27
28
 
28
29
  ## Quick Start
29
30
 
@@ -45,22 +46,22 @@ engine.control.set_calc_tendon(True)
45
46
  engine.control.set_calc_creep(True)
46
47
 
47
48
  # Create sections
48
- sec = engine.section.create_circle("CircleSection", d=0.5, tw=0.02)
49
+ sec = engine.section.create_circle(no=1, name="CircleSection", d=0.5)
49
50
 
50
51
  # Create materials
51
- mat = engine.material.create_conc("C30Concrete", eCode="JTG3362_2018", eGrade="C30")
52
+ mat = engine.material.create_conc(no=1, name="C30Concrete", code="JTG3362_2018", grade="C30")
52
53
 
53
54
  # Create nodes
54
- n1 = engine.node.create(0, 0, 0)
55
- n2 = engine.node.create(15, 0, 0)
55
+ n1 = engine.node.create(no=1, x=0, y=0, z=0)
56
+ n2 = engine.node.create(no=2, x=15, y=0, z=0)
56
57
 
57
58
  # Create elements
58
59
  elem = engine.element.create_beam3d(
59
- n1.no, n2.no, nMat=mat.no, nSec1=sec.no, nSec2=sec.no
60
+ no=1, node1=n1.no, node2=n2.no, nMat=mat.no, nSec1=sec.no, nSec2=sec.no
60
61
  )
61
62
 
62
63
  # Create boundaries
63
- bd = engine.boundary.create_general(bX=1, bY=1, bZ=1, bRX=1, bRY=1, bRZ=1)
64
+ bd = engine.boundary.create_general(no=1, x=1, y=1, z=1, rx=1, ry=1, rz=1, rw=1)
64
65
  bd.assign("a", [n1.no])
65
66
 
66
67
  # Create load case and add loads
@@ -103,10 +104,35 @@ If you don't need the convenience methods of Engine, you can also import individ
103
104
  from pyosis.material import material_manager
104
105
  from pyosis.node import node_manager
105
106
 
106
- mat = material_manager.create_conc("C30", eCode="JTG3362_2018", eGrade="C30")
107
+ mat = material_manager.create_conc(no=1, name="C30", code="JTG3362_2018", grade="C30")
107
108
  node = node_manager.create(0, 0, 0)
108
109
  ```
109
110
 
111
+ ### 4. Using OSISSolver — Start the Solver Directly (Solver-Only Mode)
112
+
113
+ By default, `OSISEngine()` connects to an already-running OSIS GUI process. If you want to drive the solver **without opening the GUI** (e.g. for headless batch runs, CI, or server-side automation), use `OSISSolver` to load the solver DLL directly via ctypes and launch its HTTP server:
114
+
115
+ ```python
116
+ from pyosis.core.solver import OSISSolver
117
+ from pyosis.core.engine import OSISEngine
118
+
119
+ # Load <install>/PySolver.dll and start the HTTP server (default port 18080)
120
+ solver = OSISSolver(osis_install_path=r"D:\OSIS_Solver\Rbin64")
121
+ engine = OSISEngine.from_solver(solver)
122
+
123
+ # Create a project (type 101 = bridge analysis), then build the model as usual
124
+ engine.project.create(101, r"D:\work\my_bridge\my_bridge.sis")
125
+ engine.control.set_gravity_acceleration(9.8066)
126
+ # ... build sections / materials / nodes / elements ...
127
+ engine.solve()
128
+ ```
129
+
130
+ Notes on solver-only mode:
131
+
132
+ - `osis_install_path` must be the directory containing `PySolver.dll` (and its dependency DLLs).
133
+ - The solver needs a project to exist before model commands run: call `engine.project.create()` / `open()` first.
134
+ - Crash minidumps are written to `<install>\Error\dmp\` (created on startup).
135
+
110
136
  ## Core Architecture
111
137
 
112
138
  ### Manager System
@@ -134,66 +160,84 @@ pyosis adopts a Manager pattern to organize code. Each module corresponds to a M
134
160
  | ResultManager | `engine.result` | Result export (load case / envelope / check results) |
135
161
  | ControlManager | `engine.control` | Global control parameters |
136
162
  | ProjectManager | `engine.project` | Project operations |
163
+ | DisplayManager | `engine.display` | Display control (show/hide boundaries, loads, tendons; view orientation; display switches) |
137
164
 
138
165
  ### Sub-Managers
139
166
 
140
167
  Some managers contain sub-managers, accessed via attributes:
141
168
 
142
169
  ```python
143
- # Element groups
144
- grp = engine.element.group.create("MainGirderElements")
145
- grp.add([1, 2, 3])
170
+ # Element groups (create + add elements in one call)
171
+ engine.element.group.create("MainGirderElements", "c") # create empty group
172
+ engine.element.group.create("MainGirderElements", "a", "1to3") # add elements 1-3
146
173
 
147
174
  # Boundary groups
148
- bg = engine.boundary.group.create("AbutmentBoundaries")
149
- bg.add([1, 2])
175
+ engine.boundary.group.create("AbutmentBoundaries", "c")
176
+ engine.boundary.group.create("AbutmentBoundaries", "a", "1to2")
150
177
 
151
178
  # Various boundary types
152
- engine.boundary.create_general(bX=1, bY=1, bZ=1, bRX=1, bRY=1, bRZ=1) # General support
153
- engine.boundary.create_master_slave(nMast=1, nSlav=2, dDir=1) # Master-slave
154
- engine.boundary.create_release(nElem=1, iReleaseEnd=2) # End release
155
- engine.boundary.create_elstcspt(nNode=1, dK=[1e9, 1e9, 1e9, 0, 0, 0]) # Elastic support
156
- engine.boundary.create_general_elstcspt(nNode=1, bX=1, bY=1, bZ=1, dKx=1e9, dKy=1e9, dKz=1e9) # General elastic
157
- engine.boundary.create_rigid(nNode1=1, nNode2=2) # Rigid link
158
- engine.boundary.create_section_factor(nElem=1, iEnd=1) # Section factor
179
+ engine.boundary.create_general(no=1, x=1, y=1, z=1, rx=1, ry=1, rz=1, rw=1) # General support
180
+ engine.boundary.create_master_slave(no=1, node=1, dx=1, dy=1, dz=1, rx=0, ry=1, rz=1, coincident=2) # Master-slave
181
+ engine.boundary.create_rigid(no=1, nNodeI=1) # Rigid link
182
+ engine.boundary.create_elstcspt(no=1, coor="", x=0, dx=1e9, y=0, dy=1e9, z=0, dz=1e9) # Elastic support
159
183
 
160
184
  # Tendons
161
185
  prop = engine.tendon.prop.create_in(
162
- "15-10", mat_no=1, e_code="GBT5224_2014",
163
- diameter=15.2, n_num=10, d_pipe=0.09
186
+ name="15-10", mat=3, code="GBT5224_2014",
187
+ diameter=15.2, num=10, pipe=0.09,
164
188
  )
165
189
  shape = engine.tendon.shape.create_arc3d(
166
- "N1", n_num=2, prop="15-10",
190
+ name="N1", n_num=2, prop="15-10",
167
191
  element_group="MainGirderElements", curve_name="curve1"
168
192
  )
169
193
 
170
194
  # Live loads
171
- grade = engine.live.grade.create("HighwayClassI")
172
- lane = engine.live.lane.create("Lane1")
173
- case = engine.live.case.create("LiveLoadCase 1")
195
+ grade = engine.live.grade.create(name="HighwayClassI", code="JTGD60_2015", type="HIGHWAY_I")
196
+ lane = engine.live.lane.create(name="Lane1", type="VE")
197
+ case = engine.live.case.create(name="LiveLoadCase 1", code="JTGD60_2015")
198
+ ```
199
+
200
+ ### Display Control
201
+
202
+ ```python
203
+ # Show/hide boundaries, loads and tendons
204
+ engine.display.disp_ctrl("bc", "all", "all", 1) # Show all boundaries
205
+ engine.display.disp_ctrl("lg", "nforce", "all", 0) # Hide all concentrated forces
206
+ engine.display.disp_ctrl("td", "all", ["T1", "T2"], 1) # Show specific tendons
207
+
208
+ # View orientation
209
+ engine.display.set_view("top") # standard / top / right / front
210
+
211
+ # Display switch
212
+ engine.display.set_plsm(1) # 0 = off, 1 = on
174
213
  ```
175
214
 
176
215
  ### Property & Thickness Management
177
216
 
178
217
  ```python
179
- # Coordinate systems
180
- engine.prop.coord.create_local("CS1", origin=[0, 0, 0], x_axis=[1, 0, 0], y_axis=[0, 1, 0])
218
+ # Coordinate systems (三点定义)
219
+ engine.prop.coord.create_three_point(
220
+ no=1, p1x=0, p1y=0, p1z=0,
221
+ p2x=1, p2y=0, p2z=0,
222
+ p3x=0, p3y=1, p3z=0,
223
+ )
181
224
 
182
- # Creep and shrinkage
183
- engine.prop.creep_shrink.create("Creep1", eCode="JTG3362_2018", eGrade="C30")
225
+ # Creep and shrinkage(no, name, avg_humidity, birth_time, type_coeff, shrink_birth)
226
+ engine.prop.creep_shrink.create(no=1, name="Creep1", avg_humidity=70.0,
227
+ birth_time=7, type_coeff=5.0, shrink_birth=3)
184
228
 
185
- # Damping
186
- engine.prop.damping.create("Damping1", dDmp=0.05)
229
+ # Damping (Rayleigh 自定义系数)
230
+ engine.prop.damping.create_rayleigh_custom(name="Damping1", alpha=0.05, beta=0.005)
187
231
 
188
- # P-U curve (for soil-structure interaction)
189
- engine.prop.pu_curve.create("PU1", data=[(0, 0), (0.01, 1000), (0.02, 1500)])
232
+ # P-U curve (no, name, curve_type, num, values)
233
+ # curve_type: 1=水平位移推力 2=竖向位移推力 3=竖向力位移
234
+ engine.prop.pu_curve.create(no=1, name="PU1", curve_type=1, num=3, values=[0, 0.01, 1000, 0.02, 1500])
190
235
 
191
- # Element thickness assignment
192
- engine.prop.thickness.assign_element(nElem=1, dThick=0.3)
236
+ # Element thickness assignment (thickness, op, *elems)
237
+ engine.prop.assign_component_thickness(thickness=0.3, op="a", elems=[1])
193
238
 
194
- # Shell thickness properties
195
- engine.thickness.create_uniform("Thick1", dThick=0.3)
196
- engine.thickness.create_tapered("Thick2", dThick1=0.2, dThick2=0.4)
239
+ # Shell thickness (no, in_plane, out_plane)
240
+ engine.thickness.create(no=1, in_plane=0.3, out_plane=0.3)
197
241
  ```
198
242
 
199
243
  ### Geometry Queries
@@ -233,10 +277,10 @@ Some `create_*` functions support explicit numbering via the `no` parameter. If
233
277
 
234
278
  ```python
235
279
  # Auto-assigned number
236
- sec = engine.section.create_circle("Section1", d=0.5)
280
+ sec = engine.section.create_circle(name="Section1", d=0.5)
237
281
 
238
282
  # Explicit number
239
- sec = engine.section.create_circle("Section1", d=0.5, no=100)
283
+ sec = engine.section.create_circle(name="Section1", d=0.5, no=100)
240
284
  ```
241
285
 
242
286
  ## Result Export
@@ -293,7 +337,7 @@ engine.section.create_circle("CircleSection2", d=0.180, tw=0.008, no=2)
293
337
 
294
338
  # Materials
295
339
  engine.material.create_steel(
296
- "Steel1", eCode="JTGD64_2015", eGrade="Q345", dDmp=0.05, no=1
340
+ "Steel1", code="JTGD64_2015", grade="Q345", dmp=0.05, no=1
297
341
  )
298
342
 
299
343
  # Nodes
@@ -323,6 +367,13 @@ lc.create_nforce(4, dFx=200000, dFy=0, dFz=0)
323
367
  engine.solve()
324
368
  ```
325
369
 
326
- ## More Resources
370
+ ## End-to-End Demo
371
+
372
+ See [`tests/pyosis_demo.py`](tests/pyosis_demo.py) for a runnable end-to-end example that:
373
+
374
+ - Starts the solver directly via `OSISSolver` (no GUI required)
375
+ - Builds the 25m 简支小箱梁 example model (10 prep modules)
376
+ - Runs `engine.solve()`
377
+ - Exports LCND / LCEF / EnvND / EnvEF results to CSV
327
378
 
328
- - [tests/](tests/): Example code for each module
379
+ The demo reuses the prep modules from `tests/output/output_py/25m简支小箱梁中梁-solveronly/`, so it serves both as a smoke test and a copy-paste template.