Spaces:
Sleeping
Sleeping
| 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() | |