Note
Go to the end to download the full example code.
Topology optimization of a simple cantilever beam#
This example demonstrates the structural topology optimization of a simple cantilever beam. The structural analysis is performed with basic constraints and load, which is then transferred to the topology optimization.
Import the necessary libraries#
from pathlib import Path
from typing import TYPE_CHECKING
from matplotlib import image as mpimg
from matplotlib import pyplot as plt
from ansys.mechanical.core import App
from ansys.mechanical.core.examples import delete_downloads, download_file
if TYPE_CHECKING:
import Ansys
Initialize the embedded application#
app = App(globals=globals())
print(app)
Ansys Mechanical [Ansys Mechanical Enterprise]
Product Version:252
Software build date: 06/13/2025 11:25:56
Create functions to set camera and display images#
# Set the path for the output files (images, gifs, mechdat)
output_path = Path.cwd() / "out"
def set_camera_and_display_image(
camera,
graphics,
graphics_image_export_settings,
image_output_path: Path,
image_name: str,
) -> None:
"""Set the camera to fit the model and display the image.
Parameters
----------
camera : Ansys.ACT.Common.Graphics.MechanicalCameraWrapper
The camera object to set the view.
graphics : Ansys.ACT.Common.Graphics.MechanicalGraphicsWrapper
The graphics object to export the image.
graphics_image_export_settings : Ansys.Mechanical.Graphics.GraphicsImageExportSettings
The settings for exporting the image.
image_output_path : Path
The path to save the exported image.
image_name : str
The name of the exported image file.
"""
# Set the camera to fit the mesh
camera.SetFit()
# Export the mesh image with the specified settings
image_path = image_output_path / image_name
graphics.ExportImage(str(image_path), image_export_format, graphics_image_export_settings)
# Display the exported mesh image
display_image(image_path)
def display_image(
image_path: str,
pyplot_figsize_coordinates: tuple = (16, 9),
plot_xticks: list = [],
plot_yticks: list = [],
plot_axis: str = "off",
) -> None:
"""Display the image with the specified parameters.
Parameters
----------
image_path : str
The path to the image file to display.
pyplot_figsize_coordinates : tuple
The size of the figure in inches (width, height).
plot_xticks : list
The x-ticks to display on the plot.
plot_yticks : list
The y-ticks to display on the plot.
plot_axis : str
The axis visibility setting ('on' or 'off').
"""
# Set the figure size based on the coordinates specified
plt.figure(figsize=pyplot_figsize_coordinates)
# Read the image from the file into an array
plt.imshow(mpimg.imread(image_path))
# Get or set the current tick locations and labels of the x-axis
plt.xticks(plot_xticks)
# Get or set the current tick locations and labels of the y-axis
plt.yticks(plot_yticks)
# Turn off the axis
plt.axis(plot_axis)
# Display the figure
plt.show()
Configure graphics for image export
graphics = app.Graphics
camera = graphics.Camera
# Set the camera orientation to the front view
camera.SetSpecificViewOrientation(ViewOrientationType.Front)
# Set the image export format and settings
image_export_format = GraphicsImageExportFormat.PNG
settings_720p = Ansys.Mechanical.Graphics.GraphicsImageExportSettings()
settings_720p.Resolution = GraphicsResolutionType.EnhancedResolution
settings_720p.Background = GraphicsBackgroundType.White
settings_720p.Width = 1280
settings_720p.Height = 720
settings_720p.CurrentGraphicsDisplay = False
Import the structural analysis model#
# Download ``.mechdat`` file
structural_mechdat_file = download_file("cantilever.mechdat", "pymechanical", "embedding")
# Open the project file
app.open(structural_mechdat_file)
# Define the model
model = app.Model
# Get the structural analysis object
struct = model.Analyses[0]
# Get the structural analysis object's solution and solve it
struct_sln = struct.Solution
struct_sln.Solve(True)
Display the structural analysis results#
Activate the total deformation result and display the image
struct_sln.Children[1].Activate()
set_camera_and_display_image(camera, graphics, settings_720p, output_path, "total_deformation.png")

Activate the equivalent stress result and display the image
struct_sln.Children[2].Activate()
set_camera_and_display_image(camera, graphics, settings_720p, output_path, "equivalent_stress.png")

Topology optimization#
# Set the MKS unit system
app.ExtAPI.Application.ActiveUnitSystem = MechanicalUnitSystem.StandardMKS
# Add the topology optimization analysis to the model and transfer data from the
# structural analysis
topology_optimization = model.AddTopologyOptimizationAnalysis()
topology_optimization.TransferDataFrom(struct)
# Get the optimization region from the data model
optimization_region = DataModel.GetObjectsByType(DataModelObjectCategory.OptimizationRegion)[0]
# Set the optimization region's boundary condition to all loads and supports
optimization_region.BoundaryCondition = BoundaryConditionType.AllLoadsAndSupports
# Set the optimization region's optimization type to topology density
optimization_region.OptimizationType = OptimizationType.TopologyDensity
# Delete the mass response constraint from the topology optimization
mass_constraint = topology_optimization.Children[3]
app.DataModel.Remove(mass_constraint)
# Add a volume response constraint to the topology optimization
volume_constraint = topology_optimization.AddVolumeConstraint()
# Add a member size manufacturing constraint to the topology optimization
mem_size_manufacturing_constraint = topology_optimization.AddMemberSizeManufacturingConstraint()
# Set the constraint's minimum to manual and its minimum size to 2.4m
mem_size_manufacturing_constraint.Minimum = ManuMemberSizeControlledType.Manual
mem_size_manufacturing_constraint.MinSize = Quantity("2.4 [m]")
# Activate the topology optimization analysis and display the image
topology_optimization.Activate()
set_camera_and_display_image(
camera, graphics, settings_720p, output_path, "boundary_conditions.png"
)

