Download this example
Download this example as a Jupyter Notebook or as a Python script.
Tools: Using PrepareTools to prepare geometry for simulation#
This example demonstrates how to use the PrepareTools class to prepare geometry for simulation. The PrepareTools class provides methods for extracting flow volumes, removing rounds, sharing topology between bodies, detecting helixes, creating enclosures, and identifying sweepable bodies.
The PrepareTools instance is accessible through modeler.prepare_tools. It should not be instantiated directly by the user.
Perform required imports#
Perform the required imports.
[1]:
from pathlib import Path
import requests
from ansys.geometry.core import launch_modeler
from ansys.geometry.core.math import Point2D
from ansys.geometry.core.misc.measurements import UNITS
from ansys.geometry.core.sketch import Sketch
from ansys.geometry.core.tools.prepare_tools import EnclosureOptions
Download example files#
Download example geometry files from the PyAnsys Geometry repository. These files are used to demonstrate how the PrepareTools methods work with real geometry.
[2]:
BASE_URL = (
"https://raw.githubusercontent.com/ansys/pyansys-geometry/main/tests/integration/files/"
)
FILES = {
"hollow_cylinder": "hollowCylinder.scdocx",
"box_with_round": "BoxWithRound.scdocx",
"mixing_tank": "MixingTank.scdocx",
"bolt": "bolt.scdocx",
"different_shapes": "DifferentShapes.scdocx",
}
def download_file(filename):
"""Download a file from the PyAnsys Geometry repository."""
url = BASE_URL + filename
local_path = Path.cwd() / filename
response = requests.get(url)
response.raise_for_status()
local_path.write_bytes(response.content)
print(f"Downloaded: {filename}")
return local_path
file_paths = {key: download_file(name) for key, name in FILES.items()}
Downloaded: hollowCylinder.scdocx
Downloaded: BoxWithRound.scdocx
Downloaded: MixingTank.scdocx
Downloaded: bolt.scdocx
Downloaded: DifferentShapes.scdocx
Initialize the modeler#
[3]:
modeler = launch_modeler()
print(modeler)
Ansys Geometry Modeler (0x7efe26601550)
Ansys Geometry Modeler Client (0x7efe2636a3c0)
Target: localhost:700
Connection: Healthy
Backend info:
Version: 27.1.0
Backend type: CORE_LINUX
Backend number: 20260222.1
API server number: 2123
CADIntegration: 27.1.0.13
Extract a flow volume from faces#
extract_volume_from_faces() creates a new body representing the interior volume of a part. You provide sealing faces (which close off the volume) and inside faces (which define the wetted interior surface).
This is commonly used to extract a fluid domain from a solid CAD model.
[4]:
design = modeler.open_file(file_paths["hollow_cylinder"])
design.plot()
body = design.bodies[0]
print(f"Body name: {body.name}")
print(f"Number of faces: {len(body.faces)}")
# Use two end faces as sealing faces and the inner cylindrical face as the inside face
sealing_faces = [body.faces[1], body.faces[2]]
inside_faces = [body.faces[0]]
created_bodies = modeler.prepare_tools.extract_volume_from_faces(sealing_faces, inside_faces)
print(f"Number of bodies created: {len(created_bodies)}")
design.plot()
Body name: Solid
Number of faces: 4
Number of bodies created: 1
Extract a flow volume from edge loops#
extract_volume_from_edge_loops() creates a volume from a set of edges that define a closed loop. This is an alternative to face-based extraction when working with open-shell or surface models.
[5]:
design = modeler.open_file(file_paths["hollow_cylinder"])
body = design.bodies[0]
print(f"Number of edges: {len(body.edges)}")
# Use two circular edges at either end of the hollow cylinder to define the sealing loop
sealing_edges = [body.edges[2], body.edges[3]]
created_bodies = modeler.prepare_tools.extract_volume_from_edge_loops(sealing_edges)
print(f"Number of bodies created: {len(created_bodies)}")
design.plot()
Number of edges: 4
Number of bodies created: 1
Remove rounds from geometry#
remove_rounds() removes fillet or round faces from a solid body. This is useful for simplifying geometry before meshing or simulation.
The auto_shrink parameter controls whether the surrounding faces are extended to fill the gap left by the removed rounds.
[6]:
from ansys.geometry.core.designer import SurfaceType
design = modeler.open_file(file_paths["box_with_round"])
design.plot()
body = design.bodies[0]
print(f"Number of faces before removing rounds: {len(body.faces)}")
# Identify and remove the cylindrical (round) faces
round_faces = [
face for face in body.faces if face.surface_type == SurfaceType.SURFACETYPE_CYLINDER
]
print(f"Number of round faces found: {len(round_faces)}")
result = modeler.prepare_tools.remove_rounds(round_faces)
print(f"Remove rounds successful: {result}")
print(f"Number of faces after removing rounds: {len(body.faces)}")
design.plot()
Number of faces before removing rounds: 7
Number of round faces found: 1
Remove rounds successful: True
Number of faces after removing rounds: 6
Detect helixes in geometry#
detect_helixes() identifies helical edges in a body, such as screw threads. The method accepts optional min_radius, max_radius, and fit_radius_error parameters to control which helixes are detected.
[8]:
design = modeler.open_file(file_paths["bolt"])
design.plot()
bodies = design.bodies
print(f"Number of bodies: {len(bodies)}")
# Detect helixes using default parameters
result = modeler.prepare_tools.detect_helixes([bodies[0]])
print(f"Number of helixes detected: {len(result['helixes'])}")
for i, helix in enumerate(result["helixes"]):
print(f" Helix {i + 1}: {len(helix['edges'])} edge(s)")
Number of bodies: 2
Number of helixes detected: 1
Helix 1: 4 edge(s)
Create a box enclosure around bodies#
create_box_enclosure() generates a rectangular box that surrounds the specified bodies. The distance parameters control the clearance between each body face and the enclosure wall.
EnclosureOptions controls whether the enclosed bodies are subtracted from the enclosure and whether shared topology is applied automatically.
[9]:
design = modeler.open_file(file_paths["box_with_round"])
bodies = [design.bodies[0]]
# Create an enclosure with the enclosed body subtracted (default behavior)
enclosure_options = EnclosureOptions(subtract_bodies=True)
enclosure_bodies = modeler.prepare_tools.create_box_enclosure(
bodies, 0.005, 0.01, 0.01, 0.005, 0.10, 0.10, enclosure_options
)
print(f"Number of enclosure bodies created: {len(enclosure_bodies)}")
design.plot()
Number of enclosure bodies created: 1
Create a sphere enclosure around bodies#
create_sphere_enclosure() generates a spherical enclosure around the given bodies. The radial_distance parameter sets the clearance between the bodies and the sphere surface.
[10]:
design = modeler.open_file(file_paths["box_with_round"])
bodies = [design.bodies[0]]
enclosure_options = EnclosureOptions()
enclosure_bodies = modeler.prepare_tools.create_sphere_enclosure(bodies, 0.1, enclosure_options)
print(f"Number of enclosure bodies created: {len(enclosure_bodies)}")
design.plot()
Number of enclosure bodies created: 1
Detect sweepable bodies#
detect_sweepable_bodies() checks whether each body in a list can be swept (that is, whether it has a consistent cross-section that can be extruded along a path). Set get_source_target_faces=True to also retrieve the source and target faces used for the sweep.
[11]:
design = modeler.open_file(file_paths["different_shapes"])
bodies = design.bodies
print(f"Number of bodies: {len(bodies)}")
# Check sweepability without retrieving source/target faces
results = modeler.prepare_tools.detect_sweepable_bodies(bodies)
for i, (is_sweepable, faces) in enumerate(results):
print(f" Body '{bodies[i].name}': sweepable={is_sweepable}")
Number of bodies: 6
Body 'Elliptical': sweepable=True
Body 'Hexagon': sweepable=True
Body 'PartialCone': sweepable=False
Body 'Sphere': sweepable=False
Body 'SquareSurface': sweepable=False
Body 'EllipticalSuface': sweepable=False
[12]:
# Check sweepability and retrieve source/target faces for sweepable bodies
results_with_faces = modeler.prepare_tools.detect_sweepable_bodies(
bodies, get_source_target_faces=True
)
for i, (is_sweepable, faces) in enumerate(results_with_faces):
face_info = f", source/target faces={len(faces)}" if is_sweepable else ""
print(f" Body '{bodies[i].name}': sweepable={is_sweepable}{face_info}")
Body 'Elliptical': sweepable=True, source/target faces=2
Body 'Hexagon': sweepable=True, source/target faces=2
Body 'PartialCone': sweepable=False
Body 'Sphere': sweepable=False
Body 'SquareSurface': sweepable=False
Body 'EllipticalSuface': sweepable=False
Close the modeler#
Close the modeler to free up resources and release the connection.
[13]:
modeler.close()