-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathapp.py
More file actions
119 lines (101 loc) · 4.28 KB
/
Copy pathapp.py
File metadata and controls
119 lines (101 loc) · 4.28 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
import json
from io import BytesIO
from pathlib import Path
import viktor as vkt
from viktor.core import File
from viktor.external.python import PythonAnalysis
def create_frame_data(length, height, cross_section="IPE400"):
nodes = {
1: {"node_id": 1, "x": 0, "z": 0, "y": 0},
2: {"node_id": 2, "x": 0, "z": length, "y": 0},
3: {"node_id": 3, "x": 0, "z": 0, "y": height},
4: {"node_id": 4, "x": 0, "z": length, "y": height},
5: {"node_id": 5, "x": length, "z": 0, "y": 0},
6: {"node_id": 6, "x": length, "z": length, "y": 0},
7: {"node_id": 7, "x": length, "z": 0, "y": height},
8: {"node_id": 8, "x": length, "z": length, "y": height},
}
lines = {
1: {"line_id": 1, "node_i": 1, "node_j": 3},
2: {"line_id": 2, "node_i": 2, "node_j": 4},
3: {"line_id": 3, "node_i": 3, "node_j": 4},
4: {"line_id": 4, "node_i": 6, "node_j": 8},
5: {"line_id": 5, "node_i": 5, "node_j": 7},
6: {"line_id": 6, "node_i": 3, "node_j": 7},
7: {"line_id": 7, "node_i": 4, "node_j": 8},
8: {"line_id": 8, "node_i": 7, "node_j": 8},
9: {"line_id": 9, "node_i": 1, "node_j": 4},
10: {"line_id": 10, "node_i": 5, "node_j": 8},
}
return nodes, lines, cross_section
class Parametrization(vkt.Parametrization):
intro = vkt.Text("# STAAD.Pro - Member End Forces App")
inputs_title = vkt.Text("""## Frame Geometry
Fill in the following parameters to create the steel structure:"""
)
frame_length = vkt.NumberField("Frame Length", min=0.3, default=8, suffix="m")
frame_height = vkt.NumberField("Frame Height", min=1, default=6, suffix="m")
line_break = vkt.LineBreak()
section_title = vkt.Text("""## Frame Cross-Section
Select a cross section for the frame elements:"""
)
cross_sect = vkt.OptionField(
"Cross-Section", options=["IPE400", "IPE200"], default="IPE400"
)
class Controller(vkt.Controller):
parametrization = Parametrization
@vkt.GeometryView("3D Model", duration_guess=1, x_axis_to_right=True)
def create_render(self, params, **kwargs):
nodes, lines, _ = create_frame_data(
length=params.frame_length,
height=params.frame_height,
cross_section=params.cross_sect,
)
sections_group = []
for line_id, line_data in lines.items():
node_i = nodes[line_data["node_i"]]
node_j = nodes[line_data["node_j"]]
point_i = vkt.Point(node_i["x"], node_i["z"], node_i["y"])
point_j = vkt.Point(node_j["x"], node_j["z"], node_j["y"])
line = vkt.Line(point_i, point_j)
section_size = float(params.cross_sect[3:]) / 1000
section = vkt.RectangularExtrusion(
section_size, section_size, line, identifier=str(line_id)
)
sections_group.append(section)
return vkt.GeometryResult(geometry=sections_group)
@vkt.TableView(
"Member End Forces", duration_guess=10, update_label="Run STAAD.Pro Analysis"
)
def run_staad(self, params, **kwargs):
nodes, lines, cross_section = create_frame_data(
length=params.frame_length,
height=params.frame_height,
cross_section=params.cross_sect,
)
input_json = json.dumps([nodes, lines, cross_section])
script_path = Path(__file__).parent / "run_staad_model.py"
staad_analysis = PythonAnalysis(
script=File.from_path(script_path),
files=[("inputs.json", BytesIO(input_json.encode("utf-8")))],
output_filenames=["output.json"],
)
staad_analysis.execute(timeout=300)
output_file = staad_analysis.get_output_file("output.json")
output_raw = output_file.getvalue()
if isinstance(output_raw, bytes):
output_raw = output_raw.decode("utf-8")
output = json.loads(output_raw)
forces = [[round(force, 2) for force in row] for row in output["forces"]]
return vkt.TableResult(
forces,
row_headers=output["headers"],
column_headers=[
"FX [kN]",
"FY [kN]",
"FZ [kN]",
"MX [kN m]",
"MY [kN m]",
"MZ [kN m]",
],
)