Download this example

Download this example as a Jupyter Notebook or as a Python script.


Applied: Import a STEP file, add named selections, and export to Mechanical#

This example demonstrates a complete geometry-to-simulation workflow:

  1. Open a STEP file using the Geometry Core Service.

  2. Programmatically create named selections on the geometry using PyAnsys Geometry.

  3. Export the annotated geometry to a PMDB file — the recommended cross-platform format for transferring geometry with named selections to Ansys Mechanical.

  4. Import the PMDB file into an embedded Mechanical session and verify that the named selections are preserved.

The geometry used in this example is a two-car assembly (twoCars.stp) available in the PyAnsys Geometry integration-tests folder. It is downloaded at runtime rather than shipped alongside this notebook.

Download the STEP file#

The STEP file lives in the integration-tests folder of the PyAnsys Geometry repository. The following code downloads it at runtime so that no binary asset needs to ship alongside the notebook.

[1]:
from pathlib import Path
import requests

STEP_URL = (
    "https://raw.githubusercontent.com/ansys/pyansys-geometry/main"
    "/tests/integration/files/import/twoCars.stp"
)

step_file = Path.cwd() / "twoCars.stp"
response = requests.get(STEP_URL)
response.raise_for_status()
step_file.write_bytes(response.content)
print(f"Downloaded STEP file to: {step_file}")
Downloaded STEP file to: /home/runner/work/pyansys-geometry/pyansys-geometry/doc/source/examples/04_applied/twoCars.stp

Launch the Geometry service and open the STEP file#

The following code starts the Geometry service and opens the STEP file.

[2]:
from ansys.geometry.core import launch_modeler

# Launch the Geometry service
modeler = launch_modeler()

# Open the STEP file
design = modeler.open_file(step_file)

Explore the imported design#

After opening the file, inspect the design hierarchy. In an imported STEP assembly the bodies are owned by sub-components, not by the root design object directly. Use the built-in tree_print() method to visualise the full component/body tree, then get_all_bodies() to collect every body regardless of nesting depth.

[3]:
# Print the component/body tree of the imported design
design.tree_print()
>>> Tree print view of component 'twoCars'

Location
--------
Root component (Design)

Subtree
-------
(comp) twoCars
|---(comp) Car1
:   |---(comp) B
:   :   |---(comp) Wheel1
:   :   :   |---(body) Wheel1
:   :   |---(comp) Wheel1
:   :   :   |---(body) Wheel1
:   :   |---(comp) Wheel1
:   :   :   |---(body) Wheel1
:   :   |---(comp) Base
:   :   :   |---(body) Base
:   :   |---(comp) Wheel1
:   :       |---(body) Wheel1
:   |---(comp) A
:       |---(body) A
|---(comp) Car1
    |---(comp) B
    :   |---(comp) Wheel1
    :   :   |---(body) Wheel1
    :   |---(comp) Wheel1
    :   :   |---(body) Wheel1
    :   |---(comp) Wheel1
    :   :   |---(body) Wheel1
    :   |---(comp) Base
    :   :   |---(body) Base
    :   |---(comp) Wheel1
    :       |---(body) Wheel1
    |---(comp) A
        |---(body) A
[4]:
# Retrieve every body in the assembly (traverses all nested components)
all_bodies = design.get_all_bodies()
print(f"Total bodies found: {len(all_bodies)}")
for body in all_bodies:
    print(f"  {body.name}")
Total bodies found: 12
  Wheel1
  Wheel1
  Wheel1
  Base
  Wheel1
  A
  Wheel1
  Wheel1
  Wheel1
  Base
  Wheel1
  A
[5]:
# Plot the design
design.plot()

Create named selections#

Named selections are labels that group bodies, faces, edges, or vertices. They pass through the PMDB format into Mechanical as Named Selections, where they can be used directly as scoping targets for boundary conditions, contacts, mesh controls, and result probes.

