An Example to Automate Ansys Post-Processing with Python
An Example to Automate Ansys Post-Processing with Python
Integrating PyAnsys with Python expands possibilities for automating simulation tasks and improving post-processing workflows. By configuring your environment correctly, you can optimize the process of running Ansys simulations and extracting valuable insights from the results.
Setting Up PyAnsys
To install PyAnsys libraries, clone the GitHub repository:
git clone https://github.com/pyansys/pymapdl.git
cd pymapdl
pip install .
Create a new environment using virtualenv or conda:
virtualenv ansys_env
source ansys_env/bin/activate
Or for conda:
conda create --name ansys_env python=3.8
conda activate ansys_env
Install PyDPF-Core and PyMAPDL:
pip install pydpf-core pymapdl
Start an instance of Ansys with PyMAPDL:
from ansys.mapdl.core import launch_mapdl
mapdl = launch_mapdl()
print(mapdl)
For post-processing, import PyDPF:
from ansys.dpf import post
Load results and retrieve stress data:
model = post.load_simulation("path_to_file.rst")
stress = model.stresses
print(stress)
Automate multiple analyses:
for i in range(1, 10):
mapdl.run('/solu')
mapdl.input(f"input_file_{i}.dat")
mapdl.solve()
Extract displacements:
displacements = model.displacements
for disp in displacements:
print(disp)
Create plots from data:
import matplotlib.pyplot as plt
results = model.results()
time_steps = results.time_steps
values = [result.value for result in results]
plt.plot(time_steps, values)
plt.xlabel('Time')
plt.ylabel('Values')
plt.title('Simulation Results Over Time')
plt.show()
Executing Ansys Simulations
Define geometry using PyMAPDL:
mapdl.prep7()
mapdl.blc4(xcorner=0, ycorner=0, width=10, height=10)
Define materials:
mapdl.mp('EX', 1, 210e9)
mapdl.mp('PRXY', 1, 0.3)
Specify boundary conditions and loads:
mapdl.nsel('S', 'LOC', 'X', 0)
mapdl.d('ALL', 'UX', 0)
mapdl.fk(2, 'FY', -1000)
Mesh the model:
mapdl.et(1, 42)
mapdl.esize(0.5)
mapdl.amesh('ALL')
Solve the model:
mapdl.run('/solu')
mapdl.antype('STATIC')
mapdl.solve()
mapdl.finish()
For more complex geometry:
mapdl.blc4(xcorner=0, ycorner=0, width=5, height=5)
mapdl.blc4(xcorner=5, ycorner=5, width=10, height=10)
Post-Processing with PyDPF
Import necessary modules:
from ansys.dpf import core as dpf
from ansys.dpf.core import operators as ops
from ansys.dpf.core import examples
Load results:
model = dpf.Model("path_to_file.rst")
Extract stress results:
stress_operator = ops.result.stress_principal_1()
stress_operator.inputs.streams_connect(model)
stress_fields = stress_operator.outputs.fields_container()
Visualize stress data:
import matplotlib.pyplot as plt
stress_values = [field.data for field in stress_fields]
nodes = model.metadata.meshed_region.nodes
x_coords = [node.x for node in nodes]
y_coords = [node.y for node in nodes]
z_coords = [node.z for node in nodes]
stress_values_flat = [val for sublist in stress_values for val in sublist]
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
sc = ax.scatter(x_coords, y_coords, z_coords, c=stress_values_flat, cmap='viridis')
plt.colorbar(sc)
plt.show()
Compute von Mises stress:
von_mises_operator = ops.result.stress_eqv_von_mises()
von_mises_operator.inputs.streams_connect(model)
von_mises_fields = von_mises_operator.outputs.fields_container()
Export results to CSV:
import csv
with open('stress_results.csv', mode='w', newline='') as file:
writer = csv.writer(file)
writer.writerow(['Node ID', 'Stress Value'])
for node, stress in zip(nodes, stress_values_flat):
writer.writerow([node.id, stress])
Integrating Dash for Visualization
Combining Dash with PyAnsys provides an effective method to display Ansys simulation data. Using Dash_VTK, developers can create interactive web applications, offering customized UIs for monitoring and examining simulation results within a standard web browser.
To begin, install the necessary packages:
pip install dash dash-vtk
Import the required libraries in your Python script:
import dash
import dash_vtk
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
from ansys.dpf.core import Model
from ansys.dpf.core import examples
Set up your Dash application and define the layout:
app = dash.Dash(__name__)
app.layout = html.Div([
dcc.Dropdown(
id='result_type',
options=[
{'label': 'Displacement', 'value': 'disp'},
{'label': 'Stress', 'value': 'stress'}
],
value='disp'
),
dcc.Graph(
id='output_graph'
),
dash_vtk.View(
id='vtk_view'
)
])
Create callbacks to handle user interactions and update the visualization:
@app.callback(
Output('vtk_view', 'children'),
Input('result_type', 'value')
)
def update_vtk_view(result_type):
model = Model(examples.download_transient_result())
if result_type == 'disp':
disp_operator = model.results().displacement()
disp_fields = disp_operator.outputs.fields_container()
vtk_data = # Conversion to VTK-compatible data
# Plot displacement data
elif result_type == 'stress':
stress_operator = model.results().principal_stress()
stress_fields = stress_operator.outputs.fields_container()
vtk_data = # Conversion to VTK-compatible data
# Plot stress data
return dash_vtk.GeometryRepresentation([
dash_vtk.Mesh(
# Insert VTK-compatible data here
),
dash_vtk.PointData([
dash_vtk.DataArray(
registration="vtkPointData",
values=vtk_data
)
])
])
To improve the visualization, convert the DPF fields to VTK-compatible data structures:
def convert_to_vtk(field):
from pyvista import lines_from_points
import vtk
points = []
cells = []
for data in field.data:
points.append([data[0], data[1], data[2]])
cells.append(len(points))
cells.extend(range(len(points)))
vtk_points = vtk.vtkPoints()
vtk_points.SetNumberOfPoints(len(points))
for i, pt in enumerate(points):
vtk_points.SetPoint(i, pt)
vtk_cells = vtk.vtkCellArray()
for cell in cells:
vtk_cells.InsertNextCell(cell)
poly_data = vtk.vtkPolyData()
poly_data.SetPoints(vtk_points)
poly_data.SetLines(vtk_cells)
return poly_data
Incorporate this function into your callback for rendering VTK data:
@app.callback(
Output('vtk_view', 'children'),
Input('result_type', 'value')
)
def update_vtk_view(result_type):
model = Model(examples.download_transient_result())
data = None
if result_type == 'disp':
disp_operator = model.results().displacement()
disp_fields = disp_operator.outputs.fields_container()
data = convert_to_vtk(disp_fields[0])
elif result_type == 'stress':
stress_operator = model.results().principal_stress()
stress_fields = stress_operator.outputs.fields_container()
data = convert_to_vtk(stress_fields[0])
vtk_data = data
return dash_vtk.GeometryRepresentation([
dash_vtk.Mesh(
vtkPolyData=vtk_data,
),
dash_vtk.PointData([
dash_vtk.DataArray(
registration="vtkPointData",
values=[d for d in vtk_data]
)
])
])
Launch the Dash server to view the interactive visualization in your web browser:
if __name__ == '__main__':
app.run_server(debug=True)
This integration of Dash with PyAnsys and Dash_VTK creates an interactive platform for visualizing simulation data, enhancing accessibility and enabling efficient data analysis and interpretation from a standard web browser.
Using PyAnsys improves the automation and analysis of complex simulations. This approach enhances efficiency and accuracy in modeling tasks, making it a valuable tool for engineers and researchers working with Ansys. Some key benefits include:
- Streamlined workflow automation
- Improved data visualization capabilities
- Enhanced integration with other Python libraries
- Easier collaboration and sharing of results
By leveraging PyAnsys, engineers can focus more on interpreting results and making design decisions, rather than spending time on manual data processing and visualization tasks. A very interesting article about Ansys Post-Processing with Python can also be found here.