karthikmn commited on
Commit
49b7a98
·
verified ·
1 Parent(s): 32ecd71

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +123 -0
app.py ADDED
@@ -0,0 +1,123 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import subprocess
3
+ import numpy as np
4
+ import pyvista as pv
5
+ import matplotlib.pyplot as plt
6
+ from ansys.mapdl.core import launch_mapdl
7
+ from pycalculix import *
8
+
9
+ # Simulation Workflow
10
+ def simulation_workflow(use_case, simulator, **kwargs):
11
+ # Generate APDL script based on user inputs
12
+ if use_case == "plate":
13
+ apdl_script = f"""
14
+ /PREP7
15
+ MP,EX,1,2E11 ! Elastic modulus
16
+ MP,PRXY,1,0.3 ! Poisson's ratio
17
+ BLOCK,0,{kwargs["length"]},0,{kwargs["width"]},0,{kwargs["thickness"]} ! Main block geometry
18
+ CYLIND,0,{kwargs["hole_diameter"]/2},0,0,{kwargs["thickness"]} ! Circular hole geometry
19
+ VSUB,ALL ! Subtract the hole from the block
20
+ ET,1,SOLID185 ! Define element type as SOLID185
21
+ ESIZE,5 ! Mesh element size
22
+ VMESH,ALL ! Mesh the entire volume
23
+ NSEL,S,LOC,Z,0 ! Select bottom face nodes
24
+ D,ALL,ALL ! Apply constraints on selected nodes
25
+ NSEL,S,LOC,Z,{kwargs["thickness"]} ! Select top face nodes
26
+ F,ALL,FY,-{kwargs["force"]} ! Apply vertical force
27
+ /SOLU
28
+ ANTYPE,STATIC ! Static structural analysis
29
+ SOLVE
30
+ /POST1
31
+ PRNSOL,S,EQV ! Print equivalent stress results
32
+ PRNSOL,U,SUM ! Print total deformation results
33
+ /EXIT
34
+ """
35
+ elif use_case == "beam":
36
+ apdl_script = f"""
37
+ /PREP7
38
+ MP,EX,1,2E11 ! Elastic modulus
39
+ MP,PRXY,1,0.3 ! Poisson's ratio
40
+ BLOCK,0,{kwargs["length"]},0,{kwargs["width"]},0,{kwargs["thickness"]} ! Beam geometry
41
+ ET,1,SOLID185 ! Define element type as SOLID185
42
+ ESIZE,5 ! Mesh element size
43
+ VMESH,ALL ! Mesh the entire volume
44
+ NSEL,S,LOC,X,0 ! Select nodes at one end of the beam
45
+ D,ALL,ALL ! Apply fixed constraints on one end
46
+ NSEL,S,LOC,X,{kwargs["length"]} ! Select nodes at the other end
47
+ F,ALL,FY,-{kwargs["load"]} ! Apply uniform load
48
+ /SOLU
49
+ ANTYPE,STATIC ! Static structural analysis
50
+ SOLVE
51
+ /POST1
52
+ PRNSOL,S,EQV ! Print equivalent stress results
53
+ PRNSOL,U,SUM ! Print total deformation results
54
+ /EXIT
55
+ """
56
+ else:
57
+ return "Invalid use case selected.", None, None
58
+
59
+ # Save APDL script
60
+ with open("simulation_input.inp", "w") as file:
61
+ file.write(apdl_script)
62
+
63
+ # Run the selected simulator
64
+ if simulator == "PyCalculix":
65
+ model = Model("pycalculix_simulation")
66
+ model.set_units("mm")
67
+ part = Part("block", model)
68
+ part.make_box(0, kwargs["length"], 0, kwargs["width"], 0, kwargs["thickness"])
69
+ if use_case == "plate":
70
+ part.cut_cylinder(0, kwargs["hole_diameter"] / 2, 0, kwargs["hole_diameter"] / 2, kwargs["thickness"])
71
+ model.make_step_static(kwargs.get("force", kwargs.get("load", 0)))
72
+ model.run()
73
+ stress = model.results().max_stress()
74
+ deformation = model.results().max_displacement()
75
+ elif simulator == "ANSYS":
76
+ mapdl = launch_mapdl()
77
+ mapdl.input("simulation_input.inp")
78
+ max_stress = mapdl.get_value("NODE", 0, "S", "EQV")
79
+ deformation = mapdl.get_value("NODE", 0, "U", "SUM")
80
+ mapdl.exit()
81
+ stress, deformation = max_stress, deformation
82
+ else:
83
+ return "Invalid simulator selected.", None, None
84
+
85
+ # Visualize results (both 2D and 3D)
86
+ fig, ax = plt.subplots()
87
+ ax.bar(["Stress", "Deformation"], [stress, deformation], color=["red", "blue"])
88
+ ax.set_title(f"Results ({simulator})")
89
+ plt.savefig("results_2d.png")
90
+ plt.close(fig)
91
+
92
+ # 3D Visualization
93
+ mesh = pv.Box(bounds=(0, kwargs["length"], 0, kwargs["width"], 0, kwargs["thickness"]))
94
+ plotter = pv.Plotter(off_screen=True)
95
+ plotter.add_mesh(mesh, color="white", show_edges=True)
96
+ plotter.screenshot("results_3d.png")
97
+
98
+ return f"Stress: {stress:.2f} MPa, Deformation: {deformation:.2f} mm", "results_2d.png", "results_3d.png"
99
+
100
+ # Define Gradio interface
101
+ interface = gr.Interface(
102
+ fn=simulation_workflow,
103
+ inputs=[
104
+ gr.Radio(["plate", "beam"], label="Select Use Case"), # Choose plate or beam simulation
105
+ gr.Dropdown(["PyCalculix", "ANSYS"], label="Select Simulator"), # Choose simulator
106
+ gr.Slider(10, 50, step=1, label="Thickness (mm)"), # Input: Thickness
107
+ gr.Slider(100, 500, step=10, label="Length (mm)"), # Input: Length
108
+ gr.Slider(50, 200, step=10, label="Width (mm)"), # Input: Width
109
+ gr.Slider(5, 25, step=1, label="Hole Diameter (mm)", optional=True), # Input: Hole Diameter (for plate)
110
+ gr.Slider(1000, 10000, step=500, label="Force (N)", optional=True), # Input: Force (for plate)
111
+ gr.Slider(1000, 20000, step=1000, label="Load (N)", optional=True) # Input: Load (for beam)
112
+ ],
113
+ outputs=[
114
+ gr.Textbox(label="Simulation Results"), # Output: Simulation text results
115
+ gr.Image(label="2D Results Visualization"), # Output: 2D plot (stress and deformation)
116
+ gr.Image(label="3D Results Visualization") # Output: 3D plot (stress distribution)
117
+ ],
118
+ title="Unified Simulation Tool (PyCalculix and ANSYS)",
119
+ live=True
120
+ )
121
+
122
+ # Launch Gradio interface
123
+ interface.launch()