[6]:
# Create one named selection per body so that each part can be
# addressed individually inside Mechanical.
for i, body in enumerate(all_bodies):
    ns_name = f"Part_{i + 1}"
    design.create_named_selection(ns_name, bodies=[body])
    print(f"Created named selection '{ns_name}' containing body '{body.name}'")
Created named selection 'Part_1' containing body 'Wheel1'
Created named selection 'Part_2' containing body 'Wheel1'
Created named selection 'Part_3' containing body 'Wheel1'
Created named selection 'Part_4' containing body 'Base'
Created named selection 'Part_5' containing body 'Wheel1'
Created named selection 'Part_6' containing body 'A'
Created named selection 'Part_7' containing body 'Wheel1'
Created named selection 'Part_8' containing body 'Wheel1'
Created named selection 'Part_9' containing body 'Wheel1'
Created named selection 'Part_10' containing body 'Base'
Created named selection 'Part_11' containing body 'Wheel1'
Created named selection 'Part_12' containing body 'A'
[7]:
# Create a combined named selection that covers the entire assembly.
# This is useful for applying global mesh settings or result scoping.
design.create_named_selection("All_Parts", bodies=all_bodies)
print("Created named selection 'All_Parts' containing all bodies")
Created named selection 'All_Parts' containing all bodies
[8]:
# Filter to only the named selections we created
filtered_ns = [ns for ns in design.named_selections if ns.name == "All_Parts" or ns.name.startswith("Part_")]
print(f"\nNamed selections in design {len(filtered_ns)}:")
for ns in filtered_ns:
    n_bodies = len(ns.bodies)
    print(f"  '{ns.name}' — {n_bodies} body/bodies")

Named selections in design 13:
  'Part_1' — 1 body/bodies
  'Part_2' — 1 body/bodies
  'Part_3' — 1 body/bodies
  'Part_4' — 1 body/bodies
  'Part_5' — 1 body/bodies
  'Part_6' — 1 body/bodies
  'Part_7' — 1 body/bodies
  'Part_8' — 1 body/bodies
  'Part_9' — 1 body/bodies
  'Part_10' — 1 body/bodies
  'Part_11' — 1 body/bodies
  'Part_12' — 1 body/bodies
  'All_Parts' — 12 body/bodies

Export to PMDB#

PMDB (Persistent Model Database) is the recommended format for transferring geometry with named selections from the Geometry service to Ansys Mechanical on both Windows and Linux.

[9]:
# Export the annotated design to a PMDB file in the current working directory.
pmdb_path = design.export_to_pmdb()
print(f"Design exported to: {pmdb_path}")
Design exported to: /home/runner/work/pyansys-geometry/pyansys-geometry/doc/source/examples/04_applied/twoCars.pmdb

Close the Geometry service#

[10]:
modeler.close()

Import the PMDB into Mechanical#

The PMDB file can now be imported into an embedded Mechanical session. The named selections created above will be preserved and appear in the Mechanical tree under Named Selections.

The following code requires PyMechanical and an Ansys Mechanical installation (2024 R1 or later).

import ansys.mechanical.core as mech

# Launch an embedded Mechanical session
app = mech.App(version=261)

# ---- geometry import ----
geometry_import = app.Model.GeometryImportGroup.AddGeometryImport()

# Enable named-selection transfer
geometry_import.GeometryImportPreferences.ProcessNamedSelections = True
geometry_import.GeometryImportPreferences.NameSelectionKey = ""

# Import the PMDB produced in the previous step
geometry_import.Import(str(pmdb_path))

# ---- verify named selections ----
ns_group = app.Model.NamedSelections
print(f"Named selections imported ({ns_group.Children.Count} total):")
for child in ns_group.Children:
    print(f"  {child.Name}")

# ---- clean up ----
app.close()

The named selections (Part_1, Part_2, …, All_Parts) are now available inside Mechanical and can be used for mesh controls, boundary conditions, contacts, and result evaluation.

References#


Download this example

Download this example as a Jupyter Notebook or as a Python script.