pyosis
Python client library for OSIS Bridge & Tunnel Analysis Platform (developed by CCCC Highway Consultants Co., Ltd.).
pyosis provides an object-oriented Python API for automating the creation of bridge/tunnel finite element models, executing analysis solvers, and extracting post-processing results.
Installation
Due to naming conflicts on PyPI, please install using:
pip install osis-python
If your mirror hasn't synced yet, use:
pip install osis-python -i https://pypi.org/simple
Requirements
- OSIS >= 5.0 (includes the required Python runtime environment)
- Python >= 3.8
- Solver-only mode additionally requires the solver distribution that ships
PySolver.dll(e.g.D:\OSIS_Solver\Rbin64).
Quick Start
1. Using OSISEngine (Recommended)
OSISEngine is the core facade class of pyosis, integrating all module managers and providing a unified project-level entry point:
from pyosis.core.engine import OSISEngine
engine = OSISEngine()
# Clear project
engine.clear()
# Set global parameters
engine.control.set_gravity_acceleration(9.8066)
engine.control.set_calc_tendon(True)
engine.control.set_calc_creep(True)
# Create sections
sec = engine.section.create_circle(no=1, name="CircleSection", d=0.5)
# Create materials
mat = engine.material.create_conc(no=1, name="C30Concrete", code="JTG3362_2018", grade="C30")
# Create nodes
n1 = engine.node.create(no=1, x=0, y=0, z=0)
n2 = engine.node.create(no=2, x=15, y=0, z=0)
# Create elements
elem = engine.element.create_beam3d(
no=1, node1=n1.no, node2=n2.no, nMat=mat.no, nSec1=sec.no, nSec2=sec.no
)
# Create boundaries
bd = engine.boundary.create_general(no=1, x=1, y=1, z=1, rx=1, ry=1, rz=1, rw=1)
bd.assign("a", [n1.no])
# Create load case and add loads
lc = engine.load.create("Self-weight", load_case_type="D")
lc.create_gravity()
# Solve
engine.solve()
2. Engine Convenience Methods
OSISEngine provides project-level convenience methods:
# Project management
engine.new_project() # Create new project
engine.save_project() # Save current project
engine.open_project(path) # Open existing project
# Model information
summary = engine.model_summary() # Returns dict with all manager counts
# Import/Export
engine.export_apdl(path) # Export to APDL format
engine.import_apdl(path) # Import from APDL format
# Result output for calculation book
engine.output_result_for_calc_book()
# Matrix output
engine.matrix("matrix_1", [[1, 2],[3, 4]])
3. Using Managers Directly
If you don't need the convenience methods of Engine, you can also import individual managers directly:
from pyosis.material import material_manager
from pyosis.node import node_manager
mat = material_manager.create_conc(no=1, name="C30", code="JTG3362_2018", grade="C30")
node = node_manager.create(0, 0, 0)
4. Using OSISSolver — Start the Solver Directly (Solver-Only Mode)
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:
from pyosis.core.solver import OSISSolver
from pyosis.core.engine import OSISEngine
# Load <install>/PySolver.dll and start the HTTP server (default port 18080)
solver = OSISSolver(osis_install_path=r"D:\OSIS_Solver\Rbin64")
engine = OSISEngine.from_solver(solver)
# Create a project (type 101 = bridge analysis), then build the model as usual
engine.project.create(101, r"D:\work\my_bridge\my_bridge.sis")
engine.control.set_gravity_acceleration(9.8066)
# ... build sections / materials / nodes / elements ...
engine.solve()
Notes on solver-only mode:
osis_install_pathmust be the directory containingPySolver.dll(and its dependency DLLs).- The solver needs a project to exist before model commands run: call
engine.project.create()/open()first. - Crash minidumps are written to
<install>\Error\dmp\(created on startup).
Core Architecture
Manager System
pyosis adopts a Manager pattern to organize code. Each module corresponds to a Manager:
| Manager | Attribute | Description |
|---|---|---|
| MaterialManager | engine.material |
Materials (concrete, steel, prestressed, rebar, etc.) |
| SectionManager | engine.section |
Sections (box girder, T-girder, hollow slab, steel box, etc.) |
| NodeManager | engine.node |
Nodes |
| ElementManager | engine.element |
Elements (beam, truss, spring, cable, shell) |
| BoundaryManager | engine.boundary |
Boundaries (general support, master-slave, elastic support, etc.) |
| GeometryManager | engine.geometry |
Geometric entities (splines, spatial curves) |
| PropertyManager | engine.prop |
Properties (coordinate systems, creep/shrinkage, damping, P-U curves, element thickness assignments) |
| ThicknessManager | engine.thickness |
Shell thickness properties |
| LoadCaseManager | engine.load |
Load cases |
| StageManager | engine.stage |
Construction stages |
| TendonManager | engine.tendon |
Tendons (properties + shapes) |
| LiveManager | engine.live |
Live loads (grades + lanes + cases) |
| SettlementManager | engine.settlement |
Settlement analysis |
| StabilityManager | engine.stability |
Stability analysis |
| DynamicManager | engine.dynamic |
Dynamic analysis |
| PostManager | engine.post |
Post-processing (load combinations, design checks) |
| ResultManager | engine.result |
Result export (load case / envelope / check results) |
| ControlManager | engine.control |
Global control parameters |
| ProjectManager | engine.project |
Project operations |
| DisplayManager | engine.display |
Display control (show/hide boundaries, loads, tendons; view orientation; display switches) |
Sub-Managers
Some managers contain sub-managers, accessed via attributes:
# Element groups (create + add elements in one call)
engine.element.group.create("MainGirderElements", "c") # create empty group
engine.element.group.create("MainGirderElements", "a", "1to3") # add elements 1-3
# Boundary groups
engine.boundary.group.create("AbutmentBoundaries", "c")
engine.boundary.group.create("AbutmentBoundaries", "a", "1to2")
# Various boundary types
engine.boundary.create_general(no=1, x=1, y=1, z=1, rx=1, ry=1, rz=1, rw=1) # General support
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
engine.boundary.create_rigid(no=1, nNodeI=1) # Rigid link
engine.boundary.create_elstcspt(no=1, coor="", x=0, dx=1e9, y=0, dy=1e9, z=0, dz=1e9) # Elastic support
# Tendons
prop = engine.tendon.prop.create_in(
name="15-10", mat=3, code="GBT5224_2014",
diameter=15.2, num=10, pipe=0.09,
)
shape = engine.tendon.shape.create_arc3d(
name="N1", n_num=2, prop="15-10",
element_group="MainGirderElements", curve_name="curve1"
)
# Live loads
grade = engine.live.grade.create(name="HighwayClassI", code="JTGD60_2015", type="HIGHWAY_I")
lane = engine.live.lane.create(name="Lane1", type="VE")
case = engine.live.case.create(name="LiveLoadCase 1", code="JTGD60_2015")
Display Control
# Show/hide boundaries, loads and tendons
engine.display.disp_ctrl("bc", "all", "all", 1) # Show all boundaries
engine.display.disp_ctrl("lg", "nforce", "all", 0) # Hide all concentrated forces
engine.display.disp_ctrl("td", "all", ["T1", "T2"], 1) # Show specific tendons
# View orientation
engine.display.set_view("top") # standard / top / right / front
# Display switch
engine.display.set_plsm(1) # 0 = off, 1 = on
Property & Thickness Management
# Coordinate systems (三点定义)
engine.prop.coord.create_three_point(
no=1, p1x=0, p1y=0, p1z=0,
p2x=1, p2y=0, p2z=0,
p3x=0, p3y=1, p3z=0,
)
# Creep and shrinkage(no, name, avg_humidity, birth_time, type_coeff, shrink_birth)
engine.prop.creep_shrink.create(no=1, name="Creep1", avg_humidity=70.0,
birth_time=7, type_coeff=5.0, shrink_birth=3)
# Damping (Rayleigh 自定义系数)
engine.prop.damping.create_rayleigh_custom(name="Damping1", alpha=0.05, beta=0.005)
# P-U curve (no, name, curve_type, num, values)
# curve_type: 1=水平位移推力 2=竖向位移推力 3=竖向力位移
engine.prop.pu_curve.create(no=1, name="PU1", curve_type=1, num=3, values=[0, 0.01, 1000, 0.02, 1500])
# Element thickness assignment (thickness, op, *elems)
engine.prop.assign_component_thickness(thickness=0.3, op="a", elems=[1])
# Shell thickness (no, in_plane, out_plane)
engine.thickness.create(no=1, in_plane=0.3, out_plane=0.3)
Geometry Queries
The GeometryManager supports querying geometric entities:
# Get all splines
splines = engine.geometry.all("spline")
# Get a specific spline
spline = engine.geometry.get("spline", name="curve1")
# Filter by type
arcs = engine.geometry.filter("spline", spline_type="ARC3D")
Data Class Objects
Create and query operations return data class objects (dataclass) instead of raw dictionaries:
elem = engine.element.get(1)
print(elem.no) # ID
print(elem.node_vec) # Node list
print(elem.mat) # Material ID
# Objects support operations (operations下沉 to object)
lc = engine.load.get("Self-weight")
lc.create_gravity()
lc.create_nforce(1, dFx=1000)
Explicit Numbering
Some create_* functions support explicit numbering via the no parameter. If not specified, the number is automatically assigned:
# Auto-assigned number
sec = engine.section.create_circle(name="Section1", d=0.5)
# Explicit number
sec = engine.section.create_circle(name="Section1", d=0.5, no=100)
Result Export
After solving, you can export various analysis results using engine.result. All export methods return pandas DataFrames:
# Export load case results (element forces)
df = engine.result.loadcase("Self-weight", "LCEF")
# Export envelope results (element forces)
df = engine.result.env("BasicCombinationEnvelope", "EnvEF")
# Export design check results
df = engine.result.check(
"混凝土", "正截面抗弯验算", "基本组合"
)
# Batch export all check results from Check folder
results = engine.result.check_all()
for name, df in results.items():
print(f"{name}: {len(df)} rows")
Supported result types:
- Load case:
LCEF(element force),LCED(element displacement),LCND(node displacement),LCBF(boundary reaction),LCTL(tendon loss),LCS(element stress) - Envelope:
EnvBF(boundary reaction),EnvEF(element force),EnvES(element strain),EnvS(element stress),EnvND(node displacement)
Requires pandas to be installed: python -m install pandas
Complete Example
from pyosis.core.engine import OSISEngine
engine = OSISEngine()
engine.clear()
# Control parameters
engine.control.set_gravity_acceleration(9.8066)
engine.control.set_calc_tendon(True)
engine.control.set_calc_concurrent_force(True)
engine.control.set_calc_shrink(True)
engine.control.set_calc_creep(True)
engine.control.set_calc_shear(True)
engine.control.set_calc_relaxation(True)
engine.control.set_mod_loc_coor(False)
engine.control.set_inc_tendon(True)
engine.control.set_nonlinear(geom=False, link=False)
# Sections
engine.section.create_circle("CircleSection1", d=0.219, tw=0.012, no=1)
engine.section.create_circle("CircleSection2", d=0.180, tw=0.008, no=2)
# Materials
engine.material.create_steel(
"Steel1", code="JTGD64_2015", grade="Q345", dmp=0.05, no=1
)
# Nodes
engine.node.create(0, 5, 0, no=1)
engine.node.create(15, 5, 0, no=2)
engine.node.create(7.5, 0, 0, no=3)
engine.node.create(20, 0, 0, no=4)
# Elements
engine.element.create_beam3d(1, 3, nMat=1, nSec1=1, nSec2=1, no=1)
engine.element.create_beam3d(2, 3, nMat=1, nSec1=2, nSec2=2, no=2)
# Boundaries
engine.boundary.create_general(no=1)
engine.boundary.get(1).assign("a", [1, 2])
# Loads
lc = engine.load.create(
"CustomLoadCase1",
load_case_type="USER",
prompt="Two forces applied at nodes 3 and 4"
)
lc.create_nforce(3, dFx=0, dFy=-1000000, dFz=0)
lc.create_nforce(4, dFx=200000, dFy=0, dFz=0)
# Solve
engine.solve()
End-to-End Demo
See tests/pyosis_demo.py for a runnable end-to-end example that:
- Starts the solver directly via
OSISSolver(no GUI required) - Builds the 25m 简支小箱梁 example model (10 prep modules)
- Runs
engine.solve() - Exports LCND / LCEF / EnvND / EnvEF results to CSV
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.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file osis_python-0.6.1.tar.gz.
File metadata
- Download URL: osis_python-0.6.1.tar.gz
- Upload date:
- Size: 182.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5a57f4338980b4ed877f16a86a167ea30002b38b3af0c471bb01ebea5c7673e2
|
|
| MD5 |
7f8ec2ae72c6bf028b3b063f37b6acaa
|
|
| BLAKE2b-256 |
0e07eda1b4210b6ed868d226775ef6600008531d0764d91ddf96ed3b6bcfe57e
|
File details
Details for the file osis_python-0.6.1-py3-none-any.whl.
File metadata
- Download URL: osis_python-0.6.1-py3-none-any.whl
- Upload date:
- Size: 224.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
474ef2baecb0ac346c82f242bbe06bfa05f03e71c6706c2b5d831f276089648f
|
|
| MD5 |
a5f0c55d63be752188cf94fc0c7f2303
|
|
| BLAKE2b-256 |
136ab7502ed8a735fe94c5c05def298baa1e174600d0ce506d559bdccae6fa70
|