Solve the solution#
# Get the topology optimization analysis solution
top_opt_sln = topology_optimization.Solution
# Solve the solution
top_opt_sln.Solve(True)
Show messages#
# Print all messages from Mechanical
app.messages.show()
Severity: Info
DisplayString: For geometric constraint (Mass, Volume, Center of Gravity or Moment of Inertia constraints), it is recommended to use Criterion of the upstream Measure folder (inserted from Model object).
Severity: Info
DisplayString: The requested license was received from the License Manager after 22 seconds.
Severity: Warning
DisplayString: The default mesh size calculations have changed in 18.2. Specifically, the default min size values and/or defeature size values scale dynamically in relation to the element (max face) size. These settings could lead to a significantly different mesh, so the model will be resumed using the previous values for min size and defeature size rather than leaving those values as default.
Display the results#
# Get the topology density result and activate it
top_opt_sln.Children[1].Activate()
topology_density = top_opt_sln.Children[1]
Add smoothing to the stereolithography (STL)
# Add smoothing to the topology density result
topology_density.AddSmoothing()
# Evaluate all results for the topology optimization solution
topology_optimization.Solution.EvaluateAllResults()
# Activate the topology density result after smoothing and display the image
topology_density.Children[0].Activate()
set_camera_and_display_image(
camera, graphics, settings_720p, output_path, "topo_opitimized_smooth.png"
)

Export the animation
app.Tree.Activate([topology_density])
# Set the animation export format and settings
animation_export_format = Ansys.Mechanical.DataModel.Enums.GraphicsAnimationExportFormat.GIF
settings_720p = Ansys.Mechanical.Graphics.AnimationExportSettings()
settings_720p.Width = 1280
settings_720p.Height = 720
# Export the animation of the topology density result
topology_optimized_gif = output_path / "topology_opitimized.gif"
topology_density.ExportAnimation(
str(topology_optimized_gif), animation_export_format, settings_720p
)

Review the results
# Print the topology density results
print("Topology Density Results")
print("Minimum Density: ", topology_density.Minimum)
print("Maximum Density: ", topology_density.Maximum)
print("Iteration Number: ", topology_density.IterationNumber)
print("Original Volume: ", topology_density.OriginalVolume.Value)
print("Final Volume: ", topology_density.FinalVolume.Value)
print("Percent Volume of Original: ", topology_density.PercentVolumeOfOriginal)
print("Original Mass: ", topology_density.OriginalMass.Value)
print("Final Mass: ", topology_density.FinalMass.Value)
print("Percent Mass of Original: ", topology_density.PercentMassOfOriginal)
Topology Density Results
Minimum Density: 0.0010000000474974513
Maximum Density: 1.0
Iteration Number: 35
Original Volume: 1000.0000054389238
Final Volume: 522.4924773573875
Percent Volume of Original: 52.24924745155908
Original Mass: 7849999.975463867
Final Mass: 4101565.9057617188
Percent Mass of Original: 52.24924737046705
Display the project tree#
app.print_tree()
├── Project
| ├── Model
| | ├── Geometry Imports (✓)
| | | ├── Geometry Import (✓)
| | ├── Geometry (✓)
| | | ├── Surface Body Bodies
| | | | ├── Surface Body
| | ├── Materials (✓)
| | | ├── Structural Steel (✓)
| | ├── Coordinate Systems (✓)
| | | ├── Global Coordinate System (✓)
| | | ├── Coordinate System (✓)
| | | ├── Coordinate System 2 (✓)
| | | ├── Coordinate System 3 (✓)
| | | ├── Coordinate System 4 (✓)
| | | ├── Coordinate System 5 (✓)
| | | ├── Coordinate System 6 (✓)
| | | ├── Coordinate System 7 (✓)
| | | ├── Coordinate System 8 (✓)
| | ├── Remote Points (✓)
| | ├── Mesh (✓)
| | | ├── Face Sizing (✓)
| | ├── Named Selections
| | | ├── Selection (✓)
| | | ├── Bottom_Elements (✓)
| | | ├── Top_Elements (✓)
| | | ├── Middle1_Elements (✓)
| | | ├── Middle2_Elements (✓)
| | | ├── Left1_Elements (✓)
| | | ├── Left2_Elements (✓)
| | | ├── Right1_Elements (✓)
| | | ├── Right2_Elements (✓)
| | | ├── Optimized_Shape (✓)
| | | ├── Outside_Optimized_Shape (✓)
| | | ├── Selection 2 (✓)
| | | ├── Selection 3 (✓)
| | | ├── Selection 4 (✓)
| | | ├── Selection 5 (✓)
| | ├── Static Structural (✓)
| | | ├── Analysis Settings (✓)
| | | ├── Fixed Support (✓)
| | | ├── Nodal Force (✓)
| | | ├── Solution (✓)
| | | | ├── Solution Information (✓)
| | | | ├── Total Deformation (✓)
| | | | ├── Equivalent Stress (✓)
| | ├── Structural Optimization (✓)
| | | ├── Analysis Settings (✓)
| | | ├── Optimization Region (✓)
| | | ├── Objective (✓)
| | | ├── Response Constraint (✓)
| | | ├── Manufacturing Constraint (✓)
| | | ├── Solution (✓)
| | | | ├── Solution Information (✓)
| | | | | ├── Topology Density Tracker (✓)
| | | | ├── Topology Density (✓)
| | | | | ├── Smoothing (✓)
Clean up the project#
# Save the project file
mechdat_file = output_path / "cantilever_beam_topology_optimization.mechdat"
app.save(str(mechdat_file))
# Close the app
app.close()
# Delete the example files
delete_downloads()
True
Total running time of the script: (0 minutes 39.837 seconds)