File size: 6,931 Bytes
49b7a98
 
 
 
 
 
 
 
 
6e0070d
 
 
944acc4
6e0070d
49b7a98
 
944acc4
49b7a98
 
 
 
6e0070d
 
49b7a98
 
 
 
 
 
6e0070d
 
49b7a98
 
 
 
 
 
 
 
 
944acc4
49b7a98
 
 
 
6e0070d
49b7a98
 
 
 
 
6e0070d
 
49b7a98
 
 
 
 
 
 
 
 
944acc4
49b7a98
6e0070d
49b7a98
 
 
6e0070d
944acc4
 
49b7a98
 
944acc4
49b7a98
 
 
6e0070d
49b7a98
6e0070d
 
49b7a98
 
 
 
944acc4
49b7a98
 
 
 
 
 
 
944acc4
49b7a98
 
944acc4
 
49b7a98
944acc4
49b7a98
 
 
 
 
 
6e0070d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
49b7a98
 
 
 
 
 
 
74a552f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
49b7a98
 
6e0070d
49b7a98
 
6e0070d
 
 
 
 
 
 
 
49b7a98
 
6e0070d
 
 
49b7a98
 
 
6e0070d
49b7a98
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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
import gradio as gr
import subprocess
import numpy as np
import pyvista as pv
import matplotlib.pyplot as plt
from ansys.mapdl.core import launch_mapdl
from pycalculix import *

# Simulation Workflow
def simulation_workflow(
    use_case, simulator, thickness, length, width, hole_diameter, force, load
):
    print(f"Running simulation for use_case={use_case}, simulator={simulator}")

    # Generate APDL script based on user inputs
    if use_case == "plate":
        print("Generating APDL script for plate simulation...")
        apdl_script = f"""
/PREP7
MP,EX,1,2E11       ! Elastic modulus
MP,PRXY,1,0.3      ! Poisson's ratio
BLOCK,0,{length},0,{width},0,{thickness}  ! Main block geometry
CYLIND,0,{hole_diameter / 2},0,0,{thickness} ! Circular hole geometry
VSUB,ALL           ! Subtract the hole from the block
ET,1,SOLID185      ! Define element type as SOLID185
ESIZE,5            ! Mesh element size
VMESH,ALL          ! Mesh the entire volume
NSEL,S,LOC,Z,0     ! Select bottom face nodes
D,ALL,ALL          ! Apply constraints on selected nodes
NSEL,S,LOC,Z,{thickness} ! Select top face nodes
F,ALL,FY,-{force}  ! Apply vertical force
/SOLU
ANTYPE,STATIC      ! Static structural analysis
SOLVE
/POST1
PRNSOL,S,EQV       ! Print equivalent stress results
PRNSOL,U,SUM       ! Print total deformation results
/EXIT
"""
    elif use_case == "beam":
        print("Generating APDL script for beam simulation...")
        apdl_script = f"""
/PREP7
MP,EX,1,2E11       ! Elastic modulus
MP,PRXY,1,0.3      ! Poisson's ratio
BLOCK,0,{length},0,{width},0,{thickness}  ! Beam geometry
ET,1,SOLID185      ! Define element type as SOLID185
ESIZE,5            ! Mesh element size
VMESH,ALL          ! Mesh the entire volume
NSEL,S,LOC,X,0     ! Select nodes at one end of the beam
D,ALL,ALL          ! Apply fixed constraints on one end
NSEL,S,LOC,X,{length} ! Select nodes at the other end
F,ALL,FY,-{load}   ! Apply uniform load
/SOLU
ANTYPE,STATIC      ! Static structural analysis
SOLVE
/POST1
PRNSOL,S,EQV       ! Print equivalent stress results
PRNSOL,U,SUM       ! Print total deformation results
/EXIT
"""
    else:
        print("Invalid use case selected.")
        return "Invalid use case selected.", None, None

    # Save APDL script
    with open("simulation_input.inp", "w") as file:
        file.write(apdl_script)

    print(f"APDL script saved at: simulation_input.inp")

    # Run the selected simulator
    if simulator == "PyCalculix":
        print("Running PyCalculix simulation...")
        model = Model("pycalculix_simulation")
        model.set_units("mm")
        part = Part("block", model)
        part.make_box(0, length, 0, width, 0, thickness)
        if use_case == "plate":
            part.cut_cylinder(0, hole_diameter / 2, 0, hole_diameter / 2, thickness)
        model.make_step_static(force if force else load)
        model.run()
        stress = model.results().max_stress()
        deformation = model.results().max_displacement()
    elif simulator == "ANSYS":
        print("Running ANSYS simulation...")
        mapdl = launch_mapdl()
        mapdl.input("simulation_input.inp")
        max_stress = mapdl.get_value("NODE", 0, "S", "EQV")
        deformation = mapdl.get_value("NODE", 0, "U", "SUM")
        mapdl.exit()
        stress, deformation = max_stress, deformation
    else:
        print("Invalid simulator selected.")
        return "Invalid simulator selected.", None, None

    print(f"Simulation results - Stress: {stress}, Deformation: {deformation}")

    # Visualize results (both 2D and 3D)
    print("Visualizing results...")
    fig, ax = plt.subplots()
    ax.bar(["Stress", "Deformation"], [stress, deformation], color=["red", "blue"])
    ax.set_title(f"Results ({simulator})")
    plt.savefig("results_2d.png")
    plt.close(fig)

    # 3D Visualization
    mesh = pv.Box(bounds=(0, length, 0, width, 0, thickness))
    plotter = pv.Plotter(off_screen=True)
    plotter.add_mesh(mesh, color="white", show_edges=True)
    plotter.screenshot("results_3d.png")

    return f"Stress: {stress:.2f} MPa, Deformation: {deformation:.2f} mm", "results_2d.png", "results_3d.png"

    # Visualize results (both 2D and 3D)
    print("Visualizing results...")
    fig, ax = plt.subplots()
    ax.bar(["Stress", "Deformation"], [stress, deformation], color=["red", "blue"])
    ax.set_title(f"Results ({simulator})")
    plt.savefig("results_2d.png")
    plt.close(fig)

    # 3D Visualization
    mesh = pv.Box(bounds=(0, kwargs["length"], 0, kwargs["width"], 0, kwargs["thickness"]))
    plotter = pv.Plotter(off_screen=True)
    plotter.add_mesh(mesh, color="white", show_edges=True)
    plotter.screenshot("results_3d.png")

    return f"Stress: {stress:.2f} MPa, Deformation: {deformation:.2f} mm", "results_2d.png", "results_3d.png"
    
# Define Gradio interface with Submit button
with gr.Blocks() as demo:
    # Input components
    use_case = gr.Radio(["plate", "beam"], label="Select Use Case")
    simulator = gr.Dropdown(["PyCalculix", "ANSYS"], label="Select Simulator")
    thickness = gr.Slider(10, 50, step=1, label="Thickness (mm)")
    length = gr.Slider(100, 500, step=10, label="Length (mm)")
    width = gr.Slider(50, 200, step=10, label="Width (mm)")
    hole_diameter = gr.Slider(5, 25, step=1, label="Hole Diameter (mm)", value=5)
    force = gr.Slider(1000, 10000, step=500, label="Force (N)", value=5000)
    load = gr.Slider(1000, 20000, step=1000, label="Load (N)", value=5000)
    
    # Output components
    results_text = gr.Textbox(label="Simulation Results")
    results_2d = gr.Image(label="2D Results Visualization")
    results_3d = gr.Image(label="3D Results Visualization")
    
    # Submit button
    submit_button = gr.Button("Submit")
    
    # Link function to inputs and outputs
    submit_button.click(
        simulation_workflow,
        inputs=[use_case, simulator, thickness, length, width, hole_diameter, force, load],
        outputs=[results_text, results_2d, results_3d]
    )

# Define Gradio interface
gr.Interface(
    fn=simulation_workflow,
    inputs=[
        gr.Radio(["plate", "beam"], label="Select Use Case"),
        gr.Dropdown(["PyCalculix", "ANSYS"], label="Select Simulator"),
        gr.Slider(10, 50, step=1, label="Thickness (mm)"),
        gr.Slider(100, 500, step=10, label="Length (mm)"),
        gr.Slider(50, 200, step=10, label="Width (mm)"),
        gr.Slider(5, 25, step=1, label="Hole Diameter (mm)", value=5),  # Default for Plate
        gr.Slider(1000, 10000, step=500, label="Force (N)", value=5000),  # Default for Plate
        gr.Slider(1000, 20000, step=1000, label="Load (N)", value=5000)  # Default for Beam
    ],
    outputs=[
        gr.Textbox(label="Simulation Results"),
        gr.Image(label="2D Results Visualization"),
        gr.Image(label="3D Results Visualization")
    ],
    title="Unified Simulation Tool (PyCalculix and ANSYS)",
    live=True
).launch()